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 LoadChangeSpeedFunc();
50
51 return SUCCESS;
52 }
53
LoadChangeSpeedFunc()54 int32_t AudioSpeed::LoadChangeSpeedFunc()
55 {
56 switch (format_) {
57 case SAMPLE_U8:
58 formatSize_ = 1; // size is 1
59 ChangeSpeedFunc = [this] (uint8_t *buffer, int32_t bufferSize,
60 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)-> int32_t {
61 return this->ChangeSpeedFor8Bit(buffer, bufferSize, outBuffer, outBufferSize);
62 };
63 break;
64 case SAMPLE_S16LE:
65 formatSize_ = 2; // size is 2
66 ChangeSpeedFunc = [this] (uint8_t *buffer, int32_t bufferSize,
67 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)-> int32_t {
68 return this->ChangeSpeedFor16Bit(buffer, bufferSize, outBuffer, outBufferSize);
69 };
70 break;
71 case SAMPLE_S24LE:
72 formatSize_ = 3; // size is 3
73 ChangeSpeedFunc = [this] (uint8_t *buffer, int32_t bufferSize,
74 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)-> int32_t {
75 return this->ChangeSpeedFor24Bit(buffer, bufferSize, outBuffer, outBufferSize);
76 };
77 break;
78 case SAMPLE_S32LE:
79 formatSize_ = 4; // size is 4
80 ChangeSpeedFunc = [this] (uint8_t *buffer, int32_t bufferSize,
81 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)-> int32_t {
82 return this->ChangeSpeedFor32Bit(buffer, bufferSize, outBuffer, outBufferSize);
83 };
84 break;
85 default:
86 formatSize_ = 2; // size is 2
87 ChangeSpeedFunc = [this] (uint8_t *buffer, int32_t bufferSize,
88 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)-> int32_t {
89 return this->ChangeSpeedFor16Bit(buffer, bufferSize, outBuffer, outBufferSize);
90 };
91 }
92 AUDIO_INFO_LOG("load change speed func for format %{public}zu", format_);
93 return SUCCESS;
94 }
95
SetSpeed(float speed)96 int32_t AudioSpeed::SetSpeed(float speed)
97 {
98 AUDIO_INFO_LOG("SetSpeed %{public}f", speed);
99 speed_ = speed;
100 sonicSetSpeed(sonicStream_, speed_);
101 return SUCCESS;
102 }
103
GetSpeed()104 float AudioSpeed::GetSpeed()
105 {
106 return speed_;
107 }
108
ChangeSpeedFor8Bit(uint8_t * buffer,int32_t bufferSize,std::unique_ptr<uint8_t[]> & outBuffer,int32_t & outBufferSize)109 int32_t AudioSpeed::ChangeSpeedFor8Bit(uint8_t *buffer, int32_t bufferSize,
110 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)
111 {
112 Trace trace("AudioSpeed::ChangeSpeedFor8Bit");
113 int32_t numSamples = bufferSize / static_cast<int32_t>(formatSize_ * channels_);
114 int32_t res = sonicWriteUnsignedCharToStream(sonicStream_, static_cast<unsigned char*>(buffer), numSamples);
115 CHECK_AND_RETURN_RET_LOG(res == 1, 0, "sonic write unsigned char to stream failed.");
116
117 int32_t outSamples = sonicReadUnsignedCharFromStream(sonicStream_,
118 static_cast<unsigned char*>(outBuffer.get()), MAX_BUFFER_SIZE);
119 CHECK_AND_RETURN_RET_LOG(outSamples != 0, bufferSize, "sonic stream is not full continue to write.");
120
121 outBufferSize = outSamples * static_cast<int32_t>(formatSize_ * channels_);
122 return bufferSize;
123 }
124
ChangeSpeedFor16Bit(uint8_t * buffer,int32_t bufferSize,std::unique_ptr<uint8_t[]> & outBuffer,int32_t & outBufferSize)125 int32_t AudioSpeed::ChangeSpeedFor16Bit(uint8_t *buffer, int32_t bufferSize,
126 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)
127 {
128 Trace trace("AudioSpeed::ChangeSpeedFor16Bit");
129 int32_t numSamples = bufferSize / static_cast<int32_t>(formatSize_ * channels_);
130 int32_t res = sonicWriteShortToStream(sonicStream_, reinterpret_cast<short*>(buffer), numSamples);
131 CHECK_AND_RETURN_RET_LOG(res == 1, 0, "sonic write short to stream failed.");
132
133 int32_t outSamples = sonicReadShortFromStream(sonicStream_, reinterpret_cast<short*>(outBuffer.get()),
134 MAX_BUFFER_SIZE);
135 CHECK_AND_RETURN_RET_LOG(outSamples != 0, bufferSize, "sonic stream is not full continue to write.");
136
137 outBufferSize = outSamples * static_cast<int32_t>(formatSize_ * channels_);
138 return bufferSize;
139 }
140
ChangeSpeedFor24Bit(uint8_t * buffer,int32_t bufferSize,std::unique_ptr<uint8_t[]> & outBuffer,int32_t & outBufferSize)141 int32_t AudioSpeed::ChangeSpeedFor24Bit(uint8_t *buffer, int32_t bufferSize,
142 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)
143 {
144 Trace trace("AudioSpeed::ChangeSpeedFor24Bit");
145 if (bufferSize <= 0 || bufferSize > MAX_BUFFER_SIZE) {
146 AUDIO_ERR_LOG("BufferSize is illegal");
147 return ERR_MEMORY_ALLOC_FAILED;
148 }
149 float *bitTofloat = new (std::nothrow) float[bufferSize];
150 if (bitTofloat == nullptr) {
151 AUDIO_ERR_LOG("bitTofloat nullptr, No memory");
152 return ERR_MEMORY_ALLOC_FAILED;
153 }
154 ConvertFrom24BitToFloat(bufferSize / formatSize_, buffer, bitTofloat);
155
156 float *speedBuf = new (std::nothrow) float[MAX_BUFFER_SIZE];
157 if (speedBuf == nullptr) {
158 AUDIO_ERR_LOG("speedBuf nullptr, No memory");
159 delete [] bitTofloat;
160 return ERR_MEMORY_ALLOC_FAILED;
161 }
162 int32_t ret = ChangeSpeedForFloat(bitTofloat, bufferSize, speedBuf, outBufferSize);
163
164 ConvertFromFloatTo24Bit(outBufferSize / formatSize_, speedBuf, outBuffer.get());
165
166 delete [] bitTofloat;
167 delete [] speedBuf;
168 return ret;
169 }
170
ChangeSpeedFor32Bit(uint8_t * buffer,int32_t bufferSize,std::unique_ptr<uint8_t[]> & outBuffer,int32_t & outBufferSize)171 int32_t AudioSpeed::ChangeSpeedFor32Bit(uint8_t *buffer, int32_t bufferSize,
172 std::unique_ptr<uint8_t []> &outBuffer, int32_t &outBufferSize)
173 {
174 Trace trace("AudioSpeed::ChangeSpeedFor32Bit");
175 if (bufferSize <= 0 || bufferSize > MAX_BUFFER_SIZE) {
176 AUDIO_ERR_LOG("BufferSize is illegal");
177 return ERR_MEMORY_ALLOC_FAILED;
178 }
179 float *bitTofloat = new (std::nothrow) float[bufferSize];
180 if (bitTofloat == nullptr) {
181 AUDIO_ERR_LOG("bitTofloat nullptr, No memory");
182 return ERR_MEMORY_ALLOC_FAILED;
183 }
184 ConvertFrom32BitToFloat(bufferSize / formatSize_, reinterpret_cast<int32_t *>(buffer), bitTofloat);
185
186 float *speedBuf = new (std::nothrow) float[MAX_BUFFER_SIZE];
187 if (speedBuf == nullptr) {
188 AUDIO_ERR_LOG("speedBuf nullptr, No memory");
189 delete [] bitTofloat;
190 return ERR_MEMORY_ALLOC_FAILED;
191 }
192 int32_t ret = ChangeSpeedForFloat(bitTofloat, bufferSize, speedBuf, outBufferSize);
193
194 ConvertFromFloatTo32Bit(outBufferSize / formatSize_, speedBuf, reinterpret_cast<int32_t *>(outBuffer.get()));
195
196 delete [] bitTofloat;
197 delete [] speedBuf;
198 return ret;
199 }
200
ChangeSpeedForFloat(float * buffer,int32_t bufferSize,float * outBuffer,int32_t & outBufferSize)201 int32_t AudioSpeed::ChangeSpeedForFloat(float *buffer, int32_t bufferSize,
202 float* outBuffer, int32_t &outBufferSize)
203 {
204 Trace trace("AudioSpeed::ChangeSpeedForFloat");
205 int32_t numSamples = bufferSize / static_cast<int32_t>(formatSize_ * channels_);
206 int32_t res = static_cast<int32_t>(sonicWriteFloatToStream(sonicStream_, buffer, numSamples));
207 CHECK_AND_RETURN_RET_LOG(res == 1, 0, "sonic write float to stream failed.");
208 int32_t outSamples = sonicReadFloatFromStream(sonicStream_, outBuffer, MAX_BUFFER_SIZE);
209 outBufferSize = outSamples * static_cast<int32_t>(formatSize_ * channels_);
210 return bufferSize;
211 }
212 } // namespace AudioStandard
213 } // namespace OHOS
214