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