失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 声道切换 android [RK3288][Android6.0] Audio中的单声道到双声道的转换处理过程

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

时间:2024-07-03 21:08:03

相关推荐

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

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中的单声道到双声道的转换处理过程》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。