1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <thread>
16
17 #include <memory>
18
19 #include <securec.h>
20 #include "gtest/gtest.h"
21
22 #include "audio_capturer.h"
23 #include "audio_errors.h"
24 #include "audio_info.h"
25 #include "audio_capturer_log.h"
26 #include "audio_renderer.h"
27
28 using namespace std;
29 using namespace testing::ext;
30
31 namespace OHOS {
32 namespace AudioStandard {
33 namespace {
34 } // namespace
35
36 class InnerCapturerUnitTest : public testing::Test {
37 public:
38 // SetUpTestCase: Called before all test cases
39 static void SetUpTestCase(void);
40 // TearDownTestCase: Called after all test case
41 static void TearDownTestCase(void);
42 // SetUp: Called before each test cases
43 void SetUp(void);
44 // TearDown: Called after each test cases
45 void TearDown(void);
46 // Init Capturer Options
47 static AudioCapturerOptions GetCapturerOptions(AudioPlaybackCaptureConfig config);
48 };
49
SetUpTestCase(void)50 void InnerCapturerUnitTest::SetUpTestCase(void) {}
TearDownTestCase(void)51 void InnerCapturerUnitTest::TearDownTestCase(void) {}
SetUp(void)52 void InnerCapturerUnitTest::SetUp(void) {}
TearDown(void)53 void InnerCapturerUnitTest::TearDown(void) {}
54
55 class MockRenderer : public AudioRendererWriteCallback, public std::enable_shared_from_this<MockRenderer> {
56 public:
MockRenderer()57 MockRenderer() {};
58
59 ~MockRenderer();
60
61 void OnWriteData(size_t length) override;
62
63 bool InitRenderer(StreamUsage usage, AudioPrivacyType type);
64
65 bool Start();
66
67 bool Stop();
68
69 private:
70 void InitBuffer();
71 private:
72 std::unique_ptr<AudioRenderer> audioRenderer_ = nullptr;
73 std::unique_ptr<uint8_t []> cacheBuffer_ = nullptr;
74 size_t cacheBufferSize_ = 0;
75 size_t bytesAlreadyWrite_ = 0;
76 };
77
~MockRenderer()78 MockRenderer::~MockRenderer()
79 {
80 if (audioRenderer_ != nullptr) {
81 audioRenderer_->Release();
82 }
83 }
84
OnWriteData(size_t length)85 void MockRenderer::OnWriteData(size_t length)
86 {
87 if (audioRenderer_ == nullptr) {
88 return;
89 }
90 BufferDesc buffer = { nullptr, 0, 0};
91 audioRenderer_->GetBufferDesc(buffer);
92 if (buffer.buffer == nullptr) {
93 return ;
94 }
95 if (length > buffer.bufLength) {
96 buffer.dataLength = buffer.bufLength;
97 } else {
98 buffer.dataLength = length;
99 }
100
101 int ret = memcpy_s(static_cast<void *>(buffer.buffer), buffer.dataLength,
102 static_cast<void *>(cacheBuffer_.get()), cacheBufferSize_);
103 if (ret != EOK) {
104 AUDIO_ERR_LOG("OnWriteData failed");
105 }
106
107 bytesAlreadyWrite_ += buffer.dataLength;
108 audioRenderer_->Enqueue(buffer);
109 }
110
InitBuffer()111 void MockRenderer::InitBuffer()
112 {
113 cacheBuffer_ = std::make_unique<uint8_t []>(cacheBufferSize_);
114 const int channels = 2; // 2 channels
115 const int samplePerChannel = cacheBufferSize_ / channels; // 1920 for 20ms
116
117 int16_t *signalData = reinterpret_cast<int16_t *>(cacheBuffer_.get());
118 int16_t bound = 10;
119 for (int idx = 0; idx < samplePerChannel; idx++) {
120 signalData[channels * idx] = bound + static_cast<int16_t>(sinf(2.0f * static_cast<float>(M_PI) * idx /
121 samplePerChannel) * (SHRT_MAX - bound));
122 for (int c = 1; c < channels; c++) {
123 signalData[channels * idx + c] = signalData[channels * idx];
124 }
125 }
126 }
127
InitRenderer(StreamUsage usage,AudioPrivacyType type)128 bool MockRenderer::InitRenderer(StreamUsage usage, AudioPrivacyType type)
129 {
130 AudioRendererOptions rendererOptions = {};
131 rendererOptions.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
132 rendererOptions.streamInfo.samplingRate = AudioSamplingRate::SAMPLE_RATE_48000;
133 rendererOptions.streamInfo.format = AudioSampleFormat::SAMPLE_S16LE;
134 rendererOptions.streamInfo.channels = AudioChannel::STEREO;
135
136 rendererOptions.rendererInfo.contentType = ContentType::CONTENT_TYPE_UNKNOWN;
137 rendererOptions.rendererInfo.streamUsage = usage;
138 rendererOptions.rendererInfo.rendererFlags = 0;
139
140 rendererOptions.privacyType = type;
141
142 audioRenderer_ = AudioRenderer::Create(rendererOptions);
143 if (audioRenderer_ == nullptr) {
144 AUDIO_ERR_LOG("RenderCallbackTest: Renderer create failed");
145 return false;
146 }
147
148 size_t targetSize = 0;
149 int32_t ret = audioRenderer_->GetBufferSize(targetSize);
150
151 AUDIO_INFO_LOG("RenderCallbackTest: Playback renderer created");
152 if (audioRenderer_->SetRenderMode(RENDER_MODE_CALLBACK)) {
153 AUDIO_ERR_LOG("RenderCallbackTest: SetRenderMode failed");
154 return false;
155 }
156
157 if (ret == 0 && targetSize != 0) {
158 size_t bufferDuration = 20; // 20 -> 20ms
159 audioRenderer_->SetBufferDuration(bufferDuration);
160 cacheBufferSize_ = targetSize;
161 InitBuffer();
162 } else {
163 AUDIO_ERR_LOG("Init renderer failed size:%{public}zu, ret:%{public}d", targetSize, ret);
164 return false;
165 }
166
167 if (audioRenderer_->SetRendererWriteCallback(shared_from_this())) {
168 AUDIO_ERR_LOG("RenderCallbackTest: SetRendererWriteCallback failed");
169 return false;
170 }
171 return true;
172 }
173
Start()174 bool MockRenderer::Start()
175 {
176 if (audioRenderer_ == nullptr) {
177 return false;
178 }
179
180 return audioRenderer_->Start();
181 }
182
183
Stop()184 bool MockRenderer::Stop()
185 {
186 if (audioRenderer_ == nullptr) {
187 return false;
188 }
189
190 return audioRenderer_->Stop();
191 }
192
GetCapturerOptions(AudioPlaybackCaptureConfig config)193 AudioCapturerOptions InnerCapturerUnitTest::GetCapturerOptions(AudioPlaybackCaptureConfig config)
194 {
195 AudioCapturerOptions capturerOptions;
196
197 capturerOptions.streamInfo.samplingRate = AudioSamplingRate::SAMPLE_RATE_48000;
198 capturerOptions.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
199 capturerOptions.streamInfo.format = AudioSampleFormat::SAMPLE_S16LE;
200 capturerOptions.streamInfo.channels = AudioChannel::STEREO;
201
202 capturerOptions.capturerInfo.sourceType = SourceType::SOURCE_TYPE_PLAYBACK_CAPTURE;
203 capturerOptions.capturerInfo.capturerFlags = 0;
204
205 capturerOptions.playbackCaptureConfig = config;
206
207 return capturerOptions;
208 }
209
210 } // namespace AudioStandard
211 } // namespace OHOS
212