summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--services/audioflinger/AudioMixer.cpp34
-rw-r--r--services/audioflinger/AudioMixer.h21
2 files changed, 53 insertions, 2 deletions
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index ba135c6..529f2af 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -62,6 +62,10 @@
#define ALOGVV(a...) do { } while (0)
#endif
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
+#endif
+
// Set kUseNewMixer to true to use the new mixer engine. Otherwise the
// original code will be used. This is false for now.
static const bool kUseNewMixer = false;
@@ -317,6 +321,36 @@ void AudioMixer::DownmixerBufferProvider::copyFrames(void *dst, const void *src,
/*static*/ bool AudioMixer::DownmixerBufferProvider::sIsMultichannelCapable = false;
/*static*/ effect_descriptor_t AudioMixer::DownmixerBufferProvider::sDwnmFxDesc;
+AudioMixer::RemixBufferProvider::RemixBufferProvider(audio_channel_mask_t inputChannelMask,
+ audio_channel_mask_t outputChannelMask, audio_format_t format,
+ size_t bufferFrameCount) :
+ CopyBufferProvider(
+ audio_bytes_per_sample(format)
+ * audio_channel_count_from_out_mask(inputChannelMask),
+ audio_bytes_per_sample(format)
+ * audio_channel_count_from_out_mask(outputChannelMask),
+ bufferFrameCount),
+ mFormat(format),
+ mSampleSize(audio_bytes_per_sample(format)),
+ mInputChannels(audio_channel_count_from_out_mask(inputChannelMask)),
+ mOutputChannels(audio_channel_count_from_out_mask(outputChannelMask))
+{
+ ALOGV("RemixBufferProvider(%p)(%#x, %#x, %#x) %d %d",
+ this, format, inputChannelMask, outputChannelMask,
+ mInputChannels, mOutputChannels);
+ // TODO: consider channel representation in index array formulation
+ // We ignore channel representation, and just use the bits.
+ memcpy_by_index_array_initialization(mIdxAry, ARRAY_SIZE(mIdxAry),
+ audio_channel_mask_get_bits(outputChannelMask),
+ audio_channel_mask_get_bits(inputChannelMask));
+}
+
+void AudioMixer::RemixBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
+{
+ memcpy_by_index_array(dst, mOutputChannels,
+ src, mInputChannels, mIdxAry, mSampleSize, frames);
+}
+
AudioMixer::ReformatBufferProvider::ReformatBufferProvider(int32_t channels,
audio_format_t inputFormat, audio_format_t outputFormat,
size_t bufferFrameCount) :
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index 7ad2e75..09a4d89 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -252,8 +252,8 @@ private:
track_t tracks[MAX_NUM_TRACKS] __attribute__((aligned(32)));
};
- // Base AudioBufferProvider class used for ReformatBufferProvider and
- // DownmixerBufferProvider.
+ // Base AudioBufferProvider class used for DownMixerBufferProvider, RemixBufferProvider,
+ // and ReformatBufferProvider.
// It handles a private buffer for use in converting format or channel masks from the
// input data to a form acceptable by the mixer.
// TODO: Make a ResamplerBufferProvider when integers are entirely removed from the
@@ -326,6 +326,23 @@ private:
static const int32_t SESSION_ID_INVALID_AND_IGNORED = -2;
};
+ // RemixBufferProvider wraps a track AudioBufferProvider to perform an
+ // upmix or downmix to the proper channel count and mask.
+ class RemixBufferProvider : public CopyBufferProvider {
+ public:
+ RemixBufferProvider(audio_channel_mask_t inputChannelMask,
+ audio_channel_mask_t outputChannelMask, audio_format_t format,
+ size_t bufferFrameCount);
+ virtual void copyFrames(void *dst, const void *src, size_t frames);
+
+ protected:
+ const audio_format_t mFormat;
+ const size_t mSampleSize;
+ const size_t mInputChannels;
+ const size_t mOutputChannels;
+ int8_t mIdxAry[sizeof(uint32_t)*8]; // 32 bits => channel indices
+ };
+
// ReformatBufferProvider wraps a track AudioBufferProvider to convert the input data
// to an acceptable mixer input format type.
class ReformatBufferProvider : public CopyBufferProvider {