1 /*
2 * Copyright (c) 2023 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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioSpeed"
17 #endif
18
19 #include "audio_speed.h"
20 #include "audio_common_log.h"
21 #include "audio_utils.h"
22 #include "audio_errors.h"
23
24 namespace OHOS {
25 namespace AudioStandard {
26
27 static const int32_t MAX_BUFFER_SIZE = 100000;
28
AudioSpeed(size_t rate,size_t format,size_t channels)29 AudioSpeed::AudioSpeed(size_t rate, size_t format, size_t channels):rate_(rate), format_(format), channels_(channels)
30 {
31 AUDIO_INFO_LOG("AudioSpeed construct");
32 Init();
33 streamParam_ = {};
34 }
35
~AudioSpeed()36 AudioSpeed::~AudioSpeed()
37 {
38 AUDIO_INFO_LOG("~AudioSpeed destroy");
39 if (sonicStream_ != nullptr) {
40 sonicDestroyStream(sonicStream_);
41 sonicStream_ = nullptr;
42 AUDIO_INFO_LOG("Sonic stream destroy");
43 }
44 }
45
Init()46 int32_t AudioSpeed::Init()
47 {
48 sonicStream_ = sonicCreateStream(rate_, channels_);
49 CHECK_AND_RETURN_RET_LOG(sonicStream_ != nullptr, ERROR, "sonicCreateStream failed.");
50 LoadChangeSpeedFunc();
51
52 return SUCCESS;
53 }
54
LoadChangeSpeedFunc()55 int32_t AudioSpeed::LoadChangeSpeedFunc()
56 {
57 switch (format_) {
58 case SAMPLE_U8:
59 formatSize_ = 1; // size is 1
60 ChangeSpeedFunc = [this] (uint8_t *buffer, int32_t bufferSize,
61 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)-> int32_t {
62 return this->ChangeSpeedFor8Bit(buffer, bufferSize, outBuffer, outBufferSize);
63 };
64 break;
65 case SAMPLE_S16LE:
66 formatSize_ = 2; // size is 2
67 ChangeSpeedFunc = [this] (uint8_t *buffer, int32_t bufferSize,
68 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)-> int32_t {
69 return this->ChangeSpeedFor16Bit(buffer, bufferSize, outBuffer, outBufferSize);
70 };
71 break;
72 case SAMPLE_S24LE:
73 formatSize_ = 3; // size is 3
74 ChangeSpeedFunc = [this] (uint8_t *buffer, int32_t bufferSize,
75 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)-> int32_t {
76 return this->ChangeSpeedFor24Bit(buffer, bufferSize, outBuffer, outBufferSize);
77 };
78 break;
79 case SAMPLE_S32LE:
80 formatSize_ = 4; // size is 4
81 ChangeSpeedFunc = [this] (uint8_t *buffer, int32_t bufferSize,
82 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)-> int32_t {
83 return this->ChangeSpeedFor32Bit(buffer, bufferSize, outBuffer, outBufferSize);
84 };
85 break;
86 case SAMPLE_F32LE:
87 formatSize_ = 4; // size is 4
88 ChangeSpeedFunc = [this] (uint8_t *buffer, int32_t bufferSize,
89 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)-> int32_t {
90 return this->ChangeSpeedForFloat(reinterpret_cast<float*>(buffer), bufferSize,
91 reinterpret_cast<float*>(outBuffer.get()), outBufferSize);
92 };
93 break;
94 default:
95 formatSize_ = 2; // size is 2
96 ChangeSpeedFunc = [this] (uint8_t *buffer, int32_t bufferSize,
97 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)-> int32_t {
98 return this->ChangeSpeedFor16Bit(buffer, bufferSize, outBuffer, outBufferSize);
99 };
100 }
101 AUDIO_INFO_LOG("load change speed func for format %{public}zu", format_);
102 return SUCCESS;
103 }
104
SetSpeed(float speed)105 int32_t AudioSpeed::SetSpeed(float speed)
106 {
107 AUDIO_INFO_LOG("SetSpeed %{public}f", speed);
108 speed_ = speed;
109 sonicSetSpeed(sonicStream_, speed_);
110 return SUCCESS;
111 }
112
GetSpeed()113 float AudioSpeed::GetSpeed()
114 {
115 return speed_;
116 }
117
ChangeSpeedFor8Bit(uint8_t * buffer,int32_t bufferSize,std::unique_ptr<uint8_t[]> & outBuffer,int32_t & outBufferSize)118 int32_t AudioSpeed::ChangeSpeedFor8Bit(uint8_t *buffer, int32_t bufferSize,
119 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)
120 {
121 Trace trace("AudioSpeed::ChangeSpeedFor8Bit");
122 int32_t numSamples = bufferSize / static_cast<int32_t>(formatSize_ * channels_);
123 int32_t res = sonicWriteUnsignedCharToStream(sonicStream_, static_cast<unsigned char*>(buffer), numSamples);
124 CHECK_AND_RETURN_RET_LOG(res == 1, 0, "sonic write unsigned char to stream failed.");
125
126 int32_t outSamples = sonicReadUnsignedCharFromStream(sonicStream_,
127 static_cast<unsigned char*>(outBuffer.get()), MAX_BUFFER_SIZE);
128 CHECK_AND_RETURN_RET_LOG(outSamples != 0, bufferSize, "sonic stream is not full continue to write.");
129
130 outBufferSize = outSamples * static_cast<int32_t>(formatSize_ * channels_);
131 return bufferSize;
132 }
133
ChangeSpeedFor16Bit(uint8_t * buffer,int32_t bufferSize,std::unique_ptr<uint8_t[]> & outBuffer,int32_t & outBufferSize)134 int32_t AudioSpeed::ChangeSpeedFor16Bit(uint8_t *buffer, int32_t bufferSize,
135 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)
136 {
137 Trace trace("AudioSpeed::ChangeSpeedFor16Bit");
138 int32_t numSamples = bufferSize / static_cast<int32_t>(formatSize_ * channels_);
139 int32_t res = sonicWriteShortToStream(sonicStream_, reinterpret_cast<short*>(buffer), numSamples);
140 CHECK_AND_RETURN_RET_LOG(res == 1, 0, "sonic write short to stream failed.");
141
142 int32_t outSamples = sonicReadShortFromStream(sonicStream_, reinterpret_cast<short*>(outBuffer.get()),
143 MAX_BUFFER_SIZE);
144 CHECK_AND_RETURN_RET_LOG(outSamples != 0, bufferSize, "sonic stream is not full continue to write.");
145
146 outBufferSize = outSamples * static_cast<int32_t>(formatSize_ * channels_);
147 return bufferSize;
148 }
149
ChangeSpeedFor24Bit(uint8_t * buffer,int32_t bufferSize,std::unique_ptr<uint8_t[]> & outBuffer,int32_t & outBufferSize)150 int32_t AudioSpeed::ChangeSpeedFor24Bit(uint8_t *buffer, int32_t bufferSize,
151 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)
152 {
153 Trace trace("AudioSpeed::ChangeSpeedFor24Bit");
154 if (bufferSize <= 0 || bufferSize > MAX_BUFFER_SIZE) {
155 AUDIO_ERR_LOG("BufferSize is illegal");
156 return ERR_MEMORY_ALLOC_FAILED;
157 }
158 float *bitTofloat = new (std::nothrow) float[bufferSize];
159 if (bitTofloat == nullptr) {
160 AUDIO_ERR_LOG("bitTofloat nullptr, No memory");
161 return ERR_MEMORY_ALLOC_FAILED;
162 }
163 ConvertFrom24BitToFloat(bufferSize / formatSize_, buffer, bitTofloat);
164
165 float *speedBuf = new (std::nothrow) float[MAX_BUFFER_SIZE];
166 if (speedBuf == nullptr) {
167 AUDIO_ERR_LOG("speedBuf nullptr, No memory");
168 delete [] bitTofloat;
169 return ERR_MEMORY_ALLOC_FAILED;
170 }
171 int32_t ret = ChangeSpeedForFloat(bitTofloat, bufferSize, speedBuf, outBufferSize);
172
173 ConvertFromFloatTo24Bit(outBufferSize / formatSize_, speedBuf, outBuffer.get());
174
175 delete [] bitTofloat;
176 delete [] speedBuf;
177 return ret;
178 }
179
ChangeSpeedFor32Bit(uint8_t * buffer,int32_t bufferSize,std::unique_ptr<uint8_t[]> & outBuffer,int32_t & outBufferSize)180 int32_t AudioSpeed::ChangeSpeedFor32Bit(uint8_t *buffer, int32_t bufferSize,
181 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)
182 {
183 Trace trace("AudioSpeed::ChangeSpeedFor32Bit");
184 if (bufferSize <= 0 || bufferSize > MAX_BUFFER_SIZE) {
185 AUDIO_ERR_LOG("BufferSize is illegal");
186 return ERR_MEMORY_ALLOC_FAILED;
187 }
188 float *bitTofloat = new (std::nothrow) float[bufferSize];
189 if (bitTofloat == nullptr) {
190 AUDIO_ERR_LOG("bitTofloat nullptr, No memory");
191 return ERR_MEMORY_ALLOC_FAILED;
192 }
193 ConvertFrom32BitToFloat(bufferSize / formatSize_, reinterpret_cast<int32_t *>(buffer), bitTofloat);
194
195 float *speedBuf = new (std::nothrow) float[MAX_BUFFER_SIZE];
196 if (speedBuf == nullptr) {
197 AUDIO_ERR_LOG("speedBuf nullptr, No memory");
198 delete [] bitTofloat;
199 return ERR_MEMORY_ALLOC_FAILED;
200 }
201 int32_t ret = ChangeSpeedForFloat(bitTofloat, bufferSize, speedBuf, outBufferSize);
202
203 ConvertFromFloatTo32Bit(outBufferSize / formatSize_, speedBuf, reinterpret_cast<int32_t *>(outBuffer.get()));
204
205 delete [] bitTofloat;
206 delete [] speedBuf;
207 return ret;
208 }
209
ChangeSpeedForFloat(float * buffer,int32_t bufferSize,float * outBuffer,int32_t & outBufferSize)210 int32_t AudioSpeed::ChangeSpeedForFloat(float *buffer, int32_t bufferSize,
211 float* outBuffer, int32_t &outBufferSize)
212 {
213 Trace trace("AudioSpeed::ChangeSpeedForFloat");
214 int32_t numSamples = bufferSize / static_cast<int32_t>(formatSize_ * channels_);
215 int32_t res = static_cast<int32_t>(sonicWriteFloatToStream(sonicStream_, buffer, numSamples));
216 CHECK_AND_RETURN_RET_LOG(res == 1, 0, "sonic write float to stream failed.");
217 int32_t outSamples = sonicReadFloatFromStream(sonicStream_, outBuffer, MAX_BUFFER_SIZE);
218 outBufferSize = outSamples * static_cast<int32_t>(formatSize_ * channels_);
219 return bufferSize;
220 }
221 } // namespace AudioStandard
222 } // namespace OHOS
223