• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
83 #ifdef FIRST_STAGE_ONESHOT_ENABLE
84     if (!ThreadWrapper::Start("WakeUpAudioSource")) {
85         INTELL_VOICE_LOG_ERROR("failed to start wakeup source");
86         return false;
87     }
88 #else
89     std::thread t1(std::bind(&AudioSource::Run, this));
90     readThread_ = std::move(t1);
91 #endif
92     return true;
93 }
94 
Run()95 void AudioSource::Run()
96 {
97     INTELL_VOICE_LOG_INFO("enter");
98     uint32_t readCnt = 0;
99     isEnd_ = false;
100     while (isReading_.load()) {
101         if (!isEnd_ && (readCnt == bufferCnt_)) {
102             INTELL_VOICE_LOG_INFO("finish reading data");
103             isEnd_ = true;
104             if (listener_ != nullptr) {
105                 listener_->bufferEndCb_();
106             }
107         }
108 
109         if (!Read()) {
110             INTELL_VOICE_LOG_WARN("failed to read data");
111             break;
112         }
113         ++readCnt;
114     }
115 }
116 
Read()117 bool AudioSource::Read()
118 {
119     int32_t len = audioCapturer_->Read(*(buffer_.get()), minBufferSize_, 1);
120     if (len != static_cast<int32_t>(minBufferSize_)) {
121         INTELL_VOICE_LOG_ERROR("failed to read data,  len is %{public}d", len);
122         return false;
123     }
124 
125     WriteData(reinterpret_cast<char *>(buffer_.get()), minBufferSize_);
126 
127     if ((listener_ != nullptr)) {
128         listener_->readBufferCb_(buffer_.get(), minBufferSize_, isEnd_);
129     }
130     return true;
131 }
132 
Stop()133 void AudioSource::Stop()
134 {
135     INTELL_VOICE_LOG_INFO("enter");
136     if (!isReading_.load()) {
137         INTELL_VOICE_LOG_INFO("already stop");
138         return;
139     }
140 
141     MemoryGuard memoryGuard;
142 
143     isReading_.store(false);
144 #ifdef FIRST_STAGE_ONESHOT_ENABLE
145     ThreadWrapper::Join();
146 #else
147     readThread_.join();
148 #endif
149 
150     DestroyAudioDebugFile();
151 
152     if (audioCapturer_ == nullptr) {
153         INTELL_VOICE_LOG_ERROR("audioCapturer_ is nullptr");
154         return;
155     }
156 
157     if (!audioCapturer_->Stop()) {
158         INTELL_VOICE_LOG_ERROR("stop audio capturer error");
159     }
160 
161     if (!audioCapturer_->Release()) {
162         INTELL_VOICE_LOG_ERROR("release audio capturer error");
163     }
164 
165     audioCapturer_ = nullptr;
166     listener_ = nullptr;
167 }
168 }
169 }