home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / hacking / phreak_utils_pc / sbvoice.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-04-01  |  7.6 KB  |  301 lines

  1. { --------------------------------------------------------------------------
  2.  
  3.                                SBVoice v2.15
  4.  
  5.      A collection of kick-ass routines to load, save, play and make .voc
  6.    files with a soundblaster ct-voice driver. Based on voc2exe (c) 1990 by
  7.   me. A whole lot of werk went into those routines, and they were gradually
  8.   improved over the years. If you have to rip em off, give me proper credit.
  9.  
  10.                  Copyright (C) 1991-1995 by Onkel Dittmeyer
  11.  
  12.   -------------------------------------------------------------------------- }
  13.  
  14. unit SBVoice;
  15. interface
  16. type VOCHDR = record
  17.                   id           :array[0..19] of char;
  18.                   voice_offset,
  19.                   version,
  20.                   check_code   :word;
  21.                 end;
  22.      blocktype=array[0..63999] of byte;
  23.      voicefile=record
  24.                    lastblock :byte;
  25.                    lastlength:word;
  26.                    data      :array[0..10] of ^blocktype;
  27.                  end;
  28.  
  29. const driversize = 2493; { standard 1.0 ct-voice.drv is 2493 bytes.. }
  30.  
  31. var f                             :file;
  32.     res,status                    :word;
  33.     p                             :voicefile;
  34.     size                          :longint;
  35.     pofs,pseg,statusofs,statusseg :word;
  36.     lastblock                     :byte;
  37.  
  38. function  DriverVersion:string;
  39. function  InitBlaster(sbint,adress:word):byte;
  40. procedure LoadVoice(vfile:string;var p:voicefile;start:longint);
  41. procedure PlayVoice(p:voicefile);
  42. procedure KillVoice(var p:voicefile);
  43. procedure FixDriver(drvfile:string;drvpos:longint);
  44. procedure FinishBlaster;
  45. procedure RemoveDriver;
  46. procedure Speaker(onoff:word);
  47. procedure StopIO;
  48. procedure SampleInput(buffer:pointer;buffersize:longint;samplerate:word);
  49. procedure RecordVoice(szFilename:string;samplerate:word;time:word);
  50.  
  51. implementation
  52.  
  53. uses dos,crt,extras,optimer,ferror,sos;
  54.  
  55. type drivertype=array[0..3000] of byte;
  56.  
  57. var x      :integer;
  58.     driver :^drivertype;
  59.  
  60. function st(x:integer):string;
  61. var dummy :string;
  62. begin
  63.   str(x,dummy);
  64.   st:=dummy;
  65. end;
  66.  
  67. function DriverVersion:string;
  68. var x,y   :byte;
  69.     xs,ys :string;
  70. begin
  71.   asm
  72.     mov bx,0
  73.     call driver
  74.     mov x,ah
  75.     mov y,al
  76.   end;
  77.   str(x,xs);
  78.   str(y,ys);
  79.   DriverVersion:=xs+'.'+ys;
  80. end;
  81.  
  82. function InitBlaster(sbint,adress:word):byte;
  83. var err:word;
  84. begin
  85.   asm
  86.     mov bx,1
  87.     mov ax,adress
  88.     call driver
  89.     mov bx,2
  90.     mov ax,sbint
  91.     call driver
  92.     mov bx,3
  93.     call driver
  94.     mov err,ax
  95.   end;
  96.   initblaster:=err;
  97. end;
  98.  
  99. procedure FinishBlaster;
  100. begin
  101.   asm
  102.     mov bx,9
  103.     call driver
  104.   end;
  105. end;
  106.  
  107. procedure LoadVoice(vfile:string;var p:voicefile;start:longint);
  108. begin
  109.   if not sosexist(vfile) then fatalerror('Error opening sample ['+uppercase(vfile)+']: not in database!');
  110.   size:=sosbfsize(vfile);
  111.   sosopen;
  112.   sosfopen(vfile);
  113.   sosseek($1A+start);
  114.   x:=-1;
  115.   repeat
  116.     inc(x);
  117.     getmem(p.data[x],64000);
  118.     sosblockread(p.data[x],64000,res);
  119.   until res<>64000;
  120.   sosclose;
  121.   p.lastlength:=res;
  122.   p.lastblock:=x;
  123. end;
  124.  
  125. procedure KillVoice(var p:voicefile);
  126. var x:byte;
  127. begin
  128.   for x:=0 to p.lastblock do dispose(p.data[x]);
  129. end;
  130.  
  131. procedure PlayVoice(p:voicefile);
  132. begin
  133.   statusofs:=ofs(status); statusseg:=seg(status);
  134.   asm
  135.     mov bx,5
  136.     mov es,statusseg
  137.     mov di,statusofs
  138.     call driver
  139.   end;
  140.   for x:=0 to p.lastblock do begin
  141.     pofs:=ofs(p.data[x]^); pseg:=seg(p.data[x]^);
  142.     asm
  143.       mov bx,6
  144.       mov es,pseg
  145.       mov di,pofs
  146.       call driver
  147.     end;
  148.   end;
  149. end;
  150.  
  151. procedure FixDriver(drvfile:string;drvpos:longint);
  152. begin
  153.   if not sosexist(drvfile) then fatalerror('Sound Card Driver ['+uppercase(drvfile)+'] not in database!');
  154.   sosopen;
  155.   sosfopen(drvfile);
  156.   sosseek(drvpos);
  157.   getmem(driver,driversize);
  158.   sosread(driver,driversize);
  159.   sosclose;
  160. end;
  161.  
  162. procedure RemoveDriver;
  163. begin
  164.   freemem(driver,driversize);
  165. end;
  166.  
  167. procedure Speaker(onoff:word);
  168. begin
  169.   asm
  170.     mov bx,4
  171.     mov ax,onoff
  172.     call driver
  173.   end;
  174. end;
  175.  
  176. procedure StopIO;
  177. begin
  178.   asm
  179.     mov bx,8
  180.     call driver
  181.   end;
  182.   if status<>0 then begin
  183.     writeln('I/O IS UNSTOPPABLE! HERE GOES WERLD PEACE! #HACK IN uPRoAr! AaarghL!');
  184.     halt($ff);
  185.   end;
  186. end;
  187.  
  188. procedure sampleinput(buffer:pointer;buffersize:longint;samplerate:word);
  189. var es_tmp,di_tmp,dx_tmp,cx_tmp :word;
  190.     bstemp                      :longint;
  191. begin
  192.   statusofs:=ofs(status); statusseg:=seg(status);
  193.   asm
  194.     mov bx,5
  195.     mov es,statusseg
  196.     mov di,statusofs
  197.     call driver
  198.   end;
  199.   bstemp:=buffersize;
  200.   es_tmp:=seg(buffer^);
  201.   di_tmp:=ofs(buffer^);
  202.   cx_tmp:=memw[seg(bstemp):ofs(bstemp)];
  203.   dx_tmp:=memw[seg(bstemp):ofs(bstemp)+2];
  204.   asm
  205.     mov bx,7
  206.     mov ax,samplerate
  207.     mov dx,dx_tmp
  208.     mov cx,cx_tmp
  209.     mov es,es_tmp
  210.     mov di,di_tmp
  211.     call driver
  212.   end;
  213. end;
  214.  
  215. function WriteToFile(var f:file;lpBuf:pointer;lsize:longint):boolean;
  216. type PtrRec = record lo,hi:word; end;
  217. var wByteToWrite,wByteWritten,wTemp :word;
  218. begin
  219.   WriteToFile:=True;
  220.   wTemp:=0;
  221.   repeat
  222.     wByteToWrite:=$8000;
  223.     if lSize<$8000 then wByteToWrite:=Word(lSize);
  224.     BlockWrite(F,lpBuf^,wByteToWrite,wByteWritten);
  225.     if wByteWritten<>wByteToWrite then begin
  226.       writeln('d00d... l1k3 y0uR hDd is fU11 0r s0meTh1nG... tHaT sUx d00d.');
  227.       WriteToFile := False;
  228.       lSize := 0;
  229.     end else begin
  230.       wTemp:=wTemp+wByteWritten;
  231.       PtrRec(lpBuf).lo:=PtrRec(lpBuf).lo+wByteWritten;
  232.       if not Boolean(Hi(wTemp)) then PtrRec(lpBuf).hi:=PtrRec(lpBuf).hi+$1000;
  233.       lSize:=lSize-wByteWritten;
  234.     end;
  235.   until not boolean(Lo(word(lSize)));
  236. end;
  237.  
  238. function Recording(lpBuf:pointer;lpBufSize:longint;samplerate:word;time:word):Boolean;
  239. begin
  240.   Recording:=False;
  241.   speaker(0);
  242.   sampleinput(lpBuf,lpBufSize,samplerate);
  243.   Recording:=True;
  244.   if time=0 then repeat until keypressed xor (status<>$ffff) else delayms(time);
  245.   stopio;
  246. end;
  247.  
  248. procedure SaveVoiceFile(szFilename:string;lpBuf:pointer);
  249. var  F                :file;
  250.     lVoiceSize, lTemp :longint;
  251.     header            :VOCHDR;
  252.     dummy             :boolean;
  253.     S                 :String[20];
  254. begin
  255.   S:='Creative Voice File';
  256.   move( S[1], header.id,20);
  257.   header.id[19]:=#26;
  258.   header.voice_offset:=SizeOf(VOCHDR);
  259.   header.version:=$010a;
  260.   header.check_code:=$1129;
  261.   {$I-}
  262.   Assign(F,szFilename);
  263.   Rewrite(F,1);
  264.   {$I+}
  265.   if IOResult=0 then begin
  266.     if WriteToFile(F,@header,longint(SizeOf(VOCHDR))) then begin
  267.       lVoiceSize:=longint(pointer(longint(lpBuf)+1)^);
  268.       lVoiceSize:=lVoiceSize and $00ffffff;
  269.       { add 5 bytes for the bloack header and terminating block }
  270.       lVoiceSize:=lVoiceSize+5;
  271.       dummy:=WriteToFile(F,lpBuf,lVoiceSize);
  272.     end;
  273.     Close(F);
  274.   end else writeln('Create ',szFilename,' error.');
  275. end;
  276.  
  277. procedure RecordVoice(szFilename:string;samplerate:word;time:word);
  278. var lpVoiceBuf, lpTmpPtr, lpMarkPtr :pointer;
  279.                            lBufSize :longint;
  280. begin
  281.   { allocate memory 128 KB memory }
  282.   Mark(lpMarkPtr);
  283.   GetMem(lpVoiceBuf,$ffff);
  284.   GetMem(lpTmpPtr,$ffff);
  285.   if (lpVoiceBuf<>nil) and (lpTmpPtr<>nil) then begin
  286.       lBufSize := $ffff + $ffff;
  287.       if Recording(lpVoiceBuf,lBufSize,samplerate,time) then
  288.         SaveVoiceFile(szFilename,lpVoiceBuf);
  289.   end else writeln('Memory allocation error ...');
  290.   { release allocated memory }
  291.   Release(lpMarkPtr);
  292. end;
  293.  
  294. begin
  295.   if paramstr(1)='/(C)' then begin
  296.     writeln('SBVOICE.PAS  v2.15  SoundBlaster VOC and Driver Load/Play/Rec Stuff');
  297.     writeln('                    Copyright (C) 1991-1995 by Onkel Dittmeyer');
  298.     writeln;
  299.     readln;
  300.   end;
  301. end.