📄 wmwavepdd.c
字号:
* FALSE indicates that this WPDM_OPEN message is a
* genuine open request.
*
* Returns: MMRESULT
* MMSYSERR_NOERROR indicates success
* MMSYSERR_ERROR indicates failure
* WAVEERR_BADFORMAT if the format is not supported.
* MMSYSERR_ALLOCATED if device is already in use.
* MMSYSERR_NOTSUPPORTED if sample rate is not supported.
*---------------------------------------------------------------------------*/
static MMRESULT private_PddWaveOpen( WAPI_INOUT apidir,
LPWAVEFORMATEX lpFormat,
BOOL fQueryFormatOnly
)
{
MMRESULT retval = MMSYSERR_NOERROR;
WMSTATUS status;
WM_STREAM_ID stream;
WM_STREAM_HANDLE *phStream;
/*
* Check to see the number of channels in the waveform audio data.
* 1 channel is mono, 2 channels is stereo.
*/
WM_BOOL isStereo = ( lpFormat->nChannels == 2 ) ? TRUE : FALSE;
DEBUGMSG(ZONE_FUNCTION, (TEXT( "private_PddWaveOpen+\r\n" )) );
/*
* Check the requested Waveform-audio format is supported by the driver.
*/
if (lpFormat->wFormatTag != WAVE_FORMAT_PCM)
{
DEBUGMSG( ZONE_ERROR, ( TEXT("private_PddWaveOpen: Unsupported Waveform-audio format type %d\r\n "),
lpFormat->wFormatTag )
);
retval = WAVERR_BADFORMAT;
goto exit;
}
/*
* Check the requested number of channels is supported by the driver.
*/
if ( lpFormat->nChannels != 1 && lpFormat->nChannels != 2 )
{
DEBUGMSG( ZONE_ERROR, (TEXT( "private_PddWaveOpen: Unsupported number of channels %d\r\n " ),
lpFormat->nChannels )
);
retval = WAVERR_BADFORMAT;
goto exit;
}
/*
* Check the requested sample rate is supported by the driver.
*/
if ( lpFormat->nSamplesPerSec != WM_SAMPLE_RATE_8K &&
lpFormat->nSamplesPerSec != WM_SAMPLE_RATE_11K025 &&
lpFormat->nSamplesPerSec != WM_SAMPLE_RATE_16K &&
lpFormat->nSamplesPerSec != WM_SAMPLE_RATE_22K05 &&
lpFormat->nSamplesPerSec != WM_SAMPLE_RATE_32K &&
lpFormat->nSamplesPerSec != WM_SAMPLE_RATE_44K1 &&
lpFormat->nSamplesPerSec != WM_SAMPLE_RATE_48K
)
{
DEBUGMSG( ZONE_ERROR, (TEXT( "private_PddWaveOpen: Unsupported sample rate %d\r\n " ),
lpFormat->nSamplesPerSec )
);
retval = MMSYSERR_NOTSUPPORTED;
goto exit;
}
/* if they only want a query format, then we can return success. */
if (fQueryFormatOnly)
{
DEBUGMSG( ZONE_VERBOSE, (TEXT( "private_PddWaveOpen: Format Query\r\n " )) );
retval = MMSYSERR_NOERROR;
goto exit;
}
/*
* Open the stream based on the direction.
*/
if ( WAPI_OUT == apidir )
{
stream = WM_STREAM_DEFAULT_OUTPUT;
phStream = &g_hOutputStream;
}
else
{
stream = WM_STREAM_DEFAULT_INPUT;
phStream = &g_hInputStream;
}
status = WMAudioOpenStream( g_hAudioDevice,
stream,
phStream,
lpFormat->nSamplesPerSec,
lpFormat->wBitsPerSample,
isStereo
);
if ( WM_ERROR( status ) )
{
DEBUGMSG( ZONE_ERROR,
(TEXT( "private_PddWaveOpen: WMAudioOpenStream failed: %hs\r\n" ),
WMStatusText( status )
));
/*
* Check to see if we failed because the stream
* is already in use.
*/
if ( WMS_DEVICE_BUSY == status )
{
retval = MMSYSERR_ALLOCATED;
}
else
{
retval = MMSYSERR_ERROR;
}
goto exit;
}
exit:
DEBUGMSG(ZONE_FUNCTION, (TEXT( "private_PddWaveWaveOpen-\r\n" )) );
return retval;
}
/*-----------------------------------------------------------------------------
* Function: private_PddWaveOutStart
*
* This function starts playing the data pointed to by the wave header.
*
* Parameters:
* pwh pointer to the wave header.
* pWMAudioData pointer to the global audio data
*
* Returns: MMRESULT
* MMSYSERR_NOERROR indicates success
* MMSYSERR_ERROR indicates failure
*---------------------------------------------------------------------------*/
static MMRESULT private_PddWaveOutStart( PWAVEHDR pwh,
volatile WM_SHARED_AUDIO_DATA *pWMAudioData
)
{
MMRESULT retval = MMSYSERR_ERROR;
WMSTATUS status = WMS_SUCCESS;
DEBUGMSG( ZONE_FUNCTION, ( TEXT( "private_PddWaveOutStart+\r\n" ) ) );
/*
* Lock our global data access
*/
retval = WaitForSingleObject( g_hGlobalDataDeviceMutex, WM_GLOBAL_TIME_OUT );
if ( WAIT_OBJECT_0 != retval )
{
ASSERT( 0 );
goto error;
}
if ( !OUTPUTDMARUNNING( pWMAudioData ) )
{
/*
* For now, pretend output dma is running in case we accidentally get reentered
*/
pWMAudioData->moreData[WAPI_OUT] = TRUE; /* We expect to have more data coming... */
/*
* Enable the output paths.
*/
retval = private_PrepareOutputPaths( WM_STREAM_DEFAULT_OUTPUT, pWMAudioData, TRUE );
if ( MMSYSERR_NOERROR != retval )
{
DEBUGMSG( ZONE_ERROR,
( TEXT( "private_PddWaveOutStart - preparing output paths failed\r\n") ) );
goto error;
}
/*
* Call private_PddWaveFillBuffer to fill the DMA buffers.
*/
private_PddWaveFillBuffer( pwh );
}
/*
* Unlock access to the global data.
*/
ReleaseMutex( g_hGlobalDataDeviceMutex );
DEBUGMSG( ZONE_FUNCTION, ( TEXT( "private_PddWaveOutStart-\r\n" ) ) );
return MMSYSERR_NOERROR;
error:
pWMAudioData->moreData[WAPI_OUT] = FALSE;
/*
* Unlock access to the global data.
*/
ReleaseMutex( g_hGlobalDataDeviceMutex );
return retval;
}
/*-----------------------------------------------------------------------------
* Function: private_PddWaveInStart
*
* This function starts recording the data to a buffer pointed to by the wave
* header.
*
* Parameters:
* pWMAudioData pointer to the global audio data
*
* Returns: MMRESULT
* MMSYSERR_NOERROR indicates success
* MMSYSERR_ERROR indicates failure
*---------------------------------------------------------------------------*/
static MMRESULT private_PddWaveInStart( volatile WM_SHARED_AUDIO_DATA *pWMAudioData )
{
MMRESULT retval = MMSYSERR_ERROR;
WMSTATUS status = WMS_SUCCESS;
DEBUGMSG( ZONE_FUNCTION, ( TEXT( "private_PddWaveInStart+\r\n" ) ) );
/*
* Lock our global data access
*/
retval = WaitForSingleObject( g_hGlobalDataDeviceMutex, WM_GLOBAL_TIME_OUT );
if ( WAIT_OBJECT_0 != retval )
{
ASSERT( 0 );
goto error;
}
if ( !INPUTDMARUNNING( pWMAudioData ) )
{
/*
* For now, pretend input dma is running in case we accidentally get reentered
*/
pWMAudioData->moreData[WAPI_IN] = TRUE; /* We expect to have more data coming... */
/*
* Enable the input paths.
*/
retval = private_PrepareInputPaths( WM_STREAM_DEFAULT_INPUT, pWMAudioData, TRUE );
if ( MMSYSERR_NOERROR != retval )
{
DEBUGMSG( ZONE_ERROR,
( TEXT( "private_PddWaveInStart - preparing input paths failed\r\n") ) );
goto error;
}
/*
* Start recording.
*/
WMAudioStartRecording( g_hAudioDevice, g_hInputStream );
}
/*
* Unlock access to the global data.
*/
ReleaseMutex( g_hGlobalDataDeviceMutex );
DEBUGMSG( ZONE_FUNCTION, ( TEXT( "private_PddWaveInStart-\r\n" ) ) );
return MMSYSERR_NOERROR;
error:
pWMAudioData->moreData[WAPI_IN] = FALSE;
/*
* Unlock access to the global data.
*/
ReleaseMutex( g_hGlobalDataDeviceMutex );
return retval;
}
/*-----------------------------------------------------------------------------
* Function: private_PddWaveOutContinue
*
* This function continues to play the data pointed to by the wave header.
*
* Parameters:
* pwh pointer to a structure that defines the header used to
* identify a waveform-audio buffer.
*
* Returns: void
*---------------------------------------------------------------------------*/
static void private_PddWaveOutContinue( PWAVEHDR pwh )
{
DEBUGMSG( ZONE_FUNCTION, ( TEXT( "private_PddWaveOutContinue+\r\n" ) ) );
private_PddWaveComplete(pwh, WMAUDIO_MAX_BUFFER_SIZE);
private_PddWaveFillBuffer( pwh );
DEBUGMSG( ZONE_FUNCTION, ( TEXT( "private_PddWaveOutContinue-\r\n" ) ) );
}
/*-----------------------------------------------------------------------------
* Function: private_PddWaveInContinue
*
* This function continues to record data a buffer pointed to by the wave
* header.
*
* Parameters:
* pwh pointer to a structure that defines the header used to
* identify a waveform-audio buffer.
*
* Returns: void
*---------------------------------------------------------------------------*/
static void private_PddWaveInContinue( PWAVEHDR pwh )
{
DEBUGMSG( ZONE_FUNCTION, ( TEXT( "private_PddWaveInContinue+\r\n" ) ) );
private_PddWaveGetBuffer( pwh );
DEBUGMSG( ZONE_FUNCTION, ( TEXT( "private_PddWaveInContinue-\r\n" ) ) );
}
/*-----------------------------------------------------------------------------
* Function: private_PddWaveOutStop
*
* This function stops playback of data from a buffer pointed to by the wave
* header.
*
* Parameters:
* pWMAudioData pointer to the global audio data
*
* Returns: MMRESULT
* MMSYSERR_NOERROR indicates success
* MMSYSERR_ERROR indicates failure
*---------------------------------------------------------------------------*/
static MMRESULT private_PddWaveOutStop( volatile WM_SHARED_AUDIO_DATA *pWMAudioData )
{
MMRESULT retval = MMSYSERR_ERROR;
WMSTATUS status = WMS_SUCCESS;
DEBUGMSG( ZONE_FUNCTION, ( TEXT( "private_PddWaveOutStop+\r\n" ) ) );
/*
* Lock our global data access
*/
retval = WaitForSingleObject( g_hGlobalDataDeviceMutex, WM_GLOBAL_TIME_OUT );
if ( WAIT_OBJECT_0 != retval )
{
ASSERT( 0 );
goto error;
}
/*
* Check to make sure that we have a valid running
* output stream.
*/
if ( !OUTPUTDMARUNNING( pWMAudioData ) )
{
DEBUGMSG( ZONE_ERROR,
( TEXT( "private_PddWaveOutStop - Trying to stop a non-running stream\r\n") ) );
ASSERT( 0 );
goto error;
}
WMAudioStop( g_hAudioDevice, g_hOutputStream );
pWMAudioData->moreData[WAPI_OUT] = FALSE;
/*
* Disable the output paths.
*/
retval = private_PrepareOutputPaths( WM_STREAM_DEFAULT_OUTPUT, pWMAudioData, FALSE );
if ( MMSYSERR_NOERROR != retval )
{
DEBUGMSG( ZONE_ERROR,
( TEXT( "private_PddWaveOutStop - disabling output paths failed\r\n") ) );
goto error;
}
DEBUGMSG( ZONE_FUNCTION, ( TEXT( "private_PddWaveOutStop-\r\n" ) ) );
/*
* Unlock access to the global data.
*/
ReleaseMutex( g_hGlobalDataDeviceMutex );
return MMSYSERR_NOERROR;
error:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -