1 /*
2 **
3 ** Copyright 2019, 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_BASE_H
19 #define ANDROID_AUDIO_MIXER_BASE_H
20 
21 #include <map>
22 #include <memory>
23 #include <string>
24 #include <unordered_map>
25 #include <vector>
26 
27 #include <media/AudioBufferProvider.h>
28 #include <media/AudioResampler.h>
29 #include <media/AudioResamplerPublic.h>
30 #include <system/audio.h>
31 #include <utils/Compat.h>
32 
33 // This must match frameworks/av/services/audioflinger/Configuration.h
34 // when used with the Audio Framework.
35 #define FLOAT_AUX
36 
37 namespace android {
38 
39 // ----------------------------------------------------------------------------
40 
41 // AudioMixerBase is functional on its own if only mixing and resampling
42 // is needed.
43 
44 class AudioMixerBase
45 {
46 public:
47     // Do not change these unless underlying code changes.
48     // This mixer has a hard-coded upper limit of 8 channels for output.
49     static constexpr uint32_t MAX_NUM_CHANNELS = FCC_8;
50     static constexpr uint32_t MAX_NUM_VOLUMES = FCC_2; // stereo volume only
51 
52     static const uint16_t UNITY_GAIN_INT = 0x1000;
53     static const CONSTEXPR float UNITY_GAIN_FLOAT = 1.0f;
54 
55     enum { // names
56         // setParameter targets
57         TRACK           = 0x3000,
58         RESAMPLE        = 0x3001,
59         RAMP_VOLUME     = 0x3002, // ramp to new volume
60         VOLUME          = 0x3003, // don't ramp
61         TIMESTRETCH     = 0x3004,
62 
63         // set Parameter names
64         // for target TRACK
65         CHANNEL_MASK    = 0x4000,
66         FORMAT          = 0x4001,
67         MAIN_BUFFER     = 0x4002,
68         AUX_BUFFER      = 0x4003,
69         // 0x4004 reserved
70         MIXER_FORMAT    = 0x4005, // AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
71         MIXER_CHANNEL_MASK = 0x4006, // Channel mask for mixer output
72         // for target RESAMPLE
73         SAMPLE_RATE     = 0x4100, // Configure sample rate conversion on this track name;
74                                   // parameter 'value' is the new sample rate in Hz.
75                                   // Only creates a sample rate converter the first time that
76                                   // the track sample rate is different from the mix sample rate.
77                                   // If the new sample rate is the same as the mix sample rate,
78                                   // and a sample rate converter already exists,
79                                   // then the sample rate converter remains present but is a no-op.
80         RESET           = 0x4101, // Reset sample rate converter without changing sample rate.
81                                   // This clears out the resampler's input buffer.
82         REMOVE          = 0x4102, // Remove the sample rate converter on this track name;
83                                   // the track is restored to the mix sample rate.
84         // for target RAMP_VOLUME and VOLUME (8 channels max)
85         // FIXME use float for these 3 to improve the dynamic range
86         VOLUME0         = 0x4200,
87         VOLUME1         = 0x4201,
88         AUXLEVEL        = 0x4210,
89     };
90 
AudioMixerBase(size_t frameCount,uint32_t sampleRate)91     AudioMixerBase(size_t frameCount, uint32_t sampleRate)
92         : mSampleRate(sampleRate)
93         , mFrameCount(frameCount) {
94     }
95 
~AudioMixerBase()96     virtual ~AudioMixerBase() {}
97 
98     virtual bool isValidFormat(audio_format_t format) const;
99     virtual bool isValidChannelMask(audio_channel_mask_t channelMask) const;
100 
101     // Create a new track in the mixer.
102     //
103     // \param name        a unique user-provided integer associated with the track.
104     //                    If name already exists, the function will abort.
105     // \param channelMask output channel mask.
106     // \param format      PCM format
107     // \param sessionId   Session id for the track. Tracks with the same
108     //                    session id will be submixed together.
109     //
110     // \return OK        on success.
111     //         BAD_VALUE if the format does not satisfy isValidFormat()
112     //                   or the channelMask does not satisfy isValidChannelMask().
113     status_t    create(
114             int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId);
115 
exists(int name)116     bool        exists(int name) const {
117         return mTracks.count(name) > 0;
118     }
119 
120     // Free an allocated track by name.
121     void        destroy(int name);
122 
123     // Enable or disable an allocated track by name
124     void        enable(int name);
125     void        disable(int name);
126 
127     virtual void setParameter(int name, int target, int param, void *value);
128 
process()129     void        process() {
130         preProcess();
131         (this->*mHook)();
132         postProcess();
133     }
134 
135     size_t      getUnreleasedFrames(int name) const;
136 
137     std::string trackNames() const;
138 
139   protected:
140     // Set kUseNewMixer to true to use the new mixer engine always. Otherwise the
141     // original code will be used for stereo sinks, the new mixer for everything else.
142     static constexpr bool kUseNewMixer = true;
143 
144     // Set kUseFloat to true to allow floating input into the mixer engine.
145     // If kUseNewMixer is false, this is ignored or may be overridden internally
146     static constexpr bool kUseFloat = true;
147 
148 #ifdef FLOAT_AUX
149     using TYPE_AUX = float;
150     static_assert(kUseNewMixer && kUseFloat,
151             "kUseNewMixer and kUseFloat must be true for FLOAT_AUX option");
152 #else
153     using TYPE_AUX = int32_t; // q4.27
154 #endif
155 
156     /* For multi-format functions (calls template functions
157      * in AudioMixerOps.h).  The template parameters are as follows:
158      *
159      *   MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
160      *   USEFLOATVOL (set to true if float volume is used)
161      *   ADJUSTVOL   (set to true if volume ramp parameters needs adjustment afterwards)
162      *   TO: int32_t (Q4.27) or float
163      *   TI: int32_t (Q4.27) or int16_t (Q0.15) or float
164      *   TA: int32_t (Q4.27)
165      */
166 
167     enum {
168         // FIXME this representation permits up to 8 channels
169         NEEDS_CHANNEL_COUNT__MASK   = 0x00000007,
170     };
171 
172     enum {
173         NEEDS_CHANNEL_1             = 0x00000000,   // mono
174         NEEDS_CHANNEL_2             = 0x00000001,   // stereo
175 
176         // sample format is not explicitly specified, and is assumed to be AUDIO_FORMAT_PCM_16_BIT
177 
178         NEEDS_MUTE                  = 0x00000100,
179         NEEDS_RESAMPLE              = 0x00001000,
180         NEEDS_AUX                   = 0x00010000,
181     };
182 
183     // hook types
184     enum {
185         PROCESSTYPE_NORESAMPLEONETRACK, // others set elsewhere
186     };
187 
188     enum {
189         TRACKTYPE_NOP,
190         TRACKTYPE_RESAMPLE,
191         TRACKTYPE_RESAMPLEMONO,
192         TRACKTYPE_RESAMPLESTEREO,
193         TRACKTYPE_NORESAMPLE,
194         TRACKTYPE_NORESAMPLEMONO,
195         TRACKTYPE_NORESAMPLESTEREO,
196     };
197 
198     // process hook functionality
199     using process_hook_t = void(AudioMixerBase::*)();
200 
isAudioChannelPositionMask(audio_channel_mask_t channelMask)201     static bool isAudioChannelPositionMask(audio_channel_mask_t channelMask) {
202         return audio_channel_mask_get_representation(channelMask)
203                 == AUDIO_CHANNEL_REPRESENTATION_POSITION;
204     }
205 
206     struct TrackBase;
207     using hook_t = void(TrackBase::*)(
208             int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux);
209 
210     struct TrackBase {
TrackBaseTrackBase211         TrackBase()
212             : bufferProvider(nullptr)
213         {
214             // TODO: move additional initialization here.
215         }
~TrackBaseTrackBase216         virtual ~TrackBase() {}
217 
getOutputChannelCountTrackBase218         virtual uint32_t getOutputChannelCount() { return channelCount; }
getMixerChannelCountTrackBase219         virtual uint32_t getMixerChannelCount() { return mMixerChannelCount; }
220 
needsRampTrackBase221         bool        needsRamp() { return (volumeInc[0] | volumeInc[1] | auxInc) != 0; }
222         bool        setResampler(uint32_t trackSampleRate, uint32_t devSampleRate);
doesResampleTrackBase223         bool        doesResample() const { return mResampler.get() != nullptr; }
224         void        recreateResampler(uint32_t devSampleRate);
resetResamplerTrackBase225         void        resetResampler() { if (mResampler.get() != nullptr) mResampler->reset(); }
226         void        adjustVolumeRamp(bool aux, bool useFloat = false);
getUnreleasedFramesTrackBase227         size_t      getUnreleasedFrames() const { return mResampler.get() != nullptr ?
228                                                     mResampler->getUnreleasedFrames() : 0; };
229 
useStereoVolumeTrackBase230         bool        useStereoVolume() const { return channelMask == AUDIO_CHANNEL_OUT_STEREO
231                                         && isAudioChannelPositionMask(mMixerChannelMask); }
232 
233         static hook_t getTrackHook(int trackType, uint32_t channelCount,
234                 audio_format_t mixerInFormat, audio_format_t mixerOutFormat);
235 
236         void track__nop(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
237 
238         template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
239             typename TO, typename TI, typename TA>
240         void volumeMix(TO *out, size_t outFrames, const TI *in, TA *aux, bool ramp);
241 
242         uint32_t    needs;
243 
244         // TODO: Eventually remove legacy integer volume settings
245         union {
246         int16_t     volume[MAX_NUM_VOLUMES]; // U4.12 fixed point (top bit should be zero)
247         int32_t     volumeRL;
248         };
249 
250         int32_t     prevVolume[MAX_NUM_VOLUMES];
251         int32_t     volumeInc[MAX_NUM_VOLUMES];
252         int32_t     auxInc;
253         int32_t     prevAuxLevel;
254         int16_t     auxLevel;       // 0 <= auxLevel <= MAX_GAIN_INT, but signed for mul performance
255 
256         uint16_t    frameCount;
257 
258         uint8_t     channelCount;   // 1 or 2, redundant with (needs & NEEDS_CHANNEL_COUNT__MASK)
259         uint8_t     unused_padding; // formerly format, was always 16
260         uint16_t    enabled;        // actually bool
261         audio_channel_mask_t channelMask;
262 
263         // actual buffer provider used by the track hooks
264         AudioBufferProvider*                bufferProvider;
265 
266         mutable AudioBufferProvider::Buffer buffer; // 8 bytes
267 
268         hook_t      hook;
269         const void  *mIn;             // current location in buffer
270 
271         std::unique_ptr<AudioResampler> mResampler;
272         uint32_t    sampleRate;
273         int32_t*    mainBuffer;
274         int32_t*    auxBuffer;
275 
276         int32_t     sessionId;
277 
278         audio_format_t mMixerFormat;     // output mix format: AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
279         audio_format_t mFormat;          // input track format
280         audio_format_t mMixerInFormat;   // mix internal format AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
281                                          // each track must be converted to this format.
282 
283         float          mVolume[MAX_NUM_VOLUMES];     // floating point set volume
284         float          mPrevVolume[MAX_NUM_VOLUMES]; // floating point previous volume
285         float          mVolumeInc[MAX_NUM_VOLUMES];  // floating point volume increment
286 
287         float          mAuxLevel;                     // floating point set aux level
288         float          mPrevAuxLevel;                 // floating point prev aux level
289         float          mAuxInc;                       // floating point aux increment
290 
291         audio_channel_mask_t mMixerChannelMask;
292         uint32_t             mMixerChannelCount;
293 
294       protected:
295 
296         // hooks
297         void track__genericResample(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
298         void track__16BitsStereo(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
299         void track__16BitsMono(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
300 
301         void volumeRampStereo(int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
302         void volumeStereo(int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
303 
304         // multi-format track hooks
305         template <int MIXTYPE, typename TO, typename TI, typename TA>
306         void track__Resample(TO* out, size_t frameCount, TO* temp __unused, TA* aux);
307         template <int MIXTYPE, typename TO, typename TI, typename TA>
308         void track__NoResample(TO* out, size_t frameCount, TO* temp __unused, TA* aux);
309     };
310 
311     // preCreateTrack must create an instance of a proper TrackBase descendant.
312     // postCreateTrack is called after filling out fields of TrackBase. It can
313     // abort track creation by returning non-OK status. See the implementation
314     // of create() for details.
315     virtual std::shared_ptr<TrackBase> preCreateTrack();
postCreateTrack(TrackBase * track __unused)316     virtual status_t postCreateTrack(TrackBase *track __unused) { return OK; }
317 
318     // preProcess is called before the process hook, postProcess after,
319     // see the implementation of process() method.
preProcess()320     virtual void preProcess() {}
postProcess()321     virtual void postProcess() {}
322 
323     virtual bool setChannelMasks(int name,
324             audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask);
325 
326     // Called when track info changes and a new process hook should be determined.
invalidate()327     void invalidate() {
328         mHook = &AudioMixerBase::process__validate;
329     }
330 
331     void process__validate();
332     void process__nop();
333     void process__genericNoResampling();
334     void process__genericResampling();
335     void process__oneTrack16BitsStereoNoResampling();
336 
337     template <int MIXTYPE, typename TO, typename TI, typename TA>
338     void process__noResampleOneTrack();
339 
340     static process_hook_t getProcessHook(int processType, uint32_t channelCount,
341             audio_format_t mixerInFormat, audio_format_t mixerOutFormat,
342             bool useStereoVolume);
343 
344     static void convertMixerFormat(void *out, audio_format_t mixerOutFormat,
345             void *in, audio_format_t mixerInFormat, size_t sampleCount);
346 
347     // initialization constants
348     const uint32_t mSampleRate;
349     const size_t mFrameCount;
350 
351     process_hook_t mHook = &AudioMixerBase::process__nop;   // one of process__*, never nullptr
352 
353     // the size of the type (int32_t) should be the largest of all types supported
354     // by the mixer.
355     std::unique_ptr<int32_t[]> mOutputTemp;
356     std::unique_ptr<int32_t[]> mResampleTemp;
357 
358     // track names grouped by main buffer, in no particular order of main buffer.
359     // however names for a particular main buffer are in order (by construction).
360     std::unordered_map<void * /* mainBuffer */, std::vector<int /* name */>> mGroups;
361 
362     // track names that are enabled, in increasing order (by construction).
363     std::vector<int /* name */> mEnabled;
364 
365     // track smart pointers, by name, in increasing order of name.
366     std::map<int /* name */, std::shared_ptr<TrackBase>> mTracks;
367 };
368 
369 }  // namespace android
370 
371 #endif  // ANDROID_AUDIO_MIXER_BASE_H
372