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