📄 wmwavepdd.c
字号:
{
DWORD retval = MMSYSERR_NOERROR;
WMSTATUS status = WMS_NO_SUPPORTED_DEVICE;
int loop = 0;
DEBUGMSG(ZONE_FUNCTION, (TEXT( "PDD_AudioInitialize+\r\n" )) );
/*
* Initialise the Wolfson library.
*/
#if WM_I2S && defined( WM_AUDIO_I2S_DEVICE )
/*
* Try the I2S first...
*/
status = WMOpenAudioDevice( WM_DEV_PRIMARY_DEVICE( WM_AUDIO_I2S_DEVICE ), &g_hAudioDevice );
if ( WM_SUCCESS( status ) )
{
DEBUGMSG( ZONE_PDD, ( TEXT( "PDD_AudioInitialise - primary I2S device\r\n" ) ) );
}
if ( WMS_CODEC_NOT_READY == status || WMS_NO_SUPPORTED_DEVICE == status )
{
/*
* Nothing responding on I2S primary - try secondary instead...
*/
status = WMOpenAudioDevice( WM_DEV_SECONDARY_DEVICE( WM_AUDIO_I2S_DEVICE ), &g_hAudioDevice );
if ( WM_SUCCESS( status ) )
{
DEBUGMSG( ZONE_PDD, ( TEXT( "PDD_AudioInitialise - secondary I2S device\r\n" ) ) );
}
}
#endif
#if WM_AC97
if ( WMS_CODEC_NOT_READY == status || WMS_NO_SUPPORTED_DEVICE == status )
{
/*
* Nothing responding on I2S secondary - try AC'97 instead...
*/
status = WMOpenAudioDevice( WM_DEV_AC97_PRIMARY, &g_hAudioDevice );
if ( WM_SUCCESS( status ) )
{
DEBUGMSG( ZONE_PDD, ( TEXT( "PDD_AudioInitialise - primary AC'97 device\r\n" ) ) );
}
}
if ( WMS_CODEC_NOT_READY == status || WMS_NO_SUPPORTED_DEVICE == status )
{
/*
* Nothing responding on AC'97 primary - try secondary instead...
*/
status = WMOpenAudioDevice( WM_DEV_AC97_SECONDARY, &g_hAudioDevice );
if ( WM_SUCCESS( status ) )
{
DEBUGMSG( ZONE_PDD, ( TEXT( "PDD_AudioInitialise - secondary AC'97 device\r\n" ) ) );
}
}
#endif /* WM_AC97 */
if ( WM_ERROR( status ) )
{
/*
* Nothing responding on AC'97 or I2S, or something really went wrong
* - nothing much we can do except tell the user...
*/
RETAILMSG( ZONE_ALWAYS, (
TEXT("PDD_AudioInitialize - WMOpenAudioDevice failed: %hs\r\n"),
WMStatusText( status )
));
goto error0;
}
/*
* Get some information about the device.
*/
WMGetDeviceType( g_hAudioDevice, &s_deviceType, NULL );
/*
* Create a mutex for the shared audio data.
*/
g_hGlobalDataDeviceMutex = CreateMutex ( NULL, FALSE, WM_GLOBAL_DATA_MUTEX_NAME );
if ( NULL == g_hGlobalDataDeviceMutex )
{
status = WMS_RESOURCE_FAIL;
goto error1;
}
/*
* Allocate shared memory for the shared audio data in the device
* process.
*/
g_pWMAudioDeviceData = ALLOC_SHARED_MEMORY( g_hAudioDevice,
volatile WM_SHARED_AUDIO_DATA,
sizeof( WM_SHARED_AUDIO_DATA ),
_T("WMGlobalAudioDriverMemory")
);
if ( !g_pWMAudioDeviceData )
{
status = WMS_RESOURCE_FAIL;
goto error1;
}
/*
* Initialise the shared audio data.
*/
g_pWMAudioDeviceData->inPowerHandler = FALSE;
g_pWMAudioDeviceData->moreData[WAPI_OUT] = FALSE;
g_pWMAudioDeviceData->moreData[WAPI_IN] = FALSE;
/*
* Initalise the global mixer mute variables.
*/
g_VolumeSettings.fMasterMute = FALSE;
g_VolumeSettings.fLineInMute = FALSE;
g_VolumeSettings.fMicMute = FALSE;
/*
* Make sure everything is quiet.
*/
retval = private_PrepareOutputPaths( WM_STREAM_DEFAULT_OUTPUT,
g_pWMAudioDeviceData,
FALSE
);
if( MMSYSERR_NOERROR != retval )
{
DEBUGMSG( ZONE_ERROR,
( TEXT( "PDD_AudioInitialize - disabling output paths failed\r\n") ) );
status = WMS_FAILURE;
goto error1;
}
/*
* Disable the input paths.
*/
retval = private_PrepareInputPaths( WM_STREAM_DEFAULT_INPUT,
g_pWMAudioDeviceData,
FALSE
);
if ( MMSYSERR_NOERROR != retval )
{
DEBUGMSG( ZONE_ERROR,
( TEXT( "PDD_AudioInitialize - disabling input paths failed\r\n") ) );
status = WMS_FAILURE;
goto error1;
}
status = WMAudioMuteAllInputs( g_hAudioDevice, TRUE );
if ( WM_ERROR( status ) && ( status != WMS_UNSUPPORTED ) )
{
DEBUGMSG( ZONE_ERROR,
( TEXT( "PDD_AudioInitialize - Muting inputs failed: %hs\r\n"),
WMStatusText( status ) )
);
goto error1;
}
/*
* Set up the record path parameters.
* NOTE: see WMConfig.h for the definition of the default record paths.
* Each application will differ so this is the
* point at which the correct path parameters should be set
* up in the driver to record.
*/
g_SignalL = WM_AUDIO_DEFAULT_RECORD_LEFT_PATH;
g_SignalR = WM_AUDIO_DEFAULT_RECORD_RIGHT_PATH;
/*
* On the WM9713 AMR card WM_AUDIO_MIC2B is the default mic input
* so change the value of Mic input used.
*/
#if WM_BOARD_LUBBOCK
if ( WM_SIGNAL_IS_MIC( WM_AUDIO_DEFAULT_RECORD_LEFT_PATH ) )
{
if ( IS_WM9713_DEVICE( s_deviceType ) )
{
g_SignalL = WM_AUDIO_MIC2B; /* Lubbock AMR MIC_IN */
}
}
if ( WM_SIGNAL_IS_MIC( WM_AUDIO_DEFAULT_RECORD_RIGHT_PATH ) )
{
if ( IS_WM9713_DEVICE( s_deviceType ) )
{
g_SignalR = WM_AUDIO_MIC2B; /* Lubbock AMR MIC_IN */
}
}
#endif /* WM_BOARD_LUBBOCK */
DEBUGMSG(ZONE_FUNCTION, (TEXT( "PDD_AudioInitialize-\r\n" )) );
return TRUE;
/* error cleanup */
error1:
WMCloseDevice( g_hAudioDevice, WM_DRIVER_AUDIO );
error0:
return FALSE;
}
/*-----------------------------------------------------------------------------
* Function: PDD_AudioMessage
*
* This function receives messages from the user applications.
* Custom functions can be access through this function.
*
* Parameters:
* uMsg Specifies the message that has been sent.
* dwParam1 Specifies parameter 1.
* dwParam2 Specifies parameter 2.
*
* Returns: DWORD
* Dependent on uMsg.
*---------------------------------------------------------------------------*/
DWORD PDD_AudioMessage( UINT uMsg, DWORD dwParam1, DWORD dwParam2 )
{
DWORD retval = MMSYSERR_NOTSUPPORTED;
WMSTATUS wmStatus;
if ( WODM_GETEXTDEVCAPS == uMsg )
{
WAVEOUTEXTCAPS *pCaps = (void *) dwParam1;
DWORD dwSize = dwParam2;
static const WAVEOUTEXTCAPS wec =
{
1, // max number of hw-mixed streams
1, // available HW streams
0, // preferred sample rate for software mixer (0 indicates no preference)
WMAUDIO_MAX_BUFFER_SIZE, // preferred buffer size for software mixer (0 indicates no preference)
0, // preferred number of buffers for software mixer (0 indicates no preference)
8000, // minimum sample rate for a hw-mixed stream
48000 // maximum sample rate for a hw-mixed stream
};
memcpy( pCaps, &wec, min( dwSize, sizeof( wec ) ) );
return MMSYSERR_NOERROR;
}
else if( WMMSG_SELECT_RECORD_PATHS == uMsg )
{
/*
* The Audio drivers make a local copy of the record inputs
* This causes communication problems for the WDCL when it
* tries to change the record settings - how does it inform the driver ?
* This is only a temporary solution.
*/
/*
* Note: The value returned to WAV_IOControl is returned to
* waveInMessage OR waveOutMessage so we can use our WMSTATUS.
*/
WM_AUDIO_SIGNAL leftInput;
WM_AUDIO_SIGNAL rightInput;
leftInput = (WM_AUDIO_SIGNAL) dwParam1;
rightInput = (WM_AUDIO_SIGNAL) dwParam2;
/* Ensure that the supplied parameters are valid */
if ( !WM_SIGNAL_IS_RECORDABLE( leftInput ) || !WM_SIGNAL_IS_RECORDABLE( rightInput ) )
{
retval = WMS_INVALID_PARAMETER;
}
else
{
retval = WMS_SUCCESS;
/*
* We make the call to WMAudioSetRecPaths so that
* we can check that the signals are valid for the codec.
* We then call WMAudioClearRecPaths .
*/
if ( WM_SUCCESS( (wmStatus = WMAudioSetRecPaths( g_hAudioDevice, leftInput, rightInput ) ) ) )
{
wmStatus = WMAudioClearRecPaths( g_hAudioDevice, leftInput, rightInput );
}
if ( WMS_UNKNOWN_MESSAGE != wmStatus )
{
retval = wmStatus;
}
}
/* Set up our global signal variables */
g_SignalL = leftInput;
g_SignalR = rightInput;
}
else
{
wmStatus = WMDriverMessage( g_hAudioDevice, uMsg, dwParam1, dwParam2 );
if ( WMS_UNKNOWN_MESSAGE != wmStatus )
{
/*
* Note: The value returned to WAV_IOControl is returned to
* waveInMessage OR waveOutMessage so we can use our WMSTATUS.
*/
retval = wmStatus;
}
}
return retval;
}
/*-----------------------------------------------------------------------------
* Function: PDD_WaveProc
*
* This function received messages to instruct the pdd layer of the audio driver
*
* Parameters:
* apidir Specifies the direction of the API request.
* dwCode Specifies the function to execute.
* dwParam1 Specifies parameter 1.
* dwParam2 Specifies parameter 2.
*
* Returns: MMRESULT
* MMRESULT is dependent on dwCode. If dwCode and apidir indicate that
* the function is not supported the MMSYSERR_NOTSUPPORTED should be
* returned.
*---------------------------------------------------------------------------*/
MMRESULT PDD_WaveProc( WAPI_INOUT apidir,
DWORD dwCode,
DWORD dwParam1,
DWORD dwParam2 )
{
MMRESULT retval = MMSYSERR_NOERROR;
WM_STREAM_HANDLE hStream;
DEBUGMSG(ZONE_FUNCTION, (TEXT( "PDD_WaveProc+\r\n" )) );
/*
* Work out the audio stream from the direction of the API request.
*/
hStream =
(apidir == WAPI_OUT) ? g_hOutputStream : g_hInputStream;
switch(dwCode)
{
/*
* This message enables the PDD to undo,
* if necessary, any setup that took place
* in WPDM_OPEN.
*/
case WPDM_CLOSE:
if (apidir == WAPI_IN)
{
/*
* If app never send WIDM_RESET,
* the capture DMA is still running.
* Stop it now.
*/
if ( INPUTDMARUNNING( g_pWMAudioDeviceData ) )
{
retval = private_PddWaveInStop( g_pWMAudioDeviceData );
if( retval != MMSYSERR_NOERROR )
{
DEBUGMSG( ZONE_ERROR, (TEXT( "WPDM_CLOSE error 0x%X\r\n" ),
retval ) );
break;
}
}
}
WMAudioCloseStream( g_hAudioDevice, hStream );
if ( WAPI_IN == apidir )
{
g_hInputStream = WM_HANDLE_INVALID;
}
else
{
g_hOutputStream = WM_HANDLE_INVALID;
}
DEBUGMSG( ZONE_PDD, (TEXT( "WPDM_CLOSE - %s\r\n" ),
(apidir == WAPI_OUT)?(TEXT("WAPI_OUT")):(TEXT("WAPI_IN")) ) );
break;
/*
* This message instructs the audio PDD to continue with the data
* pointed to by the wave header.
*/
case WPDM_CONTINUE:
if( apidir == WAPI_OUT )
{
private_PddWaveOutContinue( (PWAVEHDR)dwParam1 );
}
else
{
private_PddWaveInContinue( (PWAVEHDR)dwParam1 );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -