高通CSR QCC300x i2s和AudioCodec 输出切换

一. 以A2DP为例, 并仅分析SBC情况

lib库中的MusicConnectAudio函数

  1. 申请local_config内存, 初始化local_config参数

  2. InitMultiChannelParams(&(local_config->mch_params));
    决定采样频率

  3. DECODER->sink_type: A2DP音乐时参数是 AUDIO_SINK_AV

  4. audioDecoderConnectInputSources(DECODER->sink_type, local_config)
    //目标是连接所有的input source到合适的DSP port.
    {
    sources_t sources;

    sources = audioDecoderGetSources(sink_type);
    //sources.source[0] = StreamSourceFromSink(decoder->media_sink); //A2DP 时候, 实际上只得到source[0], 并且来源于空中A2DP的media_sink.

    generalConfiguration(localConfig);

    configureSources(&sources);
    audioDecodeConnectSources(&sources, sink_type, localConfig->content_protection);
    VmalTransformRtpSbcDecode(sources->source[0], StreamKalimbaSink(GetDspPort(0)));
    //创建A2DP 空中source端到KalimbaSink端的实时流媒体转换.GetDspPort(0)=0;
    connectBackChannel(sink_type, localConfig->codec_data);
    }

以上, 主要是连接 A2DP空中的数据到StreamKalimbaSink(0), 并实时转换.
**
6. // Connect up DSP output ports to hardware sinks
audioDecodeConnectDspOutputs(&(local_config->mch_params));
函数实现:

{
AudioOutputAddSourceOrPanic(StreamKalimbaSource(DSP_OUTPUT_PORT_PRI_LEFT), audio_output_primary_left);
//StreamKalimbaSource(port)意义为StreamSourceFromSink(StreamKalimbaSink(port));
//        DSP_OUTPUT_PORT_PRI_LEFT 宏定义值为4, 后面的基本依次加1
//        audio_output_primary_left 宏定义值为0
//        AudioOutputAddSourceOrPanic(source, output)的意义是: state.sources[output] = source;

AudioOutputAddSourceOrPanic(StreamKalimbaSource(DSP_OUTPUT_PORT_PRI_RIGHT), audio_output_primary_right);
   AudioOutputAddSourceOrPanic(StreamKalimbaSource(DSP_OUTPUT_PORT_SEC_LEFT), audio_output_secondary_left);   
    AudioOutputAddSourceOrPanic(StreamKalimbaSource(DSP_OUTPUT_PORT_SEC_RIGHT), audio_output_secondary_right);  
      AudioOutputAddSourceOrPanic(StreamKalimbaSource(DSP_OUTPUT_PORT_AUX_LEFT), audio_output_aux_left);    
      AudioOutputAddSourceOrPanic(StreamKalimbaSource(DSP_OUTPUT_PORT_AUX_RIGHT), audio_output_aux_right);    
      AudioOutputAddSourceOrPanic(StreamKalimbaSource(DSP_OUTPUT_PORT_SUB_WIRED), audio_output_wired_sub);      
    AudioOutputConnectOrPanic(params);
}
bool AudioOutputConnectOrPanic(audio_output_params_t* params)
{
    forEachOutput(audio_out) //audio_out范围是 audio_output_primary_left ~ audio_output_max.
    {
        audio_sink = StreamAudioSink(getAudioHardwareType(audio_out),
                           getAudioHardwareInstance(audio_out),
                           getAudioHardwareChannel(audio_out));
        configureSink(audio_sink, audio_out, params); //设置sink采样率之类的参数.
        if (last_valid_sink)
        {
            PanicFalse(SinkSynchronise(last_valid_sink, audio_sink)); //同步上次的sink
        }    
        last_valid_sink = audio_sink;
    }


    /* Connect up each valid sink to its source and un-mute. Must happen after
     * synchronisation, hence the need for a second loop and duplicate checks.
     */
    forEachOutput(audio_out)
    {
        audio_sink = StreamAudioSink(getAudioHardwareType(audio_out),
                           getAudioHardwareInstance(audio_out),
                           getAudioHardwareChannel(audio_out));
        StreamConnect(state.sources[audio_out], audio_sink);//这里是关键代码                       
    }
}

通过以上分析, 得知可以实现I2S和CODEC选择输出. 具体方法是通过发送不同的串口指令,更新配置,最后对应到以上audio_sink的变更, 就可以切换选择I2S输出或者是DAC codec输出了.

你可能感兴趣的:(CSR,蓝牙)