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