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

quantization question #117

Open
koswir opened this issue Dec 3, 2024 · 21 comments
Open

quantization question #117

koswir opened this issue Dec 3, 2024 · 21 comments

Comments

@koswir
Copy link

koswir commented Dec 3, 2024

@eh2k
I've been testing the new chord engines and I realised that the build in i/o quantizer is kinda weird.

Am I right that the generator's pitch and i/o's transpose happen before quantization?

If it works like that it means that any set scale is fixed on the note C.

Could you add a setting for quantizer key in the i/o settings?

@rootapprox
Copy link

Hello @koswir ,

the Quantizer is normal from my experience.. you basically have 2 types of creating chords in the CH algorithms u have two options either you qualitize and have chords related to the root key and the second note on the scale and third related which creates Triads , or if u turn the quantizer Off , you are using the algorithms like before ( WTx4 ) algo .

Chord Modes
Braids Renaissance adds a total of 10 new chord algorithms.

\ \CH, -_CH, /\CH, SICH, WTCH
With the quantizer disabled, these modes play the same chords as the original paraphonic WTx4 algorithm, where the Color parameter blends between 16 different chords. But when quantizer is enabled with one of the diatonic modes (dorian, aeolian, etc), the chords will stay in key, picking the correct major or minor chord and extensions based on the configured quantizer mode and root note. For example if the quantizer is set to C Dorian, sending a D value into the V/oct input will result in a minor triad. Color parameter still controls the chord extension but is also picked correctly based on the scale determined by the quantizer.

\ \x6, -_x6, /\x6, SIx6, WTx6
6 oscillators starting at the 1v/oct input, spaced evenly across the currently selected quantize scale. Color controls the number of scale steps between oscillators. When the Braids quantizer is turned off, the oscillators are evenly spaced by semitones (controlled by Color).

Timbre parameter
The Timbre parameter morphs the sound differently depending on the chord waveform.

For saw algorithms (\ \CH, \ \x6), each note is actually 2 saw waves, and Timbre controls the detuning between the 2 saw waves.

For square algorithms (-_CH, -_x6), Timbre controls the pulse width of the square wave.

For triangle and sine algorithms (/\CH, /\x6, SICH, SIx6), Timbre controls the amount of wavefolding to apply to each oscillator before summing.

For wavetable algorithms (WTCH, WTx6), Timbre morphs between a small set of wavetable entries. This is the same wavetable list as the original WTx4 mode.

here from the manual of the Chords modes from renaissance.

@koswir
Copy link
Author

koswir commented Dec 3, 2024

oh really? @rootapprox
so tell me please how to quantize an input voltage to F# minor (F# aeolian)

the Quantizer is normal from my experience.. you basically have 2 types of creating chords in the CH algorithms u have two options either you qualitize and have chords related to the root key and the second note on the scale and third related which creates Triads , or if u turn the quantizer Off , you are using the algorithms like before ( WTx4 ) algo .

yes I know what you mean - but there is no Root key setting

@rootapprox
Copy link

rootapprox commented Dec 3, 2024

The root key is the first key in the little piano roll in the waveforms interface. like F#3 for exmple then i you want a chord with F# Aeolian , you go the quantizer you set aeolian scale then when u open the color u will hear more notes coming after your root Key to complete your chord in the proper scale that you choose, hope i explained myself good here .
to understand more the procces i suggest you to open the VCA ( make it off ) so u have consistent sound and u can swap between scales , notes ( with Color control )

@koswir
Copy link
Author

koswir commented Dec 3, 2024

The root key is the first key in the little piano roll in the waveforms interface.

I do not think so - from what I hear - the piano does not set the root key of the scale setting from the i/o page.
Lets forget about chords... :D I didn't asked about them.
Just try it with a mono voice - it is easier to hear.
Play F# aeolian scale on your keyboard without quantizer.
Than turn on the aeolian setting - no matter what note will you set on the keyboard or in transpose settings - it is not the F# aeolian.
My guess is - the transposition happens before the quantizer - and it is fixed to C all the time.

@rootapprox
Copy link

