VAE - Virtual Audio Engine 1
Small Data Driven Audio Engine
tklb::ResamplerSpeexTpl< T, Buffer > Class Template Reference

#include <TResamplerSpeex.hpp>

Inheritance diagram for tklb::ResamplerSpeexTpl< T, Buffer >:
Collaboration diagram for tklb::ResamplerSpeexTpl< T, Buffer >:

Public Member Functions

 ResamplerSpeexTpl (uint rateIn, uint rateOut, uint maxBlock=512, uchar quality=5)
 
 ResamplerSpeexTpl ()=default
 
 ~ResamplerSpeexTpl ()
 
bool init (uint rateIn, uint rateOut, uint maxBlock=512, uchar maxChannels=2, uchar quality=5)
 setup the resampler More...
 
Size process (const Buffer &in, Buffer &out)
 Resample function Make sure the out buffer has enough space. More...
 
int getLatency () const
 Get the latency in samples. More...
 
Size estimateNeed (const Size out) const
 Estimate how many samples need to be put in to get n samples out. More...
 
Size estimateOut (const Size in) const
 Estimate how many sample will be emitted in the next step. More...
 
bool isInitialized () const
 
Size calculateBufferSize (Size initialSize)
 Calculate a buffersize fit for the resampled result. More...
 

Static Public Member Functions

static void resample (Buffer &buffer, const uint rateOut, const uchar quality=5)
 Resamples the provided buffer from its sampleRate to the target rate. More...
 

Private Types

using uchar = unsigned char
 
using uint = unsigned int
 
using Size = typename Buffer::Size
 

Private Attributes

uint mRateIn
 
uint mRateOut
 
AudioBufferFloat mConvertOut
 
AudioBufferFloat mConvertIn
 
SpeexResamplerState * mState = nullptr
 

Detailed Description

template<typename T, class Buffer = AudioBufferTpl<T>>
class tklb::ResamplerSpeexTpl< T, Buffer >

Definition at line 45 of file TResamplerSpeex.hpp.

Member Typedef Documentation

◆ Size

template<typename T , class Buffer = AudioBufferTpl<T>>
using tklb::ResamplerSpeexTpl< T, Buffer >::Size = typename Buffer::Size
private

Definition at line 48 of file TResamplerSpeex.hpp.

◆ uchar

template<typename T , class Buffer = AudioBufferTpl<T>>
using tklb::ResamplerSpeexTpl< T, Buffer >::uchar = unsigned char
private

Definition at line 46 of file TResamplerSpeex.hpp.

◆ uint

template<typename T , class Buffer = AudioBufferTpl<T>>
using tklb::ResamplerSpeexTpl< T, Buffer >::uint = unsigned int
private

Definition at line 47 of file TResamplerSpeex.hpp.

Constructor & Destructor Documentation

◆ ResamplerSpeexTpl() [1/2]

template<typename T , class Buffer = AudioBufferTpl<T>>
tklb::ResamplerSpeexTpl< T, Buffer >::ResamplerSpeexTpl ( uint  rateIn,
uint  rateOut,
uint  maxBlock = 512,
uchar  quality = 5 
)
inline

Definition at line 55 of file TResamplerSpeex.hpp.

55 {
56 init(rateIn, rateOut, maxBlock, quality);
57 }
bool init(uint rateIn, uint rateOut, uint maxBlock=512, uchar maxChannels=2, uchar quality=5)
setup the resampler
Here is the call graph for this function:

◆ ResamplerSpeexTpl() [2/2]

template<typename T , class Buffer = AudioBufferTpl<T>>
tklb::ResamplerSpeexTpl< T, Buffer >::ResamplerSpeexTpl ( )
default

◆ ~ResamplerSpeexTpl()

template<typename T , class Buffer = AudioBufferTpl<T>>
tklb::ResamplerSpeexTpl< T, Buffer >::~ResamplerSpeexTpl ( )
inline

Definition at line 61 of file TResamplerSpeex.hpp.

61 {
62 if (mState == nullptr) { return; }
63 speex_resampler_destroy(mState);
64 }
SpeexResamplerState * mState

Member Function Documentation

◆ calculateBufferSize()

template<typename T , class Buffer = AudioBufferTpl<T>>
Size tklb::ResamplerSpeexTpl< T, Buffer >::calculateBufferSize ( Size  initialSize)
inline

Calculate a buffersize fit for the resampled result.

Also adds a bit of padding.

Definition at line 174 of file TResamplerSpeex.hpp.

174 {
175 return estimateOut(initialSize) + 10;
176 }
Size estimateOut(const Size in) const
Estimate how many sample will be emitted in the next step.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ estimateNeed()

