home *** CD-ROM | disk | FTP | other *** search
- (***C*H*I*P***S*P*E*C*I*A**L*************************************************)
- (* *)
- (* VOC-Beispiel 1: Sound-Wiedergabe über den digitalen Audiokanal *)
- (* *)
- (* (c) 1993 Rainer Reusch, Patrick Haller & Vogel Verlag München *)
- (* *)
- (* Turbo Pascal 7.0 *)
- (* *)
- (****************************************************************************)
-
- {
- Dieses Beispiel zeigt:
- - die Initialisierung des Digital Sound Processors der Sound Blaster
- - die direkte Wiedergabe eines 8-Bit-Sounds ohne Berücksichtigung einer
- Abtastrate
- }
-
- {$A+,B-,D-,E+,F-,G+,I-,L-,N+,O-,P-,Q-,R-,S-,T-,V-,X+}
- {$M 16384,0,655360}
-
- program VOVBsp1;
-
- uses
- Dos, Crt;
-
- type
- { Sound-Kartenparameter
- (Reihenfolge nicht ändern, nichts einfügen, neue Parameter nur anhängen!) }
- tBoardParams = record
- PortAdr, { Portadresse }
- IRQ, { Hardware-Interrupt }
- DMA, { DMA-Kanal }
- BoardType : word; { Kartentyp }
- end { record };
-
- const
- { Default-Sound-Kartenparameter }
- DefBoardParams : tBoardParams =
- ( PortAdr : $220;
- IRQ : 7;
- DMA : 1;
- BoardType : 1);
-
- { Indizes für Sound-Blaster-Register }
- SB_Reset = $06; { DSP-Initialisierung }
- SB_Write = $0C; { DSP-Befehlsregister }
- SB_Data = $0A; { DSP-Datenregister }
- SB_Status = $0E; { DSP-Statusregister }
-
-
- { -------------------------------------------------------------------------- }
- function GetBoardParams(var BoardParams : tBoardParams) : boolean;
- { -------------------------------------------------------------------------- }
-
- { Diese Funktion sucht nach der Environmentvariablen "BLASTER" und ermittelt
- daraus die Sound-Kartenkonfiguration. Das Funktionsergebnis ist true, wenn
- die Variable gefunden wurde und alle vier Parameter (siehe Typvereinbarung
- tBoardParams) angegeben sind. Fehlende Parameter werden durch Defaultwerte
- (Variable DefBoardParams) ersetzt. }
-
- function GetParamValue(var ParamLine : string; ParamCode : char;
- var Value : word; IsHex : boolean) : boolean;
- { Ermittelt den Parameter aus einem String. Ergebnis true, wenn gefunden.
- Value bleibt unverändert, wenn nicht gefunden. IsHex=true: Parameter ist
- als Hexzahl aufzufassen. }
- var
- p : byte;
- ss : string[5];
- v : word;
- e : integer;
- begin
- p:=Pos(ParamCode,ParamLine);
- if p>0 then
- begin { gewünschter Parameter gefunden }
- GetParamValue:=true;
- ss:=copy(ParamLine,p+1,5); { Ziffernstring extrahieren }
- p:=Pos(#$20,ss);
- if p>0 then ss[0]:=chr(p-1);
- if IsHex then
- begin { Parameter ist als Hexzahl aufzufassen }
- if length(ss)>0 then
- begin
- v:=0;
- e:=0;
- for p:=1 to length(ss) do
- begin
- v:=v shl 4;
- if (ss[p]>='0') and (ss[p]<='9') then v:=v+ord(ss[p])-48
- else
- if (ss[p]>='A') and (ss[p]<='F') then v:=v+ord(ss[p])-55
- else inc(e);
- end;
- end
- else GetParamValue:=false;
- end
- else val(ss,v,e); { Parameter ist als Dezimalzahl aufzufassen }
- if e=0 then Value:=v
- else GetParamValue:=false;
- end
- else GetParamValue:=false;
- end { GetParamValue };
-
- const
- VarName = 'BLASTER'; { Name der zu suchenden Environmentvariablen }
-
- var
- Params : string[62];
- Result : boolean;
-
- begin
- BoardParams:=DefBoardParams;
- Params:=GetEnv(VarName);
- Result:=GetParamValue(Params,'A',BoardParams.PortAdr,true);
- Result:=Result and GetParamValue(Params,'I',BoardParams.IRQ,false);
- Result:=Result and GetParamValue(Params,'D',BoardParams.DMA,false);
- Result:=Result and GetParamValue(Params,'T',BoardParams.BoardType,false);
- GetBoardParams:=Result;
- end { GetBoardParams };
-
-
- { -------------------------------------------------------------------------- }
- function SBInit(var BoardParams : tBoardParams) : boolean; assembler;
- { -------------------------------------------------------------------------- }
-
- { DSP der Sound Blaster initialisieren
- Funktionsergebnis true, wenn Aktion erfolgreich. }
-
- asm
- push es
- les bx,BoardParams { Adresse der Kartenparameter in ES:BX }
- mov cx,es:[bx] { 1. Record-Variable (hier PortAdr) in CX }
- mov dx,cx { und CX }
- add dx,SB_Reset { Index für Reset-Register dazuaddieren }
- mov al,1 { eine "1" auf Reset-Register ausgeben }
- out dx,al
- xor al,al { ein bißchen warten (mind. 3µs) }
- @1:
- nop
- dec al
- jnz @1
- out dx,al { eine "0" auf Reset-Register ausgeben }
- mov ax,2000h { nochmal ein bißchen warten }
- @2:
- nop
- dec ax
- jnz @2
- mov dx,cx { Status ermitteln }
- add dx,SB_Status
- in al,dx
- test al,80h { Bit 7 gesetzt? }
- jz @NotOk { Sprung, wenn nein }
- mov dx,cx { zusätzliche Prüfung }
- add dx,SB_Data { aus dem DSP-Datenregister muß AAh gelesen werden }
- in al,dx
- cmp al,0AAh
- jne @NotOk
- mov ax,1 { Funktionsergebnis true }
- jmp @Ready
- @NotOk:
- xor ax,ax { Funktionsergebnis false }
- @Ready:
- pop es
- end { SBInit };
-
-
- { -------------------------------------------------------------------------- }
- procedure SBWrite(PortAdr : word; Data : byte); assembler;
- { -------------------------------------------------------------------------- }
-
- { Übergabe eines Kommando- oder Datenbytes an DSP }
-
- asm
- mov dx,PortAdr { Basisadresse der Sound-Karte }
- add dx,SB_Write { Index für Ausgaberegister hinzuaddieren }
- @1:
- in al,dx { Prüfen, ob der DSP zur Datenaufnahme bereits ist }
- and al,80h
- jnz @1
- mov al,[Data] { Kommando bzw. Datenbyte ausgeben }
- out dx,al
- end { SBWrite };
-
-
- { -------------------------------------------------------------------------- }
- procedure SBDAC(var BoardParams : tBoardParams; Data : byte);
- { -------------------------------------------------------------------------- }
-
- { "Wiedergabe" eines Datenbytes }
-
- begin
- SBWrite(BoardParams.PortAdr,$10); { Kommando 10h für DSP }
- SBWrite(BoardParams.PortAdr,Data); { das Datenbyte gleich hinterher }
- end { SBDAC };
-
- const
- MaxSample = 64000;
-
- var
- Board : tBoardParams;
- b : byte;
- i : word;
- Sample : array[0..MaxSample] of byte;
-
- begin
- ClrScr;
- writeln('*** VOC-Beispiel 1: Sound-Wiedergabe über den digitalen Audiokanal ***');
- writeln;
-
- { Wo ist die Sound-Karte? }
- if GetBoardParams(Board) then writeln('Im Environment eingetragene Parameter:')
- else writeln('Parameter nicht gefunden! Verwendung von Defaultwerten.');
- with Board do
- begin
- writeln(' PortAdresse (A): ',PortAdr);
- writeln(' Hardware-Interrupt (I): ',IRQ);
- writeln(' DMA-Kanal (D): ',DMA);
- writeln(' Sound-Kartentyp (T): ',Boardtype);
- end;
- writeln;
-
- { der Demo-Sound wird hier mathematisch erzeugt }
- writeln('Bitte etwas Geduld, Sound wird berechnet...');
- for i:=0 to MaxSample do
- begin
- write(MaxSample-i,' ',#13);
- Sample[i]:=round(128+63*sin(i/10*(i/1000)));
- end;
- writeln;
-
- { Wiedergabe }
- writeln('Sound-Wiedergabe');
- if not SBInit(Board) then
- begin
- writeln('Initialisierung der Sound Blaster fehlgeschlagen!');
- Halt(1);
- end;
- SBWrite(Board.PortAdr,$D1); { DSP mit Verstärker verbinden }
- for b:=0 to 3 do
- for i:=0 to MaxSample do SBDAC(Board,Sample[i]);
- end.
-