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
Upsample - sinc filter - downsample?
No permission to create posts
September 13, 2017
12:05 pm
Avatar
djfresha
Member
Members
Forum Posts: 14
Member Since:
October 10, 2013
sp_UserOfflineSmall Offline

Hi Will,

Been scouring the net and reading your book again in regards to upsampling for antialiasing functions (so upsample, sinc filter, process, sinc filter, downsample). Been reading that FIR is the way to go for this after zero-stuffing. 

Got the zero stuffing fine, it's the how to setup the sinc filter that I'm trying to wrap my head around. I totally get the requirement and the method, it's just applying it to code using the right sinc filter algo.

IIRs I've got no problem, FIRs are something new. I'm looking to upsample once (so 44100 to 88200 say) so that I could use a 12dB/Oct shelf filter as a 24dB/Oct shelf filter using the same coeffs in the shelfing filter on the 'doublebuffer' so I can use the one set of controls. I've got filter frequency, and gain control, plus a toggle for 12/24dB modes. Using 0.707 for resonance so keeping things simple for now.

Can you advise on the way to get the sinc filter setup (correct variables needed), plus if FIR is the way how would we get the coeffs and pass the 'doublebuffer-with-zeros' through it before I process the upsample-sincfiltered results?

Cheers - Matt

September 14, 2017
4:33 am
Avatar
djfresha
Member
Members
Forum Posts: 14
Member Since:
October 10, 2013
sp_UserOfflineSmall Offline

Ok had another look at a few more sources online and think I know what I need to do.

 

1) Get my original audio buffer (64 samples, as per the SDK kit I'm using)

2) Zero stuff the audio buffer with 'alternating' zeros (so zerostuffbuffer[0] = audiobuffer[0], zerostuffbuffer[1] = 0, zerostuffbuffer[2] = audiobuffer[1] etc up to zerostuffbuffer[126] = audiobuffer[63] then zerostuffbuffer[127] = 0)

3) Convolute the zerostuffbuffer with the LPF FIR (mine will be 1024 taps to ensure ultra nice sharp LFP @ close to Nyquist as I want as close to full signal as possible, so 22000 may be about there)
     
(a) set the counter length to be 0 to 127 for the 'upsampled' buffer

(b) have an accumulator variable ('samplemem') for the 'zerostuffbuffer' sample * LFP FIR tap, so I would expect to pass the 'samplemem' result each time through each tap (1 sample result processed 1024 times based on the FIR tap count) - wondering about the 'zero' values though how I would pass the result on, or would it be the last stage memory passed on from the previous circular loop ie 'samplemem-pass2' = 'samplemem-pass1@1024step result' + 'samplemem-pass2@1ststep' * LPF FIR tap1? else the 'zero' value would still be zero? or do the zeros in the stuffed buffer actually need to be an other value? Either way the 'zerostuffbuffer[x]' result would be the final calculation of the sample * LFP FIR tap function

(c) perform the 12dB/Oct filter on the 'zerostuffbuffer' samples, so I could end up with a sharper 24dB/oct slope even though running 128 samples through with a 12dB/oct filter (maybe this is where the values 'smooth out' and populate the previous zero-values with actual filter values due to IIR?)

(d) now do I decimate back here ditching the 'odd' zerostuffbuffer values keeping [0],[2],[4],[6]... etc and return them back to my final audiobufferoutput[0],[1],[2]... etc or do I convolute again using the LPF FIR taps as step 3 before decimating back to 64 samples?

