Avatar

Please consider registering
Guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed sp_TopicIcon
Oversampling using polyphase filter
No permission to create posts
October 9, 2013
8:32 am
Avatar
Simon Janvier
New Member
Members
Forum Posts: 1
Member Since:
June 8, 2013
sp_UserOfflineSmall Offline

First of all, a big thank to you Will for everything you do to make audio DSP easier to understand and put in pratice.

After reading and trying to understand this mysterious world I finally got it working. The code is write for another SDK but can be easily adapted to RackAFX. The big difference is that in the SDK I use we process audio with a buffer of length kBatchSize (64 samples) - so you just have to adapt the code by removing the for_loop of lenght kBatchSize.

Variable explanation:
kFactorL: Oversampling ratio
phaseNumber: The number of sub-bank filters
*h_Coeff: a pointer to the value contain in the filter's IR
pH: Adress of the array which contain the filter's IR
kTapsPerPhase: Number of filter taps (pH[ ]) divide by phaseNumber

With some trials I finally got an efficient (both in term of CPU load and anti-aliasing solution) polyphase filter for my apps using a 64taps filters and 2X oversampling ratio.

void CShapeEffect::Interpolate(unsigned char iNumberOfConnectedChannel) {

size_t tap;
size_t phaseNumber;
const double *h_Coeff;

size_t OutputWriteIndex = 0;

for(size_t i = 0; i 0; tap--) {
LeftInterpDelayLineBuffer[tap] = LeftInterpDelayLineBuffer[tap - 1];
if(iNumberOfConnectedChannel == 2) {
RightInterpDelayLineBuffer[tap] = RightInterpDelayLineBuffer[tap - 1];
}
}

//Copy next sample from input buffer to bottom of Z delay line
LeftInterpDelayLineBuffer[0] = fLeftAudioBuffer[i];
if(iNumberOfConnectedChannel == 2) {
RightInterpDelayLineBuffer[0] = fRightAudioBuffer[i];
}

//Calculate outputs
for(phaseNumber = 0; phaseNumber < kFactorL; phaseNumber++) {

//Point to the current FIR coefficient
h_Coeff = pH + phaseNumber;

double leftSum = 0.0f;
double rightSum = 0.0f;

//Do the sum of product of Delay Line value filter taps value
//And increment h_Coeff [pH Index Adress] by kFactorL
for(tap = 0; tap < kTapsPerPhase; tap++) {
leftSum += *h_Coeff * LeftInterpDelayLineBuffer[tap];
if(iNumberOfConnectedChannel == 2) {
rightSum += *h_Coeff * RightInterpDelayLineBuffer[tap];
}
h_Coeff += kFactorL;
}

fLeftOversampledBuffer[OutputWriteIndex] = static_cast(leftSum * kFactorL);
if(iNumberOfConnectedChannel == 2) {
fRightOversampledBuffer[OutputWriteIndex] = static_cast(rightSum * kFactorL);
}
OutputWriteIndex++;
}
}
}

Cool

October 9, 2013
6:07 pm
Avatar
W Pirkle
Admin
Forum Posts: 143
Member Since:
January 28, 2017
sp_UserOfflineSmall Offline

Hi Simon

Thanks for the update and the code! I remember that you were one of the first that really got into the Polyphase App Note right after I released it. If you want to submit a RackAFX sample project that uses this (like a simple waveshaper or filter) contact me and I could add it to the Bonus Projects and/or App Note pages.

All the best,
Will

Forum Timezone: America/New_York

Most Users Ever Online: 36

Currently Online:
3 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

Skyler: 47

Peter: 41

Derek: 41

clau_ste: 39

Frodson: 38

Gwen: 32

EZB: 24

lppier: 23

Msaldaña: 18

Jorge: 17

Member Stats:

Guest Posters: 1

Members: 476

Moderators: 1

Admins: 4

Forum Stats:

Groups: 11

Forums: 30

Topics: 482

Posts: 1876

Newest Members:

sam, annaharris, Marie Weaver, kev, Steven, Mr Anderson, mguy, omelc

Moderators: W Pirkle: 143

Administrators: Tom: 65, JD Young: 80, Will Pirkle: 0, W Pirkle: 143