• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 <chrono>
17 #include <thread>
18 #include <vector>
19 
20 #include "audio_errors.h"
21 #include "audio_info.h"
22 #include "media_log.h"
23 
24 #include "audio_stream.h"
25 
26 using namespace std;
27 
28 namespace OHOS {
29 namespace AudioStandard {
30 const unsigned long long TIME_CONVERSION_US_S = 1000000ULL; /* us to s */
31 const unsigned long long TIME_CONVERSION_NS_US = 1000ULL; /* ns to us */
32 const unsigned long long TIME_CONVERSION_NS_S = 1000000000ULL; /* ns to s */
33 constexpr int32_t WRITE_RETRY_DELAY_IN_US = 500;
34 constexpr int32_t READ_WRITE_WAIT_TIME_IN_US = 500;
35 constexpr int32_t CB_WRITE_BUFFERS_WAIT_IN_US = 500;
36 
37 const map<pair<ContentType, StreamUsage>, AudioStreamType> AudioStream::streamTypeMap_ = AudioStream::CreateStreamMap();
38 
CreateStreamMap()39 map<pair<ContentType, StreamUsage>, AudioStreamType> AudioStream::CreateStreamMap()
40 {
41     map<pair<ContentType, StreamUsage>, AudioStreamType> streamMap;
42 
43     streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_UNKNOWN)] = STREAM_MUSIC;
44     streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_MEDIA)] = STREAM_MUSIC;
45     streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
46     streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_MUSIC;
47     streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_MUSIC;
48 
49     streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_UNKNOWN)] = STREAM_MUSIC;
50     streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_MEDIA)] = STREAM_VOICE_ASSISTANT;
51     streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_VOICE_CALL;
52     streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_VOICE_ASSISTANT;
53     streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_MUSIC;
54 
55     streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_UNKNOWN)] = STREAM_MUSIC;
56     streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_MEDIA)] = STREAM_MUSIC;
57     streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
58     streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_VOICE_ASSISTANT;
59     streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_RING;
60 
61     streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_UNKNOWN)] = STREAM_MEDIA;
62     streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_MEDIA)] = STREAM_MEDIA;
63     streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
64     streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_MUSIC;
65     streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_MUSIC;
66 
67     streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_UNKNOWN)] = STREAM_NOTIFICATION;
68     streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_MEDIA)] = STREAM_NOTIFICATION;
69     streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
70     streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_MUSIC;
71     streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_MUSIC;
72 
73     streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_UNKNOWN)] = STREAM_RING;
74     streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_MEDIA)] = STREAM_RING;
75     streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
76     streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_MUSIC;
77     streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_RING;
78 
79     return streamMap;
80 }
81 
AudioStream(AudioStreamType eStreamType,AudioMode eMode)82 AudioStream::AudioStream(AudioStreamType eStreamType, AudioMode eMode) : eStreamType_(eStreamType),
83                                                                          eMode_(eMode),
84                                                                          state_(NEW),
85                                                                          isReadInProgress_(false),
86                                                                          isWriteInProgress_(false),
87                                                                          resetTime_(false),
88                                                                          resetTimestamp_(0),
89                                                                          renderMode_(RENDER_MODE_NORMAL),
90                                                                          isReadyToWrite_(false),
91                                                                          isFirstRead_(false)
92 {
93     MEDIA_DEBUG_LOG("AudioStream ctor");
94 }
95 
~AudioStream()96 AudioStream::~AudioStream()
97 {
98     isReadyToWrite_ = false;
99     if (writeThread_ && writeThread_->joinable()) {
100         writeThread_->join();
101     }
102 
103     if (state_ != RELEASED && state_ != NEW) {
104         ReleaseAudioStream();
105     }
106 }
107 
GetState()108 State AudioStream::GetState()
109 {
110     return state_;
111 }
112 
GetAudioSessionID(uint32_t & sessionID) const113 int32_t AudioStream::GetAudioSessionID(uint32_t &sessionID) const
114 {
115     if ((state_ == RELEASED) || (state_ == NEW)) {
116         return ERR_ILLEGAL_STATE;
117     }
118 
119     if (GetSessionID(sessionID) != 0) {
120         return ERR_INVALID_INDEX;
121     }
122 
123     return SUCCESS;
124 }
125 
GetAudioTime(Timestamp & timestamp,Timestamp::Timestampbase base)126 bool AudioStream::GetAudioTime(Timestamp &timestamp, Timestamp::Timestampbase base)
127 {
128     uint64_t paTimeStamp = 0;
129     if (GetCurrentTimeStamp(paTimeStamp) == SUCCESS) {
130         if (resetTime_) {
131             MEDIA_INFO_LOG("AudioStream::GetAudioTime resetTime_ %{public}d", resetTime_);
132             resetTime_ = false;
133             resetTimestamp_ = paTimeStamp;
134         }
135 
136         timestamp.time.tv_sec = static_cast<time_t>((paTimeStamp - resetTimestamp_) / TIME_CONVERSION_US_S);
137         timestamp.time.tv_nsec
138             = static_cast<time_t>(((paTimeStamp - resetTimestamp_) - (timestamp.time.tv_sec * TIME_CONVERSION_US_S))
139                                   * TIME_CONVERSION_NS_US);
140         timestamp.time.tv_sec += baseTimestamp_.tv_sec;
141         timestamp.time.tv_nsec += baseTimestamp_.tv_nsec;
142         timestamp.time.tv_sec += (timestamp.time.tv_nsec / TIME_CONVERSION_NS_S);
143         timestamp.time.tv_nsec = (timestamp.time.tv_nsec % TIME_CONVERSION_NS_S);
144 
145         return true;
146     }
147     return false;
148 }
149 
GetBufferSize(size_t & bufferSize) const150 int32_t AudioStream::GetBufferSize(size_t &bufferSize) const
151 {
152     MEDIA_INFO_LOG("AudioStream: Get Buffer size");
153     if (GetMinimumBufferSize(bufferSize) != 0) {
154         return ERR_OPERATION_FAILED;
155     }
156 
157     return SUCCESS;
158 }
159 
GetFrameCount(uint32_t & frameCount) const160 int32_t AudioStream::GetFrameCount(uint32_t &frameCount) const
161 {
162     MEDIA_INFO_LOG("AudioStream: Get frame count");
163     if (GetMinimumFrameCount(frameCount) != 0) {
164         return ERR_OPERATION_FAILED;
165     }
166 
167     return SUCCESS;
168 }
169 
GetLatency(uint64_t & latency) const170 int32_t AudioStream::GetLatency(uint64_t &latency) const
171 {
172     if (GetAudioLatency(latency) != SUCCESS) {
173         return ERR_OPERATION_FAILED;
174     } else {
175         return SUCCESS;
176     }
177 }
178 
GetSupportedFormats() const179 vector<AudioSampleFormat> AudioStream::GetSupportedFormats() const
180 {
181     return AUDIO_SUPPORTED_FORMATS;
182 }
183 
GetSupportedChannels() const184 vector<AudioChannel> AudioStream::GetSupportedChannels() const
185 {
186     return AUDIO_SUPPORTED_CHANNELS;
187 }
188 
GetSupportedEncodingTypes() const189 vector<AudioEncodingType> AudioStream::GetSupportedEncodingTypes() const
190 {
191     return AUDIO_SUPPORTED_ENCODING_TYPES;
192 }
193 
GetSupportedSamplingRates() const194 vector<AudioSamplingRate> AudioStream::GetSupportedSamplingRates() const
195 {
196     return AUDIO_SUPPORTED_SAMPLING_RATES;
197 }
198 
IsFormatValid(uint8_t format)199 bool IsFormatValid(uint8_t format)
200 {
201     bool isValidFormat = (find(AUDIO_SUPPORTED_FORMATS.begin(), AUDIO_SUPPORTED_FORMATS.end(), format)
202                           != AUDIO_SUPPORTED_FORMATS.end());
203     MEDIA_DEBUG_LOG("AudioStream: IsFormatValid: %{public}s", isValidFormat ? "true" : "false");
204     return isValidFormat;
205 }
206 
IsChannelValid(uint8_t channel)207 bool IsChannelValid(uint8_t channel)
208 {
209     bool isValidChannel = (find(AUDIO_SUPPORTED_CHANNELS.begin(), AUDIO_SUPPORTED_CHANNELS.end(), channel)
210                            != AUDIO_SUPPORTED_CHANNELS.end());
211     MEDIA_DEBUG_LOG("AudioStream: IsChannelValid: %{public}s", isValidChannel ? "true" : "false");
212     return isValidChannel;
213 }
214 
IsEncodingTypeValid(uint8_t encodingType)215 bool IsEncodingTypeValid(uint8_t encodingType)
216 {
217     bool isValidEncodingType
218             = (find(AUDIO_SUPPORTED_ENCODING_TYPES.begin(), AUDIO_SUPPORTED_ENCODING_TYPES.end(), encodingType)
219                != AUDIO_SUPPORTED_ENCODING_TYPES.end());
220     MEDIA_DEBUG_LOG("AudioStream: IsEncodingTypeValid: %{public}s",
221                     isValidEncodingType ? "true" : "false");
222     return isValidEncodingType;
223 }
224 
IsSamplingRateValid(uint32_t samplingRate)225 bool IsSamplingRateValid(uint32_t samplingRate)
226 {
227     bool isValidSamplingRate
228             = (find(AUDIO_SUPPORTED_SAMPLING_RATES.begin(), AUDIO_SUPPORTED_SAMPLING_RATES.end(), samplingRate)
229                != AUDIO_SUPPORTED_SAMPLING_RATES.end());
230     MEDIA_DEBUG_LOG("AudioStream: IsSamplingRateValid: %{public}s",
231                     isValidSamplingRate ? "true" : "false");
232     return isValidSamplingRate;
233 }
234 
GetAudioStreamInfo(AudioStreamParams & audioStreamInfo)235 int32_t AudioStream::GetAudioStreamInfo(AudioStreamParams &audioStreamInfo)
236 {
237     MEDIA_INFO_LOG("AudioStream: GetAudioStreamInfo");
238     if (GetAudioStreamParams(audioStreamInfo) != 0) {
239         return ERR_OPERATION_FAILED;
240     }
241 
242     return SUCCESS;
243 }
244 
SetAudioStreamInfo(const AudioStreamParams info)245 int32_t AudioStream::SetAudioStreamInfo(const AudioStreamParams info)
246 {
247     MEDIA_INFO_LOG("AudioStream: SetAudioParams");
248 
249     MEDIA_DEBUG_LOG("AudioStream: Sampling rate: %{public}d", info.samplingRate);
250     MEDIA_DEBUG_LOG("AudioStream: channels: %{public}d", info.channels);
251     MEDIA_DEBUG_LOG("AudioStream: format: %{public}d", info.format);
252     MEDIA_DEBUG_LOG("AudioStream: stream type: %{public}d", eStreamType_);
253 
254     if (!IsFormatValid(info.format) || !IsChannelValid(info.channels)
255         || !IsSamplingRateValid(info.samplingRate) || !IsEncodingTypeValid(info.encoding)) {
256         MEDIA_ERR_LOG("AudioStream: Unsupported audio parameter");
257         return ERR_NOT_SUPPORTED;
258     }
259     if (state_ != NEW) {
260         MEDIA_DEBUG_LOG("AudioStream: State is not new, release existing stream");
261         StopAudioStream();
262         ReleaseAudioStream();
263     }
264 
265     int32_t ret = 0;
266     switch (eMode_) {
267         case AUDIO_MODE_PLAYBACK:
268             MEDIA_DEBUG_LOG("AudioStream: Initialize playback");
269             ret = Initialize(AUDIO_SERVICE_CLIENT_PLAYBACK);
270             break;
271         case AUDIO_MODE_RECORD:
272             MEDIA_DEBUG_LOG("AudioStream: Initialize recording");
273             ret = Initialize(AUDIO_SERVICE_CLIENT_RECORD);
274             break;
275         default:
276             return ERR_INVALID_OPERATION;
277     }
278 
279     if (ret) {
280         MEDIA_DEBUG_LOG("AudioStream: Error initializing!");
281         return ret;
282     }
283 
284     if (CreateStream(info, eStreamType_) != SUCCESS) {
285         MEDIA_ERR_LOG("AudioStream:Create stream failed");
286         return ERROR;
287     }
288 
289     state_ = PREPARED;
290     MEDIA_INFO_LOG("AudioStream:Set stream Info SUCCESS");
291     return SUCCESS;
292 }
293 
StartAudioStream()294 bool AudioStream::StartAudioStream()
295 {
296     if ((state_ != PREPARED) && (state_ != STOPPED) && (state_ != PAUSED)) {
297         MEDIA_ERR_LOG("StartAudioStream Illegal state:%{public}u", state_);
298         return false;
299     }
300 
301     int32_t ret = StartStream();
302     if (ret != SUCCESS) {
303         MEDIA_ERR_LOG("StartStream Start failed:%{public}d", ret);
304         return false;
305     }
306 
307     resetTime_ = true;
308     int32_t retCode = clock_gettime(CLOCK_MONOTONIC, &baseTimestamp_);
309     if (retCode != 0) {
310         MEDIA_ERR_LOG("AudioStream::StartAudioStream get system elapsed time failed: %d", retCode);
311     }
312 
313     if (renderMode_ == RENDER_MODE_CALLBACK) {
314         isReadyToWrite_ = true;
315         writeThread_ = std::make_unique<std::thread>(&AudioStream::WriteBuffers, this);
316     }
317 
318     isFirstRead_ = true;
319     state_ = RUNNING;
320     MEDIA_INFO_LOG("StartAudioStream SUCCESS");
321     return true;
322 }
323 
Read(uint8_t & buffer,size_t userSize,bool isBlockingRead)324 int32_t AudioStream::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead)
325 {
326     if (userSize <= 0) {
327         MEDIA_ERR_LOG("Invalid userSize:%{public}zu", userSize);
328         return ERR_INVALID_PARAM;
329     }
330 
331     if (state_ != RUNNING) {
332         MEDIA_ERR_LOG("Read: State is not RUNNNIG. Illegal  state:%{public}u", state_);
333         return ERR_ILLEGAL_STATE;
334     }
335 
336     if (isFirstRead_) {
337         FlushAudioStream();
338         isFirstRead_ = false;
339     }
340 
341     StreamBuffer stream;
342     stream.buffer = &buffer;
343     stream.bufferLen = userSize;
344     isReadInProgress_ = true;
345     int32_t readLen = ReadStream(stream, isBlockingRead);
346     isReadInProgress_ = false;
347     if (readLen < 0) {
348         MEDIA_ERR_LOG("ReadStream fail,ret:%{public}d", readLen);
349         return ERR_INVALID_READ;
350     }
351 
352     return readLen;
353 }
354 
Write(uint8_t * buffer,size_t buffer_size)355 size_t AudioStream::Write(uint8_t *buffer, size_t buffer_size)
356 {
357     if (renderMode_ == RENDER_MODE_CALLBACK) {
358         MEDIA_ERR_LOG("AudioStream::Write not supported. RenderMode is callback");
359         return ERR_INCORRECT_MODE;
360     }
361 
362     if ((buffer == nullptr) || (buffer_size <= 0)) {
363         MEDIA_ERR_LOG("Invalid buffer size:%{public}zu", buffer_size);
364         return ERR_INVALID_PARAM;
365     }
366 
367     if (state_ != RUNNING) {
368         MEDIA_ERR_LOG("Write: Illegal  state:%{public}u", state_);
369         // To allow context switch for APIs running in different thread contexts
370         std::this_thread::sleep_for(std::chrono::microseconds(WRITE_RETRY_DELAY_IN_US));
371         return ERR_ILLEGAL_STATE;
372     }
373 
374     int32_t writeError;
375     StreamBuffer stream;
376     stream.buffer = buffer;
377     stream.bufferLen = buffer_size;
378     isWriteInProgress_ = true;
379     size_t bytesWritten = WriteStream(stream, writeError);
380     isWriteInProgress_ = false;
381     if (writeError != 0) {
382         MEDIA_ERR_LOG("WriteStream fail,writeError:%{public}d", writeError);
383         return ERR_WRITE_FAILED;
384     }
385     if (bytesWritten < 0) {
386         MEDIA_ERR_LOG("WriteStream fail,bytesWritten:%{public}zu", bytesWritten);
387         return ERR_INVALID_WRITE;
388     }
389 
390     return bytesWritten;
391 }
392 
PauseAudioStream()393 bool AudioStream::PauseAudioStream()
394 {
395     if (state_ != RUNNING) {
396         MEDIA_ERR_LOG("PauseAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
397         return false;
398     }
399     State oldState = state_;
400     state_ = PAUSED; // Set it before stopping as Read/Write and Stop can be called from different threads
401     while (isReadInProgress_ || isWriteInProgress_) {
402         std::this_thread::sleep_for(std::chrono::microseconds(READ_WRITE_WAIT_TIME_IN_US));
403     }
404 
405     int32_t ret = PauseStream();
406     if (ret != SUCCESS) {
407         MEDIA_DEBUG_LOG("StreamPause fail,ret:%{public}d", ret);
408         state_ = oldState;
409         return false;
410     }
411 
412     // Ends the WriteBuffers thread
413     if (renderMode_ == RENDER_MODE_CALLBACK) {
414         isReadyToWrite_ = false;
415     }
416 
417     MEDIA_INFO_LOG("PauseAudioStream SUCCESS");
418 
419     return true;
420 }
421 
StopAudioStream()422 bool AudioStream::StopAudioStream()
423 {
424     MEDIA_INFO_LOG("AudioStream: StopAudioStream begin");
425     if (state_ == PAUSED) {
426         state_ = STOPPED;
427         MEDIA_INFO_LOG("StopAudioStream SUCCESS");
428         return true;
429     }
430 
431     if (state_ != RUNNING) {
432         MEDIA_ERR_LOG("StopAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
433         return false;
434     }
435     State oldState = state_;
436     state_ = STOPPED; // Set it before stopping as Read/Write and Stop can be called from different threads
437     while (isReadInProgress_ || isWriteInProgress_) {
438         std::this_thread::sleep_for(std::chrono::microseconds(READ_WRITE_WAIT_TIME_IN_US));
439     }
440 
441     int32_t ret = StopStream();
442     if (ret != SUCCESS) {
443         MEDIA_DEBUG_LOG("StreamStop fail,ret:%{public}d", ret);
444         state_ = oldState;
445         return false;
446     }
447 
448     // Ends the WriteBuffers thread
449     if (renderMode_ == RENDER_MODE_CALLBACK) {
450         isReadyToWrite_ = false;
451     }
452 
453     MEDIA_INFO_LOG("StopAudioStream SUCCESS");
454 
455     return true;
456 }
457 
FlushAudioStream()458 bool AudioStream::FlushAudioStream()
459 {
460     if ((state_ != RUNNING) && (state_ != PAUSED) && (state_ != STOPPED)) {
461         MEDIA_ERR_LOG("FlushAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
462         return false;
463     }
464 
465     int32_t ret = FlushStream();
466     if (ret != SUCCESS) {
467         MEDIA_DEBUG_LOG("Flush stream fail,ret:%{public}d", ret);
468         return false;
469     }
470 
471     MEDIA_INFO_LOG("Flush stream SUCCESS");
472     return true;
473 }
474 
DrainAudioStream()475 bool AudioStream::DrainAudioStream()
476 {
477     if (state_ != RUNNING) {
478         MEDIA_ERR_LOG("DrainAudioStream: State is not RUNNING. Illegal  state:%{public}u", state_);
479         return false;
480     }
481 
482     int32_t ret = DrainStream();
483     if (ret != SUCCESS) {
484         MEDIA_DEBUG_LOG("Drain stream fail,ret:%{public}d", ret);
485         return false;
486     }
487 
488     MEDIA_INFO_LOG("Drain stream SUCCESS");
489     return true;
490 }
491 
ReleaseAudioStream()492 bool AudioStream::ReleaseAudioStream()
493 {
494     if (state_ == RELEASED || state_ == NEW) {
495         MEDIA_ERR_LOG("Illegal state: state = %{public}u", state_);
496         return false;
497     }
498     // If state_ is RUNNING try to Stop it first and Release
499     if (state_ == RUNNING) {
500         StopAudioStream();
501     }
502 
503     ReleaseStream();
504     state_ = RELEASED;
505     MEDIA_INFO_LOG("ReleaseAudiostream SUCCESS");
506 
507     return true;
508 }
509 
GetStreamType(ContentType contentType,StreamUsage streamUsage)510 AudioStreamType AudioStream::GetStreamType(ContentType contentType, StreamUsage streamUsage)
511 {
512     AudioStreamType streamType = STREAM_MUSIC;
513     auto pos = streamTypeMap_.find(make_pair(contentType, streamUsage));
514     if (pos != streamTypeMap_.end()) {
515         streamType = pos->second;
516     }
517 
518     if (streamType == STREAM_MEDIA) {
519         streamType = STREAM_MUSIC;
520     }
521 
522     return streamType;
523 }
524 
SetAudioStreamType(AudioStreamType audioStreamType)525 int32_t AudioStream::SetAudioStreamType(AudioStreamType audioStreamType)
526 {
527     return SetStreamType(audioStreamType);
528 }
529 
SetVolume(float volume)530 int32_t AudioStream::SetVolume(float volume)
531 {
532     return SetStreamVolume(volume);
533 }
534 
GetVolume()535 float AudioStream::GetVolume()
536 {
537     return GetStreamVolume();
538 }
539 
SetRenderRate(AudioRendererRate renderRate)540 int32_t AudioStream::SetRenderRate(AudioRendererRate renderRate)
541 {
542     return SetStreamRenderRate(renderRate);
543 }
544 
GetRenderRate()545 AudioRendererRate AudioStream::GetRenderRate()
546 {
547     return GetStreamRenderRate();
548 }
549 
SetStreamCallback(const std::shared_ptr<AudioStreamCallback> & callback)550 int32_t AudioStream::SetStreamCallback(const std::shared_ptr<AudioStreamCallback> &callback)
551 {
552     if (callback == nullptr) {
553         MEDIA_ERR_LOG("AudioStream::SetStreamCallback failed. callback == nullptr");
554         return ERR_INVALID_PARAM;
555     }
556 
557     SaveStreamCallback(callback);
558 
559     return SUCCESS;
560 }
561 
SetRenderMode(AudioRenderMode renderMode)562 int32_t AudioStream::SetRenderMode(AudioRenderMode renderMode)
563 {
564     int32_t ret = SetAudioRenderMode(renderMode);
565     if (ret) {
566         MEDIA_ERR_LOG("AudioStream::SetRenderMode: renderMode: %{public}d failed", renderMode);
567         return ERR_OPERATION_FAILED;
568     }
569     renderMode_ = renderMode;
570 
571     for (int32_t i = 0; i < MAX_NUM_BUFFERS; ++i) {
572         size_t length;
573         GetMinimumBufferSize(length);
574         MEDIA_INFO_LOG("AudioServiceClient:: GetMinimumBufferSize: %{public}zu", length);
575 
576         bufferPool_[i] = std::make_unique<uint8_t[]>(length);
577         if (bufferPool_[i] == nullptr) {
578             MEDIA_INFO_LOG("AudioServiceClient::GetBufferDescriptor bufferPool_[i]==nullptr. Allocate memory failed.");
579             return ERR_OPERATION_FAILED;
580         }
581 
582         BufferDesc bufDesc {};
583         bufDesc.buffer = bufferPool_[i].get();
584         bufDesc.bufLength = length;
585         freeBufferQ_.emplace(bufDesc);
586     }
587 
588     return SUCCESS;
589 }
590 
GetRenderMode()591 AudioRenderMode AudioStream::GetRenderMode()
592 {
593     return GetAudioRenderMode();
594 }
595 
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)596 int32_t AudioStream::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
597 {
598     if (renderMode_ != RENDER_MODE_CALLBACK) {
599         MEDIA_ERR_LOG("AudioStream::SetRendererWriteCallback not supported. Render mode is not callback.");
600         return ERR_INCORRECT_MODE;
601     }
602 
603     int32_t ret = SaveWriteCallback(callback);
604     if (ret) {
605         MEDIA_ERR_LOG("AudioStream::SetRendererWriteCallback: failed");
606         return ERR_INVALID_PARAM;
607     }
608 
609     return SUCCESS;
610 }
611 
GetBufferDesc(BufferDesc & bufDesc)612 int32_t AudioStream::GetBufferDesc(BufferDesc &bufDesc)
613 {
614     if (renderMode_ != RENDER_MODE_CALLBACK) {
615         MEDIA_ERR_LOG("AudioStream::GetBufferDesc not supported. Render mode is not callback.");
616         return ERR_INCORRECT_MODE;
617     }
618 
619     MEDIA_INFO_LOG("AudioStream::freeBufferQ_ count %{public}zu", freeBufferQ_.size());
620     MEDIA_INFO_LOG("AudioStream::filledBufferQ_ count %{public}zu", filledBufferQ_.size());
621 
622     if (!freeBufferQ_.empty()) {
623         bufDesc.buffer = freeBufferQ_.front().buffer;
624         bufDesc.bufLength = freeBufferQ_.front().bufLength;
625         freeBufferQ_.pop();
626     } else {
627         bufDesc.buffer = nullptr;
628     }
629 
630     if (bufDesc.buffer == nullptr) {
631         MEDIA_INFO_LOG("AudioStream::GetBufferDesc freeBufferQ_.empty()");
632         return ERR_OPERATION_FAILED;
633     }
634 
635     return SUCCESS;
636 }
637 
Enqueue(const BufferDesc & bufDesc)638 int32_t AudioStream::Enqueue(const BufferDesc &bufDesc)
639 {
640     MEDIA_INFO_LOG("AudioStream::Enqueue");
641     if (renderMode_ != RENDER_MODE_CALLBACK) {
642         MEDIA_ERR_LOG("AudioStream::Enqueue not supported. Render mode is not callback.");
643         return ERR_INCORRECT_MODE;
644     }
645 
646     if (bufDesc.buffer == nullptr) {
647         MEDIA_ERR_LOG("AudioStream::Enqueue: failed. bufDesc.buffer == nullptr.");
648         return ERR_INVALID_PARAM;
649     }
650     filledBufferQ_.emplace(bufDesc);
651 
652     return SUCCESS;
653 }
654 
Clear()655 int32_t AudioStream::Clear()
656 {
657     if (renderMode_ != RENDER_MODE_CALLBACK) {
658         MEDIA_ERR_LOG("AudioStream::Clear not supported. Render mode is not callback.");
659         return ERR_INCORRECT_MODE;
660     }
661 
662     while (!filledBufferQ_.empty()) {
663         freeBufferQ_.emplace(filledBufferQ_.front());
664         filledBufferQ_.pop();
665     }
666 
667     return SUCCESS;
668 }
669 
WriteBuffers()670 void AudioStream::WriteBuffers()
671 {
672     MEDIA_INFO_LOG("AudioStream::WriteBuffers thread start");
673     StreamBuffer stream;
674     size_t bytesWritten;
675     int32_t writeError;
676 
677     while (isReadyToWrite_) {
678         while (!filledBufferQ_.empty()) {
679             if (state_ != RUNNING) {
680                 MEDIA_ERR_LOG("Write: Illegal  state:%{public}u", state_);
681                 isReadyToWrite_ = false;
682                 return;
683             }
684             MEDIA_DEBUG_LOG("AudioStream::WriteBuffers !filledBufferQ_.empty()");
685             stream.buffer = filledBufferQ_.front().buffer;
686             stream.bufferLen = filledBufferQ_.front().dataLength;
687             MEDIA_DEBUG_LOG("AudioStream::WriteBuffers stream.bufferLen:%{public}d", stream.bufferLen);
688             freeBufferQ_.emplace(filledBufferQ_.front());
689             filledBufferQ_.pop();
690             if (stream.buffer == nullptr) {
691                 continue;
692             }
693             bytesWritten = WriteStreamInCb(stream, writeError);
694             if (writeError != 0) {
695                 MEDIA_ERR_LOG("AudioStream::WriteStreamInCb fail, writeError:%{public}d", writeError);
696             }
697             MEDIA_INFO_LOG("AudioStream::WriteBuffers WriteStream, bytesWritten:%{public}zu", bytesWritten);
698         }
699         std::this_thread::sleep_for(std::chrono::microseconds(CB_WRITE_BUFFERS_WAIT_IN_US));
700     }
701     MEDIA_INFO_LOG("AudioStream::WriteBuffers thread end");
702 }
703 } // namespace AudioStandard
704 } // namespace OHOS
705