diff options
author | Arne Coucheron <arco68@gmail.com> | 2015-12-04 22:26:44 +0100 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2015-12-07 20:35:35 -0800 |
commit | 02d88d66c02982deec3aedee78c1f64352c539bc (patch) | |
tree | 2d0ef2ce131f048e77ffe5b766c2fd4fe8634726 /services | |
parent | 41ccd68b80a426236ee8ff511c22119e955bc548 (diff) | |
download | frameworks_av-02d88d66c02982deec3aedee78c1f64352c539bc.zip frameworks_av-02d88d66c02982deec3aedee78c1f64352c539bc.tar.gz frameworks_av-02d88d66c02982deec3aedee78c1f64352c539bc.tar.bz2 |
audioflinger: Don't do float conversion in upmix/downmix for legacy ALSA
Legacy ALSA really hates floating point, and it's breaking
mic input when doing things like audio recording.
Use the old conversion routine for legacy ALSA.
Change-Id: I616f4cd42fa0e4d7595dd61ed2d36c4fa7052c53
Diffstat (limited to 'services')
-rw-r--r-- | services/audioflinger/Threads.cpp | 59 | ||||
-rw-r--r-- | services/audioflinger/Threads.h | 5 |
2 files changed, 64 insertions, 0 deletions
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index e80221e..bc7b7dc 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -6586,7 +6586,11 @@ size_t AudioFlinger::RecordThread::RecordBufferConverter::convert(void *dst, break; } // format convert to destination buffer +#ifdef LEGACY_ALSA_AUDIO + convert(dst, buffer.raw, buffer.frameCount); +#else convertNoResampler(dst, buffer.raw, buffer.frameCount); +#endif dst = (int8_t*)dst + buffer.frameCount * mDstFrameSize; i -= buffer.frameCount; @@ -6606,7 +6610,11 @@ size_t AudioFlinger::RecordThread::RecordBufferConverter::convert(void *dst, memset(mBuf, 0, frames * mBufFrameSize); frames = mResampler->resample((int32_t*)mBuf, frames, provider); // format convert to destination buffer +#ifdef LEGACY_ALSA_AUDIO + convert(dst, mBuf, frames); +#else convertResampler(dst, mBuf, frames); +#endif } return frames; } @@ -6707,6 +6715,56 @@ status_t AudioFlinger::RecordThread::RecordBufferConverter::updateParameters( return NO_ERROR; } +#ifdef LEGACY_ALSA_AUDIO +void AudioFlinger::RecordThread::RecordBufferConverter::convert( + void *dst, /*const*/ void *src, size_t frames) +{ + // check if a memcpy will do + if (mResampler == NULL + && mSrcChannelCount == mDstChannelCount + && mSrcFormat == mDstFormat) { + memcpy(dst, src, + frames * mDstChannelCount * audio_bytes_per_sample(mDstFormat)); + return; + } + // reallocate buffer if needed + if (mBufFrameSize != 0 && mBufFrames < frames) { + free(mBuf); + mBufFrames = frames; + (void)posix_memalign(&mBuf, 32, mBufFrames * mBufFrameSize); + } + // do processing + if (mResampler != NULL) { + // src channel count is always >= 2. + void *dstBuf = mBuf != NULL ? mBuf : dst; + // ditherAndClamp() works as long as all buffers returned by + // activeTrack->getNextBuffer() are 32 bit aligned which should be always true. + if (mDstChannelCount == 1) { + // the resampler always outputs stereo samples. + // FIXME: this rewrites back into src + ditherAndClamp((int32_t *)src, (const int32_t *)src, frames); + downmix_to_mono_i16_from_stereo_i16((int16_t *)dstBuf, + (const int16_t *)src, frames); + } else { + ditherAndClamp((int32_t *)dstBuf, (const int32_t *)src, frames); + } + } else if (mSrcChannelCount != mDstChannelCount) { + void *dstBuf = mBuf != NULL ? mBuf : dst; + if (mSrcChannelCount == 1) { + upmix_to_stereo_i16_from_mono_i16((int16_t *)dstBuf, (const int16_t *)src, + frames); + } else { + downmix_to_mono_i16_from_stereo_i16((int16_t *)dstBuf, + (const int16_t *)src, frames); + } + } + if (mSrcFormat != mDstFormat) { + void *srcBuf = mBuf != NULL ? mBuf : src; + memcpy_by_audio_format(dst, mDstFormat, srcBuf, mSrcFormat, + frames * mDstChannelCount); + } +} +#else void AudioFlinger::RecordThread::RecordBufferConverter::convertNoResampler( void *dst, const void *src, size_t frames) { @@ -6780,6 +6838,7 @@ void AudioFlinger::RecordThread::RecordBufferConverter::convertResampler( memcpy_by_audio_format(dst, mDstFormat, src, AUDIO_FORMAT_PCM_FLOAT, frames * mDstChannelCount); } +#endif bool AudioFlinger::RecordThread::checkForNewParameter_l(const String8& keyValuePair, status_t& status) diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 9e32ea1..6182364 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -1160,11 +1160,16 @@ public: } private: +#ifdef LEGACY_ALSA_AUDIO + // internal convert function for format and channel mask. + void convert(void *dst, /*const*/ void *src, size_t frames); +#else // format conversion when not using resampler void convertNoResampler(void *dst, const void *src, size_t frames); // format conversion when using resampler; modifies src in-place void convertResampler(void *dst, /*not-a-const*/ void *src, size_t frames); +#endif // user provided information audio_channel_mask_t mSrcChannelMask; |