1 /*
2 **
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 
21 #include <pthread.h>
22 #include <stdint.h>
23 #include <sys/types.h>
24 
25 #include <android/os/IExternalVibratorService.h>
26 #include <media/AudioMixerBase.h>
27 #include <media/BufferProviders.h>
28 #include <utils/threads.h>
29 
30 // FIXME This is actually unity gain, which might not be max in future, expressed in U.12
31 #define MAX_GAIN_INT AudioMixerBase::UNITY_GAIN_INT
32 
33 namespace android {
34 
35 // ----------------------------------------------------------------------------
36 
37 // 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 
42 class AudioMixer : public AudioMixerBase
43 {
44 public:
45     // maximum number of channels supported for the content
46     static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = AUDIO_CHANNEL_COUNT_MAX;
47 
48     enum { // extension of AudioMixerBase parameters
49         DOWNMIX_TYPE    = 0x4004,
50         // for haptic
51         HAPTIC_ENABLED  = 0x4007, // Set haptic data from this track should be played or not.
52         HAPTIC_INTENSITY = 0x4008, // Set the intensity to play haptic data.
53         // for target TIMESTRETCH
54         PLAYBACK_RATE   = 0x4300, // Configure timestretch on this track name;
55                                   // parameter 'value' is a pointer to the new playback rate.
56     };
57 
58     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;
69 
isValidHapticIntensity(haptic_intensity_t hapticIntensity)70     static inline bool isValidHapticIntensity(haptic_intensity_t hapticIntensity) {
71         switch (hapticIntensity) {
72         case HAPTIC_SCALE_MUTE:
73         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 
AudioMixer(size_t frameCount,uint32_t sampleRate)84     AudioMixer(size_t frameCount, uint32_t sampleRate)
85             : AudioMixerBase(frameCount, sampleRate) {
86         pthread_once(&sOnceControl, &sInitRoutine);
87     }
88 
89     bool isValidChannelMask(audio_channel_mask_t channelMask) const override;
90 
91     void setParameter(int name, int target, int param, void *value) override;
92     void setBufferProvider(int name, AudioBufferProvider* bufferProvider);
93 
94 private:
95 
96     struct Track : public TrackBase {
TrackTrack97         Track() : TrackBase() {}
98 
~TrackTrack99         ~Track()
100         {
101             // mInputBufferProvider need not be deleted.
102             // 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);
108             mContractChannelsNonDestructiveBufferProvider.reset(nullptr);
109             mAdjustChannelsBufferProvider.reset(nullptr);
110         }
111 
getOutputChannelCountTrack112         uint32_t getOutputChannelCount() override {
113             return mDownmixerBufferProvider.get() != nullptr ? mMixerChannelCount : channelCount;
114         }
getMixerChannelCountTrack115         uint32_t getMixerChannelCount() override {
116             return mMixerChannelCount + mMixerHapticChannelCount;
117         }
118 
119         status_t    prepareForDownmix();
120         void        unprepareForDownmix();
121         status_t    prepareForReformat();
122         void        unprepareForReformat();
123         status_t    prepareForAdjustChannels();
124         void        unprepareForAdjustChannels();
125         status_t    prepareForAdjustChannelsNonDestructive(size_t frames);
126         void        unprepareForAdjustChannelsNonDestructive();
127         void        clearContractedBuffer();
128         bool        setPlaybackRate(const AudioPlaybackRate &playbackRate);
129         void        reconfigureBufferProviders();
130 
131         /* Buffer providers are constructed to translate the track input data as needed.
132          * See DownmixerBufferProvider below for how the Track buffer provider
133          * is wrapped by another one when dowmixing is required.
134          *
135          * TODO: perhaps make a single PlaybackConverterProvider class to move
136          * all pre-mixer track buffer conversions outside the AudioMixer class.
137          *
138          * 1) mInputBufferProvider: The AudioTrack buffer provider.
139          * 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.
145          * 4) mReformatBufferProvider: If not NULL, performs the audio reformat to
146          *    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.
149          * 5) mDownmixerBufferProvider: If not NULL, performs the channel remixing to match
150          *    the number of channels required by the mixer sink.
151          * 6) mPostDownmixReformatBufferProvider: If not NULL, performs reformatting from
152          *    the downmixer requirements to the mixer engine input requirements.
153          * 7) mTimestretchBufferProvider: Adds timestretching for playback rate
154          */
155         AudioBufferProvider* mInputBufferProvider;    // externally provided buffer provider.
156         // TODO: combine mAdjustChannelsBufferProvider and
157         // mContractChannelsNonDestructiveBufferProvider
158         std::unique_ptr<PassthruBufferProvider> mAdjustChannelsBufferProvider;
159         std::unique_ptr<PassthruBufferProvider> mContractChannelsNonDestructiveBufferProvider;
160         std::unique_ptr<PassthruBufferProvider> mReformatBufferProvider;
161         std::unique_ptr<PassthruBufferProvider> mDownmixerBufferProvider;
162         std::unique_ptr<PassthruBufferProvider> mPostDownmixReformatBufferProvider;
163         std::unique_ptr<PassthruBufferProvider> mTimestretchBufferProvider;
164 
165         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
168 
169         AudioPlaybackRate    mPlaybackRate;
170 
171         // Haptic
172         bool                 mHapticPlaybackEnabled;
173         haptic_intensity_t   mHapticIntensity;
174         audio_channel_mask_t mHapticChannelMask;
175         uint32_t             mHapticChannelCount;
176         audio_channel_mask_t mMixerHapticChannelMask;
177         uint32_t             mMixerHapticChannelCount;
178         uint32_t             mAdjustInChannelCount;
179         uint32_t             mAdjustOutChannelCount;
180         uint32_t             mAdjustNonDestructiveInChannelCount;
181         uint32_t             mAdjustNonDestructiveOutChannelCount;
182         bool                 mKeepContractedChannels;
183 
getHapticScaleGammaTrack184         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 
getHapticMaxAmplitudeRatioTrack200         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:
210             return 1.0f;
211         default:
212             return 0.0f;
213         }
214         }
215     };
216 
getTrack(int name)217     inline std::shared_ptr<Track> getTrack(int name) {
218         return std::static_pointer_cast<Track>(mTracks[name]);
219     }
220 
221     std::shared_ptr<TrackBase> preCreateTrack() override;
222     status_t postCreateTrack(TrackBase *track) override;
223 
224     void preProcess() override;
225     void postProcess() override;
226 
227     bool setChannelMasks(int name,
228             audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) override;
229 
230     static void sInitRoutine();
231 
232     static pthread_once_t sOnceControl; // initialized in constructor by first new
233 };
234 
235 // ----------------------------------------------------------------------------
236 } // namespace android
237 
238 #endif // ANDROID_AUDIO_MIXER_H
239