• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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