shorepine / amy

AMY - A high-performance fixed-point Music synthesizer librarY for microcontrollers
https://shorepine.github.io/amy/
MIT License
198 stars 11 forks source link

Logarithmic frequency axis #60

Closed dpwe closed 9 months ago

dpwe commented 10 months ago

In service of #59, we would need voice parameters in a domain where linear summing naturally supports the desired control.

Specifying frequency in Hertz doesn't satisfy this. Currently, we apply controls like envelopes to frequency parameters by multiplication.

If instead we used a logarithmic frequency scale, we could add an envelope to a base frequency value to get similar control behavior (since addition in a logarithmic domain corresponds to multiplication in the linear domain).

However, we can then also scale the modulating inputs to vary their effect. (This actually corresponds to raising linear envelopes to a power.)

This arrangement mirrors the "one volt per octave" standard used in modular analog synthesizers.

dpwe commented 10 months ago

I'm thinking specifically log_2(freq_hz / 440.0) (1.0 per octave, with 0.0 meaning A440) but I'd be glad to adopt a popular existing convention.

dpwe commented 10 months ago

Another choice would be float(midi_note) / 12.0 which would be 1.0 per octave with 0 meaning 8.1758 Hz. This has the attraction of making all useful frequencies be positive values.

dpwe commented 9 months ago

Implemented in cb9fe11 et seq. synth[osc].freq and synth[osc].filter_freq are replaced by synth[osc].logfreq and synth[osc].filter_logfreq, which are in units of octaves relative to MIDI 0 (so, midi_note / 12.0).

znmeb commented 9 months ago

My personal choice is fractional MIDI note numbers, i. e., the quarter tone exactly between middle C and C# is 60.5, but you've already made the patch. :-)

dpwe commented 9 months ago

I hear you, and a log2 scale like this isn't good for human interface. However, the API is still in Hz, it's only the internal variables that are affected.

This is in service of "1 volt per octave"-like reuse of control signals as in an analog (modular) synth. For that, needing a value of 12.0 to move by an octave seems too big. I think this will work out.