199e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten/* 265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** 365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Copyright 2007, The Android Open Source Project 465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** 565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Licensed under the Apache License, Version 2.0 (the "License"); 665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** you may not use this file except in compliance with the License. 765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** You may obtain a copy of the License at 865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** 965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** http://www.apache.org/licenses/LICENSE-2.0 1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** 1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Unless required by applicable law or agreed to in writing, software 1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** distributed under the License is distributed on an "AS IS" BASIS, 1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** See the License for the specific language governing permissions and 1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** limitations under the License. 1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian*/ 1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#ifndef ANDROID_AUDIO_MIXER_H 1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define ANDROID_AUDIO_MIXER_H 2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <stdint.h> 2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/types.h> 2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2436802bd18b7b4e8c87fa019c7e3068bee330d174Dan Albert#include <hardware/audio_effect.h> 2536802bd18b7b4e8c87fa019c7e3068bee330d174Dan Albert#include <media/AudioBufferProvider.h> 265a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia#include <media/AudioResamplerPublic.h> 2736802bd18b7b4e8c87fa019c7e3068bee330d174Dan Albert#include <media/nbaio/NBLog.h> 2836802bd18b7b4e8c87fa019c7e3068bee330d174Dan Albert#include <system/audio.h> 2936802bd18b7b4e8c87fa019c7e3068bee330d174Dan Albert#include <utils/Compat.h> 307d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi#include <utils/threads.h> 317d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi 3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioResampler.h" 33857d5a20a956ef61b64ae07b018ecc2f1eb0a503Andy Hung#include "BufferProviders.h" 3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 35c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten// FIXME This is actually unity gain, which might not be max in future, expressed in U.12 3697ae82408469286426d8dc57a361350f74e24a8bAndy Hung#define MAX_GAIN_INT AudioMixer::UNITY_GAIN_INT 37c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten 3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android { 3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 4165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianclass AudioMixer 4365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 4465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianpublic: 455c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten AudioMixer(size_t frameCount, uint32_t sampleRate, 465c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten uint32_t maxNumTracks = MAX_NUM_TRACKS); 4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 48c19e22450e6e3d07594c935c7a9522e85e909e82Glenn Kasten /*virtual*/ ~AudioMixer(); // non-virtual saves a v-table, restore if sub-classed 4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 50599fabc596687efa4b71b8f3ebbb957c7cae0c72Glenn Kasten 51599fabc596687efa4b71b8f3ebbb957c7cae0c72Glenn Kasten // This mixer has a hard-coded upper limit of 32 active track inputs. 52599fabc596687efa4b71b8f3ebbb957c7cae0c72Glenn Kasten // Adding support for > 32 tracks would require more than simply changing this value. 5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static const uint32_t MAX_NUM_TRACKS = 32; 547d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi // maximum number of channels supported by the mixer 55599fabc596687efa4b71b8f3ebbb957c7cae0c72Glenn Kasten 56e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung // This mixer has a hard-coded upper limit of 8 channels for output. 57e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung static const uint32_t MAX_NUM_CHANNELS = 8; 58e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung static const uint32_t MAX_NUM_VOLUMES = 2; // stereo volume only 597d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi // maximum number of channels supported for the content 60e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = AUDIO_CHANNEL_COUNT_MAX; 6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6297ae82408469286426d8dc57a361350f74e24a8bAndy Hung static const uint16_t UNITY_GAIN_INT = 0x1000; 6336802bd18b7b4e8c87fa019c7e3068bee330d174Dan Albert static const CONSTEXPR float UNITY_GAIN_FLOAT = 1.0f; 6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian enum { // names 6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 679c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten // track names (MAX_NUM_TRACKS units) 6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian TRACK0 = 0x1000, 6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 701c48c3c61970527b97892ab6a2daae8eaac26964Glenn Kasten // 0x2000 is unused 7165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // setParameter targets 7365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian TRACK = 0x3000, 7465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian RESAMPLE = 0x3001, 7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian RAMP_VOLUME = 0x3002, // ramp to new volume 7665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian VOLUME = 0x3003, // don't ramp 77c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung TIMESTRETCH = 0x3004, 7865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 7965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // set Parameter names 8065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // for target TRACK 810d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi CHANNEL_MASK = 0x4000, 8265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian FORMAT = 0x4001, 8365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian MAIN_BUFFER = 0x4002, 8465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AUX_BUFFER = 0x4003, 857d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi DOWNMIX_TYPE = 0X4004, 86788207057ed4b8df4719ed8089f376ef52de9ca1Andy Hung MIXER_FORMAT = 0x4005, // AUDIO_FORMAT_PCM_(FLOAT|16_BIT) 87e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung MIXER_CHANNEL_MASK = 0x4006, // Channel mask for mixer output 88362c4e697d8e9c034e964ac7b40227e054491547Glenn Kasten // for target RESAMPLE 894e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten SAMPLE_RATE = 0x4100, // Configure sample rate conversion on this track name; 904e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // parameter 'value' is the new sample rate in Hz. 914e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // Only creates a sample rate converter the first time that 924e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // the track sample rate is different from the mix sample rate. 934e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // If the new sample rate is the same as the mix sample rate, 944e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // and a sample rate converter already exists, 954e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // then the sample rate converter remains present but is a no-op. 964e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten RESET = 0x4101, // Reset sample rate converter without changing sample rate. 974e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // This clears out the resampler's input buffer. 984e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten REMOVE = 0x4102, // Remove the sample rate converter on this track name; 994e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // the track is restored to the mix sample rate. 100362c4e697d8e9c034e964ac7b40227e054491547Glenn Kasten // for target RAMP_VOLUME and VOLUME (8 channels max) 101c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten // FIXME use float for these 3 to improve the dynamic range 10265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian VOLUME0 = 0x4200, 10365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian VOLUME1 = 0x4201, 10465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AUXLEVEL = 0x4210, 105c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung // for target TIMESTRETCH 106c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung PLAYBACK_RATE = 0x4300, // Configure timestretch on this track name; 107c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung // parameter 'value' is a pointer to the new playback rate. 10865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }; 10965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 11065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1119c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten // For all APIs with "name": TRACK0 <= name < TRACK0 + MAX_NUM_TRACKS 11217a736c3e1d062d7fc916329eb32aef8935614afGlenn Kasten 11317a736c3e1d062d7fc916329eb32aef8935614afGlenn Kasten // Allocate a track name. Returns new track name if successful, -1 on failure. 114e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung // The failure could be because of an invalid channelMask or format, or that 115e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung // the track capacity of the mixer is exceeded. 116e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung int getTrackName(audio_channel_mask_t channelMask, 117e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung audio_format_t format, int sessionId); 11817a736c3e1d062d7fc916329eb32aef8935614afGlenn Kasten 11917a736c3e1d062d7fc916329eb32aef8935614afGlenn Kasten // Free an allocated track by name 12065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian void deleteTrackName(int name); 12165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 12217a736c3e1d062d7fc916329eb32aef8935614afGlenn Kasten // Enable or disable an allocated track by name 1239c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten void enable(int name); 1249c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten void disable(int name); 12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1269c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten void setParameter(int name, int target, int param, void *value); 12765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1289c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten void setBufferProvider(int name, AudioBufferProvider* bufferProvider); 129d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten void process(); 13065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 13165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t trackNames() const { return mTrackNames; } 13265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 133c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kasten size_t getUnreleasedFrames(int name) const; 134071ccd5a9702500f3f7d62ef881300914926184dEric Laurent 135e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung static inline bool isValidPcmTrackFormat(audio_format_t format) { 136abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung switch (format) { 137abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung case AUDIO_FORMAT_PCM_8_BIT: 138abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung case AUDIO_FORMAT_PCM_16_BIT: 139abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung case AUDIO_FORMAT_PCM_24_BIT_PACKED: 140abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung case AUDIO_FORMAT_PCM_32_BIT: 141abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung case AUDIO_FORMAT_PCM_FLOAT: 142abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung return true; 143abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung default: 144abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung return false; 145abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung } 146e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung } 147e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung 14865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprivate: 14965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 15065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian enum { 151d6fadf0479b489b09b764070974d8a59855ede64Glenn Kasten // FIXME this representation permits up to 8 channels 1527d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi NEEDS_CHANNEL_COUNT__MASK = 0x00000007, 15365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }; 15465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 15565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian enum { 156d6fadf0479b489b09b764070974d8a59855ede64Glenn Kasten NEEDS_CHANNEL_1 = 0x00000000, // mono 157d6fadf0479b489b09b764070974d8a59855ede64Glenn Kasten NEEDS_CHANNEL_2 = 0x00000001, // stereo 15865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 159d6fadf0479b489b09b764070974d8a59855ede64Glenn Kasten // sample format is not explicitly specified, and is assumed to be AUDIO_FORMAT_PCM_16_BIT 16065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 161d6fadf0479b489b09b764070974d8a59855ede64Glenn Kasten NEEDS_MUTE = 0x00000100, 162d6fadf0479b489b09b764070974d8a59855ede64Glenn Kasten NEEDS_RESAMPLE = 0x00001000, 163d6fadf0479b489b09b764070974d8a59855ede64Glenn Kasten NEEDS_AUX = 0x00010000, 16465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }; 16565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 16665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian struct state_t; 16765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian struct track_t; 16865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 16985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten typedef void (*hook_t)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp, 17085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten int32_t* aux); 17165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static const int BLOCKSIZE = 16; // 4 cache lines 17265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 17365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian struct track_t { 17465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t needs; 17565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1765e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung // TODO: Eventually remove legacy integer volume settings 17765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian union { 178e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung int16_t volume[MAX_NUM_VOLUMES]; // U4.12 fixed point (top bit should be zero) 17965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t volumeRL; 18065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }; 18165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 182e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung int32_t prevVolume[MAX_NUM_VOLUMES]; 18365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1843b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten // 16-byte boundary 1853b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 186e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung int32_t volumeInc[MAX_NUM_VOLUMES]; 18765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t auxInc; 18865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t prevAuxLevel; 18965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1903b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten // 16-byte boundary 1913b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 1923b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten int16_t auxLevel; // 0 <= auxLevel <= MAX_GAIN_INT, but signed for mul performance 19365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint16_t frameCount; 19465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1953b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten uint8_t channelCount; // 1 or 2, redundant with (needs & NEEDS_CHANNEL_COUNT__MASK) 196ef7c7fbd0e3fb36af14cd7d39f64c949031516a5Andy Hung uint8_t unused_padding; // formerly format, was always 16 1973b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten uint16_t enabled; // actually bool 1987d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi audio_channel_mask_t channelMask; 19965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2007d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi // actual buffer provider used by the track hooks, see DownmixerBufferProvider below 2017d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi // for how the Track buffer provider is wrapped by another one when dowmixing is required 20265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioBufferProvider* bufferProvider; 2033b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 2043b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten // 16-byte boundary 2053b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 2063b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten mutable AudioBufferProvider::Buffer buffer; // 8 bytes 20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian hook_t hook; 20954c3b66444ebfb9f2265ee70ac3b76ccefa0506aGlenn Kasten const void* in; // current location in buffer 21065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2113b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten // 16-byte boundary 2123b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 21365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioResampler* resampler; 21465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t sampleRate; 21565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t* mainBuffer; 21665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t* auxBuffer; 21765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2183b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten // 16-byte boundary 2197f47549516ae5938759b5c834c8423378a60b3d8Andy Hung 2207f47549516ae5938759b5c834c8423378a60b3d8Andy Hung /* Buffer providers are constructed to translate the track input data as needed. 2217f47549516ae5938759b5c834c8423378a60b3d8Andy Hung * 222c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung * TODO: perhaps make a single PlaybackConverterProvider class to move 223c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung * all pre-mixer track buffer conversions outside the AudioMixer class. 224c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung * 2257f47549516ae5938759b5c834c8423378a60b3d8Andy Hung * 1) mInputBufferProvider: The AudioTrack buffer provider. 2267f47549516ae5938759b5c834c8423378a60b3d8Andy Hung * 2) mReformatBufferProvider: If not NULL, performs the audio reformat to 2277f47549516ae5938759b5c834c8423378a60b3d8Andy Hung * match either mMixerInFormat or mDownmixRequiresFormat, if the downmixer 2287f47549516ae5938759b5c834c8423378a60b3d8Andy Hung * requires reformat. For example, it may convert floating point input to 2297f47549516ae5938759b5c834c8423378a60b3d8Andy Hung * PCM_16_bit if that's required by the downmixer. 2307f47549516ae5938759b5c834c8423378a60b3d8Andy Hung * 3) downmixerBufferProvider: If not NULL, performs the channel remixing to match 2317f47549516ae5938759b5c834c8423378a60b3d8Andy Hung * the number of channels required by the mixer sink. 2327f47549516ae5938759b5c834c8423378a60b3d8Andy Hung * 4) mPostDownmixReformatBufferProvider: If not NULL, performs reformatting from 2337f47549516ae5938759b5c834c8423378a60b3d8Andy Hung * the downmixer requirements to the mixer engine input requirements. 234c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung * 5) mTimestretchBufferProvider: Adds timestretching for playback rate 2357f47549516ae5938759b5c834c8423378a60b3d8Andy Hung */ 2361b2fdcb005f9fbe5ad465cec46ec5992b718b5e3Andy Hung AudioBufferProvider* mInputBufferProvider; // externally provided buffer provider. 237857d5a20a956ef61b64ae07b018ecc2f1eb0a503Andy Hung PassthruBufferProvider* mReformatBufferProvider; // provider wrapper for reformatting. 238857d5a20a956ef61b64ae07b018ecc2f1eb0a503Andy Hung PassthruBufferProvider* downmixerBufferProvider; // wrapper for channel conversion. 239857d5a20a956ef61b64ae07b018ecc2f1eb0a503Andy Hung PassthruBufferProvider* mPostDownmixReformatBufferProvider; 240c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung PassthruBufferProvider* mTimestretchBufferProvider; 2417d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi 242d06e132358d44f02c22527b4f463df1f58da9216Jean-Michel Trivi int32_t sessionId; 243d06e132358d44f02c22527b4f463df1f58da9216Jean-Michel Trivi 244e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung audio_format_t mMixerFormat; // output mix format: AUDIO_FORMAT_PCM_(FLOAT|16_BIT) 245e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung audio_format_t mFormat; // input track format 246ef7c7fbd0e3fb36af14cd7d39f64c949031516a5Andy Hung audio_format_t mMixerInFormat; // mix internal format AUDIO_FORMAT_PCM_(FLOAT|16_BIT) 247ef7c7fbd0e3fb36af14cd7d39f64c949031516a5Andy Hung // each track must be converted to this format. 2487f47549516ae5938759b5c834c8423378a60b3d8Andy Hung audio_format_t mDownmixRequiresFormat; // required downmixer format 2497f47549516ae5938759b5c834c8423378a60b3d8Andy Hung // AUDIO_FORMAT_PCM_16_BIT if 16 bit necessary 2507f47549516ae5938759b5c834c8423378a60b3d8Andy Hung // AUDIO_FORMAT_INVALID if no required format 251ef7c7fbd0e3fb36af14cd7d39f64c949031516a5Andy Hung 252e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung float mVolume[MAX_NUM_VOLUMES]; // floating point set volume 253e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung float mPrevVolume[MAX_NUM_VOLUMES]; // floating point previous volume 254e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung float mVolumeInc[MAX_NUM_VOLUMES]; // floating point volume increment 2555e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung 2565e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung float mAuxLevel; // floating point set aux level 2575e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung float mPrevAuxLevel; // floating point prev aux level 2585e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung float mAuxInc; // floating point aux increment 2593b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 260e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung audio_channel_mask_t mMixerChannelMask; 261e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung uint32_t mMixerChannelCount; 2623b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 2635a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia AudioPlaybackRate mPlaybackRate; 264c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung 265296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung bool needsRamp() { return (volumeInc[0] | volumeInc[1] | auxInc) != 0; } 266e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung bool setResampler(uint32_t trackSampleRate, uint32_t devSampleRate); 267c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kasten bool doesResample() const { return resampler != NULL; } 268c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kasten void resetResampler() { if (resampler != NULL) resampler->reset(); } 2695e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung void adjustVolumeRamp(bool aux, bool useFloat = false); 270c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kasten size_t getUnreleasedFrames() const { return resampler != NULL ? 271c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kasten resampler->getUnreleasedFrames() : 0; }; 2720f451e92f09e089e588f303f729425a54fcd804bAndy Hung 2730f451e92f09e089e588f303f729425a54fcd804bAndy Hung status_t prepareForDownmix(); 2740f451e92f09e089e588f303f729425a54fcd804bAndy Hung void unprepareForDownmix(); 2750f451e92f09e089e588f303f729425a54fcd804bAndy Hung status_t prepareForReformat(); 2760f451e92f09e089e588f303f729425a54fcd804bAndy Hung void unprepareForReformat(); 2775a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia bool setPlaybackRate(const AudioPlaybackRate &playbackRate); 2780f451e92f09e089e588f303f729425a54fcd804bAndy Hung void reconfigureBufferProviders(); 27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }; 28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 281d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten typedef void (*process_hook_t)(state_t* state); 282296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 28365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // pad to 32-bytes to fill cache line 28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian struct state_t { 28565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t enabledTracks; 28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t needsChanged; 28765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian size_t frameCount; 288296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung process_hook_t hook; // one of process__*, never NULL 28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t *outputTemp; 29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t *resampleTemp; 291ab7d72f0804fbb7e91ad9d2a16f826d97e20e5d0Glenn Kasten NBLog::Writer* mLog; 292ab7d72f0804fbb7e91ad9d2a16f826d97e20e5d0Glenn Kasten int32_t reserved[1]; 2935c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten // FIXME allocate dynamically to save some memory when maxNumTracks < MAX_NUM_TRACKS 29401d3acba9de861cb2b718338e787cff3566fc5ecGlenn Kasten track_t tracks[MAX_NUM_TRACKS] __attribute__((aligned(32))); 29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }; 29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2979c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten // bitmask of allocated track names, where bit 0 corresponds to TRACK0 etc. 29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t mTrackNames; 2995c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten 3005c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten // bitmask of configured track names; ~0 if maxNumTracks == MAX_NUM_TRACKS, 3015c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten // but will have fewer bits set if maxNumTracks < MAX_NUM_TRACKS 3025c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten const uint32_t mConfiguredNames; 3035c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten 30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const uint32_t mSampleRate; 30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 306ab7d72f0804fbb7e91ad9d2a16f826d97e20e5d0Glenn Kasten NBLog::Writer mDummyLog; 307ab7d72f0804fbb7e91ad9d2a16f826d97e20e5d0Glenn Kastenpublic: 308ab7d72f0804fbb7e91ad9d2a16f826d97e20e5d0Glenn Kasten void setLog(NBLog::Writer* log); 309ab7d72f0804fbb7e91ad9d2a16f826d97e20e5d0Glenn Kastenprivate: 31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian state_t mState __attribute__((aligned(32))); 31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 3124e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // Call after changing either the enabled status of a track, or parameters of an enabled track. 3134e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // OK to call more often than that, but unnecessary. 31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian void invalidateState(uint32_t mask); 3154e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten 316e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung bool setChannelMasks(int name, 317e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask); 318e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung 31985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, 32085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten int32_t* aux); 32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); 32285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, 32385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten int32_t* aux); 32485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, 32585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten int32_t* aux); 32685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, 32785ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten int32_t* aux); 32885ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten static void volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, 32985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten int32_t* aux); 33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 331d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten static void process__validate(state_t* state); 332d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten static void process__nop(state_t* state); 333d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten static void process__genericNoResampling(state_t* state); 334d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten static void process__genericResampling(state_t* state); 335d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten static void process__OneTrack16BitsStereoNoResampling(state_t* state); 3364ff14bae91075eb274eb1c2975982358946e7e63John Grossman 33752008f821a5202502a82a8ba2c024e69bd336350Glenn Kasten static pthread_once_t sOnceControl; 33852008f821a5202502a82a8ba2c024e69bd336350Glenn Kasten static void sInitRoutine(); 339296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 3405e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung /* multi-format volume mixing function (calls template functions 3415e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung * in AudioMixerOps.h). The template parameters are as follows: 3425e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung * 3435e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration) 3445e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung * USEFLOATVOL (set to true if float volume is used) 3455e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards) 3465e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung * TO: int32_t (Q4.27) or float 3475e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung * TI: int32_t (Q4.27) or int16_t (Q0.15) or float 3485e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung * TA: int32_t (Q4.27) 3495e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung */ 350e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL, 3515e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung typename TO, typename TI, typename TA> 3525e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung static void volumeMix(TO *out, size_t outFrames, 3535e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung const TI *in, TA *aux, bool ramp, AudioMixer::track_t *t); 3545e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung 355296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung // multi-format process hooks 356e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung template <int MIXTYPE, typename TO, typename TI, typename TA> 357d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten static void process_NoResampleOneTrack(state_t* state); 358296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 359296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung // multi-format track hooks 360e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung template <int MIXTYPE, typename TO, typename TI, typename TA> 361296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung static void track__Resample(track_t* t, TO* out, size_t frameCount, 362296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung TO* temp __unused, TA* aux); 363e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung template <int MIXTYPE, typename TO, typename TI, typename TA> 364296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung static void track__NoResample(track_t* t, TO* out, size_t frameCount, 365296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung TO* temp __unused, TA* aux); 366296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 367296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung static void convertMixerFormat(void *out, audio_format_t mixerOutFormat, 368296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung void *in, audio_format_t mixerInFormat, size_t sampleCount); 369296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 370296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung // hook types 371296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung enum { 372296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung PROCESSTYPE_NORESAMPLEONETRACK, 373296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung }; 374296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung enum { 375296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung TRACKTYPE_NOP, 376296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung TRACKTYPE_RESAMPLE, 377296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung TRACKTYPE_NORESAMPLE, 378296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung TRACKTYPE_NORESAMPLEMONO, 379296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung }; 380296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 381296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung // functions for determining the proper process and track hooks. 382e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung static process_hook_t getProcessHook(int processType, uint32_t channelCount, 383296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung audio_format_t mixerInFormat, audio_format_t mixerOutFormat); 384e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung static hook_t getTrackHook(int trackType, uint32_t channelCount, 385296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung audio_format_t mixerInFormat, audio_format_t mixerOutFormat); 38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; 38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 38963238efb0d674758902918e3cdaac322126484b7Glenn Kasten} // namespace android 39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#endif // ANDROID_AUDIO_MIXER_H 392