Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General linear-combination control inputs #59

Closed
dpwe opened this issue Dec 9, 2023 · 2 comments
Closed

General linear-combination control inputs #59

dpwe opened this issue Dec 9, 2023 · 2 comments

Comments

@dpwe
Copy link
Collaborator

dpwe commented Dec 9, 2023

Currently, the way that note, envelope, and lfo inputs affect pitch, envelope, and filter cutoff etc. is fairly complex and irregular.

In the spirit of the voltage-summing nodes of analog synths, I want to introduce a fully orthogonal structure, where each voice parameter is calculated as the sum of the same set of control inputs via a matrix of scale coefficients.

For example, instead of filter_freq=1000 setting the cutoff to a fixed value, followed by bp0_target=FILTER_FREQ and setting up the bp0 envelope to get a sweep, you would do something like:

filter_freq=1000.0,1.0,0,0,0

where the vector of coefficients now indicate the weights for a fixed set of control inputs that are summed together.

The first coefficient is always taken as-is, providing a constant starting point, but the remainder are applied to inputs whose values vary, defined in some fixed order. In the example above, the second value applies to bp0, but we would also include note value (pitch), note velocity, lfo, etc.

Voice parameters include oscillator frequency, output level, filter frequency, PWM duty, and stereo pan.

@dpwe
Copy link
Collaborator Author

dpwe commented Dec 26, 2023

I have this approach working in branch linear_combo_ctl. Each of amp, freq, filter_freq, duty, and pan take a list of up to 6 parameters, which are applied to CONST, NOTE, VEL, EG0, EG1, and MOD to calculate the actual values used by the oscillator.

All the calculations are linear sums (param = \sum coefficient * control_input) except amplitude. To support scaling the envelope generator by the velocity value, we have to multiply together all the non-zero elements. This is irregular and inelegant. It also means the amp coefficients are essentially just binary, i.e. included or not (since any nonzero value other than 1 simply scales the overall amplitude). The fix here would be to have the amplitude also specified in log-units (e.g. dB, although probably something with a range closer to 0..10), but it's impossible to express 0 amplitude in log units (since log(0) = -inf). However, we could define 0.0 as, e.g., -100 dB (which becomes silence for 16 bit outputs), and 10.0 as 0 dB (nominal full-scale).

To make the behavior sort-of contiguous with how things were before, I also had to introduce some specific defaults:

  • amp_coefs defaults to {0, 0, 1, 1, 0, 0} so that by default the note amplitude is the product of the velocity attribute and the first envelope generator (EG0). EG0 follows the key gate (1 after a nonzero velocity, then 0 after a vel=0 event), so it provides the rectangular envelope proportional to velocity. (Note that the VEL control input does not clear to zero at note-off, so any release provided by the EG will continue at the same scale).
  • freq_coefs defaults to {0, 1, 0, 0, 0, 0}, i.e. the oscillator frequency follows the note input by default. However, a command such as amy.send(osc=0, freq=1000) is interpreted as freq_coefs = {1000, 0, 0, 0, 0, 0}, i.e., the frequency is made independent of the note attribute. You can, of course, have the frequency be offset from the note input with something like amy.send(osc=0, freq='16.36,1'). The constant frequency is represented as log-frequency relative to MIDI 0 (8.18 Hz), so this command makes osc 0 have a frequency one octave above the note value.

@dpwe dpwe closed this as completed Dec 26, 2023
@dpwe dpwe reopened this Dec 26, 2023
@dpwe
Copy link
Collaborator Author

dpwe commented Jan 29, 2024

This was resolved by #93

@dpwe dpwe closed this as completed Jan 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant