📄 wmaudiosignals.c
字号:
status = private_StepSignalVolume( hDevice, signal, TRUE );
if ( WM_ERROR( status ) && ( WMS_UNSUPPORTED != status ) )
{
goto error;
}
}
#endif /* WM_OUTPUT_GAIN_RAMP */
return WMS_SUCCESS;
error:
return status;
}
/*-----------------------------------------------------------------------------
* Function: WMAudioIsSignalMuted
*
* Check to see if the signal is muted to all paths.
*
* Parameters:
* hDevice The handle to the device (from WMOpenDevice).
* signal The signal to check.
*
* Returns: WMSTATUS
* WMS_RETURN_TRUE if the signal is muted to all paths.
* WMS_RETURN_FALSE if the signal is unmuted to one or more paths.
* WMS_UNSUPPORTED if the signal is not available on this device.
* See WMStatus.h for all other values and meanings.
*---------------------------------------------------------------------------*/
WMSTATUS WMAudioIsSignalMuted( WM_DEVICE_HANDLE hDevice,
WM_AUDIO_SIGNAL signal
)
{
const WM_SIGNAL_DETAILS *pSignalDetails = NULL;
const WM_CHIPDEF *pChipDef;
WMSTATUS status = WMS_UNSUPPORTED;
unsigned int nSignal;
/*
* Look up our chipdef.
*/
pChipDef = WMGetChipDef( hDevice );
if ( !pChipDef )
{
status = WMS_NO_SUPPORTED_DEVICE;
goto finish;
}
/*
* Run through the signals, looking for ones which match. If we get
* one, check whether it's muted.
*/
for ( nSignal = 0; nSignal < pChipDef->signalCount; nSignal++ )
{
pSignalDetails = &pChipDef->pSignalDetails[ nSignal ];
if ( pSignalDetails->signal == signal &&
WM_REG_INVALID != pSignalDetails->muteReg
)
{
WM_REGTYPE muteReg = pSignalDetails->muteReg;
WM_REGVAL signalMute = pSignalDetails->mute;
WM_REGVAL muteMask = pSignalDetails->muteMask;
WM_REGVAL signalVal;
/* It matches. Check the mute. */
WMRead( hDevice, muteReg, &signalVal );
if ( signalMute != ( signalVal & muteMask ) )
{
/* It's not completely muted */
status = WMS_RETURN_FALSE;
break;
}
/* It's muted so far... */
status = WMS_RETURN_TRUE;
}
}
finish:
return status;
}
/*-----------------------------------------------------------------------------
* Function: WMAudioVolToDbAdv
*
* Called to calculate the dB volume for a given perceived volume level.
* Experiments have shown that a 10dB increase in sound level corresponds
* approximately to a perceived doubling of loudness. We take 0x10000 as
* 0dBFS, and scale from there (so 0xFFFF is loudest, 0x8000 is -10dBFS,
* 0x4000 is -20dBFS, etc).
*
* Note: Linearly reducing the perceived volume does _not_ result in a linear
* attenuation of the output signal.
*
* Parameters:
* hDevice device handle
* perceivedVolume 16-bit volume where 0xFFFF is 0dBFS
*
* Returns: int
* corresponding volume in 1/16dB steps
*---------------------------------------------------------------------------*/
int WMAudioVolToDbAdv( WM_DEVICE_HANDLE hDevice, unsigned short perceivedVolume )
{
int dbVol = 0;
unsigned short currVal = perceivedVolume;
unsigned int index;
/*
* First we get the 10dB range by shifting until we get a bit in the top.
*/
while ( currVal && !(currVal & 0x8000) )
{
/* Each shift is a halving of the volume, so a 10dB attenuation */
dbVol -= WM_SIGNAL_LEVEL( 10 );
currVal = currVal << 1;
}
/*
* Now we get the rest of the range. The value of the next few bits
* comes from the lookup table. We use significant bits 2:6 as the
* index into our lookup table.
*/
/* Skip the first bit */
index = currVal & 0x7FFF;
/* Now shift down */
index = index >> (16 - VOL_SIGNIFICANT_BITS);
if ( (currVal & VOL_INSIGNIFICANT_MASK) > VOL_INSIGNIFICANT_MASK/2 )
{
index++;
}
WM_ASSERT( hDevice, index < WM_ARRAY_COUNT( s_VolumeTable ) );
WM_ASSERT( hDevice,
0 == currVal ||
s_VolumeTable[index].pattern == (currVal & VOL_SIGNIFICANT_MASK) ||
( index > 0 &&
s_VolumeTable[index-1].pattern == (currVal & VOL_SIGNIFICANT_MASK)
)
);
dbVol -= s_VolumeTable[index].level;
return dbVol;
}
/*-----------------------------------------------------------------------------
* Function: WMAudioSetSignalVolume
*
* Set the perceived volume for the given signal.
* Experiments have shown that a 10dB increase in sound level corresponds
* approximately to a perceived doubling of loudness. We take 0x10000 as
* 0dBFS, and scale from there (so 0xFFFF is loudest, 0x8000 is -10dBFS,
* 0x4000 is -20dBFS, etc).
*
* Note: Linearly reducing the perceived volume does _not_ result in a linear
* attenuation of the output signal.
*
* Parameters:
* hDevice The handle to the device (from WMOpenDevice).
* signal The signal to set.
* volume The level to apply, where 0xFFFF is 0dBFS.
* 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 WMAudioSetSignalVolume( WM_DEVICE_HANDLE hDevice,
WM_AUDIO_SIGNAL signal,
unsigned short volume,
WM_AUDIO_CHANNELS channels
)
{
WMSTATUS status;
int baseVol;
/*
* Convert to dBFS, measured in 1/16dB.
*/
baseVol = WMAudioVolToDbAdv( hDevice, volume );
/*
* Call through to our helper function.
*/
status = WMAudioSetSignalVolumeAdv( hDevice,
signal,
baseVol,
channels
);
return status;
}
/*-----------------------------------------------------------------------------
* Function: WMAudioSetSignalVolumes
*
* Set the perceived volumes for the given stereo signal.
* Experiments have shown that a 10dB increase in sound level corresponds
* approximately to a perceived doubling of loudness. We take 0x10000 as
* 0dBFS, and scale from there (so 0xFFFF is loudest, 0x8000 is -10dBFS,
* 0x4000 is -20dBFS, etc).
*
* Note: Linearly reducing the perceived volume does _not_ result in a linear
* attenuation of the output signal.
*
* Parameters:
* hDevice The handle to the device (from WMOpenDevice).
* signal The signal to set.
* leftVol The level to apply to the left channel, where 0xFFFF
* is 0dBFS.
* rightVol The level to apply to the right channel, where 0xFFFF
* is 0dBFS.
*
* 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 WMAudioSetSignalVolumes( WM_DEVICE_HANDLE hDevice,
WM_AUDIO_SIGNAL signal,
unsigned short leftVol,
unsigned short rightVol
)
{
WMSTATUS status;
int baseVolLeft, baseVolRight;
/*
* Convert to dBFS, measured in 1/16dB.
*/
baseVolLeft = WMAudioVolToDbAdv( hDevice, leftVol );
baseVolRight = WMAudioVolToDbAdv( hDevice, rightVol );
/*
* Call through to our helper function.
*/
status = WMAudioSetSignalVolumesAdv( hDevice,
signal,
baseVolLeft,
baseVolRight
);
return status;
}
/*-----------------------------------------------------------------------------
* Function: WMAudioSetSignalVolumeDb
*
* Set the signal level relative to full-scale.
*
* Note: the underlying device may not use dB steps. In this case, 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 4 or 5 would both
* result in a 4.5dBFS signal.
*
* Parameters:
* hDevice The handle to the device (from WMOpenDevice).
* signal The signal to set.
* dbVol The relative amplification or attenuation to apply,
* in decibels.
* 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 WMAudioSetSignalVolumeDb( WM_DEVICE_HANDLE hDevice,
WM_AUDIO_SIGNAL signal,
int dbVol,
WM_AUDIO_CHANNELS channels
)
{
WMSTATUS status;
/*
* Call through to our helper function.
*/
status = WMAudioSetSignalVolumeAdv( hDevice,
signal,
WM_SIGNAL_LEVEL( dbVol ),
channels
);
return status;
}
/*-----------------------------------------------------------------------------
* Function: WMAudioSetSignalVolumesDb
*
* Set the signal level relative to full-scale.
*
* Note: the underlying device may not use dB steps. In this case, 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 4 or 5 would both
* 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
* to the left channel, in decibels.
* rightVol The relative amplification or attenuation to apply
* to the right channel, in decibels.
*
*
* 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 WMAudioSetSignalVolumesDb( WM_DEVICE_HANDLE hDevice,
WM_AUDIO_SIGNAL signal,
int leftVol,
int rightVol
)
{
WMSTATUS status;
/*
* Call through to our helper function.
*/
status = WMAudioSetSignalVolumesAdv( hDevice,
signal,
WM_SIGNAL_LEVEL( leftVol ),
WM_SIGNAL_LEVEL( rightVol )
);
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -