⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmaudiosignals.c

📁 WM9713 audio codec driver for WinCE 5.0
💻 C
📖 第 1 页 / 共 5 页
字号:
 *      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;
}

/*-----------------------------------------------------------------------------
 * 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;
    const WM_SIGNAL_DETAILS *pSignalDetails = NULL;
    const WM_CHIPDEF        *pChipDef;
    unsigned int            nSignal;
    WM_REGTYPE              reg = WM_REG_INVALID;
    WM_REGVAL               regval = 0;
    WM_REGVAL               mask = 0;
    WM_REGVAL               update = 0;
    
    /*
     * 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 ones which match.  We have
     * several scenarios here:
     * 
     *    - single field (one entry)
     *    - multiple fields in the same register (e.g. AC'97)
     *    - multiple fields in multiple registers (e.g. WM8753)
     */
    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 == channels ) ||
                 ( 0 == ( pSignalDetails->flags & WM_CHANNEL_ALL ) ) ||
                 ( 0 != ( channels & pSignalDetails->flags ) )
               )
            {
                int regVol;
                int halfStep;
                
                /* 
                 * It matches.
                 * Check whether we need to setup for a new register.
                 */
                if ( pSignalDetails->reg != reg )
                {
                    if ( WM_REG_INVALID != reg )
                    {
                        /*
                         * If we're adding to a previous signal, but it's a different
                         * register, write the previous one.
                         */
                        status = WMSetField( hDevice, reg, regval, mask );
                        if ( WM_ERROR( status ) )
                        {
                            goto error;
                        }
                    }
                    
                    /* Now initialise our working variables */
                    reg = pSignalDetails->reg;
                    regval = 0;
                    mask = 0;
                    if ( pSignalDetails->flags & WM_SIG_HAS_UPDATE )
                        update = pSignalDetails->special;
                }

                /*
                 * Work out what is the largest value less than half a step
                 * (i.e. the largest value we can add to an exact signal so
                 * we can guarantee it will not change on rounding.
                 */
                halfStep = pSignalDetails->step/2;
                if ( halfStep < 0 )
                    halfStep = -halfStep;
                halfStep = halfStep - 1;
                if ( baseVol < 0 )
                    halfStep = -halfStep;

                /*
                 * Now work out the register value.
                 * Note we add half a step to get the rounding right.
                 */
                regVol = baseVol + halfStep;
                regVol = regVol / pSignalDetails->step;
                regVol += pSignalDetails->zerodB;
                
                /* Trim it to the valid range */
                if ( regVol > pSignalDetails->maxval )
                    regVol = pSignalDetails->maxval;
                if ( regVol < pSignalDetails->minval )
                    regVol = pSignalDetails->minval;
                
                /* Now shift it to the right place in the register */
                regVol = regVol << pSignalDetails->shift;
                regval |= (WM_REGVAL) regVol;
               
                /* And store the mask */
                mask |= pSignalDetails->mask;

#if WM_AUDIO_USE_ZERO_CROSS
                /* Set zero-cross if it's there */
                if ( WM_SIG_NO_ZERO_CROSS != pSignalDetails->zeroCross )
                {
                    regval |= pSignalDetails->zeroCross;
                    mask |= pSignalDetails->zeroCross;
                }
#endif
                
                /* Check whether we've got a "both" bit we can use */
                if ( WM_CHANNEL_STEREO == ( channels & WM_CHANNEL_STEREO ) &&
                     ( pSignalDetails->flags & WM_SIG_HAS_BOTH )
                   )
                {
                    regval |= pSignalDetails->special;
                    mask |= pSignalDetails->special;
                    break;
                }
            }
        }
    } 

    /* Did we find it? */
    if ( WM_REG_INVALID == reg )
    {
        status = WMS_UNSUPPORTED;
        goto error;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -