[Back to SOUND SWAG index] [Back to Main SWAG index] [Original]
UNIT vocdecl; { see demo at end of document }
INTERFACE
function reset_dsp(base:word):boolean;
procedure write_dac(level:byte);
function read_dac:byte;
function speaker_on:byte;
function speaker_off:byte;
procedure dma_pause;
procedure dma_continue;
procedure play_back(sound:pointer;size:word;frequency:word);
procedure play_voc(filename:string;buf:pointer);
function done_playing:boolean;
function play_raw(filename:string;buf:pointer):word;
IMPLEMENTATION
uses crt;
type
iDsound=record
dunno,
rate,
num_samples,
dunno2:word;
end;
var
dsp_reset:word;
dsp_read_data:word;
dsp_write_data:word;
dsp_write_status:word;
dsp_data_avail:word;
since_midnight:longint absolute $40:$6C;
playing_till:longint;
function reset_dsp(base:word):boolean;
begin
base:=base*$10;
dsp_reset:=base+$206;
dsp_read_data:=base+$20a;
dsp_write_data:=base+$20c;
dsp_write_status:=base+$20c;
dsp_data_avail:=base+$20e;
port[dsp_reset]:=1;
delay(10);
port[dsp_reset]:=0;
delay(10);
reset_dsp:=(port[dsp_data_avail]and $80=$80)and(port[dsp_read_data]=$aa);
end;
procedure write_dsp(value:byte);
begin
while port[dsp_write_status] and $80<>0 do;
port[dsp_write_data]:=value;
end;
function read_dsp:byte;
begin
while port[dsp_data_avail]and $80=0 do;
read_dsp:=port[dsp_read_data];
end;
procedure write_dac(level:byte);
begin
write_dsp($10);
write_dsp(level);
end;
function read_dac:byte;
begin
write_dsp($20);
read_dac:=read_dsp;
end;
function speaker_on:byte;
begin
write_dsp($d1);
end;
function speaker_off:byte;
begin
write_dsp($d3);
end;
procedure dma_continue;
begin
playing_till:=since_midnight+playing_till;
write_dsp($d4);
end;
procedure dma_pause;
begin
playing_till:=playing_till-since_midnight;
write_dsp($d0);
end;
procedure play_back(sound:pointer;size:word;frequency:word);
var
time_constant:word;
page:word;
offset:word;
begin
speaker_on;
size:=size-1;
{ set up the dma chip }
offset:=seg(sound^)shl 4+ofs(sound^);
page:=(seg(sound^)+ofs(sound^)shr 4)shr 12;
port[$0a]:=5;
port[$0c]:=0;
port[$0b]:=$49;
port[$02]:=lo(offset);
port[$02]:=hi(offset);
port[$83]:=page;
port[$03]:=lo(size);
port[$03]:=hi(size);
port[$0a]:=1;
{ set the playback frequency }
time_constant:=256-1000000 div frequency;
write_dsp($40);
write_dsp(time_constant);
{ set the playback type (8-bit) }
write_dsp($14);
write_dsp(lo(size));
write_dsp(hi(size));
end;
procedure play_voc(filename:string;buf:pointer);
var
f:file;
s:word;
freq:word;
h:record
signature:array[1..20]of char;
data_start:word;
version:integer;
id:integer;
end;
d:record
id:byte;
len:array[1..3]of byte;
sr:byte;
pack:byte;
end;
begin
{$i-}
{ if pos('.',filename)=0 then filename:=filename+'.voc';}
assign(f,filename);
reset(f,1);
blockread(f,h,26);
blockread(f,d,6);
freq:=round(1000000/(256-d.sr));
s:=ord(d.len[3])+ord(d.len[2])*256+ord(d.len[1])*256*256;
{ writeln('-----------header----------');
writeln('signature: ', h.signature);
writeln('data_start: ', h.data_start);
writeln('version: ', hi(h.version), '.', lo(h.version));
writeln('id: ', h.id);
writeln;
writeln('------------data-----------');
writeln('id: ', d.id);
writeln('len: ', s);
writeln('sr: ', d.sr);
writeln('freq: ', freq);
writeln('pack: ', d.pack);}
blockread(f,buf^,s);
close(f);
{$i-}
if ioresult<>0 then
begin
writeln('Can''t find voc file "',filename,'".');
halt(1);
end;
playing_till:=since_midnight+round(s/freq*18.20648193);
play_back(buf,s,freq);
end;
function done_playing:boolean;
begin
done_playing:=since_midnight>playing_till;
end;
function play_raw(filename:string;buf:pointer):word;
var
f:file;
s:word;
head:idSound;
begin
play_raw:=0;
if pos('.',filename)=0 then filename:=filename+'.raw';
assign(f,filename);
{$i-} reset(f,1); {$i+}
if(ioresult<>0)then
exit;
blockread(f,head,sizeof(head));
if(maxavail<head.num_samples)then exit;
getmem(buf,head.num_samples);
s:=head.num_samples;
blockread(f,buf^,s);
close(f);
play_back(buf,s,head.rate);
playing_till:=since_midnight+round(s/head.rate*18.20648193);
play_raw:=head.num_samples;
freemem(buf,head.num_samples);
end;
begin
if not reset_dsp(2)then
begin
writeln('SoundBlaster not found at 220h');
halt(1);
end else writeln('SoundBlaster found at 220h');
end.
{ ------------------------ DEMO --------------------- }
uses utils,vocdecl;
var
buf:pointer;
begin
if(paramcount<1)then
begin
writeln('Syntax: P [file].voc');
halt;
end;
getmem(buf,fsize(paramstr(1)));
play_voc(paramstr(1),buf);
end.
[Back to SOUND SWAG index] [Back to Main SWAG index] [Original]