[RK3288][Android6.0] Audio中的单声道到双声道的转换处理过程
来源:互联网 发布:选择排序和冒泡算法 编辑:程序博客网 时间:2024/05/17 19:59
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<MIXTYPE_MONOEXPAND, float, float, int32_t>; case AUDIO_FORMAT_PCM_16_BIT: //16bit的情况 return (AudioMixer::hook_t) track__NoResample<MIXTYPE_MONOEXPAND, int32_t, int16_t, int32_t>; 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 <int MIXTYPE, typename TO, typename TI, typename TA>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<const TI *>(t->in); volumeMix<MIXTYPE, is_same<TI, float>::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,也就是转换成立体声。
阅读全文
1 0
- [RK3288][Android6.0] Audio中的单声道到双声道的转换处理过程
- [RK3288][Android6.0] Audio中的混音过程小结
- C++音频单声道、双声道之间的转换
- [RK3288][Android6.0] Audio的音量计算过程小结
- 立体声、双声道、单声道的区别
- [RK3288][Android6.0] Audio中的HW Params设置流程
- [RK3288][Android6.0] Audio中的period_size使用规则
- [RK3288][Android6.0] Audio中的录音重采样小结
- [RK3288][Android6.0] Audio中的放音重采样小结
- [RK3288][Android6.0] Audio的ASOC驱动及数据结构
- [RK3288][Android6.0] Audio的DMA调用实例流程
- [RK3288][Android6.0] Audio的frame/period_size/bps_rate
- [RK3288][Android6.0] Audio的音量设置流程小结
- [RK3288][Android6.0] WiFi在Setting中的开启过程小结
- [RK3288][Android6.0] MediaCodec的configure配置过程小结
- [RK3288][Android6.0] WiFi的驱动初始化过程小结
- [RK3288][Android6.0] WiFi之无线网络配置的保存过程
- [RK3288][Android6.0] WiFi之无线网络配置的断开过程
- linux
- Skyline TerraExplorer 7.0- 扩展信息树
- sql笔记
- tomcat bio nio apr 模式 ---待自己整理
- 59_数组_模拟ArrayList容器的底层实现_JDK源码分析ArrayList
- [RK3288][Android6.0] Audio中的单声道到双声道的转换处理过程
- EAS 供应链,业务类型相关
- 【HTTP header】【Content-disposition 内容部署】
- MySQL锁系列(三)之 redo log
- Packet for query is too large (30697 > 1024)解决方案
- Kotlin Reference (七) feature: Range
- 转载-CSS导航菜单水平居中实例
- 编译caffe提示错误/usr/bin/ld: cannot find -lhdf5_hl
- spinner的简单使用