1 /*
2 * Copyright (c) 2023-2025 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 #ifndef LOG_TAG
16 #define LOG_TAG "IAudioStream"
17 #endif
18
19 #include "i_audio_stream.h"
20 #include <map>
21
22 #include "audio_errors.h"
23 #include "audio_service_log.h"
24 #include "audio_utils.h"
25 #include "audio_policy_manager.h"
26 #include "capturer_in_client.h"
27 #include "renderer_in_client.h"
28
29 #ifdef SUPPORT_LOW_LATENCY
30 #include "fast_audio_stream.h"
31 #endif
32
33 namespace OHOS {
34 namespace AudioStandard {
35 const std::map<std::pair<ContentType, StreamUsage>, AudioStreamType> streamTypeMap_ = IAudioStream::CreateStreamMap();
36 // Supported audio parameters for fast audio stream
37 const std::vector<AudioSamplingRate> AUDIO_FAST_STREAM_SUPPORTED_SAMPLING_RATES {
38 SAMPLE_RATE_48000,
39 };
40
41 const std::vector<AudioChannel> AUDIO_FAST_STREAM_SUPPORTED_CHANNELS {
42 MONO,
43 STEREO,
44 };
45
46 const std::vector<AudioSampleFormat> AUDIO_FAST_STREAM_SUPPORTED_FORMATS {
47 SAMPLE_S16LE,
48 SAMPLE_S32LE,
49 SAMPLE_F32LE
50 };
51
CreateStreamMap()52 std::map<std::pair<ContentType, StreamUsage>, AudioStreamType> IAudioStream::CreateStreamMap()
53 {
54 std::map<std::pair<ContentType, StreamUsage>, AudioStreamType> streamMap;
55 // Mapping relationships from content and usage to stream type in design
56 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_UNKNOWN)] = STREAM_MUSIC;
57 streamMap[std::make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_VOICE_COMMUNICATION;
58 streamMap[std::make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_VIDEO_COMMUNICATION)] = STREAM_VOICE_COMMUNICATION;
59 streamMap[std::make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_VOICE_MODEM_COMMUNICATION)] = STREAM_VOICE_CALL;
60 streamMap[std::make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_VOICE_CALL_ASSISTANT)] = STREAM_VOICE_CALL_ASSISTANT;
61 streamMap[std::make_pair(CONTENT_TYPE_PROMPT, STREAM_USAGE_SYSTEM)] = STREAM_SYSTEM;
62 streamMap[std::make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_RING;
63 streamMap[std::make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_MEDIA)] = STREAM_MUSIC;
64 streamMap[std::make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_MEDIA)] = STREAM_MOVIE;
65 streamMap[std::make_pair(CONTENT_TYPE_GAME, STREAM_USAGE_MEDIA)] = STREAM_GAME;
66 streamMap[std::make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_MEDIA)] = STREAM_SPEECH;
67 streamMap[std::make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_ALARM)] = STREAM_ALARM;
68 streamMap[std::make_pair(CONTENT_TYPE_PROMPT, STREAM_USAGE_NOTIFICATION)] = STREAM_NOTIFICATION;
69 streamMap[std::make_pair(CONTENT_TYPE_PROMPT, STREAM_USAGE_ENFORCED_TONE)] = STREAM_SYSTEM_ENFORCED;
70 streamMap[std::make_pair(CONTENT_TYPE_DTMF, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_DTMF;
71 streamMap[std::make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_VOICE_ASSISTANT;
72 streamMap[std::make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_ACCESSIBILITY)] = STREAM_ACCESSIBILITY;
73 streamMap[std::make_pair(CONTENT_TYPE_ULTRASONIC, STREAM_USAGE_SYSTEM)] = STREAM_ULTRASONIC;
74
75 // Old mapping relationships from content and usage to stream type
76 streamMap[std::make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_VOICE_ASSISTANT;
77 streamMap[std::make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_UNKNOWN)] = STREAM_NOTIFICATION;
78 streamMap[std::make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_MEDIA)] = STREAM_NOTIFICATION;
79 streamMap[std::make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_RING;
80 streamMap[std::make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_UNKNOWN)] = STREAM_RING;
81 streamMap[std::make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_MEDIA)] = STREAM_RING;
82 streamMap[std::make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_RING;
83
84 IAudioStream::CreateStreamMap(streamMap);
85 return streamMap;
86 }
87
CreateStreamMap(std::map<std::pair<ContentType,StreamUsage>,AudioStreamType> & streamMap)88 void IAudioStream::CreateStreamMap(std::map<std::pair<ContentType, StreamUsage>, AudioStreamType> &streamMap)
89 {
90 // Only use stream usage to choose stream type
91 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_MEDIA)] = STREAM_MUSIC;
92 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_MUSIC)] = STREAM_MUSIC;
93 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_VOICE_COMMUNICATION;
94 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VIDEO_COMMUNICATION)] = STREAM_VOICE_COMMUNICATION;
95 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VOICE_MODEM_COMMUNICATION)] = STREAM_VOICE_CALL;
96 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_VOICE_ASSISTANT;
97 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_ALARM)] = STREAM_ALARM;
98 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VOICE_MESSAGE)] = STREAM_VOICE_MESSAGE;
99 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_RING;
100 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_RINGTONE)] = STREAM_RING;
101 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_NOTIFICATION)] = STREAM_NOTIFICATION;
102 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_ACCESSIBILITY)] = STREAM_ACCESSIBILITY;
103 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_SYSTEM)] = STREAM_SYSTEM;
104 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_MOVIE)] = STREAM_MOVIE;
105 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_GAME)] = STREAM_GAME;
106 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_AUDIOBOOK)] = STREAM_SPEECH;
107 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_NAVIGATION)] = STREAM_NAVIGATION;
108 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_DTMF)] = STREAM_DTMF;
109 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_ENFORCED_TONE)] = STREAM_SYSTEM_ENFORCED;
110 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_ULTRASONIC)] = STREAM_ULTRASONIC;
111 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VOICE_RINGTONE)] = STREAM_VOICE_RING;
112 streamMap[std::make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VOICE_CALL_ASSISTANT)] = STREAM_VOICE_CALL_ASSISTANT;
113 }
114
GetStreamType(ContentType contentType,StreamUsage streamUsage)115 AudioStreamType IAudioStream::GetStreamType(ContentType contentType, StreamUsage streamUsage)
116 {
117 AudioStreamType streamType = STREAM_MUSIC;
118 auto pos = streamTypeMap_.find(std::make_pair(contentType, streamUsage));
119 if (pos != streamTypeMap_.end()) {
120 streamType = pos->second;
121 }
122
123 if (streamType == STREAM_MEDIA) {
124 streamType = STREAM_MUSIC;
125 }
126
127 return streamType;
128 }
129
GetByteSizePerFrame(const AudioStreamParams & params,size_t & result)130 int32_t IAudioStream::GetByteSizePerFrame(const AudioStreamParams ¶ms, size_t &result)
131 {
132 result = 0;
133 size_t bitWidthSize = 0;
134 switch (params.format) {
135 case SAMPLE_U8:
136 bitWidthSize = 1; // size is 1
137 break;
138 case SAMPLE_S16LE:
139 bitWidthSize = 2; // size is 2
140 break;
141 case SAMPLE_S24LE:
142 bitWidthSize = 3; // size is 3
143 break;
144 case SAMPLE_S32LE:
145 bitWidthSize = 4; // size is 4
146 break;
147 case SAMPLE_F32LE:
148 bitWidthSize = 4; // size is 4
149 break;
150 default:
151 return ERR_INVALID_PARAM;
152 break;
153 }
154
155 if (params.channels < 1 || params.channels > 16) { // 1 is min channel size, 16 is max channel size
156 return ERR_INVALID_PARAM;
157 }
158 result = bitWidthSize * static_cast<size_t>(params.channels);
159 return SUCCESS;
160 }
161
IsStreamSupported(int32_t streamFlags,const AudioStreamParams & params)162 bool IAudioStream::IsStreamSupported(int32_t streamFlags, const AudioStreamParams ¶ms)
163 {
164 // 0 for normal stream
165 if (streamFlags == 0) {
166 return true;
167 }
168 // 1 for fast stream
169 if (streamFlags == STREAM_FLAG_FAST) {
170 // check audio sample rate
171 AudioSamplingRate samplingRate = static_cast<AudioSamplingRate>(params.samplingRate);
172 auto rateItem = std::find(AUDIO_FAST_STREAM_SUPPORTED_SAMPLING_RATES.begin(),
173 AUDIO_FAST_STREAM_SUPPORTED_SAMPLING_RATES.end(), samplingRate);
174 if (rateItem == AUDIO_FAST_STREAM_SUPPORTED_SAMPLING_RATES.end()) {
175 AUDIO_WARNING_LOG("Sampling rate %{public}d does not meet the requirements", samplingRate);
176 return false;
177 }
178
179 // check audio channel
180 AudioChannel channels = static_cast<AudioChannel>(params.channels);
181 auto channelItem = std::find(AUDIO_FAST_STREAM_SUPPORTED_CHANNELS.begin(),
182 AUDIO_FAST_STREAM_SUPPORTED_CHANNELS.end(), channels);
183 if (channelItem == AUDIO_FAST_STREAM_SUPPORTED_CHANNELS.end()) {
184 AUDIO_WARNING_LOG("Audio channel %{public}d does not meet the requirements", channels);
185 return false;
186 }
187
188 // check audio sample format
189 AudioSampleFormat format = static_cast<AudioSampleFormat>(params.format);
190 auto formatItem = std::find(AUDIO_FAST_STREAM_SUPPORTED_FORMATS.begin(),
191 AUDIO_FAST_STREAM_SUPPORTED_FORMATS.end(), format);
192 if (formatItem == AUDIO_FAST_STREAM_SUPPORTED_FORMATS.end()) {
193 AUDIO_WARNING_LOG("Audio sample format %{public}d does not meet the requirements", format);
194 return false;
195 }
196 }
197 return true;
198 }
199
GetPlaybackStream(StreamClass streamClass,AudioStreamParams params,AudioStreamType eStreamType,int32_t appUid)200 std::shared_ptr<IAudioStream> IAudioStream::GetPlaybackStream(StreamClass streamClass, AudioStreamParams params,
201 AudioStreamType eStreamType, int32_t appUid)
202 {
203 Trace trace("IAudioStream::GetPlaybackStream");
204 if (streamClass == FAST_STREAM || streamClass == VOIP_STREAM) {
205 #ifdef SUPPORT_LOW_LATENCY
206 AUDIO_INFO_LOG("Create fast playback stream");
207 return std::make_shared<FastAudioStream>(eStreamType, AUDIO_MODE_PLAYBACK, appUid);
208 #else
209 (void)params;
210 AUDIO_INFO_LOG("Unsupport create fast playback stream, so create ipc playback stream");
211 return RendererInClient::GetInstance(eStreamType, appUid);
212 #endif
213 }
214
215 if (streamClass == PA_STREAM) {
216 AUDIO_INFO_LOG("Create ipc playback stream");
217 return RendererInClient::GetInstance(eStreamType, appUid);
218 }
219 return nullptr;
220 }
221
GetRecordStream(StreamClass streamClass,AudioStreamParams params,AudioStreamType eStreamType,int32_t appUid)222 std::shared_ptr<IAudioStream> IAudioStream::GetRecordStream(StreamClass streamClass, AudioStreamParams params,
223 AudioStreamType eStreamType, int32_t appUid)
224 {
225 Trace trace("IAudioStream::GetRecordStream");
226 if (streamClass == FAST_STREAM || streamClass == VOIP_STREAM) {
227 #ifdef SUPPORT_LOW_LATENCY
228 AUDIO_INFO_LOG("Create fast record stream");
229 return std::make_shared<FastAudioStream>(eStreamType, AUDIO_MODE_RECORD, appUid);
230 #else
231 (void)params;
232 AUDIO_INFO_LOG("Unsupport create fast record stream, so create ipc record stream");
233 return CapturerInClient::GetInstance(eStreamType, appUid);
234 #endif
235 }
236 if (streamClass == PA_STREAM) {
237 AUDIO_INFO_LOG("Create ipc record stream");
238 return CapturerInClient::GetInstance(eStreamType, appUid);
239 }
240 return nullptr;
241 }
242
IsFormatValid(uint8_t format)243 bool IAudioStream::IsFormatValid(uint8_t format)
244 {
245 bool isValidFormat = (find(AUDIO_SUPPORTED_FORMATS.begin(), AUDIO_SUPPORTED_FORMATS.end(), format)
246 != AUDIO_SUPPORTED_FORMATS.end());
247 AUDIO_DEBUG_LOG("AudioStream: IsFormatValid: %{public}s", isValidFormat ? "true" : "false");
248 return isValidFormat;
249 }
250
IsRendererChannelValid(uint8_t channel)251 bool IAudioStream::IsRendererChannelValid(uint8_t channel)
252 {
253 bool isValidChannel = (find(RENDERER_SUPPORTED_CHANNELS.begin(), RENDERER_SUPPORTED_CHANNELS.end(), channel)
254 != RENDERER_SUPPORTED_CHANNELS.end());
255 AUDIO_DEBUG_LOG("AudioStream: IsChannelValid: %{public}s", isValidChannel ? "true" : "false");
256 return isValidChannel;
257 }
258
IsCapturerChannelValid(uint8_t channel)259 bool IAudioStream::IsCapturerChannelValid(uint8_t channel)
260 {
261 bool isValidChannel = (find(CAPTURER_SUPPORTED_CHANNELS.begin(), CAPTURER_SUPPORTED_CHANNELS.end(), channel)
262 != CAPTURER_SUPPORTED_CHANNELS.end());
263 AUDIO_DEBUG_LOG("AudioStream: IsChannelValid: %{public}s", isValidChannel ? "true" : "false");
264 return isValidChannel;
265 }
266
IsEncodingTypeValid(uint8_t encodingType)267 bool IAudioStream::IsEncodingTypeValid(uint8_t encodingType)
268 {
269 bool isValidEncodingType
270 = (find(AUDIO_SUPPORTED_ENCODING_TYPES.begin(), AUDIO_SUPPORTED_ENCODING_TYPES.end(), encodingType)
271 != AUDIO_SUPPORTED_ENCODING_TYPES.end());
272 AUDIO_DEBUG_LOG("AudioStream: IsEncodingTypeValid: %{public}s", isValidEncodingType ? "true" : "false");
273 return isValidEncodingType;
274 }
275
IsSamplingRateValid(uint32_t samplingRate)276 bool IAudioStream::IsSamplingRateValid(uint32_t samplingRate)
277 {
278 bool isValidSamplingRate
279 = (find(AUDIO_SUPPORTED_SAMPLING_RATES.begin(), AUDIO_SUPPORTED_SAMPLING_RATES.end(), samplingRate)
280 != AUDIO_SUPPORTED_SAMPLING_RATES.end());
281 AUDIO_DEBUG_LOG("AudioStream: IsSamplingRateValid: %{public}s", isValidSamplingRate ? "true" : "false");
282 return isValidSamplingRate;
283 }
284
IsRendererChannelLayoutValid(uint64_t channelLayout)285 bool IAudioStream::IsRendererChannelLayoutValid(uint64_t channelLayout)
286 {
287 bool isValidRendererChannelLayout = (find(RENDERER_SUPPORTED_CHANNELLAYOUTS.begin(),
288 RENDERER_SUPPORTED_CHANNELLAYOUTS.end(), channelLayout) != RENDERER_SUPPORTED_CHANNELLAYOUTS.end());
289 AUDIO_DEBUG_LOG("AudioStream: isValidRendererChannelLayout: %{public}s",
290 isValidRendererChannelLayout ? "true" : "false");
291 return isValidRendererChannelLayout;
292 }
293
IsCapturerChannelLayoutValid(uint64_t channelLayout)294 bool IAudioStream::IsCapturerChannelLayoutValid(uint64_t channelLayout)
295 {
296 bool isValidCapturerChannelLayout = IsRendererChannelLayoutValid(channelLayout);
297 AUDIO_DEBUG_LOG("AudioStream: isValidCapturerChannelLayout: %{public}s",
298 isValidCapturerChannelLayout ? "true" : "false");
299 return isValidCapturerChannelLayout;
300 }
301
IsPlaybackChannelRelatedInfoValid(uint8_t channels,uint64_t channelLayout)302 bool IAudioStream::IsPlaybackChannelRelatedInfoValid(uint8_t channels, uint64_t channelLayout)
303 {
304 if (!IsRendererChannelValid(channels)) {
305 AUDIO_ERR_LOG("AudioStream: Invalid sink channel %{public}d", channels);
306 return false;
307 }
308 if (!IsRendererChannelLayoutValid(channelLayout)) {
309 AUDIO_ERR_LOG("AudioStream: Invalid sink channel layout");
310 return false;
311 }
312 return true;
313 }
314
IsRecordChannelRelatedInfoValid(uint8_t channels,uint64_t channelLayout)315 bool IAudioStream::IsRecordChannelRelatedInfoValid(uint8_t channels, uint64_t channelLayout)
316 {
317 if (!IsCapturerChannelValid(channels)) {
318 return false;
319 }
320 if (!IsCapturerChannelLayoutValid(channelLayout)) {
321 return false;
322 }
323 return true;
324 }
325 } // namespace AudioStandard
326 } // namespace OHOS
327