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