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