home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Intermedia 1998 January
/
inter1_98.iso
/
www
/
rozi
/
VOC2.ZIP
/
PLAY.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1997-01-18
|
4KB
|
150 lines
unit play;
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 playing_voc : boolean;
implementation
uses crt;
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;
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;
time_constant := 256 - 1000000 div frequency;
write_dsp($40);
write_dsp(time_constant);
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; { vendor's name }
data_start : word; { start of data in file }
version : integer; { min. driver version required }
id : integer; { 1 - complement of version field
+$1234 } end; { used to indentify a .voc
file }
d : record
id : byte; { = 1 }
len : array[1..3] of byte; { length of voice data (len data + 2) }
sr : byte; { sr = 256 - (1,000,000 / sampling rate) }
pack : byte; { 0 : unpacked, 1 : 4-bit, 2 : 2.6 bit, 3:
2 bit packed } 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;
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 playing_voc : boolean;
begin
playing_voc := since_midnight > playing_till;
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.