1 /*
2 * Copyright (c) 2024 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_resample.h"
16 #include "audio_errors.h"
17 #include "audio_service_log.h"
18 #include "audio_utils.h"
19 #include <cinttypes>
20 #ifdef SPEEX_ENABLE
21 #include <speex/speex_resampler.h>
22 #endif
23
24 namespace OHOS {
25 namespace AudioStandard {
26 struct AudioResample::SpeexResample {
27 #ifdef SPEEX_ENABLE
28 SpeexResamplerState *resampler;
29 uint32_t channelCount_;
30 #endif
31 };
AudioResample(uint32_t channels,uint32_t inRate,uint32_t outRate,int32_t quantity)32 AudioResample::AudioResample(uint32_t channels, uint32_t inRate, uint32_t outRate, int32_t quantity) : speex_(nullptr)
33 {
34 #ifdef SPEEX_ENABLE
35 int32_t error;
36 speex_ = std::make_unique<SpeexResample>();
37 speex_->channelCount_ = channels;
38 speex_->resampler = speex_resampler_init(channels, inRate, outRate, quantity, &error);
39 if (speex_->resampler) {
40 speex_resampler_skip_zeros(speex_->resampler);
41 } else {
42 AUDIO_INFO_LOG("create resample failed.");
43 speex_ = nullptr;
44 }
45 #endif
46 }
47
IsResampleInit() const48 bool AudioResample::IsResampleInit() const noexcept
49 {
50 if (speex_) {
51 return true;
52 }
53 return false;
54 }
55
~AudioResample()56 AudioResample::~AudioResample()
57 {
58 if (!speex_) {
59 return;
60 }
61 #ifdef SPEEX_ENABLE
62 if (!speex_->resampler)
63 return;
64 speex_resampler_destroy(speex_->resampler);
65 #endif
66 }
67
ProcessFloatResample(const std::vector<float> & input,std::vector<float> & output)68 int32_t AudioResample::ProcessFloatResample(const std::vector<float> &input, std::vector<float> &output)
69 {
70 int32_t ret = 0;
71 if (!speex_) {
72 return ERR_INVALID_PARAM;
73 }
74 #ifdef SPEEX_ENABLE
75 if (speex_->channelCount_ <= 0) {
76 return ERR_INVALID_PARAM;
77 }
78 uint32_t inSize = input.size() / speex_->channelCount_;
79 uint32_t outSize = output.size() / speex_->channelCount_;
80 ret = speex_resampler_process_interleaved_float(speex_->resampler, input.data(), &inSize, output.data(), &outSize);
81 AUDIO_DEBUG_LOG("after in size:%{public}d,out size:%{public}d,result:%{public}d", inSize, outSize, ret);
82 #endif
83 return ret;
84 }
85 } // namespace AudioStandard
86 } // namespace OHOS
87