shorepine / amy

AMY - the Additive Music synthesizer librarY

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Interaction of filter env and amp env on fixed-point

dpwe opened this issue · comments

I don't know what's happening yet, but applying both amplitude and filter-freq envelopes leads to a floating point explosion:

amy.send(osc=0, wave=amy.SAW_DOWN, filter_type=amy.FILTER_LPF, resonance=0.7, filter_freq=4500, bp1_target=amy.TARGET_FILTER_FREQ, bp1='0,0.1,150,1.0,1000,0.4,100,0.1', bp0_target=amy.TARGET_AMP, bp0='0,0,60,1.0,500,0.5,100,0')
amy.send(osc=0, note=64, vel=1)

Weirdly, the filter without the amplitude scaling is fine (the filter is the most likely culprit when things go unstable). The amplitude envelope without the filter is fine too of course.

The problem seems to wait until the amplitude envelop hits the sustain phase. Which .. makes #552554a suspicious.

It's not the filter. With this command:

amy.send(osc=0, wave=amy.SAW_DOWN, bp0_target=amy.TARGET_AMP, bp0='100,1,600,1,500,0', bp1_target=amy.TARGET_FREQ)

.. where bp0 controls amplitude, and there's a suggestion that bp1 will control pitch, we usually get dysfunction during the release phase (after amy.send(osc=0, vel=0)) -- even though the filter code isn't even being run.

No, the problem during release is a red herring. It comes from the way that an empty envelope generator always returns a 1.0 until the key-off, whereafter it returns 0.0. This is good for amplitude, but not for pitch when we want the oscillator to keep oscillating during the decay.

I verified this was the cause by commenting out the logic to make default envelopes zero after note off (envelope.c:63). It fixes the noise during release, but doesn't fix the noise-during-amplitude-sustain-through-a-filter of the earlier problem.

I'm not sure it's worth fixing, since using an empty bp set seems like an edge case. I'm surprised, however, that setting the oscillator frequency to zero results in loud buzzing.

Somehow bp0 is returning the release time of bp1 as a float instead of its sustain value. It thinks it's pulling the sustain from segment index 4 (i.e., the 5th segment) of bp0, even though bp0 only has 3 segments.

Issue was the way amy.c:parse_breakpoint() decided when to stop parsing. It looked for the first character greater-than-or-equal-to 'a' to find the beginning of the next command. Which was fine when all the commands had lower-case prefixes, but did not terminate on upper-case command prefixes. So when I had two bpsets, with, as it happened, only upper-case prefixes in-between, it plowed right through and appended some version of the second on onto the first. strspn fixed.