home *** CD-ROM | disk | FTP | other *** search
/ Intermedia 1998 January / inter1_98.iso / www / rozi / VOC2.ZIP / PLAY.PAS < prev    next >
Pascal/Delphi Source File  |  1997-01-18  |  4KB  |  150 lines

  1. unit play;
  2. interface
  3. function reset_dsp(base : word) : boolean;
  4. procedure write_dac(level : byte);
  5. function read_dac : byte;
  6. function speaker_on: byte;
  7. function speaker_off: byte;
  8. procedure dma_pause;
  9. procedure dma_continue;
  10. procedure play_back(sound : pointer; size : word; frequency : word);
  11. procedure play_voc(filename : string; buf : pointer);
  12. function playing_voc : boolean;
  13. implementation
  14. uses crt;
  15. var dsp_reset        : word;
  16.     dsp_read_data    : word;
  17.     dsp_write_data   : word;
  18.     dsp_write_status : word;
  19.     dsp_data_avail   : word;
  20.     since_midnight   : longint absolute $40:$6C;
  21.     playing_till     : longint;
  22. function reset_dsp(base : word) : boolean;
  23. begin
  24.  base := base * $10;
  25.  dsp_reset        := base + $206;
  26.  dsp_read_data    := base + $20a;
  27.  dsp_write_data   := base + $20c;
  28.  dsp_write_status := base + $20c;
  29.  dsp_data_avail   := base + $20e;
  30.  port[dsp_reset] := 1;
  31.  delay(10);
  32.  port[dsp_reset] := 0;
  33.  delay(10);
  34.  reset_dsp := (port[dsp_data_avail] and $80 = $80) and
  35.               (port[dsp_read_data] = $aa);
  36. end;
  37. procedure write_dsp(value : byte);
  38. begin
  39.  while port[dsp_write_status] and $80 <> 0 do;
  40.  port[dsp_write_data] := value;
  41. end;
  42. function read_dsp : byte;
  43. begin
  44.  while port[dsp_data_avail] and $80 = 0 do;
  45.  read_dsp := port[dsp_read_data];
  46. end;
  47. procedure write_dac(level : byte);
  48. begin
  49.  write_dsp($10);
  50.  write_dsp(level);
  51. end;
  52. function read_dac : byte;
  53. begin
  54.  write_dsp($20);
  55.  read_dac := read_dsp;
  56. end;
  57. function speaker_on: byte;
  58. begin
  59.  write_dsp($d1);
  60. end;
  61. function speaker_off: byte;
  62. begin
  63.  write_dsp($d3);
  64. end;
  65. procedure dma_continue;
  66. begin
  67.  playing_till := since_midnight + playing_till;
  68.  write_dsp($d4);
  69. end;
  70. procedure dma_pause;
  71. begin
  72.  playing_till := playing_till - since_midnight;
  73.  write_dsp($d0);
  74. end;
  75. procedure play_back(sound : pointer; size : word; frequency : word);
  76. var time_constant : word;
  77.     page          : word;
  78.     offset        : word;
  79. begin
  80.  speaker_on;
  81.  size := size - 1;
  82.  offset := seg(sound^) shl 4 + ofs(sound^);
  83.  page := (seg(sound^) + ofs(sound^) shr 4) shr 12;
  84.  port[$0a] := 5;
  85.  port[$0c] := 0;
  86.  port[$0b] := $49;
  87.  port[$02] := lo(offset);
  88.  port[$02] := hi(offset);
  89.  port[$83] := page;
  90.  port[$03] := lo(size);
  91.  port[$03] := hi(size);
  92.  port[$0a] := 1;
  93.  time_constant := 256 - 1000000 div frequency;
  94.  write_dsp($40);
  95.  write_dsp(time_constant);
  96.  write_dsp($14);
  97.  write_dsp(lo(size));
  98.  write_dsp(hi(size));
  99. end;
  100. procedure play_voc(filename : string; buf : pointer);
  101. var f : file;
  102.     s : word;
  103.  
  104.     freq : word;
  105.     h : record
  106.          signature  : array[1..20] of char; { vendor's name }
  107.          data_start : word;                 { start of data in file }
  108.          version    : integer;              { min. driver version required }
  109.          id         : integer;              { 1 - complement of version field
  110. +$1234 }        end;                                { used to indentify a .voc
  111. file }
  112.     d : record
  113.          id   : byte;                { = 1 }
  114.          len  : array[1..3] of byte; { length of voice data (len data + 2) }
  115.          sr   : byte;                { sr = 256 - (1,000,000 / sampling rate) }
  116.          pack : byte;                { 0 : unpacked, 1 : 4-bit, 2 : 2.6 bit, 3:
  117. 2 bit packed }        end;
  118. begin
  119.  {$i-}
  120.  if pos('.', filename) = 0 then filename := filename + '.voc';
  121.  assign(f, filename);
  122.  reset(f, 1);
  123.  blockread(f, h, 26);
  124.  blockread(f, d, 6);
  125.  freq := round(1000000 / (256 - d.sr));
  126.  s    := ord(d.len[3]) + ord(d.len[2]) * 256 + ord(d.len[1]) * 256 * 256;
  127.  blockread(f, buf^, s);
  128.  close(f);
  129.  {$i-}
  130.  if ioresult <> 0 then
  131.   begin
  132.    writeln('Can''t find voc file "' + filename + '"');
  133.    halt(1);
  134.   end;
  135.  playing_till := since_midnight + round(s / freq * 18.20648193);
  136.  play_back(buf, s, freq);
  137. end;
  138. function playing_voc : boolean;
  139. begin
  140.  playing_voc := since_midnight > playing_till;
  141. end;
  142. begin
  143.  if not reset_dsp(2) then
  144.   begin
  145.    writeln('SoundBlaster not found at 220h');
  146.    halt(1);
  147.   end
  148.  else
  149.   writeln('SoundBlaster found at 220h');
  150. end.