home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vpdart01.zip / PM / daudio.pas < prev    next >
Pascal/Delphi Source File  |  1998-07-17  |  9KB  |  338 lines

  1. Program DAudio;
  2. {$PMTYPE PM }{$S-}{$R *.RES}{&CDecl+}
  3. uses Use32,Os2Def,Os2PMApi,os2mm;
  4.  
  5.  
  6. const
  7.   ID_DIALOG      = 100;
  8.   ID_PLAY        = 101;
  9.   ID_RECORD      = 102;
  10.   ID_STOP        = 103;
  11.   ID_ICON        = 104;
  12.   STRING_LENGTH  = 128;
  13.   MAX_BUFFERS    = 256;
  14.   DEFAULT_FILE = 'daudio.wav';
  15.  
  16. var
  17.   hwndFrame        : HWND;         (* Dialog fram window id   *)
  18.  
  19. {$I DART.INC}
  20.  
  21. (***************************************************************************
  22.  * Name        : LoadFile
  23.  *
  24.  * Description : Allocate application buffers for audio file and load
  25.  *         audio file. These buffers will be copied to device
  26.  *         buffers by another thread.
  27.  *
  28.  *         Before this procedure loads the audio file, the global
  29.  *         MixSetupParms data structure is loaded with information
  30.  *         from the audio files header.
  31.  *
  32.  *
  33.  * Parameters  : CHAR szFilename[]     - Name of wave file to open
  34.  *
  35.  * Return      : BOOL    - TRUE    = failure
  36.  *            - FALSE = success
  37.  *
  38.  ***************************************************************************)
  39.  
  40. Function LoadFile( szFileName:PChar ):Boolean;
  41. var
  42.   mmioINFO        : OS2MM.MMIOINFO;
  43.   mmAudioHeader     : OS2MM.MMAUDIOHEADER;
  44.   hmmio         : OS2MM.HMMIO;
  45.   lBytesRead        : LONG;
  46.   ulBufferOffset    : LONG;
  47.   AmpOpenParms        : MCI_AMP_OPEN_PARMS;
  48.   rc, ulIndex        : ULONG;
  49. begin
  50.  
  51.   (* open the mixer device *)
  52.   fillchar( AmpOpenParms, sizeof( MCI_AMP_OPEN_PARMS ), 0 );
  53.   AmpOpenParms.usDeviceID := (* USHORT *) 0;
  54.   AmpOpenParms.pszDeviceType := PChar(MCI_DEVTYPE_AUDIO_AMPMIX);
  55.  
  56.   if not mciCommand( 0, MCI_OPEN, 
  57.             MCI_WAIT or MCI_OPEN_TYPE_ID or MCI_OPEN_SHAREABLE,
  58.             AmpOpenParms) then
  59.   begin
  60.     LoadFile := false;
  61.     exit;
  62.   end;
  63.  
  64.   usDeviceID := AmpOpenParms.usDeviceID;
  65.  
  66.   (* Open the audio file. *)
  67.  
  68.   fillchar( mmioInfo, sizeof( MMIOINFO ), 0 );
  69.   mmioInfo.fccIOProc := mmioFOURCC( 'W', 'A', 'V', 'E' );
  70.   hmmio := mmioOpen( szFileName, @mmioInfo, MMIO_READ or MMIO_DENYNONE );
  71.  
  72.   if hmmio=0 then begin
  73.  
  74.     WinMessageBox( HWND_DESKTOP,
  75.            HWND_DESKTOP,
  76.            'Unable to open wave file',
  77.            'MMIO Error',
  78.            0,
  79.            MB_OK or MB_ERROR or MB_MOVEABLE);
  80.  
  81.     LoadFile := false;
  82.     exit;
  83.   end;
  84.  
  85.   (* Get the audio file header. *)
  86.   mmioGetHeader( hmmio, @mmAudioHeader, sizeof( MMAUDIOHEADER ),
  87.          @lBytesRead, 0, 0);
  88.  
  89.   (* Set the MixSetupParms data structure to match the loaded file.
  90.    * This is a global that is used to setup the mixer. *)
  91.  
  92.   fillchar( MixSetupParms, sizeof( MCI_MIXSETUP_PARMS ), 0 );
  93.  
  94.   MixSetupParms.ulBitsPerSample :=
  95.     mmAudioHeader.mmXWAVHeader.WAVEHeader.usBitsPerSample;
  96.  
  97.   MixSetupParms.ulFormatTag :=
  98.     mmAudioHeader.mmXWAVHeader.WAVEHeader.usFormatTag;
  99.  
  100.   MixSetupParms.ulSamplesPerSec :=
  101.     mmAudioHeader.mmXWAVHeader.WAVEHeader.ulSamplesPerSec;
  102.  
  103.   MixSetupParms.ulChannels :=
  104.     mmAudioHeader.mmXWAVHeader.WAVEHeader.usChannels;
  105.  
  106.   (* Setup the mixer for playback of wave data *)
  107.   MixSetupParms.ulFormatMode := MCI_PLAY;
  108.   MixSetupParms.ulDeviceType := MCI_DEVTYPE_WAVEFORM_AUDIO;
  109.   MixSetupParms.pmixEvent    := MyEvent;
  110.  
  111.   if not mciCommand( usDeviceID, MCI_MIXSETUP,
  112.              MCI_WAIT or MCI_MIXSETUP_INIT, MixSetupParms) then
  113.   begin
  114.     LoadFile := false;
  115.     exit;
  116.   end;
  117.  
  118.   (* Use the suggested buffer size provide by the mixer device
  119.    * and the size of the audio file to calculate the required
  120.    * number of Amp-Mixer buffers.
  121.    * Note: The result is rounded up 1 to make sure we get the
  122.    *       tail end of the file.
  123.    *)
  124.   ulNumBuffers :=
  125.     mmAudioHeader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes
  126.     DIV MixSetupParms.ulBufferSize + 1;
  127.  
  128.  
  129.   (* Set up the BufferParms data structure and allocate
  130.    * device buffers from the Amp-Mixer
  131.    *)
  132.   BufferParms.ulNumBuffers := ulNumBuffers;
  133.   BufferParms.ulBufferSize := MixSetupParms.ulBufferSize;
  134.   BufferParms.pBufList := @MixBuffers;
  135.  
  136.   if not mciCommand( usDeviceID,
  137.             MCI_BUFFER,
  138.             MCI_WAIT or MCI_ALLOCATE_MEMORY,
  139.             BufferParms) then
  140.   begin
  141.     LoadFile := false;
  142.     exit;
  143.   end;
  144.  
  145.   (* Fill all device buffers with data from the audio file.
  146.    *)
  147.   for ulIndex := 0 to ulNumBuffers-1 do begin
  148.     fillchar( MixBuffers[ ulIndex ].pBuffer^, BufferParms.ulBufferSize, 0 );
  149.     MixBuffers[ ulIndex ].ulBufferLength := BufferParms.ulBufferSize;
  150.  
  151.     rc := mmioRead ( hmmio,
  152.              MixBuffers[ ulIndex ].pBuffer,
  153.              MixBuffers[ ulIndex ].ulBufferLength );
  154.  
  155.   end;
  156.  
  157.   (* Set the "end-of-stream" flag
  158.    *)
  159.   MixBuffers[ulNumBuffers - 1].ulFlags := MIX_BUFFER_EOS;
  160.  
  161.   mmioClose( hmmio, 0 );
  162.  
  163.   LoadFile := true;
  164. end;
  165.  
  166.  
  167. (***************************************************************************
  168.  * Name        : MainDialogProc
  169.  *
  170.  * Description : This function controls the main dialog box.  It will handle
  171.  *         received messages such as pushbutton notifications, and
  172.  *         entry field messages.
  173.  *
  174.  *
  175.  ***************************************************************************)
  176. const
  177.   hwndPlayButton    : OS2Def.HWND = NULLHANDLE;
  178.   hwndRecordButton    : OS2Def.HWND = NULLHANDLE;
  179.   hwndStopButton    : OS2Def.HWND = NULLHANDLE;
  180.   fPassedDevice     : BOOLEAN = TRUE;
  181.   fRecording        : BOOLEAN = FALSE;
  182.  
  183.  
  184.  
  185. Function MainDialogProc( hwnd : HWND;
  186.              msg  : ULONG;
  187.              mp1  : MPARAM;
  188.              mp2  : MPARAM ) : MRESULT;
  189. var
  190.   GenericParms        : MCI_GENERIC_PARMS;
  191.   ulIndex,rc        : ULONG;
  192. begin
  193.   case msg of
  194.     WM_INITDLG: begin
  195.       (* Get the handles for the PLAY and RECORD buttons
  196.        *)
  197.       hwndPlayButton := WinWindowFromID( hwnd, ID_PLAY );
  198.       hwndRecordButton := WinWindowFromID( hwnd, ID_RECORD );
  199.       hwndStopButton := WinWindowFromID( hwnd, ID_STOP );
  200.  
  201.       (* Disable the stop button
  202.        *)
  203.       WinEnableWindow( hwndStopButton, FALSE );
  204.  
  205.       (* Load the audio file and setup for playback.
  206.        *)
  207.       
  208.       if not LoadFile( DEFAULT_FILE ) then WinPostMsg( hwnd, WM_QUIT, 0, 0 );
  209.     end;
  210.     MM_MCIPASSDEVICE: begin
  211.  
  212.       (* Check if we are gaining or passing use of the amp-mixer device
  213.        *)
  214.       if SHORT1FROMMP( mp2 ) = MCI_GAINING_USE then
  215.      fPassedDevice := FALSE
  216.       else
  217.      fPassedDevice := TRUE;
  218.  
  219.     end;
  220.  
  221.     WM_ACTIVATE: begin
  222.  
  223.       (* Check if this window is the active window and if we have passed
  224.        * use of the Amp-Mixer device. If yes, then send MCI_ACQUIREDEVICE
  225.        * message. *)
  226.       if Boolean( mp1 ) and fPassedDevice then begin
  227.  
  228.      GenericParms.hwndCallback := hwnd;
  229.  
  230.      mciCommand( usDeviceID, MCI_ACQUIREDEVICE,
  231.              MCI_NOTIFY or MCI_ACQUIRE_QUEUE,GenericParms);
  232.       end;
  233.     end;
  234.  
  235.     WM_COMMAND: case SHORT1FROMMP ( mp1 ) of
  236.  
  237.       ID_PLAY: begin
  238.  
  239.      (* Disable the play and record buttons
  240.       * Enable the stop button.
  241.       *)
  242.      WinEnableWindow( hwndPlayButton, FALSE );
  243.      WinEnableWindow( hwndRecordButton, FALSE );
  244.      WinEnableWindow( hwndStopButton, TRUE );
  245.  
  246.      StartPlayBack;
  247.  
  248.      MainDialogProc := MRESULT( FALSE );
  249.      exit;
  250.       end;
  251.  
  252.       ID_RECORD: begin
  253.      (* The new recording will overwrite the file that was loaded
  254.       * at the start of the program. If the user presses the PLAY
  255.       * button, the newly recorded file will be played.
  256.       *)
  257.      if ResetRecord then begin
  258.         fRecording := TRUE;       
  259.         (* Disable the play and record buttons
  260.          * Enable the stop button. *)
  261.         WinEnableWindow( hwndPlayButton, FALSE );
  262.         WinEnableWindow( hwndRecordButton, FALSE );
  263.         WinEnableWindow( hwndStopButton, TRUE );
  264.       end;
  265.      MainDialogProc := MRESULT( FALSE );
  266.          exit;
  267.       end;
  268.  
  269.       ID_STOP: begin
  270.      { Send message to stop the audio device }
  271.      mciCommand( usDeviceID, MCI_STOP, MCI_WAIT, GenericParms );
  272.  
  273.      { If we were recording then reset for playback }
  274.      if fRecording then begin
  275.  
  276.         { Reset the Amp-Mixer device for playback }
  277.         ResetPlayBack;
  278.         fRecording := FALSE;
  279.  
  280.      end; 
  281.  
  282.  
  283.      (* Enable the play and record buttons *)
  284.      WinEnableWindow( hwndRecordButton, TRUE );
  285.      WinEnableWindow( hwndPlayButton, TRUE );
  286.      WinEnableWindow( hwndStopButton, FALSE );
  287.  
  288.      MainDialogProc := MRESULT( FALSE );
  289.      exit;
  290.       end;
  291.     end; (* end switch *)
  292.  
  293.     WM_CLOSE: begin
  294.  
  295.       Close;
  296.  
  297.       WinPostMsg( hwnd, WM_QUIT, 0, 0 );
  298.       MainDialogProc := MRESULT( FALSE );
  299.       exit;
  300.     end;
  301.  
  302.   end; (* end switch *)
  303.  
  304.    (* Pass messages on to the frame window
  305.     *)
  306.   MainDialogProc := WinDefDlgProc( hwnd, msg, mp1, mp2 );
  307.  
  308. end; (* End MainDialogProc *)
  309.  
  310.  
  311. var
  312.   rc        : ULONG;
  313.   hab        : OS2Def.HAB;
  314.   hmq        : OS2Def.HMQ;
  315.   qmsg        : OS2PMAPI.QMSG;
  316.   ulIndex    : ULONG;
  317.  
  318. begin
  319.    hab := WinInitialize(0);
  320.    hmq := WinCreateMsgQueue(hab,0);
  321.  
  322.    hwndFrame := WinLoadDlg( HWND_DESKTOP,
  323.                 HWND_DESKTOP,
  324.                 MainDialogProc,
  325.                 NULLHANDLE,
  326.                 ID_DIALOG,
  327.                 NIL );
  328.  
  329.    while WinGetMsg( hab, qmsg, NULLHANDLE, 0, 0 ) do 
  330.      WinDispatchMsg( hab, qmsg );
  331.  
  332.    WinDismissDlg( hwndFrame, ULONG( TRUE ) );
  333.    WinDestroyMsgQueue( hmq );
  334.    WinTerminate( hab );
  335. end. (* end main *)
  336.  
  337.  
  338.