Blog topic: Tidal Music - Xuixo EP by Relyt R

Ready to expand your musical horizons? Eager to learn about microtonal algorave? Then dig in! Relyt R has given us an amazing view into the creative world behind their new EP release - Xuixo. It features

algorithmic and machine learning enabled techno and dance music using non-Western tunings, including 19-, 21-, and 33-tone equal temperaments - what is termed xenharmonic.

The music here is intense, driving, & alive! It is both familiar (fast beat techno/dance influenced), full of unexpected surprises of timbre and textures, and also highly unusual and, well, yes "alien." The blog post is incredible in its depth of coverage, analysis, and attributions. We see the influences, the theory, the Tidal code, custom Haskell functions, chord structures, mixing and production methods, aesthetics, yes and more! Covered topics:

  • Wave Clustering Workflow
  • binaural panning with Envelop max4live
  • NEJI tuning learned from the Xenharmonic discord
  • Brauerizing mixing techniques
  • Arturia Pigments with Sevish scale workshop
  • Toussaint's Geometry of Musical Rhythm
  • drum bus limiting
  • Slynk's recipe for sub bass
  • tricks learned from kindohm - preventing sample bleed
  • pulu's non-default ncat
  • and (whew!) yes more. :exploding_head: :exploding_head:

Don't know all of these? (Don't know any of these?) Then check it out!!
and say no to twelve notes and no to 16 beats!


cool stuff, lots of useful info in there!

1 Like

Very interesting, and the EP is an absolute banger! Congrats @RTylerMclaughlin !!!

1 Like

This music is fantastic, and the writeup of it is heroic. Bravissimo!

1 Like

Love the EP, love the ideas, love the writing, love the code <3

been having fun with the wav_clustering_workflow repository, a great start to dig into python properly!

one question though, you refer to that repo as a machine learning tool - which part of it exactly is based on machine learning? or is it more of a ML-adjacent tool insofar as it can be used to prepare labelled datasets?

I started reading this blog post today and I'm really enjoying your approach. Thanks for taking the time to write this up!

I'm having issues compiling the definition of takeArp'. I imported sortOn through import Data.List (sortOn) (I presume that is the function you are using here) and now compiling the code, I get the following error:

    • Couldn't match type: Pattern ValueMap
                     with: [Double]
      Expected: [Double]
        Actual: ControlPattern
    • In the second argument of ‘take’, namely
        ‘(cycle (patternToList p))’
      In the second argument of ‘nTake’, namely
        ‘(take amt (cycle (patternToList p)))’
      In the expression: nTake name (take amt (cycle (patternToList p)))

    • Couldn't match expected type: Pattern Double
                  with actual type: [b]
    • In the first argument of ‘cycle’, namely ‘(patternToList p)’
      In the second argument of ‘take’, namely
        ‘(cycle (patternToList p))’
      In the second argument of ‘nTake’, namely
        ‘(take amt (cycle (patternToList p)))’
    • Relevant bindings include
        p :: Pattern b
        nT :: String -> Int -> Pattern b -> ControlPattern

Do you have any pointers on how to make this work?

thanks for reading and listening @QBRNTHSS @Robin_Hase @mashaal @jeff_brown and @jobi !

sorry for the belated reply, happy to answer questions. :slight_smile:

The tool is based on hierarchical clustering, a form of unsupervised machine learning, implemented in Python's scipy.cluster.hierarchy. Like NMF, VAEs, and PCA, it's a way to find structure in complex, high-dimensional data. It's not deep learning--there's no neurons or backpropagation--and a deep generative model with a VAE would be fun to try.

1 Like

@jobi, Oh yes, the import Data.List is necessary, kudos for finding that!

Copying the code from the blogpost works for me on two separate installations, with tidal_version returning 1.7.2 and 1.9.4.

hmmm. it's not clear to me which function is broken in your session. Here's how I'd test patternToList in isolation:

import Data.List

let patternToList pat = map value $ sortOn whole $ queryArc pat (Arc 0 1)

# this should run without errors
d1 $ n $ toScale (patternToList "0 3 5 7 10") "0 [2 3] 4 5" 
1 Like

I figured out my issue: years ago I had defined a custom function in my Tidal Boot script called cycle that was overriding the default cycle function from Data.List.

Sorted now and now able to make wild microtonal music. Thanks again and great work!


oh no, i can imagine going through that. a treacherous bug for sure.

I'm so happy you got it working @jobi ! (=