Audio Codec介绍-3

1.    AGC(Automatic Gain Control)

即自动增益控制; 对一个输入信号进行放大,为了方便处理,应该保证输出有一定的幅度同时又不会饱和,但是由于输入信号的幅度通常变化很大,所以不能采用一个简单的单一放大倍数,AGC就是根据输入信号调整放大倍数,是输出信号幅度一致。

2.    音频数据的格式WAVE_FORMAT

音频格式包括Sample rateMono/Stereo等内容,具体的类型包括下面的几种:

#define WAVE_FORMAT_1M08       0x00000001       /* 11.025 kHz, Mono,   8-bit  */

#define WAVE_FORMAT_1S08       0x00000002       /* 11.025 kHz, Stereo, 8-bit  */

#define WAVE_FORMAT_1M16       0x00000004       /* 11.025 kHz, Mono,   16-bit */

#define WAVE_FORMAT_1S16       0x00000008       /* 11.025 kHz, Stereo, 16-bit */

#define WAVE_FORMAT_2M08       0x00000010       /* 22.05  kHz, Mono,   8-bit  */

#define WAVE_FORMAT_2S08       0x00000020       /* 22.05  kHz, Stereo, 8-bit  */

#define WAVE_FORMAT_2M16       0x00000040       /* 22.05  kHz, Mono,   16-bit */

#define WAVE_FORMAT_2S16       0x00000080       /* 22.05  kHz, Stereo, 16-bit */

#define WAVE_FORMAT_4M08       0x00000100       /* 44.1   kHz, Mono,   8-bit  */

#define WAVE_FORMAT_4S08       0x00000200       /* 44.1   kHz, Stereo, 8-bit  */

#define WAVE_FORMAT_4M16       0x00000400       /* 44.1   kHz, Mono,   16-bit */

#define WAVE_FORMAT_4S16       0x00000800       /* 44.1   kHz, Stereo, 16-bit */

通过Wave API waveInGetDevCaps()可以获取Audio驱动所支持的音频格式,如下所示:

mmRtn=waveInGetDevCaps(g_dwDeviceNum-1,&woc,sizeof(woc));

CheckMMRESULT(mmRtn,"ERROR:  Failed to get device caps.  waveInGetDevCaps",TPR_FAIL,"Driver responded incorrectly");

WinCE下面标准的Audio驱动中采样率为4800048K),软件上在通过插值运算来支持各个各样的采样率,这部分实现可以在类StreamContext的继承类诸如OutputStreamContext1M8/OutputStreamContext1M16等中的方法Rend2中实现。

         当我们使用Wave API waveInOpen来创建音频Stream的时候,需要通过实参向驱动传送结构体WAVEFORMATEX以告知驱动待创建的Stream的种类,如下:

WAVEFORMATEX wfx;

WAVEHDR      wh;

ZeroMemory( &wfx, sizeof( wfx ) );

 

wfx.wFormatTag           = WAVE_FORMAT_PCM;

wfx.nChannels            = 1;

wfx.nSamplesPerSec       = 11025;

wfx.wBitsPerSample       = 8;

wfx.nBlockAlign          = wfx.nChannels * wfx.wBitsPerSample / 8;

wfx.nAvgBytesPerSec      = wfx.nSamplesPerSec * wfx.nBlockAlign;

wfx.cbSize               = 0;

 

//---- Open the Wave Input Stream

mmRtn = waveInOpen( &hwi, g_dwDeviceNum-1, &wfx, NULL, 0, NULL );

if( MMSYSERR_NOERROR != mmRtn )

{

    LOG( TEXT( "FAIL in %s @ line %u:" ), TEXT( __FILE__ ), __LINE__ );

    LOG( TEXT( "/twaveInOpen returned error code, #%d." ), mmRtn );

    return TPR_FAIL;

}

         驱动中会依次调用WAV_IOControlà HandleWaveMessageà DeviceContext::OpenStream()来创建音频流。在函数DeviceContext::OpenStream的实现过程中,首先会去调用DeviceContext::IsSupportedFormat()来判断是否为支持的音频格式流,如果不支持的话则创建失败,这部分代码如下:

BOOL DeviceContext::IsSupportedFormat(LPWAVEFORMATEX lpFormat)

{

    if (lpFormat->wFormatTag != WAVE_FORMAT_PCM)

        return FALSE;

 

    if (  (lpFormat->nChannels!=1) && (lpFormat->nChannels!=2) )

        return FALSE;

 

    if (  (lpFormat->wBitsPerSample!=8) && (lpFormat->wBitsPerSample!=16) )

        return FALSE;

 

    if (lpFormat->nSamplesPerSec < 100 || lpFormat->nSamplesPerSec > 192000)

        return FALSE;

 

    return TRUE;

}

         对于支持的音频流格式,则会调用虚函数CreateStream()来创建对应的流,具体的实现将在类DeviceContext的继承中找到,以继承类OutputDeviceContext的实现为例,代码如下:

StreamContext *OutputDeviceContext::CreateStream(LPWAVEOPENDESC lpWOD)

{

    LPWAVEFORMATEX lpFormat = lpWOD->lpFormat;

 

#if ENABLE_MIDI

 

    if (lpFormat->wFormatTag == WAVE_FORMAT_MIDI)

    {

        return new CMidiStream;

    }

 

#endif

 

    // 应用层可以通过api的参数来告诉driver有几个channel

    // 下面会根据具体的通道数和采样来决定创建什么样的output device stream 类实例

    switch (lpFormat->nChannels)

    {

        case 1:

 

            switch (g_pHWContext->m_dwWavOutChnum)

            {

                case 1:

                    return (lpFormat->wBitsPerSample == 8) ?

                           (StreamContext *)new OutputStreamContext1M8 :

                           (StreamContext *)new OutputStreamContext1M16;

 

                case 2:

                    return (lpFormat->wBitsPerSample == 8) ?

                           (StreamContext *)new OutputStreamContext2M8 :

                           (StreamContext *)new OutputStreamContext2M16;

                case 6:

                    return (lpFormat->wBitsPerSample == 8) ?

                           (StreamContext *)new OutputStreamContext6M8 :

                           (StreamContext *)new OutputStreamContext6M16;

                default:

                    break;

            }

 

            break;

 

        case 2:

 

            switch (g_pHWContext->m_dwWavOutChnum)

            {

                case 1:

                    return (lpFormat->wBitsPerSample == 8) ?

                           (StreamContext *)new OutputStreamContext1S8 :

                           (StreamContext *)new OutputStreamContext1S16;

 

                case 2:

                    return (lpFormat->wBitsPerSample == 8) ?

                           (StreamContext *)new OutputStreamContext2S8 :

                           (StreamContext *)new OutputStreamContext2S16;

                case 6:

                    return (lpFormat->wBitsPerSample == 8) ?

                           (StreamContext *)new OutputStreamContext6S8 :

                           (StreamContext *)new OutputStreamContext6S16;

                default:

                    break;

            }

 

            break;

 

        default:

 

            switch (g_pHWContext->m_dwWavOutChnum)

            {

                case 6:

                    return new OutputStreamContext6X16;

            }

 

            break;

    }

 

    return NULL;

}

         其实,驱动中可以选择去支持那些格式,没有必要去支持每一种音频Stream格式。

你可能感兴趣的:(Audio Codec介绍-3)