It is currently Sun Oct 22, 2017 12:31 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Thu Nov 03, 2005 3:20 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Currently I have a big table with several 'sets', each consisting of 12 steps. Each of the 12 steps is output everytime audio output changes (transition). Those familiar with blargg's BL synth docs/methods might have the general idea of what I'm talking about.

I vaguely recall blargg saying something about a simple lowpass filter being easily implimented with such a setup -- as you wouldn't have to do any additional code during sample generation -- you could just modify your lookup table so that the filter takes effect for every transition before any of them are output.

However, I scanned blargg's site for info on the subject and didn't come up with a thing. I tried fiddling around on my own but my general lack of audio filter knowledge just led to distorted/ugly sound (I even seemed to decrease the signal:noise ratio rather than increase =P)

Anyway if anyone (*cough*blargg*cough*) can give me some info/advice on implimenting a lowpass filter with such a setup, I'd be very appreciative.

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 03, 2005 6:16 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
To recap, as I understand it Disch is essentially generating a master square wave and then sampling one of its band-limited transitions at several offsets, then reusing these to generate band-limited transitions. To implement low-pass with this scheme you just reduce the amplitude of the higher sine wave harmonics to whatever profile you want as you add them when generating the master square wave. A simple algorithm is to scale each harmonic by an exponential "rolloff" factor, where the first harmonic is at normal amplitude, the second at 0.98 the usual, the third at 0.98*0.98, the fourth at 0.98*0.98*0.98, etc. This is in addition to the normal scaling of square wave harmonics, of course, where the first is at 1.0, the second at 1/3, the third at 1/5, fourth at 1/7, etc.

Code:
double period = 100;
double scale = 1.0;
double rolloff = 0.98;
for ( double harmonic = 1; harmonic <= period / 2; harmonic = harmonic + 2 )
{
    add_sine( period / harmonic, scale / harmonic );
    scale = scale * rolloff;
}


Here are a few square waves with progressively lower rolloff factors:

Image

If you still have trouble with this, I'll finish working on the demo code tutorial I've been wanting to complete for a while.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 03, 2005 6:35 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Excellent, that seems simple enough. So then the 'rolloff' factor would be the "strength" of the lowpass filter? The further down from 1.0 you get, the more the filter applies?

Up until now I've been using a pre-calculated const transition lookup table -- but now it looks like I'd be better off building one at runtime.

Many thanks, blargg -- I'll start implimenting this right away.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 03, 2005 6:49 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Yeah, the rolloff is as simple as that. It needs to be fairly close to 1.0 or else it will really roll off (since it's multiplied by itself many times). Building the square wave from individual harmonics makes this really simple to understand, almost like a graphic equalizer. I've tried other schemes where none of the lower harmonics are affected at all and found that the simple rolloff sounds best.

Seriously optimizing generation of the master transitions is quite complex and messy, so I definitely recommend sticking to building the square from sine waves. You can always make a sine lookup table that has the same number of entries as your base period is, times how ever many sub-sample offsets you're taking. All harmonics are at integer multiples of the base frequency, so you just step through this table at an increment of 1, then 3, then 5, then 7, etc. I'll probably go ahead and write the simple demo tomorrow, since I need a break from my emulator. :)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 04, 2005 11:10 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
I finished the demo code. It shows how to generate the master square wave using a sine table (for speed) and then sample each band-limited step at each phase, then add them into a buffer. I tried to make it fairly readable, but didn't go to great lengths for that.

band_limited_step.zip


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 04, 2005 4:48 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
And here's the super-simple version (with added high-pass filtering) rewritten for clarity, at only 53 lines of code.

band_limited_step2.zip


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 04, 2005 5:49 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Would it be possible to get some recorded examples with that method? I tried my own method but it didn't work out very well -- I was probably mucking something up.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 04, 2005 6:37 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
If you want its output, just run the demo and examine the wave sound file. If you set the high-pass to 0.0, you can see the raw first difference of the sampled steps. I'm not sure what help this would be, since it'll look pretty much like the output with no high-pass filtering.

The main intermediate is the "master" band-limited step:

Image

This is just a square made from sines, with the angle from -pi/2 to pi/2 (one half of a full cycle). You'll sample it at the same interval as shown by the vertical lines, at several phases (shift the vertical lines to the right very slightly each time until you would get back to the original ones):

Image

Each time I've implemented this method I've had to write wave file of the intermediate waveforms in order to debug each one. It's tricky to get each one right.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Memblers and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group