1 /*
2 * Copyright (C) 2021 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 "audio_player.h"
17
18 #include "audio_control_manager.h"
19 #include "audio_system_manager.h"
20 #include "call_manager_errors.h"
21 #include "telephony_log_wrapper.h"
22
23 namespace OHOS {
24 namespace Telephony {
InitRenderer(const wav_hdr & wavHeader,AudioStandard::AudioStreamType streamType)25 bool AudioPlayer::InitRenderer(const wav_hdr &wavHeader, AudioStandard::AudioStreamType streamType)
26 {
27 AudioStandard::AudioRendererParams rendererParams;
28 rendererParams.sampleFormat = AudioStandard::AudioSampleFormat::SAMPLE_S16LE;
29 rendererParams.sampleRate = static_cast<AudioStandard::AudioSamplingRate>(wavHeader.SamplesPerSec);
30 rendererParams.channelCount = static_cast<AudioStandard::AudioChannel>(wavHeader.NumOfChan);
31 rendererParams.encodingType = static_cast<AudioStandard::AudioEncodingType>(AudioStandard::ENCODING_PCM);
32 audioRenderer_ = AudioStandard::AudioRenderer::Create(streamType);
33 if (audioRenderer_ == nullptr) {
34 TELEPHONY_LOGE("audio renderer create failed");
35 return false;
36 }
37 if (audioRenderer_->SetParams(rendererParams) != TELEPHONY_SUCCESS) {
38 TELEPHONY_LOGE("audio renderer set params failed");
39 return false;
40 }
41 callback_ = std::make_shared<CallAudioRendererCallback>();
42 if (callback_ == nullptr) {
43 TELEPHONY_LOGE("callback_ is nullptr");
44 return false;
45 }
46 audioRenderer_->SetRendererCallback(callback_);
47 if (!audioRenderer_->Start()) {
48 TELEPHONY_LOGE("audio renderer start failed");
49 return false;
50 }
51 if (audioRenderer_->GetBufferSize(bufferLen)) {
52 TELEPHONY_LOGE("audio renderer get buffer size failed");
53 return false;
54 }
55 uint32_t frameCount;
56 if (audioRenderer_->GetFrameCount(frameCount)) {
57 TELEPHONY_LOGE("audio renderer get frame count failed");
58 return false;
59 }
60 isRenderInitialized_ = true;
61 return true;
62 }
63
InitRenderer()64 bool AudioPlayer::InitRenderer()
65 {
66 AudioStandard::AudioRendererOptions rendererOptions;
67 rendererOptions.streamInfo.samplingRate = AudioStandard::AudioSamplingRate::SAMPLE_RATE_96000;
68 rendererOptions.streamInfo.encoding = AudioStandard::AudioEncodingType::ENCODING_PCM;
69 rendererOptions.streamInfo.format = AudioStandard::AudioSampleFormat::SAMPLE_U8;
70 rendererOptions.streamInfo.channels = AudioStandard::AudioChannel::MONO;
71 rendererOptions.rendererInfo.contentType = AudioStandard::ContentType::CONTENT_TYPE_SPEECH;
72 rendererOptions.rendererInfo.streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_VOICE_MODEM_COMMUNICATION;
73 rendererOptions.rendererInfo.rendererFlags = RENDERER_FLAG;
74 audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions);
75 if (audioRenderer_ == nullptr) {
76 TELEPHONY_LOGE("audio renderer create failed");
77 return false;
78 }
79 if (!audioRenderer_->Start()) {
80 TELEPHONY_LOGE("audio renderer start failed");
81 return false;
82 }
83 uint32_t frameCount;
84 if (audioRenderer_->GetFrameCount(frameCount)) {
85 TELEPHONY_LOGE("audio renderer get frame count failed");
86 return false;
87 }
88 isRenderInitialized_ = true;
89 return true;
90 }
91
InitCapturer()92 bool AudioPlayer::InitCapturer()
93 {
94 AudioStandard::AudioCapturerOptions capturerOptions;
95 capturerOptions.streamInfo.samplingRate = AudioStandard::AudioSamplingRate::SAMPLE_RATE_96000;
96 capturerOptions.streamInfo.encoding = AudioStandard::AudioEncodingType::ENCODING_PCM;
97 capturerOptions.streamInfo.format = AudioStandard::AudioSampleFormat::SAMPLE_U8;
98 capturerOptions.streamInfo.channels = AudioStandard::AudioChannel::MONO;
99 capturerOptions.capturerInfo.sourceType = AudioStandard::SourceType::SOURCE_TYPE_VIRTUAL_CAPTURE;
100 capturerOptions.capturerInfo.capturerFlags = CAPTURER_FLAG;
101 audioCapturer_ = AudioStandard::AudioCapturer::Create(capturerOptions);
102 if (audioCapturer_ == nullptr) {
103 TELEPHONY_LOGE("audio capturer create failed");
104 return false;
105 }
106 if (!audioCapturer_->Start()) {
107 TELEPHONY_LOGE("audio capturer start failed");
108 return false;
109 }
110 uint32_t frameCount;
111 if (audioCapturer_->GetFrameCount(frameCount)) {
112 TELEPHONY_LOGE("audio capturer get frame count failed");
113 return false;
114 }
115 isCapturerInitialized_ = true;
116 return true;
117 }
118
Play(const std::string & path,AudioStandard::AudioStreamType streamType,PlayerType playerType)119 int32_t AudioPlayer::Play(const std::string &path, AudioStandard::AudioStreamType streamType, PlayerType playerType)
120 {
121 wav_hdr wavHeader;
122 std::string realPath = "";
123 if (!GetRealPath(path, realPath) || realPath.empty()) {
124 TELEPHONY_LOGE("path or realPath is NULL");
125 return TELEPHONY_ERR_ARGUMENT_INVALID;
126 }
127 FILE *wavFile = fopen(realPath.c_str(), "rb");
128 if (wavFile == nullptr) {
129 TELEPHONY_LOGE("open audio file failed");
130 return TELEPHONY_ERR_LOCAL_PTR_NULL;
131 }
132 (void)fread(&wavHeader, READ_SIZE, sizeof(wav_hdr), wavFile);
133 SetStop(playerType, false);
134 if (!InitRenderer(wavHeader, streamType)) {
135 TELEPHONY_LOGE("audio renderer and capturer init failed");
136 (void)fclose(wavFile);
137 return TELEPHONY_ERR_UNINIT;
138 }
139 uint8_t *buffer = (uint8_t *)malloc(bufferLen + bufferLen);
140 if (buffer == nullptr) {
141 TELEPHONY_LOGE("audio malloc buffer failed");
142 (void)fclose(wavFile);
143 return TELEPHONY_ERR_LOCAL_PTR_NULL;
144 }
145 size_t bytesToWrite = 0, bytesWritten = 0;
146 TELEPHONY_LOGI("start audio rendering");
147 while (!isStop_) {
148 if (IsStop(playerType)) {
149 break;
150 } else if (feof(wavFile)) {
151 fseek(wavFile, 0, SEEK_SET); // jump back to the beginning of the file
152 fread(&wavHeader, READ_SIZE, sizeof(wav_hdr), wavFile); // skip the wav header
153 }
154 bytesToWrite = fread(buffer, READ_SIZE, bufferLen, wavFile);
155 bytesWritten = 0;
156 while ((bytesWritten < bytesToWrite) && ((bytesToWrite - bytesWritten) > MIN_BYTES)) {
157 if (IsStop(playerType)) {
158 break;
159 }
160 bytesWritten += static_cast<size_t>(
161 audioRenderer_->Write(buffer + bytesWritten, bytesToWrite - bytesWritten));
162 }
163 }
164 free(buffer);
165 (void)fclose(wavFile);
166 TELEPHONY_LOGI("audio renderer playback done");
167 return TELEPHONY_SUCCESS;
168 }
169
Play(PlayerType playerType)170 int32_t AudioPlayer::Play(PlayerType playerType)
171 {
172 SetStop(playerType, false);
173 if (!InitRenderer() || !InitCapturer()) {
174 TELEPHONY_LOGE("audio renderer and capturer init failed");
175 return TELEPHONY_ERR_UNINIT;
176 }
177 return TELEPHONY_SUCCESS;
178 }
179
SetStop(PlayerType playerType,bool state)180 void AudioPlayer::SetStop(PlayerType playerType, bool state)
181 {
182 switch (playerType) {
183 case PlayerType::TYPE_RING:
184 isRingStop_ = state;
185 if (isRingStop_) {
186 DelayedSingleton<AudioControlManager>::GetInstance()->SetRingState(RingState::STOPPED);
187 } else {
188 DelayedSingleton<AudioControlManager>::GetInstance()->SetRingState(RingState::RINGING);
189 }
190 break;
191 case PlayerType::TYPE_TONE:
192 isToneStop_ = state;
193 if (isToneStop_) {
194 DelayedSingleton<AudioControlManager>::GetInstance()->SetToneState(ToneState::STOPPED);
195 } else {
196 DelayedSingleton<AudioControlManager>::GetInstance()->SetToneState(ToneState::TONEING);
197 }
198 break;
199 case PlayerType::TYPE_SOUND:
200 isSoundStop_ = state;
201 if (isSoundStop_) {
202 DelayedSingleton<AudioControlManager>::GetInstance()->SetSoundState(SoundState::STOPPED);
203 } else {
204 DelayedSingleton<AudioControlManager>::GetInstance()->SetSoundState(SoundState::SOUNDING);
205 }
206 break;
207 default:
208 break;
209 }
210 }
211
IsStop(PlayerType playerType)212 bool AudioPlayer::IsStop(PlayerType playerType)
213 {
214 bool ret = false;
215 switch (playerType) {
216 case PlayerType::TYPE_RING:
217 ret = isRingStop_;
218 break;
219 case PlayerType::TYPE_TONE:
220 ret = isToneStop_;
221 break;
222 case PlayerType::TYPE_SOUND:
223 ret = isSoundStop_;
224 break;
225 default:
226 break;
227 }
228 return ret;
229 }
230
ReleaseRenderer()231 void AudioPlayer::ReleaseRenderer()
232 {
233 if (!isRenderInitialized_) {
234 return;
235 }
236 audioRenderer_->Flush();
237 audioRenderer_->Drain();
238 audioRenderer_->Stop();
239 audioRenderer_->Release();
240 isRenderInitialized_ = false;
241 }
242
ReleaseCapturer()243 void AudioPlayer::ReleaseCapturer()
244 {
245 if (!isCapturerInitialized_) {
246 return;
247 }
248 audioCapturer_->Flush();
249 audioCapturer_->Stop();
250 audioCapturer_->Release();
251 isCapturerInitialized_ = false;
252 }
253
GetRealPath(const std::string & profilePath,std::string & realPath)254 bool AudioPlayer::GetRealPath(const std::string &profilePath, std::string &realPath)
255 {
256 if (profilePath.empty()) {
257 TELEPHONY_LOGE("profilePath is empty");
258 return false;
259 }
260
261 char path[PATH_MAX] = { '\0' };
262 if (realpath(profilePath.c_str(), path) == nullptr) {
263 TELEPHONY_LOGE("get real path fail");
264 return false;
265 }
266 realPath = path;
267 return true;
268 }
269
OnInterrupt(const AudioStandard::InterruptEvent & interruptEvent)270 void AudioPlayer::CallAudioRendererCallback::OnInterrupt(const AudioStandard::InterruptEvent &interruptEvent)
271 {
272 if (interruptEvent.forceType == AudioStandard::INTERRUPT_FORCE) {
273 switch (interruptEvent.hintType) {
274 case AudioStandard::INTERRUPT_HINT_PAUSE:
275 break;
276 case AudioStandard::INTERRUPT_HINT_STOP:
277 if (DelayedSingleton<AudioControlManager>::GetInstance()->IsCurrentRinging() &&
278 DelayedSingleton<AudioControlManager>::GetInstance()->IsSoundPlaying()) {
279 DelayedSingleton<AudioControlManager>::GetInstance()->StopRingtone();
280 }
281 break;
282 default:
283 break;
284 }
285 }
286 }
287
OnInterrupt(const AudioStandard::InterruptEvent & interruptEvent)288 void AudioPlayer::RingCallback::OnInterrupt(const AudioStandard::InterruptEvent &interruptEvent)
289 {
290 if (interruptEvent.forceType == AudioStandard::INTERRUPT_FORCE) {
291 switch (interruptEvent.hintType) {
292 case AudioStandard::INTERRUPT_HINT_PAUSE:
293 break;
294 case AudioStandard::INTERRUPT_HINT_STOP:
295 if (DelayedSingleton<AudioControlManager>::GetInstance()->IsCurrentRinging() &&
296 DelayedSingleton<AudioControlManager>::GetInstance()->IsSoundPlaying()) {
297 DelayedSingleton<AudioControlManager>::GetInstance()->StopRingtone();
298 }
299 break;
300 default:
301 break;
302 }
303 }
304 }
305
RegisterRingCallback(std::shared_ptr<Media::RingtonePlayer> & RingtonePlayer)306 void AudioPlayer::RegisterRingCallback(std::shared_ptr<Media::RingtonePlayer> &RingtonePlayer)
307 {
308 std::lock_guard<std::mutex> lock(mutex_);
309 ringCallback_ = std::make_shared<RingCallback>();
310 if (ringCallback_ == nullptr) {
311 TELEPHONY_LOGE("ringCallback_ is nullptr");
312 return;
313 }
314 if (RingtonePlayer == nullptr) {
315 TELEPHONY_LOGE("RingtonePlayer is nullptr");
316 return;
317 }
318 RingtonePlayer->SetRingtonePlayerInterruptCallback(ringCallback_);
319 }
320
SetMute()321 int32_t AudioPlayer::SetMute()
322 {
323 if (audioRenderer_ == nullptr) {
324 TELEPHONY_LOGE("audioRenderer_ is nullptr");
325 return TELEPHONY_ERR_LOCAL_PTR_NULL;
326 }
327 float volume = 0.0f;
328 return audioRenderer_->SetVolume(volume);
329 }
330 } // namespace Telephony
331 } // namespace OHOS
332