1 /*
2 * Copyright (c) 2023 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 "audio_source.h"
16
17 #include "securec.h"
18 #include "intell_voice_log.h"
19 #include "memory_guard.h"
20 #include "array_buffer_util.h"
21
22 #define LOG_TAG "AudioSource"
23
24 using namespace OHOS::AudioStandard;
25 using namespace OHOS::IntellVoiceUtils;
26
27 namespace OHOS {
28 namespace IntellVoiceEngine {
29 static const std::string CACHE_PATH = "/data/data/intell_voice/cache/";
30
AudioSource(uint32_t minBufferSize,uint32_t bufferCnt,std::unique_ptr<AudioSourceListener> listener,const OHOS::AudioStandard::AudioCapturerOptions & capturerOptions)31 AudioSource::AudioSource(uint32_t minBufferSize, uint32_t bufferCnt,
32 std::unique_ptr<AudioSourceListener> listener, const OHOS::AudioStandard::AudioCapturerOptions &capturerOptions)
33 : minBufferSize_(minBufferSize), bufferCnt_(bufferCnt), listener_(std::move(listener))
34 {
35 capturerOptions_.streamInfo.samplingRate = capturerOptions.streamInfo.samplingRate;
36 capturerOptions_.streamInfo.encoding = capturerOptions.streamInfo.encoding;
37 capturerOptions_.streamInfo.format = capturerOptions.streamInfo.format;
38 capturerOptions_.streamInfo.channels = capturerOptions.streamInfo.channels;
39 capturerOptions_.capturerInfo.sourceType = capturerOptions.capturerInfo.sourceType;
40 capturerOptions_.capturerInfo.capturerFlags = capturerOptions.capturerInfo.capturerFlags;
41 }
42
~AudioSource()43 AudioSource::~AudioSource()
44 {
45 Stop();
46 }
47
Start()48 bool AudioSource::Start()
49 {
50 INTELL_VOICE_LOG_INFO("enter");
51 if (listener_ == nullptr) {
52 INTELL_VOICE_LOG_ERROR("listener_ is nullptr");
53 return false;
54 }
55
56 if (minBufferSize_ == 0) {
57 INTELL_VOICE_LOG_ERROR("minBufferSize_ is invalid");
58 return false;
59 }
60
61 buffer_ = std::shared_ptr<uint8_t>(new uint8_t[minBufferSize_], [](uint8_t *p) { delete[] p; });
62 if (buffer_ == nullptr) {
63 INTELL_VOICE_LOG_ERROR("malloc buffer failed");
64 return false;
65 }
66
67 audioCapturer_ = AudioCapturer::Create(capturerOptions_, CACHE_PATH);
68 if (audioCapturer_ == nullptr) {
69 INTELL_VOICE_LOG_ERROR("audioCapturer_ is nullptr");
70 return false;
71 }
72
73 if (!audioCapturer_->Start()) {
74 INTELL_VOICE_LOG_ERROR("start audio capturer failed");
75 audioCapturer_->Release();
76 audioCapturer_ = nullptr;
77 return false;
78 }
79
80 isReading_.store(true);
81 CreateAudioDebugFile("_audio_source");
82 std::thread t1(std::bind(&AudioSource::ReadThread, this));
83 readThread_ = std::move(t1);
84 return true;
85 }
86
ReadThread()87 void AudioSource::ReadThread()
88 {
89 INTELL_VOICE_LOG_INFO("enter");
90 uint32_t readCnt = 0;
91 isEnd_ = false;
92 while (isReading_.load()) {
93 if (!isEnd_ && (readCnt == bufferCnt_)) {
94 INTELL_VOICE_LOG_INFO("finish reading data");
95 isEnd_ = true;
96 if (listener_ != nullptr) {
97 listener_->bufferEndCb_();
98 }
99 }
100
101 if (!Read()) {
102 INTELL_VOICE_LOG_WARN("failed to read data");
103 break;
104 }
105 ++readCnt;
106 }
107 }
108
Read()109 bool AudioSource::Read()
110 {
111 int32_t len = audioCapturer_->Read(*(buffer_.get()), minBufferSize_, 1);
112 if (len != static_cast<int32_t>(minBufferSize_)) {
113 INTELL_VOICE_LOG_ERROR("failed to read data, len is %{public}d", len);
114 return false;
115 }
116
117 WriteData(reinterpret_cast<char *>(buffer_.get()), minBufferSize_);
118
119 if ((listener_ != nullptr)) {
120 listener_->readBufferCb_(buffer_.get(), minBufferSize_, isEnd_);
121 }
122 return true;
123 }
124
Stop()125 void AudioSource::Stop()
126 {
127 INTELL_VOICE_LOG_INFO("enter");
128 if (!isReading_.load()) {
129 INTELL_VOICE_LOG_INFO("already stop");
130 return;
131 }
132
133 MemoryGuard memoryGuard;
134
135 isReading_.store(false);
136 readThread_.join();
137
138 DestroyAudioDebugFile();
139
140 if (audioCapturer_ == nullptr) {
141 INTELL_VOICE_LOG_ERROR("audioCapturer_ is nullptr");
142 return;
143 }
144
145 if (!audioCapturer_->Stop()) {
146 INTELL_VOICE_LOG_ERROR("stop audio capturer error");
147 }
148
149 if (!audioCapturer_->Release()) {
150 INTELL_VOICE_LOG_ERROR("release audio capturer error");
151 }
152
153 audioCapturer_ = nullptr;
154 listener_ = nullptr;
155 }
156 }
157 }