AudioMixer.h revision 7d5b26230a179cd7bcc01f6578cd80d8c15a92a5
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 <stdint.h>
22#include <sys/types.h>
23
24#include <utils/threads.h>
25
26#include "AudioBufferProvider.h"
27#include "AudioResampler.h"
28
29#include <audio_effects/effect_downmix.h>
30#include <system/audio.h>
31
32namespace android {
33
34// ----------------------------------------------------------------------------
35
36class AudioMixer
37{
38public:
39                            AudioMixer(size_t frameCount, uint32_t sampleRate,
40                                       uint32_t maxNumTracks = MAX_NUM_TRACKS);
41
42    /*virtual*/             ~AudioMixer();  // non-virtual saves a v-table, restore if sub-classed
43
44    static const uint32_t MAX_NUM_TRACKS = 32;
45    // maximum number of channels supported by the mixer
46    static const uint32_t MAX_NUM_CHANNELS = 2;
47    // maximum number of channels supported for the content
48    static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = 8;
49
50    static const uint16_t UNITY_GAIN = 0x1000;
51
52    enum { // names
53
54        // track names (MAX_NUM_TRACKS units)
55        TRACK0          = 0x1000,
56
57        // 0x2000 is unused
58
59        // setParameter targets
60        TRACK           = 0x3000,
61        RESAMPLE        = 0x3001,
62        RAMP_VOLUME     = 0x3002, // ramp to new volume
63        VOLUME          = 0x3003, // don't ramp
64
65        // set Parameter names
66        // for target TRACK
67        CHANNEL_MASK    = 0x4000,
68        FORMAT          = 0x4001,
69        MAIN_BUFFER     = 0x4002,
70        AUX_BUFFER      = 0x4003,
71        DOWNMIX_TYPE    = 0X4004,
72        // for target RESAMPLE
73        SAMPLE_RATE     = 0x4100,
74        RESET           = 0x4101,
75        // for target RAMP_VOLUME and VOLUME (8 channels max)
76        VOLUME0         = 0x4200,
77        VOLUME1         = 0x4201,
78        AUXLEVEL        = 0x4210,
79    };
80
81
82    // For all APIs with "name": TRACK0 <= name < TRACK0 + MAX_NUM_TRACKS
83
84    // Allocate a track name.  Returns new track name if successful, -1 on failure.
85    int         getTrackName();
86
87    // Free an allocated track by name
88    void        deleteTrackName(int name);
89
90    // Enable or disable an allocated track by name
91    void        enable(int name);
92    void        disable(int name);
93
94    void        setParameter(int name, int target, int param, void *value);
95
96    void        setBufferProvider(int name, AudioBufferProvider* bufferProvider);
97    void        process(int64_t pts);
98
99    uint32_t    trackNames() const { return mTrackNames; }
100
101    size_t      getUnreleasedFrames(int name) const;
102
103private:
104
105    enum {
106        NEEDS_CHANNEL_COUNT__MASK   = 0x00000007,
107        NEEDS_FORMAT__MASK          = 0x000000F0,
108        NEEDS_MUTE__MASK            = 0x00000100,
109        NEEDS_RESAMPLE__MASK        = 0x00001000,
110        NEEDS_AUX__MASK             = 0x00010000,
111    };
112
113    enum {
114        NEEDS_CHANNEL_1             = 0x00000000,
115        NEEDS_CHANNEL_2             = 0x00000001,
116
117        NEEDS_FORMAT_16             = 0x00000010,
118
119        NEEDS_MUTE_DISABLED         = 0x00000000,
120        NEEDS_MUTE_ENABLED          = 0x00000100,
121
122        NEEDS_RESAMPLE_DISABLED     = 0x00000000,
123        NEEDS_RESAMPLE_ENABLED      = 0x00001000,
124
125        NEEDS_AUX_DISABLED     = 0x00000000,
126        NEEDS_AUX_ENABLED      = 0x00010000,
127    };
128
129    struct state_t;
130    struct track_t;
131    class DownmixerBufferProvider;
132
133    typedef void (*hook_t)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux);
134    static const int BLOCKSIZE = 16; // 4 cache lines
135
136    struct track_t {
137        uint32_t    needs;
138
139        union {
140        int16_t     volume[MAX_NUM_CHANNELS]; // [0]3.12 fixed point
141        int32_t     volumeRL;
142        };
143
144        int32_t     prevVolume[MAX_NUM_CHANNELS];
145
146        // 16-byte boundary
147
148        int32_t     volumeInc[MAX_NUM_CHANNELS];
149        int32_t     auxInc;
150        int32_t     prevAuxLevel;
151
152        // 16-byte boundary
153
154        int16_t     auxLevel;       // 0 <= auxLevel <= MAX_GAIN_INT, but signed for mul performance
155        uint16_t    frameCount;
156
157        uint8_t     channelCount;   // 1 or 2, redundant with (needs & NEEDS_CHANNEL_COUNT__MASK)
158        uint8_t     format;         // always 16
159        uint16_t    enabled;        // actually bool
160        audio_channel_mask_t channelMask;
161
162        // actual buffer provider used by the track hooks, see DownmixerBufferProvider below
163        //  for how the Track buffer provider is wrapped by another one when dowmixing is required
164        AudioBufferProvider*                bufferProvider;
165
166        // 16-byte boundary
167
168        mutable AudioBufferProvider::Buffer buffer; // 8 bytes
169
170        hook_t      hook;
171        const void* in;             // current location in buffer
172
173        // 16-byte boundary
174
175        AudioResampler*     resampler;
176        uint32_t            sampleRate;
177        int32_t*           mainBuffer;
178        int32_t*           auxBuffer;
179
180        // 16-byte boundary
181
182        uint64_t    localTimeFreq;
183
184        DownmixerBufferProvider* downmixerBufferProvider; // 4 bytes
185
186        int32_t     padding;
187
188        // 16-byte boundary
189
190        bool        setResampler(uint32_t sampleRate, uint32_t devSampleRate);
191        bool        doesResample() const { return resampler != NULL; }
192        void        resetResampler() { if (resampler != NULL) resampler->reset(); }
193        void        adjustVolumeRamp(bool aux);
194        size_t      getUnreleasedFrames() const { return resampler != NULL ?
195                                                    resampler->getUnreleasedFrames() : 0; };
196    };
197
198    // pad to 32-bytes to fill cache line
199    struct state_t {
200        uint32_t        enabledTracks;
201        uint32_t        needsChanged;
202        size_t          frameCount;
203        void            (*hook)(state_t* state, int64_t pts);   // one of process__*, never NULL
204        int32_t         *outputTemp;
205        int32_t         *resampleTemp;
206        int32_t         reserved[2];
207        // FIXME allocate dynamically to save some memory when maxNumTracks < MAX_NUM_TRACKS
208        track_t         tracks[MAX_NUM_TRACKS]; __attribute__((aligned(32)));
209    };
210
211    // AudioBufferProvider that wraps a track AudioBufferProvider by a call to a downmix effect
212    class DownmixerBufferProvider : public AudioBufferProvider {
213    public:
214        virtual status_t getNextBuffer(Buffer* buffer, int64_t pts);
215        virtual void releaseBuffer(Buffer* buffer);
216        DownmixerBufferProvider();
217        virtual ~DownmixerBufferProvider();
218
219        AudioBufferProvider* mTrackBufferProvider;
220        effect_handle_t    mDownmixHandle;
221        effect_config_t    mDownmixConfig;
222    };
223
224    // bitmask of allocated track names, where bit 0 corresponds to TRACK0 etc.
225    uint32_t        mTrackNames;
226
227    // bitmask of configured track names; ~0 if maxNumTracks == MAX_NUM_TRACKS,
228    // but will have fewer bits set if maxNumTracks < MAX_NUM_TRACKS
229    const uint32_t  mConfiguredNames;
230
231    const uint32_t  mSampleRate;
232
233    state_t         mState __attribute__((aligned(32)));
234
235    // effect descriptor for the downmixer used by the mixer
236    static effect_descriptor_t dwnmFxDesc;
237    // indicates whether a downmix effect has been found and is usable by this mixer
238    static bool                isMultichannelCapable;
239
240    void invalidateState(uint32_t mask);
241    static status_t prepareTrackForDownmix(track_t* pTrack, int trackNum);
242
243    static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
244    static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
245    static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
246    static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
247    static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
248    static void volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
249
250    static void process__validate(state_t* state, int64_t pts);
251    static void process__nop(state_t* state, int64_t pts);
252    static void process__genericNoResampling(state_t* state, int64_t pts);
253    static void process__genericResampling(state_t* state, int64_t pts);
254    static void process__OneTrack16BitsStereoNoResampling(state_t* state,
255                                                          int64_t pts);
256#if 0
257    static void process__TwoTracks16BitsStereoNoResampling(state_t* state,
258                                                           int64_t pts);
259#endif
260
261    static int64_t calculateOutputPTS(const track_t& t, int64_t basePTS,
262                                      int outputFrameIndex);
263};
264
265// ----------------------------------------------------------------------------
266}; // namespace android
267
268#endif // ANDROID_AUDIO_MIXER_H
269