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