Loading media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh +43 −25 Original line number Diff line number Diff line Loading @@ -41,22 +41,30 @@ fs_arr=( 192000 ) flags_arr=( "--M --fch 1" "--fch 2" ) # run reverb at different configs, saving only the stereo channel # pair. error_count=0 testcase_count=0 for cmd in "${cmds[@]}" do $cmd for flags in "${flags_arr[@]}" do for preset_val in {0..6} do for fs in ${fs_arr[*]} do for chMask in {1..22} for chMask in {0..22} do adb shell LD_LIBRARY_PATH=/system/vendor/lib/soundfx $testdir/reverb_test \ --input $testdir/sinesweepraw.raw \ --output $testdir/sinesweep_$((chMask))_$((fs)).raw \ --chMask $chMask --fs $fs --preset $preset_val --chMask $chMask $flags --fs $fs --preset $preset_val shell_ret=$? if [ $shell_ret -ne 0 ]; then Loading @@ -64,24 +72,34 @@ do ((++error_count)) fi if [[ "$chMask" -gt 0 ]] && [[ $flags != *"--fch 2"* ]] then # single channel files should be identical to higher channel # computation (first channel). adb shell cmp $testdir/sinesweep_0_$((fs)).raw \ $testdir/sinesweep_$((chMask))_$((fs)).raw elif [[ "$chMask" -gt 1 ]] then # two channel files should be identical to higher channel # computation (first 2 channels). if [[ "$chMask" -gt 1 ]] then adb shell cmp $testdir/sinesweep_1_$((fs)).raw \ $testdir/sinesweep_$((chMask))_$((fs)).raw fi # cmp returns EXIT_FAILURE on mismatch. shell_ret=$? if [ $shell_ret -ne 0 ]; then echo "error: $shell_ret" ((++error_count)) fi ((++testcase_count)) done done done done done adb shell rm -r $testdir echo "$testcase_count tests performed" echo "$error_count errors" exit $error_count media/libeffects/lvm/tests/reverb_test.cpp +10 −7 Original line number Diff line number Diff line Loading @@ -297,6 +297,9 @@ int main(int argc, const char *argv[]) { config.inputCfg.samplingRate = config.outputCfg.samplingRate = revConfigParams.sampleRate; config.inputCfg.channels = config.outputCfg.channels = revConfigParams.chMask; config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT; if (AUDIO_CHANNEL_OUT_MONO == revConfigParams.chMask) { config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; } if (int status = reverbCreateEffect(&effectHandle, &config, sessionId, ioId, revConfigParams.auxiliary); status != 0) { Loading Loading @@ -332,15 +335,15 @@ int main(int argc, const char *argv[]) { * Mono input will be converted to 2 channels internally in the process call * by copying the same data into the second channel. * Hence when channelCount is 1, output buffer should be allocated for * 2 channels. The memAllocChCount takes care of allocation of sufficient * 2 channels. The outChannelCount takes care of allocation of sufficient * memory for the output buffer. */ const int memAllocChCount = (channelCount == 1 ? 2 : channelCount); const int outChannelCount = (channelCount == 1 ? 2 : channelCount); std::vector<short> in(frameLength * maxChannelCount); std::vector<short> out(frameLength * maxChannelCount); std::vector<float> floatIn(frameLength * channelCount); std::vector<float> floatOut(frameLength * memAllocChCount); std::vector<float> floatOut(frameLength * outChannelCount); int frameCounter = 0; Loading Loading @@ -374,11 +377,11 @@ int main(int argc, const char *argv[]) { #else memcpy(floatOut.data(), floatIn.data(), frameLength * frameSize); #endif memcpy_to_i16_from_float(out.data(), floatOut.data(), frameLength * channelCount); memcpy_to_i16_from_float(out.data(), floatOut.data(), frameLength * outChannelCount); if (ioChannelCount != channelCount) { adjust_channels(out.data(), channelCount, out.data(), ioChannelCount, sizeof(short), frameLength * channelCount * sizeof(short)); if (ioChannelCount != outChannelCount) { adjust_channels(out.data(), outChannelCount, out.data(), ioChannelCount, sizeof(short), frameLength * outChannelCount * sizeof(short)); } (void)fwrite(out.data(), ioFrameSize, frameLength, outputFp.get()); frameCounter += frameLength; Loading media/libeffects/lvm/wrapper/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ cc_library_shared { cppflags: [ "-fvisibility=hidden", "-DSUPPORT_MC", "-Wall", "-Werror", Loading media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp +88 −2 Original line number Diff line number Diff line Loading @@ -259,6 +259,9 @@ extern "C" int EffectCreate(const effect_uuid_t *uuid, int channels = audio_channel_count_from_out_mask(pContext->config.inputCfg.channels); #ifdef SUPPORT_MC channels = (pContext->auxiliary == true)? channels : FCC_2; #endif // Allocate memory for reverb process (*2 is for STEREO) pContext->bufferSizeIn = LVREV_MAX_FRAME_SIZE * sizeof(process_buffer_t) * channels; pContext->bufferSizeOut = LVREV_MAX_FRAME_SIZE * sizeof(process_buffer_t) * FCC_2; Loading Loading @@ -343,11 +346,18 @@ int process( effect_buffer_t *pIn, int channels = audio_channel_count_from_out_mask(pContext->config.inputCfg.channels); LVREV_ReturnStatus_en LvmStatus = LVREV_SUCCESS; /* Function call status */ // Check that the input is either mono or stereo // Reverb only effects the stereo channels in multichannel source. #ifdef SUPPORT_MC if (channels < 1 || channels > LVM_MAX_CHANNELS) { ALOGE("\tLVREV_ERROR : process invalid PCM channels %d", channels); return -EINVAL; } #else if (!(channels == 1 || channels == FCC_2) ) { ALOGE("\tLVREV_ERROR : process invalid PCM format"); return -EINVAL; } #endif size_t inSize = frameCount * sizeof(process_buffer_t) * channels; size_t outSize = frameCount * sizeof(process_buffer_t) * FCC_2; Loading Loading @@ -381,11 +391,27 @@ int process( effect_buffer_t *pIn, "pIn and InFrames must be same type"); memcpy(pContext->InFrames, pIn, frameCount * channels * sizeof(*pIn)); } else { // insert reverb input is always stereo // mono input is duplicated #ifdef SUPPORT_MC if (channels >= FCC_2) { for (int i = 0; i < frameCount; i++) { pContext->InFrames[FCC_2 * i] = (process_buffer_t)pIn[channels * i] * REVERB_SEND_LEVEL; pContext->InFrames[FCC_2 * i + 1] = (process_buffer_t)pIn[channels * i + 1] * REVERB_SEND_LEVEL; } } else { for (int i = 0; i < frameCount; i++) { pContext->InFrames[FCC_2 * i] = pContext->InFrames[FCC_2 * i + 1] = (process_buffer_t)pIn[i] * REVERB_SEND_LEVEL; } } #else for (int i = 0; i < frameCount; i++) { pContext->InFrames[2 * i] = (process_buffer_t)pIn[2 * i] * REVERB_SEND_LEVEL; pContext->InFrames[2 * i + 1] = (process_buffer_t)pIn[2 * i + 1] * REVERB_SEND_LEVEL; } #endif } if (pContext->preset && pContext->curPreset == REVERB_PRESET_NONE) { Loading @@ -412,10 +438,26 @@ int process( effect_buffer_t *pIn, if (pContext->auxiliary) { // nothing to do here } else { #ifdef SUPPORT_MC if (channels >= FCC_2) { for (int i = 0; i < frameCount; i++) { // Mix with dry input pContext->OutFrames[FCC_2 * i] += pIn[channels * i]; pContext->OutFrames[FCC_2 * i + 1] += pIn[channels * i + 1]; } } else { for (int i = 0; i < frameCount; i++) { // Mix with dry input pContext->OutFrames[FCC_2 * i] += pIn[i]; pContext->OutFrames[FCC_2 * i + 1] += pIn[i]; } } #else for (int i = 0; i < frameCount * FCC_2; i++) { // always stereo here // Mix with dry input pContext->OutFrames[i] += pIn[i]; } #endif // apply volume with ramp if needed if ((pContext->leftVolume != pContext->prevLeftVolume || pContext->rightVolume != pContext->prevRightVolume) && Loading Loading @@ -450,6 +492,35 @@ int process( effect_buffer_t *pIn, } } #ifdef SUPPORT_MC if (channels > 2) { //Accumulate if required if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) { for (int i = 0; i < frameCount; i++) { pOut[channels * i] += pContext->OutFrames[FCC_2 * i]; pOut[channels * i + 1] += pContext->OutFrames[FCC_2 * i + 1]; } } else { for (int i = 0; i < frameCount; i++) { pOut[channels * i] = pContext->OutFrames[FCC_2 * i]; pOut[channels * i + 1] = pContext->OutFrames[FCC_2 * i + 1]; } } for (int i = 0; i < frameCount; i++) { for (int j = FCC_2; j < channels; j++) { pOut[channels * i + j] = pIn[channels * i + j]; } } } else { if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) { for (int i = 0; i < frameCount * FCC_2; i++) { pOut[i] += pContext->OutFrames[i]; } } else { memcpy(pOut, pContext->OutFrames, frameCount * sizeof(*pOut) * FCC_2); } } #else // Accumulate if required if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){ Loading @@ -462,6 +533,7 @@ int process( effect_buffer_t *pIn, memcpy(pOut, pContext->OutFrames, frameCount * sizeof(*pOut) * FCC_2); } #endif return 0; } /* end process */ Loading Loading @@ -525,9 +597,18 @@ int Reverb_setConfig(ReverbContext *pContext, effect_config_t *pConfig){ CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate); CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format); #ifdef SUPPORT_MC int inputChannels = audio_channel_count_from_out_mask(pConfig->inputCfg.channels); CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) || ((!pContext->auxiliary) && (inputChannels <= LVM_MAX_CHANNELS))); int outputChannels = audio_channel_count_from_out_mask(pConfig->outputCfg.channels); CHECK_ARG(outputChannels >= FCC_2 && outputChannels <= LVM_MAX_CHANNELS); #else CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) || ((!pContext->auxiliary) && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO)); CHECK_ARG(pConfig->outputCfg.channels == AUDIO_CHANNEL_OUT_STEREO); #endif CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE); CHECK_ARG(pConfig->inputCfg.format == EFFECT_BUFFER_FORMAT); Loading Loading @@ -749,6 +830,11 @@ int Reverb_init(ReverbContext *pContext){ params.SourceFormat = LVM_STEREO; } #ifdef SUPPORT_MC if ((pContext->auxiliary == false) && (params.SourceFormat == LVM_MONO)) { params.SourceFormat = LVM_STEREO; } #endif /* Reverb parameters */ params.Level = 0; params.LPF = 23999; Loading Loading
media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh +43 −25 Original line number Diff line number Diff line Loading @@ -41,22 +41,30 @@ fs_arr=( 192000 ) flags_arr=( "--M --fch 1" "--fch 2" ) # run reverb at different configs, saving only the stereo channel # pair. error_count=0 testcase_count=0 for cmd in "${cmds[@]}" do $cmd for flags in "${flags_arr[@]}" do for preset_val in {0..6} do for fs in ${fs_arr[*]} do for chMask in {1..22} for chMask in {0..22} do adb shell LD_LIBRARY_PATH=/system/vendor/lib/soundfx $testdir/reverb_test \ --input $testdir/sinesweepraw.raw \ --output $testdir/sinesweep_$((chMask))_$((fs)).raw \ --chMask $chMask --fs $fs --preset $preset_val --chMask $chMask $flags --fs $fs --preset $preset_val shell_ret=$? if [ $shell_ret -ne 0 ]; then Loading @@ -64,24 +72,34 @@ do ((++error_count)) fi if [[ "$chMask" -gt 0 ]] && [[ $flags != *"--fch 2"* ]] then # single channel files should be identical to higher channel # computation (first channel). adb shell cmp $testdir/sinesweep_0_$((fs)).raw \ $testdir/sinesweep_$((chMask))_$((fs)).raw elif [[ "$chMask" -gt 1 ]] then # two channel files should be identical to higher channel # computation (first 2 channels). if [[ "$chMask" -gt 1 ]] then adb shell cmp $testdir/sinesweep_1_$((fs)).raw \ $testdir/sinesweep_$((chMask))_$((fs)).raw fi # cmp returns EXIT_FAILURE on mismatch. shell_ret=$? if [ $shell_ret -ne 0 ]; then echo "error: $shell_ret" ((++error_count)) fi ((++testcase_count)) done done done done done adb shell rm -r $testdir echo "$testcase_count tests performed" echo "$error_count errors" exit $error_count
media/libeffects/lvm/tests/reverb_test.cpp +10 −7 Original line number Diff line number Diff line Loading @@ -297,6 +297,9 @@ int main(int argc, const char *argv[]) { config.inputCfg.samplingRate = config.outputCfg.samplingRate = revConfigParams.sampleRate; config.inputCfg.channels = config.outputCfg.channels = revConfigParams.chMask; config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT; if (AUDIO_CHANNEL_OUT_MONO == revConfigParams.chMask) { config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; } if (int status = reverbCreateEffect(&effectHandle, &config, sessionId, ioId, revConfigParams.auxiliary); status != 0) { Loading Loading @@ -332,15 +335,15 @@ int main(int argc, const char *argv[]) { * Mono input will be converted to 2 channels internally in the process call * by copying the same data into the second channel. * Hence when channelCount is 1, output buffer should be allocated for * 2 channels. The memAllocChCount takes care of allocation of sufficient * 2 channels. The outChannelCount takes care of allocation of sufficient * memory for the output buffer. */ const int memAllocChCount = (channelCount == 1 ? 2 : channelCount); const int outChannelCount = (channelCount == 1 ? 2 : channelCount); std::vector<short> in(frameLength * maxChannelCount); std::vector<short> out(frameLength * maxChannelCount); std::vector<float> floatIn(frameLength * channelCount); std::vector<float> floatOut(frameLength * memAllocChCount); std::vector<float> floatOut(frameLength * outChannelCount); int frameCounter = 0; Loading Loading @@ -374,11 +377,11 @@ int main(int argc, const char *argv[]) { #else memcpy(floatOut.data(), floatIn.data(), frameLength * frameSize); #endif memcpy_to_i16_from_float(out.data(), floatOut.data(), frameLength * channelCount); memcpy_to_i16_from_float(out.data(), floatOut.data(), frameLength * outChannelCount); if (ioChannelCount != channelCount) { adjust_channels(out.data(), channelCount, out.data(), ioChannelCount, sizeof(short), frameLength * channelCount * sizeof(short)); if (ioChannelCount != outChannelCount) { adjust_channels(out.data(), outChannelCount, out.data(), ioChannelCount, sizeof(short), frameLength * outChannelCount * sizeof(short)); } (void)fwrite(out.data(), ioFrameSize, frameLength, outputFp.get()); frameCounter += frameLength; Loading
media/libeffects/lvm/wrapper/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ cc_library_shared { cppflags: [ "-fvisibility=hidden", "-DSUPPORT_MC", "-Wall", "-Werror", Loading
media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp +88 −2 Original line number Diff line number Diff line Loading @@ -259,6 +259,9 @@ extern "C" int EffectCreate(const effect_uuid_t *uuid, int channels = audio_channel_count_from_out_mask(pContext->config.inputCfg.channels); #ifdef SUPPORT_MC channels = (pContext->auxiliary == true)? channels : FCC_2; #endif // Allocate memory for reverb process (*2 is for STEREO) pContext->bufferSizeIn = LVREV_MAX_FRAME_SIZE * sizeof(process_buffer_t) * channels; pContext->bufferSizeOut = LVREV_MAX_FRAME_SIZE * sizeof(process_buffer_t) * FCC_2; Loading Loading @@ -343,11 +346,18 @@ int process( effect_buffer_t *pIn, int channels = audio_channel_count_from_out_mask(pContext->config.inputCfg.channels); LVREV_ReturnStatus_en LvmStatus = LVREV_SUCCESS; /* Function call status */ // Check that the input is either mono or stereo // Reverb only effects the stereo channels in multichannel source. #ifdef SUPPORT_MC if (channels < 1 || channels > LVM_MAX_CHANNELS) { ALOGE("\tLVREV_ERROR : process invalid PCM channels %d", channels); return -EINVAL; } #else if (!(channels == 1 || channels == FCC_2) ) { ALOGE("\tLVREV_ERROR : process invalid PCM format"); return -EINVAL; } #endif size_t inSize = frameCount * sizeof(process_buffer_t) * channels; size_t outSize = frameCount * sizeof(process_buffer_t) * FCC_2; Loading Loading @@ -381,11 +391,27 @@ int process( effect_buffer_t *pIn, "pIn and InFrames must be same type"); memcpy(pContext->InFrames, pIn, frameCount * channels * sizeof(*pIn)); } else { // insert reverb input is always stereo // mono input is duplicated #ifdef SUPPORT_MC if (channels >= FCC_2) { for (int i = 0; i < frameCount; i++) { pContext->InFrames[FCC_2 * i] = (process_buffer_t)pIn[channels * i] * REVERB_SEND_LEVEL; pContext->InFrames[FCC_2 * i + 1] = (process_buffer_t)pIn[channels * i + 1] * REVERB_SEND_LEVEL; } } else { for (int i = 0; i < frameCount; i++) { pContext->InFrames[FCC_2 * i] = pContext->InFrames[FCC_2 * i + 1] = (process_buffer_t)pIn[i] * REVERB_SEND_LEVEL; } } #else for (int i = 0; i < frameCount; i++) { pContext->InFrames[2 * i] = (process_buffer_t)pIn[2 * i] * REVERB_SEND_LEVEL; pContext->InFrames[2 * i + 1] = (process_buffer_t)pIn[2 * i + 1] * REVERB_SEND_LEVEL; } #endif } if (pContext->preset && pContext->curPreset == REVERB_PRESET_NONE) { Loading @@ -412,10 +438,26 @@ int process( effect_buffer_t *pIn, if (pContext->auxiliary) { // nothing to do here } else { #ifdef SUPPORT_MC if (channels >= FCC_2) { for (int i = 0; i < frameCount; i++) { // Mix with dry input pContext->OutFrames[FCC_2 * i] += pIn[channels * i]; pContext->OutFrames[FCC_2 * i + 1] += pIn[channels * i + 1]; } } else { for (int i = 0; i < frameCount; i++) { // Mix with dry input pContext->OutFrames[FCC_2 * i] += pIn[i]; pContext->OutFrames[FCC_2 * i + 1] += pIn[i]; } } #else for (int i = 0; i < frameCount * FCC_2; i++) { // always stereo here // Mix with dry input pContext->OutFrames[i] += pIn[i]; } #endif // apply volume with ramp if needed if ((pContext->leftVolume != pContext->prevLeftVolume || pContext->rightVolume != pContext->prevRightVolume) && Loading Loading @@ -450,6 +492,35 @@ int process( effect_buffer_t *pIn, } } #ifdef SUPPORT_MC if (channels > 2) { //Accumulate if required if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) { for (int i = 0; i < frameCount; i++) { pOut[channels * i] += pContext->OutFrames[FCC_2 * i]; pOut[channels * i + 1] += pContext->OutFrames[FCC_2 * i + 1]; } } else { for (int i = 0; i < frameCount; i++) { pOut[channels * i] = pContext->OutFrames[FCC_2 * i]; pOut[channels * i + 1] = pContext->OutFrames[FCC_2 * i + 1]; } } for (int i = 0; i < frameCount; i++) { for (int j = FCC_2; j < channels; j++) { pOut[channels * i + j] = pIn[channels * i + j]; } } } else { if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) { for (int i = 0; i < frameCount * FCC_2; i++) { pOut[i] += pContext->OutFrames[i]; } } else { memcpy(pOut, pContext->OutFrames, frameCount * sizeof(*pOut) * FCC_2); } } #else // Accumulate if required if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){ Loading @@ -462,6 +533,7 @@ int process( effect_buffer_t *pIn, memcpy(pOut, pContext->OutFrames, frameCount * sizeof(*pOut) * FCC_2); } #endif return 0; } /* end process */ Loading Loading @@ -525,9 +597,18 @@ int Reverb_setConfig(ReverbContext *pContext, effect_config_t *pConfig){ CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate); CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format); #ifdef SUPPORT_MC int inputChannels = audio_channel_count_from_out_mask(pConfig->inputCfg.channels); CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) || ((!pContext->auxiliary) && (inputChannels <= LVM_MAX_CHANNELS))); int outputChannels = audio_channel_count_from_out_mask(pConfig->outputCfg.channels); CHECK_ARG(outputChannels >= FCC_2 && outputChannels <= LVM_MAX_CHANNELS); #else CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) || ((!pContext->auxiliary) && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO)); CHECK_ARG(pConfig->outputCfg.channels == AUDIO_CHANNEL_OUT_STEREO); #endif CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE); CHECK_ARG(pConfig->inputCfg.format == EFFECT_BUFFER_FORMAT); Loading Loading @@ -749,6 +830,11 @@ int Reverb_init(ReverbContext *pContext){ params.SourceFormat = LVM_STEREO; } #ifdef SUPPORT_MC if ((pContext->auxiliary == false) && (params.SourceFormat == LVM_MONO)) { params.SourceFormat = LVM_STEREO; } #endif /* Reverb parameters */ params.Level = 0; params.LPF = 23999; Loading