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