1 /*
2 * Copyright (c) 2022-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
16 #include "daudio_manager_callback.h"
17
18 #include <cstdint>
19 #include <hdf_base.h>
20 #include <securec.h>
21
22 #include "audio_types.h"
23
24 #include "daudio_constants.h"
25 #include "daudio_errorcode.h"
26 #include "daudio_log.h"
27
28 #undef DH_LOG_TAG
29 #define DH_LOG_TAG "DAudioManagerCallback"
30
31 using OHOS::HDI::DistributedAudio::Audioext::V2_1::AudioParameter;
32
33 namespace OHOS {
34 namespace DistributedHardware {
CreateStream(int32_t streamId)35 int32_t DAudioManagerCallback::CreateStream(int32_t streamId /* for multistream */)
36 {
37 DHLOGI("Open device.");
38 CHECK_NULL_RETURN(callback_, HDF_FAILURE);
39 int32_t ret = callback_->CreateStream(streamId);
40 if (ret != DH_SUCCESS) {
41 DHLOGE("Call hdi callback failed.");
42 return HDF_FAILURE;
43 }
44 return HDF_SUCCESS;
45 }
46
DestroyStream(int32_t streamId)47 int32_t DAudioManagerCallback::DestroyStream(int32_t streamId)
48 {
49 DHLOGI("Close device.");
50 CHECK_NULL_RETURN(callback_, HDF_FAILURE);
51 if (callback_->DestroyStream(streamId) != DH_SUCCESS) {
52 DHLOGE("Rall hdi callback failed.");
53 return HDF_FAILURE;
54 }
55 return HDF_SUCCESS;
56 }
57
GetAudioParamHDF(const AudioParameter & param,AudioParamHDF & paramHDF)58 int32_t DAudioManagerCallback::GetAudioParamHDF(const AudioParameter& param, AudioParamHDF& paramHDF)
59 {
60 paramHDF.sampleRate = static_cast<AudioSampleRate>(param.sampleRate);
61 paramHDF.channelMask = static_cast<AudioChannel>(param.channelCount);
62 switch (static_cast<AudioFormat>(param.format)) {
63 case AUDIO_FORMAT_TYPE_PCM_8_BIT:
64 paramHDF.bitFormat = AudioSampleFormat::SAMPLE_U8;
65 break;
66 case AUDIO_FORMAT_TYPE_PCM_16_BIT:
67 paramHDF.bitFormat = AudioSampleFormat::SAMPLE_S16LE;
68 break;
69 case AUDIO_FORMAT_TYPE_PCM_24_BIT:
70 paramHDF.bitFormat = AudioSampleFormat::SAMPLE_S24LE;
71 break;
72 default:
73 DHLOGE("Format [%{public}" PRIu32"] does not support conversion.", param.format);
74 return HDF_FAILURE;
75 }
76 switch (static_cast<AudioCategory>(param.streamUsage)) {
77 case AUDIO_IN_MEDIA:
78 paramHDF.streamUsage = StreamUsage::STREAM_USAGE_MEDIA;
79 break;
80 case AUDIO_IN_COMMUNICATION:
81 case AUDIO_MMAP_VOIP:
82 paramHDF.streamUsage = StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION;
83 break;
84 case AUDIO_IN_RINGTONE:
85 paramHDF.streamUsage = StreamUsage::STREAM_USAGE_NOTIFICATION_RINGTONE;
86 break;
87 case AUDIO_MMAP_NOIRQ:
88 paramHDF.streamUsage = StreamUsage::STREAM_USAGE_MEDIA;
89 break;
90 default:
91 DHLOGE("Stream usage [%{public}" PRIu32"] does not support conversion.", param.streamUsage);
92 return HDF_FAILURE;
93 }
94 paramHDF.frameSize = param.frameSize;
95 paramHDF.period = param.period;
96 paramHDF.ext = param.ext;
97 paramHDF.renderFlags = static_cast<OHOS::DistributedHardware::PortOperationMode>(param.renderFlags);
98 paramHDF.capturerFlags = static_cast<OHOS::DistributedHardware::PortOperationMode>(param.capturerFlags);
99 DHLOGI("HDF Param: sample rate %{public}d, channel %{public}d, bit format %{public}d, stream "
100 "usage %{public}d, frame size %{public}" PRIu32", period %{public}" PRIu32
101 ", renderFlags %{public}d, capturerFlags %{public}d, ext {%{public}s}.", paramHDF.sampleRate,
102 paramHDF.channelMask, paramHDF.bitFormat, paramHDF.streamUsage, paramHDF.frameSize, paramHDF.period,
103 paramHDF.renderFlags, paramHDF.capturerFlags, paramHDF.ext.c_str());
104 return HDF_SUCCESS;
105 }
106
SetParameters(int32_t streamId,const AudioParameter & param)107 int32_t DAudioManagerCallback::SetParameters(int32_t streamId, const AudioParameter& param)
108 {
109 DHLOGD("Set Parameters.");
110 CHECK_NULL_RETURN(callback_, HDF_FAILURE);
111 AudioParamHDF paramHDF;
112 int32_t ret = GetAudioParamHDF(param, paramHDF);
113 if (ret != DH_SUCCESS) {
114 DHLOGE("Get audio HDF param failed.");
115 return HDF_FAILURE;
116 }
117 ret = callback_->SetParameters(streamId, paramHDF);
118 if (ret != DH_SUCCESS) {
119 DHLOGE("Call hdi callback failed.");
120 return HDF_FAILURE;
121 }
122 return HDF_SUCCESS;
123 }
124
NotifyEvent(int32_t streamId,const OHOS::HDI::DistributedAudio::Audioext::V2_1::DAudioEvent & event)125 int32_t DAudioManagerCallback::NotifyEvent(int32_t streamId,
126 const OHOS::HDI::DistributedAudio::Audioext::V2_1::DAudioEvent& event)
127 {
128 DHLOGI("Notify event.");
129 CHECK_NULL_RETURN(callback_, HDF_FAILURE);
130 AudioEvent newEvent(AudioEventType::EVENT_UNKNOWN, event.content);
131 switch (event.type) {
132 case AudioEventHDF::AUDIO_EVENT_VOLUME_SET:
133 newEvent.type = AudioEventType::VOLUME_SET;
134 break;
135 case AudioEventHDF::AUDIO_EVENT_MUTE_SET:
136 newEvent.type = AudioEventType::VOLUME_MUTE_SET;
137 break;
138 case AudioEventHDF::AUDIO_EVENT_CHANGE_PLAY_STATUS:
139 newEvent.type = AudioEventType::CHANGE_PLAY_STATUS;
140 break;
141 case AudioEventHDF::AUDIO_EVENT_MMAP_START_SPK:
142 newEvent.type = AudioEventType::MMAP_SPK_START;
143 break;
144 case AudioEventHDF::AUDIO_EVENT_MMAP_STOP_SPK:
145 newEvent.type = AudioEventType::MMAP_SPK_STOP;
146 break;
147 case AudioEventHDF::AUDIO_EVENT_MMAP_START_MIC:
148 newEvent.type = AudioEventType::MMAP_MIC_START;
149 break;
150 case AudioEventHDF::AUDIO_EVENT_MMAP_STOP_MIC:
151 newEvent.type = AudioEventType::MMAP_MIC_STOP;
152 break;
153 case AudioEventHDF::AUDIO_EVENT_START:
154 newEvent.type = AudioEventType::AUDIO_START;
155 break;
156 case AudioEventHDF::AUDIO_EVENT_STOP:
157 newEvent.type = AudioEventType::AUDIO_STOP;
158 break;
159 default:
160 DHLOGE("Unsupport event tpye.");
161 break;
162 }
163
164 int32_t ret = callback_->NotifyEvent(streamId, newEvent);
165 if (ret != DH_SUCCESS) {
166 DHLOGE("Call hdi callback failed.");
167 return HDF_FAILURE;
168 }
169 return HDF_SUCCESS;
170 }
171
WriteStreamData(int32_t streamId,const OHOS::HDI::DistributedAudio::Audioext::V2_1::AudioData & data)172 int32_t DAudioManagerCallback::WriteStreamData(int32_t streamId,
173 const OHOS::HDI::DistributedAudio::Audioext::V2_1::AudioData &data)
174 {
175 DHLOGD("Write Stream Data, audio data param frameSize is %{public}d.", data.param.frameSize);
176 if (data.param.frameSize == 0 || data.param.frameSize > DEFAULT_AUDIO_DATA_SIZE) {
177 DHLOGE("Audio data param frameSize is 0. or > 4096");
178 return HDF_FAILURE;
179 }
180
181 std::shared_ptr<AudioData> audioData = std::make_shared<AudioData>(data.param.frameSize);
182 int32_t ret = memcpy_s(audioData->Data(), audioData->Capacity(), data.data.data(), data.data.size());
183 if (ret != EOK) {
184 DHLOGE("Copy audio data failed, error code %{public}d.", ret);
185 return HDF_FAILURE;
186 }
187
188 CHECK_NULL_RETURN(callback_, HDF_FAILURE);
189 if (callback_->WriteStreamData(streamId, audioData) != DH_SUCCESS) {
190 DHLOGE("WriteStreamData failed.");
191 return HDF_FAILURE;
192 }
193 return HDF_SUCCESS;
194 }
195
ReadStreamData(int32_t streamId,OHOS::HDI::DistributedAudio::Audioext::V2_1::AudioData & data)196 int32_t DAudioManagerCallback::ReadStreamData(int32_t streamId,
197 OHOS::HDI::DistributedAudio::Audioext::V2_1::AudioData &data)
198 {
199 DHLOGD("Read stream data.");
200 std::shared_ptr<AudioData> audioData = nullptr;
201 CHECK_NULL_RETURN(callback_, HDF_FAILURE);
202 if (callback_->ReadStreamData(streamId, audioData) != DH_SUCCESS) {
203 DHLOGE("Read stream data failed.");
204 return HDF_FAILURE;
205 }
206
207 CHECK_NULL_RETURN(audioData, HDF_FAILURE);
208 data.data.assign(audioData->Data(), audioData->Data()+audioData->Capacity());
209 DHLOGD("Read stream data success.");
210 return HDF_SUCCESS;
211 }
212
ReadMmapPosition(int32_t streamId,uint64_t & frames,OHOS::HDI::DistributedAudio::Audioext::V2_1::CurrentTime & time)213 int32_t DAudioManagerCallback::ReadMmapPosition(int32_t streamId,
214 uint64_t &frames, OHOS::HDI::DistributedAudio::Audioext::V2_1::CurrentTime &time)
215 {
216 DHLOGD("Read mmap position");
217 CurrentTimeHDF timeHdf;
218 CHECK_NULL_RETURN(callback_, HDF_FAILURE);
219 if (callback_->ReadMmapPosition(streamId, frames, timeHdf) != DH_SUCCESS) {
220 DHLOGE("Read mmap position failed.");
221 return HDF_FAILURE;
222 }
223 time.tvSec = timeHdf.tvSec;
224 time.tvNSec = timeHdf.tvNSec;
225 DHLOGD("Read mmap position success.");
226 return HDF_SUCCESS;
227 }
228
RefreshAshmemInfo(int32_t streamId,int fd,int32_t ashmemLength,int32_t lengthPerTrans)229 int32_t DAudioManagerCallback::RefreshAshmemInfo(int32_t streamId, int fd, int32_t ashmemLength,
230 int32_t lengthPerTrans)
231 {
232 DHLOGD("Refresh ashmem info.");
233 CHECK_NULL_RETURN(callback_, HDF_FAILURE);
234 if (callback_->RefreshAshmemInfo(streamId, fd, ashmemLength, lengthPerTrans) != DH_SUCCESS) {
235 DHLOGE("Refresh ashmem info failed.");
236 return HDF_FAILURE;
237 }
238 DHLOGD("Refresh ashmem info success.");
239 return HDF_SUCCESS;
240 }
241
GetLatency(int32_t streamId,uint32_t & ms)242 int32_t DAudioManagerCallback::GetLatency(int32_t streamId, uint32_t& ms)
243 {
244 DHLOGD("Get latency not support yet.");
245 (void)streamId;
246 (void)ms;
247 return HDF_SUCCESS;
248 }
249
GetRenderPosition(int32_t streamId,uint64_t & frames,OHOS::HDI::DistributedAudio::Audioext::V2_1::CurrentTime & time)250 int32_t DAudioManagerCallback::GetRenderPosition(int32_t streamId, uint64_t &frames,
251 OHOS::HDI::DistributedAudio::Audioext::V2_1::CurrentTime &time)
252 {
253 DHLOGD("Get render position not support yet.");
254 (void)streamId;
255 (void)frames;
256 (void)time;
257 return HDF_SUCCESS;
258 }
259 } // DistributedHardware
260 } // OHOS
261