| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1 | /* //device/include/server/AudioFlinger/AudioMixer.h | 
 | 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 |  | 
 | 27 | namespace android { | 
 | 28 |  | 
 | 29 | // ---------------------------------------------------------------------------- | 
 | 30 |  | 
 | 31 | #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  )) | 
 | 32 | #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false )) | 
 | 33 |  | 
 | 34 | // ---------------------------------------------------------------------------- | 
 | 35 |  | 
 | 36 | class AudioMixer | 
 | 37 | { | 
 | 38 | public: | 
 | 39 |                             AudioMixer(size_t frameCount, uint32_t sampleRate); | 
 | 40 |  | 
 | 41 |                             ~AudioMixer(); | 
 | 42 |  | 
 | 43 |     static const uint32_t MAX_NUM_TRACKS = 32; | 
 | 44 |     static const uint32_t MAX_NUM_CHANNELS = 2; | 
 | 45 |  | 
 | 46 |     static const uint16_t UNITY_GAIN = 0x1000; | 
 | 47 |  | 
 | 48 |     enum { // names | 
 | 49 |  | 
 | 50 |         // track units (32 units) | 
 | 51 |         TRACK0          = 0x1000, | 
 | 52 |  | 
 | 53 |         // enable/disable | 
 | 54 |         MIXING          = 0x2000, | 
 | 55 |  | 
 | 56 |         // setParameter targets | 
 | 57 |         TRACK           = 0x3000, | 
 | 58 |         RESAMPLE        = 0x3001, | 
 | 59 |         RAMP_VOLUME     = 0x3002, // ramp to new volume | 
 | 60 |         VOLUME          = 0x3003, // don't ramp | 
 | 61 |  | 
 | 62 |         // set Parameter names | 
 | 63 |         // for target TRACK | 
 | 64 |         CHANNEL_COUNT   = 0x4000, | 
 | 65 |         FORMAT          = 0x4001, | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 66 |         MAIN_BUFFER     = 0x4002, | 
 | 67 |         AUX_BUFFER      = 0x4003, | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 68 |         // for TARGET RESAMPLE | 
 | 69 |         SAMPLE_RATE     = 0x4100, | 
 | 70 |         // for TARGET VOLUME (8 channels max) | 
 | 71 |         VOLUME0         = 0x4200, | 
 | 72 |         VOLUME1         = 0x4201, | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 73 |         AUXLEVEL        = 0x4210, | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 74 |     }; | 
 | 75 |  | 
 | 76 |  | 
 | 77 |     int         getTrackName(); | 
 | 78 |     void        deleteTrackName(int name); | 
 | 79 |  | 
 | 80 |     status_t    enable(int name); | 
 | 81 |     status_t    disable(int name); | 
 | 82 |  | 
 | 83 |     status_t    setActiveTrack(int track); | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 84 |     status_t    setParameter(int target, int name, void *value); | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 85 |  | 
 | 86 |     status_t    setBufferProvider(AudioBufferProvider* bufferProvider); | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 87 |     void        process(); | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 88 |  | 
 | 89 |     uint32_t    trackNames() const { return mTrackNames; } | 
 | 90 |  | 
| Eric Laurent | a553c25 | 2009-07-17 12:17:14 -0700 | [diff] [blame] | 91 |     static void ditherAndClamp(int32_t* out, int32_t const *sums, size_t c); | 
 | 92 |  | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 93 | private: | 
 | 94 |  | 
 | 95 |     enum { | 
 | 96 |         NEEDS_CHANNEL_COUNT__MASK   = 0x00000003, | 
 | 97 |         NEEDS_FORMAT__MASK          = 0x000000F0, | 
 | 98 |         NEEDS_MUTE__MASK            = 0x00000100, | 
 | 99 |         NEEDS_RESAMPLE__MASK        = 0x00001000, | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 100 |         NEEDS_AUX__MASK             = 0x00010000, | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 101 |     }; | 
 | 102 |  | 
 | 103 |     enum { | 
 | 104 |         NEEDS_CHANNEL_1             = 0x00000000, | 
 | 105 |         NEEDS_CHANNEL_2             = 0x00000001, | 
 | 106 |  | 
 | 107 |         NEEDS_FORMAT_16             = 0x00000010, | 
 | 108 |  | 
 | 109 |         NEEDS_MUTE_DISABLED         = 0x00000000, | 
 | 110 |         NEEDS_MUTE_ENABLED          = 0x00000100, | 
 | 111 |  | 
 | 112 |         NEEDS_RESAMPLE_DISABLED     = 0x00000000, | 
 | 113 |         NEEDS_RESAMPLE_ENABLED      = 0x00001000, | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 114 |  | 
 | 115 |         NEEDS_AUX_DISABLED     = 0x00000000, | 
 | 116 |         NEEDS_AUX_ENABLED      = 0x00010000, | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 117 |     }; | 
 | 118 |  | 
 | 119 |     static inline int32_t applyVolume(int32_t in, int32_t v) { | 
 | 120 |         return in * v; | 
 | 121 |     } | 
 | 122 |  | 
 | 123 |  | 
 | 124 |     struct state_t; | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 125 |     struct track_t; | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 126 |  | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 127 |     typedef void (*mix_t)(state_t* state); | 
 | 128 |     typedef void (*hook_t)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux); | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 129 |     static const int BLOCKSIZE = 16; // 4 cache lines | 
 | 130 |  | 
 | 131 |     struct track_t { | 
 | 132 |         uint32_t    needs; | 
 | 133 |  | 
 | 134 |         union { | 
 | 135 |         int16_t     volume[2];      // [0]3.12 fixed point | 
 | 136 |         int32_t     volumeRL; | 
 | 137 |         }; | 
 | 138 |  | 
 | 139 |         int32_t     prevVolume[2]; | 
 | 140 |  | 
 | 141 |         int32_t     volumeInc[2]; | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 142 |         int32_t     auxLevel; | 
 | 143 |         int32_t     auxInc; | 
 | 144 |         int32_t     prevAuxLevel; | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 145 |  | 
 | 146 |         uint16_t    frameCount; | 
 | 147 |  | 
 | 148 |         uint8_t     channelCount : 4; | 
 | 149 |         uint8_t     enabled      : 1; | 
 | 150 |         uint8_t     reserved0    : 3; | 
 | 151 |         uint8_t     format; | 
 | 152 |  | 
 | 153 |         AudioBufferProvider*                bufferProvider; | 
 | 154 |         mutable AudioBufferProvider::Buffer buffer; | 
 | 155 |  | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 156 |         hook_t      hook; | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 157 |         void const* in;             // current location in buffer | 
 | 158 |  | 
 | 159 |         AudioResampler*     resampler; | 
 | 160 |         uint32_t            sampleRate; | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 161 |         int32_t*           mainBuffer; | 
 | 162 |         int32_t*           auxBuffer; | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 163 |  | 
 | 164 |         bool        setResampler(uint32_t sampleRate, uint32_t devSampleRate); | 
 | 165 |         bool        doesResample() const; | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 166 |         void        adjustVolumeRamp(bool aux); | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 167 |     }; | 
 | 168 |  | 
 | 169 |     // pad to 32-bytes to fill cache line | 
 | 170 |     struct state_t { | 
 | 171 |         uint32_t        enabledTracks; | 
 | 172 |         uint32_t        needsChanged; | 
 | 173 |         size_t          frameCount; | 
 | 174 |         mix_t           hook; | 
 | 175 |         int32_t         *outputTemp; | 
 | 176 |         int32_t         *resampleTemp; | 
 | 177 |         int32_t         reserved[2]; | 
 | 178 |         track_t         tracks[32]; __attribute__((aligned(32))); | 
 | 179 |     }; | 
 | 180 |  | 
 | 181 |     int             mActiveTrack; | 
 | 182 |     uint32_t        mTrackNames; | 
 | 183 |     const uint32_t  mSampleRate; | 
 | 184 |  | 
 | 185 |     state_t         mState __attribute__((aligned(32))); | 
 | 186 |  | 
 | 187 |     void invalidateState(uint32_t mask); | 
 | 188 |  | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 189 |     static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); | 
 | 190 |     static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); | 
 | 191 |     static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); | 
 | 192 |     static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); | 
 | 193 |     static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux); | 
 | 194 |     static void volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux); | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 195 |  | 
| Eric Laurent | 65b6545 | 2010-06-01 23:49:17 -0700 | [diff] [blame^] | 196 |     static void process__validate(state_t* state); | 
 | 197 |     static void process__nop(state_t* state); | 
 | 198 |     static void process__genericNoResampling(state_t* state); | 
 | 199 |     static void process__genericResampling(state_t* state); | 
 | 200 |     static void process__OneTrack16BitsStereoNoResampling(state_t* state); | 
 | 201 |     static void process__TwoTracks16BitsStereoNoResampling(state_t* state); | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 202 | }; | 
 | 203 |  | 
 | 204 | // ---------------------------------------------------------------------------- | 
 | 205 | }; // namespace android | 
 | 206 |  | 
 | 207 | #endif // ANDROID_AUDIO_MIXER_H |