• 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 #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