Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

usbd_audio_drv_<codec-name>.h / usbd_audio_drv_<codec-name>.c

Prototype

Code Block
languagecpp
static  CPU_BOOLEAN  USBD_Audio_DrvCtrlFU_VolManage (USBD_AUDIO_DRV  *p_audio_drv,
                                                     CPU_INT08U       req,
                                                     CPU_INT08U       unit_id,
                                                     CPU_INT08U       log_ch_nbr,
                                                     CPU_INT16U      *p_vol);


Arguments

p_audio_drv

Pointer to audio driver structure.

...

This listing shows an example usage of this function.

Anchor
Listing - USBD_Audio_DrvCtrlFU_VolManage() Example Usage
Listing - USBD_Audio_DrvCtrlFU_VolManage() Example Usage

Code Block
languagecpp
titleListing - USBD_Audio_DrvCtrlFU_VolManage() Example Usage
linenumberstrue
#define  FU_SPEAKER_ID      							 6u
#define  FU_MIC_ID          							 7u

#define  CODEC_MASTER_VOL_CTRL_MIN_dB               0xC200u
#define  CODEC_MASTER_VOL_CTRL_MAX_dB               0x0000u
#define  CODEC_MASTER_VOL_CTRL_RES_dB               0x0040u
#define  CODEC_MASTER_VOL_CTRL_SILENCE                 252u
#define  CODEC_DECIMATOR_VOL_CTRL_MIN_dB            0xBF80u
#define  CODEC_DECIMATOR_VOL_CTRL_MAX_dB            0x1800u
#define  CODEC_DECIMATOR_VOL_CTRL_RES_dB            0x0080u
#define  CODEC_DECIMATOR_VOL_CTRL_SILENCE              128u


static  CPU_BOOLEAN  USBD_Audio_DrvCtrlFU_VolManage (CPU_INT08U   req,
                                                     CPU_INT08U   unit_id,
                                                     CPU_INT08U   log_ch_nbr,
                                                     CPU_INT16U  *p_vol)
{
    CPU_INT16S  temp;
    CPU_INT08U  vol_to_set;


    (void)&log_ch_nbr;											              

    switch (req) {												              (1)
        case USBD_AUDIO_REQ_GET_CUR:							              (2)
             if (unit_id == FU_SPEAKER_ID) {
                 *p_vol = FU_VolSpeaker;
             } else {
                 *p_vol = FU_VolMic;
             }
             break;


        case USBD_AUDIO_REQ_GET_MIN:							              (3)
             if (unit_id == FU_SPEAKER_ID) {
                 *p_vol = CODEC_MASTER_VOL_CTRL_MIN_dB;       /* -78 dB.                               				  */
             } else {
                 *p_vol = CODEC_DECIMATOR_VOL_CTRL_MIN_dB;    /* -63.5 dB.                             			      */
             }
             break;


        case USBD_AUDIO_REQ_GET_MAX:							              (4)
             if (unit_id == FU_SPEAKER_ID) {
                 *p_vol = CODEC_MASTER_VOL_CTRL_MAX_dB;       /* 0 dB.                                                */
             } else {
                 *p_vol = CODEC_DECIMATOR_VOL_CTRL_MAX_dB;    /* +24 dB.                                              */
             }
             break;


        case USBD_AUDIO_REQ_GET_RES:							              (5)
             if (unit_id == FU_SPEAKER_ID) {
                 *p_vol = CODEC_MASTER_VOL_CTRL_RES_dB;       /* Resolution of 0.25 dB.                               */
             } else {
                 *p_vol = CODEC_DECIMATOR_VOL_CTRL_RES_dB;    /* Resolution of 0.5 dB.                                */
             }
             break;


        case USBD_AUDIO_REQ_SET_CUR:							
             if (unit_id == FU_SPEAKER_ID) {
                 FU_VolSpeaker = *p_vol;						              (6)
                 if (*p_vol == USBD_AUDIO_FU_CTRL_VOL_SILENCE) {
                     vol_to_set = CODEC_MASTER_VOL_CTRL_SILENCE;
                 }
                                                              /* Negative dB.                                         */
                                                                              (7)
                 temp       = (CPU_INT16S)*p_vol;
                 vol_to_set = (CPU_INT08U)(-temp / CODEC_MASTER_VOL_CTRL_RES_dB);
                                                                              (8)
                 /* $$$$ Set volume level for record stream in audio chip. */


             } else
                 FU_VolMic = *p_vol;
                 if (*p_vol == USBD_AUDIO_FU_CTRL_VOL_SILENCE) {
                     vol_to_set = CODEC_DECIMATOR_VOL_CTRL_SILENCE;
                 }
                                                               /* Negative dB.                                         */
                 if (*p_vol > CODEC_DECIMATOR_VOL_CTRL_MIN_dB) {              (7)
                     temp       = (CPU_INT16S)*p_vol;
                     vol_to_set = (CPU_INT08U)(-temp / CODEC_DECIMATOR_VOL_CTRL_RES_dB);
                 } else {                                      /* Positive dB.                                         */
                     vol_to_set = (CPU_INT08U)(*p_vol / CODEC_DECIMATOR_VOL_CTRL_RES_dB);
                 }
                                                                              (8)
                 /* $$$$ Set volume level for record stream in audio chip. */
             }
             break;

        default:
             return (DEF_FAIL);
    }

    return (DEF_OK);
}


