• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &params, 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 &params)
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