Platform: Rockchip

OS: Android 6.0

Kernel: 3.10.92

播放音乐是单声道,硬件用的是双声道。

AudioFlinger::PlaybackThread::Track::Track ->

thread->getTrackName_l ->

AudioMixer::getTrackName ->

t->channelCount = audio_channel_count_from_out_mask(channelMask)

t->channelMask = channelMask;

t->prepareForDownmix

status_t AudioMixer::track_t::prepareForDownmix()

{

......

// MONO_HACK Only remix (upmix or downmix) if the track and mixer/device channel masks

// are not the same and not handled internally, as mono -> stereo currently is.

if (channelMask == mMixerChannelMask

|| (channelMask == AUDIO_CHANNEL_OUT_MONO

&& mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO)) {

return NO_ERROR;

}

......

// Effect downmixer does not accept the channel conversion. Let's use our remixer.

RemixBufferProvider* pRbp = new RemixBufferProvider(channelMask,

mMixerChannelMask, mMixerInFormat, kCopyBufferFrameCount);

......

}

prepareForDownmix()有两种情况下会直接返回:

1.数据源channel和mix channel一样时,那么肯定不需要转换

2.当数据源是单声道时,也不转换,直接返回,它是一个特例,其实后面会处理。

否则会通过RemixBufferProvider这个类来实现input channel到output channel的转换。

那么单声道的处理在哪里呢?

void AudioMixer::process__validate(state_t* state, int64_t pts)

{

......

if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){

//第一个参数结果为TRACKTYPE_NORESAMPLEMONO

t.hook = getTrackHook(

(t.mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO // TODO: MONO_HACK

&& t.channelMask == AUDIO_CHANNEL_OUT_MONO)

? TRACKTYPE_NORESAMPLEMONO : TRACKTYPE_NORESAMPLE,

t.mMixerChannelCount,

t.mMixerInFormat, t.mMixerFormat);

all16BitsStereoNoResample = false;

}

......

}

AudioMixer::hook_t AudioMixer::getTrackHook(int trackType, uint32_t channelCount,

audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)

{

......

switch (trackType) {

......

case TRACKTYPE_NORESAMPLEMONO:

switch (mixerInFormat) {

case AUDIO_FORMAT_PCM_FLOAT:

return (AudioMixer::hook_t)

track__NoResample;

case AUDIO_FORMAT_PCM_16_BIT:

//16bit的情况

return (AudioMixer::hook_t)

track__NoResample;

default:

LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);

break;

}

}

......

}

t.hook对应的处理函数是track__NoResample(),在process__genericNoResampling()中调用:

void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)

{

......

if (inFrames > 0) {

t.hook(&t, outTemp + (BLOCKSIZE - outFrames) * t.mMixerChannelCount,

inFrames, state->resampleTemp, aux);

t.frameCount -= inFrames;

outFrames -= inFrames;

if (CC_UNLIKELY(aux != NULL)) {

aux += inFrames;

}

}

......

}

track__NoResample()是个模板函数。

template

void AudioMixer::track__NoResample(track_t* t, TO* out, size_t frameCount,

TO* temp __unused, TA* aux)

{

ALOGVV("track__NoResample\n");

const TI *in = static_cast(t->in);

volumeMix::value, true>(

out, frameCount, in, aux, t->needsRamp(), t);

// MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.

// MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.

in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * t->mMixerChannelCount;

t->in = in;

}

注释说得很明白了,将单声道转换成NCHAN声道,这里的NCHAN是2,也就是转换成立体声。

