1 /*
2 * Copyright 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of 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,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #pragma once
18
19 #include <array>
20 #include <audio_utils/channels.h>
21 #include <audio_utils/primitives.h>
22 #include <climits>
23 #include <cstdlib>
24 #include <gtest/gtest.h>
25 #include <hardware/audio_effect.h>
26 #include <log/log.h>
27 #include <random>
28 #include <stdint.h>
29 #include <system/audio.h>
30 #include <vector>
31
32 namespace android {
33 template <typename T>
computeSnr(const T * ref,const T * tst,size_t count)34 static float computeSnr(const T* ref, const T* tst, size_t count) {
35 double signal{};
36 double noise{};
37
38 for (size_t i = 0; i < count; ++i) {
39 const double value(ref[i]);
40 const double diff(tst[i] - value);
41 signal += value * value;
42 noise += diff * diff;
43 }
44 // Initialized to large value to handle
45 // cases where ref and tst match exactly
46 float snr = FLT_MAX;
47 if (signal > 0.0f && noise > 0.0f) {
48 snr = 10.f * log(signal / noise);
49 }
50 return snr;
51 }
52
53 class EffectTestHelper {
54 public:
EffectTestHelper(const effect_uuid_t * uuid,size_t inChMask,size_t outChMask,size_t sampleRate,size_t frameCount,size_t loopCount)55 EffectTestHelper(const effect_uuid_t* uuid, size_t inChMask, size_t outChMask,
56 size_t sampleRate, size_t frameCount, size_t loopCount)
57 : mUuid(uuid),
58 mInChMask(inChMask),
59 mInChannelCount(audio_channel_count_from_out_mask(mInChMask)),
60 mOutChMask(outChMask),
61 mOutChannelCount(audio_channel_count_from_out_mask(mOutChMask)),
62 mSampleRate(sampleRate),
63 mFrameCount(frameCount),
64 mLoopCount(loopCount) {}
65 void createEffect();
66 void releaseEffect();
67 void setConfig();
68 void setParam(uint32_t type, uint32_t val);
69 void process(float* input, float* output);
70
71 // Corresponds to SNR for 1 bit difference between two int16_t signals
72 static constexpr float kSNRThreshold = 90.308998;
73
74 static constexpr audio_channel_mask_t kChMasks[] = {
75 AUDIO_CHANNEL_OUT_MONO, AUDIO_CHANNEL_OUT_STEREO,
76 AUDIO_CHANNEL_OUT_2POINT1, AUDIO_CHANNEL_OUT_2POINT0POINT2,
77 AUDIO_CHANNEL_OUT_QUAD, AUDIO_CHANNEL_OUT_QUAD_BACK,
78 AUDIO_CHANNEL_OUT_QUAD_SIDE, AUDIO_CHANNEL_OUT_SURROUND,
79 AUDIO_CHANNEL_INDEX_MASK_4, AUDIO_CHANNEL_OUT_2POINT1POINT2,
80 AUDIO_CHANNEL_OUT_3POINT0POINT2, AUDIO_CHANNEL_OUT_PENTA,
81 AUDIO_CHANNEL_INDEX_MASK_5, AUDIO_CHANNEL_OUT_3POINT1POINT2,
82 AUDIO_CHANNEL_OUT_5POINT1, AUDIO_CHANNEL_OUT_5POINT1_BACK,
83 AUDIO_CHANNEL_OUT_5POINT1_SIDE, AUDIO_CHANNEL_INDEX_MASK_6,
84 AUDIO_CHANNEL_OUT_6POINT1, AUDIO_CHANNEL_INDEX_MASK_7,
85 AUDIO_CHANNEL_OUT_5POINT1POINT2, AUDIO_CHANNEL_OUT_7POINT1,
86 AUDIO_CHANNEL_INDEX_MASK_8, AUDIO_CHANNEL_INDEX_MASK_9,
87 AUDIO_CHANNEL_INDEX_MASK_10, AUDIO_CHANNEL_INDEX_MASK_11,
88 AUDIO_CHANNEL_INDEX_MASK_12, AUDIO_CHANNEL_INDEX_MASK_13,
89 AUDIO_CHANNEL_INDEX_MASK_14, AUDIO_CHANNEL_INDEX_MASK_15,
90 AUDIO_CHANNEL_INDEX_MASK_16, AUDIO_CHANNEL_INDEX_MASK_17,
91 AUDIO_CHANNEL_INDEX_MASK_18, AUDIO_CHANNEL_INDEX_MASK_19,
92 AUDIO_CHANNEL_INDEX_MASK_20, AUDIO_CHANNEL_INDEX_MASK_21,
93 AUDIO_CHANNEL_INDEX_MASK_22, AUDIO_CHANNEL_INDEX_MASK_23,
94 AUDIO_CHANNEL_INDEX_MASK_24,
95 };
96
97 static constexpr size_t kNumChMasks = std::size(kChMasks);
98
99 static constexpr size_t kSampleRates[] = {8000, 11025, 12000, 16000, 22050, 24000, 32000,
100 44100, 48000, 88200, 96000, 176400, 192000};
101
102 static constexpr size_t kNumSampleRates = std::size(kSampleRates);
103
104 static constexpr size_t kFrameCounts[] = {4, 2048};
105
106 static constexpr size_t kNumFrameCounts = std::size(kFrameCounts);
107
108 static constexpr size_t kLoopCounts[] = {1, 4};
109
110 static constexpr size_t kNumLoopCounts = std::size(kLoopCounts);
111
112 private:
113 const effect_uuid_t* mUuid;
114 const size_t mInChMask;
115 const size_t mInChannelCount;
116 const size_t mOutChMask;
117 const size_t mOutChannelCount;
118 const size_t mSampleRate;
119 const size_t mFrameCount;
120 const size_t mLoopCount;
121 effect_handle_t mEffectHandle{};
122 };
123 } // namespace android
124