1 /*
2 * Copyright (c) 2021-2022 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_renderer_file_sink.h"
17
18 #include <cerrno>
19 #include <cstring>
20 #include <dlfcn.h>
21 #include <iostream>
22 #include <string>
23 #include <unistd.h>
24
25 #include "audio_errors.h"
26 #include "audio_log.h"
27
28 using namespace std;
29
30 namespace OHOS {
31 namespace AudioStandard {
AudioRendererFileSink()32 AudioRendererFileSink::AudioRendererFileSink()
33 {
34 }
35
~AudioRendererFileSink()36 AudioRendererFileSink::~AudioRendererFileSink()
37 {
38 AudioRendererFileSink::DeInit();
39 }
40
GetInstance()41 AudioRendererFileSink *AudioRendererFileSink::GetInstance()
42 {
43 static AudioRendererFileSink audioRenderer;
44
45 return &audioRenderer;
46 }
47
IsInited()48 bool AudioRendererFileSink::IsInited()
49 {
50 return !filePath_.empty();
51 }
52
GetVolume(float & left,float & right)53 int32_t AudioRendererFileSink::GetVolume(float &left, float &right)
54 {
55 return ERR_NOT_SUPPORTED;
56 }
57
SetVoiceVolume(float volume)58 int32_t AudioRendererFileSink::SetVoiceVolume(float volume)
59 {
60 return ERR_NOT_SUPPORTED;
61 }
62
SetAudioScene(AudioScene audioScene,DeviceType activeDevice)63 int32_t AudioRendererFileSink::SetAudioScene(AudioScene audioScene, DeviceType activeDevice)
64 {
65 return ERR_NOT_SUPPORTED;
66 }
67
SetOutputRoute(DeviceType deviceType)68 int32_t AudioRendererFileSink::SetOutputRoute(DeviceType deviceType)
69 {
70 return ERR_NOT_SUPPORTED;
71 }
72
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)73 void AudioRendererFileSink::SetAudioParameter(const AudioParamKey key, const std::string& condition,
74 const std::string& value)
75 {
76 AUDIO_ERR_LOG("AudioRendererFileSink SetAudioParameter not supported.");
77 return;
78 }
79
GetAudioParameter(const AudioParamKey key,const std::string & condition)80 std::string AudioRendererFileSink::GetAudioParameter(const AudioParamKey key, const std::string& condition)
81 {
82 AUDIO_ERR_LOG("AudioRendererFileSink GetAudioParameter not supported.");
83 return "";
84 }
85
RegisterParameterCallback(IAudioSinkCallback * callback)86 void AudioRendererFileSink::RegisterParameterCallback(IAudioSinkCallback* callback)
87 {
88 AUDIO_ERR_LOG("AudioRendererFileSink RegisterParameterCallback not supported.");
89 }
90
SetAudioMonoState(bool audioMono)91 void AudioRendererFileSink::SetAudioMonoState(bool audioMono)
92 {
93 AUDIO_ERR_LOG("AudioRendererFileSink SetAudioMonoState not supported.");
94 return;
95 }
96
SetAudioBalanceValue(float audioBalance)97 void AudioRendererFileSink::SetAudioBalanceValue(float audioBalance)
98 {
99 AUDIO_ERR_LOG("AudioRendererFileSink SetAudioBalanceValue not supported.");
100 return;
101 }
102
DeInit()103 void AudioRendererFileSink::DeInit()
104 {
105 if (filePtr_ != nullptr) {
106 fclose(filePtr_);
107 filePtr_ = nullptr;
108 }
109 }
110
Init(IAudioSinkAttr attr)111 int32_t AudioRendererFileSink::Init(IAudioSinkAttr attr)
112 {
113 filePath_.assign(attr.filePath);
114
115 return SUCCESS;
116 }
117
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)118 int32_t AudioRendererFileSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
119 {
120 if (filePtr_ == nullptr) {
121 AUDIO_ERR_LOG("Invalid file ptr");
122 return ERROR;
123 }
124
125 size_t writeResult = fwrite(static_cast<void*>(&data), 1, len, filePtr_);
126 if (writeResult != len) {
127 AUDIO_ERR_LOG("Failed to write the file.");
128 }
129
130 writeLen = writeResult;
131
132 return SUCCESS;
133 }
134
Start(void)135 int32_t AudioRendererFileSink::Start(void)
136 {
137 char realPath[PATH_MAX + 1] = {0x00};
138 std::string rootPath;
139 std::string fileName;
140
141 auto pos = filePath_.rfind("/");
142 if (pos!= std::string::npos) {
143 rootPath = filePath_.substr(0, pos);
144 fileName = filePath_.substr(pos);
145 }
146
147 if (filePtr_ == nullptr) {
148 if ((filePath_.length() >= PATH_MAX) || (realpath(rootPath.c_str(), realPath) == nullptr)) {
149 AUDIO_ERR_LOG("AudioRendererFileSink:: Invalid path errno = %{public}d", errno);
150 return ERROR;
151 }
152
153 std::string verifiedPath(realPath);
154 filePtr_ = fopen(verifiedPath.append(fileName).c_str(), "wb+");
155 CHECK_AND_RETURN_RET_LOG(filePtr_ != nullptr, ERROR, "Failed to open file, errno = %{public}d", errno);
156 }
157
158 return SUCCESS;
159 }
160
Stop(void)161 int32_t AudioRendererFileSink::Stop(void)
162 {
163 if (filePtr_ != nullptr) {
164 fclose(filePtr_);
165 filePtr_ = nullptr;
166 }
167
168 return SUCCESS;
169 }
170
Pause(void)171 int32_t AudioRendererFileSink::Pause(void)
172 {
173 return SUCCESS;
174 }
175
Resume(void)176 int32_t AudioRendererFileSink::Resume(void)
177 {
178 return SUCCESS;
179 }
180
Reset(void)181 int32_t AudioRendererFileSink::Reset(void)
182 {
183 return SUCCESS;
184 }
185
Flush(void)186 int32_t AudioRendererFileSink::Flush(void)
187 {
188 return SUCCESS;
189 }
190
SetVolume(float left,float right)191 int32_t AudioRendererFileSink::SetVolume(float left, float right)
192 {
193 return ERR_NOT_SUPPORTED;
194 }
195
GetLatency(uint32_t * latency)196 int32_t AudioRendererFileSink::GetLatency(uint32_t *latency)
197 {
198 return ERR_NOT_SUPPORTED;
199 }
200
GetTransactionId(uint64_t * transactionId)201 int32_t AudioRendererFileSink::GetTransactionId(uint64_t *transactionId)
202 {
203 AUDIO_ERR_LOG("AudioRendererFileSink %{public}s", __func__);
204 return ERR_NOT_SUPPORTED;
205 }
206 } // namespace AudioStandard
207 } // namespace OHOS
208