关于audio的总结

做过高通平台的msm7X27,msm7x27a,qrd8x25的audio驱动工作,关于android的audio流程网上可以查到很多内容,就总结下调试audio遇到的问题吧

关于audio的总结_第1张图片

这是整个audio tx,rx的流程。包括voice的,很清晰

一。关于耳机检测及耳机按键检测的问题

耳机插拔检测是靠一个GPIO管脚检测,有上拉电阻到vbat,没有插耳机为高电平,插入之后变低电平,报中断

对应的gpio配置code在hs_gpio_cfg_s.c, 详见数组hsi_gpio_info

关于OTHC,在qcom网站找到的解释是这样的

 The one-touch headset detection feature is supported through the HSET_BIAS pin. The internal hardware in this device performs actions
 based on the amount of current being drawn by the headset microphone. The HSET_BIAS output functions like a traditional microphone
 bias except that it has some additional features to support one-touch headset detection.

而事实上,这几个平台都不是OTHC的。

msm7X27,msm7x27a平台的耳机按键检测是adc读取值进行判断的,qrd8625我们是利用micbias的电流进行判断的

相关耳机插拔代码及键值上报code见hs_othc.c

二。关于audio部分

1。多媒体音量的调节

如果是提高声音,可以调整index值,降低音量的话,对计算出来的volume进行衰减就可以了

例如:衰减

if((stream == AudioSystem::MUSIC)  && (mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET))
    {
          volume = volume *0.30903;
    }

android2.3跟android4.0volume的计算方式有差别,android2.3不管是哪种模式哪种媒体流用的是同一种计算方法,而android4.0有分开处理,默认的情况下,音量的曲线都不是很好,音量低部分变化不明显,可以调整db/step

如在android4.0上

#if 0
const AudioPolicyManagerBase::VolumeCurvePoint
    AudioPolicyManagerBase::sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = {
    {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f}
};
#else
const AudioPolicyManagerBase::VolumeCurvePoint
    AudioPolicyManagerBase::sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = {
    {1, -30.0f}, {20, -24.0f}, {60, -12.0f}, {100, 0.0f}
};
#endif

这是对media音量进行的调整,基本上是均匀变化的。基本思想就是,例如0.0f-(-12.0f)/100-60=(-12.0f)-(-24.0f)/60-20约等于-24.0f-(-30.f)/20-1

关于android音量控制,audioservice.java里定义了每种媒体流的音量等级

For example:
 /** @hide Maximum volume index values for audio streams */
/* private int[] MAX_STREAM_VOLUME = new int[] {
      7,  // STREAM_SYSTEM
      7,  // STREAM_RING
      15, // STREAM_MUSIC
      7,  // STREAM_ALARM
      7,  // STREAM_NOTIFICATION
      15, // STREAM_BLUETOOTH_SCO
      7,  // STREAM_SYSTEM_ENFORCED
      15, // STREAM_DTMF
      15  // STREAM_TTS
};*/

在audiomanager.java里设定每种媒体流默认音量级别

For example

/** @hide Default volume index values for audio streams*/
/* private int[]DEFAULT_STREAM_VALUE = new int[] {
      7,  // STREAM_SYSTEM
      7,  // STREAM_RING
      15, // STREAM_MUSIC
      7,  // STREAM_ALARM
      7,  // STREAM_NOTIFICATION
      15, // STREAM_BLUETOOTH_SCO
      7,  // STREAM_SYSTEM_ENFORCED
      15, // STREAM_DTMF
      15  // STREAM_TTS
};*/

2. adjust peaker ---ringtone or media

可以调节MBADRC 的band改变频响,这个调节的过程由硬件完成,硬件会给audiofilter.csv文件

The AudioFilter.csv file can be parsed in AudioHardware.cpp. The tuning parameters are pushed down to the ADSP when there is a device change.

       1: Speaker,

       2: Handset,

       3: Headset

3。连接蓝牙耳机,notification会断续,播ringtone的时候,speaker声音会断续,not smoothly

