{ SoundS.INC 5-27-93 by Steven Tallent This is a Unit to play 8-bit raw Sound Files on any PC, up to 64k large. It supports the PC speaker or a DAC (LPT1 or LPT2), although I do plan to upgrade it to support the SoundBlaster and Adlib Sound cards. It is Object-oriented in nature, With one instance of a speaker defined automatically. This Unit is public domain, With code and ideas captured from this echo and Dr. Dobbs Journal. Using the code is simple. Just setup the the Speaker.Kind, Speaker.Silent, and Speaker.DisINT to the appropriate values, then just use the methods included. The SoundBoard Object is very flexible For your own code. SoundBoard.Play - Plays 8-bit music in What^ For Size length, With Speed milliseconds between each Byte, and SampleRate as the sample rate (in Hz). Speed will need to be changed on different computers (of course). SoundBoard.Sound - Plays a Sound at HZ Hertz, Duration in ms, on VOICE voice. The code included is useable on the PC speaker (1 voice) or the Tandy speaker (3 voices!). SoundBoard.Reset - Resets the Sound board. SoundBoard.Silent- Convenient Variable that disables all PLAY and Sound if set to True. SoundBoard.DisINT- Disables all interrupts (except during Delays) While using PLAY. This code may be freely distributed, changed, or included in your own commercial or shareware code, as long as this isn't all your code does. This code may be included in commercial or shareware code libraries only With my permission (I'd like to see someone get some use out of it). } Unit Sounds; Interface Type BigArray = Array[0..0] of Byte; PBigArray = ^BigArray; KSoundBoard = (PCspeaker, Tandy, DAC1, DAC2, AdLib, SB, SBpro, SB16); SoundBoard = Object Kind : KSoundBoard; Silent : Boolean; DisINT : Boolean; Procedure Play(What : PBigArray; Size : Word; Speed : Byte; SampleRate : Word); Procedure Sound(Hz, Duration : Word; Voice, Volume : Byte); Procedure Reset; end; Var Speaker : SoundBoard; Procedure Delay(ms : Word); Implementation Procedure SoundBoard.Reset; begin Case Kind of PCspeaker, Tandy : Port[97] := Port[97] and $FC; end; end; Procedure SoundBoard.Sound(Hz, Duration : Word; Voice, Volume : Byte); Var Count : Word; SendByte, VoiceID : Byte; begin Case Kind of PCspeaker : begin Count := 1193180 div Hz; Port[97] := Port[97] or 3; Port[67] := 182; Port[66] := Lo(Count); Port[66] := Hi(Count); Delay(Duration); Port[97] := Port[97] and $FC; end; Tandy : begin if Voice = 1 then VoiceId := 0 else if Voice = 2 then VoiceId := 32 else VoiceId := 64; Count := 111861 div Hz; SendByte := 128 + VoiceId + (Count mod 16); Port [$61] := $68; Port [$C0] := SendByte; Port [$C0] := Count div 16; if Voice = 1 then VoiceId := 16 else if Voice = 2 then VoiceId := 48 else VoiceId := 96; SendByte := 128 + VoiceId + (15 - Volume); Port [$61] := $68; Port [$C0] := SendByte; Delay(Duration); SendByte := 128 + VoiceId + 15; Port [$61] := $68; Port [$C0] := SendByte; DAC1:; DAC2:; AdLib:; SB:; SBPro:; SB16:; end; Procedure SoundBoard.Play(What : PBigArray; Size : Word; Speed : Byte; SampleRate : Word); Var Loop, Count, Data : Word; begin if not Silent then begin Case Kind of PCspeaker, Tandy : begin Port[97] := Port[97] or 3; Count := 1193180 div (SampleRate div 256); For Loop := 1 to Size do begin Data := Count div (What^[Loop] + 1); Port[67] := 182; Port[66] := Lo(Data); Port[66] := Hi(Data); Delay(Speed); if DisINT then Asm CLI end; end; Port[97] := Port[97] and $FC; end; DAC1: For Loop := 1 to Size do begin Port [$0378] := What^[Loop]; Delay (Speed); if DisINT then Asm CLI end; end; DAC2: For Loop := 1 to Size do begin Port [$0278] := What^[Loop]; Delay (Speed); if DisINT then Asm CLI end; end; AdLib:; SB:; SBPro:; SB16:; end; Asm STI end; end; end; Procedure Delay(ms : Word); Assembler; Asm STI MOV AH, $86 MOV CX, 0 MOV DX, [ms] INT $15 end; end. {----------------------------------------------------------------- Here's a Program that will accept three values from the command line, the File, its speed, and the sample rate, and plays it through the PC speaker. I've tried in on WAV, VOC, SAM, and even Amiga sampled Files, With no problems (limited to 64k). I've even played MOD Files to hear all the sampled instruments! This Program does not strip header information, but plays it too, but I can't hear the difference on WAV and VOC Files. } Program TestSnd; Uses Sounds; Var I2 : PBigArray; spd : Integer; samp : Word; res : Word; siz : Word; s : String; f1 : File of Byte; F : File; begin Speaker.Kind := PCspeaker; Speaker.DisINT := True; Speaker.Silent := False; s := ParamStr(1); Assign(f1,s); {Get size of File} Reset(f1); Val (ParamStr(2), Spd, Res); Val (ParamStr(3), samp, Res); siz := FileSize(f1); close(f1); Assign(f,s); Reset(f); getmem (I2,siz); {Allocate Memory For Sound File} BlockRead(f,I2^,siz,res); {Load Sound into Memory} Speaker.Play (i2, siz, spd, samp); FreeMem (I2, siz); end.