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

Arpeggiator - Random distribution #6478

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

zonkmachine
Copy link
Member

@zonkmachine zonkmachine commented Aug 5, 2022

Implements different random sources in the arpeggiator, selectable from a new combobox, and adds a knob to control the behaviour.

Exponential (default) - A negative value make the base note more likely and the top note less likely to be selected. The opposite
is true for a positive value. Center (0) is equivalent to the old random behavior with equal representation.

Normal - Normal distribution, a bell curve. A positive value will put the weight on the center note(s) and a negative value will put
the weight on the base/top notes. Center (0) is equivalent to equal representation.

Chase - Brownian motion for the keys. Nudges the last note with a random value whose extreme value is set by the knob. On a positive value the base/top notes are stop points and on a negative value the note is allowed to warp around between base/note.


I've also made some changes to 'range' that is intended for testing purposes only. For this reason the PR is a draft for now. The range of the arpeggio doesn't go the whole way to the full octave. If you play a scale on an instrument you usually complete a full octave and this is not the case on the lmms arpeggiator. I've tested other arpeggiators and we're not unique in this regard.
I think the discussion here touches on the matter: #1836 (comment)
The 'Chase' function won't mind but the other additions is more at home in a full octave context.

https://www.youtube.com/watch?v=wegC5eXN6TU

@LmmsBot
Copy link

LmmsBot commented Aug 5, 2022

🤖 Hey, I'm @LmmsBot from github.com/lmms/bot and I made downloads for this pull request, click me to make them magically appear! 🎩

Linux

Windows

🤖
{"platform_name_to_artifacts": {"Linux": [{"artifact": {"title": {"title": "(AppImage)", "platform_name": "Linux"}, "link": {"link": "https://output.circle-artifacts.com/output/job/d97ec0ac-3828-4116-b918-bfaddaf921ec/artifacts/0/lmms-1.3.0-alpha.1.223+g064320a53-linux-x86_64.AppImage"}}, "build_link": "https://circleci.com/gh/LMMS/lmms/17940?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"}], "Windows": [{"artifact": {"title": {"title": "32-bit", "platform_name": "Windows"}, "link": {"link": "https://output.circle-artifacts.com/output/job/ce064ba3-8703-40e7-a4e6-3640bdbde094/artifacts/0/lmms-1.3.0-alpha.1.223+g064320a53-mingw-win32.exe"}}, "build_link": "https://circleci.com/gh/LMMS/lmms/17939?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"}, {"artifact": {"title": {"title": "64-bit", "platform_name": "Windows"}, "link": {"link": "https://output.circle-artifacts.com/output/job/3ea9ca4d-1f28-4850-a1c9-1a094c6bbfdd/artifacts/0/lmms-1.3.0-alpha.1.223+g064320a53-mingw-win64.exe"}}, "build_link": "https://circleci.com/gh/LMMS/lmms/17936?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"}]}, "commit_sha": "e3de88790ed756f114da0a49ce0f7ab6f008cb80"}

@allejok96
Copy link
Contributor

Works good! Here's a brain dump:

  1. If a bell curve is displaced all the way to the edge (or even a little bit more) wouldn't it be pretty close to an exponential curve - at least by the sound of it? In that case we could have an OFFSET knob instead of the Exponential function.
  2. CYCLE and MISS has no use for randomness, right? So it could be hidden or disabled or replaced by OFFSET when random is selected.
  3. It would be nice with a more descriptive name for the RAND knob, since we can't see the curve. If the knob has different meaning for different modes, it should change its label and tooltip. For normal distribution it could be "Variance".
  4. If we stick to different curves of random distribution, the icon should show each curve's shape. You could use something like filter_bp for the bell curve and white_noise_wave_active for chase.
  5. I'd prefer a checkbox for looping around in chase mode instead of negative numbers.
  6. If we had a LOOP checkbox it could apply to the bell curve too. E.g. turn OFFSET to max and tick LOOP has the same effect as negative bell curve. That way the RAND knob could be positive only. Why on earth would you want that, you ask... Because when you can't see and understand what each knob does you tend to generalize their meaning. "This is the knob that makes it center around a note". Turning that negative doesn't make sense. Plus I quite like having the knob default all the way to the left and then being able to turn it up to hear the effect it has...
  7. Since having the full octave breaks compatibility, maybe we can have a box for that too?

@zonkmachine
Copy link
Member Author

1. If a bell curve is displaced all the way to the edge (or even a little bit more) wouldn't it be pretty close to an exponential curve - at least by the sound of it? In that case we could have an OFFSET knob instead of the Exponential function.

