home *** CD-ROM | disk | FTP | other *** search
/ Chip: Special Sound & MIDI / Chip-Special_Sound-und-Midi-auf-dem-PC.bin / dosprog / vocbsp1.pas < prev    next >
Pascal/Delphi Source File  |  1993-11-21  |  8KB  |  241 lines

  1. (***C*H*I*P***S*P*E*C*I*A**L*************************************************)
  2. (*                                                                          *)
  3. (*       VOC-Beispiel 1: Sound-Wiedergabe über den digitalen Audiokanal     *)
  4. (*                                                                          *)
  5. (*   (c) 1993 Rainer Reusch, Patrick Haller & Vogel Verlag München          *)
  6. (*                                                                          *)
  7. (*   Turbo Pascal 7.0                                                       *)
  8. (*                                                                          *)
  9. (****************************************************************************)
  10.  
  11. {
  12. Dieses Beispiel zeigt:
  13. - die Initialisierung des Digital Sound Processors der Sound Blaster
  14. - die direkte Wiedergabe eines 8-Bit-Sounds ohne Berücksichtigung einer
  15.   Abtastrate
  16. }
  17.  
  18. {$A+,B-,D-,E+,F-,G+,I-,L-,N+,O-,P-,Q-,R-,S-,T-,V-,X+}
  19. {$M 16384,0,655360}
  20.  
  21. program VOVBsp1;
  22.  
  23. uses
  24.   Dos, Crt;
  25.  
  26. type
  27.   { Sound-Kartenparameter
  28.     (Reihenfolge nicht ändern, nichts einfügen, neue Parameter nur anhängen!) }
  29.   tBoardParams   = record
  30.                      PortAdr,            { Portadresse }
  31.                      IRQ,                { Hardware-Interrupt }
  32.                      DMA,                { DMA-Kanal }
  33.                      BoardType : word;   { Kartentyp }
  34.                    end { record };
  35.  
  36. const
  37.   { Default-Sound-Kartenparameter }
  38.   DefBoardParams : tBoardParams =
  39.                      ( PortAdr   : $220;
  40.                        IRQ       : 7;
  41.                        DMA       : 1;
  42.                        BoardType : 1);
  43.  
  44.   { Indizes für Sound-Blaster-Register }
  45.   SB_Reset  = $06;   { DSP-Initialisierung }
  46.   SB_Write  = $0C;   { DSP-Befehlsregister }
  47.   SB_Data   = $0A;   { DSP-Datenregister }
  48.   SB_Status = $0E;   { DSP-Statusregister }
  49.  
  50.  
  51. { -------------------------------------------------------------------------- }
  52. function GetBoardParams(var BoardParams : tBoardParams) : boolean;
  53. { -------------------------------------------------------------------------- }
  54.  
  55. { Diese Funktion sucht nach der Environmentvariablen "BLASTER" und ermittelt
  56.   daraus die Sound-Kartenkonfiguration. Das Funktionsergebnis ist true, wenn
  57.   die Variable gefunden wurde und alle vier Parameter (siehe Typvereinbarung
  58.   tBoardParams) angegeben sind. Fehlende Parameter werden durch Defaultwerte
  59.   (Variable DefBoardParams) ersetzt. }
  60.  
  61.   function GetParamValue(var ParamLine : string; ParamCode : char;
  62.                          var Value : word; IsHex : boolean) : boolean;
  63.   { Ermittelt den Parameter aus einem String. Ergebnis true, wenn gefunden.
  64.     Value bleibt unverändert, wenn nicht gefunden. IsHex=true: Parameter ist
  65.     als Hexzahl aufzufassen. }
  66.   var
  67.     p  : byte;
  68.     ss : string[5];
  69.     v  : word;
  70.     e  : integer;
  71.   begin
  72.     p:=Pos(ParamCode,ParamLine);
  73.     if p>0 then
  74.     begin   { gewünschter Parameter gefunden }
  75.       GetParamValue:=true;
  76.       ss:=copy(ParamLine,p+1,5);   { Ziffernstring extrahieren }
  77.       p:=Pos(#$20,ss);
  78.       if p>0 then ss[0]:=chr(p-1);
  79.       if IsHex then
  80.       begin   { Parameter ist als Hexzahl aufzufassen }
  81.         if length(ss)>0 then
  82.         begin
  83.           v:=0;
  84.           e:=0;
  85.           for p:=1 to length(ss) do
  86.           begin
  87.             v:=v shl 4;
  88.             if (ss[p]>='0') and (ss[p]<='9') then v:=v+ord(ss[p])-48
  89.             else
  90.             if (ss[p]>='A') and (ss[p]<='F') then v:=v+ord(ss[p])-55
  91.             else inc(e);
  92.           end;
  93.         end
  94.         else GetParamValue:=false;
  95.       end
  96.       else val(ss,v,e);   { Parameter ist als Dezimalzahl aufzufassen }
  97.       if e=0 then Value:=v
  98.              else GetParamValue:=false;
  99.     end
  100.     else GetParamValue:=false;
  101.   end { GetParamValue };
  102.  
  103. const
  104.   VarName = 'BLASTER';   { Name der zu suchenden Environmentvariablen }
  105.  
  106. var
  107.   Params  : string[62];
  108.   Result  : boolean;
  109.  
  110. begin
  111.   BoardParams:=DefBoardParams;
  112.   Params:=GetEnv(VarName);
  113.   Result:=GetParamValue(Params,'A',BoardParams.PortAdr,true);
  114.   Result:=Result and GetParamValue(Params,'I',BoardParams.IRQ,false);
  115.   Result:=Result and GetParamValue(Params,'D',BoardParams.DMA,false);
  116.   Result:=Result and GetParamValue(Params,'T',BoardParams.BoardType,false);
  117.   GetBoardParams:=Result;
  118. end { GetBoardParams };
  119.  
  120.  
  121. { -------------------------------------------------------------------------- }
  122. function SBInit(var BoardParams : tBoardParams) : boolean; assembler;
  123. { -------------------------------------------------------------------------- }
  124.  
  125. { DSP der Sound Blaster initialisieren
  126.   Funktionsergebnis true, wenn Aktion erfolgreich. }
  127.  
  128. asm
  129.   push es
  130.   les  bx,BoardParams   { Adresse der Kartenparameter in ES:BX }
  131.   mov  cx,es:[bx]       { 1. Record-Variable (hier PortAdr) in CX }
  132.   mov  dx,cx            { und CX }
  133.   add  dx,SB_Reset      { Index für Reset-Register dazuaddieren }
  134.   mov  al,1             { eine "1" auf Reset-Register ausgeben }
  135.   out  dx,al
  136.   xor  al,al            { ein bißchen warten (mind. 3µs) }
  137.   @1:
  138.   nop
  139.   dec  al
  140.   jnz  @1
  141.   out  dx,al            { eine "0" auf Reset-Register ausgeben }
  142.   mov  ax,2000h         { nochmal ein bißchen warten }
  143.   @2:
  144.   nop
  145.   dec  ax
  146.   jnz  @2
  147.   mov  dx,cx            { Status ermitteln }
  148.   add  dx,SB_Status
  149.   in   al,dx
  150.   test al,80h           { Bit 7 gesetzt? }
  151.   jz   @NotOk           { Sprung, wenn nein }
  152.   mov  dx,cx            { zusätzliche Prüfung }
  153.   add  dx,SB_Data       { aus dem DSP-Datenregister muß AAh gelesen werden }
  154.   in   al,dx
  155.   cmp  al,0AAh
  156.   jne  @NotOk
  157.   mov  ax,1             { Funktionsergebnis true }
  158.   jmp  @Ready
  159.   @NotOk:
  160.   xor  ax,ax            { Funktionsergebnis false }
  161.   @Ready:
  162.   pop  es
  163. end { SBInit };
  164.  
  165.  
  166. { -------------------------------------------------------------------------- }
  167. procedure SBWrite(PortAdr : word; Data : byte); assembler;
  168. { -------------------------------------------------------------------------- }
  169.  
  170. { Übergabe eines Kommando- oder Datenbytes an DSP }
  171.  
  172. asm
  173.   mov  dx,PortAdr    { Basisadresse der Sound-Karte }
  174.   add  dx,SB_Write   { Index für Ausgaberegister hinzuaddieren }
  175.   @1:
  176.   in   al,dx         { Prüfen, ob der DSP zur Datenaufnahme bereits ist }
  177.   and  al,80h
  178.   jnz  @1
  179.   mov  al,[Data]     { Kommando bzw. Datenbyte ausgeben }
  180.   out  dx,al
  181. end { SBWrite };
  182.  
  183.  
  184. { -------------------------------------------------------------------------- }
  185. procedure SBDAC(var BoardParams : tBoardParams; Data : byte);
  186. { -------------------------------------------------------------------------- }
  187.  
  188. { "Wiedergabe" eines Datenbytes }
  189.  
  190. begin
  191.   SBWrite(BoardParams.PortAdr,$10);    { Kommando 10h für DSP }
  192.   SBWrite(BoardParams.PortAdr,Data);   { das Datenbyte gleich hinterher }
  193. end { SBDAC };
  194.  
  195. const
  196.   MaxSample = 64000;
  197.  
  198. var
  199.   Board : tBoardParams;
  200.   b : byte;
  201.   i : word;
  202.   Sample : array[0..MaxSample] of byte;
  203.  
  204. begin
  205.   ClrScr;
  206.   writeln('*** VOC-Beispiel 1: Sound-Wiedergabe über den digitalen Audiokanal ***');
  207.   writeln;
  208.  
  209.   { Wo ist die Sound-Karte? }
  210.   if GetBoardParams(Board) then writeln('Im Environment eingetragene Parameter:')
  211.   else writeln('Parameter nicht gefunden! Verwendung von Defaultwerten.');
  212.   with Board do
  213.   begin
  214.     writeln('  PortAdresse        (A): ',PortAdr);
  215.     writeln('  Hardware-Interrupt (I): ',IRQ);
  216.     writeln('  DMA-Kanal          (D): ',DMA);
  217.     writeln('  Sound-Kartentyp    (T): ',Boardtype);
  218.   end;
  219.   writeln;
  220.  
  221.   { der Demo-Sound wird hier mathematisch erzeugt }
  222.   writeln('Bitte etwas Geduld, Sound wird berechnet...');
  223.   for i:=0 to MaxSample do
  224.   begin
  225.     write(MaxSample-i,'    ',#13);
  226.     Sample[i]:=round(128+63*sin(i/10*(i/1000)));
  227.   end;
  228.   writeln;
  229.  
  230.   { Wiedergabe }
  231.   writeln('Sound-Wiedergabe');
  232.   if not SBInit(Board) then
  233.   begin
  234.     writeln('Initialisierung der Sound Blaster fehlgeschlagen!');
  235.     Halt(1);
  236.   end;
  237.   SBWrite(Board.PortAdr,$D1);   { DSP mit Verstärker verbinden }
  238.   for b:=0 to 3 do
  239.     for i:=0 to MaxSample do SBDAC(Board,Sample[i]);
  240. end.
  241.