summaryrefslogtreecommitdiffstats
path: root/services/audioflinger
diff options
context:
space:
mode:
authorArne Coucheron <arco68@gmail.com>2015-12-04 22:26:44 +0100
committerSteve Kondik <shade@chemlab.org>2015-12-07 20:35:35 -0800
commit02d88d66c02982deec3aedee78c1f64352c539bc (patch)
tree2d0ef2ce131f048e77ffe5b766c2fd4fe8634726 /services/audioflinger
parent41ccd68b80a426236ee8ff511c22119e955bc548 (diff)
downloadframeworks_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/audioflinger')
-rw-r--r--services/audioflinger/Threads.cpp59
-rw-r--r--services/audioflinger/Threads.h5
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;