Aria's thread of barely working betas and bug squashing: Psychopump (in library soon)

Yes.

I want Darius to be “easy to learn, impossible to tame”. I don’t want to overwhelm the user with too many esoteric import/export options.

The knobs are internally represented as follows (rotated CW):

Step 1:               00        
Step 2:             02  01            
Step 3:           05  04  03          
Step 4:         09  08  07  06        
Step 5:       14  13  12  11  10      
Step 6:     20  19  18  17  16  15    
Step 7:   27  26  25  24  23  22  21  
Step 8: 35  34  33  32  31  30  29  28

Despite having four directional trigger inputs, the up and down inputs do not move within the same step bud forward diagonally. E.g., from node 04, the Down input moves to 08. Arbitrary movement within the grid is impractical. By design it is about repetition, call & response structures. Most users move through the steps in sequence and disregard the “back” input.

Thus, importing 36 events means that:

  • I need 36 events to import, while many sequencers will have a multiple of 8.
  • The events would never be played in sequence, thus any melody would be unrecognizable.
1 Like

What a great seuencer! I dream of a Daruis ADSR: attack always the same, then two probable options for decay, 4 prob for sustain, 8 prob for decay :slight_smile:

2 Likes

After many hours of research and a few private conversations with friends, I have settled on the following list of scales. Once I push it to the library, it’s set in stone forever for Darius and any future module I make. Otherwise I’d break people’s songs. So if you have remarks make them now! I am not very knowledgeable about theory and want to get it right the first time.

A few design considerations:

  • Except for the Major/Natural minor, and Major pentatonic/Minor pentatonic, no scales that are modes of another. Or in simpler words, when represented on a single piano octave, no scales that, when transposed, can be represented identically. I make an exception for the two pairs above for convenience of dialing in settings without having to look up the transposition rules.
  • Only 12 Tone Equal Temperament. So no scales that can only be approximated in 12TET, such as Balinese Pelog or Arabic 24TET scales minus the quarter tones.
  • When scales have multiple common names, I prefer the one that is the easiest to abbreviate on my LCD (which will definitely be reused on other modules in the future). That’s why I go for “Gypsy Major” rather than “Double Harmonic”.
  • The curation has to be limited! The more I add, the harder it is to operate the selection knob. I support arbitrary external scales anyway.
  • Prefer “instant satisfaction” presets to musical curiosities. So no Enigmatic scale, for example.
  • The scales should be sorted in a somewhat coherent order.

Here’s my current list, in order:

  • Chromatic
  • Major
  • Natural Minor
  • Melodic Minor
  • Harmonic Minor
  • Pentatonic Major
  • Pentatonic Minor
  • Whole Tone
  • Blues Major
  • Blues Minor
  • Dominant Diminished
  • Bebop Major
  • Bebop Minor
  • Gypsy Major
  • Eight Tone Spanish
  • Hirajōshi
  • In Sen
1 Like

Good point. would not be a very good default behavior.

haha - I was going to suggest the only ones missing from the list Seq++ has are those ones. And you’ve got a bunch I don’t have.

1 Like

And with the last automatic build, every user-facing planned feature (except portable sequences) was implemented, so be sure to give it a try! I’ll submit it to the library soon.

Learned a TON doing this update, about C++, synth design, and music theory. I was surprising myself at things I had working perfectly on the first attempt (for example, slide). And while the LCD might be a bit over the top, I plan to turn it into a reusable component for future modules.

If someone could tell me whether it works on OSX that would be useful! I know it compiles, so hopefully it will work.

As usual, automatic builds for every platform are here:

And here’s an unintended fun little trick I discovered:

Have two quantized Darii with identical settings, with the range set (integral values work well so it spans one or more octaves). Give them both the same clock and the same random seed. On the second instance, invert the Min and the Max value. Presto - you’ve inverted the melody! Use the -1 oct toggle, and you’ve got a bassline correlated to the melody.

I was trying not to copy other people’s selection, since I did not know if they had the same goals in their selection! It’s easy to find databases that give a name to all 4096 possible scales, but it’s way harder to settle on settings that will be fun to play with. Plus, it was educational for me, haha.

3 Likes

Nice list! I wonder if it would not be better to have all major scales together, then all “neutral scales” then minor scales, because major or minor is the first choice you make, and then you check if you want to go for pentatonic, or blues.

Also the simple fact of scrolling the scales becomes musical, as done in the 4ms resonator

3 Likes

What’s that piece of software with the cassette at 5:21 in the video?

Excellent, thank you for adding the last two. A few quantizers (mother and XOR one) have an option for Pelog but still using 12tet (as far as I know) and sound great. I don’t know how much difference it makes or if it has another name when 12tet though.

1 Like

Voicemeeter Banana, the virtual audio driver system I use to route stuff between programs.

All I gathered from researching the topic is that there is a huge amount of variation across gamelan ensembles, so I don’t feel confident offering the option, I’d rather leave it to module creators more versed in the topic. I see that Frozen Wasteland made a quantizer for Arabic music that seems very thoroughly researched, for example.

Plus, I’m trying to be kinda culturally respectful (without overdoing it), so I don’t want to name something “Balinese” or “Pelog” if I’m aware it’s just an approximation of the real thing. Also did a fair bit of research to figure out whether there is opposition to the term “Gypsy scale” in English, but the term seems generally well established and neutral in music (whereas many Roma people object to it as a demonym). I’m trying not to be that person still naming a synth preset “Ethnic Beats” in 2020, yknow, lol.

If I continue making modules, I think I’d like my collection to be a cohesive system that focuses on exploring the possibilities of live improvisation of generative / aleatoric techno with repetitive patterns in 4/4 & western scales.
I have various ideas where I want to take things next: a sequencer focusing on live performance of an evolving pattern, my own take on the turing machine, gimmicky live performance controllers.

