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 &params, 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 &params)
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