1296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung/* 2296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * Copyright (C) 2014 The Android Open Source Project 3296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 4296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * Licensed under the Apache License, Version 2.0 (the "License"); 5296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * you may not use this file except in compliance with the License. 6296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * You may obtain a copy of the License at 7296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 8296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * http://www.apache.org/licenses/LICENSE-2.0 9296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 10296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * Unless required by applicable law or agreed to in writing, software 11296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * distributed under the License is distributed on an "AS IS" BASIS, 12296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * See the License for the specific language governing permissions and 14296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * limitations under the License. 15296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung */ 16296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 17296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung#ifndef ANDROID_AUDIO_MIXER_OPS_H 18296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung#define ANDROID_AUDIO_MIXER_OPS_H 19296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 20296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungnamespace android { 21296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 22296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung/* Behavior of is_same<>::value is true if the types are identical, 23296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * false otherwise. Identical to the STL std::is_same. 24296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung */ 25296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate<typename T, typename U> 26296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungstruct is_same 27296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung{ 28296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung static const bool value = false; 29296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung}; 30296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 31296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate<typename T> 32296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungstruct is_same<T, T> // partial specialization 33296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung{ 34296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung static const bool value = true; 35296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung}; 36296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 37296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 38296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung/* MixMul is a multiplication operator to scale an audio input signal 39296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * by a volume gain, with the formula: 40296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 41296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * O(utput) = I(nput) * V(olume) 42296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 43296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * The output, input, and volume may have different types. 44296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * There are 27 variants, of which 14 are actually defined in an 45296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * explicitly templated class. 46296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 47296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * The following type variables and the underlying meaning: 48296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 49296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * Output type TO: int32_t (Q4.27) or int16_t (Q.15) or float [-1,1] 50296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * Input signal type TI: int32_t (Q4.27) or int16_t (Q.15) or float [-1,1] 51296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * Volume type TV: int32_t (U4.28) or int16_t (U4.12) or float [-1,1] 52296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 53296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * For high precision audio, only the <TO, TI, TV> = <float, float, float> 54296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * needs to be accelerated. This is perhaps the easiest form to do quickly as well. 55650254065e7c6b5abab5e3d154f720753fe1e1cfChih-Hung Hsieh * 56650254065e7c6b5abab5e3d154f720753fe1e1cfChih-Hung Hsieh * A generic version is NOT defined to catch any mistake of using it. 57296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung */ 58296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 59296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <typename TO, typename TI, typename TV> 60650254065e7c6b5abab5e3d154f720753fe1e1cfChih-Hung HsiehTO MixMul(TI value, TV volume); 61296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 62296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 63296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline int32_t MixMul<int32_t, int16_t, int16_t>(int16_t value, int16_t volume) { 64296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return value * volume; 65296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 66296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 67296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 68296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline int32_t MixMul<int32_t, int32_t, int16_t>(int32_t value, int16_t volume) { 69296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return (value >> 12) * volume; 70296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 71296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 72296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 73296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline int32_t MixMul<int32_t, int16_t, int32_t>(int16_t value, int32_t volume) { 74296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return value * (volume >> 16); 75296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 76296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 77296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 78296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline int32_t MixMul<int32_t, int32_t, int32_t>(int32_t value, int32_t volume) { 79296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return (value >> 12) * (volume >> 16); 80296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 81296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 82296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 83296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline float MixMul<float, float, int16_t>(float value, int16_t volume) { 84296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung static const float norm = 1. / (1 << 12); 85296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return value * volume * norm; 86296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 87296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 88296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 89296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline float MixMul<float, float, int32_t>(float value, int32_t volume) { 90296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung static const float norm = 1. / (1 << 28); 91296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return value * volume * norm; 92296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 93296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 94296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 95296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline int16_t MixMul<int16_t, float, int16_t>(float value, int16_t volume) { 96296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return clamp16_from_float(MixMul<float, float, int16_t>(value, volume)); 97296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 98296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 99296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 100296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline int16_t MixMul<int16_t, float, int32_t>(float value, int32_t volume) { 101296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return clamp16_from_float(MixMul<float, float, int32_t>(value, volume)); 102296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 103296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 104296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 105296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline float MixMul<float, int16_t, int16_t>(int16_t value, int16_t volume) { 106296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung static const float norm = 1. / (1 << (15 + 12)); 107296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return static_cast<float>(value) * static_cast<float>(volume) * norm; 108296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 109296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 110296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 111296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline float MixMul<float, int16_t, int32_t>(int16_t value, int32_t volume) { 112296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung static const float norm = 1. / (1ULL << (15 + 28)); 113296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return static_cast<float>(value) * static_cast<float>(volume) * norm; 114296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 115296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 116296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 117296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline int16_t MixMul<int16_t, int16_t, int16_t>(int16_t value, int16_t volume) { 118296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return clamp16(MixMul<int32_t, int16_t, int16_t>(value, volume) >> 12); 119296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 120296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 121296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 122296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline int16_t MixMul<int16_t, int32_t, int16_t>(int32_t value, int16_t volume) { 123296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return clamp16(MixMul<int32_t, int32_t, int16_t>(value, volume) >> 12); 124296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 125296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 126296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 127296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline int16_t MixMul<int16_t, int16_t, int32_t>(int16_t value, int32_t volume) { 128296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return clamp16(MixMul<int32_t, int16_t, int32_t>(value, volume) >> 12); 129296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 130296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 131296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <> 132296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline int16_t MixMul<int16_t, int32_t, int32_t>(int32_t value, int32_t volume) { 133296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return clamp16(MixMul<int32_t, int32_t, int32_t>(value, volume) >> 12); 134296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 135296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 1365e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung/* Required for floating point volume. Some are needed for compilation but 1375e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung * are not needed in execution and should be removed from the final build by 1385e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung * an optimizing compiler. 1395e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung */ 1405e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hungtemplate <> 1415e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hunginline float MixMul<float, float, float>(float value, float volume) { 1425e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung return value * volume; 1435e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung} 1445e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung 1455e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hungtemplate <> 1465e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hunginline float MixMul<float, int16_t, float>(int16_t value, float volume) { 1475e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung static const float float_from_q_15 = 1. / (1 << 15); 1485e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung return value * volume * float_from_q_15; 1495e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung} 1505e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung 1515e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hungtemplate <> 1525e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hunginline int32_t MixMul<int32_t, int32_t, float>(int32_t value, float volume) { 1535e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung LOG_ALWAYS_FATAL("MixMul<int32_t, int32_t, float> Runtime Should not be here"); 1545e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung return value * volume; 1555e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung} 1565e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung 1575e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hungtemplate <> 1585e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hunginline int32_t MixMul<int32_t, int16_t, float>(int16_t value, float volume) { 1595e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung LOG_ALWAYS_FATAL("MixMul<int32_t, int16_t, float> Runtime Should not be here"); 1605e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung static const float u4_12_from_float = (1 << 12); 1615e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung return value * volume * u4_12_from_float; 1625e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung} 1635e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung 1645e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hungtemplate <> 1655e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hunginline int16_t MixMul<int16_t, int16_t, float>(int16_t value, float volume) { 1665e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung LOG_ALWAYS_FATAL("MixMul<int16_t, int16_t, float> Runtime Should not be here"); 16783ffcfb53b62489de9d2bd0b0277e879c3e57ab6Andy Hung return clamp16_from_float(MixMul<float, int16_t, float>(value, volume)); 1685e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung} 1695e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung 1705e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hungtemplate <> 1715e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hunginline int16_t MixMul<int16_t, float, float>(float value, float volume) { 17283ffcfb53b62489de9d2bd0b0277e879c3e57ab6Andy Hung return clamp16_from_float(value * volume); 1735e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung} 1745e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung 175296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung/* 176296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * MixAccum is used to add into an accumulator register of a possibly different 177296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * type. The TO and TI types are the same as MixMul. 178296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung */ 179296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 180296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <typename TO, typename TI> 181296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline void MixAccum(TO *auxaccum, TI value) { 182296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung if (!is_same<TO, TI>::value) { 183a4daf0b4f934b800a49f199fb8c09409391c8fc0Glenn Kasten LOG_ALWAYS_FATAL("MixAccum type not properly specialized: %zu %zu\n", 184296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung sizeof(TO), sizeof(TI)); 185296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 186296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *auxaccum += value; 187296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 188296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 189296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate<> 190296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline void MixAccum<float, int16_t>(float *auxaccum, int16_t value) { 191296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung static const float norm = 1. / (1 << 15); 192296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *auxaccum += norm * value; 193296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 194296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 195296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate<> 196296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline void MixAccum<float, int32_t>(float *auxaccum, int32_t value) { 197296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung static const float norm = 1. / (1 << 27); 198296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *auxaccum += norm * value; 199296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 200296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 201296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate<> 202296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline void MixAccum<int32_t, int16_t>(int32_t *auxaccum, int16_t value) { 203296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *auxaccum += value << 12; 204296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 205296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 206296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate<> 207296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline void MixAccum<int32_t, float>(int32_t *auxaccum, float value) { 208296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *auxaccum += clampq4_27_from_float(value); 209296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 210296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 211296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung/* MixMulAux is just like MixMul except it combines with 212296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * an accumulator operation MixAccum. 213296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung */ 214296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 215296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <typename TO, typename TI, typename TV, typename TA> 216296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline TO MixMulAux(TI value, TV volume, TA *auxaccum) { 217296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung MixAccum<TA, TI>(auxaccum, value); 218296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung return MixMul<TO, TI, TV>(value, volume); 219296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 220296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 221296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung/* MIXTYPE is used to determine how the samples in the input frame 222296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * are mixed with volume gain into the output frame. 223296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * See the volumeRampMulti functions below for more details. 224296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung */ 225296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungenum { 226296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung MIXTYPE_MULTI, 227296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung MIXTYPE_MONOEXPAND, 228296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung MIXTYPE_MULTI_SAVEONLY, 229e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung MIXTYPE_MULTI_MONOVOL, 230e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung MIXTYPE_MULTI_SAVEONLY_MONOVOL, 231296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung}; 232296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 233296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung/* 234296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * The volumeRampMulti and volumeRamp functions take a MIXTYPE 235296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * which indicates the per-frame mixing and accumulation strategy. 236296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 237296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * MIXTYPE_MULTI: 238296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * NCHAN represents number of input and output channels. 239296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * TO: int32_t (Q4.27) or float 240296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * TI: int32_t (Q4.27) or int16_t (Q0.15) or float 241296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * TV: int32_t (U4.28) or int16_t (U4.12) or float 242296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * vol: represents a volume array. 243296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 244296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * This accumulates into the out pointer. 245296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 246296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * MIXTYPE_MONOEXPAND: 247296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * Single input channel. NCHAN represents number of output channels. 248296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * TO: int32_t (Q4.27) or float 249296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * TI: int32_t (Q4.27) or int16_t (Q0.15) or float 250296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * TV: int32_t (U4.28) or int16_t (U4.12) or float 251296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * Input channel count is 1. 252296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * vol: represents volume array. 253296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 254296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * This accumulates into the out pointer. 255296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 256296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * MIXTYPE_MULTI_SAVEONLY: 257296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * NCHAN represents number of input and output channels. 258296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * TO: int16_t (Q.15) or float 259296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * TI: int32_t (Q4.27) or int16_t (Q0.15) or float 260296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * TV: int32_t (U4.28) or int16_t (U4.12) or float 261296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * vol: represents a volume array. 262296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * 263296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung * MIXTYPE_MULTI_SAVEONLY does not accumulate into the out pointer. 264e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung * 265e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung * MIXTYPE_MULTI_MONOVOL: 266e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung * Same as MIXTYPE_MULTI, but uses only volume[0]. 267e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung * 268e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung * MIXTYPE_MULTI_SAVEONLY_MONOVOL: 269e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung * Same as MIXTYPE_MULTI_SAVEONLY, but uses only volume[0]. 270e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung * 271296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung */ 272296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 273296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <int MIXTYPE, int NCHAN, 274296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung typename TO, typename TI, typename TV, typename TA, typename TAV> 275296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline void volumeRampMulti(TO* out, size_t frameCount, 276296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung const TI* in, TA* aux, TV *vol, const TV *volinc, TAV *vola, TAV volainc) 277296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung{ 278296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung#ifdef ALOGVV 279296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung ALOGVV("volumeRampMulti, MIXTYPE:%d\n", MIXTYPE); 280296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung#endif 281296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung if (aux != NULL) { 282296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung do { 283296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung TA auxaccum = 0; 284296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung switch (MIXTYPE) { 285296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung case MIXTYPE_MULTI: 286296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung for (int i = 0; i < NCHAN; ++i) { 287296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *out++ += MixMulAux<TO, TI, TV, TA>(*in++, vol[i], &auxaccum); 288296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung vol[i] += volinc[i]; 289296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 290296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 291e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung case MIXTYPE_MONOEXPAND: 292e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung for (int i = 0; i < NCHAN; ++i) { 293e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung *out++ += MixMulAux<TO, TI, TV, TA>(*in, vol[i], &auxaccum); 294e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung vol[i] += volinc[i]; 295e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung } 296e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung in++; 297e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung break; 298296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung case MIXTYPE_MULTI_SAVEONLY: 299296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung for (int i = 0; i < NCHAN; ++i) { 300296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *out++ = MixMulAux<TO, TI, TV, TA>(*in++, vol[i], &auxaccum); 301296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung vol[i] += volinc[i]; 302296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 303296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 304e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung case MIXTYPE_MULTI_MONOVOL: 305296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung for (int i = 0; i < NCHAN; ++i) { 306e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung *out++ += MixMulAux<TO, TI, TV, TA>(*in++, vol[0], &auxaccum); 307296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 308e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung vol[0] += volinc[0]; 309e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung break; 310e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung case MIXTYPE_MULTI_SAVEONLY_MONOVOL: 311e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung for (int i = 0; i < NCHAN; ++i) { 312e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung *out++ = MixMulAux<TO, TI, TV, TA>(*in++, vol[0], &auxaccum); 313e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung } 314e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung vol[0] += volinc[0]; 315296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 316296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung default: 317296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung LOG_ALWAYS_FATAL("invalid mixtype %d", MIXTYPE); 318296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 319296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 320296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung auxaccum /= NCHAN; 321296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *aux++ += MixMul<TA, TA, TAV>(auxaccum, *vola); 322296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung vola[0] += volainc; 323296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } while (--frameCount); 324296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } else { 325296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung do { 326296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung switch (MIXTYPE) { 327296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung case MIXTYPE_MULTI: 328296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung for (int i = 0; i < NCHAN; ++i) { 329296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *out++ += MixMul<TO, TI, TV>(*in++, vol[i]); 330296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung vol[i] += volinc[i]; 331296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 332296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 333e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung case MIXTYPE_MONOEXPAND: 334e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung for (int i = 0; i < NCHAN; ++i) { 335e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung *out++ += MixMul<TO, TI, TV>(*in, vol[i]); 336e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung vol[i] += volinc[i]; 337e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung } 338e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung in++; 339e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung break; 340296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung case MIXTYPE_MULTI_SAVEONLY: 341296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung for (int i = 0; i < NCHAN; ++i) { 342296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *out++ = MixMul<TO, TI, TV>(*in++, vol[i]); 343296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung vol[i] += volinc[i]; 344296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 345296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 346e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung case MIXTYPE_MULTI_MONOVOL: 347296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung for (int i = 0; i < NCHAN; ++i) { 348e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung *out++ += MixMul<TO, TI, TV>(*in++, vol[0]); 349296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 350e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung vol[0] += volinc[0]; 351e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung break; 352e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung case MIXTYPE_MULTI_SAVEONLY_MONOVOL: 353e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung for (int i = 0; i < NCHAN; ++i) { 354e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung *out++ = MixMul<TO, TI, TV>(*in++, vol[0]); 355e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung } 356e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung vol[0] += volinc[0]; 357296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 358296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung default: 359296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung LOG_ALWAYS_FATAL("invalid mixtype %d", MIXTYPE); 360296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 361296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 362296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } while (--frameCount); 363296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 364296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 365296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 366296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hungtemplate <int MIXTYPE, int NCHAN, 367296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung typename TO, typename TI, typename TV, typename TA, typename TAV> 368296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hunginline void volumeMulti(TO* out, size_t frameCount, 369296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung const TI* in, TA* aux, const TV *vol, TAV vola) 370296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung{ 371296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung#ifdef ALOGVV 372296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung ALOGVV("volumeMulti MIXTYPE:%d\n", MIXTYPE); 373296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung#endif 374296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung if (aux != NULL) { 375296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung do { 376296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung TA auxaccum = 0; 377296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung switch (MIXTYPE) { 378296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung case MIXTYPE_MULTI: 379296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung for (int i = 0; i < NCHAN; ++i) { 380296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *out++ += MixMulAux<TO, TI, TV, TA>(*in++, vol[i], &auxaccum); 381296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 382296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 383e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung case MIXTYPE_MONOEXPAND: 384e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung for (int i = 0; i < NCHAN; ++i) { 385e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung *out++ += MixMulAux<TO, TI, TV, TA>(*in, vol[i], &auxaccum); 386e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung } 387e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung in++; 388e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung break; 389296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung case MIXTYPE_MULTI_SAVEONLY: 390296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung for (int i = 0; i < NCHAN; ++i) { 391296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *out++ = MixMulAux<TO, TI, TV, TA>(*in++, vol[i], &auxaccum); 392296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 393296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 394e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung case MIXTYPE_MULTI_MONOVOL: 395296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung for (int i = 0; i < NCHAN; ++i) { 396e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung *out++ += MixMulAux<TO, TI, TV, TA>(*in++, vol[0], &auxaccum); 397e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung } 398e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung break; 399e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung case MIXTYPE_MULTI_SAVEONLY_MONOVOL: 400e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung for (int i = 0; i < NCHAN; ++i) { 401e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung *out++ = MixMulAux<TO, TI, TV, TA>(*in++, vol[0], &auxaccum); 402296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 403296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 404296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung default: 405296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung LOG_ALWAYS_FATAL("invalid mixtype %d", MIXTYPE); 406296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 407296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 408296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung auxaccum /= NCHAN; 409296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *aux++ += MixMul<TA, TA, TAV>(auxaccum, vola); 410296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } while (--frameCount); 411296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } else { 412296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung do { 413296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung switch (MIXTYPE) { 414296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung case MIXTYPE_MULTI: 415296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung for (int i = 0; i < NCHAN; ++i) { 416296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *out++ += MixMul<TO, TI, TV>(*in++, vol[i]); 417296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 418296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 419e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung case MIXTYPE_MONOEXPAND: 420e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung for (int i = 0; i < NCHAN; ++i) { 421e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung *out++ += MixMul<TO, TI, TV>(*in, vol[i]); 422e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung } 423e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung in++; 424e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung break; 425296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung case MIXTYPE_MULTI_SAVEONLY: 426296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung for (int i = 0; i < NCHAN; ++i) { 427296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung *out++ = MixMul<TO, TI, TV>(*in++, vol[i]); 428296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 429296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 430e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung case MIXTYPE_MULTI_MONOVOL: 431296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung for (int i = 0; i < NCHAN; ++i) { 432e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung *out++ += MixMul<TO, TI, TV>(*in++, vol[0]); 433e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung } 434e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung break; 435e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung case MIXTYPE_MULTI_SAVEONLY_MONOVOL: 436e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung for (int i = 0; i < NCHAN; ++i) { 437e93b6b7347a7846c8fd746542364ec11b0cd5124Andy Hung *out++ = MixMul<TO, TI, TV>(*in++, vol[0]); 438296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 439296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 440296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung default: 441296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung LOG_ALWAYS_FATAL("invalid mixtype %d", MIXTYPE); 442296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung break; 443296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 444296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } while (--frameCount); 445296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung } 446296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung} 447296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 448296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung}; 449296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung 450296b741e8eb38e749e3202182f703a2e30ee5f1fAndy Hung#endif /* ANDROID_AUDIO_MIXER_OPS_H */ 451