A synthesizer for arbitrary EDO (equal division of the octave) scales, written for the monome in Haskell

can be found here.

It’s a working synthesizer, and also a working demonstration of how to speak to serialosc using Haskell. The synth relies on SuperCollider, but it’s written in Haskell, specifically using the Vivid library. The sound is simple – just some distorted sine waves – but easily edited (it’s the function called boop, in the file ET31.hs). The latency (on my system anyway) is excellent; I’m not sure I even notice it.

I expect to be extending it for the rest of my life. First on the agenda:

  • Controls to shift octave.
  • A sustain pedal.
  • A sustain-current-notes-but-not-future-ones button. (Some physical pianos have this.)
  • A bank of chords to write to and read from.
  • A bank of loops to write to and read from.
  • Timbre controls.
  • Split keyboard.

The Vivid module looks really cool. Is that how Tidal Cycles talks to scsynth?

Would love to see an example video if someone feels inclined! Also nice to see someone build something for the grid using Haskell. Would love to contribute something to that backend infrastructure (maybe auto-address-discovery) if you’re open to that.

Looking forward to experimenting with 31 tones very soon!

1 Like

Would love to contribute something to that backend infrastructure

That would be amazing!

Would love to see an example video

I’ll do that before the end of the year, I think. Work happens to have recently gotten heavy, but I expect it to calm down in a few months.

I tried to write Haskell music code for a long time and couldn’t do it. Now that I’ve got SuperCollider and Haskell and Vivid and Vivid-OSC in place, the code practically writes itself.

I don’t think Tidal uses Vivid; I just grepped the code for “vivid” (with -i for case-insensitive) and found no results.

I guess that is it. Haskell is finally taking the world :astonished:

Kidding aside, didn’t knew about the Vivid library, it is very nice to see the world of technology augmenting artistic possibilities! And that is also because of good developers like you sir, thanks for this beautiful addition to the community.

It feels strange that most synthesizers still rely on (or presuppose, at least) a 12 tones per octave keyboard. Don Buchla decades ago would already depart from this idea in favor of other dimensions of control, and microtonality came from even earlier, as old as music itself.

So I’m really happy to see this project developing around 31 ET and timbral music, although I’m not a monome owner. Thanks and keep up! :clap: :clap: :clap:

Really excited to try this as well- thanks for sharing @Jeffrey_Brown ! Actually, I’ve been thinking (once I get time to learn how to code it) that it would be great to have a keyboard like this for norns as well.

Video walk-through.


I updated the app. Now it can play in any temperament, not just 31-edo.

Here’s the code[1]. The readme (visible on the same page) explains it in detail.

[1] https://github.com/JeffreyBenjaminBrown/monome


hi jeffrey

does you app works with gs128 monome also?
i would like to try – i am using tidal also, installed with cabal… installing this using stack will not mess my tidal install, right? :smiley:

thx in advance!!!

Sure! It works with a grayscale 128 (I use one myself), and it shouldn’t interfere with Tidal.

You’ll want to check out not the master branch, but the windowsCanMove branch, which I’m currently working on. (It already works, I’m just making it better.)

The St (state) type includes the following field:

  _stWindowLayers :: Map MonomeId
                     [ ( (X,Y) -- ^ the top-left corner
                       , Window app ) ]

The MonomeId type is just an enum for my three monomes. You can change it to whatever you want. Currently it’s this:

data MonomeId = Monome_256 | Monome_128 | Monome_old

(My Monome_old is also a 256.)

Note that monome coordinates are like CGI coordinates: (0,0) is the top-left, and they increase as you go down or right.

Montevideo.Monome.Main defines where the windows are on each monome.

I should note that this design is going to change a little. If you check out this commit:

you won’t have to deal with those changes. The upcoming changes will be to give each “keyboard window” (there are also a Shift window to shift the keys, a Sustain window that functions kind of like a piano sustain pedal, and windows for changing parameter values) separable timbres and sustain facilities.

You get your choice of which windows to use, and where. See Montevideo.Monome.Main’s edoMonome function for how I set the values of stWindowLayers and edoKeyboards.

You could modify the code if you wanted to make it so that most of the time, most of the area of your 128 is the keyboard, but sometimes it instead lets you control the parameters of the synth. (Currently I put a keyboard window on the two 256s and use the 128 for parameter control. That’s how you’ll find the code when you clone the repo.)