@koswir The Transpose in the IO section it just shift the note to other notes , for exmple u want to go 1 octave down you put -12 in the IO section.
A mono voice is Color set to 0. and i dont play chords in my keyboaord bro , thats the point of the Algorithm that you are missing i guess ... its not your normal chord that u can play with your keyboard .. its programmable chord generator with the appropriate setting that you can learn in the Braids Renaissance Manual.
so if you want to make chords with it you feed a voltage to the C Input with the setting of the transposition / Color and Root key you will have a chord . for me when i change that piano roll Key simply change the note so its not always C here ..

@koswir
Copy link
Author

koswir commented Dec 3, 2024

@koswir The Transpose in the IO section it just shift the note to other notes , for exmple u want to go 1 octave down you put -12 in the IO section. A mono voice is Color set to 0. and i dont play chords in my keyboaord bro , thats the point of the Algorithm that you are missing i guess ... its not your normal chord that u can play with your keyboard .. its programmable chord generator with the appropriate setting that you can learn in the Braids Renaissance Manual. so if you want to make chords with it you feed a voltage to the C Input with the setting of the transposition / Color and Root key you will have a chord . for me when i change that piano roll Key simply change the note so its not always C here ..

Thanks for all your help bro.
I really appreciate that but I see that you didn't understand me.
I didn't ask about chords.
I hope @eh2k understands what I mean 🙏

@eh2k
Copy link
Owner

eh2k commented Dec 3, 2024

@koswir i'm not sure if i have fully understood the discussion (somehow i lack the ability to concentrate at the moment).

In any case, the CV or the return value of engine::cv() is calculated internally as follows:

cv = quantized(v_oct_parameter + transpose + input_voltage)

The v_oct_paramter is always in twelve semitones steps (like the piano roll). Actually not correct - I think the steps should be according to the quantizer setting (i.e. there should be only white keys instead of the classic piano roll, with less than 12 keys)

