What is the fastest way to upsample or downsample a signal, given that both block sizes and up/downsample ratios are all powers of 2? For some audio processing filter I need to upsample and downsamplte my signal 16 (!) times, and I need to repeat this a lot of times per block of audio - my current method doesn't even run in realtime on my i7 system. Most important restriction: After downsampling the upsampled signal, the result must be identical to the original (except for rounding errors of course).
I currently use 2 FFTs for this: For example, downsampling looks like this (block size is 2^n): Typical block size: 4096 floats (n=12).
ippsFFTFwd_RToCCS_32f_I(in, pFFTSpec[n+downsampleratio], buf);
ippsFFTInv_CCSToR_32f(in, out, pFFTSpec
ippsFFTFwd_RToCCS_32f(in, out, pFFTSpec
__m128 zero_mm = _mm_setzero_ps();
for (int count=number/4+1; count<=number*times/4+1; count++)
((__m128*)out)[count] = zero_mm;
ippsFFTInv_CCSToR_32f_I(out, pFFTSpec[n+newplus], buf);
Yes, sorry I wasn't clear about that. I need to clip inter-sample peaks, then downsample again.
So what I actually need is: Upsample (x4) -> Clip -> Downsample (/4). For blocks of floats where the number of values is a power of 2 (usually 16384, 8192 or 4096). If clipping is not perfectly accurate (1% too much or too little) that would be acceptable.
Maybe also important: I know that there are no very high frequencies present (typical values are a maximum signal frequency of 60 kHz, for a sampling frequency of 176.4 or 192 kHz).
There's no difference for me between 2 and 4, and they look like what I need.
Input: -6 0 6 10 10 6 0 -6 -10 ...
With oversampling, that would give something like: -6 -3 0 3 6 8 10 11 10 8 6 3 0 -3 -6 -8 -10 .... (Note: Actual upsampling should result in something that looks much smoother than this it's just an example). The 11 is higher than any of the input values.
Now, say we clip at level 10. That leads to: -6 -3 0 3 6 8 10 10 10 8 6 3 0 -3 -6 -8 -10
After downsampling, that would lead to a reduction of the 2 '10' values in the input, and probably some other small effects. And that's what I need.
Did you have a look at Multi-Rate FIRs? or ResamplePolyphaseFixed?
IPPAPI( IppStatus, ippsFIRMRInit_32f,( IppsFIRState_32f** ppState,
const Ipp32f* pTaps, int tapsLen, int upFactor, int upPhase,
int downFactor, int downPhase, const Ipp32f* pDlyLine, Ipp8u* pBuffer ))
IPPAPI(IppStatus, ippsResamplePolyphaseFixed_32f,(const Ipp32f *pSrc, int len, Ipp32f *pDst,
Ipp32f norm, Ipp64f *pTime, int *pOutlen,
const IppsResamplingPolyphaseFixed_32f *pState))