summaryrefslogtreecommitdiffstats
path: root/media/libeffects/preprocessing
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2012-04-03 15:36:53 -0700
committerEric Laurent <elaurent@google.com>2012-04-11 12:17:59 -0700
commit3f9c84c0a5af83fceb8669390e2d71b75ec7b550 (patch)
tree12f049ef754cdd81c720dbfbed8adfca0808f073 /media/libeffects/preprocessing
parent2d531e1b5865d61d5ca25d77d53017b1ad180efa (diff)
downloadframeworks_av-3f9c84c0a5af83fceb8669390e2d71b75ec7b550.zip
frameworks_av-3f9c84c0a5af83fceb8669390e2d71b75ec7b550.tar.gz
frameworks_av-3f9c84c0a5af83fceb8669390e2d71b75ec7b550.tar.bz2
audio pre processing: test code for dual mic
Added functional test code to validate effect API for multi mic simplementations. Also fixed warning in AudioFlinger. Change-Id: I07be4d2e4d17791d3626c804ba3e9f87ff26d05a
Diffstat (limited to 'media/libeffects/preprocessing')
-rwxr-xr-xmedia/libeffects/preprocessing/PreProcessing.cpp264
1 files changed, 261 insertions, 3 deletions
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 1d76f62..cfa7f51 100755
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -28,6 +28,8 @@
#include <audio_processing.h>
#include "speex/speex_resampler.h"
+// undefine to perform multi channels API functional tests
+//#define DUAL_MIC_TEST
//------------------------------------------------------------------------------
// local definitions
@@ -87,6 +89,10 @@ struct preproc_effect_s {
preproc_session_t *session; // session the effect is on
const preproc_ops_t *ops; // effect ops table
preproc_fx_handle_t engine; // handle on webRTC engine
+#ifdef DUAL_MIC_TEST
+ bool aux_channels_on; // support auxiliary channels
+ size_t cur_channel_config; // current auciliary channel configuration
+#endif
};
// Session context
@@ -127,6 +133,41 @@ struct preproc_session_s {
SpeexResamplerState *revResampler; // handle on reverse channel input speex resampler
};
+#ifdef DUAL_MIC_TEST
+enum {
+ PREPROC_CMD_DUAL_MIC_ENABLE = EFFECT_CMD_FIRST_PROPRIETARY, // enable dual mic mode
+ PREPROC_CMD_DUAL_MIC_PCM_DUMP_START, // start pcm capture
+ PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP // stop pcm capture
+};
+
+enum {
+ CHANNEL_CFG_MONO,
+ CHANNEL_CFG_STEREO,
+ CHANNEL_CFG_MONO_AUX,
+ CHANNEL_CFG_STEREO_AUX,
+ CHANNEL_CFG_CNT,
+ CHANNEL_CFG_FIRST_AUX = CHANNEL_CFG_MONO_AUX,
+};
+
+const channel_config_t sDualMicConfigs[CHANNEL_CFG_CNT] = {
+ {AUDIO_CHANNEL_IN_MONO , 0},
+ {AUDIO_CHANNEL_IN_STEREO , 0},
+ {AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
+ {AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
+};
+
+bool sHasAuxChannels[PREPROC_NUM_EFFECTS] = {
+ false, // PREPROC_AGC
+ true, // PREPROC_AEC
+ true, // PREPROC_NS
+};
+
+bool gDualMicEnabled;
+FILE *gPcmDumpFh;
+static pthread_mutex_t gPcmDumpLock = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+
//------------------------------------------------------------------------------
// Effect descriptors
//------------------------------------------------------------------------------
@@ -644,10 +685,12 @@ int Effect_SetState(preproc_effect_t *effect, uint32_t state)
switch(effect->state) {
case PREPROC_EFFECT_STATE_INIT:
case PREPROC_EFFECT_STATE_CREATED:
- case PREPROC_EFFECT_STATE_ACTIVE:
ALOGE("Effect_SetState invalid transition");
status = -ENOSYS;
break;
+ case PREPROC_EFFECT_STATE_ACTIVE:
+ // enabling an already enabled effect is just ignored
+ break;
case PREPROC_EFFECT_STATE_CONFIG:
effect->ops->enable(effect);
Session_SetProcEnabled(effect->session, effect->procId, true);
@@ -895,6 +938,13 @@ int Session_SetConfig(preproc_session_t *session, effect_config_t *config)
session->revFrame->_audioChannel = inCnl;
session->revFrame->_frequencyInHz = session->apmSamplingRate;
+ // force process buffer reallocation
+ session->inBufSize = 0;
+ session->outBufSize = 0;
+ session->framesIn = 0;
+ session->framesOut = 0;
+
+
if (session->inResampler != NULL) {
speex_resampler_destroy(session->inResampler);
session->inResampler = NULL;
@@ -989,6 +1039,10 @@ int Session_SetReverseConfig(preproc_session_t *session, effect_config_t *config
session->revChannelCount = inCnl;
session->revFrame->_audioChannel = inCnl;
session->revFrame->_frequencyInHz = session->apmSamplingRate;
+ // force process buffer reallocation
+ session->revBufSize = 0;
+ session->framesRev = 0;
+
return 0;
}
@@ -1161,6 +1215,14 @@ int PreProcessingFx_Process(effect_handle_t self,
memcpy(session->inBuf + session->framesIn * session->inChannelCount,
inBuffer->s16,
fr * session->inChannelCount * sizeof(int16_t));
+#ifdef DUAL_MIC_TEST
+ pthread_mutex_lock(&gPcmDumpLock);
+ if (gPcmDumpFh != NULL) {
+ fwrite(inBuffer->raw,
+ fr * session->inChannelCount * sizeof(int16_t), 1, gPcmDumpFh);
+ }
+ pthread_mutex_unlock(&gPcmDumpLock);
+#endif
session->framesIn += fr;
inBuffer->frameCount = fr;
@@ -1195,6 +1257,16 @@ int PreProcessingFx_Process(effect_handle_t self,
memcpy(session->procFrame->_payloadData + session->framesIn * session->inChannelCount,
inBuffer->s16,
fr * session->inChannelCount * sizeof(int16_t));
+
+#ifdef DUAL_MIC_TEST
+ pthread_mutex_lock(&gPcmDumpLock);
+ if (gPcmDumpFh != NULL) {
+ fwrite(inBuffer->raw,
+ fr * session->inChannelCount * sizeof(int16_t), 1, gPcmDumpFh);
+ }
+ pthread_mutex_unlock(&gPcmDumpLock);
+#endif
+
session->framesIn += fr;
inBuffer->frameCount = fr;
if (session->framesIn < session->frameCount) {
@@ -1284,7 +1356,7 @@ int PreProcessingFx_Command(effect_handle_t self,
*(int *)pReplyData = 0;
break;
- case EFFECT_CMD_SET_CONFIG:
+ case EFFECT_CMD_SET_CONFIG: {
if (pCmdData == NULL||
cmdSize != sizeof(effect_config_t)||
pReplyData == NULL||
@@ -1293,14 +1365,27 @@ int PreProcessingFx_Command(effect_handle_t self,
"EFFECT_CMD_SET_CONFIG: ERROR");
return -EINVAL;
}
+#ifdef DUAL_MIC_TEST
+ // make sure that the config command is accepted by making as if all effects were
+ // disabled: this is OK for functional tests
+ uint32_t enabledMsk = effect->session->enabledMsk;
+ if (gDualMicEnabled) {
+ effect->session->enabledMsk = 0;
+ }
+#endif
*(int *)pReplyData = Session_SetConfig(effect->session, (effect_config_t *)pCmdData);
+#ifdef DUAL_MIC_TEST
+ if (gDualMicEnabled) {
+ effect->session->enabledMsk = enabledMsk;
+ }
+#endif
if (*(int *)pReplyData != 0) {
break;
}
if (effect->state != PREPROC_EFFECT_STATE_ACTIVE) {
*(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
}
- break;
+ } break;
case EFFECT_CMD_GET_CONFIG:
if (pReplyData == NULL ||
@@ -1426,6 +1511,179 @@ int PreProcessingFx_Command(effect_handle_t self,
case EFFECT_CMD_SET_AUDIO_MODE:
break;
+#ifdef DUAL_MIC_TEST
+ ///// test commands start
+ case PREPROC_CMD_DUAL_MIC_ENABLE: {
+ if (pCmdData == NULL|| cmdSize != sizeof(uint32_t) ||
+ pReplyData == NULL || replySize == NULL) {
+ ALOGE("PreProcessingFx_Command cmdCode Case: "
+ "PREPROC_CMD_DUAL_MIC_ENABLE: ERROR");
+ *replySize = 0;
+ return -EINVAL;
+ }
+ gDualMicEnabled = *(bool *)pCmdData;
+ if (gDualMicEnabled) {
+ effect->aux_channels_on = sHasAuxChannels[effect->procId];
+ } else {
+ effect->aux_channels_on = false;
+ }
+ effect->cur_channel_config = (effect->session->inChannelCount == 1) ?
+ CHANNEL_CFG_MONO : CHANNEL_CFG_STEREO;
+
+ ALOGV("PREPROC_CMD_DUAL_MIC_ENABLE: %s", gDualMicEnabled ? "enabled" : "disabled");
+ *replySize = sizeof(int);
+ *(int *)pReplyData = 0;
+ } break;
+ case PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: {
+ if (pCmdData == NULL|| pReplyData == NULL || replySize == NULL) {
+ ALOGE("PreProcessingFx_Command cmdCode Case: "
+ "PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: ERROR");
+ *replySize = 0;
+ return -EINVAL;
+ }
+ pthread_mutex_lock(&gPcmDumpLock);
+ if (gPcmDumpFh != NULL) {
+ fclose(gPcmDumpFh);
+ gPcmDumpFh = NULL;
+ }
+ char *path = strndup((char *)pCmdData, cmdSize);
+ gPcmDumpFh = fopen((char *)path, "wb");
+ pthread_mutex_unlock(&gPcmDumpLock);
+ ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: path %s gPcmDumpFh %p",
+ path, gPcmDumpFh);
+ ALOGE_IF(gPcmDumpFh <= 0, "gPcmDumpFh open error %d %s", errno, strerror(errno));
+ free(path);
+ *replySize = sizeof(int);
+ *(int *)pReplyData = 0;
+ } break;
+ case PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: {
+ if (pReplyData == NULL || replySize == NULL) {
+ ALOGE("PreProcessingFx_Command cmdCode Case: "
+ "PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: ERROR");
+ *replySize = 0;
+ return -EINVAL;
+ }
+ pthread_mutex_lock(&gPcmDumpLock);
+ if (gPcmDumpFh != NULL) {
+ fclose(gPcmDumpFh);
+ gPcmDumpFh = NULL;
+ }
+ pthread_mutex_unlock(&gPcmDumpLock);
+ ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP");
+ *replySize = sizeof(int);
+ *(int *)pReplyData = 0;
+ } break;
+ ///// test commands end
+
+ case EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: {
+ if(!gDualMicEnabled) {
+ return -EINVAL;
+ }
+ if (pCmdData == NULL|| cmdSize != 2 * sizeof(uint32_t) ||
+ pReplyData == NULL || replySize == NULL) {
+ ALOGE("PreProcessingFx_Command cmdCode Case: "
+ "EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: ERROR");
+ *replySize = 0;
+ return -EINVAL;
+ }
+ if (*(uint32_t *)pCmdData != EFFECT_FEATURE_AUX_CHANNELS ||
+ !effect->aux_channels_on) {
+ ALOGV("PreProcessingFx_Command feature EFFECT_FEATURE_AUX_CHANNELS not supported by"
+ " fx %d", effect->procId);
+ *(uint32_t *)pReplyData = -ENOSYS;
+ *replySize = sizeof(uint32_t);
+ break;
+ }
+ size_t num_configs = *((uint32_t *)pCmdData + 1);
+ if (*replySize < (2 * sizeof(uint32_t) +
+ num_configs * sizeof(channel_config_t))) {
+ *replySize = 0;
+ return -EINVAL;
+ }
+
+ *((uint32_t *)pReplyData + 1) = CHANNEL_CFG_CNT;
+ if (num_configs < CHANNEL_CFG_CNT ||
+ *replySize < (2 * sizeof(uint32_t) +
+ CHANNEL_CFG_CNT * sizeof(channel_config_t))) {
+ *(uint32_t *)pReplyData = -ENOMEM;
+ } else {
+ num_configs = CHANNEL_CFG_CNT;
+ *(uint32_t *)pReplyData = 0;
+ }
+ ALOGV("PreProcessingFx_Command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS num config %d",
+ num_configs);
+
+ *replySize = 2 * sizeof(uint32_t) + num_configs * sizeof(channel_config_t);
+ *((uint32_t *)pReplyData + 1) = num_configs;
+ memcpy((uint32_t *)pReplyData + 2, &sDualMicConfigs, num_configs * sizeof(channel_config_t));
+ } break;
+ case EFFECT_CMD_GET_FEATURE_CONFIG:
+ if(!gDualMicEnabled) {
+ return -EINVAL;
+ }
+ if (pCmdData == NULL|| cmdSize != sizeof(uint32_t) ||
+ pReplyData == NULL || replySize == NULL ||
+ *replySize < sizeof(uint32_t) + sizeof(channel_config_t)) {
+ ALOGE("PreProcessingFx_Command cmdCode Case: "
+ "EFFECT_CMD_GET_FEATURE_CONFIG: ERROR");
+ return -EINVAL;
+ }
+ if (*(uint32_t *)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
+ *(uint32_t *)pReplyData = -ENOSYS;
+ *replySize = sizeof(uint32_t);
+ break;
+ }
+ ALOGV("PreProcessingFx_Command EFFECT_CMD_GET_FEATURE_CONFIG");
+ *(uint32_t *)pReplyData = 0;
+ *replySize = sizeof(uint32_t) + sizeof(channel_config_t);
+ memcpy((uint32_t *)pReplyData + 1,
+ &sDualMicConfigs[effect->cur_channel_config],
+ sizeof(channel_config_t));
+ break;
+ case EFFECT_CMD_SET_FEATURE_CONFIG: {
+ ALOGV("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG: "
+ "gDualMicEnabled %d effect->aux_channels_on %d",
+ gDualMicEnabled, effect->aux_channels_on);
+ if(!gDualMicEnabled) {
+ return -EINVAL;
+ }
+ if (pCmdData == NULL|| cmdSize != (sizeof(uint32_t) + sizeof(channel_config_t)) ||
+ pReplyData == NULL || replySize == NULL ||
+ *replySize < sizeof(uint32_t)) {
+ ALOGE("PreProcessingFx_Command cmdCode Case: "
+ "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n"
+ "pCmdData %p cmdSize %d pReplyData %p replySize %p *replySize %d",
+ pCmdData, cmdSize, pReplyData, replySize, replySize ? *replySize : -1);
+ return -EINVAL;
+ }
+ *replySize = sizeof(uint32_t);
+ if (*(uint32_t *)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
+ *(uint32_t *)pReplyData = -ENOSYS;
+ ALOGV("PreProcessingFx_Command cmdCode Case: "
+ "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n"
+ "CmdData %d effect->aux_channels_on %d",
+ *(uint32_t *)pCmdData, effect->aux_channels_on);
+ break;
+ }
+ size_t i;
+ for (i = 0; i < CHANNEL_CFG_CNT;i++) {
+ if (memcmp((uint32_t *)pCmdData + 1,
+ &sDualMicConfigs[i], sizeof(channel_config_t)) == 0) {
+ break;
+ }
+ }
+ if (i == CHANNEL_CFG_CNT) {
+ *(uint32_t *)pReplyData = -EINVAL;
+ ALOGW("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG invalid config"
+ "[%08x].[%08x]", *((uint32_t *)pCmdData + 1), *((uint32_t *)pCmdData + 2));
+ } else {
+ effect->cur_channel_config = i;
+ *(uint32_t *)pReplyData = 0;
+ ALOGV("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG New config"
+ "[%08x].[%08x]", sDualMicConfigs[i].main_channels, sDualMicConfigs[i].aux_channels);
+ }
+ } break;
+#endif
default:
return -EINVAL;
}