EffectDownmix.c revision 7d5b26230a179cd7bcc01f6578cd80d8c15a92a5
104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/* 204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Copyright (C) 2012 The Android Open Source Project 304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * you may not use this file except in compliance with the License. 604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * You may obtain a copy of the License at 704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 1004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 1104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 1204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * See the License for the specific language governing permissions and 1404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * limitations under the License. 1504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi */ 1604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 1704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi#define LOG_TAG "EffectDownmix" 1804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi#define LOG_NDEBUG 0 1904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi#include <cutils/log.h> 2004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi#include <stdlib.h> 2104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi#include <string.h> 2204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi#include <stdbool.h> 2304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi#include "EffectDownmix.h" 2404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 2504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi#define MINUS_3_DB_IN_Q19_12 2896 // -3dB = 0.707 * 2^12 = 2896 2604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 2704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi// effect_handle_t interface implementation for downmix effect 2804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviconst struct effect_interface_s gDownmixInterface = { 2904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi Downmix_Process, 3004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi Downmix_Command, 3104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi Downmix_GetDescriptor, 3204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi NULL /* no process_reverse function, no reference stream needed */ 3304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi}; 3404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 3504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviaudio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { 3604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi tag : AUDIO_EFFECT_LIBRARY_TAG, 3704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi version : EFFECT_LIBRARY_API_VERSION, 3804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi name : "Downmix Library", 3904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi implementor : "The Android Open Source Project", 4004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi query_num_effects : DownmixLib_QueryNumberEffects, 4104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi query_effect : DownmixLib_QueryEffect, 4204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi create_effect : DownmixLib_Create, 4304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi release_effect : DownmixLib_Release, 4404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi get_descriptor : DownmixLib_GetDescriptor, 4504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi}; 4604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 4704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 4804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi// AOSP insert downmix UUID: 93f04452-e4fe-41cc-91f9-e475b6d1d69f 4904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivistatic const effect_descriptor_t gDownmixDescriptor = { 5004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi EFFECT_UIID_DOWNMIX__, //type 5104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi {0x93f04452, 0xe4fe, 0x41cc, 0x91f9, {0xe4, 0x75, 0xb6, 0xd1, 0xd6, 0x9f}}, // uuid 5204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi EFFECT_CONTROL_API_VERSION, 5304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST, 5404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 0, //FIXME what value should be reported? // cpu load 5504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 0, //FIXME what value should be reported? // memory usage 5604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi "Multichannel Downmix To Stereo", // human readable effect name 5704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi "The Android Open Source Project" // human readable effect implementor name 5804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi}; 5904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 6004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi// gDescriptors contains pointers to all defined effect descriptor in this library 6104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivistatic const effect_descriptor_t * const gDescriptors[] = { 6204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi &gDownmixDescriptor 6304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi}; 6404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 6504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi// number of effects in this library 6604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviconst int kNbEffects = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *); 6704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 6804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 6904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*---------------------------------------------------------------------------- 7004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Effect API implementation 7104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *--------------------------------------------------------------------------*/ 7204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 7304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*--- Effect Library Interface Implementation ---*/ 7404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 7504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviint32_t DownmixLib_QueryNumberEffects(uint32_t *pNumEffects) { 7604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("DownmixLib_QueryNumberEffects()"); 7704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *pNumEffects = kNbEffects; 7804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return 0; 7904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 8004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 8104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviint32_t DownmixLib_QueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) { 8204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("DownmixLib_QueryEffect() index=%d", index); 8304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pDescriptor == NULL) { 8404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 8504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 8604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (index >= (uint32_t)kNbEffects) { 8704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 8804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 8904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi memcpy(pDescriptor, gDescriptors[index], sizeof(effect_descriptor_t)); 9004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return 0; 9104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 9204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 9304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 9404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviint32_t DownmixLib_Create(const effect_uuid_t *uuid, 9504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int32_t sessionId, 9604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int32_t ioId, 9704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi effect_handle_t *pHandle) { 9804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int ret; 9904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int i; 10004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi downmix_module_t *module; 10104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi const effect_descriptor_t *desc; 10204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 10304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("DownmixLib_Create()"); 10404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 10504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pHandle == NULL || uuid == NULL) { 10604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 10704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 10804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 10904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi for (i = 0 ; i < kNbEffects ; i++) { 11004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi desc = gDescriptors[i]; 11104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (memcmp(uuid, &desc->uuid, sizeof(effect_uuid_t)) == 0) { 11204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 11304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 11404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 11504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 11604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (i == kNbEffects) { 11704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -ENOENT; 11804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 11904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 12004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi module = malloc(sizeof(downmix_module_t)); 12104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 12204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi module->itfe = &gDownmixInterface; 12304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 12404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi module->context.state = DOWNMIX_STATE_UNINITIALIZED; 12504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 12604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ret = Downmix_Init(module); 12704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (ret < 0) { 12804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGW("DownmixLib_Create() init failed"); 12904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi free(module); 13004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return ret; 13104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 13204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 13304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *pHandle = (effect_handle_t) module; 13404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 13504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("DownmixLib_Create() %p , size %d", module, sizeof(downmix_module_t)); 13604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 13704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return 0; 13804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 13904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 14004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 14104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviint32_t DownmixLib_Release(effect_handle_t handle) { 14204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi downmix_module_t *pDwmModule = (downmix_module_t *)handle; 14304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 14404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("DownmixLib_Release() %p", handle); 14504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (handle == NULL) { 14604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 14704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 14804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 14904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->context.state = DOWNMIX_STATE_UNINITIALIZED; 15004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 15104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi free(pDwmModule); 15204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return 0; 15304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 15404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 15504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 15604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviint32_t DownmixLib_GetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) { 15704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("DownmixLib_GetDescriptor()"); 15804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int i; 15904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 16004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pDescriptor == NULL || uuid == NULL){ 16104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGE("DownmixLib_Create() called with NULL pointer"); 16204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 16304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 16404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("DownmixLib_GetDescriptor() nb effects=%d", kNbEffects); 16504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi for (i = 0; i < kNbEffects; i++) { 16604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("DownmixLib_GetDescriptor() i=%d", i); 16704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (memcmp(uuid, &gDescriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) { 16804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi memcpy(pDescriptor, gDescriptors[i], sizeof(effect_descriptor_t)); 16904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("EffectGetDescriptor - UUID matched downmix type %d, UUID = %x", 17004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi i, gDescriptors[i]->uuid.timeLow); 17104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return 0; 17204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 17304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 17404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 17504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 17604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 17704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 17804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 17904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*--- Effect Control Interface Implementation ---*/ 18004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 18104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivistatic int Downmix_Process(effect_handle_t self, 18204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) { 18304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 18404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi downmix_object_t *pDownmixer; 18504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int16_t *pSrc, *pDst; 18604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi downmix_module_t *pDwmModule = (downmix_module_t *)self; 18704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 18804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pDwmModule == NULL) { 18904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 19004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 19104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 19204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (inBuffer == NULL || inBuffer->raw == NULL || 19304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi outBuffer == NULL || outBuffer->raw == NULL || 19404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi inBuffer->frameCount != outBuffer->frameCount) { 19504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 19604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 19704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 19804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDownmixer = (downmix_object_t*) &pDwmModule->context; 19904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 20004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pDownmixer->state == DOWNMIX_STATE_UNINITIALIZED) { 20104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGE("Downmix_Process error: trying to use an uninitialized downmixer"); 20204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 20304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } else if (pDownmixer->state == DOWNMIX_STATE_INITIALIZED) { 20404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGE("Downmix_Process error: trying to use a non-configured downmixer"); 20504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -ENODATA; 20604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 20704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 20804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pSrc = inBuffer->s16; 20904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst = outBuffer->s16; 21004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi size_t numFrames = outBuffer->frameCount; 21104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 21204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi const bool accumulate = 21304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi (pDwmModule->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE); 21404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 21504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi switch(pDownmixer->type) { 21604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 21704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case DOWNMIX_TYPE_STRIP: 21804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (accumulate) { 21904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi while (numFrames) { 22004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[0] = clamp16(pDst[0] + pSrc[0]); 22104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[1] = clamp16(pDst[1] + pSrc[1]); 22204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pSrc += pDownmixer->input_channel_count; 22304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst += 2; 22404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi numFrames--; 22504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 22604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } else { 22704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi while (numFrames) { 22804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[0] = pSrc[0]; 22904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[1] = pSrc[1]; 23004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pSrc += pDownmixer->input_channel_count; 23104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst += 2; 23204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi numFrames--; 23304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 23404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 23504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 23604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 23704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case DOWNMIX_TYPE_FOLD: 23804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // optimize for the common formats 23904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi switch(pDwmModule->config.inputCfg.channels) { 24004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case AUDIO_CHANNEL_OUT_QUAD: 24104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi Downmix_foldFromQuad(pSrc, pDst, numFrames, accumulate); 24204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 24304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case AUDIO_CHANNEL_OUT_SURROUND: 24404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi Downmix_foldFromSurround(pSrc, pDst, numFrames, accumulate); 24504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 24604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case AUDIO_CHANNEL_OUT_5POINT1: 24704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi Downmix_foldFrom5Point1(pSrc, pDst, numFrames, accumulate); 24804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 24904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case AUDIO_CHANNEL_OUT_7POINT1: 25004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi Downmix_foldFrom7Point1(pSrc, pDst, numFrames, accumulate); 25104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 25204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi default: 25304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FIXME implement generic downmix 25404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGE("Multichannel configurations other than quad, 4.0, 5.1 and 7.1 are not supported"); 25504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 25604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 25704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 25804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 25904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi default: 26004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 26104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 26204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 26304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return 0; 26404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 26504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 26604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 26704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivistatic int Downmix_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, 26804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi void *pCmdData, uint32_t *replySize, void *pReplyData) { 26904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 27004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi downmix_module_t *pDwmModule = (downmix_module_t *) self; 27104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi downmix_object_t *pDownmixer; 27204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int retsize; 27304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 27404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pDwmModule == NULL || pDwmModule->context.state == DOWNMIX_STATE_UNINITIALIZED) { 27504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 27604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 27704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 27804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDownmixer = (downmix_object_t*) &pDwmModule->context; 27904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 28004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("Downmix_Command command %d cmdSize %d",cmdCode, cmdSize); 28104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 28204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi switch (cmdCode) { 28304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_INIT: 28404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pReplyData == NULL || *replySize != sizeof(int)) { 28504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 28604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 28704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *(int *) pReplyData = Downmix_Init(pDwmModule); 28804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 28904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 29004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_SET_CONFIG: 29104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) 29204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi || pReplyData == NULL || *replySize != sizeof(int)) { 29304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 29404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 29504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *(int *) pReplyData = Downmix_Configure(pDwmModule, 29604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi (effect_config_t *)pCmdData, false); 29704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 29804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 29904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_RESET: 30004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi Downmix_Reset(pDownmixer, false); 30104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 30204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 30304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_GET_PARAM: 30404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("Downmix_Command EFFECT_CMD_GET_PARAM pCmdData %p, *replySize %d, pReplyData: %p", 30504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pCmdData, *replySize, pReplyData); 30604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) || 30704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pReplyData == NULL || 30804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *replySize < (int) sizeof(effect_param_t) + 2 * sizeof(int32_t)) { 30904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 31004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 31104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi effect_param_t *rep = (effect_param_t *) pReplyData; 31204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + sizeof(int32_t)); 31304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("Downmix_Command EFFECT_CMD_GET_PARAM param %d, replySize %d", 31404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *(int32_t *)rep->data, rep->vsize); 31504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi rep->status = Downmix_getParameter(pDownmixer, *(int32_t *)rep->data, &rep->vsize, 31604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi rep->data + sizeof(int32_t)); 31704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *replySize = sizeof(effect_param_t) + sizeof(int32_t) + rep->vsize; 31804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 31904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 32004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_SET_PARAM: 32104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("Downmix_Command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, " \ 32204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi "pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData); 32304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pCmdData == NULL || (cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t))) 32404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi || pReplyData == NULL || *replySize != (int)sizeof(int32_t)) { 32504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 32604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 32704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi effect_param_t *cmd = (effect_param_t *) pCmdData; 32804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *(int *)pReplyData = Downmix_setParameter(pDownmixer, *(int32_t *)cmd->data, 32904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi cmd->vsize, cmd->data + sizeof(int32_t)); 33004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 33104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 33204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_SET_PARAM_DEFERRED: 33304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi //FIXME implement 33404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGW("Downmix_Command command EFFECT_CMD_SET_PARAM_DEFERRED not supported, FIXME"); 33504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 33604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 33704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_SET_PARAM_COMMIT: 33804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi //FIXME implement 33904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGW("Downmix_Command command EFFECT_CMD_SET_PARAM_COMMIT not supported, FIXME"); 34004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 34104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 34204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_ENABLE: 34304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pReplyData == NULL || *replySize != sizeof(int)) { 34404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 34504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 34604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pDownmixer->state != DOWNMIX_STATE_INITIALIZED) { 34704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -ENOSYS; 34804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 34904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDownmixer->state = DOWNMIX_STATE_ACTIVE; 35004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("EFFECT_CMD_ENABLE() OK"); 35104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *(int *)pReplyData = 0; 35204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 35304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 35404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_DISABLE: 35504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pReplyData == NULL || *replySize != sizeof(int)) { 35604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 35704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 35804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pDownmixer->state != DOWNMIX_STATE_ACTIVE) { 35904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -ENOSYS; 36004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 36104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDownmixer->state = DOWNMIX_STATE_INITIALIZED; 36204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("EFFECT_CMD_DISABLE() OK"); 36304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *(int *)pReplyData = 0; 36404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 36504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 36604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_SET_DEVICE: 36704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pCmdData == NULL || cmdSize != (int)sizeof(uint32_t)) { 36804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 36904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 37004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FIXME change type if playing on headset vs speaker 37104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("Downmix_Command EFFECT_CMD_SET_DEVICE: 0x%08x", *(uint32_t *)pCmdData); 37204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 37304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 37404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_SET_VOLUME: { 37504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // audio output is always stereo => 2 channel volumes 37604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pCmdData == NULL || cmdSize != (int)sizeof(uint32_t) * 2) { 37704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 37804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 37904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FIXME change volume 38004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGW("Downmix_Command command EFFECT_CMD_SET_VOLUME not supported, FIXME"); 38104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi float left = (float)(*(uint32_t *)pCmdData) / (1 << 24); 38204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi float right = (float)(*((uint32_t *)pCmdData + 1)) / (1 << 24); 38304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("Downmix_Command EFFECT_CMD_SET_VOLUME: left %f, right %f ", left, right); 38404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 38504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 38604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 38704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_SET_AUDIO_MODE: 38804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pCmdData == NULL || cmdSize != (int)sizeof(uint32_t)) { 38904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 39004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 39104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("Downmix_Command EFFECT_CMD_SET_AUDIO_MODE: %d", *(uint32_t *)pCmdData); 39204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 39304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 39404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_SET_CONFIG_REVERSE: 39504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case EFFECT_CMD_SET_INPUT_DEVICE: 39604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // these commands are ignored by a downmix effect 39704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 39804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 39904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi default: 40004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGW("Downmix_Command invalid command %d",cmdCode); 40104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 40204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 40304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 40404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return 0; 40504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 40604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 40704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 40804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviint Downmix_GetDescriptor(effect_handle_t self, effect_descriptor_t *pDescriptor) 40904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi{ 41004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi downmix_module_t *pDwnmxModule = (downmix_module_t *) self; 41104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 41204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pDwnmxModule == NULL || 41304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwnmxModule->context.state == DOWNMIX_STATE_UNINITIALIZED) { 41404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 41504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 41604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 41704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi memcpy(pDescriptor, &gDownmixDescriptor, sizeof(effect_descriptor_t)); 41804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 41904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return 0; 42004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 42104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 42204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 42304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*---------------------------------------------------------------------------- 42404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Downmix internal functions 42504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *--------------------------------------------------------------------------*/ 42604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 42704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*---------------------------------------------------------------------------- 42804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Downmix_Init() 42904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 43004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Purpose: 43104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Initialize downmix context and apply default parameters 43204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 43304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Inputs: 43404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDwmModule pointer to downmix effect module 43504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 43604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Outputs: 43704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 43804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Returns: 43904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 0 indicates success 44004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 44104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Side Effects: 44204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * updates: 44304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDwmModule->context.type 44404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDwmModule->context.apply_volume_correction 44504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDwmModule->config.inputCfg 44604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDwmModule->config.outputCfg 44704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDwmModule->config.inputCfg.samplingRate 44804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDwmModule->config.outputCfg.samplingRate 44904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDwmModule->context.state 45004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * doesn't set: 45104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDwmModule->itfe 45204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 45304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 45404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi */ 45504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 45604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviint Downmix_Init(downmix_module_t *pDwmModule) { 45704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 45804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("Downmix_Init module %p", pDwmModule); 45904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int ret = 0; 46004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 46104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi memset(&pDwmModule->context, 0, sizeof(downmix_object_t)); 46204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 46304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; 46404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 46504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.inputCfg.channels = AUDIO_CHANNEL_OUT_7POINT1; 46604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.inputCfg.bufferProvider.getBuffer = NULL; 46704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.inputCfg.bufferProvider.releaseBuffer = NULL; 46804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.inputCfg.bufferProvider.cookie = NULL; 46904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.inputCfg.mask = EFFECT_CONFIG_ALL; 47004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 47104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.inputCfg.samplingRate = 44100; 47204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.outputCfg.samplingRate = pDwmModule->config.inputCfg.samplingRate; 47304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 47404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // set a default value for the access mode, but should be overwritten by caller 47504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE; 47604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 47704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 47804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.outputCfg.bufferProvider.getBuffer = NULL; 47904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.outputCfg.bufferProvider.releaseBuffer = NULL; 48004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.outputCfg.bufferProvider.cookie = NULL; 48104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->config.outputCfg.mask = EFFECT_CONFIG_ALL; 48204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 48304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ret = Downmix_Configure(pDwmModule, &pDwmModule->config, true); 48404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (ret != 0) { 48504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("Downmix_Init error %d on module %p", ret, pDwmModule); 48604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } else { 48704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDwmModule->context.state = DOWNMIX_STATE_INITIALIZED; 48804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 48904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 49004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return ret; 49104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 49204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 49304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 49404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*---------------------------------------------------------------------------- 49504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Downmix_Configure() 49604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 49704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Purpose: 49804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Set input and output audio configuration. 49904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 50004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Inputs: 50104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDwmModule pointer to downmix effect module 50204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pConfig pointer to effect_config_t structure containing input 50304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * and output audio parameters configuration 50404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * init true if called from init function 50504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 50604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Outputs: 50704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 50804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Returns: 50904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 0 indicates success 51004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 51104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Side Effects: 51204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 51304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 51404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi */ 51504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 51604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviint Downmix_Configure(downmix_module_t *pDwmModule, effect_config_t *pConfig, bool init) { 51704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 51804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi downmix_object_t *pDownmixer = &pDwmModule->context; 51904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 52004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // Check configuration compatibility with build options, and effect capabilities 52104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pConfig->inputCfg.samplingRate != pConfig->outputCfg.samplingRate 52204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi || pConfig->outputCfg.channels != DOWNMIX_OUTPUT_CHANNELS 52304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi || pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT 52404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi || pConfig->outputCfg.format != AUDIO_FORMAT_PCM_16_BIT) { 52504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGE("Downmix_Configure error: invalid config"); 52604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 52704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 52804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 52904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi memcpy(&pDwmModule->config, pConfig, sizeof(effect_config_t)); 53004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 53104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (init) { 53204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDownmixer->type = DOWNMIX_TYPE_FOLD; 53304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDownmixer->apply_volume_correction = false; 53404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDownmixer->input_channel_count = 8; // matches default input of AUDIO_CHANNEL_OUT_7POINT1 53504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } else { 53604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // when configuring the effect, do not allow a blank channel mask 53704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (pConfig->inputCfg.channels == 0) { 53804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGE("Downmix_Configure error: input channel mask can't be 0"); 53904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 54004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 54104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDownmixer->input_channel_count = popcount(pConfig->inputCfg.channels); 54204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 54304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 54404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi Downmix_Reset(pDownmixer, init); 54504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 54604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return 0; 54704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 54804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 54904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 55004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*---------------------------------------------------------------------------- 55104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Downmix_Reset() 55204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 55304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Purpose: 55404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Reset internal states. 55504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 55604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Inputs: 55704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDownmixer pointer to downmix context 55804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * init true if called from init function 55904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 56004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Outputs: 56104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi* 56204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Returns: 56304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 0 indicates success 56404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 56504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Side Effects: 56604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 56704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 56804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi */ 56904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 57004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviint Downmix_Reset(downmix_object_t *pDownmixer, bool init) { 57104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // nothing to do here 57204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return 0; 57304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 57404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 57504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 57604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*---------------------------------------------------------------------------- 57704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Downmix_setParameter() 57804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 57904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Purpose: 58004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Set a Downmix parameter 58104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 58204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Inputs: 58304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDownmixer handle to instance data 58404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * param parameter 58504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pValue pointer to parameter value 58604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * size value size 58704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 58804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Outputs: 58904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 59004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Returns: 59104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 0 indicates success 59204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 59304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Side Effects: 59404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 59504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 59604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi */ 59704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviint Downmix_setParameter(downmix_object_t *pDownmixer, int32_t param, size_t size, void *pValue) { 59804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 59904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int16_t value16; 60004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("Downmix_setParameter, context %p, param %d, value16 %d, value32 %d", 60104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDownmixer, param, *(int16_t *)pValue, *(int32_t *)pValue); 60204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 60304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi switch (param) { 60404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 60504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case DOWNMIX_PARAM_TYPE: 60604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (size != sizeof(downmix_type_t)) { 60704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGE("Downmix_setParameter(DOWNMIX_PARAM_TYPE) invalid size %d, should be %d", 60804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi size, sizeof(downmix_type_t)); 60904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 61004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 61104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi value16 = *(int16_t *)pValue; 61204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("set DOWNMIX_PARAM_TYPE, type %d", value16); 6137d5b26230a179cd7bcc01f6578cd80d8c15a92a5Jean-Michel Trivi if (!((value16 > DOWNMIX_TYPE_INVALID) && (value16 <= DOWNMIX_TYPE_LAST))) { 61404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGE("Downmix_setParameter invalid DOWNMIX_PARAM_TYPE value %d", value16); 61504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 61604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } else { 61704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDownmixer->type = (downmix_type_t) value16; 61804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 61904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 62004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi default: 62104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGE("Downmix_setParameter unknown parameter %d", param); 62204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 62304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 62404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 62504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 62604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return 0; 62704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} /* end Downmix_setParameter */ 62804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 62904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 63004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*---------------------------------------------------------------------------- 63104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Downmix_getParameter() 63204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 63304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Purpose: 63404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Get a Downmix parameter 63504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 63604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Inputs: 63704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDownmixer handle to instance data 63804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * param parameter 63904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pValue pointer to variable to hold retrieved value 64004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pSize pointer to value size: maximum size as input 64104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 64204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Outputs: 64304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * *pValue updated with parameter value 64404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * *pSize updated with actual value size 64504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 64604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Returns: 64704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 0 indicates success 64804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 64904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Side Effects: 65004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 65104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 65204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi */ 65304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Triviint Downmix_getParameter(downmix_object_t *pDownmixer, int32_t param, size_t *pSize, void *pValue) { 65404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int16_t *pValue16; 65504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 65604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi switch (param) { 65704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 65804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi case DOWNMIX_PARAM_TYPE: 65904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (*pSize < sizeof(int16_t)) { 66004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGE("Downmix_getParameter invalid parameter size %d for DOWNMIX_PARAM_TYPE", *pSize); 66104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 66204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 66304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pValue16 = (int16_t *)pValue; 66404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *pValue16 = (int16_t) pDownmixer->type; 66504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *pSize = sizeof(int16_t); 66604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGV("Downmix_getParameter DOWNMIX_PARAM_TYPE is %d", *pValue16); 66704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi break; 66804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 66904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi default: 67004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi ALOGE("Downmix_getParameter unknown parameter %d", param); 67104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return -EINVAL; 67204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 67304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 67404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi return 0; 67504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} /* end Downmix_getParameter */ 67604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 67704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 67804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*---------------------------------------------------------------------------- 67904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Downmix_foldFromQuad() 68004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 68104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Purpose: 68204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * downmix a quad signal to stereo 68304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 68404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Inputs: 68504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pSrc quad audio samples to downmix 68604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * numFrames the number of quad frames to downmix 68704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 68804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Outputs: 68904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDst downmixed stereo audio samples 69004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 69104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 69204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi */ 69304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivivoid Downmix_foldFromQuad(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) { 69404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 0 is FL 69504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 1 is FR 69604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 2 is RL 69704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 3 is RR 69804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (accumulate) { 69904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi while (numFrames) { 70004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FL + RL 70104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[0] = clamp16(pDst[0] + pSrc[0] + pSrc[2]); 70204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FR + RR 70304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[1] = clamp16(pDst[1] + pSrc[1] + pSrc[3]); 70404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pSrc += 4; 70504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst += 2; 70604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi numFrames--; 70704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 70804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } else { // same code as above but without adding and clamping pDst[i] to itself 70904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi while (numFrames) { 71004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FL + RL 71104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[0] = clamp16(pSrc[0] + pSrc[2]); 71204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FR + RR 71304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[1] = clamp16(pSrc[1] + pSrc[3]); 71404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pSrc += 4; 71504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst += 2; 71604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi numFrames--; 71704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 71804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 71904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 72004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 72104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 72204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*---------------------------------------------------------------------------- 72304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Downmix_foldFromSurround() 72404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 72504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Purpose: 72604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * downmix a "surround sound" (mono rear) signal to stereo 72704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 72804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Inputs: 72904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pSrc surround signal to downmix 73004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * numFrames the number of surround frames to downmix 73104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 73204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Outputs: 73304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDst downmixed stereo audio samples 73404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 73504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 73604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi */ 73704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivivoid Downmix_foldFromSurround(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) { 73804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int32_t lt, rt, centerPlusRearContrib; // samples in Q19.12 format 73904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 0 is FL 74004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 1 is FR 74104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 2 is FC 74204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 3 is RC 74304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (accumulate) { 74404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi while (numFrames) { 74504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // centerPlusRearContrib = FC(-3dB) + RC(-3dB) 74604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi centerPlusRearContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12) + (pSrc[3] * MINUS_3_DB_IN_Q19_12); 74704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FL + centerPlusRearContrib 74804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi lt = (pSrc[0] << 12) + centerPlusRearContrib; 74904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FR + centerPlusRearContrib 75004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi rt = (pSrc[1] << 12) + centerPlusRearContrib; 75104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[0] = clamp16(pDst[0] + (lt >> 12)); 75204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[1] = clamp16(pDst[1] + (rt >> 12)); 75304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pSrc += 4; 75404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst += 2; 75504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi numFrames--; 75604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 75704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } else { // same code as above but without adding and clamping pDst[i] to itself 75804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi while (numFrames) { 75904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // centerPlusRearContrib = FC(-3dB) + RC(-3dB) 76004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi centerPlusRearContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12) + (pSrc[3] * MINUS_3_DB_IN_Q19_12); 76104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FL + centerPlusRearContrib 76204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi lt = (pSrc[0] << 12) + centerPlusRearContrib; 76304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FR + centerPlusRearContrib 76404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi rt = (pSrc[1] << 12) + centerPlusRearContrib; 76504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[0] = clamp16(lt >> 12); 76604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[1] = clamp16(rt >> 12); 76704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pSrc += 4; 76804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst += 2; 76904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi numFrames--; 77004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 77104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 77204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 77304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 77404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 77504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*---------------------------------------------------------------------------- 77604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Downmix_foldFrom5Point1() 77704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 77804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Purpose: 77904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * downmix a 5.1 signal to stereo 78004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 78104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Inputs: 78204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pSrc 5.1 audio samples to downmix 78304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * numFrames the number of 5.1 frames to downmix 78404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 78504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Outputs: 78604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDst downmixed stereo audio samples 78704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 78804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 78904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi */ 79004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivivoid Downmix_foldFrom5Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) { 79104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int32_t lt, rt, centerPlusLfeContrib; // samples in Q19.12 format 79204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 0 is FL 79304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 1 is FR 79404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 2 is FC 79504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 3 is LFE 79604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 4 is RL 79704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 5 is RR 79804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (accumulate) { 79904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi while (numFrames) { 80004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB) 80104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12) 80204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi + (pSrc[3] * MINUS_3_DB_IN_Q19_12); 80304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FL + centerPlusLfeContrib + RL 80404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi lt = (pSrc[0] << 12) + centerPlusLfeContrib + (pSrc[4] << 12); 80504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FR + centerPlusLfeContrib + RR 80604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi rt = (pSrc[1] << 12) + centerPlusLfeContrib + (pSrc[5] << 12); 80704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[0] = clamp16(pDst[0] + (lt >> 12)); 80804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[1] = clamp16(pDst[1] + (rt >> 12)); 80904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pSrc += 6; 81004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst += 2; 81104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi numFrames--; 81204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 81304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } else { // same code as above but without adding and clamping pDst[i] to itself 81404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi while (numFrames) { 81504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB) 81604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12) 81704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi + (pSrc[3] * MINUS_3_DB_IN_Q19_12); 81804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FL + centerPlusLfeContrib + RL 81904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi lt = (pSrc[0] << 12) + centerPlusLfeContrib + (pSrc[4] << 12); 82004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FR + centerPlusLfeContrib + RR 82104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi rt = (pSrc[1] << 12) + centerPlusLfeContrib + (pSrc[5] << 12); 82204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[0] = clamp16(lt >> 12); 82304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[1] = clamp16(rt >> 12); 82404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pSrc += 6; 82504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst += 2; 82604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi numFrames--; 82704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 82804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 82904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 83004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 83104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 83204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi/*---------------------------------------------------------------------------- 83304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Downmix_foldFrom7Point1() 83404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 83504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Purpose: 83604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * downmix a 7.1 signal to stereo 83704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 83804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Inputs: 83904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pSrc 7.1 audio samples to downmix 84004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * numFrames the number of 7.1 frames to downmix 84104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 84204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * Outputs: 84304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * pDst downmixed stereo audio samples 84404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi * 84504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi *---------------------------------------------------------------------------- 84604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi */ 84704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivivoid Downmix_foldFrom7Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) { 84804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi int32_t lt, rt, centerPlusLfeContrib; // samples in Q19.12 format 84904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 0 is FL 85004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 1 is FR 85104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 2 is FC 85204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 3 is LFE 85304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 4 is RL 85404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 5 is RR 85504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 6 is SL 85604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // sample at index 7 is SR 85704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi if (accumulate) { 85804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi while (numFrames) { 85904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB) 86004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12) 86104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi + (pSrc[3] * MINUS_3_DB_IN_Q19_12); 86204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FL + centerPlusLfeContrib + SL + RL 86304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi lt = (pSrc[0] << 12) + centerPlusLfeContrib + (pSrc[6] << 12) + (pSrc[4] << 12); 86404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FR + centerPlusLfeContrib + SR + RR 86504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi rt = (pSrc[1] << 12) + centerPlusLfeContrib + (pSrc[7] << 12) + (pSrc[5] << 12); 86604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[0] = clamp16(lt >> 12); 86704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[1] = clamp16(rt >> 12); 86804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pSrc += 8; 86904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst += 2; 87004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi numFrames--; 87104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 87204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } else { // same code as above but without adding and clamping pDst[i] to itself 87304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi while (numFrames) { 87404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB) 87504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12) 87604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi + (pSrc[3] * MINUS_3_DB_IN_Q19_12); 87704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FL + centerPlusLfeContrib + SL + RL 87804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi lt = (pSrc[0] << 12) + centerPlusLfeContrib + (pSrc[6] << 12) + (pSrc[4] << 12); 87904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi // FR + centerPlusLfeContrib + SR + RR 88004c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi rt = (pSrc[1] << 12) + centerPlusLfeContrib + (pSrc[7] << 12) + (pSrc[5] << 12); 88104c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[0] = clamp16(pDst[0] + (lt >> 12)); 88204c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst[1] = clamp16(pDst[1] + (rt >> 12)); 88304c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pSrc += 8; 88404c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi pDst += 2; 88504c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi numFrames--; 88604c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 88704c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi } 88804c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi} 88904c1e531b5913c09aa9b2e59e2b8ed9b4d8a4cbaJean-Michel Trivi 890