home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Pascal / MAXONPASCAL3.DMS / in.adf / DEMOS-OS1.3 / Play8SVX.p < prev    next >
Encoding:
Text File  |  1994-07-23  |  7.5 KB  |  301 lines

  1. PROGRAM Play8SVX;
  2.  
  3. { Demo für die Benutzung des Audio-Device.              }
  4. { Die Funktion "LoadSample" lädt einen 8SVX-IFF-Sound,  }
  5. { legt ihn in einer dynamisch eingerichteten Struktur   }
  6. { ab und gibt einen Zeiger auf diese Struktur zurück.   }
  7. { Die Datei muß vor Aufruf von "LoadSample" bereits     }
  8. { geöffnet sein.                                        }
  9. { Die Prozedur "PlaySample" spielt den Sound dann ab.   }
  10. { Vorraussetzung ist, daß das Audio-Device geöffnet und }
  11. { initialisiert ist.                                    }
  12.  
  13. { MaxonPascal3-Anpassung / Test:  Falk Zühlsdorff (PackMAN) 1994 }
  14. { nutzt richtiggestellte "Workbench/startup.h"  von PackMAN      }
  15.  
  16. { Bsp.-Sound: MPascal3:demo/Sound                                }
  17.  
  18. USES ExecSupport,ExecIO,DOS;
  19.  
  20. {$incl 'devices/audio.h', "workbench/startup.h" }
  21.  
  22. Const
  23.   CLOCK = 3579545;
  24.  
  25.  
  26. TYPE
  27.   File8SVX = File of Byte;
  28.  
  29.   VHDRTYPE = RECORD
  30.                OneShotHiSamples: Long;
  31.                RepeatHiSamples: Long;
  32.                SamplesPerHiCycle: Long;
  33.                SamplesPerSecond: Word;
  34.                Oktaven: Byte;
  35.                PackFlag: Byte;
  36.                Volume: Long
  37.              END;
  38.  
  39.   SamplePtr = ^SampleTYPE;
  40.   SampleTYPE = RECORD
  41.                  VHDR: VHDRTYPE;
  42.                  Len: LongInt;
  43.                  Data: ARRAY[0..MaxLongInt] OF Short
  44.                END;
  45.  
  46.  
  47. VAR F1                  : File8SVX;
  48.     Filename            : STRING;
  49.     MySample            : SamplePtr;
  50.     allocIOB, lockIOB   : ^IOAudio;
  51.     port                : ^MsgPort;
  52.     mydevice            : p_Device;
  53.     err                 : Long;
  54.  
  55.  
  56. FUNCTION LoadSample(VAR f: File8SVX): SamplePtr;
  57.   TYPE StrTYPE = String[5];
  58.   VAR sp: SamplePtr;
  59.       lw, err: LongInt;
  60.       s1: StrTYPE;
  61.       HeadFlag, BodyFlag: Boolean;
  62.       VHDR: VHDRTYPE;
  63.  
  64.   FUNCTION ReadStr4: StrTYPE;
  65.     VAR s: Array[1..5] OF Byte;
  66.         s2: String[5];
  67.     BEGIN
  68.       Read(f, s[1], s[2], s[3], s[4] );
  69.       s[5] := 0;
  70.       s2 := Str(^s);
  71.       ReadStr4 := S2;
  72.     END;
  73.  
  74.   FUNCTION ReadLong: LongInt;
  75.     VAR b1, b2, b3, b4: Byte;
  76.     BEGIN
  77.       Read(f, b1, b2, b3, b4 );
  78.       ReadLong := Long( Long(b1 shl 8 + b2) shl 8 + b3) shl 8 + b4
  79.     END;
  80.  
  81.   PROCEDURE Overread(Anz: LongInt);
  82.     VAR b: Byte;
  83.     BEGIN
  84.       While Anz>0 DO
  85.         BEGIN
  86.           Read(f, b);
  87.           Dec(Anz)
  88.         END
  89.     END;
  90.  
  91.   PROCEDURE ReadTo(Point: Ptr; Anz: Long );
  92.     VAR p2: ^Array[1..MaxLongInt] Of Byte;
  93.         i: LongInt;
  94.     BEGIN
  95.       p2 := Point;
  96.       For i:=1 to Anz Do Read(f, p2^[i]);
  97.       { Blockread(f, p2^, Anz); }
  98.     END;
  99.  
  100.  
  101.   BEGIN    { LoadSample }
  102.     s1 := ReadStr4;
  103.     IF s1 <> 'FORM' THEN
  104.       BEGIN
  105.         Writeln('Kein IFF-Format!');
  106.         LoadSample := Nil;
  107.         Exit
  108.       END;
  109.     lw := ReadLong;
  110.     s1 := ReadStr4;
  111.     IF s1 <> '8SVX' THEN
  112.       BEGIN
  113.         Writeln('Kein 8SVX-File!');
  114.         LoadSample := Nil;
  115.         Exit
  116.       END;
  117.  
  118.     sp := Nil;
  119.     HeadFlag := false;
  120.     BodyFlag := false;
  121.  
  122.     While not (HeadFlag and BodyFlag) Do
  123.       BEGIN
  124.         s1 := ReadStr4;
  125.         lw := ReadLong;
  126.         IF s1='VHDR' THEN
  127.           BEGIN
  128.             ReadTo(^VHDR, SizeOf(VHDRTYPE));
  129.             Overread(lw-SizeOf(VHDRTYPE));
  130.             HeadFlag := true
  131.           END
  132.         ELSE
  133.         IF s1='BODY' THEN
  134.           BEGIN
  135.             IF not HeadFlag THEN
  136.               BEGIN
  137.                 Writeln('Fehler in DateIFormat!');
  138.                 LoadSample := Nil;
  139.                 Exit
  140.               END;
  141.             sp := Ptr (Alloc_Mem (lw+4+SizeOf(VHDRTYPE), 2));
  142.             sp^.Len := lw+4+SizeOf(VHDRTYPE);
  143.             sp^.VHDR := VHDR;
  144.             BlockRead(f, sp^.Data, lw);
  145.             BodyFlag := true
  146.           END
  147.         ELSE
  148.           OverRead(lw);
  149.  
  150.       END;
  151.  
  152.     LoadSample := sp
  153.   END;
  154.  
  155.  
  156.  
  157. PROCEDURE InitAudio;
  158.   { Device öffnen, Ports einrichten, Kanäle reservieren usw. }
  159.   VAR alloctable : Array[1..4] Of Byte;
  160.   BEGIN
  161.     port := CreatePort ('sound example', 0);
  162.     IF port=Nil THEN Halt(0);
  163.  
  164.     allocIOB := CreateExtIO (port, SizeOf (IOAudio));
  165.     IF allocIOB=Nil THEN Halt(0);
  166.  
  167.     lockIOB := CreateExtIO (port, SizeOf (IOAudio));
  168.     IF lockIOB=Nil THEN Halt(0);
  169.  
  170.     Open_Device(AUDIONAME, 0, AllocIOB, 0);
  171.  
  172.     mydevice := allocIOB^.ioa_Request.io_Device;
  173.     lockIOB^.ioa_Request.io_Device := mydevice;
  174.  
  175.     AllocTable[1] := %0001;
  176.     AllocTable[2] := %0010;
  177.     AllocTable[3] := %0100;
  178.     AllocTable[4] := %1000;
  179.  
  180.     With allocIOB^, ioa_Request, io_Message Do
  181.       BEGIN
  182.         io_Flags := ADIOF_NOWAIT;
  183.         ioa_Data := ^AllocTable;
  184.         ioa_Length := 4;
  185.         io_Command := ADCMD_ALLOCATE;
  186.         BEGINIO(allocIOB);
  187.       END;
  188.     err:=WaitIO(PTR(allocIOB));
  189.     IF err <> 0 THEN
  190.       Error('Allocation failed');
  191.  
  192.     With lockIOB^, ioa_Request Do
  193.       BEGIN
  194.         io_Unit := allocIOB^.ioa_Request.io_Unit;
  195.         io_Command := ADCMD_LOCK;
  196.         ioa_AllocKey := allocIOB^.ioa_AllocKey;
  197.       END;
  198.     SENDIO(PTR(lockIOB));
  199.     IF CheckIO(PTR(lockIOB)) THEN
  200.       Error('Channel stolen.');
  201.   END;
  202.  
  203. PROCEDURE PlaySample(s: SamplePtr);
  204.   VAR Laenge,Rate: Long;
  205.   BEGIN
  206.     With s^.VHDR Do
  207.       BEGIN
  208.         Laenge := OneShotHiSamples+RepeatHiSamples;
  209.         Rate := CLOCK div SamplesPerSecond;
  210.       END;
  211.  
  212.     With lockIOB^, ioa_Request Do
  213.       BEGIN
  214.         io_Command := CMD_WRITE;
  215.         io_Flags := ADIOF_PERVOL;
  216.         ioa_Data := ^s^.Data;
  217.         ioa_Length := Laenge;
  218.         ioa_Volume := 64;
  219.         ioa_Period := Rate;
  220.         ioa_Cycles := 1;
  221.       END;
  222.     BEGINIO(lockIOB);
  223.     IF not fromWB THEN writeln('Playing...');
  224.     err:=WaitIO(PTR(lockIOB))
  225.  END;
  226.  
  227.  
  228.  
  229. PROCEDURE StartVonWorkbench;
  230.   { Workbench-Parameter auswerten }
  231.   VAR StMess  : p_WBStartup;
  232.       OldLock : BPTR;
  233.   BEGIN
  234.     StMess := StartupMessage;
  235.       { "StartupMessage" ist ein typfreier "Ptr"-Pointer. Deshalb
  236.         wird zum Auswerten der Hilfszeiger "StMess" benötigt.    }
  237.     IF StMess^.sm_NumArgs < 2 THEN
  238.       { Anzahl der Argumente, d. h. der aktiven Icons. Das erste
  239.         Argument ist immer das Programm selbst. Also müssen mindestens
  240.         zwei Argumente vorhanden sein. }
  241.       Filename := ''
  242.     ELSE
  243.       WITH StMess^.sm_ArgList^[2] DO
  244.         BEGIN
  245.           { Als Datei wird das Argument Nr. #2 genommen. Falls noch
  246.             mehr Icons aktiviert sing (z. B. durch "ShIFt-Klick",
  247.             werden diese ignoroert. }
  248.           Filename:=wa_Name;
  249.           { reiner Name ohne Pfad! Deshalb muss das aktuelle Verzeichnis
  250.             entsprechEND gewählt werden:  }
  251.           OldLock:=CurrentDir(wa_Lock );
  252.         END;
  253.   END;
  254.  
  255.  
  256. BEGIN { Main }
  257.  
  258.   { Dateinamen bestimmen }
  259.  
  260.   IF FromWB THEN
  261.     BEGIN
  262.       StartVonWorkbench;
  263.       IF Filename = '' THEN Exit
  264.     END
  265.   ELSE { Start von CLI }
  266.     BEGIN
  267.       Filename := ParameterStr;
  268.       IF ParameterLen < 80 THEN Filename[ParameterLen+1] := chr(0);
  269.       While Filename[1] = ' ' Do
  270.         Delete (Filename, 1, 1);    { führende Spaces löschen }
  271.       While (Filename <> '') and (Filename[Length(Filename)] <= ' ') Do
  272.         Filename[Length(Filename)] := chr(0);
  273.  
  274.       IF Filename='' THEN
  275.         BEGIN
  276.           Writeln(#e'33mPlay8SVX'#e'31m - geschrieben von '#e'33mJens Gelhar'#&
  277.                   #e'31m 1990 mit Kickpascal 2.0');
  278.           Write('Dateiname : '); Readln(Filename);
  279.           IF Filename='' THEN Exit
  280.         END;
  281.     END;
  282.  
  283.   Reset (F1, Filename);
  284.   IF IOResult <> 0 THEN
  285.     Error('Datei konnte nicht geöffnet werden.');
  286.  
  287.   Buffer (F1, 5000);
  288.   IF not FromWB THEN Writeln ('Loading ', Filename, '...');
  289.   MySample := LoadSample (F1);
  290.   Close (F1);
  291.  
  292.   IF MySample <> Nil THEN
  293.     BEGIN
  294.       InitAudio;
  295.       PlaySample(MySample);
  296.       Close_Device(allocIOB);
  297.     END;
  298.  
  299. END.
  300.  
  301.