声道切换 android,[RK3288][Android6.0] Audio中的单声道到双声道的转换处理过程相关推荐

  1. [RK3288][Android6.0] Audio中的单声道到双声道的转换处理过程

    Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 播放音乐是单声道,硬件用的是双声道. AudioFlinger::PlaybackThread:: ...

  2. android声音播放函数双声道合并,Android音视频系列(七):PCM音频单声道与双声道的相互转换...

    前言 上一篇我们已经学习了PCM音频的保存格式,这一篇我们通过掌握的知识,完成PCM音频的单声道和双声道的互相转换. 正文 首先我们把上一篇的最核心部分贴出来: PCM音频保存格式 我们首先完成单声道 ...

  3. matlab双声道转单声道,单声道和双声道的区别是什么

    区别:1.单声道是指一个声音的通道:双声道是指有两个声音的通道.2.单声道是把来自不同方位的音频信号混合后统一由录音器材把它记录下来,再由一个扬声器进行重放:双声道是在空间放置两个互成一定角度的扬声器 ...

  4. [RK3288][Android6.0] 设置中通过Sensor旋转显示画面小结

    Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 Settings -> Display有个选项控制旋转屏幕时内容是否跟着旋转 这个功能是通过 ...

  5. gpio驱动广播Android,[RK3288][Android6.0] 调试笔记 --- 通用GPIO驱动控制LED【转】

    Platform: ROCKCHIP OS: Android 6.0 Kernel: 3.10.92 由于板子没有lcd无法得知sd卡升级是否完成,因此使用LED显示. Recovery中升级完成后控 ...

  6. [RK3288][Android6.0] Audio录音frame rate设置流程小结

    Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 HAL: 默认的配置在 hardware/rockchip/audio/tinyalsa_hal/ ...

  7. [RK3288][Android6.0] Audio的音量设置流程小结

    Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 说明一: AudioManager提供了两个调节音量接口 adjustSuggestedStrea ...

  8. [RK3288][Android6.0] Skia中的编解码小结

    Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 编解码器注册: SKIA的编解码部分通过一个模板类来实现,这样做的为了实现不同类型的codec兼容 ...

  9. Android系统(127)---Android6.0存储中加入总内存和系统内存项和在西语下把,换成.

    Android6.0存储中加入总内存和系统内存项 阅读数:651 平台下patches/packages/apps/Settings/里面 1.存储中加入总内存和系统内存项 在 res/values- ...

最新文章

  1. 数据库的三大范式和事物
  2. QThreadPool类和QtConcurrent命名空间
  3. 【阿里云课程】如何基于GAN完成人脸图像超分辨任务
  4. mysql relay_技术分享 | MySQL:产生大量小 relay log 的故障一例
  5. mysql导入csvnull,MySQL Workbench从CSV导入NULL
  6. Windows Server 2008搭建域环境---安装活动目录
  7. 事件---------2
  8. QT初探(QT+VS2010)
  9. python工厂模式看不懂_python模式 工厂模式原理及实例详解
  10. 1526B - I Hate 1111
  11. 9700usb网卡 linux驱动,qf9700 USB网卡在x86 linux和arm linux上的驱动安装以及配置
  12. matlab自带滤波器,matlab自带滤波器函数
  13. thinkphp的这些扩展插架你都知道吗?
  14. PADS-VX入门到精通实战项目讲解(下)—layout部分-覃小刚-专题视频课程
  15. 抖音短视频创业,抖音机房怎么样搭建?有哪些技巧
  16. 直播APP搭建常见难点的解决方案
  17. 银行账户存储系统C++
  18. P4711 「化学」相对分子质量
  19. [HR规划]什么是人力资源规划?(zt)
  20. Java中线程池详解

热门文章

  1. 深信服防火墙多线路负载导致财务网银无法使用的解决办法
  2. 舍弗勒将向全球首批客户批产轮毂电机
  3. 教育部调整台湾高中毕业生凭学测成绩申请大陆高校标准
  4. HTML5中的数字类型的输入框:数字选择器
  5. 干货 | 信息图谱在携程酒店的应用
  6. oracle和mysql判断空值替换函数
  7. 100%成功率的顶象面积验证码识别方案
  8. linux 内核协议栈 UDP数据报校验和
  9. Ubuntu20.04创建.sh可执行文件
  10. Java开发入门与实战!java电子书教材下载