blob: 8c56319da4c7ebae23644cf8d76a16587ce25a55 [file] [log] [blame]
Andy Hung86eae0e2013-12-09 12:12:46 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_AUDIO_RESAMPLER_DYN_H
18#define ANDROID_AUDIO_RESAMPLER_DYN_H
19
20#include <stdint.h>
21#include <sys/types.h>
22#include <cutils/log.h>
23
24#include "AudioResampler.h"
25
26namespace android {
27
Andy Hung771386e2014-04-08 18:44:38 -070028/* AudioResamplerDyn
29 *
30 * This class template is used for floating point and integer resamplers.
31 *
32 * Type variables:
33 * TC = filter coefficient type (one of int16_t, int32_t, or float)
34 * TI = input data type (one of int16_t or float)
35 * TO = output data type (one of int32_t or float)
36 *
37 * For integer input data types TI, the coefficient type TC is either int16_t or int32_t.
38 * For float input data types TI, the coefficient type TC is float.
39 */
40
41template<typename TC, typename TI, typename TO>
Andy Hung86eae0e2013-12-09 12:12:46 -080042class AudioResamplerDyn: public AudioResampler {
43public:
Andy Hung771386e2014-04-08 18:44:38 -070044 AudioResamplerDyn(int bitDepth, int inChannelCount,
45 int32_t sampleRate, src_quality quality);
Andy Hung86eae0e2013-12-09 12:12:46 -080046
47 virtual ~AudioResamplerDyn();
48
49 virtual void init();
50
51 virtual void setSampleRate(int32_t inSampleRate);
52
53 virtual void setVolume(int16_t left, int16_t right);
54
55 virtual void resample(int32_t* out, size_t outFrameCount,
56 AudioBufferProvider* provider);
57
58private:
59
60 class Constants { // stores the filter constants.
61 public:
62 Constants() :
Andy Hung771386e2014-04-08 18:44:38 -070063 mL(0), mShift(0), mHalfNumCoefs(0), mFirCoefs(NULL)
Andy Hung86eae0e2013-12-09 12:12:46 -080064 {}
65 void set(int L, int halfNumCoefs,
66 int inSampleRate, int outSampleRate);
Andy Hung86eae0e2013-12-09 12:12:46 -080067
Andy Hung771386e2014-04-08 18:44:38 -070068 int mL; // interpolation phases in the filter.
69 int mShift; // right shift to get polyphase index
Andy Hung86eae0e2013-12-09 12:12:46 -080070 unsigned int mHalfNumCoefs; // filter half #coefs
Andy Hung771386e2014-04-08 18:44:38 -070071 const TC* mFirCoefs; // polyphase filter bank
Andy Hung86eae0e2013-12-09 12:12:46 -080072 };
73
Andy Hung771386e2014-04-08 18:44:38 -070074 class InBuffer { // buffer management for input type TI
Andy Hung86eae0e2013-12-09 12:12:46 -080075 public:
76 InBuffer();
77 ~InBuffer();
78 void init();
Andy Hung771386e2014-04-08 18:44:38 -070079
Andy Hung86eae0e2013-12-09 12:12:46 -080080 void resize(int CHANNELS, int halfNumCoefs);
81
82 // used for direct management of the mImpulse pointer
83 inline TI* getImpulse() {
84 return mImpulse;
85 }
Andy Hung771386e2014-04-08 18:44:38 -070086
Andy Hung86eae0e2013-12-09 12:12:46 -080087 inline void setImpulse(TI *impulse) {
88 mImpulse = impulse;
89 }
Andy Hung771386e2014-04-08 18:44:38 -070090
Andy Hung86eae0e2013-12-09 12:12:46 -080091 template<int CHANNELS>
92 inline void readAgain(TI*& impulse, const int halfNumCoefs,
93 const TI* const in, const size_t inputIndex);
Andy Hung771386e2014-04-08 18:44:38 -070094
Andy Hung86eae0e2013-12-09 12:12:46 -080095 template<int CHANNELS>
96 inline void readAdvance(TI*& impulse, const int halfNumCoefs,
97 const TI* const in, const size_t inputIndex);
98
99 private:
100 // tuning parameter guidelines: 2 <= multiple <= 8
101 static const int kStateSizeMultipleOfFilterLength = 4;
102
Andy Hung86eae0e2013-12-09 12:12:46 -0800103 // in general, mRingFull = mState + mStateSize - halfNumCoefs*CHANNELS.
Andy Hung771386e2014-04-08 18:44:38 -0700104 TI* mState; // base pointer for the input buffer storage
105 TI* mImpulse; // current location of the impulse response (centered)
106 TI* mRingFull; // mState <= mImpulse < mRingFull
107 size_t mStateCount; // size of state in units of TI.
Andy Hung86eae0e2013-12-09 12:12:46 -0800108 };
109
Andy Hung86eae0e2013-12-09 12:12:46 -0800110 void createKaiserFir(Constants &c, double stopBandAtten,
111 int inSampleRate, int outSampleRate, double tbwCheat);
112
Andy Hung771386e2014-04-08 18:44:38 -0700113 void setResampler(unsigned resampleType);
114
115 template<int CHANNELS, bool LOCKED, int STRIDE>
116 void resample(TO* out, size_t outFrameCount, AudioBufferProvider* provider);
117
118 // declare a pointer to member function for resample
119 typedef void (AudioResamplerDyn<TC, TI, TO>::*resample_ABP_t)(TO* out,
120 size_t outFrameCount, AudioBufferProvider* provider);
121
122 // data - the contiguous storage and layout of these is important.
123 InBuffer mInBuffer;
124 Constants mConstants; // current set of coefficient parameters
125 TO __attribute__ ((aligned (8))) mVolumeSimd[2]; // must be aligned or NEON may crash
126 resample_ABP_t mResampleFunc; // called function for resampling
127 int32_t mFilterSampleRate; // designed filter sample rate.
128 src_quality mFilterQuality; // designed filter quality.
129 void* mCoefBuffer; // if a filter is created, this is not null
Andy Hung86eae0e2013-12-09 12:12:46 -0800130};
131
Andy Hung86eae0e2013-12-09 12:12:46 -0800132}; // namespace android
133
134#endif /*ANDROID_AUDIO_RESAMPLER_DYN_H*/