template<typename T , class Buffer = AudioBufferTpl<T>>
Size tklb::ResamplerSpeexTpl< T, Buffer >::estimateNeed ( const Size  out) const
inline

Estimate how many samples need to be put in to get n samples out.

Definition at line 156 of file TResamplerSpeex.hpp.

156 {
157 return Size(std::floor(out * (double(mRateIn) / double(mRateOut))));
158 }
typename Buffer::Size Size
Here is the caller graph for this function:

◆ estimateOut()

template<typename T , class Buffer = AudioBufferTpl<T>>
Size tklb::ResamplerSpeexTpl< T, Buffer >::estimateOut ( const Size  in) const
inline

Estimate how many sample will be emitted in the next step.

Definition at line 163 of file TResamplerSpeex.hpp.

163 {
164 TKLB_ASSERT(0 < mRateOut && 0 < mRateIn)
165 return (Size) std::round(in * (double(mRateOut) / double(mRateIn)));
166 }
#define TKLB_ASSERT(condition)
Wrap assertions.
Definition: TAssert.h:18
Here is the caller graph for this function:

◆ getLatency()

template<typename T , class Buffer = AudioBufferTpl<T>>
int tklb::ResamplerSpeexTpl< T, Buffer >::getLatency ( ) const
inline

Get the latency in samples.

Definition at line 149 of file TResamplerSpeex.hpp.

149 {
150 return speex_resampler_get_input_latency(mState);
151 }

◆ init()

template<typename T , class Buffer = AudioBufferTpl<T>>
bool tklb::ResamplerSpeexTpl< T, Buffer >::init ( uint  rateIn,
uint  rateOut,
uint  maxBlock = 512,
uchar  maxChannels = 2,
uchar  quality = 5 
)
inline

setup the resampler

Parameters
rateInInput sample rate
rateOutDesired output samplerate
maxBlockThe maximum blocksize beeing passed into process(). Only relevant when doing non float resampling to allocate space for the conversion buffers
qualityQuality factor from 1-10. Higher results in better quality and higher CPU usage. Depending on implementataion may not do anything.
Returns
True on success

Definition at line 76 of file TResamplerSpeex.hpp.

76 {
77 int err;
78 if (rateIn == mRateIn && mRateOut == rateOut && mState != nullptr) {
79 // only clears out old data
80 speex_resampler_reset_mem(mState);
81 } else {
82 if (mState != nullptr) {
83 speex_resampler_destroy(mState);
84 }
85 mState = speex_resampler_init(maxChannels, rateIn, rateOut, quality, &err);
86 }
87
88 mRateIn = rateIn;
89 mRateOut = rateOut;
90 // Conversion buffers if not doing float resampling
91 if (!std::is_same<T, float>::value) {
92 mConvertIn.resize(maxBlock, maxChannels);
93 mConvertOut.resize(calculateBufferSize(maxBlock), maxChannels);
94 }
95 return err == 0;
96 }
bool resize(const Size length, uchar channels)
! Will not keep the contents! Resizes the buffer to the desired length and channel count.
AudioBufferFloat mConvertIn
Size calculateBufferSize(Size initialSize)
Calculate a buffersize fit for the resampled result.
AudioBufferFloat mConvertOut
Here is the call graph for this function:
Here is the caller graph for this function:

◆ isInitialized()

template<typename T , class Buffer = AudioBufferTpl<T>>
bool tklb::ResamplerSpeexTpl< T, Buffer >::isInitialized ( ) const
inline

Definition at line 168 of file TResamplerSpeex.hpp.

168{ return mState != nullptr; }
Here is the caller graph for this function:

◆ process()

template<typename T , class Buffer = AudioBufferTpl<T>>
Size tklb::ResamplerSpeexTpl< T, Buffer >::process ( const Buffer &  in,
Buffer &  out 
)
inline

Resample function Make sure the out buffer has enough space.

Definition at line 102 of file TResamplerSpeex.hpp.