Panel
bgColor#f0f0f0

(1) The request type may be processed in a switch statement. Volume control supports all GET_XXX requests and SET_CUR.

(2) By using the Feature Unit ID, unique within the audio function, you can return the current volume level stored for example in a local global variable updated by the SET_CUR request case.

(3) By using the Feature Unit ID, you can return the minimum volume level possible. This value will be a constant. In this example, the volume attenuation for the speaker ranges from 0 to -78 dB and corresponds to the range supported by the audio codec. Thus, the minimum value is -78 dB. Refer to the warning below about volume levels range translated from audio codec range to Audio 1.0 specification range and vice versa.

(4) By using the Feature Unit ID, you can return the maximum volume level possible. This value will be a constant. In this example, the volume attenuation for the speaker ranges from 0 to -78 dB and corresponds to the range supported by the audio codec. Thus, the minimum value is 0 dB. Refer to the warning below about volume levels range translated from audio codec range to Audio 1.0 specification range and vice versa.

(5) By using the Feature Unit ID, you can return the resolution supported by the audio codec to change the volume level. This value will be a constant. In this example, the codec uses steps of 0.25 dB. Refer to the warning below about volume levels range translated from audio codec range to Audio 1.0 specification range and vice versa.

(6) For the request SET_CUR, you can update the volume level stored for instance locally in a global variable. This global variable will be read by GET_CUR request case.

(7) The volume value pointed by p_vol is translated into a value understood by the audio codec. Indeed, the volume value sent by the host corresponds to the volume range defined by Audio 1.0 specification. This range does not necessarily match the volume range supported by the audio codec. Refer to the warning below about volume levels range translated from Audio 1.0 specification range to audio codec range to and vice versa.

(8) You should use the proper functions to set the volume level in the audio codec. It could be for instance sending some I2C commands to write in some audio codec registers. Return DEF_FAIL if any error occurs during the volume setting.


Warning
titleVolume Values Range Conversion (Audio Chip <-> Audio 1.0 spec)

When manipulating volume levels, be aware that you must handle the conversion from the audio codec range to the Audio 1.0 specification range and vice versa. Audio 1.0 indicates that the volume can range from +127.9961 dB (0x7FFF) down to -127.9961 dB (0x8001) in steps of 1/256 dB (0x0001) with an extended value of 0x8000 for -∞dB.

For GET_MIN, GET_MAX, and GET_RES request, respectively, the minimum, maximum and step volume must be translated from the audio codec range to the Audio 1.0 range.

For SET_CUR request, the volume level must be translated from the Audio 1.0 range to the audio codec range.

...