silvansky / mobilesynth

Automatically exported from code.google.com/p/mobilesynth
0 stars 0 forks source link

ResonantFilter::GetValue() sometimes escapes into NaN and won't return to earth #28

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
This is very hard to reproduce consistently. I am using mobilesynth code in an 
early-stage iPad app and I have discovered that sometimes 
ResonantFilter::GetValue() can return a NaN value which fills the output buffer 
with maximum volume samples.

The problem seems to be that the variable y4_ in that function can occasionally 
wildly oscillate, as things attached to power functions are wont to do. Within 
three or four steps it's outside MAXFLOAT and that causes the other vars (y1_ 
and so on) to also breach their boundaries.

I have implemented a quick fix, placing this line right at the top of the 
function:

// Give the filter a whack with a hammer if it's out of control
if (isnan(y4_)) { 
            y1_ = 0.0;
            y2_ = 0.0;
            y3_ = 0.0;
            y4_ = 0.0;
            oldx_ = 0.0;
            oldy1_ = 0.0;
            oldy2_ = 0.0;
            oldy3_ = 0.0;
        }

Which appears to resolve the issue. It's not very pretty - the hammer analogy 
was deliberate - but it does the job. I haven't got to the bottom of why the 
values occasionally go wild, but because it's so intermittent and hard to 
reproduce my guess is that it only occurs at very specific points on the 
oscillator cycle, so the filter doesn't 'catch' that x value every single time.

I am setting up the synth like so:

        controller_ = new synth::Controller;
        controller_->set_osc1_level(1);
        controller_->set_osc1_wave_type(synth::Oscillator::SAWTOOTH);
        controller_->set_filter_cutoff(15000.0);
        controller_->set_filter_resonance(1.0);
        controller_->set_modulation_amount(0.0);

So no envelopes or modulation get initialised. I realise this may also be part 
of the problem since it's not the typical use case where you have some 
controllers on-screen with sensible values pre-set. Then I simply call:

        controller_->NoteOn(note)

when my app wants to play a sound (and NoteOff when it stops.)

Hope this helps. Thanks for the excellent code which is giving me a nice 
introduction to synthesis.

Tim

Original issue reported on code.google.com by timothyk...@gmail.com on 21 Nov 2011 at 10:34