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

📄 wmaudiosignals.c

📁 WM9713 audio codec driver for WinCE 5.0
💻 C
📖 第 1 页 / 共 5 页
字号:
    WM_AUDIO_CHANNELS       channels = 0;
    WMSTATUS                status;
    unsigned int            nSignal;
    WM_BOOL                 found = FALSE;

    /*
     * 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.  If we get
     * both left and right, we've got a stereo signal.
     */
    for ( nSignal = 0; nSignal < pChipDef->signalCount; nSignal++ )
    {
        pSignalDetails = &pChipDef->pSignalDetails[ nSignal ];
        if ( pSignalDetails->signal == signal )
        {
            /* It matches.  Remember the channel. */
            channels |= ( pSignalDetails->flags & WM_SIG_CHANNEL_MASK );
            found = TRUE;
        }
    }
    
    if ( !found )
    {
        status = WMS_UNSUPPORTED;
        goto error;
    }
    
    /*
     * Success - return the channels we found.
     */
    *pChannels = channels;
    return WMS_SUCCESS;
    
error:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WMAudioMuteSignal
 *
 * Called to mute or unmute the signal to all paths.
 *
 * Note: This function will set and clear all the mute bits for the signal.
 *
 * Parameters:
 *      hDevice         The handle to the device (from WMOpenDevice).
 *      signal          The signal to mute.
 *      mute            Mute if TRUE, unmute if FALSE.
 *
 * Returns:     WMSTATUS
 *       See WMStatus.h.
 *---------------------------------------------------------------------------*/
WMSTATUS WMAudioMuteSignal( WM_DEVICE_HANDLE    hDevice,
                            WM_AUDIO_SIGNAL     signal,
                            WM_BOOL             mute
                          )
{
    const WM_SIGNAL_DETAILS *pSignalDetails = NULL;
    const WM_CHIPDEF        *pChipDef;
    WMSTATUS                status = WMS_UNSUPPORTED;
    unsigned int            nSignal;
    WM_REGTYPE              reg = WM_REG_INVALID;
    WM_REGVAL               regval = 0;
    WM_REGVAL               update = 0;
    WM_REGVAL               mask = 0;

    /*
     * 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.  Apply the
     * mute to each.  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->muteReg
           )
        {
            /* 
             * It matches.  Do some checks.
             */
            if ( !mute && pSignalDetails->flags & WM_SIG_VOLUME_MUTE )
            {
                /*
                 * This signal is muted by setting the volume value to a special
                 * value.  This means we've lost the information about what the
                 * volume used to be, so the only way to unmute is to set the
                 * volume to a non-muted value.
                 */
                WM_TRACE( hDevice, (
                          "WMAudioMuteSignal: signal %s has a zero mute - to unmute set new volume",
                          WMSignalName( signal )
                        ));
                status = WMS_UNSUPPORTED;
                goto error;
            }

            /*
             * Check whether we need to setup for a new register.
             */
            if ( pSignalDetails->muteReg != 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->muteReg;
                regval = 0;
                mask = 0;
                if ( pSignalDetails->flags & WM_SIG_HAS_UPDATE )
                {
                    update = pSignalDetails->special;
                }
            }
            
            /* Now add this mute */
            if ( mute )
                regval |= pSignalDetails->mute;
            mask |= pSignalDetails->muteMask;

            /* Check whether we've got a "both" bit we can use */
            if ( 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;
    }
    
    /* Now do our final write, setting the update bit if we have one */
    if ( update )
    {
        regval |= update;
        mask |= update;
    }

    /*
     * And do the write.
     */
    status = WMSetField( hDevice, reg, regval, mask );
    if ( WM_ERROR( status ) )
    {
        goto error;
    }
                    
    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

⌨️ 快捷键说明

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