102 {
103 TKLB_ASSERT(in.sampleRate == mRateIn);
104 TKLB_ASSERT(out.sampleRate == mRateOut);
105 TKLB_ASSERT(in.validSize() > 0)
106 TKLB_ASSERT(estimateOut(in.validSize()) <= out.size())
107 Size samplesOut = 0;
108 if (std::is_same<T, float>::value) {
109 // Input output buffer must not overlap when working directly on them
110 TKLB_ASSERT(&in != &out)
111 for (uchar c = 0; c < in.channels(); c++) {
112 spx_uint32_t countIn = in.validSize();
113 spx_uint32_t countOut = out.size();
114 const float* inBuf = reinterpret_cast<const float*>(in[c]);
115 float* outBuf = reinterpret_cast<float*>(out[c]);
116 speex_resampler_process_float(mState, c, inBuf, &countIn, outBuf, &countOut);
117 samplesOut = countOut;
118 }
119 } else {
120 const Size validSamples = in.validSize();
121 const Size blockSize = mConvertIn.size();
122 for (Size i = 0; i < validSamples; i += blockSize) {
123 const Size blockLeft = min(blockSize, validSamples - i);
124 Size samplesEmitted = 0;
125 mConvertIn.set(in, blockLeft, i);
126 for (uchar c = 0; c < in.channels(); c++) {
127 spx_uint32_t countIn = blockLeft;
128 spx_uint32_t countOut = mConvertOut.size();
129 const float* inBuf = mConvertIn[c];
130 float* outBuf = mConvertOut[c];
131 speex_resampler_process_float(mState, c, inBuf, &countIn, outBuf, &countOut);
132 samplesEmitted = countOut;
133 TKLB_ASSERT(mConvertOut.size() >= countOut);
134 }
135 out.set(mConvertOut, samplesEmitted, 0, samplesOut);
136 samplesOut += samplesEmitted;
137 }
138 }
139
140 // There might be some more samples beeing emitted, some padding is needed
141 TKLB_ASSERT(out.size() >= samplesOut);
142 out.setValidSize(samplesOut);
143 return samplesOut;
144 }
void set(const T2 *samples, Size length, const uchar channel=0, const Size offsetDst=0)
Set a single channel from an array.
Size size() const
Returns the allocated length of the buffer.
T min(const T &v1, const T &v2)
Definition: TMath.hpp:16
Here is the call graph for this function:
Here is the caller graph for this function:

◆ resample()

template<typename T , class Buffer = AudioBufferTpl<T>>
static void tklb::ResamplerSpeexTpl< T, Buffer >::resample ( Buffer &  buffer,
const uint  rateOut,
const uchar  quality = 5 
)
inlinestatic

Resamples the provided buffer from its sampleRate to the target rate.

Parameters
bufferAudiobuffer to resample, set the rate of the buffer object
rateOutDesired output samplerate in Hz
qualityQuality from 1-10

Definition at line 185 of file TResamplerSpeex.hpp.

185 {
186 // TODO tklb compensate delay
187 const uint rateIn = buffer.sampleRate;
188 const Size samples = buffer.size();
189 TKLB_ASSERT(rateIn > 0)
190 // Make a copy, this could be skipped when a conversion to float is needed anyways
191 Buffer copy;
192 copy.resize(buffer);
193 copy.set(buffer);
194 copy.sampleRate = rateIn;
195 buffer.sampleRate = rateOut;
196 copy.setValidSize(samples);
197
198 ResamplerSpeexTpl<T, Buffer> resampler;
199 resampler.init(rateIn, rateOut, copy.size(), buffer.channels(), quality);
200 buffer.resize(resampler.calculateBufferSize(samples));
201
202 resampler.process(copy, buffer);
203 }
Size process(const Buffer &in, Buffer &out)
Resample function Make sure the out buffer has enough space.
static void set(void *dst, const unsigned char val, size_t size)
memset wrapper
Definition: TMemoryUtil.hpp:40
static void copy(void *dst, const void *src, const size_t size)
memcpy wrapper
Definition: TMemoryUtil.hpp:14
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mConvertIn

template<typename T , class Buffer = AudioBufferTpl<T>>
AudioBufferFloat tklb::ResamplerSpeexTpl< T, Buffer >::mConvertIn
private

Definition at line 51 of file TResamplerSpeex.hpp.

◆ mConvertOut

template<typename T , class Buffer = AudioBufferTpl<T>>
AudioBufferFloat tklb::ResamplerSpeexTpl< T, Buffer >::mConvertOut
private

Definition at line 51 of file TResamplerSpeex.hpp.

◆ mRateIn

template<typename T , class Buffer = AudioBufferTpl<T>>
uint tklb::ResamplerSpeexTpl< T, Buffer >::mRateIn
private

Definition at line 50 of file TResamplerSpeex.hpp.

◆ mRateOut

template<typename T , class Buffer = AudioBufferTpl<T>>
uint tklb::ResamplerSpeexTpl< T, Buffer >::mRateOut
private

Definition at line 50 of file TResamplerSpeex.hpp.

◆ mState

template<typename T , class Buffer = AudioBufferTpl<T>>
SpeexResamplerState* tklb::ResamplerSpeexTpl< T, Buffer >::mState = nullptr
private

Definition at line 52 of file TResamplerSpeex.hpp.


The documentation for this class was generated from the following file: