1 /*
2 * Copyright (c) 2024-2025 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 <cinttypes>
19 #ifdef SPEEX_ENABLE
20 #include <speex/speex_resampler.h>
21 #endif
22
23 namespace OHOS {
24 namespace AudioStandard {
25 struct AudioResample::SpeexResample {
26 #ifdef SPEEX_ENABLE
27 SpeexResamplerState *resampler;
28 uint32_t channelCount_;
29 #endif
30 };
AudioResample(uint32_t channels,uint32_t inRate,uint32_t outRate,int32_t quantity)31 AudioResample::AudioResample(uint32_t channels, uint32_t inRate, uint32_t outRate, int32_t quantity) : speex_(nullptr)
32 {
33 #ifdef SPEEX_ENABLE
34 int32_t error;
35 speex_ = std::make_unique<SpeexResample>();
36 speex_->channelCount_ = channels;
37 speex_->resampler = speex_resampler_init(channels, inRate, outRate, quantity, &error);
38 if (speex_->resampler) {
39 speex_resampler_skip_zeros(speex_->resampler);
40 } else {
41 AUDIO_INFO_LOG("create resample failed.");
42 speex_ = nullptr;
43 }
44 #endif
45 }
46
IsResampleInit() const47 bool AudioResample::IsResampleInit() const noexcept
48 {
49 if (speex_) {
50 return true;
51 }
52 return false;
53 }
54
~AudioResample()55 AudioResample::~AudioResample()
56 {
57 if (!speex_) {
58 return;
59 }
60 #ifdef SPEEX_ENABLE
61 if (!speex_->resampler)
62 return;
63 speex_resampler_destroy(speex_->resampler);
64 #endif
65 }
66
ProcessFloatResample(const std::vector<float> & input,std::vector<float> & output)67 int32_t AudioResample::ProcessFloatResample(const std::vector<float> &input, std::vector<float> &output)
68 {
69 int32_t ret = 0;
70 if (!speex_) {
71 return ERR_INVALID_PARAM;
72 }
73 #ifdef SPEEX_ENABLE
74 Trace trace("AudioResample::ProcessFloatResample");
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