• 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 "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