AudioMixer.h revision 0d255b2d9061ba31f13ada3fc0f7e51916407176
19969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang/* //device/include/server/AudioFlinger/AudioMixer.h
29969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang**
39969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang** Copyright 2007, The Android Open Source Project
49969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang**
59969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang** Licensed under the Apache License, Version 2.0 (the "License");
69969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang** you may not use this file except in compliance with the License.
79969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang** You may obtain a copy of the License at
89969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang**
99969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang**     http://www.apache.org/licenses/LICENSE-2.0
109969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang**
119969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang** Unless required by applicable law or agreed to in writing, software
129969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang** distributed under the License is distributed on an "AS IS" BASIS,
139969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang** See the License for the specific language governing permissions and
159969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang** limitations under the License.
169969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang*/
179969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
189969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#ifndef ANDROID_AUDIO_MIXER_H
199969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#define ANDROID_AUDIO_MIXER_H
209969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
219969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#include <stdint.h>
229969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#include <sys/types.h>
239969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
24c4689fae1bdb8d1c94eb28af1b2a1f30d2b1a3daJames Dong#include "AudioBufferProvider.h"
2590b6191067990a7a3ee947d7ce08c64f780f0de7Mathias Agopian#include "AudioResampler.h"
269969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
279969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Changnamespace android {
289969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2908b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang// ----------------------------------------------------------------------------
3008b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
319969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
3208b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
339969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
3408b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang// ----------------------------------------------------------------------------
3508b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
3608b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Changclass AudioMixer
3708b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang{
389969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Changpublic:
3908b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang                            AudioMixer(size_t frameCount, uint32_t sampleRate);
409969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
419969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                            ~AudioMixer();
429969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
439969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    static const uint32_t MAX_NUM_TRACKS = 32;
4408b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    static const uint32_t MAX_NUM_CHANNELS = 2;
4508b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
4608b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    static const uint16_t UNITY_GAIN = 0x1000;
4708b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
4808b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    enum { // names
4908b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
5008b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        // track units (32 units)
5108b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        TRACK0          = 0x1000,
52aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang
5308b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        // enable/disable
54aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang        MIXING          = 0x2000,
5508b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
5608b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        // setParameter targets
57aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang        TRACK           = 0x3000,
58aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang        RESAMPLE        = 0x3001,
5908b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        RAMP_VOLUME     = 0x3002, // ramp to new volume
6008b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        VOLUME          = 0x3003, // don't ramp
61aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang
6208b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        // set Parameter names
6308b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        // for target TRACK
6408b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        CHANNEL_MASK    = 0x4000,
65aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang        FORMAT          = 0x4001,
6608b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        MAIN_BUFFER     = 0x4002,
6708b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        AUX_BUFFER      = 0x4003,
6808b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        // for TARGET RESAMPLE
69aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang        SAMPLE_RATE     = 0x4100,
70aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang        RESET           = 0x4101,
71aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang        // for TARGET VOLUME (8 channels max)
72aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang        VOLUME0         = 0x4200,
7308b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        VOLUME1         = 0x4201,
7408b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        AUXLEVEL        = 0x4210,
7508b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    };
7608b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
779969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
789969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    int         getTrackName();
799969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    void        deleteTrackName(int name);
8008b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
819969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    status_t    enable(int name);
829969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    status_t    disable(int name);
839969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
849969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    status_t    setActiveTrack(int track);
859969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    status_t    setParameter(int target, int name, void *value);
869969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
879969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    status_t    setBufferProvider(AudioBufferProvider* bufferProvider);
889969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    void        process();
899969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
909969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    uint32_t    trackNames() const { return mTrackNames; }
919969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
929969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    static void ditherAndClamp(int32_t* out, int32_t const *sums, size_t c);
939969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
949969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Changprivate:
959969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
969969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    enum {
979969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        NEEDS_CHANNEL_COUNT__MASK   = 0x00000003,
989969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        NEEDS_FORMAT__MASK          = 0x000000F0,
999969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        NEEDS_MUTE__MASK            = 0x00000100,
1001e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        NEEDS_RESAMPLE__MASK        = 0x00001000,
1011e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        NEEDS_AUX__MASK             = 0x00010000,
1021e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    };
1039969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1049969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    enum {
1059969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        NEEDS_CHANNEL_1             = 0x00000000,
1069969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        NEEDS_CHANNEL_2             = 0x00000001,
1079969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
10808b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        NEEDS_FORMAT_16             = 0x00000010,
1099969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1109969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        NEEDS_MUTE_DISABLED         = 0x00000000,
11108b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        NEEDS_MUTE_ENABLED          = 0x00000100,
11208b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
11308b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        NEEDS_RESAMPLE_DISABLED     = 0x00000000,
1149969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        NEEDS_RESAMPLE_ENABLED      = 0x00001000,
1159969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1169969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        NEEDS_AUX_DISABLED     = 0x00000000,
1179969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        NEEDS_AUX_ENABLED      = 0x00010000,
1189969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    };
1199969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1209969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    static inline int32_t applyVolume(int32_t in, int32_t v) {
1219969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        return in * v;
1229969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    }
1239969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1249969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1259969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    struct state_t;
1269969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    struct track_t;
1279969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1289969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    typedef void (*mix_t)(state_t* state);
1299969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    typedef void (*hook_t)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux);
1309969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    static const int BLOCKSIZE = 16; // 4 cache lines
1319969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1329969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    struct track_t {
1331e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        uint32_t    needs;
134e70ff37034fdb93f65d34704aec400ec9123e55cSteve Block
1359969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        union {
1369969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        int16_t     volume[2];      // [0]3.12 fixed point
1379969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        int32_t     volumeRL;
1389969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        };
1399969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1409969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        int32_t     prevVolume[2];
141
142        int32_t     volumeInc[2];
143        int32_t     auxLevel;
144        int32_t     auxInc;
145        int32_t     prevAuxLevel;
146
147        uint16_t    frameCount;
148
149        uint8_t     channelCount : 4;
150        uint8_t     enabled      : 1;
151        uint8_t     reserved0    : 3;
152        uint8_t     format;
153        uint32_t    channelMask;
154
155        AudioBufferProvider*                bufferProvider;
156        mutable AudioBufferProvider::Buffer buffer;
157
158        hook_t      hook;
159        void const* in;             // current location in buffer
160
161        AudioResampler*     resampler;
162        uint32_t            sampleRate;
163        int32_t*           mainBuffer;
164        int32_t*           auxBuffer;
165
166        bool        setResampler(uint32_t sampleRate, uint32_t devSampleRate);
167        bool        doesResample() const;
168        void        resetResampler();
169        void        adjustVolumeRamp(bool aux);
170    };
171
172    // pad to 32-bytes to fill cache line
173    struct state_t {
174        uint32_t        enabledTracks;
175        uint32_t        needsChanged;
176        size_t          frameCount;
177        mix_t           hook;
178        int32_t         *outputTemp;
179        int32_t         *resampleTemp;
180        int32_t         reserved[2];
181        track_t         tracks[32]; __attribute__((aligned(32)));
182    };
183
184    int             mActiveTrack;
185    uint32_t        mTrackNames;
186    const uint32_t  mSampleRate;
187
188    state_t         mState __attribute__((aligned(32)));
189
190    void invalidateState(uint32_t mask);
191
192    static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
193    static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
194    static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
195    static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
196    static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
197    static void volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
198
199    static void process__validate(state_t* state);
200    static void process__nop(state_t* state);
201    static void process__genericNoResampling(state_t* state);
202    static void process__genericResampling(state_t* state);
203    static void process__OneTrack16BitsStereoNoResampling(state_t* state);
204    static void process__TwoTracks16BitsStereoNoResampling(state_t* state);
205};
206
207// ----------------------------------------------------------------------------
208}; // namespace android
209
210#endif // ANDROID_AUDIO_MIXER_H
211