drv_dart.c
资源名称:tcpmp.rar [点击查看]
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:8k
源码类别:
Windows CE
开发平台:
C/C++
- /* MikMod sound library
- (c) 1998, 1999, 2000 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., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
- */
- /*==============================================================================
- $Id: drv_dart.c,v 1.2 2004/01/31 22:39:40 raph Exp $
- Driver for output on OS/2 MMPM/2 using direct audio (DART)
- ==============================================================================*/
- /*
- Written by Miodrag Vallat <miod@mikmod.org>
- Lots of improvements (basically made usable...) by Andrew Zabolotny
- <bit@eltech.ru>
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "mikmod_internals.h"
- #ifdef DRV_DART
- #define INCL_DOS
- #define INCL_OS2MM
- #include <os2.h>
- /* Prevent a warning: PPFN redefined */
- #define PPFN _PPFN
- #include <os2me.h>
- #undef PPFN
- #include <stdlib.h>
- #include <string.h>
- #define MAX_BUFFERCOUNT 8
- static MCI_MIX_BUFFER MixBuffers[MAX_BUFFERCOUNT];
- static MCI_MIXSETUP_PARMS MixSetupParms;
- static MCI_BUFFER_PARMS BufferParms;
- static ULONG DeviceIndex = 0; /* use default waveaudio device */
- static ULONG BufferSize = (ULONG)-1; /* autodetect buffer size */
- static ULONG BufferCount = 2; /* use two buffers */
- static ULONG DeviceID = 0;
- static void Dart_CommandLine(CHAR *cmdline)
- {
- char *ptr;
- int buf;
- if ((ptr = MD_GetAtom("buffer", cmdline, 0))) {
- buf = atoi(ptr);
- if (buf >= 12 && buf <= 16)
- BufferSize = 1 << buf;
- free(ptr);
- }
- if ((ptr = MD_GetAtom("count", cmdline, 0))) {
- buf = atoi(ptr);
- if (buf >= 2 && buf <= MAX_BUFFERCOUNT)
- BufferCount = buf;
- free(ptr);
- }
- if ((ptr = MD_GetAtom("device", cmdline, 0))) {
- buf = atoi(ptr);
- if (buf >= 0 && buf <= 8)
- DeviceIndex = buf;
- free(ptr);
- }
- }
- /* Buffer update thread (created and called by DART)
- This is a high-priority thread used to compute and update the audio stream,
- automatically created by the DART subsystem. We compute the next audio
- buffer and feed it to the waveaudio device. */
- static LONG APIENTRY Dart_UpdateBuffers(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags)
- {
- /* sanity check */
- if (!pBuffer)
- return TRUE;
- /* 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))) {
- /* refill this audio buffer and feed it again */
- MUTEX_LOCK(vars);
- if (Player_Paused_internal())
- pBuffer->ulBufferLength =
- VC_SilenceBytes(pBuffer->pBuffer, BufferSize);
- else
- pBuffer->ulBufferLength =
- VC_WriteBytes(pBuffer->pBuffer, BufferSize);
- MUTEX_UNLOCK(vars);
- MixSetupParms.pmixWrite(MixSetupParms.ulMixHandle, pBuffer, 1);
- }
- return TRUE;
- }
- static BOOL Dart_IsPresent(void)
- {
- MCI_AMP_OPEN_PARMS AmpOpenParms;
- MCI_GENERIC_PARMS GenericParms;
- memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS));
- AmpOpenParms.pszDeviceType = (PSZ) MAKEULONG(MCI_DEVTYPE_AUDIO_AMPMIX,
- (USHORT) DeviceIndex);
- 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 Dart_Init(void)
- {
- MCI_AMP_OPEN_PARMS AmpOpenParms;
- MCI_GENERIC_PARMS GenericParms;
- MixBuffers[0].pBuffer = NULL; /* marker */
- DeviceID = 0;
- memset(&GenericParms, 0, sizeof(MCI_GENERIC_PARMS));
- /* open AMP device */
- memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS));
- AmpOpenParms.usDeviceID = 0;
- AmpOpenParms.pszDeviceType = (PSZ) MAKEULONG(MCI_DEVTYPE_AUDIO_AMPMIX,
- (USHORT) DeviceIndex);
- 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 = Dart_UpdateBuffers;
- if (mciSendCommand(DeviceID, MCI_MIXSETUP,
- MCI_WAIT | MCI_MIXSETUP_INIT,
- (PVOID) & MixSetupParms, 0) != MCIERR_SUCCESS) {
- _mm_errno = MMERR_OS2_MIXSETUP;
- return 1;
- }
- /* Compute audio buffer size now if necessary */
- if (BufferSize == (ULONG)-1) {
- /* DART suggested buffer size is somewhat too big. We compute a size
- for circa 1/4" of playback. */
- int bit;
- BufferSize = md_mixfreq >> 2;
- if (md_mode & DMODE_STEREO)
- BufferSize <<= 1;
- if (md_mode & DMODE_16BITS)
- BufferSize <<= 1;
- for (bit = 15; bit >= 12; bit--)
- if (BufferSize & (1 << bit))
- break;
- BufferSize = (1 << bit);
- }
- /* make sure buffer is not greater than 64 Kb, as DART can't handle this
- situation. */
- if (BufferSize > 65536)
- BufferSize = 65536;
- BufferParms.ulStructLength = sizeof(BufferParms);
- BufferParms.ulNumBuffers = BufferCount;
- BufferParms.ulBufferSize = BufferSize;
- BufferParms.pBufList = MixBuffers;
- if (mciSendCommand(DeviceID, MCI_BUFFER,
- MCI_WAIT | MCI_ALLOCATE_MEMORY,
- (PVOID) &BufferParms, 0) != MCIERR_SUCCESS) {
- _mm_errno = MMERR_OUT_OF_MEMORY;
- return 1;
- }
- return VC_Init();
- }
- static void Dart_Exit(void)
- {
- MCI_GENERIC_PARMS GenericParms;
- 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 Dart_PlayStart(void)
- {
- MCI_GENERIC_PARMS GenericParms;
- int i;
- if (VC_PlayStart())
- return 1;
- /* silence buffers */
- for (i = 0; i < BufferCount; i++) {
- VC_SilenceBytes(MixBuffers[i].pBuffer, BufferSize);
- MixBuffers[i].ulBufferLength = BufferSize;
- }
- /* grab exclusive rights to device instance (not entire device) */
- GenericParms.hwndCallback = 0; /* Not needed, so set to 0 */
- if (mciSendCommand(DeviceID, MCI_ACQUIREDEVICE, MCI_EXCLUSIVE_INSTANCE,
- (PVOID) &GenericParms, 0) != MCIERR_SUCCESS) {
- mciSendCommand(DeviceID, MCI_CLOSE, MCI_WAIT, (PVOID) &GenericParms, 0);
- _mm_errno = MMERR_OPENING_AUDIO;
- return 1;
- }
- /* wake DART up */
- MixSetupParms.pmixWrite(MixSetupParms.ulMixHandle, MixBuffers, BufferCount);
- return 0;
- }
- static void Dart_Update(void)
- {
- /* Nothing to do: everything is done in DART_UpdateBuffers() */
- }
- static void Dart_PlayStop(void)
- {
- MCI_GENERIC_PARMS GenericParms;
- GenericParms.hwndCallback = 0;
- mciSendCommand(DeviceID, MCI_STOP, MCI_WAIT, (PVOID) &GenericParms, 0);
- VC_PlayStop();
- }
- MIKMODAPI MDRIVER drv_dart = {
- NULL,
- "Direct audio (DART)",
- "OS/2 DART driver v1.2",
- 0, 255,
- "dart",
- "device:r:0,8,0:Waveaudio device index to use (0 - default)n"
- "buffer:r:12,16:Audio buffer log2 sizen"
- "count:r:2,8,2:Number of audio buffersn",
- Dart_CommandLine,
- Dart_IsPresent,
- VC_SampleLoad,
- VC_SampleUnload,
- VC_SampleSpace,
- VC_SampleLength,
- Dart_Init,
- Dart_Exit,
- NULL,
- VC_SetNumVoices,
- Dart_PlayStart,
- Dart_PlayStop,
- Dart_Update,
- NULL,
- VC_VoiceSetVolume,
- VC_VoiceGetVolume,
- VC_VoiceSetFrequency,
- VC_VoiceGetFrequency,
- VC_VoiceSetPanning,
- VC_VoiceGetPanning,
- VC_VoicePlay,
- VC_VoiceStop,
- VC_VoiceStopped,
- VC_VoiceGetPosition,
- VC_VoiceRealVolume
- };
- #else
- MISSING(drv_dart);
- #endif
- /* ex:set ts=4: */