home *** CD-ROM | disk | FTP | other *** search
/ Audio 4.94 - Over 11,000 Files / audio-11000.iso / msdos / sndbords / proaudio / tp_int94 / tp_int94.arj / TESTIT.PAS < prev   
Pascal/Delphi Source File  |  1993-12-13  |  10KB  |  243 lines

  1. {-----------------------------------------------------------------------------}
  2. {  Test program for the MVInt94 unit.                                         }
  3. {  This is a very simple program to test the functionality of the MVInt94     }
  4. {  unit.  If PCM.COM is loaded, it will play the file specified on the        }
  5. {  command line.  If the file is not a wave file, it defaults to 44.1khz, 16  }
  6. {  bit mono.  You can change that using the constants below.                  }
  7. {                                                                             }
  8. { Copyright 1993, Peter W. Cervasio                                           }
  9. {-----------------------------------------------------------------------------}
  10. PROGRAM TestPCM;
  11. {$I mvInt94.def}    { compiler flags }
  12.  
  13. USES
  14.     Dos,            { need some dos functionality }
  15.     Crt,            { want our screen writes to be faster }
  16.     Strings,        { using some nul terminated strings }
  17.     MVInt94;        { the int 94 interface unit }
  18.  
  19. CONST
  20.     DMADivisions = 4;       { number of partitions in our DMA buffer }
  21.     DMADivSize   = 8192;    { size of each DMA buffer partition }
  22.  
  23.     DefaultRate = 44100;    { default values used if the file to play is not }
  24.     DefaultBits = 16;       { a wave file.  If you want this to play .voc files }
  25.     DefaultChan = 1;        { you'll have to make it do so yourself... this is }
  26.                             { just a demonstration of how to use PCM.COM }
  27.  
  28. TYPE
  29.     Partition = Array[1..DMADivSize] of byte;
  30.     MemArray = Array[1..DMADivisions] of Partition;
  31.     MPtr = ^MemArray;
  32.  
  33. VAR
  34.     MyDMA       : DMABufType;       { record to pass to DMABuffer() }
  35.     MyBuff      : MPtr;             { Pointer to my buffer }
  36.     I           : Word;             { General counter variable }
  37.     OldCounter  : Word;             { local counter to compare with DMACounter }
  38.     InpFile     : File;             { our input file }
  39.     Done        : Boolean;          { says we're done reading from inpfile }
  40.     JunkPtr     : Pointer;          { general handy pointer for stuff }
  41.     TotalBlocks : LongInt;          { Total number of blocks in file }
  42.     WaveHeader  : WaveHeaderType;   { wavefile header }
  43.  
  44. { Read in a DMA partition.  NumRead will return the number of bytes read }
  45. { from the file.  If it's less than what we asked for, then we're done   }
  46. { with the file, and can wait for the PCM routines to be finished with   }
  47. { what's already been read.                                              }
  48. PROCEDURE FillDMASection (Counter: Word; VAR Done: Boolean);
  49. VAR
  50.     NumRead : Word;
  51. BEGIN
  52.     BlockRead (InpFile, MyBuff^[Counter], DmaDivSize, NumRead);
  53.     if NumRead < DmaDivSize then
  54.     begin
  55.         Done := True;           { flag that we're done and }
  56.                                 { fill the rest of the buffer with silence }
  57.         if WaveHeader.SampleSize = 16 then
  58.             FillChar (MyBuff^[Counter,NumRead], DMADivSize - NumRead, $00)
  59.         else
  60.             FillChar (MyBuff^[Counter,NumRead], DMADivSize - NumRead, $80);
  61.     end;
  62. END;
  63.  
  64. { Quick way out... free our buffer if needed, do a RemovePCM and halt }
  65. PROCEDURE GetOutOfProgram;
  66. BEGIN
  67.     if assigned(MyBuff) then FreeMem(MyBuff, DMADivisions * DMADivSize);
  68.     RemovePCM;
  69.     Halt(1);
  70. END;
  71.  
  72. { Open the input file.  If it isn't found, then exit the program.  If we're }
  73. { playing a wave file, get the information from the file regarding sample   }
  74. { rate and size, and whether it mono or stereo.  If it's not, assume it a   }
  75. { raw PCM file and use the defaults defined above for sample rate, etc.     }
  76. { We use the WaveHeader record in either case to hold the information.      }
  77. PROCEDURE OpenInputFile (S : String);
  78. VAR
  79.     TmpBuff : Array[0..4] of char;
  80.     Result  : Word;
  81. BEGIN
  82.     Assign (InpFile, S);
  83.     {$I-}
  84.     Reset (InpFile, 1);
  85.     {$I+}
  86.     IF IOResult <> 0 then
  87.     begin
  88.         Writeln ('Input file not found');
  89.         GetOutOfProgram;
  90.     end;
  91.     BlockRead (InpFile, TmpBuff, 4, Result);
  92.     if Result < 4 then
  93.     begin
  94.         Writeln ('Unexpected end of file.');
  95.         Close (InpFile);
  96.         GetOutOfProgram;
  97.     end;
  98.     TmpBuff[4] := #0;
  99.  
  100.     if StrComp(TmpBuff, 'RIFF') <> 0 then
  101.     begin
  102.         seek (InpFile, 0);
  103.         FillChar (WaveHeader, SizeOF(WaveHeader), 0);
  104.         WaveHeader.SampleRate := DefaultRate;
  105.         WaveHeader.SampleSize := DefaultBits;
  106.         WaveHeader.Channels := DefaultChan;
  107.         WaveHeader.WaveLength := FileSize (InpFile);
  108.     end
  109.     else
  110.     begin
  111.         seek (InpFile, 0);
  112.         { This isn't a good way to do it... there may be extra junk in the }
  113.         { header because of other programs messing it up.  This is just a  }
  114.         { quick and dirty example program, though, so I'm not bothering to }
  115.         { do checks and all that stuff.                                    }
  116.         BlockRead (InpFile, WaveHeader, SizeOF(WaveHeader), Result);
  117.         if Result <> SizeOF (WaveHeader) then
  118.         begin
  119.             Writeln ('Unexpected end of file.');
  120.             Close (InpFile);
  121.             GetOutOfProgram;
  122.         end;
  123.     end;
  124.     TotalBlocks := WaveHeader.Wavelength div DMADivSize;
  125.     if WaveHeader.Wavelength mod DMADivSize <> 0 then inc (TotalBlocks);
  126. END;
  127.  
  128. {===============================[ Fly or Die ]================================}
  129. {            -|-                                               -|-            }
  130. {    -----===<*>===----- MAIN PROGRAM LOOP STARTS HERE -----===<*>===-----    }
  131. {         o/     \o                                          o/   \o          }
  132. {=============================================================================}
  133.  
  134. BEGIN
  135.     { Check to see if we were given a file name to play }
  136.     if ParamCount < 1 then
  137.     begin
  138.         Writeln ('TESTPCM filename.ext');
  139.         Writeln ('   Please supply a file name to play.  Thanks.');
  140.         halt(1);
  141.     end;
  142.  
  143.     { Okay, try to open it and get sample rate, etc. }
  144.     OpenInputFile (ParamStr(1));
  145.  
  146.     { According to Bart Crane at Media Vision, this isn't needed, but I am }
  147.     { using it anyway.  It didn't hurt when I left it out, though...       }
  148.     JunkPtr := InitMVSound;
  149.     if not Assigned(JunkPtr) then
  150.     begin
  151.         Writeln ('InitMVSound failed...');
  152.         Halt(1);            { don't need to use GetOutOfProgram yet }
  153.     end;
  154.  
  155.     I := InitPCM;
  156.     if I = 0 then
  157.     begin
  158.         Writeln ('InitPCM failed...');
  159.         Halt(1);            { or here either }
  160.     end;
  161.  
  162.     { Allocate our DMA buffer, making sure not to cross a 64k boundary }
  163.     AllocateDMABuffer (JunkPtr, DMADivisions * DMADivSize);
  164.  
  165.     { Okay, tell the tsr about it }
  166.     MyBuff := MPtr(JunkPtr);
  167.     MyDMA.DMABuffer := MyBuff;
  168.     MyDMA.BufKBSize := DMADivisions * DMADivSize div 1024;
  169.     MyDMA.Partitions := DMADivisions;
  170.     JunkPtr := DMABuffer(MyDMA);
  171.     if not assigned(JunkPtr) then
  172.     begin
  173.         Writeln ('DMA Buffer setup failed');
  174.         GetOutOfProgram;
  175.     end;
  176.  
  177.     { Okay, fill up our DMA partitions.  We'll set the counter to 0 when we }
  178.     { get ready to play, so when it starts incrementing it will tell us the }
  179.     { #1 partition needs to be filled.                                      }
  180.     Done := False;
  181.     For I := 1 to DMADivisions do
  182.         if not Done then FillDMASection (I, Done);
  183.     DMACounter := 0; OldCounter := 0;
  184.  
  185.     { Set up the DMA interrupt callback routine, using one defined in the  }
  186.     { MVInt94 unit.  Due to the way I'm accessing the pointer in the unit  }
  187.     { we have to pass UserFunc a pointer that points to the procedure, not }
  188.     { just the address of the function.  That may be fixed in the future.  }
  189.     JunkPtr := UserFunc (EZDMA);
  190.     if not assigned(JunkPtr) then
  191.     begin
  192.         Writeln ('User Function setup failed');
  193.         GetOutOfProgram;
  194.     end;
  195.  
  196.     PausePCM;           { Tell the PCM routines that we're paused. }
  197.  
  198.  
  199.     { Set the sample rate, size, etc. }
  200.     I := SetPCMInfo(WaveHeader.SampleSize, WaveHeader.Channels-1,
  201.                     WaveHeader.SampleRate);
  202.     if I <> 0 then
  203.     begin
  204.         Writeln ('SetPCMInfo failed.');
  205.         GetOutOfProgram;
  206.     end;
  207.  
  208.  
  209.     I := PCMPlay;       { Okay, now tell it we're going to be playing }
  210.     if I <> 0 then
  211.     begin
  212.         Writeln ('PCMPlay failed... it returned ', I);
  213.         GetOutOfProgram;
  214.     end;
  215.  
  216.     
  217.     ResumePCM;          { Let's have some sound come out of the card now... }
  218.  
  219.     repeat
  220.         if KeyPressed then if ReadKey = #27 then    { if ESC pressed }
  221.         begin
  222.             Close (Inpfile);                        { close our input file }
  223.             StopPCM;                                { stop playing the data }
  224.             GetOutOfProgram;                        { and get out of the program }
  225.         end;
  226.         if DMACounter <> OldCounter then            { if it's changed }
  227.         begin
  228.             Dec (TotalBlocks);                      { decrement total counter }
  229.             if DMACounter > DMADivisions then
  230.                 DMACounter := 1;                    { handle loop around }
  231.             OldCounter := DMACounter;               { save it for next time }
  232.             if not done then
  233.                 FillDMASection (DMACounter, Done);  { fill buffer if some left }
  234.         end;
  235.     until TotalBlocks = 0;                          { we've played all of it! }
  236.  
  237.     StopPCM;                                        { stop the playback }
  238.     Close (InpFile);                                { Close the file }
  239.     RemovePCM;                                      { and we're done }
  240.     Freemem (MyBuff, DMADivSize * DMADivisions);    { free up our DMA buffer }
  241. END.
  242.  
  243.