Yes, I thought about that but I was afraid people would get tired of too much knobs. I try to keep it as simple as possible. It would be dead simple to implement though.

2. CYCLE and MISS has no use for randomness, right? So it could be hidden or disabled or replaced by OFFSET when random is selected.

CYCLE don't have a use for randomness but MISS do. Set the direction to Up or Down and add some randomness with MISS. I've thought about it but was afraid it would clutter the code to much. Would the knob be served by two different models that it switches between?

3. It would be nice with a more descriptive name for the RAND knob, since we can't see the curve. If the knob has different meaning for different modes, it should change its label and tooltip. For normal distribution it could be "Variance".

You're right. I try and keep the label to four/five letters or the layout is moved around too much. What I think the arpeggiator lacks more than anything now is a manual so I think I'll have a go at documentation and perhaps make a video about it.

4. If we stick to different curves of random distribution, the icon should show each curve's shape. You could use something like filter_bp for the bell curve and white_noise_wave_active for chase.

Fixing (pushing later). I'm thinking for a permanent solution I'd like icons which the two graph extremes superimposed on each other for the normal and exponential randomness.

5. I'd prefer a checkbox for looping around in chase mode instead of negative numbers.

Yes, or maybe rather keep them as two different menu choices. Real estate fixed...

6. E.g. turn OFFSET to max and tick LOOP has the same effect as negative bell curve.

I have a piece going right now, where I glide seamlessly between the two extremes. I like to keep that the way it is. I like the idea with a second knob better then (comment 1).

Since having the full octave breaks compatibility, maybe we can have a box for that too?

Yes, that's the easiest way to do it. I don't have any ideas that I favor really. A check box is a simple way to do it. I was thinking perhaps making the range knob have every second position being 'range +1 step'. 1, 1+1, 2, 2+1, etc. I don't know. Check box is tempting though.

Epic feedback! 🚜

@zonkmachine
Copy link
Member Author

I've also played with the idea of adding back the original plain random and then inactivate RAND. That's probably a better basic setting.

@zonkmachine
Copy link
Member Author

The pattern on Cycle when looping down, down/up was fundamentally wrong from the beginning but I only noticed it now. When starting on a high note the start note would be shifted down when adding cycle to the equation. I've added a fix for this here and the only way I could solve it was to move Cycle and Repeats to within the original direction selection logic.

if(dir == ArpDirUp || dir == ArpDirDown)
{
cur_arp_idx = ( cur_frame / arp_frames ) % range;
cur_arp_idx /= repeats;
if( m_arpCycleModel.value() )
{
cur_arp_idx *= m_arpCycleModel.value() + 1;
cur_arp_idx %= ( range / repeats );
}
// If direction is ArpDirDown the result is inverted
if( dir == ArpDirDown ){ cur_arp_idx = (range/repeats) - cur_arp_idx - 1; }
}
else if( (dir == ArpDirUpAndDown || dir == ArpDirDownAndUp) && range > 1 )
{
// imagine, we had to play the arp once up and then
// once down -> makes 2 * range possible notes...
// because we don't play the lower and upper notes
// twice, we have to subtract 2
cur_arp_idx = ( cur_frame / arp_frames ) % ( range * 2 - 2 * repeats );
cur_arp_idx /= repeats;
if( m_arpCycleModel.value() )
{
cur_arp_idx *= m_arpCycleModel.value() + 1;
cur_arp_idx %= ( range / repeats );
}
// if greater than range, we have to play down...
if( cur_arp_idx >= range / repeats )
{
cur_arp_idx = range - cur_arp_idx % ( range - 1 ) - repeats;
}
// If direction is ArpDirDownUp the result is inverted
if( dir == ArpDirDownAndUp ){ cur_arp_idx = (range/repeats) - cur_arp_idx - 1; }

@zonkmachine
Copy link
Member Author

the only way I could solve it was to move Cycle and Repeats to within the original direction selection logic.

I found a better fix for this and pulled it separately in #7007

 Implements different random sources in the arpeggiator, selectable
 from a new combobox, and adds a knob to control the behaviour.

 Exponential (default) - A negative value make the base note more
 likely and the top note less likely to be selected. The opposite
 is true for a positive value. Center (0) is equivalent to the old
 random behavior with equal representation.

 Normal - Normal distribution, a bell curve. A positive value will
 put the weight on the center note(s) and a negative value will put
 the weight on the base/top notes. Center (0) is equivalent to equal
 representation.

 Chase - Brownian motion for the keys. Nudges the last note with a
 random value whose extreme value is set by the knob. On a positive
 value the base/top notes are stop points and on a negative value the
 note is allowed to warp around between base/note.
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

Successfully merging this pull request may close these issues.

3 participants