summaryrefslogtreecommitdiffstats
path: root/media/libeffects/lvm
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2010-09-10 17:44:44 -0700
committerEric Laurent <elaurent@google.com>2010-09-13 09:08:28 -0700
commite0aed6ddcb4e3c301b80aa26706b6052dab42c41 (patch)
tree4a85e38eefe3ad4ac70ca1b182660aefacc07658 /media/libeffects/lvm
parenta1754133ee6640346b5fd6daa4666f5d2285379a (diff)
downloadframeworks_av-e0aed6ddcb4e3c301b80aa26706b6052dab42c41.zip
frameworks_av-e0aed6ddcb4e3c301b80aa26706b6052dab42c41.tar.gz
frameworks_av-e0aed6ddcb4e3c301b80aa26706b6052dab42c41.tar.bz2
Fix volume problems with insert revert
- Use a constant input level to the reverb engine and implement volume control in the insert reverb. This avoids the volume spikes when an effect that was inserted after the reverb is disabled or removed. - Fix clicks (one silent buffer) at the end of the reverb disable period. - Modified volume management in audioflinger so that the volume ramp is also done by the insert effect if present when the track is paused (avoids clicks). - Increased room level for all presets. Also fixed problems with output stage session (-1): - effect bundle wrapper was not designed to support session -1 - the permission check in audioflinger for using session -1 failed due to a wrong usage of getCallingPid() Change-Id: Id1ff51327263364bf71d3f2668fa5cde4311d84f
Diffstat (limited to 'media/libeffects/lvm')
-rw-r--r--media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp12
-rw-r--r--media/libeffects/lvm/wrapper/Bundle/EffectBundle.h2
-rwxr-xr-xmedia/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp135
3 files changed, 121 insertions, 28 deletions
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index e86ed99..90756d0 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -65,6 +65,7 @@ namespace {
int LvmInitFlag = LVM_FALSE;
int LvmSessionsActive = 0;
SessionContext GlobalSessionMemory[LVM_MAX_SESSIONS];
+
int SessionIndex[LVM_MAX_SESSIONS];
// NXP SW BassBoost UUID
@@ -199,11 +200,6 @@ extern "C" int EffectCreate(effect_uuid_t *uuid,
return -EINVAL;
}
- if(sessionId < 0){
- LOGV("\tLVM_ERROR : EffectCreate sessionId is less than 0");
- return -EINVAL;
- }
-
if(LvmInitFlag == LVM_FALSE){
LvmInitFlag = LVM_TRUE;
LOGV("\tEffectCreate - Initializing all global memory");
@@ -214,7 +210,7 @@ extern "C" int EffectCreate(effect_uuid_t *uuid,
// Find next available sessionNo
for(i=0; i<LVM_MAX_SESSIONS; i++){
- if((SessionIndex[i] == -1)||(SessionIndex[i] == sessionId)){
+ if((SessionIndex[i] == LVM_UNUSED_SESSION)||(SessionIndex[i] == sessionId)){
sessionNo = i;
SessionIndex[i] = sessionId;
LOGV("\tEffectCreate: Allocating SessionNo %d for SessionId %d\n", sessionNo,sessionId);
@@ -398,7 +394,7 @@ extern "C" int EffectRelease(effect_interface_t interface){
// Clear the SessionIndex
for(int i=0; i<LVM_MAX_SESSIONS; i++){
if(SessionIndex[i] == pContext->pBundledContext->SessionId){
- SessionIndex[i] = -1;
+ SessionIndex[i] = LVM_UNUSED_SESSION;
LOGV("\tEffectRelease: Clearing SessionIndex SessionNo %d for SessionId %d\n",
i, pContext->pBundledContext->SessionId);
break;
@@ -432,7 +428,7 @@ void LvmGlobalBundle_init(){
GlobalSessionMemory[i].bVirtualizerInstantiated = LVM_FALSE;
GlobalSessionMemory[i].pBundledContext = LVM_NULL;
- SessionIndex[i] = -1;
+ SessionIndex[i] = LVM_UNUSED_SESSION;
}
return;
}
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
index 35e1114..91963af 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
@@ -21,6 +21,7 @@
#include <media/EffectBassBoostApi.h>
#include <media/EffectVirtualizerApi.h>
#include <LVM.h>
+#include <limits.h>
#if __cplusplus
extern "C" {
@@ -30,6 +31,7 @@ extern "C" {
#define MAX_NUM_BANDS 5
#define MAX_CALL_SIZE 256
#define LVM_MAX_SESSIONS 32
+#define LVM_UNUSED_SESSION INT_MAX
#define BASS_BOOST_CUP_LOAD_ARM9E 150 // Expressed in 0.1 MIPS
#define VIRTUALIZER_CUP_LOAD_ARM9E 120 // Expressed in 0.1 MIPS
#define EQUALIZER_CUP_LOAD_ARM9E 220 // Expressed in 0.1 MIPS
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 60f4288..26c5aca 100755
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -59,17 +59,17 @@ const static t_reverb_settings sReverbPresets[] = {
// REVERB_PRESET_NONE: values are unused
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
// REVERB_PRESET_SMALLROOM
- {-1000, -600, 1100, 830, -400, 5, 500, 10, 1000, 1000},
+ {-400, -600, 1100, 830, -400, 5, 500, 10, 1000, 1000},
// REVERB_PRESET_MEDIUMROOM
- {-1000, -600, 1300, 830, -1000, 20, -200, 20, 1000, 1000},
+ {-400, -600, 1300, 830, -1000, 20, -200, 20, 1000, 1000},
// REVERB_PRESET_LARGEROOM
- {-1000, -600, 1500, 830, -1600, 5, -1000, 40, 1000, 1000},
+ {-400, -600, 1500, 830, -1600, 5, -1000, 40, 1000, 1000},
// REVERB_PRESET_MEDIUMHALL
- {-1000, -600, 1800, 700, -1300, 15, -800, 30, 1000, 1000},
+ {-400, -600, 1800, 700, -1300, 15, -800, 30, 1000, 1000},
// REVERB_PRESET_LARGEHALL
- {-1000, -600, 1800, 700, -2000, 30, -1400, 60, 1000, 1000},
+ {-400, -600, 1800, 700, -2000, 30, -1400, 60, 1000, 1000},
// REVERB_PRESET_PLATE
- {-1000, -200, 1300, 900, 0, 2, 0, 10, 1000, 750},
+ {-400, -200, 1300, 900, 0, 2, 0, 10, 1000, 750},
};
@@ -90,7 +90,7 @@ static const effect_descriptor_t gInsertEnvReverbDescriptor = {
{0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}},
{0xc7a511a0, 0xa3bb, 0x11df, 0x860e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
EFFECT_API_VERSION,
- EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST,
+ EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL,
LVREV_CUP_LOAD_ARM9E,
LVREV_MEM_USAGE,
"Insert Environmental Reverb",
@@ -114,7 +114,7 @@ static const effect_descriptor_t gInsertPresetReverbDescriptor = {
{0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
{0x172cdf00, 0xa3bc, 0x11df, 0xa72f, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
EFFECT_API_VERSION,
- EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST,
+ EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL,
LVREV_CUP_LOAD_ARM9E,
LVREV_MEM_USAGE,
"Insert Preset Reverb",
@@ -153,10 +153,25 @@ struct ReverbContext{
uint16_t curPreset;
uint16_t nextPreset;
int SamplesToExitCount;
+ LVM_INT16 leftVolume;
+ LVM_INT16 rightVolume;
+ LVM_INT16 prevLeftVolume;
+ LVM_INT16 prevRightVolume;
+ int volumeMode;
+};
+
+enum {
+ REVERB_VOLUME_OFF,
+ REVERB_VOLUME_FLAT,
+ REVERB_VOLUME_RAMP,
};
#define REVERB_DEFAULT_PRESET REVERB_PRESET_MEDIUMROOM
+
+#define REVERB_SEND_LEVEL (0x0C00) // 0.75 in 4.12 format
+#define REVERB_UNIT_VOLUME (0x1000) // 1.0 in 4.12 format
+
//--- local function prototypes
int Reverb_init (ReverbContext *pContext);
void Reverb_free (ReverbContext *pContext);
@@ -426,9 +441,20 @@ int process( LVM_INT16 *pIn,
if (pContext->preset && pContext->nextPreset != pContext->curPreset) {
Reverb_LoadPreset(pContext);
}
+
+
+
// Convert to Input 32 bits
- for(int i=0; i<frameCount*samplesPerFrame; i++){
- pContext->InFrames32[i] = (LVM_INT32)pIn[i]<<8;
+ if (pContext->auxiliary) {
+ for(int i=0; i<frameCount*samplesPerFrame; i++){
+ pContext->InFrames32[i] = (LVM_INT32)pIn[i]<<8;
+ }
+ } else {
+ // insert reverb input is always stereo
+ for (int i = 0; i < frameCount; i++) {
+ pContext->InFrames32[2*i] = (pIn[2*i] * REVERB_SEND_LEVEL) >> 4; // <<8 + >>12
+ pContext->InFrames32[2*i+1] = (pIn[2*i+1] * REVERB_SEND_LEVEL) >> 4; // <<8 + >>12
+ }
}
if (pContext->preset && pContext->curPreset == REVERB_PRESET_NONE) {
@@ -458,6 +484,42 @@ int process( LVM_INT16 *pIn,
for (int i=0; i < frameCount*2; i++) { //always stereo here
OutFrames16[i] = clamp16((pContext->OutFrames32[i]>>8) + (LVM_INT32)pIn[i]);
}
+
+ // apply volume with ramp if needed
+ if ((pContext->leftVolume != pContext->prevLeftVolume ||
+ pContext->rightVolume != pContext->prevRightVolume) &&
+ pContext->volumeMode == REVERB_VOLUME_RAMP) {
+ LVM_INT32 vl = (LVM_INT32)pContext->prevLeftVolume << 16;
+ LVM_INT32 incl = (((LVM_INT32)pContext->leftVolume << 16) - vl) / frameCount;
+ LVM_INT32 vr = (LVM_INT32)pContext->prevRightVolume << 16;
+ LVM_INT32 incr = (((LVM_INT32)pContext->rightVolume << 16) - vr) / frameCount;
+
+ for (int i = 0; i < frameCount; i++) {
+ OutFrames16[2*i] =
+ clamp16((LVM_INT32)((vl >> 16) * OutFrames16[2*i]) >> 12);
+ OutFrames16[2*i+1] =
+ clamp16((LVM_INT32)((vr >> 16) * OutFrames16[2*i+1]) >> 12);
+
+ vl += incl;
+ vr += incr;
+ }
+
+ pContext->prevLeftVolume = pContext->leftVolume;
+ pContext->prevRightVolume = pContext->rightVolume;
+ } else if (pContext->volumeMode != REVERB_VOLUME_OFF) {
+ if (pContext->leftVolume != REVERB_UNIT_VOLUME ||
+ pContext->rightVolume != REVERB_UNIT_VOLUME) {
+ for (int i = 0; i < frameCount; i++) {
+ OutFrames16[2*i] =
+ clamp16((LVM_INT32)(pContext->leftVolume * OutFrames16[2*i]) >> 12);
+ OutFrames16[2*i+1] =
+ clamp16((LVM_INT32)(pContext->rightVolume * OutFrames16[2*i+1]) >> 12);
+ }
+ }
+ pContext->prevLeftVolume = pContext->leftVolume;
+ pContext->prevRightVolume = pContext->rightVolume;
+ pContext->volumeMode = REVERB_VOLUME_RAMP;
+ }
}
#ifdef LVM_PCM
@@ -658,6 +720,12 @@ int Reverb_init(ReverbContext *pContext){
pContext->config.outputCfg.bufferProvider.cookie = NULL;
pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL;
+ pContext->leftVolume = REVERB_UNIT_VOLUME;
+ pContext->rightVolume = REVERB_UNIT_VOLUME;
+ pContext->prevLeftVolume = REVERB_UNIT_VOLUME;
+ pContext->prevRightVolume = REVERB_UNIT_VOLUME;
+ pContext->volumeMode = REVERB_VOLUME_FLAT;
+
LVREV_ReturnStatus_en LvmStatus=LVREV_SUCCESS; /* Function call status */
LVREV_ControlParams_st params; /* Control Parameters */
LVREV_InstanceParams_st InstParams; /* Instance parameters */
@@ -1781,15 +1849,6 @@ extern "C" int Reverb_process(effect_interface_t self,
LOGV("\tLVM_ERROR : Reverb_process() ERROR NULL INPUT POINTER OR FRAME COUNT IS WRONG");
return -EINVAL;
}
- if (pContext->bEnabled == LVM_FALSE){
- if( pContext->SamplesToExitCount > 0){
- pContext->SamplesToExitCount -= outBuffer->frameCount;
- LOGV("\tReverb_process() Effect is being stopped %d", pContext->SamplesToExitCount);
- }else{
- LOGV("\tReverb_process() Effect is being stopped");
- return -ENODATA;
- }
- }
//LOGV("\tReverb_process() Calling process with %d frames", outBuffer->frameCount);
/* Process all the available frames, block processing is handled internalLY by the LVM bundle */
status = process( (LVM_INT16 *)inBuffer->raw,
@@ -1797,6 +1856,14 @@ extern "C" int Reverb_process(effect_interface_t self,
outBuffer->frameCount,
pContext);
+ if (pContext->bEnabled == LVM_FALSE) {
+ if (pContext->SamplesToExitCount > 0) {
+ pContext->SamplesToExitCount -= outBuffer->frameCount;
+ } else {
+ status = -ENODATA;
+ }
+ }
+
return status;
} /* end Reverb_process */
@@ -1943,6 +2010,8 @@ extern "C" int Reverb_command(effect_interface_t self,
LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "EFFECT_CMD_ENABLE")
pContext->SamplesToExitCount =
(ActiveParams.T60 * pContext->config.inputCfg.samplingRate)/1000;
+ // force no volume ramp for first buffer processed after enabling the effect
+ pContext->volumeMode = android::REVERB_VOLUME_FLAT;
//LOGV("\tEFFECT_CMD_ENABLE SamplesToExitCount = %d", pContext->SamplesToExitCount);
break;
case EFFECT_CMD_DISABLE:
@@ -1963,8 +2032,34 @@ extern "C" int Reverb_command(effect_interface_t self,
pContext->bEnabled = LVM_FALSE;
break;
- case EFFECT_CMD_SET_DEVICE:
case EFFECT_CMD_SET_VOLUME:
+ if (pCmdData == NULL ||
+ cmdSize != 2 * sizeof(uint32_t)) {
+ LOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
+ "EFFECT_CMD_SET_VOLUME: ERROR");
+ return -EINVAL;
+ }
+
+
+ if (pReplyData != NULL) { // we have volume control
+ pContext->leftVolume = (LVM_INT16)((*(uint32_t *)pCmdData + (1 << 11)) >> 12);
+ pContext->rightVolume = (LVM_INT16)((*((uint32_t *)pCmdData + 1) + (1 << 11)) >> 12);
+ *(uint32_t *)pReplyData = (1 << 24);
+ *((uint32_t *)pReplyData + 1) = (1 << 24);
+ if (pContext->volumeMode == android::REVERB_VOLUME_OFF) {
+ // force no volume ramp for first buffer processed after getting volume control
+ pContext->volumeMode = android::REVERB_VOLUME_FLAT;
+ }
+ } else { // we don't have volume control
+ pContext->leftVolume = REVERB_UNIT_VOLUME;
+ pContext->rightVolume = REVERB_UNIT_VOLUME;
+ pContext->volumeMode = android::REVERB_VOLUME_OFF;
+ }
+ LOGV("EFFECT_CMD_SET_VOLUME left %d, right %d mode %d",
+ pContext->leftVolume, pContext->rightVolume, pContext->volumeMode);
+ break;
+
+ case EFFECT_CMD_SET_DEVICE:
case EFFECT_CMD_SET_AUDIO_MODE:
//LOGV("\tReverb_command cmdCode Case: "
// "EFFECT_CMD_SET_DEVICE/EFFECT_CMD_SET_VOLUME/EFFECT_CMD_SET_AUDIO_MODE start");