home *** CD-ROM | disk | FTP | other *** search
- /* MikMod sound library
- (c) 1998 Miodrag Vallat and others - see file AUTHORS for complete list
-
- This library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- /*==============================================================================
-
- $Id: drv_dart.c,v 1.11 1998/12/07 06:01:39 miod Exp $
-
- Mikmod driver for output on OS/2 MMPM/2 using direct audio (DART)
-
- ==============================================================================*/
-
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
-
- #define INCL_DOS
- #include <os2.h>
- #include <mcios2.h>
- #include <meerror.h>
- #include <os2medef.h>
-
- #include <stdlib.h>
- #include <string.h>
-
- #include <mikmod_internals.h>
-
- /* No need to be a power of two, but must be at least 4 */
- #define BUFFERCOUNT 4
-
- static MCI_MIX_BUFFER MixBuffers[BUFFERCOUNT];
- static MCI_MIXSETUP_PARMS MixSetupParms;
- static MCI_BUFFER_PARMS BufferParms;
- static MCI_GENERIC_PARMS GenericParms;
- static ULONG DeviceID=0,BufferSize;
- static int ready,lastbuffer;
-
- /* Buffer update thread (created and called by DART) */
- static LONG APIENTRY OS2_Dart_UpdateBuffers(ULONG ulStatus,PMCI_MIX_BUFFER pBuffer,ULONG ulFlags)
- {
- /* if we have finished a buffer, we're ready to play a new one */
- if((ulFlags==MIX_WRITE_COMPLETE)||
- ((ulFlags==(MIX_WRITE_COMPLETE|MIX_STREAM_ERROR))&&(ulStatus==ERROR_DEVICE_UNDERRUN)))
- if(ready<BUFFERCOUNT) ready++;
- return TRUE;
- }
-
- static BOOL OS2_Dart_IsPresent(void)
- {
- MCI_AMP_OPEN_PARMS AmpOpenParms;
-
- memset(&AmpOpenParms,0,sizeof(MCI_AMP_OPEN_PARMS));
- AmpOpenParms.usDeviceID=0;
- AmpOpenParms.pszDeviceType=(PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
-
- if(mciSendCommand(0,MCI_OPEN,
- MCI_WAIT|MCI_OPEN_SHAREABLE|MCI_OPEN_TYPE_ID,
- (PVOID)&AmpOpenParms,0)!=MCIERR_SUCCESS)
- return 0;
-
- mciSendCommand(AmpOpenParms.usDeviceID,MCI_CLOSE,MCI_WAIT,
- (PVOID)&GenericParms,0);
- return 1;
- }
-
- static BOOL OS2_Dart_Init(void)
- {
- MCI_AMP_OPEN_PARMS AmpOpenParms;
-
- MixBuffers[0].pBuffer=NULL; /* marker */
- memset(&GenericParms,0,sizeof(MCI_GENERIC_PARMS));
-
- /* open AMP device */
- memset(&AmpOpenParms,0,sizeof(MCI_AMP_OPEN_PARMS));
- AmpOpenParms.usDeviceID=0;
- AmpOpenParms.pszDeviceType=(PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
-
- if(mciSendCommand(0,MCI_OPEN,
- MCI_WAIT|MCI_OPEN_SHAREABLE|MCI_OPEN_TYPE_ID,
- (PVOID)&AmpOpenParms,0)!=MCIERR_SUCCESS) {
- _mm_errno=MMERR_OPENING_AUDIO;
- return 1;
- }
-
- DeviceID=AmpOpenParms.usDeviceID;
-
- /* setup playback parameters */
- memset(&MixSetupParms,0,sizeof(MCI_MIXSETUP_PARMS));
- MixSetupParms.ulBitsPerSample=(md_mode&DMODE_16BITS)?16:8;
- MixSetupParms.ulFormatTag=MCI_WAVE_FORMAT_PCM;
- MixSetupParms.ulSamplesPerSec=md_mixfreq;
- MixSetupParms.ulChannels=(md_mode&DMODE_STEREO)?2:1;
- MixSetupParms.ulFormatMode=MCI_PLAY;
- MixSetupParms.ulDeviceType=MCI_DEVTYPE_WAVEFORM_AUDIO;
- MixSetupParms.pmixEvent=OS2_Dart_UpdateBuffers;
-
- if(mciSendCommand(DeviceID,MCI_MIXSETUP,
- MCI_WAIT|MCI_MIXSETUP_INIT,
- (PVOID)&MixSetupParms,0)!=MCIERR_SUCCESS) {
- mciSendCommand(DeviceID,MCI_CLOSE,MCI_WAIT,(PVOID)&GenericParms,0);
- _mm_errno=MMERR_OS2_MIXSETUP;
- return 1;
- }
-
- /* take in account the DART suggested buffer size for the fragment size
- computation... */
- BufferSize=MixSetupParms.ulBufferSize;
-
- BufferParms.ulNumBuffers=BUFFERCOUNT;
- BufferParms.ulBufferSize=BufferSize;
- BufferParms.pBufList=MixBuffers;
-
- if(mciSendCommand(DeviceID,MCI_BUFFER,
- MCI_WAIT|MCI_ALLOCATE_MEMORY,
- (PVOID)&BufferParms,0)!=MCIERR_SUCCESS) {
- mciSendCommand(DeviceID,MCI_CLOSE,MCI_WAIT,(PVOID)&GenericParms,0);
- _mm_errno=MMERR_OUT_OF_MEMORY;
- return 1;
- }
-
- if(VC_Init()) {
- mciSendCommand(DeviceID,MCI_BUFFER,MCI_WAIT|MCI_DEALLOCATE_MEMORY,&BufferParms,0);
- mciSendCommand(DeviceID,MCI_CLOSE,MCI_WAIT,(PVOID)&GenericParms,0);
- return 1;
- }
-
- return 0;
- }
-
- static void OS2_Dart_Exit(void)
- {
- VC_Exit();
- if (MixBuffers[0].pBuffer) {
- mciSendCommand(DeviceID,MCI_BUFFER,MCI_WAIT|MCI_DEALLOCATE_MEMORY,&BufferParms,0);
- MixBuffers[0].pBuffer=NULL;
- }
- if (DeviceID) {
- mciSendCommand(DeviceID,MCI_CLOSE,MCI_WAIT,(PVOID)&GenericParms,0);
- DeviceID=0;
- }
- }
-
- static BOOL OS2_Dart_PlayStart(void)
- {
- int i;
-
- VC_PlayStart();
-
- /* silence buffers */
- for(i=0;i<BUFFERCOUNT;i++) {
- VC_SilenceBytes(MixBuffers[i].pBuffer,BufferSize);
- MixBuffers[i].ulBufferLength=BufferSize;
- }
-
- /* wake DART up - it needs at least 2 buffers to do so since the audio
- stream is left open */
- ready=0;lastbuffer=2;
- MixSetupParms.pmixWrite(MixSetupParms.ulMixHandle,MixBuffers,2);
-
- return 0;
- }
-
- static void OS2_Dart_Update(void)
- {
- /* it's certainly not the best way to keep ownership of the Amp device,
- but at least it works - it's even a bit aggressive... */
- mciSendCommand(DeviceID,MCI_ACQUIREDEVICE,MCI_ACQUIRE_QUEUE,
- (PVOID)&GenericParms,0);
-
- /* play a sound buffer if ready to play */
- while(ready) {
- lastbuffer=(lastbuffer+1)%BUFFERCOUNT;
- MixBuffers[lastbuffer].ulBufferLength=
- VC_WriteBytes(MixBuffers[lastbuffer].pBuffer,BufferSize);
- MixSetupParms.pmixWrite(MixSetupParms.ulMixHandle,
- &(MixBuffers[lastbuffer]),1);
- ready--;
- }
- }
-
- static void OS2_Dart_PlayStop(void)
- {
- int i;
-
- /* play the last BUFFERCOUNT buffers */
- for(i=0;i<BUFFERCOUNT;i++) {
- while(!ready) DosSleep(1); /* force a yield */
- OS2_Dart_Update();
- }
-
- /* send a silence buffer tagged as finishing the playback */
- while(!ready) DosSleep(1);
- VC_SilenceBytes(MixBuffers[0].pBuffer,BufferSize);
- MixBuffers[0].ulBufferLength=BufferSize;
- MixBuffers[0].ulFlags=MIX_BUFFER_EOS;
- MixSetupParms.pmixWrite(MixSetupParms.ulMixHandle,&(MixBuffers[0]),1);
- while(ready<2) DosSleep(1);
-
- VC_PlayStop();
- }
-
- static BOOL OS2_Dart_Reset(void)
- {
- OS2_Dart_Exit();
- return OS2_Dart_Init();
- }
-
- MDRIVER drv_dart=
- {
- NULL,
- "Direct audio (DART)",
- "OS/2 DART driver v1.0",
- 0,
- 255,
- OS2_Dart_IsPresent,
- VC_SampleLoad,
- VC_SampleUnload,
- VC_SampleSpace,
- VC_SampleLength,
- OS2_Dart_Init,
- OS2_Dart_Exit,
- OS2_Dart_Reset,
- VC_SetNumVoices,
- OS2_Dart_PlayStart,
- OS2_Dart_PlayStop,
- OS2_Dart_Update,
- VC_VoiceSetVolume,
- VC_VoiceSetFrequency,
- VC_VoiceSetPanning,
- VC_VoicePlay,
- VC_VoiceStop,
- VC_VoiceStopped,
- VC_VoiceGetPosition,
- VC_VoiceRealVolume,
- };
-