将a2dpUsedForSonification()改为false,声音就不会从蓝牙耳机里播放。产生这种断续现象的原因,在播放notification or ringtone的时候,蓝牙跟speaker设备会同时打开,即使对于来电铃音来说蓝牙耳机会播放自己的提示音,但code里还是会把这个设备打开,蓝牙工作的时候需要唤醒,当声音开始播放的时候,蓝牙跟蓝牙耳机的通信不是立刻建立。当播来电铃声的时候,来电铃声的数据会送到蓝牙协议栈,但是这部分数据却没有送到蓝牙耳机播放,是怎么处理的不清楚,但是会影响到speaker播放ringtone

 

4.   C网来电,拒接,铃声突然变大

The audio is played at 48KHz sample-rate so ringtone is also played 48KHz.

On CDMA call, vocder is acquired during the ringtone playback so ringtone is played at 8KHz sample-rate.

This issue is presented on only CDMA call.

To avoid this issue, need to undifne "FEATURE_RX_VOICE_OVER_HOST_PCM" in custXXXXX.h file(=AMSS side).

5.点击开始录像,开始提示音响后会有兹兹声

playback跟capture动作切换造成

status_t AudioHardware::AudioStreamInMSM72xx::standby()

{

       //mHardware->clearCurDevice();
        //mHardware->doRouting(this);
       mHardware->doRouting(NULL);

}

 

二。voice部分

1。关于蓝牙打电话

由于qrd8625这个项目外挂了一个modem,着实被蓝牙打电话折腾够呛,初期评估了解的情况不足也是导致调试时间花费比较多的原因

首先高通的默认code是主芯片做pcm的master,提供时钟,而外挂的modem pcm口只能做slave,不能做master,那么就需要将BT PCM做master,这样才行进行通信,简直为难死人。提case给高通,确认BT可以做master后,开始着手调试。看到BT相关文件的那些tag啊,都要崩溃了。还好经过有一个周吧,把pcm的主时钟给搞出来了,高通主芯片配成slave模式是有文档的,这个可以参照80_VH558_1_D_AUX_PCM_MSM72xxA_MSM75xxA_MSM76xx_MSM7x27.pdf文档去配。

其实BT做master也很容易配。改的很简单,只是当时tag跟代码里对不上,用的蓝牙芯片是WCN2243

文件vender\qcom\proprietary\bt\hci_qcomm_init\btqsoncnvmtags.c

static bt_qsoc_cfg_cst_element_type bt_qsoc_cfg_tag_44_bha_b0[] = \
{
  0x2C, 0x01, 0x2C, 0x29,
  0x2F, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
  0xFF, 0x10, 0x02, 0x02, 0x01, 0x00, 0x14, 0x01,
  0x06, 0x28, 0xA0, 0x62, 0x03, 0x64, 0x01, 0x01,
  0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0,
  0xFF, 0x10, 0x02, 0x01, 0x00, 0x14, 0x01, 0x02,
  0x03
};

要是改成master,需要将0x10改成0x00,这个是配置BT PCM是做master还是slave的寄存器,0x50这个寄存器,0x01代表的时钟是25.6khz,这个详见spec了,然后0x50就是2048khz,这个就是pcm工作的时钟,帧同步信号是0xFF这个寄存器,FF代表了256分频,正好是8k,帧同步信号跟pcm数据的采样率一致。

接着就开始建立通话部分调试,上行有声音,下行没有声音,需要将主芯片的PCM口四根线PCM_CLK,PCM_ASYNC,PCM_IN,PCM_OUT配成高阻态,高阻态的配置只需要配成gpio无拉输入状态即可。

2。蓝牙打电话后手机完全没有声音

EVDO蓝牙打电话后,挂断电话手机完全没有声音,这个问题产生的原因就是BT PCMmaster,主芯片PCM slave造成的,再挂断电话时有个提示音没有播出来。从log看是申请不到内存,其实是能看到obtainBuffer timed out (is the CPU pegged?)这句log,后来高通给了patch,是在audio_out.c文件做的修改

将audio_write()函数中的进程睡眠唤醒方式做了修改

rc = wait_event_interruptible(audio->wait,
           (frame->used == 0) || (audio->stopped));

改成

rc = wait_event_interruptible_timeout(audio->wait,
           (frame->used == 0) || (audio->stopped),
           msecs_to_jiffies(2000));

3.主micbias,hp micbias都是可以在AP侧发rpc到cp请求使能or dis功能

主micbias enable/disable

