diff options
Diffstat (limited to 'services/audioflinger')
-rw-r--r-- | services/audioflinger/AudioMixer.cpp | 34 | ||||
-rw-r--r-- | services/audioflinger/AudioMixer.h | 21 |
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 { |