The transpose in the IO settings is actually not correct for other scales either (also semitones) - I would like to change this to octave, then it would be compatible with all scales. (see #60)

If that were the case, it wouldn't really matter whether the transpose + v_oct was before or after the quantizer.

Edit: v_oct_parameter need to be quantized, because of the modulation.

The code for Braids Renaissance Chords is special in this case, otherwise there is no engine that does the lookup directly on the quantizer table. These are two places where you can work out how the chords are generated:

https://github.com/eh2k/squares-and-circles/blob/main/lib/braids/chords_stack.cc#L560
https://github.com/eh2k/squares-and-circles/blob/main/lib/braids/chords_stack.cc#L497

@rootapprox
Copy link

rootapprox commented Dec 9, 2024

@eh2k I've been testing the new chord engines and I realised that the build in i/o quantizer is kinda weird.

Am I right that the generator's pitch and i/o's transpose happen before quantization?

If it works like that it means that any set scale is fixed on the note C.

Could you add a setting for quantizer key in the i/o settings?

I Actually understand what you mean now i think @koswir , @eh2k the problem is from my end also is that when you change the note in the CV / V oct in my case , the note its fixed to C and when you keep goin down you just change to octaves , not semitones.. even if i wanted to change that from the IO menu i still cant change semitones in the actual squale , its fixed to C and its goes down only for octaves or up ..
try this and change the piano roll note or the Transpose from the IO and the root key wont change just octaves..

@koswir
Copy link
Author

koswir commented Dec 9, 2024

Not sure what you mean by octaves @rootapprox but the fact is no matter how you retune a machine the quantizer is always in C.
@eh2k I've been thinking how to explain the problem and I was about to record a vid that demonstrates this behaviour, but I was busy over the weekend 😞

@rootapprox
Copy link

@koswir you are making total sense , the quantizer is always in C and its not changin the notes when u try to change it from the IO ( only goes octaves down or up in the scales)

@eh2k
Copy link
Owner

eh2k commented Dec 14, 2024

@koswir @rootapprox

There is a new update 0e83607. In addition to a few optimisations, the piano roll is now displayed and incremented according to the quantizer.

Here, for example, the Japanese scale - there are only 5 notes per octave:

image

The transpose in not changed in the io-page yet, but I would limit it to octaves only.
I think then a ‘fine-tune’ parameter might be missing. But I don't want to add more parameters to the io-page (to avoid overloading it in the end).

What do you think - what about the initial question/issue?

@koswir
Copy link
Author

koswir commented Dec 14, 2024

Hey @eh2k
Thank you for all your work!

the piano roll is now displayed and incremented according to the quantizer.
Here, for example, the Japanese scale - there are only 5 notes per octave:
image

Well, the display of a scale looks pretty cool! It works great for modulating the Tune knob!

I am sorry to be the downer thought but this is not helping with the problem.
All the scales are still in the key of C and...

The transpose in not changed in the io-page yet, but I would limit it to octaves only. I think then a ‘fine-tune’ parameter might be missing. But I don't want to add more parameters to the io-page (to avoid overloading it in the end).

...it will be very bad to remove the i/o transposition now cause you limited a machine's transposition to steps from a selected scale. There will be no way to transpose freely other than forget about the quantizer at all.

Please add Fine Tune to the i/o - I needed it a few times and I had to waste one of the slots on v/oct engine (it has finetune parameter).


Let me try to explain again the scale key problem.

So... lets assume that we use standard 440hz=A equal temperament tuning and standard v/oct calibration so 0, 1, 2, 3 are octaves of C.

Of course if we want to play chromatic notes we have to split 1 volt /12.
So one semitone is 0,0833 in volts and in your code it seems to be 128.

{ 12 << 7, 5, { 0, 128, 640, 896, 1024} },

The voltages and values for all the notes will go like that:
0V: C (0)
0,0833V: C# (128)
0,1667V: D (256)
0,25V: D# (384)
0,3333V: E (512)
0,4167V: F (640)
0,5V: F# (768)
0,5833V: G (896)
0,6667V: G# (1024)
0,75V: A (1152)
0,8333V: A# (1280)
0,9167V: B (1408)

Now if we want to quantize to a scale.
Every scale it a set of intervals that start from a particular note (key of a scale)
So in C (from your chart) the minor (aeolian) scale is
// Aeolian (From midipal/BitT source code)
{ 12 << 7, 7, { 0, 256, 384, 640, 896, 1024, 1280} },
Basically we are skipping some notes to have a scale.
The easy way to think about a scale is to know which notes to skip starting from a key of a scale note which is number one.
In Aeolian scale we skip: 2nd, 5th, 7th 10th and 12th notes. Lets see that on the list. The right notes are indicated as bold.
note 1: 0V: C (0)
note 2: 0,0833V: C# (128)
note 3: 0,1667V: D (256)
note 4: 0,25V: D# (384)
note 5: 0,3333V: E (512)
note 6: 0,4167V: F (640)
note 7: 0,5V: F# (768)
note 8: 0,5833V: G (896)
note 9: 0,6667V: G# (1024)
note 10: 0,75V: A (1152)
note 11: 0,8333V: A# (1280)
note 12: 0,9167V: B (1408)

So now lets play a different key - for example F# aeolian.
Now the note 1 will be F# and we have to skip 2nd, 5th, 7th 10th and 12th notes starting from F#.
note 1: 0,5V: F# (768)
note 2: 0,5833V: G (896)
note 3: 0,6667V: G# (1024)
note 4: 0,75V: A (1152)
note 5: 0,8333V: A# (1280)
note 6: 0,9167V: B (1408)
note 7: 0V: C (0)
note 8: 0,0833V: C# (128)
note 9: 0,1667V: D (256)
note 10: 0,25V: D# (384)
note 11: 0,3333V: E (512)
note 12: 0,4167V: F (640)

So to be able to quantize to the F# aeolian the code should be
{ 12 << 7, 7, { 128, 256, 512, 768, 1024, 1152, 1408} },

If it still not clear I have no idea how to explain that.

@koswir
Copy link
Author

koswir commented Dec 14, 2024

or maybe it could be calculated somehow like that:
// Aeolian (From midipal/BitT source code)
{ 12 << 7, 7, { 0+x, 256+x, 384+x, 640+x, 896+x, 1024+x, 1280+x} },
where x = transposition*128

@rootapprox
Copy link

rootapprox commented Dec 14, 2024

@eh2k thanks for the update ! but the problem as @koswir mentionned is still here , you can change the root note C just to octaves ... its always playing in C for all scales ..
maybe adding a root note in the IO would solve the problem ?

@eh2k
Copy link
Owner

eh2k commented Dec 16, 2024

@koswir @rootapprox

Thank you for your feedback. To be honest, I didn't focus on the quantizer at all. I simply quantised the CV at the end of the signal chain and thought that was it.

With the last update ca4b980, there were following changes / new parameter in the io-page:

  • Quantizer - Root: Value is the note in semitones (C, C#, D ...A#, B) The behavior is actually the same as with MI Braids (the note is subtracted before quantitation and then added to the quarantined CV value). Unfortunately, I didn't find much in the documentation that explains the theory behind it (thanks for your explanation @koswir).
  • Transpose - Fine: In addition to the transpose in semitones, there is now a FINE parameter that sets the transpose by semitone/128 steps. The transpose is added after quantization and is now no longer quantized.

I think where are still the following quantizer issues:

  • Midi input: the note & pitch is added to the CV before the quantizer.
  • V_OCT modulations: Here, the value is also added before the quantizer.
    • It don't makes sense for all types modulations in general.
      • TM modulation should behaves more or less the same as the TM engine.
      • SEQ Modulations similar issue.

@rootapprox
Copy link

@eh2k Hello , now it works perfectly (you can change the Root key in the scale) !! nice additions also with the fine tune and the Root Key!
thanks a lot !!

@koswir
Copy link
Author

koswir commented Dec 16, 2024

Hey @eh2k
Thank you so much!
Now it works perfectly except the new chord algorithms - these are still messed up.

Thank you for your feedback. To be honest, I didn't focus on the quantizer at all. I simply quantised the CV at the end of the signal chain and thought that was it.

To be honest me too! I discovered it accidently becasue the new chord algos.

With the last update ca4b980, there were following changes / new parameter in the io-page:

  • Quantizer - Root: Value is the note in semitones (C, C#, D ...A#, B) The behavior is actually the same as with MI Braids (the note is subtracted before quantitation and then added to the quarantined CV value). Unfortunately, I didn't find much in the documentation that explains the theory behind it (thanks for your explanation @koswir).
  • Transpose - Fine: In addition to the transpose in semitones, there is now a FINE parameter that sets the transpose by semitone/128 steps. The transpose is added after quantization and is now no longer quantized.

It works as it should except the new chord algos.

I think where are still the following quantizer issues:

  • Midi input: the note & pitch is added to the CV before the quantizer.

  • V_OCT modulations: Here, the value is also added before the quantizer.

    • It don't makes sense for all types modulations in general.
      • TM modulation should behaves more or less the same as the TM engine.
      • SEQ Modulations similar issue.

For me there is no need to quantize midi - but I will try that later.
I will also test modulations.

@koswir
Copy link
Author

koswir commented Dec 16, 2024

@eh2k
In general the quantization seems work with midi too.

The new problem I found:
In some pitches I noticed random jumps between quantized notes which happens only in the main view.
If I switch to the i/o page - its fine.
I thought it may be some kind of midi to cv noise but it also happend over usb midi to o_c.
There is just one faulty note in the attached video in C ionian, but in other scales and keys there are other notes with such a behaviour.

quantizer-noteskippingtest.mp4

@eh2k
Copy link
Owner

eh2k commented Dec 17, 2024

@koswir @rootapprox

there is a new update 78883e6, with following changes.

  • If you have noticed, since yesterday there was a display bug in the V_OCT parameter when a modulation was set.
  • The midi pitch is no longer quantised
  • The V_OCT parameter is no longer quantised - allso all modulations, except RND and TM.
  • @koswir - I think I have fixed the bug shown above - but I haven't tried to recreate it.
  • Possible the "Braids Renaissance Chords" chords now also correct, when I get the chance I'll flash the firmware on my Braids to compare it directly.
    • Feel free to create a new Issue for further discussion...

Here is the code snippet that shows how the CV is currently calculated. At the moment I am not sure whether the midi_note should be quantized or not. The same actually applies to the V_OCT parameter (which I now add after the quantization, as the scale actually already corresponds to the quantizer)

constexpr int32_t PITCH_PER_SEMITONE = PITCH_PER_OCTAVE / 12;
constexpr int32_t DEFAULT_NOTE = 60;

int32_t cv = 0;
int32_t mod_cv = 0;

int32_t midi_note = (_ctrl.midi_note - DEFAULT_NOTE) * PITCH_PER_SEMITONE;
int32_t midi_pitch = ((float)_ctrl.midi_pitch / 8192 * PITCH_PER_OCTAVE);

if (param_v_oct)
{
    get_v_oct(param_v_oct, &cv, &mod_cv); // get the value & mod_cv form v_oct parameter

    if ((param_v_oct->mod->src == MOD_RND || param_v_oct->mod->src == MOD_TM) == false)
    {
        cv += mod_cv;
        mod_cv = 0;
    }
}

cv += quantizer->Process(midi_note + _ctrl.cv + mod_cv, io->qz_root * PITCH_PER_SEMITONE);
cv += midi_pitch;
cv += io->cv_transpose(); // transpose + finetune

@koswir
Copy link
Author

koswir commented Dec 20, 2024

Hey @eh2k
Thanks for the update!

  • @koswir - I think I have fixed the bug shown above - but I haven't tried to recreate it.

Yep - the bug seems gone!

  • Possible the "Braids Renaissance Chords" chords now also correct, when I get the chance I'll flash the firmware on my Braids to compare it directly.

No - actually Renaissance Chords are still quantized only in C (and also these are not triads but 7th chords).
In other scales weird things happen 😮I recorded two vids to illustrate the problem.
The Color parameter is set to 0 so it doesn't add any note to the test.

Here is the chord output in C aeolian. It works. The right notes in C aeolian are C, D, D#, F, G, G#, A#

Cmin-chords-works.mp4

And here is the weirdness of E aeolian. The right notes for E aeollian should be E, F#, G, A, B, C, D.
I have really no idea what happens there - there is no quantizer setting except maybe SEMI that can create such notes.
There are all the notes except C# in the output.

Emin-chords-wtf.mp4

The note controlled by the Colour knob also acts kinda weird - it plays fifths or sixths adding octaves and going very hight but starting from the +1 oct (it neven plays fifth in the basic octave).

In the Braids Renaissance documentation says:
"Chord Modes
(...)when quantizer is enabled with one of the diatonic modes (dorian, aeolian, etc), the chords will stay in key, picking the correct major or minor chord and extensions based on the configured quantizer mode and root note. For example if the quantizer is set to C Dorian, sending a D value into the V/oct input will result in a minor triad. Color parameter still controls the chord extension but is also picked correctly based on the scale determined by the quantizer."

That is not a very detailed explanation, but seems the chords should be triads with extensions controlled by the Color parameter (I guess it means 7th, 9th etc.).

  • If you have noticed, since yesterday there was a display bug in the V_OCT parameter when a modulation was set.
  • The midi pitch is no longer quantised
  • The V_OCT parameter is no longer quantised - allso all modulations, except RND and TM.
    Here is the code snippet that shows how the CV is currently calculated. At the moment I am not sure whether the midi_note should be quantized or not. The same actually applies to the V_OCT parameter (which I now add after the quantization, as the scale actually already corresponds to the quantizer)

I had no time to test these up.

  • Feel free to create a new Issue for further discussion...

Honestly I feel that the one I started is still unsolved, but of course if I should write somewhere else - please move the post.
👋

@eh2k
Copy link
Owner

eh2k commented Dec 22, 2024

@koswir - thanks again for reporting - I have found the bug.

image

in the latest firmware 8c3e8a9, the chord keys are listed on the right now.
It was initially intended for debugging, but I left it to give an idea of what the colour parameter does.
The first number is the note index in the quantizer-table ( 64 = C4 ) the other are the offset.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants