[sharing] Explore scala alternative tunings in Max with sslider

    Apr 01 2021 | 11:26 pm
    Hi all!
    I would like to share this small library of abstractions that hopefully make the usage of alternative/microtonal tunings more accessible! It uses the library of 5000+ scala tuning files from the Stichting Huygens-Fokker, and you can also import your own.
    The package contains 3 abstractions and a custom jsui file:
    • th.scala - Load a scala scale into a dictionary, refered to by other objects to easily switch scales for multiple scalaToFrequency converters (stof)
    • th.stof - Convert a number from scala scale-format to the corresponding frequency based on the tune, center and cents value.
    • th.stof~ - Similar as the th.stof object, except it works in the signal domain.
    • th.sslider.js - A custom jsui file that shows a kslider-like object to allow for playing with the custom tuning files. The keys are displayed side-by-side (no black keys), and their width denote the relative interval. A light-gray key denotes the octaves.
    Works very nicely with the lately released Leimma platform by Khyam Allami and Counterpoint: https://isartum.net/leimma
    Feedback/suggestions/bugs are very much welcome, here as a comment or in the github issues page.
    Screenshot of the abstractions help-files
    Screenshot of the abstractions help-files

    • Apr 02 2021 | 1:33 am
      Wow. Thanks!
    • Apr 03 2021 | 5:23 pm
      Going to check this out at some point - thanks!
    • Apr 03 2021 | 8:15 pm
      One extra object has been included: th.ftomb (Frequency to Midi & Bend)
      This object converts any frequency and outputs an integer MIDI note number together with a pitch bending value between 0 - 127 to allow for controlling external midi devices via [noteout] and [bendout] or [midiformat] and [midiout].
      th.ftomb connect to noteout and bendout
      th.ftomb connect to noteout and bendout
    • Sep 10 2021 | 6:38 pm
      Hi Timo,
      great tool but it seems that the new version (8.2 beta) has broken something in the code.
      Opening th.scala.maxhelp, the console returns a series of errors related to the js code: js: error calling function loadScala [th.scala.js] js: th.scala.js: Javascript TypeError: f is null, line 120 js: error calling function getmenu [th.scala.js] js: error calling function loadScala [th.scala.js] js: th.scala.js: Javascript TypeError: f is null, line 120 js: error calling function getmenu [th.scala.js]
    • Sep 11 2021 | 8:18 am
      Hi! Thanks for letting me know. Have not tried the objects with the 8.2 beta, but will look into this soon and see what is going on.
    • Sep 13 2021 | 1:41 pm
      Hi Mati, I am not getting these errors, so I'm wondering what the problem is. Are you on windows or mac? Did it work in the 8.1 version of Max? Did you put the package in the max searchpath? It looks like it is not able to find the /scl files that are shipped with the package. Can you try to click (getmenu) message and see if you still get the error? Can you try to just load a single .scl file from the /scl folder with the [opendialog]? Let me know :)
    • Sep 13 2021 | 4:47 pm
      Hi Timo, thanks for the quick reaction! I'm on Mac and it's weird… With version 8.1 it works flawlessly and yes, the package is in a recognized directory. Using 'getmenu' or loading a single file returns the same error.
      A short video explains the behaviour.
    • Sep 14 2021 | 8:05 am
      Thanks for the video. I will have to investigate a bit deeper, but it seems that maybe the reading/loading of files via JS has changed in some way. Do you get any errors if you try from the menubar Help>Examples>javascript>file both `filetester` and the `folderiter` patches?
    • Sep 14 2021 | 9:45 am
      No errors if I load the files you indicated.
    • Sep 14 2021 | 6:54 pm
      Just to be sure, also no errors if you click those message boxes with (readfile) (c74:/init) etc?
    • Sep 14 2021 | 7:06 pm
      Exactly. No errors.
    • Sep 15 2021 | 4:14 pm
      Hey, I could replicate the bug after I downloaded the latest 8.2 beta from the forum (I had one version before I think). It seemed to have something to do with the .readbytes() method that I used in the js. I changed it to a different approach and now the bug should be fixed, please clone the latest commit from the github and give it a try: https://github.com/tmhglnd/th.scala
    • Sep 15 2021 | 8:04 pm
      Hi Timo, It runs again with the latest build. Thanks for the quick reaction.
    • Sep 15 2021 | 8:57 pm
      Great! Good to hear.
    • Sep 17 2021 | 12:41 pm
      Hi, I've run into another problem. When randomly selecting files, Max would sometimes crash (the very last beta). At least I found a file that crashes every time: bell_mt_partials.scl Are you experiencing it, too?
    • Sep 17 2021 | 3:08 pm
      I'm not so JS savvy to unearth the eventual problem.... I baste a rough patch to load in dict a .scl file without js.
      Max Patcher
      In Max, select New From Clipboard.
    • Sep 18 2021 | 7:08 pm
      I get this crash as well, but I also get this crash when trying to open it with the js file example, so not sure why this is. I'll investigate. Great that you've got a patch version that works in the meantime.
    • Aug 06 2022 | 11:28 pm
      Just stumbled onto this and would like to express my thanks - very helpful, thank you Timo!
    • Aug 07 2022 | 6:43 pm
      It’s brilliant.
    • Aug 08 2022 | 9:30 am
      timo, pls could you explain this?
      why not the full range? was the idea that a pb range of 2 semitones is more likely default than a range of 1 in synthesizers´ presets? i am about to make a decision if i should eventually use 0 as center and then only pitch up or use a center in my version. (to avoid having two different halves around the center.)
    • Aug 08 2022 | 7:50 pm
      @Dan/@Yaniki, thanks! If you have any feedback on the user experience let me know!
      @Roman: Yes, the idea was that because -2/+2 semitones pb range is custom for most midi devices the user does not really have to change anything in the receiving devices settings. On the other hand of course the full range would give more precision. I could also include an MSB/LSB output option, making the range more precise. But since [midiformat] also has an @hires 1 option, allowing floating-point input, I thought using that option is more than enough for this object.
    • Aug 09 2022 | 6:19 am
      i came up with that question because if you only use half the range you could as well only use the positive or negative part. it is interesting that i have never thought about the range contained in most presets (i had a lot of hardware back in the days) but i just figured that your stuff are not externals but abstractions so maybe i will just look inside. :P my (very old) approach looks like that (but there is an error in the mapping, i assumed 128 beeing the highest number which makes the whole range splitting procedure pointless^^) - and it is also 7 bit only (for the same reason: i have never investigated how common 14 bit actually is among hardware) - mtof - div/rest - round integer (also missing here? not good. what did i do.) - split rest into 0-64 and 64-127 - map these two parts from linear to the "center 64 problem" - round PB to int but maybe it would be more perfect to provide different modes from 1 to 12 semitones? hmm...
    • Aug 09 2022 | 10:08 am
      I personally also don't know how common 14-bit is amongst hardware. I made this object more for others (i think it was even a request) then that I actually use it myself.
      You can definitely look at my code, it is al done with codebox in gen.