adie_codec_write (ADIE_CODEC_EN3_R,       

                                       ADIE_CODEC_EN3_EN_MICBIAS_M,

                                       ADIE_CODEC_EN3_MICBIAS_ENA_V/ADIE_CODEC_EN3_MICBIAS_DIS_V);

hp micbias,有这样几种状态可以选择

typedef enum
{
    /**
     * Headset module off
     */
    PM_HSED_ENABLE_OFF,
    /**
     * enabled if TCXO signal is high
     */
    PM_HSED_ENABLE_TCXO,
    /**
     * enabled if PWM or TCXO signal is high
     */
    PM_HSED_ENABLE_PWM_TCXO,
    /**
     * enabled always
     */
    PM_HSED_ENABLE_ALWAYS,
    /**
     * Invalid selection, used for range checking in PMIC APIs
     */
    PM_HSED_ENABLE_TYPE__INVALID
}pm_hsed_enable_type;

4。录音声音小的问题

一是提高录的声音,二是提高播的声音,但是调整播放相关的增益会影响其他音频的输出,最好能提高录的声音

在android4.0+qrd8625上可以这样修改

可以增大codectxgain,tx volume

增大codectxgain

1 在vocdata.c

voc_data_codec_gain_ctrl_type* voc_data_get_codec_gain()
{
....

 if (voc_check_in_call())
    {
      voc_data_codec_gain.codec_st_gain = voc_data_pcm_cal_ptr->codec_st_gain;
    }
    else
    {
+  voc_data_codec_gain.codec_tx_gain =设置新的gain
   #if defined(T_MSM7x27A) || defined(T_MSM7x25A)
      if (voc_data_codec_inuse == VOC_CODEC_STEREO_HEADSET) {
        // Hack for power measurement
        voc_data_codec_gain.codec_rx_gain = VOC_DATA_UNITY_GAIN;
      }
     
      .....


}

增大tx volume

1 在vocproc.c

vocproc_state_return_type vocproc_state_active (void)
{
....
+if(!voc_check_in_call())
+ vocproc_set_volume_normal();

return (VOCPROC_STATE_SUCCESS);
}

2

extern vocproc_status_type vocproc_set_volume()
{
...

if( voc_check_in_call() == FALSE ) {
      vocproc_vol.tx_comfort_noise_ena = QDSP_COMFORT_NOISE_DIS_V ;
+     vocproc_vol.tx_vol=设置新的gain
    }

}

 5。打开PGA通路

关于audio的总结_第2张图片

早期的FM通路是这样走的,qrd8625平台外挂modem电话免提模式是这样做的

ADIE register configurations are located in ...\services\adsp\msmaud.h

To enable AUX_PGA loopback, you should logical OR the existing register values with the following for the specific audio path that you are working with.

ADIE_CODEC_EN5_R/*0x39*/, MSMAUD_ADIE_CODEC_EN5_ENABLE_BANDGAP_AUXPGA_LR/*0x0C*/, \
ADIE_CODEC_C7B_R/*0x43*/, MSMAUD_ADIE_CODEC_C7B_AUX_PGA_RXP_L_R/*0x2F*/, \

#define MSMAUD_ADIE_CODEC_C7B_AUX_PGA_RXP_L_R \
( MSMAUD_ADIE_CODEC_C7B_INIT | \
ADIE_CODEC_C7B_AUX_PGA_RXP_L_SEL_V | \
ADIE_CODEC_C7B_AUX_PGA_RXP_R_SEL_V | \
ADIE_CODEC_C7B_AUX_PGA_RXM_L_SEL_V | \
ADIE_CODEC_C7B_AUX_PGA_RXM_R_SEL_V | \
ADIE_CODEC_C7B_AUX_PGA_VOCM_LOCAL_V )

ADIE_CODEC_C10_R/*0x46*/, /*must be configured for whatever output you're going through.  See the description for CODEC_C10 in the Software Interface Manual for your target*/

ADIE_CODEC_C10_R, (ADIE_CODEC_C10_HPH_L_ADD_LINEI_L_ENA_V        \
                             | ADIE_CODEC_C10_HPH_R_ADD_LINEI_R_ENA_V)

可以参考芯片sepc关于codec寄存器的配置说明

 

 

你可能感兴趣的:(关于audio的总结)