📄 wmaudiosignals.c
字号:
/*-----------------------------------------------------------------------------
* Function: WMAudioSetSignalVolumeAdv
*
* Set the signal level relative to full-scale, specifying the level in 1/16dB
* steps relative to full scale. The WM_SIGNAL_LEVEL macro can convert from
* a dB value to the corresponding 1/16dB value. E.g. WM_SIGNAL_LEVEL( 1.5 )
* gives 0x18, which corresponds to 1.5dBFS.
*
* Note: the underlying device will probably not be able to set this level
* precisely. The applied level will be rounded to the nearest available
* step. For example, if the device has a 1.5dB step size (typical of AC'97
* devices), a level of WM_SIGNAL_LEVEL(4) (0x40), WM_SIGNAL_LEVEL(4.125) (0x42),
* WM_SIGNAL_LEVEL(4.5) (0x48) or WM_SIGNAL_LEVEL( 5 ) (0x50) would all
* result in a 4.5dBFS signal.
*
* Parameters:
* hDevice The handle to the device (from WMOpenDevice).
* signal The signal to set.
* baseVol The relative amplification or attenuation to apply,
* in 1/16 dB steps.
* channels One or more of the WM_CHANNEL_XXX constants.
*
* Returns: WMSTATUS
* WMS_SUCCESS - success
* WMS_UNSUPPORTED - signal is not supported, or doesn't
* support volume control
* WMS_NO_SUPPORTED_DEVICE - device support not present
* See WMStatus.h for all other values and meanings.
*---------------------------------------------------------------------------*/
WMSTATUS WMAudioSetSignalVolumeAdv( WM_DEVICE_HANDLE hDevice,
WM_AUDIO_SIGNAL signal,
int baseVol,
WM_AUDIO_CHANNELS channels
)
{
WMSTATUS status = WMS_UNSUPPORTED;
#if WM_OUTPUT_GAIN_RAMP
int dBMin = 0;
int dBMax = 0;
int dBStep = 0;
/*
* Update our global gain value.
*/
status = private_SaveGlobalOutputGain( hDevice,
signal,
baseVol,
channels
);
if ( WM_ERROR( status ) && ( WMS_UNSUPPORTED != status ) )
{
goto done;
}
/*
* If the output signal is muted set the gain back to its minumum value.
*/
if ( ( WM_SIGNAL_IS_OUTPUT( signal ) ) &&
( WMS_RETURN_TRUE == WMAudioIsSignalMuted( hDevice, signal ) )
)
{
/*
* Get the minimum dB value for this signal
* and set the baseVol to this value.
*/
status = private_GetdBRange( hDevice,
signal,
&dBMin,
&dBMax,
&dBStep
);
if ( WM_ERROR( status ) && ( WMS_UNSUPPORTED != status ) )
{
goto done;
}
if( WMS_UNSUPPORTED != status )
{
baseVol = dBMin;
}
}
#endif /* WM_OUTPUT_GAIN_RAMP */
status = private_SetSignalVolumeAdv( hDevice,
signal,
baseVol,
channels
);
if ( WM_ERROR( status ) )
{
goto done;
}
return WMS_SUCCESS;
done:
return status;
}
/*-----------------------------------------------------------------------------
* Function: WMAudioSetSignalVolumesAdv
*
* Set the signal level relative to full-scale, specifying the level in 1/16dB
* steps relative to full scale. The WM_SIGNAL_LEVEL macro can convert from
* a dB value to the corresponding 1/16dB value. E.g. WM_SIGNAL_LEVEL( 1.5 )
* gives 0x18, which corresponds to 1.5dBFS.
*
* Note: the underlying device will probably not be able to set this level
* precisely. The applied level will be rounded to the nearest available
* step. For example, if the device has a 1.5dB step size (typical of AC'97
* devices), a level of WM_SIGNAL_LEVEL(4) (0x40), WM_SIGNAL_LEVEL(4.125) (0x42),
* WM_SIGNAL_LEVEL(4.5) (0x48) or WM_SIGNAL_LEVEL( 5 ) (0x50) would all
* result in a 4.5dBFS signal.
*
* Parameters:
* hDevice The handle to the device (from WMOpenDevice).
* signal The signal to set.
* leftVol The relative amplification or attenuation to apply,
* in 1/16 dB steps.
* rightVol The relative amplification or attenuation to apply,
* in 1/16 dB steps.
*
* Returns: WMSTATUS
* WMS_SUCCESS - success
* WMS_UNSUPPORTED - signal is not supported, or doesn't
* support volume control
* WMS_NO_SUPPORTED_DEVICE - device support not present
* See WMStatus.h for all other values and meanings.
*---------------------------------------------------------------------------*/
WMSTATUS WMAudioSetSignalVolumesAdv( WM_DEVICE_HANDLE hDevice,
WM_AUDIO_SIGNAL signal,
int leftVol,
int rightVol
)
{
WMSTATUS status;
if ( leftVol == rightVol )
{
/*
* Call through to our helper function.
*/
status = WMAudioSetSignalVolumeAdv( hDevice,
signal,
leftVol,
WM_CHANNEL_ALL
);
if ( WM_ERROR( status ) )
goto finish;
}
else
{
status = WMAudioSetSignalVolumeAdv( hDevice,
signal,
leftVol,
WM_CHANNEL_LEFT
);
if ( WM_ERROR( status ) )
goto finish;
status = WMAudioSetSignalVolumeAdv( hDevice,
signal,
rightVol,
WM_CHANNEL_RIGHT
);
if ( WM_ERROR( status ) )
goto finish;
}
finish:
/*
* And return.
*/
return status;
}
/*-----------------------------------------------------------------------------
* Function: WMAudioGetSignalVolumeDb
*
* Returns the signal level relative to full-scale, rounded to the nearest dB
* relative to a full-scale signal.
*
* Note: If multiple channels are specified (e.g. WM_CHANNEL_STEREO) this function
* assumes all channels are at the same level and returns the level of the first
* channel it finds. To check for different levels on different channels, call this
* function once for each channel (e.g. once with WM_CHANNEL_LEFT and once with
* WM_CHANNEL_RIGHT).
*
* Parameters:
* hDevice The handle to the device (from WMOpenDevice).
* signal The signal to get.
* pVol Receives the relative signal level in decibels.
* channel One of the WM_CHANNEL_XXX constants.
*
* Returns: WMSTATUS
* WMS_SUCCESS - success
* WMS_UNSUPPORTED - signal is not supported, or doesn't
* support volume control
* WMS_NO_SUPPORTED_DEVICE - device support not present
* See WMStatus.h for all other values and meanings.
*---------------------------------------------------------------------------*/
WMSTATUS WMAudioGetSignalVolumeDb( WM_DEVICE_HANDLE hDevice,
WM_AUDIO_SIGNAL signal,
int *pVol,
WM_AUDIO_CHANNELS channel
)
{
return private_GetSignalVolumeUnits( hDevice,
signal,
pVol,
channel,
WM_SIGNAL_LEVEL( 1 )
);
}
/*-----------------------------------------------------------------------------
* Function: WMAudioGetSignalVolumeAdv
*
* Returns the signal level relative to full-scale, using 1/16dB steps.
*
* Note: If multiple channels are specified (e.g. WM_CHANNEL_STEREO) this function
* assumes all channels are at the same level and returns the level of the first
* channel it finds. To check for different levels on different channels, call this
* function once for each channel (e.g. once with WM_CHANNEL_LEFT and once with
* WM_CHANNEL_RIGHT).
*
* Parameters:
* hDevice The handle to the device (from WMOpenDevice).
* signal The signal to get.
* pVol Receives the relative signal level in 1/16 dB steps.
* channel One of the WM_CHANNEL_XXX constants.
*
* Returns: WMSTATUS
* WMS_SUCCESS - success
* WMS_UNSUPPORTED - signal is not supported, or doesn't
* support volume control
* WMS_NO_SUPPORTED_DEVICE - device support not present
* See WMStatus.h for all other values and meanings.
*---------------------------------------------------------------------------*/
WMSTATUS WMAudioGetSignalVolumeAdv( WM_DEVICE_HANDLE hDevice,
WM_AUDIO_SIGNAL signal,
int *pVol,
WM_AUDIO_CHANNELS channel
)
{
return private_GetSignalVolumeUnits( hDevice,
signal,
pVol,
channel,
1
);
}
/*-----------------------------------------------------------------------------
* Function: private_GetSignalVolumeUnits
*
* Returns the signal level relative to full-scale in multiples of the given
* unit.
*
* Note: If multiple channels are specified (e.g. WM_CHANNEL_STEREO) this function
* assumes all channels are at the same level and returns the level of the first
* channel it finds. To check for different levels on different channels, call this
* function once for each channel (e.g. once with WM_CHANNEL_LEFT and once with
* WM_CHANNEL_RIGHT).
*
* Parameters:
* hDevice The handle to the device (from WMOpenDevice).
* signal The signal to get.
* pVol Receives the relative signal level in decibels.
* channel One of the WM_CHANNEL_XXX constants.
* baseUnit The unit size to return (in 1/16dB steps)
*
* Returns: WMSTATUS
* WMS_SUCCESS - success
* WMS_UNSUPPORTED - signal is not supported, or doesn't
* support volume control
* WMS_NO_SUPPORTED_DEVICE - device support not available in this build
*---------------------------------------------------------------------------*/
static WMSTATUS private_GetSignalVolumeUnits( WM_DEVICE_HANDLE hDevice,
WM_AUDIO_SIGNAL signal,
int *pVol,
WM_AUDIO_CHANNELS channel,
int baseUnit
)
{
WMSTATUS status = WMS_UNSUPPORTED;
const WM_SIGNAL_DETAILS *pSignalDetails = NULL;
const WM_CHIPDEF *pChipDef;
unsigned int nSignal;
int baseVol;
WM_REGTYPE reg = WM_REG_INVALID;
/*
* Make sure that the signal is valid.
*/
if ( !WM_SIGNAL_IS_VALID( signal ) )
{
status = WMS_UNSUPPORTED;
goto error;
}
/*
* Look up our chipdef.
*/
pChipDef = WMGetChipDef( hDevice );
if ( !pChipDef )
{
status = WMS_NO_SUPPORTED_DEVICE;
goto error;
}
/*
* Run through the signals, looking for the first one which matches.
*/
for ( nSignal = 0; nSignal < pChipDef->signalCount; nSignal++ )
{
pSignalDetails = &pChipDef->pSignalDetails[ nSignal ];
if ( pSignalDetails->signal == signal &&
WM_REG_INVALID != pSignalDetails->reg
)
{
/* The signal matches. Does the channel? */
if ( ( WM_CHANNEL_ALL == channel ) ||
( 0 == ( pSignalDetails->flags & WM_CHANNEL_ALL ) ) ||
( 0 != ( channel & pSignalDetails->flags ) )
)
{
int regVol;
WM_REGVAL regval;
int step;
/*
* It matches. Get the current value.
*/
reg = pSignalDetails->reg;
status = WMRead( hDevice, reg, ®val );
if ( WM_ERROR( status ) )
{
goto error;
}
/* Mask and shift */
regval &= pSignalDetails->mask;
regVol = regval >> pSignalDetails->shift;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -