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 "call_manager_errors.h"
19 #include "telephony_log_wrapper.h"
20 #include "audio_control_manager.h"
21
22 #include "audio_system_manager.h"
23
24 namespace OHOS {
25 namespace Telephony {
26 size_t AudioPlayer::bufferLen = 0;
27 bool AudioPlayer::isStop_ = false;
28 bool AudioPlayer::isRingStop_ = false;
29 bool AudioPlayer::isToneStop_ = 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 = static_cast<AudioStandard::AudioSampleFormat>(wavHeader.bitsPerSample);
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 return true;
62 }
63
Play(const std::string & path,AudioStandard::AudioStreamType streamType,PlayerType playerType)64 int32_t AudioPlayer::Play(const std::string &path, AudioStandard::AudioStreamType streamType, PlayerType playerType)
65 {
66 wav_hdr wavHeader;
67 if (path.empty()) {
68 TELEPHONY_LOGE("path is empty");
69 return TELEPHONY_ERR_ARGUMENT_INVALID;
70 }
71 FILE *wavFile = fopen(path.c_str(), "rb");
72 if (wavFile == nullptr) {
73 TELEPHONY_LOGE("open audio file failed");
74 return TELEPHONY_ERR_LOCAL_PTR_NULL;
75 }
76 (void)fread(&wavHeader, READ_SIZE, sizeof(wav_hdr), wavFile);
77 if (!InitRenderer(wavHeader, streamType)) {
78 TELEPHONY_LOGE("audio renderer init failed");
79 (void)fclose(wavFile);
80 return TELEPHONY_ERR_UNINIT;
81 }
82 uint8_t *buffer = (uint8_t *)malloc(bufferLen + bufferLen);
83 if (buffer == nullptr) {
84 TELEPHONY_LOGE("audio malloc buffer failed");
85 (void)fclose(wavFile);
86 return TELEPHONY_ERR_LOCAL_PTR_NULL;
87 }
88 size_t bytesToWrite = 0, bytesWritten = 0;
89 SetStop(playerType, false);
90 TELEPHONY_LOGI("start audio rendering");
91 while (!isStop_) {
92 if (IsStop(playerType)) {
93 break;
94 } else if (feof(wavFile)) {
95 fseek(wavFile, 0, SEEK_SET); // jump back to the beginning of the file
96 fread(&wavHeader, READ_SIZE, sizeof(wav_hdr), wavFile); // skip the wav header
97 }
98 bytesToWrite = fread(buffer, READ_SIZE, bufferLen, wavFile);
99 bytesWritten = 0;
100 while ((bytesWritten < bytesToWrite) && ((bytesToWrite - bytesWritten) > MIN_BYTES)) {
101 if (IsStop(playerType)) {
102 break;
103 }
104 bytesWritten += audioRenderer_->Write(buffer + bytesWritten, bytesToWrite - bytesWritten);
105 }
106 }
107 ReleaseRenderer();
108 free(buffer);
109 (void)fclose(wavFile);
110 TELEPHONY_LOGI("audio renderer playback done");
111 return TELEPHONY_SUCCESS;
112 }
113
SetStop(PlayerType playerType,bool state)114 void AudioPlayer::SetStop(PlayerType playerType, bool state)
115 {
116 switch (playerType) {
117 case PlayerType::TYPE_RING:
118 isRingStop_ = state;
119 if (isRingStop_) {
120 DelayedSingleton<AudioControlManager>::GetInstance()->SetRingState(RingState::STOPPED);
121 } else {
122 DelayedSingleton<AudioControlManager>::GetInstance()->SetRingState(RingState::RINGING);
123 }
124 break;
125 case PlayerType::TYPE_TONE:
126 isToneStop_ = state;
127 break;
128 default:
129 break;
130 }
131 }
132
IsStop(PlayerType playerType)133 bool AudioPlayer::IsStop(PlayerType playerType)
134 {
135 bool ret = false;
136 switch (playerType) {
137 case PlayerType::TYPE_RING:
138 ret = isRingStop_;
139 break;
140 case PlayerType::TYPE_TONE:
141 ret = isToneStop_;
142 break;
143 default:
144 break;
145 }
146 return ret;
147 }
148
ReleaseRenderer()149 void AudioPlayer::ReleaseRenderer()
150 {
151 audioRenderer_->Flush();
152 audioRenderer_->Drain();
153 audioRenderer_->Stop();
154 audioRenderer_->Release();
155 }
156 } // namespace Telephony
157 } // namespace OHOS
158