6 Likes

Oh, also the word “Gypsy” is considered racist these days.

1 Like

Yeah, as I mentioned the pejorative connotation only seem to exist when you call people that, but I see the word remains commonly used to refer to the culture without it seeming to be an issue. But on the other hand, just showing the word on a LCD below a piano diagram might not establish sufficient context, especially if it’s seen by someone who can’t identify that what they’re seeing is a music synthesizer module. I guess it might be worth swapping it to something like “DbHARMO.” on the LCD.

1 Like

I had to find some term for a package of music my company was releasing. In that case it didn’t really matter what we called it, so I think I picked “Paris in the 1920’s”. You are correct I think that using the word to describe the scale is pretty safe. On another note, did you know the “Romany” people were Indians who moved north around year 1000?

1 Like

(Thanks for the mention, @Squinky. I don’t have any radical suggestions - this proposal looks very good. I would say that a means of scattering the notes of an imported sequence throughout the knobs would be kind of equivalent to “create a scale based on the notes that this sequence uses, and invent a bunch of possible melodies based on that scale,” which might be musically useful despite the fact that the original melody would be lost. Maybe I’m suggesting an actual “Paste sequence as scale” command?)

1 Like

It would definitely be useful to support that on the separate module I plan to make to program external scales and chords!

1 Like

There seems to be no bug reports, so I submitted the Darius update to the library. Portable sequences will be implemented in a future update.

I think I will also record a quick video explaining its new features (unless a resident youtuber is interested in doing something, I guess).

I tried to make the quantizer and LCD into baby’s first C++ library, I have plans to re-use those components a lot in future modules. It’s probably not very good code (but it works), and if anyone cares to give it a quick constructive critical read, I welcome advice.

Also, if anyone’s interested, instead of keeping my notes private, I’ve made my future plans for VCV modules public - feel free to contact me with comments about them.

5 Likes

Very nice, and I really like your “statement of purpose”. As someone who programs c++ for my “day job”, please allow me to comment on the code…

First - the good stuff: the quantizer code has comments in it that are not only better than what I usually see in VCV code, but better than what I see every day in “commercial” code. Super useful for anyone who wanted to use this code.

Also - it’s very clearly written. It’s very readable. Again, much better than what I’m used to seeing. and, fwiw, on both of these points my code is pretty good, but yours is better.

Now - let’s tear it apart!

First thing I noticed is that when I view the code from the GitHub UI, it’s not lined up / indented correctly. I assume it looks fine in Visual Studio Code where you are writing it. This is almost always caused by putting tabs in your code. Github probably interprets tabs differently that your current settings in VSCode. While programmers argue about this all the time, I think the majority would agree that your code should use four spaces for indenting, rather than using tabs. You can easily re-configure VSCocde to do this.

Second thing: all of the functions in your quantizer are at “global scope” / “top level name-space”. Meaning that now you have a function called “noteName”. You can never have another function called noteName or they will conflict. Different people use different techniques to avoid this. Without getting overly detailed, you can put all this in a class, or in an namespace.

It would be very easy to retrofit a namespace. Just add namespace quantizer { at the start and put a closing brace at the end. Then from you code call it as quantizer::noteName. You an even avoid that if you say using namespace quantizer at the top of the consuming file (but don’t do that).

Next: by passing around std::array you may be making copies of the arrays, which might be incurring a runtime overhead (make your plugin use too much CPU). The compiler may be smart enough to realize it doesn’t need to do this, but if you look in the docs, std::array<T>::operator = is documented as making a copy. Easy work around, pass in a reference, like inline float quantize(float voltage, std::array<bool, 12>& validNotes) {. For extra credit you can join the cool kids and use const std::array<bool, 12>& validNotes).

Lastly, and this is really not important, your quantize algorithm needs to compare against possibly 12 pitches in the scale, which takes a bit of CPU time. Probably not important. The university people would say this algorithm is O(n), where n is the number of notes in the scale. If you instead used an std::set it would be O(log(n)) and std::unordered_set would be O(1).

But I’m just mentioning this to show off. 12 times though the loop is just fine, and doing it the cool way would be a lot of work and aggravation that you really don’t need.

Anyway, all these criticisms are kind of nit-picky and overly technical. That fact that the code is readable and commented means that next year you will probably be able to go back and understand it, and re-use it. I believe it also make for reliability – if you can look at it and see what it does it’s less likely there are bugs hiding in there.

5 Likes

In this case, would declaring the argument as const provide any performance benefit?

No, I don’t believe so. It more a “safe programming” thing so the caller can know that the function won’t modify the “shared” array. can make it easier to read the code, and will generate compiler errors if you mistakenly modify the shared array in the quantize function. But mostly a nit-picky thing, not of great importance.

1 Like

Thanks for looking into it!

Haha yeah, I’m just getting started using VS code. I’m not used to having an editor/IDE capable of inferring this much accurate knowledge about my code - because I’m not used to languages that actually benefit from such a degree of assistance. I’ll have to take the time to set up properly now that got to try it out a bit.

There’s still an embarrassing amount of copy-pasting boilerplate that appear to work without me really understanding the implications of it, I’ll have to catch up on that.

At least, writing code that has a budget of fractions of microseconds to evaluate is curing me of finding it scary graphics programming has a budget of 16 millisecond per frame, at the cost of having discovered an entirely new magnitude of terror. Gonna have to set up profiling to understand better what’s happening.

(BTW, that file was namespaced! or at least it is in the dev branch. i just didn’t indent it to avoid indenting the whole file.)