Loading media/libeffects/preprocessing/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -48,4 +48,9 @@ cc_library { "libhardware_headers", "libwebrtc_absl_headers", ], target: { darwin: { enabled: false, }, }, } media/libeffects/preprocessing/tests/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,11 @@ cc_test { "libaudioeffects", "libhardware_headers", ], target: { darwin: { enabled: false, }, }, } cc_test { Loading media/libeffects/preprocessing/tests/PreProcessingTest.cpp +58 −6 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <audio_effects/effect_agc.h> #include <audio_effects/effect_agc2.h> #include <audio_effects/effect_ns.h> #include <audio_utils/channels.h> #include <log/log.h> // This is the only symbol that needs to be imported Loading Loading @@ -55,7 +56,9 @@ enum PreProcParams { ARG_NS_LVL, ARG_AGC2_GAIN, ARG_AGC2_LVL, ARG_AGC2_SAT_MGN ARG_AGC2_SAT_MGN, ARG_FILE_CHANNELS, ARG_MONO_MODE }; struct preProcConfigParams_t { Loading @@ -68,6 +71,8 @@ struct preProcConfigParams_t { float agc2SaturationMargin = 2.f; // in dB int agc2Level = 0; // either kRms(0) or kPeak(1) int aecDelay = 0; // in ms int fileChannels = 1; int monoMode = 0; }; const effect_uuid_t kPreProcUuids[PREPROC_NUM_EFFECTS] = { Loading Loading @@ -106,7 +111,7 @@ void printUsage() { printf("\n Prints this usage information"); printf("\n --fs <sampling_freq>"); printf("\n Sampling frequency in Hz, default 16000."); printf("\n -ch_mask <channel_mask>\n"); printf("\n --ch_mask <channel_mask>\n"); printf("\n 0 - AUDIO_CHANNEL_IN_MONO"); printf("\n 1 - AUDIO_CHANNEL_IN_STEREO"); printf("\n 2 - AUDIO_CHANNEL_IN_FRONT_BACK"); Loading Loading @@ -144,6 +149,10 @@ void printUsage() { printf("\n AGC Adaptive Digital Saturation Margin in dB, default value 2dB"); printf("\n --aec_delay <delay>"); printf("\n AEC delay value in ms, default value 0ms"); printf("\n --fch <fileChannels>"); printf("\n number of channels in the input file"); printf("\n --mono <Mono Mode>"); printf("\n Mode to make data of all channels the same as first channel"); printf("\n"); } Loading Loading @@ -189,10 +198,17 @@ int main(int argc, const char* argv[]) { printUsage(); return EXIT_FAILURE; } // Print the arguments passed for (int i = 1; i < argc; i++) { printf("%s ", argv[i]); } const char* inputFile = nullptr; const char* outputFile = nullptr; const char* farFile = nullptr; int effectEn[PREPROC_NUM_EFFECTS] = {0}; struct preProcConfigParams_t preProcCfgParams {}; const option long_opts[] = { {"help", no_argument, nullptr, ARG_HELP}, Loading @@ -212,9 +228,10 @@ int main(int argc, const char* argv[]) { {"agc", no_argument, &effectEn[PREPROC_AGC], 1}, {"agc2", no_argument, &effectEn[PREPROC_AGC2], 1}, {"ns", no_argument, &effectEn[PREPROC_NS], 1}, {"fch", required_argument, nullptr, ARG_FILE_CHANNELS}, {"mono", no_argument, &preProcCfgParams.monoMode, 1}, {nullptr, 0, nullptr, 0}, }; struct preProcConfigParams_t preProcCfgParams {}; while (true) { const int opt = getopt_long(argc, (char* const*)argv, "i:o:", long_opts, nullptr); Loading Loading @@ -279,6 +296,14 @@ int main(int argc, const char* argv[]) { preProcCfgParams.nsLevel = atoi(optarg); break; } case ARG_FILE_CHANNELS: { preProcCfgParams.fileChannels = atoi(optarg); break; } case ARG_MONO_MODE: { preProcCfgParams.monoMode = 1; break; } default: break; } Loading Loading @@ -402,16 +427,28 @@ int main(int argc, const char* argv[]) { // Process Call const int frameLength = (int)(preProcCfgParams.samplingFreq * kTenMilliSecVal); const int ioChannelCount = audio_channel_count_from_in_mask(preProcCfgParams.chMask); const int fileChannelCount = preProcCfgParams.fileChannels; const int ioFrameSize = ioChannelCount * sizeof(short); const int inFrameSize = fileChannelCount * sizeof(short); int frameCounter = 0; while (true) { std::vector<short> in(frameLength * ioChannelCount); std::vector<short> out(frameLength * ioChannelCount); std::vector<short> farIn(frameLength * ioChannelCount); size_t samplesRead = fread(in.data(), ioFrameSize, frameLength, inputFp.get()); size_t samplesRead = fread(in.data(), inFrameSize, frameLength, inputFp.get()); if (samplesRead == 0) { break; } if (fileChannelCount != ioChannelCount) { adjust_channels(in.data(), fileChannelCount, in.data(), ioChannelCount, sizeof(short), frameLength * inFrameSize); if (preProcCfgParams.monoMode == 1) { for (int i = 0; i < frameLength; ++i) { auto* fp = &in[i * ioChannelCount]; std::fill(fp + 1, fp + ioChannelCount, *fp); // replicate ch 0 } } } audio_buffer_t inputBuffer, outputBuffer; audio_buffer_t farInBuffer{}; inputBuffer.frameCount = samplesRead; Loading @@ -420,10 +457,21 @@ int main(int argc, const char* argv[]) { outputBuffer.s16 = out.data(); if (farFp != nullptr) { samplesRead = fread(farIn.data(), ioFrameSize, frameLength, farFp.get()); samplesRead = fread(farIn.data(), inFrameSize, frameLength, farFp.get()); if (samplesRead == 0) { break; } if (fileChannelCount != ioChannelCount) { adjust_channels(farIn.data(), fileChannelCount, farIn.data(), ioChannelCount, sizeof(short), frameLength * inFrameSize); if (preProcCfgParams.monoMode == 1) { for (int i = 0; i < frameLength; ++i) { auto* fp = &farIn[i * ioChannelCount]; std::fill(fp + 1, fp + ioChannelCount, *fp); // replicate ch 0 } } } farInBuffer.frameCount = samplesRead; farInBuffer.s16 = farIn.data(); } Loading Loading @@ -458,8 +506,12 @@ int main(int argc, const char* argv[]) { } } if (outputFp != nullptr) { if (fileChannelCount != ioChannelCount) { adjust_channels(out.data(), ioChannelCount, out.data(), fileChannelCount, sizeof(short), frameLength * ioFrameSize); } size_t samplesWritten = fwrite(out.data(), ioFrameSize, outputBuffer.frameCount, outputFp.get()); fwrite(out.data(), inFrameSize, outputBuffer.frameCount, outputFp.get()); if (samplesWritten != outputBuffer.frameCount) { ALOGE("\nError: Output file writing failed"); break; Loading media/libeffects/preprocessing/tests/build_and_run_all_unit_tests.sh 0 → 100755 +115 −0 Original line number Diff line number Diff line #!/bin/bash # # Run tests in this directory. # if [ -z "$ANDROID_BUILD_TOP" ]; then echo "Android build environment not set" exit -1 fi # ensure we have mm . $ANDROID_BUILD_TOP/build/envsetup.sh mm -j echo "waiting for device" adb root && adb wait-for-device remount # location of test files testdir="/data/local/tmp/AudioPreProcessingTest" echo "========================================" echo "testing PreProcessing modules" adb shell mkdir -p $testdir adb push $ANDROID_BUILD_TOP/frameworks/av/media/libeffects/res/raw/sinesweepraw.raw $testdir adb push $OUT/testcases/snr/arm64/snr $testdir E_VAL=1 if [ -z "$1" ] then cmds=("adb push $OUT/testcases/AudioPreProcessingTest/arm64/AudioPreProcessingTest $testdir" "adb push $OUT/testcases/AudioPreProcessingTest/arm/AudioPreProcessingTest $testdir" ) elif [ "$1" == "32" ] then cmds="adb push $OUT/testcases/AudioPreProcessingTest/arm/AudioPreProcessingTest $testdir" elif [ "$1" == "64" ] then cmds="adb push $OUT/testcases/AudioPreProcessingTest/arm64/AudioPreProcessingTest $testdir" else echo "" echo "Invalid \"val\"" echo "Usage:" echo " "$0" [val]" echo " where, val can be either 32 or 64." echo "" echo " If val is not specified then both 32 bit and 64 bit binaries" echo " are tested." exit $E_VAL fi flags_arr=( "--agc --mono" "--ns --mono" "--agc2 --mono" "--aec --mono" ) fs_arr=( 8000 16000 24000 32000 48000 ) # run multichannel effects at different configs, saving only the mono channel error_count=0 test_count=0 for cmd in "${cmds[@]}" do $cmd for flags in "${flags_arr[@]}" do for fs in ${fs_arr[*]} do for chMask in {0..7} do adb shell $testdir/AudioPreProcessingTest $flags \ --i $testdir/sinesweepraw.raw --far $testdir/sinesweepraw.raw \ --output $testdir/sinesweep_$((chMask))_$((fs)).raw --ch_mask $chMask \ --fs $fs --fch 1 shell_ret=$? if [ $shell_ret -ne 0 ]; then echo "error shell_ret here is zero: $shell_ret" ((++error_count)) fi # single channel files should be identical to higher channel # computation (first channel). if [[ "$chMask" -gt 1 ]] then adb shell cmp $testdir/sinesweep_1_$((fs)).raw \ $testdir/sinesweep_$((chMask))_$((fs)).raw fi # cmp return EXIT_FAILURE on mismatch. shell_ret=$? if [ $shell_ret -ne 0 ]; then echo "error: $shell_ret" ((++error_count)) fi ((++test_count)) done done done done adb shell rm -r $testdir echo "$test_count tests performed" echo "$error_count errors" exit $error_count media/libstagefright/MediaExtractorFactory.cpp +11 −7 Original line number Diff line number Diff line Loading @@ -188,11 +188,11 @@ void MediaExtractorFactory::RegisterExtractor(const sp<ExtractorPlugin> &plugin, // sanity check check struct version, uuid, name if (plugin->def.def_version != EXTRACTORDEF_VERSION_NDK_V1 && plugin->def.def_version != EXTRACTORDEF_VERSION_NDK_V2) { ALOGE("don't understand extractor format %u, ignoring.", plugin->def.def_version); ALOGW("don't understand extractor format %u, ignoring.", plugin->def.def_version); return; } if (memcmp(&plugin->def.extractor_uuid, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) == 0) { ALOGE("invalid UUID, ignoring"); ALOGW("invalid UUID, ignoring"); return; } if (plugin->def.extractor_name == NULL || strlen(plugin->def.extractor_name) == 0) { Loading Loading @@ -244,13 +244,17 @@ void MediaExtractorFactory::RegisterExtractors( void *libHandle = android_dlopen_ext( libPath.string(), RTLD_NOW | RTLD_LOCAL, dlextinfo); CHECK(libHandle != nullptr) << "couldn't dlopen(" << libPath.string() << ") " << strerror(errno); if (libHandle == nullptr) { ALOGI("dlopen(%s) reported error %s", libPath.string(), strerror(errno)); continue; } GetExtractorDef getDef = (GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF"); CHECK(getDef != nullptr) << libPath.string() << " does not contain sniffer"; if (getDef == nullptr) { ALOGI("no sniffer found in %s", libPath.string()); continue; } ALOGV("registering sniffer for %s", libPath.string()); RegisterExtractor( Loading @@ -258,7 +262,7 @@ void MediaExtractorFactory::RegisterExtractors( } closedir(libDir); } else { ALOGE("couldn't opendir(%s)", libDirPath); ALOGI("plugin directory not present (%s)", libDirPath); } } Loading Loading
media/libeffects/preprocessing/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -48,4 +48,9 @@ cc_library { "libhardware_headers", "libwebrtc_absl_headers", ], target: { darwin: { enabled: false, }, }, }
media/libeffects/preprocessing/tests/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,11 @@ cc_test { "libaudioeffects", "libhardware_headers", ], target: { darwin: { enabled: false, }, }, } cc_test { Loading
media/libeffects/preprocessing/tests/PreProcessingTest.cpp +58 −6 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <audio_effects/effect_agc.h> #include <audio_effects/effect_agc2.h> #include <audio_effects/effect_ns.h> #include <audio_utils/channels.h> #include <log/log.h> // This is the only symbol that needs to be imported Loading Loading @@ -55,7 +56,9 @@ enum PreProcParams { ARG_NS_LVL, ARG_AGC2_GAIN, ARG_AGC2_LVL, ARG_AGC2_SAT_MGN ARG_AGC2_SAT_MGN, ARG_FILE_CHANNELS, ARG_MONO_MODE }; struct preProcConfigParams_t { Loading @@ -68,6 +71,8 @@ struct preProcConfigParams_t { float agc2SaturationMargin = 2.f; // in dB int agc2Level = 0; // either kRms(0) or kPeak(1) int aecDelay = 0; // in ms int fileChannels = 1; int monoMode = 0; }; const effect_uuid_t kPreProcUuids[PREPROC_NUM_EFFECTS] = { Loading Loading @@ -106,7 +111,7 @@ void printUsage() { printf("\n Prints this usage information"); printf("\n --fs <sampling_freq>"); printf("\n Sampling frequency in Hz, default 16000."); printf("\n -ch_mask <channel_mask>\n"); printf("\n --ch_mask <channel_mask>\n"); printf("\n 0 - AUDIO_CHANNEL_IN_MONO"); printf("\n 1 - AUDIO_CHANNEL_IN_STEREO"); printf("\n 2 - AUDIO_CHANNEL_IN_FRONT_BACK"); Loading Loading @@ -144,6 +149,10 @@ void printUsage() { printf("\n AGC Adaptive Digital Saturation Margin in dB, default value 2dB"); printf("\n --aec_delay <delay>"); printf("\n AEC delay value in ms, default value 0ms"); printf("\n --fch <fileChannels>"); printf("\n number of channels in the input file"); printf("\n --mono <Mono Mode>"); printf("\n Mode to make data of all channels the same as first channel"); printf("\n"); } Loading Loading @@ -189,10 +198,17 @@ int main(int argc, const char* argv[]) { printUsage(); return EXIT_FAILURE; } // Print the arguments passed for (int i = 1; i < argc; i++) { printf("%s ", argv[i]); } const char* inputFile = nullptr; const char* outputFile = nullptr; const char* farFile = nullptr; int effectEn[PREPROC_NUM_EFFECTS] = {0}; struct preProcConfigParams_t preProcCfgParams {}; const option long_opts[] = { {"help", no_argument, nullptr, ARG_HELP}, Loading @@ -212,9 +228,10 @@ int main(int argc, const char* argv[]) { {"agc", no_argument, &effectEn[PREPROC_AGC], 1}, {"agc2", no_argument, &effectEn[PREPROC_AGC2], 1}, {"ns", no_argument, &effectEn[PREPROC_NS], 1}, {"fch", required_argument, nullptr, ARG_FILE_CHANNELS}, {"mono", no_argument, &preProcCfgParams.monoMode, 1}, {nullptr, 0, nullptr, 0}, }; struct preProcConfigParams_t preProcCfgParams {}; while (true) { const int opt = getopt_long(argc, (char* const*)argv, "i:o:", long_opts, nullptr); Loading Loading @@ -279,6 +296,14 @@ int main(int argc, const char* argv[]) { preProcCfgParams.nsLevel = atoi(optarg); break; } case ARG_FILE_CHANNELS: { preProcCfgParams.fileChannels = atoi(optarg); break; } case ARG_MONO_MODE: { preProcCfgParams.monoMode = 1; break; } default: break; } Loading Loading @@ -402,16 +427,28 @@ int main(int argc, const char* argv[]) { // Process Call const int frameLength = (int)(preProcCfgParams.samplingFreq * kTenMilliSecVal); const int ioChannelCount = audio_channel_count_from_in_mask(preProcCfgParams.chMask); const int fileChannelCount = preProcCfgParams.fileChannels; const int ioFrameSize = ioChannelCount * sizeof(short); const int inFrameSize = fileChannelCount * sizeof(short); int frameCounter = 0; while (true) { std::vector<short> in(frameLength * ioChannelCount); std::vector<short> out(frameLength * ioChannelCount); std::vector<short> farIn(frameLength * ioChannelCount); size_t samplesRead = fread(in.data(), ioFrameSize, frameLength, inputFp.get()); size_t samplesRead = fread(in.data(), inFrameSize, frameLength, inputFp.get()); if (samplesRead == 0) { break; } if (fileChannelCount != ioChannelCount) { adjust_channels(in.data(), fileChannelCount, in.data(), ioChannelCount, sizeof(short), frameLength * inFrameSize); if (preProcCfgParams.monoMode == 1) { for (int i = 0; i < frameLength; ++i) { auto* fp = &in[i * ioChannelCount]; std::fill(fp + 1, fp + ioChannelCount, *fp); // replicate ch 0 } } } audio_buffer_t inputBuffer, outputBuffer; audio_buffer_t farInBuffer{}; inputBuffer.frameCount = samplesRead; Loading @@ -420,10 +457,21 @@ int main(int argc, const char* argv[]) { outputBuffer.s16 = out.data(); if (farFp != nullptr) { samplesRead = fread(farIn.data(), ioFrameSize, frameLength, farFp.get()); samplesRead = fread(farIn.data(), inFrameSize, frameLength, farFp.get()); if (samplesRead == 0) { break; } if (fileChannelCount != ioChannelCount) { adjust_channels(farIn.data(), fileChannelCount, farIn.data(), ioChannelCount, sizeof(short), frameLength * inFrameSize); if (preProcCfgParams.monoMode == 1) { for (int i = 0; i < frameLength; ++i) { auto* fp = &farIn[i * ioChannelCount]; std::fill(fp + 1, fp + ioChannelCount, *fp); // replicate ch 0 } } } farInBuffer.frameCount = samplesRead; farInBuffer.s16 = farIn.data(); } Loading Loading @@ -458,8 +506,12 @@ int main(int argc, const char* argv[]) { } } if (outputFp != nullptr) { if (fileChannelCount != ioChannelCount) { adjust_channels(out.data(), ioChannelCount, out.data(), fileChannelCount, sizeof(short), frameLength * ioFrameSize); } size_t samplesWritten = fwrite(out.data(), ioFrameSize, outputBuffer.frameCount, outputFp.get()); fwrite(out.data(), inFrameSize, outputBuffer.frameCount, outputFp.get()); if (samplesWritten != outputBuffer.frameCount) { ALOGE("\nError: Output file writing failed"); break; Loading
media/libeffects/preprocessing/tests/build_and_run_all_unit_tests.sh 0 → 100755 +115 −0 Original line number Diff line number Diff line #!/bin/bash # # Run tests in this directory. # if [ -z "$ANDROID_BUILD_TOP" ]; then echo "Android build environment not set" exit -1 fi # ensure we have mm . $ANDROID_BUILD_TOP/build/envsetup.sh mm -j echo "waiting for device" adb root && adb wait-for-device remount # location of test files testdir="/data/local/tmp/AudioPreProcessingTest" echo "========================================" echo "testing PreProcessing modules" adb shell mkdir -p $testdir adb push $ANDROID_BUILD_TOP/frameworks/av/media/libeffects/res/raw/sinesweepraw.raw $testdir adb push $OUT/testcases/snr/arm64/snr $testdir E_VAL=1 if [ -z "$1" ] then cmds=("adb push $OUT/testcases/AudioPreProcessingTest/arm64/AudioPreProcessingTest $testdir" "adb push $OUT/testcases/AudioPreProcessingTest/arm/AudioPreProcessingTest $testdir" ) elif [ "$1" == "32" ] then cmds="adb push $OUT/testcases/AudioPreProcessingTest/arm/AudioPreProcessingTest $testdir" elif [ "$1" == "64" ] then cmds="adb push $OUT/testcases/AudioPreProcessingTest/arm64/AudioPreProcessingTest $testdir" else echo "" echo "Invalid \"val\"" echo "Usage:" echo " "$0" [val]" echo " where, val can be either 32 or 64." echo "" echo " If val is not specified then both 32 bit and 64 bit binaries" echo " are tested." exit $E_VAL fi flags_arr=( "--agc --mono" "--ns --mono" "--agc2 --mono" "--aec --mono" ) fs_arr=( 8000 16000 24000 32000 48000 ) # run multichannel effects at different configs, saving only the mono channel error_count=0 test_count=0 for cmd in "${cmds[@]}" do $cmd for flags in "${flags_arr[@]}" do for fs in ${fs_arr[*]} do for chMask in {0..7} do adb shell $testdir/AudioPreProcessingTest $flags \ --i $testdir/sinesweepraw.raw --far $testdir/sinesweepraw.raw \ --output $testdir/sinesweep_$((chMask))_$((fs)).raw --ch_mask $chMask \ --fs $fs --fch 1 shell_ret=$? if [ $shell_ret -ne 0 ]; then echo "error shell_ret here is zero: $shell_ret" ((++error_count)) fi # single channel files should be identical to higher channel # computation (first channel). if [[ "$chMask" -gt 1 ]] then adb shell cmp $testdir/sinesweep_1_$((fs)).raw \ $testdir/sinesweep_$((chMask))_$((fs)).raw fi # cmp return EXIT_FAILURE on mismatch. shell_ret=$? if [ $shell_ret -ne 0 ]; then echo "error: $shell_ret" ((++error_count)) fi ((++test_count)) done done done done adb shell rm -r $testdir echo "$test_count tests performed" echo "$error_count errors" exit $error_count
media/libstagefright/MediaExtractorFactory.cpp +11 −7 Original line number Diff line number Diff line Loading @@ -188,11 +188,11 @@ void MediaExtractorFactory::RegisterExtractor(const sp<ExtractorPlugin> &plugin, // sanity check check struct version, uuid, name if (plugin->def.def_version != EXTRACTORDEF_VERSION_NDK_V1 && plugin->def.def_version != EXTRACTORDEF_VERSION_NDK_V2) { ALOGE("don't understand extractor format %u, ignoring.", plugin->def.def_version); ALOGW("don't understand extractor format %u, ignoring.", plugin->def.def_version); return; } if (memcmp(&plugin->def.extractor_uuid, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) == 0) { ALOGE("invalid UUID, ignoring"); ALOGW("invalid UUID, ignoring"); return; } if (plugin->def.extractor_name == NULL || strlen(plugin->def.extractor_name) == 0) { Loading Loading @@ -244,13 +244,17 @@ void MediaExtractorFactory::RegisterExtractors( void *libHandle = android_dlopen_ext( libPath.string(), RTLD_NOW | RTLD_LOCAL, dlextinfo); CHECK(libHandle != nullptr) << "couldn't dlopen(" << libPath.string() << ") " << strerror(errno); if (libHandle == nullptr) { ALOGI("dlopen(%s) reported error %s", libPath.string(), strerror(errno)); continue; } GetExtractorDef getDef = (GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF"); CHECK(getDef != nullptr) << libPath.string() << " does not contain sniffer"; if (getDef == nullptr) { ALOGI("no sniffer found in %s", libPath.string()); continue; } ALOGV("registering sniffer for %s", libPath.string()); RegisterExtractor( Loading @@ -258,7 +262,7 @@ void MediaExtractorFactory::RegisterExtractors( } closedir(libDir); } else { ALOGE("couldn't opendir(%s)", libDirPath); ALOGI("plugin directory not present (%s)", libDirPath); } } Loading