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