• 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     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 }