AudioMixer.h revision 4e2293f29f2e719af1245d365747ea06d074b345
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 247d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi#include <utils/threads.h> 257d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi 2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioBufferProvider.h" 2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioResampler.h" 2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 297d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi#include <audio_effects/effect_downmix.h> 307d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi#include <system/audio.h> 317d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi 3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android { 3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianclass AudioMixer 3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianpublic: 395c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten AudioMixer(size_t frameCount, uint32_t sampleRate, 405c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten uint32_t maxNumTracks = MAX_NUM_TRACKS); 4165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 42c19e22450e6e3d07594c935c7a9522e85e909e82Glenn Kasten /*virtual*/ ~AudioMixer(); // non-virtual saves a v-table, restore if sub-classed 4365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static const uint32_t MAX_NUM_TRACKS = 32; 457d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi // maximum number of channels supported by the mixer 4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static const uint32_t MAX_NUM_CHANNELS = 2; 477d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi // maximum number of channels supported for the content 487d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = 8; 4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static const uint16_t UNITY_GAIN = 0x1000; 5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian enum { // names 5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 549c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten // track names (MAX_NUM_TRACKS units) 5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian TRACK0 = 0x1000, 5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 571c48c3c61970527b97892ab6a2daae8eaac26964Glenn Kasten // 0x2000 is unused 5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // setParameter targets 6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian TRACK = 0x3000, 6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian RESAMPLE = 0x3001, 6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian RAMP_VOLUME = 0x3002, // ramp to new volume 6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian VOLUME = 0x3003, // don't ramp 6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // set Parameter names 6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // for target TRACK 670d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi CHANNEL_MASK = 0x4000, 6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian FORMAT = 0x4001, 6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian MAIN_BUFFER = 0x4002, 7065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AUX_BUFFER = 0x4003, 717d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi DOWNMIX_TYPE = 0X4004, 72362c4e697d8e9c034e964ac7b40227e054491547Glenn Kasten // for target RESAMPLE 734e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten SAMPLE_RATE = 0x4100, // Configure sample rate conversion on this track name; 744e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // parameter 'value' is the new sample rate in Hz. 754e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // Only creates a sample rate converter the first time that 764e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // the track sample rate is different from the mix sample rate. 774e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // If the new sample rate is the same as the mix sample rate, 784e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // and a sample rate converter already exists, 794e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // then the sample rate converter remains present but is a no-op. 804e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten RESET = 0x4101, // Reset sample rate converter without changing sample rate. 814e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // This clears out the resampler's input buffer. 824e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten REMOVE = 0x4102, // Remove the sample rate converter on this track name; 834e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // the track is restored to the mix sample rate. 84362c4e697d8e9c034e964ac7b40227e054491547Glenn Kasten // for target RAMP_VOLUME and VOLUME (8 channels max) 8565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian VOLUME0 = 0x4200, 8665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian VOLUME1 = 0x4201, 8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AUXLEVEL = 0x4210, 8865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }; 8965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 9065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 919c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten // For all APIs with "name": TRACK0 <= name < TRACK0 + MAX_NUM_TRACKS 9217a736c3e1d062d7fc916329eb32aef8935614afGlenn Kasten 9317a736c3e1d062d7fc916329eb32aef8935614afGlenn Kasten // Allocate a track name. Returns new track name if successful, -1 on failure. 9465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int getTrackName(); 9517a736c3e1d062d7fc916329eb32aef8935614afGlenn Kasten 9617a736c3e1d062d7fc916329eb32aef8935614afGlenn Kasten // Free an allocated track by name 9765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian void deleteTrackName(int name); 9865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 9917a736c3e1d062d7fc916329eb32aef8935614afGlenn Kasten // Enable or disable an allocated track by name 1009c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten void enable(int name); 1019c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten void disable(int name); 10265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1039c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten void setParameter(int name, int target, int param, void *value); 10465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1059c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten void setBufferProvider(int name, AudioBufferProvider* bufferProvider); 1064ff14bae91075eb274eb1c2975982358946e7e63John Grossman void process(int64_t pts); 10765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 10865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t trackNames() const { return mTrackNames; } 10965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 110c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kasten size_t getUnreleasedFrames(int name) const; 111071ccd5a9702500f3f7d62ef881300914926184dEric Laurent 11265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianprivate: 11365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 11465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian enum { 1157d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi NEEDS_CHANNEL_COUNT__MASK = 0x00000007, 11665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_FORMAT__MASK = 0x000000F0, 11765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_MUTE__MASK = 0x00000100, 11865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_RESAMPLE__MASK = 0x00001000, 11965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_AUX__MASK = 0x00010000, 12065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }; 12165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 12265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian enum { 12365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_CHANNEL_1 = 0x00000000, 12465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_CHANNEL_2 = 0x00000001, 12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 12665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_FORMAT_16 = 0x00000010, 12765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 12865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_MUTE_DISABLED = 0x00000000, 12965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_MUTE_ENABLED = 0x00000100, 13065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 13165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_RESAMPLE_DISABLED = 0x00000000, 13265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_RESAMPLE_ENABLED = 0x00001000, 13365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 13465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_AUX_DISABLED = 0x00000000, 13565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian NEEDS_AUX_ENABLED = 0x00010000, 13665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }; 13765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 13865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian struct state_t; 13965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian struct track_t; 1407d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi class DownmixerBufferProvider; 14165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 14265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian typedef void (*hook_t)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux); 14365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static const int BLOCKSIZE = 16; // 4 cache lines 14465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 14565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian struct track_t { 14665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t needs; 14765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 14865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian union { 149bf71f1e7948406492376c6cbd5e6a30c8cb670e4Glenn Kasten int16_t volume[MAX_NUM_CHANNELS]; // [0]3.12 fixed point 15065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t volumeRL; 15165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }; 15265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 153bf71f1e7948406492376c6cbd5e6a30c8cb670e4Glenn Kasten int32_t prevVolume[MAX_NUM_CHANNELS]; 15465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1553b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten // 16-byte boundary 1563b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 157bf71f1e7948406492376c6cbd5e6a30c8cb670e4Glenn Kasten int32_t volumeInc[MAX_NUM_CHANNELS]; 15865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t auxInc; 15965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t prevAuxLevel; 16065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1613b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten // 16-byte boundary 1623b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 1633b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten int16_t auxLevel; // 0 <= auxLevel <= MAX_GAIN_INT, but signed for mul performance 16465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint16_t frameCount; 16565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1663b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten uint8_t channelCount; // 1 or 2, redundant with (needs & NEEDS_CHANNEL_COUNT__MASK) 1673b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten uint8_t format; // always 16 1683b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten uint16_t enabled; // actually bool 1697d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi audio_channel_mask_t channelMask; 17065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1717d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi // actual buffer provider used by the track hooks, see DownmixerBufferProvider below 1727d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi // for how the Track buffer provider is wrapped by another one when dowmixing is required 17365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioBufferProvider* bufferProvider; 1743b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 1753b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten // 16-byte boundary 1763b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 1773b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten mutable AudioBufferProvider::Buffer buffer; // 8 bytes 17865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 17965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian hook_t hook; 18054c3b66444ebfb9f2265ee70ac3b76ccefa0506aGlenn Kasten const void* in; // current location in buffer 18165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1823b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten // 16-byte boundary 1833b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 18465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioResampler* resampler; 18565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t sampleRate; 18665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t* mainBuffer; 18765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t* auxBuffer; 18865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1893b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten // 16-byte boundary 1903b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 1914ff14bae91075eb274eb1c2975982358946e7e63John Grossman uint64_t localTimeFreq; 1924ff14bae91075eb274eb1c2975982358946e7e63John Grossman 1937d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi DownmixerBufferProvider* downmixerBufferProvider; // 4 bytes 1947d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi 1957d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi int32_t padding; 1963b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 1973b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten // 16-byte boundary 1983b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten 19965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool setResampler(uint32_t sampleRate, uint32_t devSampleRate); 200c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kasten bool doesResample() const { return resampler != NULL; } 201c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kasten void resetResampler() { if (resampler != NULL) resampler->reset(); } 20265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian void adjustVolumeRamp(bool aux); 203c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kasten size_t getUnreleasedFrames() const { return resampler != NULL ? 204c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kasten resampler->getUnreleasedFrames() : 0; }; 20565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }; 20665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // pad to 32-bytes to fill cache line 20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian struct state_t { 20965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t enabledTracks; 21065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t needsChanged; 21165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian size_t frameCount; 212a111792f1314479c649d1d44c30c2caf70c00c2aGlenn Kasten void (*hook)(state_t* state, int64_t pts); // one of process__*, never NULL 21365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t *outputTemp; 21465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t *resampleTemp; 21565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t reserved[2]; 2165c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten // FIXME allocate dynamically to save some memory when maxNumTracks < MAX_NUM_TRACKS 217bf71f1e7948406492376c6cbd5e6a30c8cb670e4Glenn Kasten track_t tracks[MAX_NUM_TRACKS]; __attribute__((aligned(32))); 21865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian }; 21965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2207d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi // AudioBufferProvider that wraps a track AudioBufferProvider by a call to a downmix effect 2217d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi class DownmixerBufferProvider : public AudioBufferProvider { 2227d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi public: 2237d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi virtual status_t getNextBuffer(Buffer* buffer, int64_t pts); 2247d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi virtual void releaseBuffer(Buffer* buffer); 2257d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi DownmixerBufferProvider(); 2267d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi virtual ~DownmixerBufferProvider(); 2277d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi 2287d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi AudioBufferProvider* mTrackBufferProvider; 2297d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi effect_handle_t mDownmixHandle; 2307d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi effect_config_t mDownmixConfig; 2317d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi }; 2327d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi 2339c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten // bitmask of allocated track names, where bit 0 corresponds to TRACK0 etc. 23465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t mTrackNames; 2355c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten 2365c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten // bitmask of configured track names; ~0 if maxNumTracks == MAX_NUM_TRACKS, 2375c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten // but will have fewer bits set if maxNumTracks < MAX_NUM_TRACKS 2385c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten const uint32_t mConfiguredNames; 2395c94b6c7689a335e26a86e8a0d04b56dc627738eGlenn Kasten 24065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const uint32_t mSampleRate; 24165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 24265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian state_t mState __attribute__((aligned(32))); 24365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2447d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi // effect descriptor for the downmixer used by the mixer 2457d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi static effect_descriptor_t dwnmFxDesc; 2467d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi // indicates whether a downmix effect has been found and is usable by this mixer 2477d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi static bool isMultichannelCapable; 2487d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi 2494e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // Call after changing either the enabled status of a track, or parameters of an enabled track. 2504e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten // OK to call more often than that, but unnecessary. 25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian void invalidateState(uint32_t mask); 2524e2293f29f2e719af1245d365747ea06d074b345Glenn Kasten 2537d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi static status_t prepareTrackForDownmix(track_t* pTrack, int trackNum); 25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 25565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); 25665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); 25765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); 25865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); 25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux); 26065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static void volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux); 26165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2624ff14bae91075eb274eb1c2975982358946e7e63John Grossman static void process__validate(state_t* state, int64_t pts); 2634ff14bae91075eb274eb1c2975982358946e7e63John Grossman static void process__nop(state_t* state, int64_t pts); 2644ff14bae91075eb274eb1c2975982358946e7e63John Grossman static void process__genericNoResampling(state_t* state, int64_t pts); 2654ff14bae91075eb274eb1c2975982358946e7e63John Grossman static void process__genericResampling(state_t* state, int64_t pts); 2664ff14bae91075eb274eb1c2975982358946e7e63John Grossman static void process__OneTrack16BitsStereoNoResampling(state_t* state, 2674ff14bae91075eb274eb1c2975982358946e7e63John Grossman int64_t pts); 26881a028fef62bcadf13fc8550067a3d29c918b3caGlenn Kasten#if 0 2694ff14bae91075eb274eb1c2975982358946e7e63John Grossman static void process__TwoTracks16BitsStereoNoResampling(state_t* state, 2704ff14bae91075eb274eb1c2975982358946e7e63John Grossman int64_t pts); 27181a028fef62bcadf13fc8550067a3d29c918b3caGlenn Kasten#endif 2724ff14bae91075eb274eb1c2975982358946e7e63John Grossman 2734ff14bae91075eb274eb1c2975982358946e7e63John Grossman static int64_t calculateOutputPTS(const track_t& t, int64_t basePTS, 2744ff14bae91075eb274eb1c2975982358946e7e63John Grossman int outputFrameIndex); 27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; 27665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 27765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 27865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android 27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#endif // ANDROID_AUDIO_MIXER_H 281