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
BuiltinProcessing()39 BuiltinProcessing::BuiltinProcessing()
40 : mRMSPasses(0)
41 {
42
43 }
44
45 // pass for 5 consecutive passes
rms_mva(void ** inputs,void ** outputs)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 MSG("Volume %lld low compared to min %lld max %lld", rms, passMin, passMax);
67 mRMSPasses = 0;
68 } else if (rms <= passMax) {
69 MSG("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