1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 #include <stdint.h> 18 #include <math.h> 19 #include <utils/StrongPointer.h> 20 #include "audio/Buffer.h" 21 #include "BuiltinProcessing.h" 22 #include "Log.h" 23 #include "task/TaskCase.h" 24 25 // Buffer, Value, Value 26 static const bool RMS_MVA_INPUT_TYPE[] = {true, false, false}; 27 // Value 28 static const bool RMS_MVA_OUTPUT_TYPE[] = {false}; 29 30 BuiltinProcessing::BuiltinInfo BuiltinProcessing::BUINTIN_FN_TABLE[N_BUILTIN_FNS] = 31 { 32 { 33 "rms_mva", &BuiltinProcessing::rms_mva, 34 sizeof(RMS_MVA_INPUT_TYPE)/sizeof(bool), RMS_MVA_INPUT_TYPE, 35 sizeof(RMS_MVA_OUTPUT_TYPE)/sizeof(bool), RMS_MVA_OUTPUT_TYPE, 36 } 37 }; 38 39 BuiltinProcessing::BuiltinProcessing() 40 : mRMSPasses(0) 41 { 42 43 } 44 45 // pass for 5 consecutive passes 46 TaskGeneric::ExecutionResult BuiltinProcessing::rms_mva(void** inputs, void** outputs) 47 { 48 LOGD("BuiltinProcessing::rms_mva in %x %x %x out %x", 49 inputs[0], inputs[1], inputs[2], outputs[0]); 50 android::sp<Buffer>& data(*reinterpret_cast<android::sp<Buffer>*>(inputs[0])); 51 52 int64_t passMin = (reinterpret_cast<TaskCase::Value*>(inputs[1]))->getInt64(); 53 int64_t passMax = (reinterpret_cast<TaskCase::Value*>(inputs[2]))->getInt64(); 54 55 int64_t rms = 0; 56 size_t samples = data->getSize()/2; 57 int16_t* rawData = reinterpret_cast<int16_t*>(data->getData()); 58 double energy = 0.0f; 59 for (size_t i = 0; i < samples; i++) { 60 energy += (rawData[i] * rawData[i]); 61 } 62 rms = (int64_t)sqrt(energy/samples); 63 64 TaskGeneric::ExecutionResult result = TaskGeneric::EResultOK; 65 if (rms < passMin) { 66 LOGW("Volume %lld low compared to min %lld max %lld", rms, passMin, passMax); 67 mRMSPasses = 0; 68 } else if (rms <= passMax) { 69 LOGW("Volume %lld OK compared to min %lld max %lld", rms, passMin, passMax); 70 mRMSPasses++; 71 if (mRMSPasses >= RMS_CONTINUOUS_PASSES) { 72 //mRMSPasses = 0; 73 result = TaskGeneric::EResultPass; 74 } 75 } else { 76 LOGW("Volume %lld high compared to min %lld max %lld", rms, passMin, passMax); 77 mRMSPasses = 0; 78 } 79 TaskCase::Value* rmsVal = reinterpret_cast<TaskCase::Value*>(outputs[0]); 80 rmsVal->setInt64(rms); 81 82 return result; 83 } 84 85 86