I'll have a play anyway, I do get the logic more behind it (stops anti-aliasing with the LPF FIR), but thought I'd run this past you before I mess with code. Will dabble a bit anyway (already got upsample / downsample zero stuffing sorted, that's pretty easy, and running through my current filter code is fine)

I also understand if doing things like distortion (bit crushing etc) then oversampling would be more desirable to prevent frequency foldbacks etc. Once I get this down though, I would revise my current effects to include oversampling for cleaner operation (would be an added option, as the effect has it's own 'sound' at the moment)

Thanks again

September 14, 2017
5:02 am
Avatar
djfresha
Member
Members
Forum Posts: 14
Member Since:
October 10, 2013
sp_UserOfflineSmall Offline

Just read this: http://www.earlevel.com/main/2.....ersion-up/

Have been looking at his site for some time as of late too, and the zero-stuffing could be bypassed which is a pretty neat DSP / time saver. Also it could mean that I could ditch half the coefficients in the LPF FIR since they won't be needed with the upsample stage, so that clears that up quite nicely. I can still do my 12dB/Oct but with the difference based on being a longer buffer (128 instead of 64) so I'll get my 'new' samplerate for the 12dB coeffs to be double when upsampling, else stay as standard samplerate if using 12dBOct+no upsampling.

Finally making sense. Hope perhaps this info helps others too

September 15, 2017
3:40 am
Avatar
djfresha
Member
Members
Forum Posts: 14
Member Since:
October 10, 2013
sp_UserOfflineSmall Offline

Ok getting a little further on this.

I've got the LPF FIR running with 1023 taps pretty close to Nyquist so that part seems ok.

Now here's my current process (had a few code changes)

1) get original buffer and zero stuff it (so was 64 samples, it's now 128 samples)

2) I run every 'other' (original buffer) value through the 1023 taps, accumulating until I pass through all the taps and then store that as my new 'processed-LPF-FIR' value - I'm only doing this on the values that are not the zero stuffed values (saves on calculation as result ends up being 'zero')

3) The 'processed-LPF-FIR-doublebuffer' values are now fed thorugh my original 12dB/oct filter coeffs, and I can see I'm getting closer to my objective, but still not 100% just yet. I've got a LPF 12/dB Oct with variable frequency from 1.5k to 16k (good for shelfing or 'classic sounding' roll off like tape might). When I process the upsampled version, I can see the slope isn't changing much, so I'm guessing something still isn't quite right.

Once I crack this I'll post back how I sorted it out

EDIT: just seen this too so will give this a thrashing http://www.willpirkle.com/Down.....yPhase.pdf Laugh

September 18, 2017
11:00 am
Avatar
djfresha
Member
Members
Forum Posts: 14
Member Since:
October 10, 2013
sp_UserOfflineSmall Offline

Ok been playing with the base code example in the App notes, so getting my noodle around it properly.

As far as I can see I need to

1) process the FIR against my 64 samples in opposite directions (original buffer read forwards as impulse reads backwards) to get the accumulation for the convolution for each sample I want returned, and do this for each of the original samples (creating a 'new' sample batch). Do this again for the 'second' batch as I'm upsampling only to 2x, so I end up with 128samples total (interweaved I think?)

2) redo my filter so the frequency is at the setting I want but up the samplerate (for the EQ warping), and apply it to the 'new' sample batch (else I would get aliasing if I tried to do this straight) - will test this if the samplerate does need to change or not (if it doesn't then bonus, but if it does then I know it's a simple toggle to 'double' the samplerate in the sin(x)/xrate formula)

3) 'decimate' back by running the resulting EQ'd 'new' back through the FIR, so I get my final result of the 128 samples but ditch every other one (to get back to 64 samples)

Seems relatively straightforward. I've got a superb 256 tap FIR with -144dB attentuation at 22000Hz, with the lower passband frequency of 20500Hz, and a ripple of 0.05dB (so pretty damn tight)

I've tried the filter using RackAFX so I know the taps work, just going to apply it to the plugin I'm working on now

September 19, 2017
3:41 am
Avatar
djfresha
Member
Members
Forum Posts: 14
Member Since:
October 10, 2013
sp_UserOfflineSmall Offline

Ok, ran through the code debug mode to see exactly what is going on, and by looks of things I can do some very effective optimization on the project code, as well as my own plugin using the other SDK. Will report back later if I crack it 😀

September 19, 2017
8:41 am
Avatar
W Pirkle
Admin
Forum Posts: 143
Member Since:
January 28, 2017
sp_UserOfflineSmall Offline

Would love to post an updated project that has more optimization - let me know.

- WP

September 20, 2017
10:27 am
Avatar
djfresha
Member
Members
Forum Posts: 14
Member Since:
October 10, 2013
sp_UserOfflineSmall Offline

Hmm will have a rethink about this 😀

September 21, 2017
5:27 am
Avatar
djfresha
Member
Members
Forum Posts: 14
Member Since:
October 10, 2013
sp_UserOfflineSmall Offline

Ok just so I get this totally in my head right.... your example of OversampleWaveshaper is working on a sample by sample basis (as far as I can see), so only one audio sample is processed at a time... is this correct?

Thanks

September 21, 2017
10:32 am
Avatar
W Pirkle
Admin
Forum Posts: 143
Member Since:
January 28, 2017
sp_UserOfflineSmall Offline

In the sample code, it does use processAudioFrame( ), but you could also refactor it to use the VST buffering by setting the boolean flag to use that instead, and process buffers at a time.

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