[Back to SOUND SWAG index] [Back to Main SWAG index] [Original]
{
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.
[Back to SOUND SWAG index] [Back to Main SWAG index] [Original]