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