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
DeInit()48 void AudioRendererFileSink::DeInit()
49 {
50 if (filePtr_ != nullptr) {
51 fclose(filePtr_);
52 filePtr_ = nullptr;
53 }
54 }
55
InitAttrs(struct AudioSampleAttributes & attrs)56 void InitAttrs(struct AudioSampleAttributes &attrs)
57 {
58 }
59
Init(const char * filePath)60 int32_t AudioRendererFileSink::Init(const char *filePath)
61 {
62 filePath_.assign(filePath);
63
64 return SUCCESS;
65 }
66
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)67 int32_t AudioRendererFileSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
68 {
69 if (filePtr_ == nullptr) {
70 AUDIO_ERR_LOG("Invalid file ptr");
71 return ERROR;
72 }
73
74 size_t writeResult = fwrite(static_cast<void*>(&data), 1, len, filePtr_);
75 if (writeResult != len) {
76 AUDIO_ERR_LOG("Failed to write the file.");
77 }
78
79 writeLen = writeResult;
80
81 return SUCCESS;
82 }
83
Start(void)84 int32_t AudioRendererFileSink::Start(void)
85 {
86 char realPath[PATH_MAX + 1] = {0x00};
87 std::string rootPath;
88 std::string fileName;
89
90 auto pos = filePath_.rfind("/");
91 if (pos!= std::string::npos) {
92 rootPath = filePath_.substr(0, pos);
93 fileName = filePath_.substr(pos);
94 }
95
96 if (filePtr_ == nullptr) {
97 if ((filePath_.length() >= PATH_MAX) || (realpath(rootPath.c_str(), realPath) == nullptr)) {
98 AUDIO_ERR_LOG("AudioRendererFileSink:: Invalid path errno = %{public}d", errno);
99 return ERROR;
100 }
101
102 std::string verifiedPath(realPath);
103 filePtr_ = fopen(verifiedPath.append(fileName).c_str(), "wb+");
104 CHECK_AND_RETURN_RET_LOG(filePtr_ != nullptr, ERROR, "Failed to open file, errno = %{public}d", errno);
105 }
106
107 return SUCCESS;
108 }
109
Stop(void)110 int32_t AudioRendererFileSink::Stop(void)
111 {
112 if (filePtr_ != nullptr) {
113 fclose(filePtr_);
114 filePtr_ = nullptr;
115 }
116
117 return SUCCESS;
118 }
119
Pause(void)120 int32_t AudioRendererFileSink::Pause(void)
121 {
122 return SUCCESS;
123 }
124
Resume(void)125 int32_t AudioRendererFileSink::Resume(void)
126 {
127 return SUCCESS;
128 }
129
Reset(void)130 int32_t AudioRendererFileSink::Reset(void)
131 {
132 return SUCCESS;
133 }
134
Flush(void)135 int32_t AudioRendererFileSink::Flush(void)
136 {
137 return SUCCESS;
138 }
139
SetVolume(float left,float right)140 int32_t AudioRendererFileSink::SetVolume(float left, float right)
141 {
142 return ERR_NOT_SUPPORTED;
143 }
144
GetLatency(uint32_t * latency)145 int32_t AudioRendererFileSink::GetLatency(uint32_t *latency)
146 {
147 return ERR_NOT_SUPPORTED;
148 }
149
GetTransactionId(uint64_t * transactionId)150 int32_t AudioRendererFileSink::GetTransactionId(uint64_t *transactionId)
151 {
152 AUDIO_ERR_LOG("AudioRendererFileSink %{public}s", __func__);
153 return ERR_NOT_SUPPORTED;
154 }
155 } // namespace AudioStandard
156 } // namespace OHOS
157
158 #ifdef __cplusplus
159 extern "C" {
160 #endif
161
162 using namespace OHOS::AudioStandard;
163
164 AudioRendererFileSink *g_fileSinkInstance = AudioRendererFileSink::GetInstance();
FillinAudioRenderFileSinkWapper(const char * deviceNetworkId,void ** wapper)165 int32_t FillinAudioRenderFileSinkWapper(const char *deviceNetworkId, void **wapper)
166 {
167 AudioRendererFileSink *instance = AudioRendererFileSink::GetInstance();
168 if (instance != nullptr) {
169 *wapper = static_cast<void *>(instance);
170 } else {
171 *wapper = nullptr;
172 return ERROR;
173 }
174
175 return SUCCESS;
176 }
177
AudioRendererFileSinkInit(void * wapper,const char * filePath)178 int32_t AudioRendererFileSinkInit(void *wapper, const char *filePath)
179 {
180 AudioRendererFileSink *fileSinkInstance = static_cast<AudioRendererFileSink *>(wapper);
181 CHECK_AND_RETURN_RET_LOG(fileSinkInstance != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
182 return fileSinkInstance->Init(filePath);
183 }
184
AudioRendererFileSinkDeInit(void * wapper)185 void AudioRendererFileSinkDeInit(void *wapper)
186 {
187 AudioRendererFileSink *fileSinkInstance = static_cast<AudioRendererFileSink *>(wapper);
188 CHECK_AND_RETURN_LOG(fileSinkInstance != nullptr, "null audioRendererSink");
189 fileSinkInstance->DeInit();
190 }
191
AudioRendererFileSinkStop(void * wapper)192 int32_t AudioRendererFileSinkStop(void *wapper)
193 {
194 AudioRendererFileSink *fileSinkInstance = static_cast<AudioRendererFileSink *>(wapper);
195 CHECK_AND_RETURN_RET_LOG(fileSinkInstance != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
196 return fileSinkInstance->Stop();
197 }
198
AudioRendererFileSinkStart(void * wapper)199 int32_t AudioRendererFileSinkStart(void *wapper)
200 {
201 AudioRendererFileSink *fileSinkInstance = static_cast<AudioRendererFileSink *>(wapper);
202 CHECK_AND_RETURN_RET_LOG(fileSinkInstance != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
203 return fileSinkInstance->Start();
204 }
205
AudioRendererFileSinkPause(void * wapper)206 int32_t AudioRendererFileSinkPause(void *wapper)
207 {
208 AudioRendererFileSink *fileSinkInstance = static_cast<AudioRendererFileSink *>(wapper);
209 CHECK_AND_RETURN_RET_LOG(fileSinkInstance != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
210 return fileSinkInstance->Pause();
211 }
212
AudioRendererFileSinkResume(void * wapper)213 int32_t AudioRendererFileSinkResume(void *wapper)
214 {
215 AudioRendererFileSink *fileSinkInstance = static_cast<AudioRendererFileSink *>(wapper);
216 CHECK_AND_RETURN_RET_LOG(fileSinkInstance != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
217 return fileSinkInstance->Resume();
218 }
219
AudioRendererFileSinkRenderFrame(void * wapper,char & data,uint64_t len,uint64_t & writeLen)220 int32_t AudioRendererFileSinkRenderFrame(void *wapper, char &data, uint64_t len, uint64_t &writeLen)
221 {
222 AudioRendererFileSink *fileSinkInstance = static_cast<AudioRendererFileSink *>(wapper);
223 CHECK_AND_RETURN_RET_LOG(fileSinkInstance != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
224 return fileSinkInstance->RenderFrame(data, len, writeLen);
225 }
226
AudioRendererFileSinkSetVolume(void * wapper,float left,float right)227 int32_t AudioRendererFileSinkSetVolume(void *wapper, float left, float right)
228 {
229 AudioRendererFileSink *fileSinkInstance = static_cast<AudioRendererFileSink *>(wapper);
230 CHECK_AND_RETURN_RET_LOG(fileSinkInstance != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
231 return fileSinkInstance->SetVolume(left, right);
232 }
233
AudioRendererFileSinkGetLatency(void * wapper,uint32_t * latency)234 int32_t AudioRendererFileSinkGetLatency(void *wapper, uint32_t *latency)
235 {
236 AudioRendererFileSink *fileSinkInstance = static_cast<AudioRendererFileSink *>(wapper);
237 CHECK_AND_RETURN_RET_LOG(fileSinkInstance != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
238 return fileSinkInstance->GetLatency(latency);
239 }
240
AudioRendererFileSinkGetTransactionId(uint64_t * transactionId)241 int32_t AudioRendererFileSinkGetTransactionId(uint64_t *transactionId)
242 {
243 return g_fileSinkInstance->GetTransactionId(transactionId);
244 }
245 #ifdef __cplusplus
246 }
247 #endif
248