1e0e9324cSopenharmony_ci/*
2e0e9324cSopenharmony_ci * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3e0e9324cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e0e9324cSopenharmony_ci * you may not use this file except in compliance with the License.
5e0e9324cSopenharmony_ci * You may obtain a copy of the License at
6e0e9324cSopenharmony_ci *
7e0e9324cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e0e9324cSopenharmony_ci *
9e0e9324cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e0e9324cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e0e9324cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e0e9324cSopenharmony_ci * See the License for the specific language governing permissions and
13e0e9324cSopenharmony_ci * limitations under the License.
14e0e9324cSopenharmony_ci */
15e0e9324cSopenharmony_ci
16e0e9324cSopenharmony_ci#include "audio_sink.h"
17e0e9324cSopenharmony_ci#include "common/media_log.h"
18e0e9324cSopenharmony_ci
19e0e9324cSopenharmony_cinamespace OHOS {
20e0e9324cSopenharmony_cinamespace Sharing {
21e0e9324cSopenharmony_ci
22e0e9324cSopenharmony_ciAudioSink::AudioSink(uint32_t playerId) : audioRenderer_(nullptr)
23e0e9324cSopenharmony_ci{
24e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u  tid: %{public}d.", playerId, gettid());
25e0e9324cSopenharmony_ci    playerId_ = playerId;
26e0e9324cSopenharmony_ci}
27e0e9324cSopenharmony_ci
28e0e9324cSopenharmony_ciAudioSink::~AudioSink()
29e0e9324cSopenharmony_ci{
30e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
31e0e9324cSopenharmony_ci    Stop();
32e0e9324cSopenharmony_ci    Release();
33e0e9324cSopenharmony_ci    SHARING_LOGD("renderthread release success,playerId: %{public}u.", playerId_);
34e0e9324cSopenharmony_ci}
35e0e9324cSopenharmony_ci
36e0e9324cSopenharmony_ciint32_t AudioSink::Prepare()
37e0e9324cSopenharmony_ci{
38e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
39e0e9324cSopenharmony_ci    audioRenderer_ = AudioStandard::AudioRenderer::Create(AudioStandard::AudioStreamType::STREAM_MUSIC);
40e0e9324cSopenharmony_ci    if (!audioRenderer_) {
41e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
42e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
43e0e9324cSopenharmony_ci    }
44e0e9324cSopenharmony_ci
45e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
46e0e9324cSopenharmony_ci}
47e0e9324cSopenharmony_ci
48e0e9324cSopenharmony_ciint32_t AudioSink::Prepare(int32_t channels, int32_t sampleRate)
49e0e9324cSopenharmony_ci{
50e0e9324cSopenharmony_ci    SHARING_LOGD("channels(%{public}d) sampleRate(%{public}d) playerId: %{public}u.", channels, sampleRate, playerId_);
51e0e9324cSopenharmony_ci    audioRenderer_ = AudioStandard::AudioRenderer::Create(AudioStandard::AudioStreamType::STREAM_MUSIC);
52e0e9324cSopenharmony_ci    if (!audioRenderer_) {
53e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
54e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
55e0e9324cSopenharmony_ci    }
56e0e9324cSopenharmony_ci
57e0e9324cSopenharmony_ci    int32_t res = SetParameters(16, channels, sampleRate);
58e0e9324cSopenharmony_ci    SHARING_LOGD("leave.");
59e0e9324cSopenharmony_ci    return res;
60e0e9324cSopenharmony_ci}
61e0e9324cSopenharmony_ci
62e0e9324cSopenharmony_ciint32_t AudioSink::Start()
63e0e9324cSopenharmony_ci{
64e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
65e0e9324cSopenharmony_ci    if (!audioRenderer_) {
66e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
67e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
68e0e9324cSopenharmony_ci    }
69e0e9324cSopenharmony_ci
70e0e9324cSopenharmony_ci    audioRenderer_->Start();
71e0e9324cSopenharmony_ci    running_ = true;
72e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
73e0e9324cSopenharmony_ci}
74e0e9324cSopenharmony_ci
75e0e9324cSopenharmony_ciint32_t AudioSink::Stop()
76e0e9324cSopenharmony_ci{
77e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
78e0e9324cSopenharmony_ci    if (!audioRenderer_) {
79e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL playerId: %{public}u!", playerId_);
80e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
81e0e9324cSopenharmony_ci    }
82e0e9324cSopenharmony_ci
83e0e9324cSopenharmony_ci    if (!running_) {
84e0e9324cSopenharmony_ci        SHARING_LOGE("running_ is false playerId: %{public}u!", playerId_);
85e0e9324cSopenharmony_ci        return PLAYER_ERROR_INVALID_STATE;
86e0e9324cSopenharmony_ci    }
87e0e9324cSopenharmony_ci
88e0e9324cSopenharmony_ci    running_ = false;
89e0e9324cSopenharmony_ci    audioRenderer_->Stop();
90e0e9324cSopenharmony_ci    SHARING_LOGD("success, playerId: %{public}u.", playerId_);
91e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
92e0e9324cSopenharmony_ci}
93e0e9324cSopenharmony_ci
94e0e9324cSopenharmony_ciint32_t AudioSink::Pause()
95e0e9324cSopenharmony_ci{
96e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
97e0e9324cSopenharmony_ci    if (!audioRenderer_) {
98e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
99e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
100e0e9324cSopenharmony_ci    }
101e0e9324cSopenharmony_ci
102e0e9324cSopenharmony_ci    if (audioRenderer_->Pause() != true) {
103e0e9324cSopenharmony_ci        SHARING_LOGE("failed!");
104e0e9324cSopenharmony_ci        return -1;
105e0e9324cSopenharmony_ci    }
106e0e9324cSopenharmony_ci
107e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
108e0e9324cSopenharmony_ci}
109e0e9324cSopenharmony_ci
110e0e9324cSopenharmony_ciint32_t AudioSink::Drain()
111e0e9324cSopenharmony_ci{
112e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
113e0e9324cSopenharmony_ci    if (!audioRenderer_) {
114e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
115e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
116e0e9324cSopenharmony_ci    }
117e0e9324cSopenharmony_ci
118e0e9324cSopenharmony_ci    if (audioRenderer_->Drain() != true) {
119e0e9324cSopenharmony_ci        SHARING_LOGE("failed!");
120e0e9324cSopenharmony_ci        return -1;
121e0e9324cSopenharmony_ci    }
122e0e9324cSopenharmony_ci
123e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
124e0e9324cSopenharmony_ci}
125e0e9324cSopenharmony_ci
126e0e9324cSopenharmony_ciint32_t AudioSink::Flush()
127e0e9324cSopenharmony_ci{
128e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
129e0e9324cSopenharmony_ci    if (!audioRenderer_) {
130e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
131e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
132e0e9324cSopenharmony_ci    }
133e0e9324cSopenharmony_ci
134e0e9324cSopenharmony_ci    if (audioRenderer_->Flush() != true) {
135e0e9324cSopenharmony_ci        SHARING_LOGE("failed!");
136e0e9324cSopenharmony_ci        return -1;
137e0e9324cSopenharmony_ci    }
138e0e9324cSopenharmony_ci
139e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
140e0e9324cSopenharmony_ci}
141e0e9324cSopenharmony_ci
142e0e9324cSopenharmony_ciint32_t AudioSink::Release()
143e0e9324cSopenharmony_ci{
144e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
145e0e9324cSopenharmony_ci    if (!audioRenderer_) {
146e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
147e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
148e0e9324cSopenharmony_ci    }
149e0e9324cSopenharmony_ci
150e0e9324cSopenharmony_ci    audioRenderer_ = nullptr;
151e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
152e0e9324cSopenharmony_ci}
153e0e9324cSopenharmony_ci
154e0e9324cSopenharmony_ciint32_t AudioSink::SetParameters(int32_t bitsPerSample, int32_t channels, int32_t sampleRate)
155e0e9324cSopenharmony_ci{
156e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
157e0e9324cSopenharmony_ci    (void)bitsPerSample;
158e0e9324cSopenharmony_ci    SHARING_LOGD("enter, channels:%{public}d, sampleRate:%{public}d.", channels, sampleRate);
159e0e9324cSopenharmony_ci
160e0e9324cSopenharmony_ci    if (!audioRenderer_) {
161e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
162e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
163e0e9324cSopenharmony_ci    }
164e0e9324cSopenharmony_ci
165e0e9324cSopenharmony_ci    AudioStandard::AudioRendererParams params;
166e0e9324cSopenharmony_ci    std::vector<AudioStandard::AudioSamplingRate> supportedSampleList =
167e0e9324cSopenharmony_ci        AudioStandard::AudioRenderer::GetSupportedSamplingRates();
168e0e9324cSopenharmony_ci    if (supportedSampleList.empty()) {
169e0e9324cSopenharmony_ci        SHARING_LOGE("GetSupportedSamplingRates empty.");
170e0e9324cSopenharmony_ci        return -1;
171e0e9324cSopenharmony_ci    }
172e0e9324cSopenharmony_ci
173e0e9324cSopenharmony_ci    bool isValidSampleRate = false;
174e0e9324cSopenharmony_ci    for (size_t i = 0; i < supportedSampleList.size(); i++) {
175e0e9324cSopenharmony_ci        if (sampleRate <= supportedSampleList[i] && supportedSampleList[i] > 0) {
176e0e9324cSopenharmony_ci            params.sampleRate = supportedSampleList[i];
177e0e9324cSopenharmony_ci            isValidSampleRate = true;
178e0e9324cSopenharmony_ci            break;
179e0e9324cSopenharmony_ci        }
180e0e9324cSopenharmony_ci    }
181e0e9324cSopenharmony_ci
182e0e9324cSopenharmony_ci    if (!isValidSampleRate) {
183e0e9324cSopenharmony_ci        SHARING_LOGE("Unsupported sample ratefailed.");
184e0e9324cSopenharmony_ci        return -1;
185e0e9324cSopenharmony_ci    }
186e0e9324cSopenharmony_ci
187e0e9324cSopenharmony_ci    std::vector<AudioStandard::AudioChannel> supportedChannelsList =
188e0e9324cSopenharmony_ci        AudioStandard::AudioRenderer::GetSupportedChannels();
189e0e9324cSopenharmony_ci    if (supportedChannelsList.empty()) {
190e0e9324cSopenharmony_ci        SHARING_LOGE("GetSupportedChannels empty.");
191e0e9324cSopenharmony_ci        return -1;
192e0e9324cSopenharmony_ci    }
193e0e9324cSopenharmony_ci
194e0e9324cSopenharmony_ci    bool isValidChannels = false;
195e0e9324cSopenharmony_ci    for (size_t i = 0; i < supportedChannelsList.size(); i++) {
196e0e9324cSopenharmony_ci        if (channels == supportedChannelsList[i] && supportedChannelsList[i] > 0) {
197e0e9324cSopenharmony_ci            params.channelCount = supportedChannelsList[i];
198e0e9324cSopenharmony_ci            isValidChannels = true;
199e0e9324cSopenharmony_ci            break;
200e0e9324cSopenharmony_ci        }
201e0e9324cSopenharmony_ci    }
202e0e9324cSopenharmony_ci
203e0e9324cSopenharmony_ci    if (!isValidChannels) {
204e0e9324cSopenharmony_ci        SHARING_LOGE("Unsupported sample ratefailed.");
205e0e9324cSopenharmony_ci        return -1;
206e0e9324cSopenharmony_ci    }
207e0e9324cSopenharmony_ci
208e0e9324cSopenharmony_ci    params.sampleFormat = AudioStandard::SAMPLE_S16LE;
209e0e9324cSopenharmony_ci    params.encodingType = AudioStandard::ENCODING_PCM;
210e0e9324cSopenharmony_ci    SHARING_LOGD("channels:%{public}d, sampleRate:%{public}d.", params.channelCount, params.sampleRate);
211e0e9324cSopenharmony_ci
212e0e9324cSopenharmony_ci    if (audioRenderer_->SetParams(params) != 0) {
213e0e9324cSopenharmony_ci        SHARING_LOGE("failed.");
214e0e9324cSopenharmony_ci        return -1;
215e0e9324cSopenharmony_ci    }
216e0e9324cSopenharmony_ci
217e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
218e0e9324cSopenharmony_ci}
219e0e9324cSopenharmony_ci
220e0e9324cSopenharmony_ciint32_t AudioSink::GetParameters(int32_t &bitsPerSample, int32_t &channels, int32_t &sampleRate)
221e0e9324cSopenharmony_ci{
222e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
223e0e9324cSopenharmony_ci    if (!audioRenderer_) {
224e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
225e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
226e0e9324cSopenharmony_ci    }
227e0e9324cSopenharmony_ci
228e0e9324cSopenharmony_ci    AudioStandard::AudioRendererParams params;
229e0e9324cSopenharmony_ci    if (audioRenderer_->GetParams(params) != 0) {
230e0e9324cSopenharmony_ci        SHARING_LOGE("failed.");
231e0e9324cSopenharmony_ci        return -1;
232e0e9324cSopenharmony_ci    }
233e0e9324cSopenharmony_ci
234e0e9324cSopenharmony_ci    channels = params.channelCount;
235e0e9324cSopenharmony_ci    sampleRate = params.sampleRate;
236e0e9324cSopenharmony_ci    bitsPerSample = (int32_t)params.sampleFormat;
237e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
238e0e9324cSopenharmony_ci}
239e0e9324cSopenharmony_ci
240e0e9324cSopenharmony_ciint32_t AudioSink::GetBufferSize(int32_t &bufferSize)
241e0e9324cSopenharmony_ci{
242e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
243e0e9324cSopenharmony_ci    if (!audioRenderer_) {
244e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
245e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
246e0e9324cSopenharmony_ci    }
247e0e9324cSopenharmony_ci
248e0e9324cSopenharmony_ci    size_t size = 0;
249e0e9324cSopenharmony_ci    if (audioRenderer_->GetBufferSize(size) != 0) {
250e0e9324cSopenharmony_ci        SHARING_LOGE("failed!");
251e0e9324cSopenharmony_ci        return -1;
252e0e9324cSopenharmony_ci    }
253e0e9324cSopenharmony_ci
254e0e9324cSopenharmony_ci    bufferSize = (int32_t)size;
255e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
256e0e9324cSopenharmony_ci}
257e0e9324cSopenharmony_ci
258e0e9324cSopenharmony_ciint32_t AudioSink::SetVolume(float volume)
259e0e9324cSopenharmony_ci{
260e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
261e0e9324cSopenharmony_ci    if (!audioRenderer_) {
262e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
263e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
264e0e9324cSopenharmony_ci    }
265e0e9324cSopenharmony_ci
266e0e9324cSopenharmony_ci    if (audioRenderer_->SetVolume(volume) != 0) {
267e0e9324cSopenharmony_ci        SHARING_LOGE("failed!");
268e0e9324cSopenharmony_ci        return -1;
269e0e9324cSopenharmony_ci    }
270e0e9324cSopenharmony_ci
271e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
272e0e9324cSopenharmony_ci}
273e0e9324cSopenharmony_ci
274e0e9324cSopenharmony_ciint32_t AudioSink::GetVolume(float &volume)
275e0e9324cSopenharmony_ci{
276e0e9324cSopenharmony_ci    SHARING_LOGD("playerId: %{public}u.", playerId_);
277e0e9324cSopenharmony_ci    if (!audioRenderer_) {
278e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
279e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
280e0e9324cSopenharmony_ci    }
281e0e9324cSopenharmony_ci
282e0e9324cSopenharmony_ci    volume = audioRenderer_->GetVolume();
283e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
284e0e9324cSopenharmony_ci}
285e0e9324cSopenharmony_ci
286e0e9324cSopenharmony_ciint32_t AudioSink::Write(uint8_t *buffer, size_t size)
287e0e9324cSopenharmony_ci{
288e0e9324cSopenharmony_ci    MEDIA_LOGD("playerId: %{public}u.", playerId_);
289e0e9324cSopenharmony_ci    if (!audioRenderer_) {
290e0e9324cSopenharmony_ci        SHARING_LOGE("audioRenderer_ is NULL.");
291e0e9324cSopenharmony_ci        return PLAYER_ERROR_EMPTY_INSTANCE;
292e0e9324cSopenharmony_ci    }
293e0e9324cSopenharmony_ci
294e0e9324cSopenharmony_ci    size_t bytesWritten = 0;
295e0e9324cSopenharmony_ci    int32_t bytesSingle = 0;
296e0e9324cSopenharmony_ci    while (audioRenderer_ && bytesWritten < size && running_) {
297e0e9324cSopenharmony_ci        bytesSingle = audioRenderer_->Write(buffer + bytesWritten, size - bytesWritten);
298e0e9324cSopenharmony_ci        if (bytesSingle <= 0) {
299e0e9324cSopenharmony_ci            MEDIA_LOGE("audioRenderer Write failed. playerId: %{public}u.", playerId_);
300e0e9324cSopenharmony_ci            continue;
301e0e9324cSopenharmony_ci        }
302e0e9324cSopenharmony_ci
303e0e9324cSopenharmony_ci        bytesWritten += static_cast<size_t>(bytesSingle);
304e0e9324cSopenharmony_ci        if (bytesWritten < static_cast<size_t>(bytesSingle)) {
305e0e9324cSopenharmony_ci            MEDIA_LOGE("audioRenderer Write failed playerId: %{public}u.", playerId_);
306e0e9324cSopenharmony_ci            continue;
307e0e9324cSopenharmony_ci        }
308e0e9324cSopenharmony_ci        MEDIA_LOGD("audioRenderer Write end. playerId: %{public}u.", playerId_);
309e0e9324cSopenharmony_ci    }
310e0e9324cSopenharmony_ci
311e0e9324cSopenharmony_ci    MEDIA_LOGD("recv data(len:%{public}zu.)", size);
312e0e9324cSopenharmony_ci    return PLAYER_SUCCESS;
313e0e9324cSopenharmony_ci}
314e0e9324cSopenharmony_ci
315e0e9324cSopenharmony_ci} // namespace Sharing
316e0e9324cSopenharmony_ci} // namespace OHOS