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_NORESAMPLE,
192         TRACKTYPE_NORESAMPLEMONO,
193     };
194 
195     // process hook functionality
196     using process_hook_t = void(AudioMixerBase::*)();
197 
198     struct TrackBase;
199     using hook_t = void(TrackBase::*)(
200             int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux);
201 
202     struct TrackBase {
TrackBaseTrackBase203         TrackBase()
204             : bufferProvider(nullptr)
205         {
206             // TODO: move additional initialization here.
207         }
~TrackBaseTrackBase208         virtual ~TrackBase() {}
209 
getOutputChannelCountTrackBase210         virtual uint32_t getOutputChannelCount() { return channelCount; }
getMixerChannelCountTrackBase211         virtual uint32_t getMixerChannelCount() { return mMixerChannelCount; }
212 
needsRampTrackBase213         bool        needsRamp() { return (volumeInc[0] | volumeInc[1] | auxInc) != 0; }
214         bool        setResampler(uint32_t trackSampleRate, uint32_t devSampleRate);
doesResampleTrackBase215         bool        doesResample() const { return mResampler.get() != nullptr; }
216         void        recreateResampler(uint32_t devSampleRate);
resetResamplerTrackBase217         void        resetResampler() { if (mResampler.get() != nullptr) mResampler->reset(); }
218         void        adjustVolumeRamp(bool aux, bool useFloat = false);
getUnreleasedFramesTrackBase219         size_t      getUnreleasedFrames() const { return mResampler.get() != nullptr ?
220                                                     mResampler->getUnreleasedFrames() : 0; };
221 
222         static hook_t getTrackHook(int trackType, uint32_t channelCount,
223                 audio_format_t mixerInFormat, audio_format_t mixerOutFormat);
224 
225         void track__nop(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
226 
227         template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
228             typename TO, typename TI, typename TA>
229         void volumeMix(TO *out, size_t outFrames, const TI *in, TA *aux, bool ramp);
230 
231         uint32_t    needs;
232 
233         // TODO: Eventually remove legacy integer volume settings
234         union {
235         int16_t     volume[MAX_NUM_VOLUMES]; // U4.12 fixed point (top bit should be zero)
236         int32_t     volumeRL;
237         };
238 
239         int32_t     prevVolume[MAX_NUM_VOLUMES];
240         int32_t     volumeInc[MAX_NUM_VOLUMES];
241         int32_t     auxInc;
242         int32_t     prevAuxLevel;
243         int16_t     auxLevel;       // 0 <= auxLevel <= MAX_GAIN_INT, but signed for mul performance
244 
245         uint16_t    frameCount;
246 
247         uint8_t     channelCount;   // 1 or 2, redundant with (needs & NEEDS_CHANNEL_COUNT__MASK)
248         uint8_t     unused_padding; // formerly format, was always 16
249         uint16_t    enabled;        // actually bool
250         audio_channel_mask_t channelMask;
251 
252         // actual buffer provider used by the track hooks
253         AudioBufferProvider*                bufferProvider;
254 
255         mutable AudioBufferProvider::Buffer buffer; // 8 bytes
256 
257         hook_t      hook;
258         const void  *mIn;             // current location in buffer
259 
260         std::unique_ptr<AudioResampler> mResampler;
261         uint32_t    sampleRate;
262         int32_t*    mainBuffer;
263         int32_t*    auxBuffer;
264 
265         int32_t     sessionId;
266 
267         audio_format_t mMixerFormat;     // output mix format: AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
268         audio_format_t mFormat;          // input track format
269         audio_format_t mMixerInFormat;   // mix internal format AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
270                                          // each track must be converted to this format.
271 
272         float          mVolume[MAX_NUM_VOLUMES];     // floating point set volume
273         float          mPrevVolume[MAX_NUM_VOLUMES]; // floating point previous volume
274         float          mVolumeInc[MAX_NUM_VOLUMES];  // floating point volume increment
275 
276         float          mAuxLevel;                     // floating point set aux level
277         float          mPrevAuxLevel;                 // floating point prev aux level
278         float          mAuxInc;                       // floating point aux increment
279 
280         audio_channel_mask_t mMixerChannelMask;
281         uint32_t             mMixerChannelCount;
282 
283       protected:
284 
285         // hooks
286         void track__genericResample(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
287         void track__16BitsStereo(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
288         void track__16BitsMono(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
289 
290         void volumeRampStereo(int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
291         void volumeStereo(int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
292 
293         // multi-format track hooks
294         template <int MIXTYPE, typename TO, typename TI, typename TA>
295         void track__Resample(TO* out, size_t frameCount, TO* temp __unused, TA* aux);
296         template <int MIXTYPE, typename TO, typename TI, typename TA>
297         void track__NoResample(TO* out, size_t frameCount, TO* temp __unused, TA* aux);
298     };
299 
300     // preCreateTrack must create an instance of a proper TrackBase descendant.
301     // postCreateTrack is called after filling out fields of TrackBase. It can
302     // abort track creation by returning non-OK status. See the implementation
303     // of create() for details.
304     virtual std::shared_ptr<TrackBase> preCreateTrack();
postCreateTrack(TrackBase * track __unused)305     virtual status_t postCreateTrack(TrackBase *track __unused) { return OK; }
306 
307     // preProcess is called before the process hook, postProcess after,
308     // see the implementation of process() method.
preProcess()309     virtual void preProcess() {}
postProcess()310     virtual void postProcess() {}
311 
312     virtual bool setChannelMasks(int name,
313             audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask);
314 
315     // Called when track info changes and a new process hook should be determined.
invalidate()316     void invalidate() {
317         mHook = &AudioMixerBase::process__validate;
318     }
319 
320     void process__validate();
321     void process__nop();
322     void process__genericNoResampling();
323     void process__genericResampling();
324     void process__oneTrack16BitsStereoNoResampling();
325 
326     template <int MIXTYPE, typename TO, typename TI, typename TA>
327     void process__noResampleOneTrack();
328 
329     static process_hook_t getProcessHook(int processType, uint32_t channelCount,
330             audio_format_t mixerInFormat, audio_format_t mixerOutFormat);
331 
332     static void convertMixerFormat(void *out, audio_format_t mixerOutFormat,
333             void *in, audio_format_t mixerInFormat, size_t sampleCount);
334 
335     // initialization constants
336     const uint32_t mSampleRate;
337     const size_t mFrameCount;
338 
339     process_hook_t mHook = &AudioMixerBase::process__nop;   // one of process__*, never nullptr
340 
341     // the size of the type (int32_t) should be the largest of all types supported
342     // by the mixer.
343     std::unique_ptr<int32_t[]> mOutputTemp;
344     std::unique_ptr<int32_t[]> mResampleTemp;
345 
346     // track names grouped by main buffer, in no particular order of main buffer.
347     // however names for a particular main buffer are in order (by construction).
348     std::unordered_map<void * /* mainBuffer */, std::vector<int /* name */>> mGroups;
349 
350     // track names that are enabled, in increasing order (by construction).
351     std::vector<int /* name */> mEnabled;
352 
353     // track smart pointers, by name, in increasing order of name.
354     std::map<int /* name */, std::shared_ptr<TrackBase>> mTracks;
355 };
356 
357 }  // namespace android
358 
359 #endif  // ANDROID_AUDIO_MIXER_BASE_H
360