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