• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "wakeup_source_process.h"
16 #include "intell_voice_log.h"
17 
18 #define LOG_TAG "WakeupSourceProc"
19 
20 using namespace OHOS::IntellVoiceUtils;
21 
22 namespace OHOS {
23 namespace IntellVoiceEngine {
24 static constexpr uint32_t WAIT_TIME = 1000;  // 1000ms
25 static constexpr uint32_t CHANNEL_CNT_1 = 1;
26 static constexpr uint32_t CHANNEL_CNT_4 = 4;
27 static constexpr uint32_t MAX_CHANNEL_CNT = 4;
28 static const std::string WRITE_SOURCE = "_write_source";
29 static const std::string READ_SOURCE = "_read_source";
30 
~WakeupSourceProcess()31 WakeupSourceProcess::~WakeupSourceProcess()
32 {
33     Release();
34 }
35 
Init(uint32_t channelCnt)36 void WakeupSourceProcess::Init(uint32_t channelCnt)
37 {
38     if (channelCnt_ != 0) {
39         INTELL_VOICE_LOG_WARN("need to release before init, channel cnt:%{public}u", channelCnt_);
40         Release();
41     }
42     for (uint32_t i = 0; i < channelCnt; i++) {
43         auto queue = std::make_unique<Uint8ArrayBufferQueue>();
44         if (queue == nullptr) {
45             INTELL_VOICE_LOG_ERROR("failed to create buffer queue");
46             return;
47         }
48         queue->Init();
49         bufferQueue_.push_back(std::move(queue));
50     }
51     channelCnt_ = channelCnt;
52     InitDebugFile(channelCnt);
53 }
54 
Write(const std::vector<std::vector<uint8_t>> & audioData)55 void WakeupSourceProcess::Write(const std::vector<std::vector<uint8_t>> &audioData)
56 {
57     if ((static_cast<uint32_t>(audioData.size()) != channelCnt_) ||
58         (static_cast<uint32_t>(bufferQueue_.size()) != channelCnt_)) {
59         INTELL_VOICE_LOG_ERROR("data size:%{public}u, queue size:%{public}u, channel cnt:%{public}u",
60             static_cast<uint32_t>(audioData.size()), static_cast<uint32_t>(bufferQueue_.size()), channelCnt_);
61         return;
62     }
63 
64     if (channelCnt_ == CHANNEL_CNT_1) {
65         WriteChannelData(audioData[CHANNEL_ID_0], CHANNEL_ID_0);
66     } else if (channelCnt_ == CHANNEL_CNT_4) {
67         WriteChannelData(audioData[CHANNEL_ID_0], CHANNEL_ID_0);
68         WriteChannelData(audioData[CHANNEL_ID_1], CHANNEL_ID_1);
69         WriteChannelData(audioData[CHANNEL_ID_2], CHANNEL_ID_2);
70         WriteChannelData(audioData[CHANNEL_ID_3], CHANNEL_ID_3);
71     } else {
72         INTELL_VOICE_LOG_WARN("not support channel cnt:%{public}u", channelCnt_);
73     }
74 }
75 
Read(std::vector<uint8_t> & data,int32_t readChannel)76 int32_t WakeupSourceProcess::Read(std::vector<uint8_t> &data, int32_t readChannel)
77 {
78     INTELL_VOICE_LOG_DEBUG("enter, read channel:%{public}d", readChannel);
79     if ((readChannel == 0) || (readChannel >= (0x1 << MAX_CHANNEL_CNT))) {
80         return -1;
81     }
82 
83     for (uint32_t i = 0; i < CHANNEL_CNT_4; i++) {
84         if (!(readChannel & (0x1 << i))) {
85             continue;
86         }
87         if (!ReadChannelData(data, i)) {
88             return -1;
89         }
90     }
91 
92     return 0;
93 }
94 
Release()95 void WakeupSourceProcess::Release()
96 {
97     for (auto &queue : bufferQueue_) {
98         queue ->Uninit();
99     }
100     std::vector<std::unique_ptr<Uint8ArrayBufferQueue>>().swap(bufferQueue_);
101     ReleaseDebugFile();
102     channelCnt_ = 0;
103 }
104 
WriteChannelData(const std::vector<uint8_t> & channelData,uint32_t channelId)105 void WakeupSourceProcess::WriteChannelData(const std::vector<uint8_t> &channelData, uint32_t channelId)
106 {
107     if ((channelId >= bufferQueue_.size()) || (bufferQueue_[channelId] == nullptr)) {
108         INTELL_VOICE_LOG_ERROR("no buffer queue, channel id:%{public}d", channelId);
109         return;
110     }
111 
112     auto arrayBuffer = CreateArrayBuffer<uint8_t>(channelData.size(), &channelData[0]);
113     if (arrayBuffer == nullptr) {
114         INTELL_VOICE_LOG_ERROR("failed to create array buffer");
115         return;
116     }
117     if (!bufferQueue_[channelId]->Push(std::move(arrayBuffer), false)) {
118         return;
119     }
120 
121     WriteDebugData(writeDebug_, channelData, channelId);
122 }
123 
ReadChannelData(std::vector<uint8_t> & channelData,uint32_t channelId)124 bool WakeupSourceProcess::ReadChannelData(std::vector<uint8_t> &channelData, uint32_t channelId)
125 {
126     if ((channelId >= bufferQueue_.size()) || (bufferQueue_[channelId] == nullptr)) {
127         INTELL_VOICE_LOG_ERROR("no buffer queue, channel id:%{public}d", channelId);
128         return false;
129     }
130 
131     std::unique_ptr<Uint8ArrayBuffer> arrayBuffer = nullptr;
132     bufferQueue_[channelId]->PopUntilTimeout(WAIT_TIME, arrayBuffer);
133     if (arrayBuffer == nullptr) {
134         INTELL_VOICE_LOG_ERROR("failed to pop data");
135         return false;
136     }
137 
138     channelData.insert(channelData.end(), arrayBuffer->GetData(), arrayBuffer->GetData() + arrayBuffer->GetSize());
139     WriteDebugData(readDebug_, channelData, channelId);
140     return true;
141 }
142 
InitDebugFile(uint32_t channelCnt)143 void WakeupSourceProcess::InitDebugFile(uint32_t channelCnt)
144 {
145     for (uint32_t i = 0; i < channelCnt; i++) {
146         auto writeObj = std::make_shared<AudioDebug>();
147         auto readObj = std::make_shared<AudioDebug>();
148         if ((writeObj == nullptr) || (readObj == nullptr)) {
149             INTELL_VOICE_LOG_ERROR("failed to create audio debug obj");
150             return;
151         }
152 
153         writeObj->CreateAudioDebugFile(WRITE_SOURCE + std::to_string(i));
154         readObj->CreateAudioDebugFile(READ_SOURCE + std::to_string(i));
155         writeDebug_.emplace_back(writeObj);
156         readDebug_.emplace_back(readObj);
157     }
158 }
159 
WriteDebugData(const std::vector<std::shared_ptr<AudioDebug>> & debugVec,const std::vector<uint8_t> & channelData,uint32_t channelId)160 void WakeupSourceProcess::WriteDebugData(const std::vector<std::shared_ptr<AudioDebug>> &debugVec,
161     const std::vector<uint8_t> &channelData, uint32_t channelId)
162 {
163     if ((channelId >= debugVec.size()) || (debugVec[channelId] == nullptr)) {
164         INTELL_VOICE_LOG_ERROR("no debug obj, channel id:%{public}d", channelId);
165         return;
166     }
167 
168     debugVec[channelId]->WriteData(reinterpret_cast<const char *>(channelData.data()), channelData.size());
169 }
170 
ReleaseDebugFile()171 void WakeupSourceProcess::ReleaseDebugFile()
172 {
173     for (auto writeObj : writeDebug_) {
174         writeObj->DestroyAudioDebugFile();
175     }
176     for (auto readObj : readDebug_) {
177         readObj->DestroyAudioDebugFile();
178     }
179     writeDebug_.clear();
180     readDebug_.clear();
181 }
182 }
183 }
184