Broadcom Nexus学习 (二) Audio

来源:互联网 发布:数据库三个范式 编辑:程序博客网 时间:2024/05/16 13:52

概念1:Audio Playback channel:

Sam感觉,Audio Playback channel可以将之理解为“一个可以解析并播放PCM数据的硬件单元”。

既然是硬件,那就可以打开,关闭,设置,并向其中填充(PCM)数据.

 

1.1:Open Audio Playback channel:

打开硬件。

NEXUS_AudioPlaybackHandle handle;

handle = NEXUS_AudioPlayback_Open(0, NULL);

if ( NULL == handle )
{
        fprintf(stderr, "Unable to open playback channel\n");
        return 0;
}

 

1.2: Setting Audio Playback channel and start :

设置硬件接收数据的格式,并开始播放。(但此时buffer 中没有数据,所以不会发出声音)

NEXUS_AudioPlaybackStartSettings settings;

NEXUS_AudioPlayback_GetDefaultStartSettings(&settings);
settings.sampleRate = 48000;
settings.bitsPerSample = 16;
settings.signedData = true;
settings.stereo = true;
settings.dataCallback.callback = data_callback;
settings.dataCallback.context = handle;
settings.dataCallback.param = (int)event;

NEXUS_AudioPlayback_Start(handle, &settings); //有数据则播放

 

callback function如下:

static void data_callback(void *pParam1, int param2)
{
   
    pParam1=pParam1;   
    BKNI_SetEvent((BKNI_EventHandle)param2);
}


 

讲解如下:

struct NEXUS_AudioPlaybackStartSettings
{
    NEXUS_Timebase timebase; //
    unsigned sampleRate;  // 波特率
    unsigned bitsPerSample;  // 只支持 8/16
    size_t startThreshold;   // 如果不为0,则hardware会在buffer头跳过这么多字节再开始播放
    bool stereo;             // 如果为true,则视数据为立体声。如果为false,则为单声道
    bool signedData;         // 如果为true,则视数据为有符号,否则视为无符号
    NEXUS_CallbackDesc dataCallback; //回调函数及其参数1,参数2。

    //当向Hardware送PCM数据的Buffer变得可用时,会回调此函数。(但之前需要调用 NEXUS_AudioPlayback_GetBuffer)


}

 

1.3: 将Audio Playback channel与硬件Output连起来:

Sam感觉,Audio Playback channel就是一个解析和播放PCM的硬件,但这个硬件要与Output联系起来,才可以将声音播放出来。(注意,在关闭Audio Playback channel时,也要断开此连接)

NEXUS_AudioOutput_AddInput(NEXUS_AudioDac_GetConnector(config.outputs.audioDacs[0]),
                               NEXUS_AudioPlayback_GetConnector(handle));

这里为audio output添加了一个input(就是Audio Playback channel)

 

 

1.4: Get Audio Playback channel Buffer.

得到向Audio Playback Buffer.

NEXUS_AudioPlayback_GetBuffer(handle, (void **)&pBuffer, &bufferSize);

参数1: AudioPlayback Handle

参数2: 此AudioPlayback 可用的传数据的buffer头。

参数3:  此次可用buffer的长度。

 

如果长度为0. 则表明当前没有可用的buffer用来传数据。此时则可以使用BKNI_WaitForEvent(event,1000)来等待buffer可用时回调函数发出的event.

在得到buffer头之后,可以向其中填充PCM数据。

 

1.5:通知Nexus Playback channel向buffer中填充了多少数据:

NEXUS_AudioPlayback_ReadComplete(handle, bufferSize);

 

注意,因为之前已经使用NEXUS_AudioPlayback_Start(),所以当向 Nexus Audio Playback Channel buffer中填充数据后,Hardware会去播放这些数据。

 

1.6:Audio Playback Stop Play :

停止播放数据并清空buffer.

 

1.7: 与Audio Output断开连接:

NEXUS_AudioOutput_RemoveInput(NEXUS_AudioDac_GetConnector(config.outputs.audioDacs[0]), NEXUS_AudioPlayback_GetConnector(handle));

 

1.8: Close Audio Playback channel:

关闭硬件。

NEXUS_AudioPlayback_Close(handle)

 

 

 

概念2:Mixer:

Sam感觉Mixer就是一个混音器,多路AudioPlayback和Audio Decoder可以作为Mixer的Input. 而Mixer又作为Audio Output(DAC)的Input. 这样就可以做到多路混音。


Audio Decoder应该是硬件接入的Audio信号(如DVR的麦)。我们主要讲Audio Playback.

 

Audio Playback可以有2路,所以就可以做到2路混音。

 

//打开2路audio playback

gAudioPlayback_Handle1 = NEXUS_AudioPlayback_Open(0, NULL);  // audio playback 0
gAudioPlayback_Handle2 = NEXUS_AudioPlayback_Open(1, NULL);  // audio playback 1

 

//打开混音器

gMixer = NEXUS_AudioMixer_Open(NULL);

//将audio playback 作为Mixer的Input与之连接起来

NEXUS_AudioMixer_AddInput(gMixer, NEXUS_AudioPlayback_GetConnector(gAudioPlayback_Handle1));
NEXUS_AudioMixer_AddInput(gMixer, NEXUS_AudioPlayback_GetConnector(gAudioPlayback_Handle2));

 

//将Mixer作为Audio Output(DAC)的Input与之连接

NEXUS_AudioOutput_AddInput(NEXUS_AudioDac_GetConnector(config.outputs.audioDacs[0]), NEXUS_AudioMixer_GetConnector(gMixer));

 

此时再按照上一节的例子,分别往2路Audio Playback Buffer中填充PCM数据。则可以发现成功混音了。

 

 

 概念3:Audio Output(DAC)

 Sam感觉Audio Output就是一个将数据转换为模拟信号发出的设备。简单的说,Audio Playback是将PCM数据解析出来,并把此数据传递给Audio OutputAudio Output 则将此数据转化为模拟信号。(模拟信号就是可以通过音响播放出来)

 

设置:

struct NEXUS_AudioOutputSettings
{
    NEXUS_Timebase timebase;
    NEXUS_AudioChannelMode channelMode;
    NEXUS_AudioVolumeType volumeType; //音量设置单位
    int32_t leftVolume;   //左声道音量
    int32_t rightVolume;  //右声道音量
    bool muted;
    unsigned additionalDelay;
    NEXUS_AudioOutputPll pll;
    unsigned defaultSampleRate;
}

讲解:

NEXUS_AudioVolumeType volumeType; //音量设置单位

音量设置单位有2种:

NEXUS_AudioVolumeType_eDecibel: dB(Decibel:分贝)。

 NEXUS_AudioVolumeType_eLinear:线性变化。

 

如果设置如下:

volumeType = NEXUS_AudioVolumeType_eDecibel;

则音量 0 - -9000 之间变化。

0 0