蓝牙音乐和导航语音播放混音卡顿问题

最近发现公司自研的智能车载设备上存在一个问题:手机通过蓝牙连接车机,在手机上播放音乐车机上发声然后跟车机上的导航语音播报一起混音播出的时候会出现卡顿的现象;但是在车机上播放音乐和导航混音就正常。另外需要说明的是播放音乐使用的是Music流,导航使用的是Alarm流

通过 adb shell dumpsys media.audio_flinger 工具对比查看两种场景下实时的音频流信息(截取其中一个回放线程中的音频流信息如下):

Output thread 0xe6c833c0 type 0 (MIXER):
  Thread name: AudioOut_1D
  I/O handle: 29
  TID: 935
  Standby: yes
  Sample rate: 48000 Hz
  HAL frame count: 1920
  HAL format: 0x1 (pcm16)
  HAL buffer size: 7680 bytes
  Channel count: 2
  Channel mask: 0x00000003 (front-left, front-right)
  Processing format: 0x1 (pcm16)
  Processing frame size: 4 bytes
  Pending config events: none
  Output device: 0x20000 (LINE)
  Input device: 0 (NONE)
  Audio source: 0 (default)
  Normal frame count: 1920
  Last write occurred (msecs): 1087537
  Total writes: 4905
  Delayed writes: 0
  Blocked in write: no
  Suspend count: 0
  Sink buffer : 0xe73da000
  Mixer buffer: 0xe83d8000
  Effect buffer: 0xe73dc000
  Fast track availMask=0xfe
  Standby delay ns=3000000000
  AudioStreamOut: 0xe83c82a0 flags 0x8 (DEEP_BUFFER)
  Frames written: 9417600
  Suspended frames: 0
  Hal stream dump:
  Thread throttle time (msecs): 106
  AudioMixer tracks: 0x00000003
  Master mono: off
  FastMixer not initialized
  Stream volumes in dB: 0:-11, 1:-10, 2:-10, 3:0, 4:-10, 5:-10, 6:0, 7:-10, 8:-10, 9:-96, 10:0, 11:0, 12:0
  Normal mixer raw underrun counters: partial=0 empty=0
  2 Tracks of which 0 are active
    Name Active Client Type      Fmt Chn mask Session fCount S F SRate  L dB  R dB    Server Main buf  Aux Buf Flags UndFrmCnt
       1     no   3190    3 00000001 00000003      97   7088 I 0 22050     0     0  00000000 0xe73da000 0x0 0x000         0
       0     no   3190    3 00000001 00000003      89   7072 P 3 44100     0     0  004FF80C 0xe73da000 0x0 0x600      1768
  0 Effect Chains

进一步的简化和比较如下所示:

[En]

Further simplification and comparison can be seen as follows:

车机上播音乐和导航 不卡顿
导航语音是 AudioStreamOut: 0xea0c8150 flags 0x6 (PRIMARY|FAST)
后台音乐是 AudioStreamOut: 0xea0c82a0 flags 0x8 (DEEP_BUFFER)
在手机上播放音乐,在汽车上导航卡顿

[En]

Play music on mobile phones and navigation stutters on cars

导航语音和后台音乐都是 AudioStreamOut: 0xea0c8150 flags 0x6 (PRIMARY|FAST)

蓝牙连接上手机后Music流走的输出流通道和导航的Alarm流走的输出流通道是同一个;车机上的Music流和导航的Alarm流走的是不同的输出流通道,也即是虽然两种场景下音乐的流都是Music流但是属性是不一样的,导致了最终系统选择的输出流通道不一致。

分析蓝牙底层的服务,看看蓝牙播放音乐时构建的AudioTrack对象跟平时播放音乐的有什么不同之处

void *BtifAvrcpAudioTrackCreate(int trackFreq, int channelType)
{
    LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btCreateTrack freq %d  channel %d ",
                     __func__, trackFreq, channelType);
    sp track =
        new android::AudioTrack(AUDIO_STREAM_MUSIC, trackFreq, AUDIO_FORMAT_PCM_16_BIT,
                                channelType, (size_t) 0 /*frameCount*/,
                                (audio_output_flags_t)AUDIO_OUTPUT_FLAG_FAST,
                                NULL /*callback_t*/, NULL /*void* user*/, 0 /*notificationFrames*/,
                                AUDIO_SESSION_ALLOCATE, android::AudioTrack::TRANSFER_SYNC);//!!!注意AUDIO_OUTPUT_FLAG_FAST属性
    assert(track != NULL);

    BtifAvrcpAudioTrack *trackHolder = new BtifAvrcpAudioTrack;
    assert(trackHolder != NULL);
    trackHolder->track = track;

    if (trackHolder->track->initCheck() != 0)
    {
        return nullptr;
    }

#if (defined(DUMP_PCM_DATA) && (DUMP_PCM_DATA == TRUE))
    outputPcmSampleFile = fopen(outputFilename, "ab");
#endif
    trackHolder->track->setVolume(1, 1);
    return (void *)trackHolder;
}

调试的经验表明车机端音乐类应用在底层给出的属性一般是 AUDIO_OUTPUT_FLAG_DEEP_BUFFER ,这里给定的是 AUDIO_OUTPUT_FLAG_FAST,所以导致了这里的Music流走了跟Alarm流同一个输出流通道,当导航的Alarm音频流过来以后,音频路由发生了改变,先关闭了当前的输出流通道然后再开启才导致的卡顿问题,最后解决方案也很简单,将蓝牙这里的AUDIO_OUTPUT_FLAG_FAST属性修改为AUDIO_OUTPUT_FLAG_DEEP_BUFFER 属性即可,卡顿现象也随即消失。

Original: https://blog.csdn.net/downloadname/article/details/113810047
Author: 睡着的海豚
Title: 蓝牙音乐和导航语音播放混音卡顿问题

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/524791/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球