700 lines
22 KiB
C++
Raw Normal View History

/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "Equalizer"
#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
//
#define LOG_NDEBUG 0
#include <cutils/log.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <new>
#include "AudioEqualizer.h"
#include "AudioBiquadFilter.h"
#include "AudioFormatAdapter.h"
#include <media/EffectEqualizerApi.h>
// effect_interface_t interface implementation for equalizer effect
extern "C" const struct effect_interface_s gEqualizerInterface;
enum equalizer_state_e {
EQUALIZER_STATE_UNINITIALIZED,
EQUALIZER_STATE_INITIALIZED,
EQUALIZER_STATE_ACTIVE,
};
namespace android {
namespace {
// Google Graphic Equalizer UUID: e25aa840-543b-11df-98a5-0002a5d5c51b
const effect_descriptor_t gEqualizerDescriptor = {
{0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
{0xe25aa840, 0x543b, 0x11df, 0x98a5, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
EFFECT_API_VERSION,
(EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
0, // TODO
1,
"Graphic Equalizer",
"Google Inc.",
};
/////////////////// BEGIN EQ PRESETS ///////////////////////////////////////////
const int kNumBands = 5;
const uint32_t gFreqs[kNumBands] = { 50000, 125000, 900000, 3200000, 6300000 };
const uint32_t gBandwidths[kNumBands] = { 0, 3600, 3600, 2400, 0 };
const AudioEqualizer::BandConfig gBandsClassic[kNumBands] = {
{ 300, gFreqs[0], gBandwidths[0] },
{ 400, gFreqs[1], gBandwidths[1] },
{ 0, gFreqs[2], gBandwidths[2] },
{ 200, gFreqs[3], gBandwidths[3] },
{ -300, gFreqs[4], gBandwidths[4] }
};
const AudioEqualizer::BandConfig gBandsJazz[kNumBands] = {
{ -600, gFreqs[0], gBandwidths[0] },
{ 200, gFreqs[1], gBandwidths[1] },
{ 400, gFreqs[2], gBandwidths[2] },
{ -400, gFreqs[3], gBandwidths[3] },
{ -600, gFreqs[4], gBandwidths[4] }
};
const AudioEqualizer::BandConfig gBandsPop[kNumBands] = {
{ 400, gFreqs[0], gBandwidths[0] },
{ -400, gFreqs[1], gBandwidths[1] },
{ 300, gFreqs[2], gBandwidths[2] },
{ -400, gFreqs[3], gBandwidths[3] },
{ 600, gFreqs[4], gBandwidths[4] }
};
const AudioEqualizer::BandConfig gBandsRock[kNumBands] = {
{ 700, gFreqs[0], gBandwidths[0] },
{ 400, gFreqs[1], gBandwidths[1] },
{ -400, gFreqs[2], gBandwidths[2] },
{ 400, gFreqs[3], gBandwidths[3] },
{ 200, gFreqs[4], gBandwidths[4] }
};
const AudioEqualizer::PresetConfig gEqualizerPresets[] = {
{ "Classic", gBandsClassic },
{ "Jazz", gBandsJazz },
{ "Pop", gBandsPop },
{ "Rock", gBandsRock }
};
/////////////////// END EQ PRESETS /////////////////////////////////////////////
static const size_t kBufferSize = 32;
typedef AudioFormatAdapter<AudioEqualizer, kBufferSize> FormatAdapter;
struct EqualizerContext {
const struct effect_interface_s *itfe;
effect_config_t config;
FormatAdapter adapter;
AudioEqualizer * pEqualizer;
uint32_t state;
};
//--- local function prototypes
int Equalizer_init(EqualizerContext *pContext);
int Equalizer_configure(EqualizerContext *pContext, effect_config_t *pConfig);
int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue);
int Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue);
//
//--- Effect Library Interface Implementation
//
Issue 2667801: [Audio Effect Framework] AudioFlinger, AudioMixer AudioTrack modifications. First drop of audio framework modifications for audio effects support. - AudioTrack/AudioRecord: Added support for auxiliary effects in AudioTrack Added support for audio sessions Fixed left right channel inversion in setVolume() - IAudioFlinger: Added interface methods for effect enumeraiton and instantiation Added support for audio sessions. - IAudioTrack: Added method to attach auxiliary effect. - AudioFlinger Created new classes to control effect engines in effect library and manage effect connections to tracks or output mix: EffectModule: wrapper object controlling the effect engine implementation in the effect library. There is one EffectModule per instance of an effect in a given audio session EffectChain: group of effects associated to one audio session. There is one EffectChain per audio session. EffectChain for session 0 is for output mix effects, other chains are attached to audio tracks with same session ID. Each chain contains a variable number of EffectModules EffectHandle: implements the IEffect interface. There is one EffectHandle object for each application controlling (or using) an effect module. THe EffectModule maintians a list of EffectHandles. Added support for effect modules and effect chains creation in PlaybackThread. modified mixer thread loop to allow track volume control by effect modules and call effect processing. -AudioMixer Each track now specifies its output buffer used by mixer for accumulation Modified mixer process functions to process tracks by groups of tracks with same buffer Modified track process functions to support accumulation to auxiliary channel Change-Id: I26d5f7c9e070a89bdd383e1a659f8b7ca150379c
2010-06-01 23:49:17 -07:00
extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects) {
*pNumEffects = 1;
return 0;
} /* end EffectQueryNumberEffects */
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) {
if (pDescriptor == NULL) {
return -EINVAL;
}
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
if (index > 0) {
return -EINVAL;
}
memcpy(pDescriptor, &gEqualizerDescriptor, sizeof(effect_descriptor_t));
return 0;
} /* end EffectQueryNext */
extern "C" int EffectCreate(effect_uuid_t *uuid,
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
int32_t sessionId,
int32_t ioId,
effect_interface_t *pInterface) {
int ret;
int i;
LOGV("EffectLibCreateEffect start");
if (pInterface == NULL || uuid == NULL) {
return -EINVAL;
}
if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) != 0) {
return -EINVAL;
}
EqualizerContext *pContext = new EqualizerContext;
pContext->itfe = &gEqualizerInterface;
pContext->pEqualizer = NULL;
pContext->state = EQUALIZER_STATE_UNINITIALIZED;
ret = Equalizer_init(pContext);
if (ret < 0) {
LOGW("EffectLibCreateEffect() init failed");
delete pContext;
return ret;
}
*pInterface = (effect_interface_t)pContext;
pContext->state = EQUALIZER_STATE_INITIALIZED;
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
LOGV("EffectLibCreateEffect %p, size %d", pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext));
return 0;
} /* end EffectCreate */
extern "C" int EffectRelease(effect_interface_t interface) {
EqualizerContext * pContext = (EqualizerContext *)interface;
LOGV("EffectLibReleaseEffect %p", interface);
if (pContext == NULL) {
return -EINVAL;
}
pContext->state = EQUALIZER_STATE_UNINITIALIZED;
pContext->pEqualizer->free();
delete pContext;
return 0;
} /* end EffectRelease */
//
//--- local functions
//
#define CHECK_ARG(cond) { \
if (!(cond)) { \
LOGV("Invalid argument: "#cond); \
return -EINVAL; \
} \
}
//----------------------------------------------------------------------------
// Equalizer_configure()
//----------------------------------------------------------------------------
// Purpose: Set input and output audio configuration.
//
// Inputs:
// pContext: effect engine context
// pConfig: pointer to effect_config_t structure holding input and output
// configuration parameters
//
// Outputs:
//
//----------------------------------------------------------------------------
int Equalizer_configure(EqualizerContext *pContext, effect_config_t *pConfig)
{
LOGV("Equalizer_configure start");
CHECK_ARG(pContext != NULL);
CHECK_ARG(pConfig != NULL);
CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
CHECK_ARG((pConfig->inputCfg.channels == CHANNEL_MONO) || (pConfig->inputCfg.channels == CHANNEL_STEREO));
CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
|| pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S7_24
|| pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15);
int channelCount;
if (pConfig->inputCfg.channels == CHANNEL_MONO) {
channelCount = 1;
} else {
channelCount = 2;
}
CHECK_ARG(channelCount <= AudioBiquadFilter::MAX_CHANNELS);
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
memcpy(&pContext->config, pConfig, sizeof(effect_config_t));
pContext->pEqualizer->configure(channelCount,
pConfig->inputCfg.samplingRate);
pContext->adapter.configure(*pContext->pEqualizer, channelCount,
pConfig->inputCfg.format,
pConfig->outputCfg.accessMode);
return 0;
} // end Equalizer_configure
//----------------------------------------------------------------------------
// Equalizer_init()
//----------------------------------------------------------------------------
// Purpose: Initialize engine with default configuration and creates
// AudioEqualizer instance.
//
// Inputs:
// pContext: effect engine context
//
// Outputs:
//
//----------------------------------------------------------------------------
int Equalizer_init(EqualizerContext *pContext)
{
int status;
LOGV("Equalizer_init start");
CHECK_ARG(pContext != NULL);
if (pContext->pEqualizer != NULL) {
pContext->pEqualizer->free();
}
pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
pContext->config.inputCfg.channels = CHANNEL_STEREO;
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
pContext->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
pContext->config.inputCfg.samplingRate = 44100;
pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
pContext->config.inputCfg.bufferProvider.cookie = NULL;
pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
pContext->config.outputCfg.channels = CHANNEL_STEREO;
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
pContext->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
pContext->config.outputCfg.samplingRate = 44100;
pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
pContext->config.outputCfg.bufferProvider.cookie = NULL;
pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL;
pContext->pEqualizer = AudioEqualizer::CreateInstance(
NULL,
kNumBands,
AudioBiquadFilter::MAX_CHANNELS,
44100,
gEqualizerPresets,
ARRAY_SIZE(gEqualizerPresets));
for (int i = 0; i < kNumBands; ++i) {
pContext->pEqualizer->setFrequency(i, gFreqs[i]);
pContext->pEqualizer->setBandwidth(i, gBandwidths[i]);
}
pContext->pEqualizer->enable(true);
Equalizer_configure(pContext, &pContext->config);
return 0;
} // end Equalizer_init
//----------------------------------------------------------------------------
// Equalizer_getParameter()
//----------------------------------------------------------------------------
// Purpose:
// Get a Equalizer parameter
//
// Inputs:
// pEqualizer - handle to instance data
// pParam - pointer to parameter
// pValue - pointer to variable to hold retrieved value
// pValueSize - pointer to value size: maximum size as input
//
// Outputs:
// *pValue updated with parameter value
// *pValueSize updated with actual value size
//
//
// Side Effects:
//
//----------------------------------------------------------------------------
int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue)
{
int status = 0;
int32_t param = *pParam++;
int32_t param2;
char *name;
switch (param) {
case EQ_PARAM_NUM_BANDS:
case EQ_PARAM_CUR_PRESET:
case EQ_PARAM_GET_NUM_OF_PRESETS:
case EQ_PARAM_BAND_LEVEL:
case EQ_PARAM_GET_BAND:
if (*pValueSize < sizeof(int16_t)) {
return -EINVAL;
}
*pValueSize = sizeof(int16_t);
break;
case EQ_PARAM_LEVEL_RANGE:
if (*pValueSize < 2 * sizeof(int16_t)) {
return -EINVAL;
}
*pValueSize = 2 * sizeof(int16_t);
break;
case EQ_PARAM_BAND_FREQ_RANGE:
if (*pValueSize < 2 * sizeof(int32_t)) {
return -EINVAL;
}
*pValueSize = 2 * sizeof(int32_t);
break;
case EQ_PARAM_CENTER_FREQ:
if (*pValueSize < sizeof(int32_t)) {
return -EINVAL;
}
*pValueSize = sizeof(int32_t);
break;
case EQ_PARAM_GET_PRESET_NAME:
break;
case EQ_PARAM_PROPERTIES:
if (*pValueSize < (2 + kNumBands) * sizeof(uint16_t)) {
return -EINVAL;
}
*pValueSize = (2 + kNumBands) * sizeof(uint16_t);
break;
default:
return -EINVAL;
}
switch (param) {
case EQ_PARAM_NUM_BANDS:
*(uint16_t *)pValue = (uint16_t)kNumBands;
LOGV("Equalizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue);
break;
case EQ_PARAM_LEVEL_RANGE:
*(int16_t *)pValue = -9600;
*((int16_t *)pValue + 1) = 4800;
LOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d", *(int32_t *)pValue, *((int32_t *)pValue + 1));
break;
case EQ_PARAM_BAND_LEVEL:
param2 = *pParam;
if (param2 >= kNumBands) {
status = -EINVAL;
break;
}
*(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2);
LOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", param2, *(int32_t *)pValue);
break;
case EQ_PARAM_CENTER_FREQ:
param2 = *pParam;
if (param2 >= kNumBands) {
status = -EINVAL;
break;
}
*(int32_t *)pValue = pEqualizer->getFrequency(param2);
LOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d", param2, *(int32_t *)pValue);
break;
case EQ_PARAM_BAND_FREQ_RANGE:
param2 = *pParam;
if (param2 >= kNumBands) {
status = -EINVAL;
break;
}
pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1));
LOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
break;
case EQ_PARAM_GET_BAND:
param2 = *pParam;
*(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2);
LOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d", param2, *(int32_t *)pValue);
break;
case EQ_PARAM_CUR_PRESET:
*(uint16_t *)pValue = (uint16_t)pEqualizer->getPreset();
LOGV("Equalizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue);
break;
case EQ_PARAM_GET_NUM_OF_PRESETS:
*(uint16_t *)pValue = (uint16_t)pEqualizer->getNumPresets();
LOGV("Equalizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue);
break;
case EQ_PARAM_GET_PRESET_NAME:
param2 = *pParam;
if (param2 >= pEqualizer->getNumPresets()) {
status = -EINVAL;
break;
}
name = (char *)pValue;
strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1);
name[*pValueSize - 1] = 0;
*pValueSize = strlen(name) + 1;
LOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", param2, gEqualizerPresets[param2].name, *pValueSize);
break;
case EQ_PARAM_PROPERTIES: {
int16_t *p = (int16_t *)pValue;
LOGV("Equalizer_getParameter() EQ_PARAM_PROPERTIES");
p[0] = (int16_t)pEqualizer->getPreset();
p[1] = (int16_t)kNumBands;
for (int i = 0; i < kNumBands; i++) {
p[2 + i] = (int16_t)pEqualizer->getGain(i);
}
} break;
default:
LOGV("Equalizer_getParameter() invalid param %d", param);
status = -EINVAL;
break;
}
return status;
} // end Equalizer_getParameter
//----------------------------------------------------------------------------
// Equalizer_setParameter()
//----------------------------------------------------------------------------
// Purpose:
// Set a Equalizer parameter
//
// Inputs:
// pEqualizer - handle to instance data
// pParam - pointer to parameter
// pValue - pointer to value
//
// Outputs:
//
//
// Side Effects:
//
//----------------------------------------------------------------------------
int Equalizer_setParameter (AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue)
{
int status = 0;
int32_t preset;
int32_t band;
int32_t level;
int32_t param = *pParam++;
switch (param) {
case EQ_PARAM_CUR_PRESET:
preset = (int32_t)(*(uint16_t *)pValue);
LOGV("setParameter() EQ_PARAM_CUR_PRESET %d", preset);
if (preset < 0 || preset >= pEqualizer->getNumPresets()) {
status = -EINVAL;
break;
}
pEqualizer->setPreset(preset);
pEqualizer->commit(true);
break;
case EQ_PARAM_BAND_LEVEL:
band = *pParam;
level = (int32_t)(*(int16_t *)pValue);
LOGV("setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level);
if (band >= kNumBands) {
status = -EINVAL;
break;
}
pEqualizer->setGain(band, level);
pEqualizer->commit(true);
break;
case EQ_PARAM_PROPERTIES: {
LOGV("setParameter() EQ_PARAM_PROPERTIES");
int16_t *p = (int16_t *)pValue;
if ((int)p[0] >= pEqualizer->getNumPresets()) {
status = -EINVAL;
break;
}
if (p[0] >= 0) {
pEqualizer->setPreset((int)p[0]);
} else {
if ((int)p[1] != kNumBands) {
status = -EINVAL;
break;
}
for (int i = 0; i < kNumBands; i++) {
pEqualizer->setGain(i, (int32_t)p[2 + i]);
}
}
pEqualizer->commit(true);
} break;
default:
LOGV("setParameter() invalid param %d", param);
status = -EINVAL;
break;
}
return status;
} // end Equalizer_setParameter
} // namespace
} // namespace
//
//--- Effect Control Interface Implementation
//
extern "C" int Equalizer_process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
{
android::EqualizerContext * pContext = (android::EqualizerContext *) self;
if (pContext == NULL) {
return -EINVAL;
}
if (inBuffer == NULL || inBuffer->raw == NULL ||
outBuffer == NULL || outBuffer->raw == NULL ||
inBuffer->frameCount != outBuffer->frameCount) {
return -EINVAL;
}
if (pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
return -EINVAL;
}
if (pContext->state == EQUALIZER_STATE_INITIALIZED) {
return -ENODATA;
}
pContext->adapter.process(inBuffer->raw, outBuffer->raw, outBuffer->frameCount);
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
return 0;
} // end Equalizer_process
extern "C" int Equalizer_command(effect_interface_t self, uint32_t cmdCode, uint32_t cmdSize,
void *pCmdData, uint32_t *replySize, void *pReplyData) {
android::EqualizerContext * pContext = (android::EqualizerContext *) self;
int retsize;
if (pContext == NULL || pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
return -EINVAL;
}
android::AudioEqualizer * pEqualizer = pContext->pEqualizer;
LOGV("Equalizer_command command %d cmdSize %d",cmdCode, cmdSize);
switch (cmdCode) {
case EFFECT_CMD_INIT:
if (pReplyData == NULL || *replySize != sizeof(int)) {
return -EINVAL;
}
*(int *) pReplyData = Equalizer_init(pContext);
break;
case EFFECT_CMD_CONFIGURE:
if (pCmdData == NULL || cmdSize != sizeof(effect_config_t)
|| pReplyData == NULL || *replySize != sizeof(int)) {
return -EINVAL;
}
*(int *) pReplyData = Equalizer_configure(pContext,
(effect_config_t *) pCmdData);
break;
case EFFECT_CMD_RESET:
Equalizer_configure(pContext, &pContext->config);
break;
case EFFECT_CMD_GET_PARAM: {
if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
pReplyData == NULL || *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))) {
return -EINVAL;
}
effect_param_t *p = (effect_param_t *)pCmdData;
memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
p = (effect_param_t *)pReplyData;
int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
p->status = android::Equalizer_getParameter(pEqualizer, (int32_t *)p->data, &p->vsize,
p->data + voffset);
*replySize = sizeof(effect_param_t) + voffset + p->vsize;
LOGV("Equalizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x",
*(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize,
*(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset),
*(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset + sizeof(int32_t)));
} break;
case EFFECT_CMD_SET_PARAM: {
LOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData);
if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
pReplyData == NULL || *replySize != sizeof(int32_t)) {
return -EINVAL;
}
effect_param_t *p = (effect_param_t *) pCmdData;
*(int *)pReplyData = android::Equalizer_setParameter(pEqualizer, (int32_t *)p->data,
p->data + p->psize);
} break;
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
case EFFECT_CMD_ENABLE:
if (pReplyData == NULL || *replySize != sizeof(int)) {
return -EINVAL;
}
if (pContext->state != EQUALIZER_STATE_INITIALIZED) {
return -ENOSYS;
}
pContext->state = EQUALIZER_STATE_ACTIVE;
LOGV("EFFECT_CMD_ENABLE() OK");
*(int *)pReplyData = 0;
break;
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
case EFFECT_CMD_DISABLE:
if (pReplyData == NULL || *replySize != sizeof(int)) {
return -EINVAL;
}
if (pContext->state != EQUALIZER_STATE_ACTIVE) {
return -ENOSYS;
}
pContext->state = EQUALIZER_STATE_INITIALIZED;
LOGV("EFFECT_CMD_DISABLE() OK");
Various fixes and improvements in audio effects implementation Effect API: - Use different definitions for audio device, channels, formats... in AudioSystem and EffectApi: Removed media/AudioCommon.h file created for initial version of EffectApi - Indicate audio session and output ID to effect library when calling EffectCreate(). Session ID can be useful to optimize the implementation of effect chains in the same audio session. Output ID can be used for effects implemented in audio hardware. - Renamed EffectQueryNext() function to EffectQueryEffect() and changed operating mode: now an index is passed for the queried effect instead of implicitly querying the next one. - Added CPU load and memory usage indication in effects descriptor - Added flags and commands to indicate changes in audio mode (ring tone, in call...) to effect engine - Added flag to indicate hardware accelerated effect implementation. - Renamed EffectFactoryApi.h to EffectsFactoryApi.h for consistency with EffectsFactory.c/h Effect libraries: - Reflected changes in Effect API - Several fixes in reverb implementation - Added build option TEST_EFFECT_LIBRARIES in makefile to prepare integration of actual effect library. - Replaced pointer by integer identifier for library handle returned by effects factory Audio effect framework: - Added support for audio session -1 in preparation of output stage effects configuration. - Reflected changes in Effect API - Removed volume ramp up/down when effect is inserted/removed: this has to be taken care of by effect engines. - Added some overflow verification on indexes used for deferred parameter updates via shared memory - Added hardcoded CPU and memory limit check when creating a new effect instance Change-Id: I43fee5182ee201384ea3479af6d0acb95092901d
2010-06-23 17:38:20 -07:00
*(int *)pReplyData = 0;
break;
case EFFECT_CMD_SET_DEVICE:
case EFFECT_CMD_SET_VOLUME:
case EFFECT_CMD_SET_AUDIO_MODE:
break;
default:
LOGW("Equalizer_command invalid command %d",cmdCode);
return -EINVAL;
}
return 0;
}
// effect_interface_t interface implementation for equalizer effect
const struct effect_interface_s gEqualizerInterface = {
Equalizer_process,
Equalizer_command
};