blob: 3f7cd48876beaaf202f108fbe93db648773410ed [file] [log] [blame]
Glenn Kasten99e53b82012-01-19 08:59:58 -08001/*
Mathias Agopian65ab4712010-07-14 17:59:35 -07002**
3** Copyright 2007, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#ifndef ANDROID_AUDIO_MIXER_H
19#define ANDROID_AUDIO_MIXER_H
20
Andy Hung8ed196a2018-01-05 13:21:11 -080021#include <pthread.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070022#include <stdint.h>
23#include <sys/types.h>
24
jiabinbf6b0ec2019-02-12 12:30:12 -080025#include <android/os/IExternalVibratorService.h>
Mikhail Naganov32f0d162019-07-30 14:42:32 -070026#include <media/AudioMixerBase.h>
Andy Hung068561c2017-01-03 17:09:32 -080027#include <media/BufferProviders.h>
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070028#include <utils/threads.h>
29
Glenn Kastenc56f3422014-03-21 17:53:17 -070030// FIXME This is actually unity gain, which might not be max in future, expressed in U.12
Mikhail Naganov32f0d162019-07-30 14:42:32 -070031#define MAX_GAIN_INT AudioMixerBase::UNITY_GAIN_INT
Andy Hung116a4982017-11-30 10:15:08 -080032
Mathias Agopian65ab4712010-07-14 17:59:35 -070033namespace android {
34
35// ----------------------------------------------------------------------------
36
Mikhail Naganov32f0d162019-07-30 14:42:32 -070037// AudioMixer extends AudioMixerBase by adding support for down- and up-mixing
38// and time stretch that are implemented via Effects HAL, and adding support
39// for haptic channels which depends on Vibrator service. This is the version
40// that is used by Audioflinger.
41
42class AudioMixer : public AudioMixerBase
Mathias Agopian65ab4712010-07-14 17:59:35 -070043{
44public:
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070045 // maximum number of channels supported for the content
Andy Hunge93b6b72014-07-17 21:30:53 -070046 static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = AUDIO_CHANNEL_COUNT_MAX;
Mathias Agopian65ab4712010-07-14 17:59:35 -070047
Mikhail Naganov32f0d162019-07-30 14:42:32 -070048 enum { // extension of AudioMixerBase parameters
49 DOWNMIX_TYPE = 0x4004,
jiabin245cdd92018-12-07 17:55:15 -080050 // for haptic
51 HAPTIC_ENABLED = 0x4007, // Set haptic data from this track should be played or not.
jiabin77270b82018-12-18 15:41:29 -080052 HAPTIC_INTENSITY = 0x4008, // Set the intensity to play haptic data.
Andy Hungc5656cc2015-03-26 19:04:33 -070053 // for target TIMESTRETCH
54 PLAYBACK_RATE = 0x4300, // Configure timestretch on this track name;
55 // parameter 'value' is a pointer to the new playback rate.
Mathias Agopian65ab4712010-07-14 17:59:35 -070056 };
57
jiabinbf6b0ec2019-02-12 12:30:12 -080058 typedef enum { // Haptic intensity, should keep consistent with VibratorService
59 HAPTIC_SCALE_MUTE = os::IExternalVibratorService::SCALE_MUTE,
60 HAPTIC_SCALE_VERY_LOW = os::IExternalVibratorService::SCALE_VERY_LOW,
61 HAPTIC_SCALE_LOW = os::IExternalVibratorService::SCALE_LOW,
62 HAPTIC_SCALE_NONE = os::IExternalVibratorService::SCALE_NONE,
63 HAPTIC_SCALE_HIGH = os::IExternalVibratorService::SCALE_HIGH,
64 HAPTIC_SCALE_VERY_HIGH = os::IExternalVibratorService::SCALE_VERY_HIGH,
65 } haptic_intensity_t;
66 static constexpr float HAPTIC_SCALE_VERY_LOW_RATIO = 2.0f / 3.0f;
67 static constexpr float HAPTIC_SCALE_LOW_RATIO = 3.0f / 4.0f;
68 static const constexpr float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f;
jiabin77270b82018-12-18 15:41:29 -080069
70 static inline bool isValidHapticIntensity(haptic_intensity_t hapticIntensity) {
71 switch (hapticIntensity) {
jiabinbf6b0ec2019-02-12 12:30:12 -080072 case HAPTIC_SCALE_MUTE:
jiabin77270b82018-12-18 15:41:29 -080073 case HAPTIC_SCALE_VERY_LOW:
74 case HAPTIC_SCALE_LOW:
75 case HAPTIC_SCALE_NONE:
76 case HAPTIC_SCALE_HIGH:
77 case HAPTIC_SCALE_VERY_HIGH:
78 return true;
79 default:
80 return false;
81 }
82 }
83
Andy Hung1bc088a2018-02-09 15:57:31 -080084 AudioMixer(size_t frameCount, uint32_t sampleRate)
Mikhail Naganov32f0d162019-07-30 14:42:32 -070085 : AudioMixerBase(frameCount, sampleRate) {
Andy Hung8ed196a2018-01-05 13:21:11 -080086 pthread_once(&sOnceControl, &sInitRoutine);
87 }
Mathias Agopian65ab4712010-07-14 17:59:35 -070088
Mikhail Naganov32f0d162019-07-30 14:42:32 -070089 bool isValidChannelMask(audio_channel_mask_t channelMask) const override;
Glenn Kasten17a736c2012-02-14 08:52:15 -080090
Mikhail Naganov32f0d162019-07-30 14:42:32 -070091 void setParameter(int name, int target, int param, void *value) override;
92 void setBufferProvider(int name, AudioBufferProvider* bufferProvider);
Andy Hung1bc088a2018-02-09 15:57:31 -080093
Mathias Agopian65ab4712010-07-14 17:59:35 -070094private:
95
Mikhail Naganov32f0d162019-07-30 14:42:32 -070096 struct Track : public TrackBase {
97 Track() : TrackBase() {}
Andy Hung8ed196a2018-01-05 13:21:11 -080098
99 ~Track()
100 {
Mikhail Naganov32f0d162019-07-30 14:42:32 -0700101 // mInputBufferProvider need not be deleted.
Andy Hung8ed196a2018-01-05 13:21:11 -0800102 // Ensure the order of destruction of buffer providers as they
103 // release the upstream provider in the destructor.
104 mTimestretchBufferProvider.reset(nullptr);
105 mPostDownmixReformatBufferProvider.reset(nullptr);
106 mDownmixerBufferProvider.reset(nullptr);
107 mReformatBufferProvider.reset(nullptr);
jiabinea8fa7a2019-02-22 14:41:50 -0800108 mContractChannelsNonDestructiveBufferProvider.reset(nullptr);
jiabindce8f8c2018-12-10 17:49:31 -0800109 mAdjustChannelsBufferProvider.reset(nullptr);
Andy Hung8ed196a2018-01-05 13:21:11 -0800110 }
111
Mikhail Naganov32f0d162019-07-30 14:42:32 -0700112 uint32_t getOutputChannelCount() override {
113 return mDownmixerBufferProvider.get() != nullptr ? mMixerChannelCount : channelCount;
114 }
115 uint32_t getMixerChannelCount() override {
116 return mMixerChannelCount + mMixerHapticChannelCount;
117 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800118
119 status_t prepareForDownmix();
120 void unprepareForDownmix();
121 status_t prepareForReformat();
122 void unprepareForReformat();
jiabindce8f8c2018-12-10 17:49:31 -0800123 status_t prepareForAdjustChannels();
124 void unprepareForAdjustChannels();
125 status_t prepareForAdjustChannelsNonDestructive(size_t frames);
126 void unprepareForAdjustChannelsNonDestructive();
127 void clearContractedBuffer();
Andy Hung8ed196a2018-01-05 13:21:11 -0800128 bool setPlaybackRate(const AudioPlaybackRate &playbackRate);
129 void reconfigureBufferProviders();
130
Andy Hung7f475492014-08-25 16:36:37 -0700131 /* Buffer providers are constructed to translate the track input data as needed.
Mikhail Naganov32f0d162019-07-30 14:42:32 -0700132 * See DownmixerBufferProvider below for how the Track buffer provider
133 * is wrapped by another one when dowmixing is required.
Andy Hung7f475492014-08-25 16:36:37 -0700134 *
Andy Hungc5656cc2015-03-26 19:04:33 -0700135 * TODO: perhaps make a single PlaybackConverterProvider class to move
136 * all pre-mixer track buffer conversions outside the AudioMixer class.
137 *
Andy Hung7f475492014-08-25 16:36:37 -0700138 * 1) mInputBufferProvider: The AudioTrack buffer provider.
jiabinea8fa7a2019-02-22 14:41:50 -0800139 * 2) mAdjustChannelsBufferProvider: Expands or contracts sample data from one interleaved
140 * channel format to another. Expanded channels are filled with zeros and put at the end
141 * of each audio frame. Contracted channels are copied to the end of the buffer.
142 * 3) mContractChannelsNonDestructiveBufferProvider: Non-destructively contract sample data.
143 * This is currently using at audio-haptic coupled playback to separate audio and haptic
144 * data. Contracted channels could be written to given buffer.
jiabindce8f8c2018-12-10 17:49:31 -0800145 * 4) mReformatBufferProvider: If not NULL, performs the audio reformat to
Andy Hung7f475492014-08-25 16:36:37 -0700146 * match either mMixerInFormat or mDownmixRequiresFormat, if the downmixer
147 * requires reformat. For example, it may convert floating point input to
148 * PCM_16_bit if that's required by the downmixer.
jiabindce8f8c2018-12-10 17:49:31 -0800149 * 5) mDownmixerBufferProvider: If not NULL, performs the channel remixing to match
Andy Hung7f475492014-08-25 16:36:37 -0700150 * the number of channels required by the mixer sink.
jiabindce8f8c2018-12-10 17:49:31 -0800151 * 6) mPostDownmixReformatBufferProvider: If not NULL, performs reformatting from
Andy Hung7f475492014-08-25 16:36:37 -0700152 * the downmixer requirements to the mixer engine input requirements.
jiabindce8f8c2018-12-10 17:49:31 -0800153 * 7) mTimestretchBufferProvider: Adds timestretching for playback rate
Andy Hung7f475492014-08-25 16:36:37 -0700154 */
Mikhail Naganova4f00e22019-07-31 14:53:29 -0700155 AudioBufferProvider* mInputBufferProvider; // externally provided buffer provider.
jiabinea8fa7a2019-02-22 14:41:50 -0800156 // TODO: combine mAdjustChannelsBufferProvider and
157 // mContractChannelsNonDestructiveBufferProvider
jiabindce8f8c2018-12-10 17:49:31 -0800158 std::unique_ptr<PassthruBufferProvider> mAdjustChannelsBufferProvider;
jiabinea8fa7a2019-02-22 14:41:50 -0800159 std::unique_ptr<PassthruBufferProvider> mContractChannelsNonDestructiveBufferProvider;
Andy Hung8ed196a2018-01-05 13:21:11 -0800160 std::unique_ptr<PassthruBufferProvider> mReformatBufferProvider;
161 std::unique_ptr<PassthruBufferProvider> mDownmixerBufferProvider;
162 std::unique_ptr<PassthruBufferProvider> mPostDownmixReformatBufferProvider;
163 std::unique_ptr<PassthruBufferProvider> mTimestretchBufferProvider;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700164
Andy Hung7f475492014-08-25 16:36:37 -0700165 audio_format_t mDownmixRequiresFormat; // required downmixer format
166 // AUDIO_FORMAT_PCM_16_BIT if 16 bit necessary
167 // AUDIO_FORMAT_INVALID if no required format
Andy Hungef7c7fb2014-05-12 16:51:41 -0700168
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700169 AudioPlaybackRate mPlaybackRate;
Andy Hungc5656cc2015-03-26 19:04:33 -0700170
jiabindce8f8c2018-12-10 17:49:31 -0800171 // Haptic
jiabin245cdd92018-12-07 17:55:15 -0800172 bool mHapticPlaybackEnabled;
jiabin77270b82018-12-18 15:41:29 -0800173 haptic_intensity_t mHapticIntensity;
jiabin245cdd92018-12-07 17:55:15 -0800174 audio_channel_mask_t mHapticChannelMask;
175 uint32_t mHapticChannelCount;
176 audio_channel_mask_t mMixerHapticChannelMask;
177 uint32_t mMixerHapticChannelCount;
jiabindce8f8c2018-12-10 17:49:31 -0800178 uint32_t mAdjustInChannelCount;
179 uint32_t mAdjustOutChannelCount;
180 uint32_t mAdjustNonDestructiveInChannelCount;
181 uint32_t mAdjustNonDestructiveOutChannelCount;
182 bool mKeepContractedChannels;
183
jiabin77270b82018-12-18 15:41:29 -0800184 float getHapticScaleGamma() const {
185 // Need to keep consistent with the value in VibratorService.
186 switch (mHapticIntensity) {
187 case HAPTIC_SCALE_VERY_LOW:
188 return 2.0f;
189 case HAPTIC_SCALE_LOW:
190 return 1.5f;
191 case HAPTIC_SCALE_HIGH:
192 return 0.5f;
193 case HAPTIC_SCALE_VERY_HIGH:
194 return 0.25f;
195 default:
196 return 1.0f;
197 }
198 }
199
200 float getHapticMaxAmplitudeRatio() const {
201 // Need to keep consistent with the value in VibratorService.
202 switch (mHapticIntensity) {
203 case HAPTIC_SCALE_VERY_LOW:
204 return HAPTIC_SCALE_VERY_LOW_RATIO;
205 case HAPTIC_SCALE_LOW:
206 return HAPTIC_SCALE_LOW_RATIO;
207 case HAPTIC_SCALE_NONE:
208 case HAPTIC_SCALE_HIGH:
209 case HAPTIC_SCALE_VERY_HIGH:
jiabin77270b82018-12-18 15:41:29 -0800210 return 1.0f;
jiabinbf6b0ec2019-02-12 12:30:12 -0800211 default:
212 return 0.0f;
jiabin77270b82018-12-18 15:41:29 -0800213 }
214 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700215 };
216
Mikhail Naganov32f0d162019-07-30 14:42:32 -0700217 inline std::shared_ptr<Track> getTrack(int name) {
218 return std::static_pointer_cast<Track>(mTracks[name]);
Andy Hung8ed196a2018-01-05 13:21:11 -0800219 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700220
Mikhail Naganov32f0d162019-07-30 14:42:32 -0700221 std::shared_ptr<TrackBase> preCreateTrack() override;
222 status_t postCreateTrack(TrackBase *track) override;
John Grossman4ff14ba2012-02-08 16:37:41 -0800223
Mikhail Naganov32f0d162019-07-30 14:42:32 -0700224 void preProcess() override;
225 void postProcess() override;
Andy Hung296b7412014-06-17 15:25:47 -0700226
Mikhail Naganov32f0d162019-07-30 14:42:32 -0700227 bool setChannelMasks(int name,
228 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) override;
Andy Hung296b7412014-06-17 15:25:47 -0700229
Andy Hung8ed196a2018-01-05 13:21:11 -0800230 static void sInitRoutine();
231
Andy Hung8ed196a2018-01-05 13:21:11 -0800232 static pthread_once_t sOnceControl; // initialized in constructor by first new
Mathias Agopian65ab4712010-07-14 17:59:35 -0700233};
234
235// ----------------------------------------------------------------------------
Glenn Kasten63238ef2015-03-02 15:50:29 -0800236} // namespace android
Mathias Agopian65ab4712010-07-14 17:59:35 -0700237
238#endif // ANDROID_AUDIO_MIXER_H