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 {
25 size_t AudioPlayer::bufferLen = 0;
26 bool AudioPlayer::isStop_ = false;
27 bool AudioPlayer::isRingStop_ = false;
28 bool AudioPlayer::isToneStop_ = false;
29 bool AudioPlayer::isRenderInitialized_ = false;
30 std::unique_ptr<AudioStandard::AudioRenderer> AudioPlayer::audioRenderer_ = nullptr;
31
InitRenderer(const wav_hdr & wavHeader,AudioStandard::AudioStreamType streamType)32 bool AudioPlayer::InitRenderer(const wav_hdr &wavHeader, AudioStandard::AudioStreamType streamType)
33 {
34 AudioStandard::AudioRendererParams rendererParams;
35 rendererParams.sampleFormat = AudioStandard::AudioSampleFormat::SAMPLE_S16LE;
36 rendererParams.sampleRate = static_cast<AudioStandard::AudioSamplingRate>(wavHeader.SamplesPerSec);
37 rendererParams.channelCount = static_cast<AudioStandard::AudioChannel>(wavHeader.NumOfChan);
38 rendererParams.encodingType = static_cast<AudioStandard::AudioEncodingType>(AudioStandard::ENCODING_PCM);
39 audioRenderer_ = AudioStandard::AudioRenderer::Create(streamType);
40 if (audioRenderer_ == nullptr) {
41 TELEPHONY_LOGE("audio renderer create failed");
42 return false;
43 }
44 if (audioRenderer_->SetParams(rendererParams) != TELEPHONY_SUCCESS) {
45 TELEPHONY_LOGE("audio renderer set params failed");
46 return false;
47 }
48 if (!audioRenderer_->Start()) {
49 TELEPHONY_LOGE("audio renderer start failed");
50 return false;
51 }
52 if (audioRenderer_->GetBufferSize(bufferLen)) {
53 TELEPHONY_LOGE("audio renderer get buffer size failed");
54 return false;
55 }
56 uint32_t frameCount;
57 if (audioRenderer_->GetFrameCount(frameCount)) {
58 TELEPHONY_LOGE("audio renderer get frame count failed");
59 return false;
60 }
61 isRenderInitialized_ = true;
62 return true;
63 }
64
Play(const std::string & path,AudioStandard::AudioStreamType streamType,PlayerType playerType)65 int32_t AudioPlayer::Play(const std::string &path, AudioStandard::AudioStreamType streamType, PlayerType playerType)
66 {
67 wav_hdr wavHeader;
68 std::string realPath = "";
69 if (!GetRealPath(path, realPath) || realPath.empty()) {
70 TELEPHONY_LOGE("path or realPath is NULL");
71 return TELEPHONY_ERR_ARGUMENT_INVALID;
72 }
73 FILE *wavFile = fopen(realPath.c_str(), "rb");
74 if (wavFile == nullptr) {
75 TELEPHONY_LOGE("open audio file failed");
76 return TELEPHONY_ERR_LOCAL_PTR_NULL;
77 }
78 (void)fread(&wavHeader, READ_SIZE, sizeof(wav_hdr), wavFile);
79 if (!InitRenderer(wavHeader, streamType)) {
80 TELEPHONY_LOGE("audio renderer init failed");
81 (void)fclose(wavFile);
82 return TELEPHONY_ERR_UNINIT;
83 }
84 uint8_t *buffer = (uint8_t *)malloc(bufferLen + bufferLen);
85 if (buffer == nullptr) {
86 TELEPHONY_LOGE("audio malloc buffer failed");
87 (void)fclose(wavFile);
88 return TELEPHONY_ERR_LOCAL_PTR_NULL;
89 }
90 size_t bytesToWrite = 0, bytesWritten = 0;
91 SetStop(playerType, false);
92 TELEPHONY_LOGI("start audio rendering");
93 while (!isStop_) {
94 if (IsStop(playerType)) {
95 break;
96 } else if (feof(wavFile)) {
97 fseek(wavFile, 0, SEEK_SET); // jump back to the beginning of the file
98 fread(&wavHeader, READ_SIZE, sizeof(wav_hdr), wavFile); // skip the wav header
99 }
100 bytesToWrite = fread(buffer, READ_SIZE, bufferLen, wavFile);
101 bytesWritten = 0;
102 while ((bytesWritten < bytesToWrite) && ((bytesToWrite - bytesWritten) > MIN_BYTES)) {
103 if (IsStop(playerType)) {
104 break;
105 }
106 bytesWritten += static_cast<size_t>(
107 audioRenderer_->Write(buffer + bytesWritten, bytesToWrite - bytesWritten));
108 }
109 }
110 free(buffer);
111 (void)fclose(wavFile);
112 TELEPHONY_LOGI("audio renderer playback done");
113 return TELEPHONY_SUCCESS;
114 }
115
SetStop(PlayerType playerType,bool state)116 void AudioPlayer::SetStop(PlayerType playerType, bool state)
117 {
118 switch (playerType) {
119 case PlayerType::TYPE_RING:
120 isRingStop_ = state;
121 if (isRingStop_) {
122 DelayedSingleton<AudioControlManager>::GetInstance()->SetRingState(RingState::STOPPED);
123 } else {
124 DelayedSingleton<AudioControlManager>::GetInstance()->SetRingState(RingState::RINGING);
125 }
126 break;
127 case PlayerType::TYPE_TONE:
128 isToneStop_ = state;
129 break;
130 default:
131 break;
132 }
133 }
134
IsStop(PlayerType playerType)135 bool AudioPlayer::IsStop(PlayerType playerType)
136 {
137 bool ret = false;
138 switch (playerType) {
139 case PlayerType::TYPE_RING:
140 ret = isRingStop_;
141 break;
142 case PlayerType::TYPE_TONE:
143 ret = isToneStop_;
144 break;
145 default:
146 break;
147 }
148 return ret;
149 }
150
ReleaseRenderer()151 void AudioPlayer::ReleaseRenderer()
152 {
153 if (!isRenderInitialized_) {
154 return;
155 }
156 audioRenderer_->Flush();
157 audioRenderer_->Drain();
158 audioRenderer_->Stop();
159 audioRenderer_->Release();
160 }
161
GetRealPath(const std::string & profilePath,std::string & realPath)162 bool AudioPlayer::GetRealPath(const std::string &profilePath, std::string &realPath)
163 {
164 if (profilePath.empty()) {
165 TELEPHONY_LOGE("profilePath is empty");
166 return false;
167 }
168
169 char path[PATH_MAX] = { '\0' };
170 if (realpath(profilePath.c_str(), path) == nullptr) {
171 TELEPHONY_LOGE("get real path fail");
172 return false;
173 }
174 realPath = path;
175 return true;
176 }
177 } // namespace Telephony
178 } // namespace OHOS
179