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
16 #include "multimedia_audio_common.h"
17
18 #include "multimedia_audio_error.h"
19
20 namespace OHOS {
21 namespace AudioStandard {
22 namespace {
23 enum class AudioCJVolumeType {
24 VOLUMETYPE_DEFAULT = -1,
25 VOICE_CALL = 0,
26 RINGTONE = 2,
27 MEDIA = 3,
28 ALARM = 4,
29 ACCESSIBILITY = 5,
30 SYSTEM = 6,
31 VOICE_ASSISTANT = 9,
32 ULTRASONIC = 10,
33 VOLUMETYPE_MAX,
34 ALL = 100
35 };
36 }
37
GetNativeAudioVolumeType(int32_t volumeType)38 AudioVolumeType GetNativeAudioVolumeType(int32_t volumeType)
39 {
40 AudioVolumeType result = STREAM_MUSIC;
41
42 switch (static_cast<AudioCJVolumeType>(volumeType)) {
43 case AudioCJVolumeType::VOICE_CALL:
44 result = STREAM_VOICE_CALL;
45 break;
46 case AudioCJVolumeType::RINGTONE:
47 result = STREAM_RING;
48 break;
49 case AudioCJVolumeType::MEDIA:
50 result = STREAM_MUSIC;
51 break;
52 case AudioCJVolumeType::ALARM:
53 result = STREAM_ALARM;
54 break;
55 case AudioCJVolumeType::ACCESSIBILITY:
56 result = STREAM_ACCESSIBILITY;
57 break;
58 case AudioCJVolumeType::VOICE_ASSISTANT:
59 result = STREAM_VOICE_ASSISTANT;
60 break;
61 case AudioCJVolumeType::ULTRASONIC:
62 result = STREAM_ULTRASONIC;
63 break;
64 case AudioCJVolumeType::SYSTEM:
65 result = STREAM_SYSTEM;
66 break;
67 case AudioCJVolumeType::ALL:
68 result = STREAM_ALL;
69 break;
70 default:
71 result = STREAM_MUSIC;
72 break;
73 }
74
75 return result;
76 }
77
MallocCString(const std::string & origin)78 char* MallocCString(const std::string& origin)
79 {
80 if (origin.empty()) {
81 return nullptr;
82 }
83 auto len = origin.length() + 1;
84 char* res = static_cast<char*>(malloc(sizeof(char) * len));
85 if (res == nullptr) {
86 return nullptr;
87 }
88 return std::char_traits<char>::copy(res, origin.c_str(), len);
89 }
90
Convert2AudioCapturerOptions(AudioCapturerOptions & opions,const CAudioCapturerOptions & cOptions)91 void Convert2AudioCapturerOptions(AudioCapturerOptions& opions, const CAudioCapturerOptions& cOptions)
92 {
93 opions.capturerInfo.sourceType = static_cast<SourceType>(cOptions.audioCapturerInfo.source);
94 opions.streamInfo.channels = static_cast<AudioChannel>(cOptions.audioStreamInfo.channels);
95 opions.streamInfo.channelLayout = static_cast<AudioChannelLayout>(cOptions.audioStreamInfo.channelLayout);
96 opions.streamInfo.encoding = static_cast<AudioEncodingType>(cOptions.audioStreamInfo.encodingType);
97 opions.streamInfo.format = static_cast<AudioSampleFormat>(cOptions.audioStreamInfo.sampleFormat);
98 opions.streamInfo.samplingRate = static_cast<AudioSamplingRate>(cOptions.audioStreamInfo.samplingRate);
99
100 /* only support flag 0 */
101 opions.capturerInfo.capturerFlags =
102 (cOptions.audioCapturerInfo.capturerFlags != 0) ? 0 : cOptions.audioCapturerInfo.capturerFlags;
103 }
104
Convert2CAudioCapturerInfo(CAudioCapturerInfo & cInfo,const AudioCapturerInfo & capturerInfo)105 void Convert2CAudioCapturerInfo(CAudioCapturerInfo& cInfo, const AudioCapturerInfo& capturerInfo)
106 {
107 cInfo.capturerFlags = capturerInfo.capturerFlags;
108 cInfo.source = static_cast<int32_t>(capturerInfo.sourceType);
109 }
110
Convert2CAudioStreamInfo(CAudioStreamInfo & cInfo,const AudioStreamInfo & streamInfo)111 void Convert2CAudioStreamInfo(CAudioStreamInfo& cInfo, const AudioStreamInfo& streamInfo)
112 {
113 cInfo.channels = static_cast<int32_t>(streamInfo.channels);
114 cInfo.encodingType = static_cast<int32_t>(streamInfo.encoding);
115 cInfo.sampleFormat = static_cast<int32_t>(streamInfo.format);
116 cInfo.samplingRate = static_cast<int32_t>(streamInfo.samplingRate);
117 cInfo.channelLayout = static_cast<int64_t>(streamInfo.channelLayout);
118 }
119
Convert2CAudioCapturerChangeInfo(CAudioCapturerChangeInfo & cInfo,const AudioCapturerChangeInfo & changeInfo,int32_t * errorCode)120 void Convert2CAudioCapturerChangeInfo(
121 CAudioCapturerChangeInfo& cInfo, const AudioCapturerChangeInfo& changeInfo, int32_t* errorCode)
122 {
123 cInfo.muted = changeInfo.muted;
124 cInfo.streamId = changeInfo.sessionId;
125 Convert2CAudioCapturerInfo(cInfo.audioCapturerInfo, changeInfo.capturerInfo);
126 Convert2CArrDeviceDescriptorByDeviceInfo(cInfo.deviceDescriptors, changeInfo.inputDeviceInfo, errorCode);
127 }
128
Convert2CArrDeviceDescriptorByDeviceInfo(CArrDeviceDescriptor & devices,const AudioDeviceDescriptor & deviceInfo,int32_t * errorCode)129 void Convert2CArrDeviceDescriptorByDeviceInfo(
130 CArrDeviceDescriptor& devices, const AudioDeviceDescriptor& deviceInfo, int32_t* errorCode)
131 {
132 size_t deviceSize = 1;
133 int32_t mallocSize = static_cast<int32_t>(sizeof(CDeviceDescriptor) * deviceSize);
134 if (mallocSize <= 0 || mallocSize > static_cast<int32_t>(sizeof(CDeviceDescriptor) * MAX_MEM_MALLOC_SIZE)) {
135 *errorCode = CJ_ERR_SYSTEM;
136 return;
137 }
138 CDeviceDescriptor* device = static_cast<CDeviceDescriptor*>(malloc(mallocSize));
139 if (device == nullptr) {
140 *errorCode = CJ_ERR_NO_MEMORY;
141 return;
142 }
143 if (memset_s(device, mallocSize, 0, mallocSize) != EOK) {
144 *errorCode = CJ_ERR_SYSTEM;
145 free(device);
146 return;
147 }
148 devices.head = device;
149 devices.size = static_cast<int64_t>(deviceSize);
150 for (int32_t i = 0; i < static_cast<int32_t>(deviceSize); i++) {
151 Convert2CDeviceDescriptor(&(device[i]), deviceInfo, errorCode);
152 if (*errorCode != SUCCESS_CODE) {
153 return;
154 }
155 }
156 }
157
InitializeDeviceChannels(CDeviceDescriptor * device,const AudioDeviceDescriptor & deviceInfo,int32_t * errorCode)158 void InitializeDeviceChannels(CDeviceDescriptor* device, const AudioDeviceDescriptor& deviceInfo, int32_t* errorCode)
159 {
160 std::set<AudioChannel> deviceInfoChannels = deviceInfo.GetDeviceStreamInfo().GetChannels();
161 size_t channelSize = deviceInfoChannels.size();
162 if (channelSize == 0 || channelSize > MAX_MEM_MALLOC_SIZE) {
163 *errorCode = CJ_ERR_SYSTEM;
164 return;
165 }
166 int32_t mallocSize = static_cast<int32_t>(sizeof(int32_t) * channelSize);
167 if (mallocSize <= 0 || mallocSize > static_cast<int32_t>(sizeof(int32_t) * MAX_MEM_MALLOC_SIZE)) {
168 *errorCode = CJ_ERR_SYSTEM;
169 return;
170 }
171 auto channels = static_cast<int32_t*>(malloc(mallocSize));
172 if (channels == nullptr) {
173 *errorCode = CJ_ERR_NO_MEMORY;
174 return;
175 }
176
177 if (memset_s(channels, mallocSize, 0, mallocSize) != EOK) {
178 *errorCode = CJ_ERR_SYSTEM;
179 free(channels);
180 return;
181 }
182 int32_t iter = 0;
183 device->channelCounts.size = static_cast<int64_t>(channelSize);
184 device->channelCounts.head = channels;
185 for (auto channel : deviceInfoChannels) {
186 channels[iter] = static_cast<int32_t>(channel);
187 iter++;
188 }
189 }
190
InitializeDeviceRates(CDeviceDescriptor * device,const AudioDeviceDescriptor & deviceInfo,int32_t * errorCode)191 void InitializeDeviceRates(CDeviceDescriptor* device, const AudioDeviceDescriptor& deviceInfo, int32_t* errorCode)
192 {
193 size_t rateSize = deviceInfo.GetDeviceStreamInfo().samplingRate.size();
194 if (rateSize == 0 || rateSize > MAX_MEM_MALLOC_SIZE) {
195 *errorCode = CJ_ERR_SYSTEM;
196 return;
197 }
198 int32_t mallocSize = static_cast<int32_t>(sizeof(int32_t) * rateSize);
199 if (mallocSize <= 0 || mallocSize > static_cast<int32_t>(sizeof(int32_t) * MAX_MEM_MALLOC_SIZE)) {
200 *errorCode = CJ_ERR_SYSTEM;
201 return;
202 }
203 auto rates = static_cast<int32_t*>(malloc(mallocSize));
204 if (rates == nullptr) {
205 *errorCode = CJ_ERR_NO_MEMORY;
206 return;
207 }
208
209 if (memset_s(rates, mallocSize, 0, mallocSize) != EOK) {
210 *errorCode = CJ_ERR_SYSTEM;
211 free(rates);
212 return;
213 }
214 int32_t iter = 0;
215 device->sampleRates.size = static_cast<int64_t>(rateSize);
216 device->sampleRates.head = rates;
217 for (auto rate : deviceInfo.GetDeviceStreamInfo().samplingRate) {
218 rates[iter] = static_cast<int32_t>(rate);
219 iter++;
220 }
221 }
222
Convert2CDeviceDescriptor(CDeviceDescriptor * device,const AudioDeviceDescriptor & deviceInfo,int32_t * errorCode)223 void Convert2CDeviceDescriptor(CDeviceDescriptor* device, const AudioDeviceDescriptor& deviceInfo, int32_t* errorCode)
224 {
225 int32_t deviceSize = 1;
226 device->deviceRole = static_cast<int32_t>(deviceInfo.deviceRole_);
227 device->deviceType = static_cast<int32_t>(deviceInfo.deviceType_);
228 device->displayName = MallocCString(deviceInfo.displayName_);
229 device->address = MallocCString(deviceInfo.macAddress_);
230 device->name = MallocCString(deviceInfo.deviceName_);
231 device->id = deviceInfo.deviceId_;
232
233 InitializeDeviceRates(device, deviceInfo, errorCode);
234 InitializeDeviceChannels(device, deviceInfo, errorCode);
235 if (*errorCode != SUCCESS_CODE) {
236 return;
237 }
238 int32_t mallocSize = static_cast<int32_t>(sizeof(int32_t)) * deviceSize;
239 if (mallocSize <= 0 || mallocSize > static_cast<int32_t>(sizeof(int32_t) * MAX_MEM_MALLOC_SIZE)) {
240 *errorCode = CJ_ERR_SYSTEM;
241 return;
242 }
243 auto masks = static_cast<int32_t*>(malloc(mallocSize));
244 if (masks == nullptr) {
245 *errorCode = CJ_ERR_NO_MEMORY;
246 return;
247 }
248
249 if (memset_s(masks, mallocSize, 0, mallocSize) != EOK) {
250 *errorCode = CJ_ERR_SYSTEM;
251 free(masks);
252 return;
253 }
254 int32_t iter = 0;
255 device->channelMasks.size = static_cast<int64_t>(deviceSize);
256 device->channelMasks.head = masks;
257 masks[iter] = static_cast<int32_t>(deviceInfo.channelMasks_);
258
259 auto encodings = static_cast<int32_t*>(malloc(mallocSize));
260 if (encodings == nullptr) {
261 *errorCode = CJ_ERR_NO_MEMORY;
262 return;
263 }
264 if (memset_s(encodings, mallocSize, 0, mallocSize) != EOK) {
265 *errorCode = CJ_ERR_SYSTEM;
266 free(encodings);
267 return;
268 }
269 device->encodingTypes.hasValue = true;
270 device->encodingTypes.arr.size = static_cast<int64_t>(deviceSize);
271 device->encodingTypes.arr.head = encodings;
272 encodings[iter] = static_cast<int32_t>(deviceInfo.GetDeviceStreamInfo().encoding);
273 }
274
Convert2CArrDeviceDescriptor(CArrDeviceDescriptor & devices,const std::vector<std::shared_ptr<AudioDeviceDescriptor>> & deviceDescriptors,int32_t * errorCode)275 void Convert2CArrDeviceDescriptor(CArrDeviceDescriptor& devices,
276 const std::vector<std::shared_ptr<AudioDeviceDescriptor>>& deviceDescriptors, int32_t* errorCode)
277 {
278 if (deviceDescriptors.empty()) {
279 devices.head = nullptr;
280 devices.size = 0;
281 return;
282 } else {
283 auto deviceSize = deviceDescriptors.size();
284 devices.size = static_cast<int64_t>(deviceSize);
285 int32_t mallocSize = static_cast<int32_t>(sizeof(CDeviceDescriptor)) * static_cast<int32_t>(deviceSize);
286 if (mallocSize <= 0 || mallocSize > static_cast<int32_t>(sizeof(CDeviceDescriptor) * MAX_MEM_MALLOC_SIZE)) {
287 *errorCode = CJ_ERR_SYSTEM;
288 return;
289 }
290 CDeviceDescriptor* device = static_cast<CDeviceDescriptor*>(malloc(mallocSize));
291 if (device == nullptr) {
292 *errorCode = CJ_ERR_NO_MEMORY;
293 return;
294 }
295 if (memset_s(device, mallocSize, 0, mallocSize) != EOK) {
296 *errorCode = CJ_ERR_SYSTEM;
297 free(device);
298 return;
299 }
300 devices.head = device;
301 for (int32_t i = 0; i < static_cast<int32_t>(deviceSize); i++) {
302 AudioDeviceDescriptor dInfo(AudioDeviceDescriptor::DEVICE_INFO);
303 ConvertAudioDeviceDescriptor2DeviceInfo(dInfo, deviceDescriptors[i]);
304 Convert2CDeviceDescriptor(&(device[i]), dInfo, errorCode);
305 if (*errorCode != SUCCESS_CODE) {
306 return;
307 }
308 }
309 }
310 }
311
ConvertAudioDeviceDescriptor2DeviceInfo(AudioDeviceDescriptor & deviceInfo,std::shared_ptr<AudioDeviceDescriptor> audioDeviceDescriptor)312 void ConvertAudioDeviceDescriptor2DeviceInfo(
313 AudioDeviceDescriptor& deviceInfo, std::shared_ptr<AudioDeviceDescriptor> audioDeviceDescriptor)
314 {
315 deviceInfo.deviceRole_ = audioDeviceDescriptor->deviceRole_;
316 deviceInfo.deviceType_ = audioDeviceDescriptor->deviceType_;
317 deviceInfo.deviceId_ = audioDeviceDescriptor->deviceId_;
318 deviceInfo.channelMasks_ = audioDeviceDescriptor->channelMasks_;
319 deviceInfo.channelIndexMasks_ = audioDeviceDescriptor->channelIndexMasks_;
320 deviceInfo.deviceName_ = audioDeviceDescriptor->deviceName_;
321 deviceInfo.macAddress_ = audioDeviceDescriptor->macAddress_;
322 deviceInfo.interruptGroupId_ = audioDeviceDescriptor->interruptGroupId_;
323 deviceInfo.volumeGroupId_ = audioDeviceDescriptor->volumeGroupId_;
324 deviceInfo.networkId_ = audioDeviceDescriptor->networkId_;
325 deviceInfo.displayName_ = audioDeviceDescriptor->displayName_;
326 deviceInfo.audioStreamInfo_ = audioDeviceDescriptor->audioStreamInfo_;
327 }
328
FreeCDeviceDescriptor(CDeviceDescriptor & device)329 void FreeCDeviceDescriptor(CDeviceDescriptor& device)
330 {
331 free(device.address);
332 device.address = nullptr;
333 free(device.displayName);
334 device.displayName = nullptr;
335 free(device.name);
336 device.name = nullptr;
337 if (device.channelCounts.size != 0) {
338 free(device.channelCounts.head);
339 }
340 device.channelCounts.head = nullptr;
341 if (device.channelMasks.size != 0) {
342 free(device.channelMasks.head);
343 }
344 device.channelMasks.head = nullptr;
345 if (device.sampleRates.size != 0) {
346 free(device.sampleRates.head);
347 }
348 device.sampleRates.head = nullptr;
349 if (device.encodingTypes.hasValue && device.encodingTypes.arr.size != 0) {
350 free(device.encodingTypes.arr.head);
351 }
352 device.encodingTypes.arr.head = nullptr;
353 }
354
FreeCArrDeviceDescriptor(CArrDeviceDescriptor & devices)355 void FreeCArrDeviceDescriptor(CArrDeviceDescriptor& devices)
356 {
357 if (devices.head == nullptr) {
358 return;
359 }
360 for (int64_t i = 0; i < devices.size; i++) {
361 FreeCDeviceDescriptor((devices.head)[i]);
362 }
363 free(devices.head);
364 devices.head = nullptr;
365 }
366
FreeCArrAudioCapturerChangeInfo(CArrAudioCapturerChangeInfo & infos)367 void FreeCArrAudioCapturerChangeInfo(CArrAudioCapturerChangeInfo& infos)
368 {
369 if (infos.head == nullptr) {
370 return;
371 }
372 for (int64_t i = 0; i < infos.size; i++) {
373 FreeCArrDeviceDescriptor((infos.head)[i].deviceDescriptors);
374 }
375 free(infos.head);
376 infos.head = nullptr;
377 }
378
FreeCArrAudioRendererChangeInfo(CArrAudioRendererChangeInfo & infos)379 void FreeCArrAudioRendererChangeInfo(CArrAudioRendererChangeInfo& infos)
380 {
381 if (infos.head == nullptr) {
382 return;
383 }
384 for (int64_t i = 0; i < infos.size; i++) {
385 FreeCArrDeviceDescriptor((infos.head)[i].deviceDescriptors);
386 }
387 free(infos.head);
388 infos.head = nullptr;
389 }
390
Convert2AudioRendererOptions(AudioRendererOptions & opions,const CAudioRendererOptions & cOptions)391 void Convert2AudioRendererOptions(AudioRendererOptions& opions, const CAudioRendererOptions& cOptions)
392 {
393 opions.rendererInfo.streamUsage = static_cast<StreamUsage>(cOptions.audioRendererInfo.usage);
394 opions.streamInfo.channels = static_cast<AudioChannel>(cOptions.audioStreamInfo.channels);
395 opions.streamInfo.channelLayout = static_cast<AudioChannelLayout>(cOptions.audioStreamInfo.channelLayout);
396 opions.streamInfo.encoding = static_cast<AudioEncodingType>(cOptions.audioStreamInfo.encodingType);
397 opions.streamInfo.format = static_cast<AudioSampleFormat>(cOptions.audioStreamInfo.sampleFormat);
398 opions.streamInfo.samplingRate = static_cast<AudioSamplingRate>(cOptions.audioStreamInfo.samplingRate);
399 opions.privacyType = static_cast<AudioPrivacyType>(cOptions.privacyType);
400
401 /* only support flag 0 */
402 opions.rendererInfo.rendererFlags =
403 (cOptions.audioRendererInfo.rendererFlags != 0) ? 0 : cOptions.audioRendererInfo.rendererFlags;
404 }
405
Convert2AudioRendererInfo(CAudioRendererInfo & cInfo,const AudioRendererInfo & rendererInfo)406 void Convert2AudioRendererInfo(CAudioRendererInfo& cInfo, const AudioRendererInfo& rendererInfo)
407 {
408 cInfo.usage = static_cast<int32_t>(rendererInfo.streamUsage);
409 cInfo.rendererFlags = rendererInfo.rendererFlags;
410 }
411
Convert2CAudioRendererChangeInfo(CAudioRendererChangeInfo & cInfo,const AudioRendererChangeInfo & changeInfo,int32_t * errorCode)412 void Convert2CAudioRendererChangeInfo(
413 CAudioRendererChangeInfo& cInfo, const AudioRendererChangeInfo& changeInfo, int32_t* errorCode)
414 {
415 cInfo.streamId = changeInfo.sessionId;
416 Convert2CArrDeviceDescriptorByDeviceInfo(cInfo.deviceDescriptors, changeInfo.outputDeviceInfo, errorCode);
417 Convert2AudioRendererInfo(cInfo.rendererInfo, changeInfo.rendererInfo);
418 }
419 } // namespace AudioStandard
420 } // namespace OHOS
421