Jump to content

TidalCycles


Yaxu
 Share

Recommended Posts

Thanks @Nil

If you're interested, I've inserted a code snippet below. This may very well make. your eyes bleed, because, well, it's Racket, but the important thing is a sequence is simply a list:

(list note null null null) is a sequence of four steps where the first step is a function called "note". "null" means, well, null. In Racket you can also write this as '() or #f if you find that more readable.

The other thing you see here is sequences can have an arbitrary number of steps. These are spaced evenly among the available time for a sequence. So in this example tracks inherit the time settings from the global settings, meaning a loop is 8 1/4 beats at 128 BPM and then the sequence i2seq1 puts five steps in that time and the sequence i2seq2 three. This makes it really easy to sequence polymeter. It's also possible to sequence polyrhythms but then you would need to set separate loop lengths for each track (which you can do).

So in theory this can get pretty fancy. In practice, it turns out it's nearly impossible to get good timing. I've spent all day on it today and the best I've managed to come up with is "fairly wobbly" although if you limit the number of tracks they can at least stay (somewhat) in sync with each other.

Spoiler
#lang racket

;; Demo (2) for rs, the racket sequencer. This demo shows you can play
;; multiple sequences that each have a different number of steps
;; (polymeter) on different instruments.
;;
;; To prepare, make sure you have at least one MIDI port available and
;; two instruments, one of which listens on channel 1 and the other on
;; channel 2.

(require "rs.rkt"
         "rs-m.rkt")

(when (not (length (list)))
  (printf "No MIDI ports available. This will not work.\n"))

;; Again, set up a simple 128 BPM loop with 8 sub divisions of 1/4 beats
;; each and start it. Note the ! at the end of these function
;; names. This ! means the function will cause something to happen to
;; the main loop.
(rs-set-global-bpm! 128)
(rs-set-global-div-length! 1/4)
(rs-set-global-steps! 8)

(rs-start-main-loop!)


;; Create an instrument on the first channel of the first available
;; MIDI port.
(define instr1 (rs-m-instr 0 1))

;; Create another instrument on the second channel of the first available MIDI port.
(define instr2 (rs-m-instr 0 2))

;; Create events and sequences for the first instrument.
(define i1low (rs-m-event-play instr1 48 100 90))
(define i1hi (rs-m-event-play instr1 60 50 80))
(define i1seq1 (list i1low
                     null
                     i1hi
                     null))
(define i1seq2 (list null
                     i1low
                     i1low
                     i1hi))

;; Create events and sequences for the second instrument.
(define i2low (rs-m-event-play instr2 48 100 90))
(define i2med (rs-m-event-play instr2 47 50 80))
(define i2hi (rs-m-event-play instr2 60 50 70))
(define i2seq1 (list i2low
                     null
                     i2med
                     null
                     i2hi
                     null))
(define i2seq2 (list i2hi
                     i2med
                     i2low))

;; Create tracks for each instrument. They can use the main loop settings for now.
(define track1 (rs-track i1seq1))
(define track2 (rs-track i2seq1))

;; First queue the first track
(rs-queue-track! track1)

;; Let it play for a while.
(sleep 2)

;; Introduce the second track
(rs-queue-track! track2)

;; Let it play for a while.
(sleep 4)

;; Make the second track play a different sequence (and wait a while).
(set-rs-t-seq! track2 i2seq2)
(sleep 4)

;; Make the first track play a different sequence (and wait a while).
(set-rs-t-seq! track1 i1seq2)
(sleep 4)

;; Stop the first track but leave the second one running.
(rs-stop-track! 0)
(sleep 2)

;; We're done. Stop the main loop. The performance is over.
(rs-stop-main-loop!)

 

 

  • Like 1
Link to comment
Share on other sites

Lisp is fucking dope. If you get any further along with this I might be interested in playing with this.

TC is awesome but part of what eventually scared me off is my brain being too small for Haskell... every time I waded in to try to change some core utility's behavior, it was like swimming into shark-infested code waters wearing floaties.

Link to comment
Share on other sites

18 hours ago, sweepstakes said:

Lisp is fucking dope

Now this is something I’m gonna get a tattoo of. On my butt. ? 

As it happens, someone *just* released something called Scheme4Max that allows you to interact with Max using Scheme. It even comes with a REPL so live coding would be a possibility.

From the looks of it it is fairly low level so you would have to do quite a bit of Max hacking to get to a situation where you can do easy sequencing with it. This might be a worthwhile avenue to explore, though, as hooking into Max will take care of what I’m finding are some of the hard bits to implement (proper timing, mostly). Drawback, of course, is that you’d have to hold your nose and do some programming in Max. ?
 

Github is here: https://github.com/iainctduncan/scheme-for-max

Video showing sending messages and accessing objects in the patcher is here:

https://youtu.be/ErirIFCTdjg

 

  • Like 1
Link to comment
Share on other sites

17 hours ago, rhmilo said:

Tonight I managed to massively improve the timing issues I had so it's now at a point where "it works on my machine". If you're not afraid of compiling some code (you need to perform some elbow grease to get the MIDI library installed) you can play around with it if you like:

https://github.com/mcdejonge/rs

Awesome, starred! I hope to fart around with this over the weekend. Got any docs on roadmap, next steps, wishlist, etc.?

Link to comment
Share on other sites

53 minutes ago, sweepstakes said:

Awesome, starred! I hope to fart around with this over the weekend. Got any docs on roadmap, next steps, wishlist, etc.?

Hey, thanks for you interest! Looking forward to hearing how you get along with it ? 
 

Next steps would be simply to play around within and determine what works and what does not and then write wrapper code to make sequencing with it more fluent. Or, you know, fix bugs as people run into them ?

The idea is to keep the core as lean and compact as possible (less code == less bugs) and to put additional features in add ons that save you from having to type the same thing out over and over again. 

Featuring very prominently on the wish list is making installation easier. This will involve dealing with someone else’s library, though, so I’m not sure how feasible it is.

Also on the wish list / next steps / roadmap is offsets per step, where you can move a single step forwards or backwards in the timeline, like in Elektron sequencers.

But anyway, thanks again for your interest and hope you have fun with it!

  • Like 1
Link to comment
Share on other sites

I watched Noise Quest last night on Graham Dunning's Youtube page, and there was a live 45 minute jam performed using TidalCycles.

 

Its not Graham Dunning doing the coding, its Tamu Nkiwane

Link to comment
Share on other sites

On 5/1/2020 at 3:31 PM, rhmilo said:

Hey, thanks for you interest! Looking forward to hearing how you get along with it ? 
 

Next steps would be simply to play around within and determine what works and what does not and then write wrapper code to make sequencing with it more fluent. Or, you know, fix bugs as people run into them ?

The idea is to keep the core as lean and compact as possible (less code == less bugs) and to put additional features in add ons that save you from having to type the same thing out over and over again. 

Featuring very prominently on the wish list is making installation easier. This will involve dealing with someone else’s library, though, so I’m not sure how feasible it is.

Also on the wish list / next steps / roadmap is offsets per step, where you can move a single step forwards or backwards in the timeline, like in Elektron sequencers.

But anyway, thanks again for your interest and hope you have fun with it!

Got it running! Thanks for that RTmidi patch; once I remapped origin to your repo and did a couple silly tests to wrap my head around how Racket/raco manages dependencies, I was off to the races pretty quickly.

Timing doesn't seem bad here on Arch Linux. I tried rs-demo2 and there was some funky phasing between the tracks but it sounded kind of cool so I thought it might be intentional :)

Right off the bat, one thing I'd like to see is more logging just to understand what's going on, but I also understand wanting to keep the code lean. Maybe it could just be added to the demos?

Also the ability to select the MIDI port would be great. As would having some kind of daemon running - a persistent port could be managed more easily. But again, more code :P

Edited by sweepstakes
Link to comment
Share on other sites

7 hours ago, sweepstakes said:

Got it running! Thanks for that RTmidi patch; once I remapped origin to your repo and did a couple silly tests to wrap my head around how Racket/raco manages dependencies, I was off to the races pretty quickly.

Timing doesn't seem bad here on Arch Linux. I tried rs-demo2 and there was some funky phasing between the tracks but it sounded kind of cool so I thought it might be intentional :)

Right off the bat, one thing I'd like to see is more logging just to understand what's going on, but I also understand wanting to keep the code lean. Maybe it could just be added to the demos?

Also the ability to select the MIDI port would be great. As would having some kind of daemon running - a persistent port could be managed more easily. But again, more code :P

Glad to hear you got it running and thank you very much for the detailed report. Very helpful!

Logging would negatively impact performance, but it could be turned on or off as needed. I’m not quite sure what you would want to see logged, however?

The ability to select the MIDi port is definitely there. I guess I just haven’t made it clear that you can do this. The demos all use the first available one but you can use as many as you like. Anyway, will make it more clear.

As for the daemon: what do you mean exactly? What sort of commands should it receive? I’m genuinely puzzled by this remark: right now there’s a main loopmthat starts and stops other loops and that’s it. What else would you like to see?

 

Finally: demo 2 being wonky. Yes, that’s a demo that illustrates doIng 3 over 4 and then 5 over 4.

 

Thanks again for trying it out!

 

Link to comment
Share on other sites

On 4/30/2020 at 3:52 PM, rhmilo said:

Now this is something I’m gonna get a tattoo of. On my butt. ? 

As it happens, someone *just* released something called Scheme4Max that allows you to interact with Max using Scheme. It even comes with a REPL so live coding would be a possibility.

From the looks of it it is fairly low level so you would have to do quite a bit of Max hacking to get to a situation where you can do easy sequencing with it. This might be a worthwhile avenue to explore, though, as hooking into Max will take care of what I’m finding are some of the hard bits to implement (proper timing, mostly). Drawback, of course, is that you’d have to hold your nose and do some programming in Max. ?
 

Github is here: https://github.com/iainctduncan/scheme-for-max

Video showing sending messages and accessing objects in the patcher is here:

https://youtu.be/ErirIFCTdjg

 

Ok! Im ready for this book ?

https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html

(in another life maybe)

Link to comment
Share on other sites

8 hours ago, rhmilo said:

Glad to hear you got it running and thank you very much for the detailed report. Very helpful!

Logging would negatively impact performance, but it could be turned on or off as needed. I’m not quite sure what you would want to see logged, however?

The ability to select the MIDi port is definitely there. I guess I just haven’t made it clear that you can do this. The demos all use the first available one but you can use as many as you like. Anyway, will make it more clear.

As for the daemon: what do you mean exactly? What sort of commands should it receive? I’m genuinely puzzled by this remark: right now there’s a main loopmthat starts and stops other loops and that’s it. What else would you like to see?

 

Finally: demo 2 being wonky. Yes, that’s a demo that illustrates doIng 3 over 4 and then 5 over 4.

 

Thanks again for trying it out!

My perspective was very biased by the fact that I expected to have to do a lot more work to get it up and running, so I was expecting to have to figure out whether Racket thought it was sending things, and then check out on my synths whether they were receiving things, etc. For troubleshooting, lots of logging can make a huge difference.

As far as selecting the MIDI port, I must have just missed that line of code. As for why I wanted that, file that also under the visual-feedback-to-assist-in-troubleshooting bucket. If I had implemented it, I would've enumerated & logged the available ports and the selected port without even thinking about it, but the fact that you didn't is another thing that keeps the code small.

Yeah I'm not sure where I was coming from with the daemon idea, that's pretty wacky. If you already have a main loop running persisting that connection to the port, there's no reason to make a daemon. Super unnecessary complication.

1 hour ago, xox said:

Ok! Im ready for this book ?

https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html

(in another life maybe)

That book is awesome. I think I only made it through the first couple chapters. Going through the whole thing is on my bucket list.

  • Like 1
Link to comment
Share on other sites

@sweepstakes

even i, who knows nothing about programming, understand how good and influential that book is! I wish i had more time to learn programming. My job (3 parallel jobs/lives actually) is just to time consuming to learn anything else. ?

  • Like 1
Link to comment
Share on other sites

1 hour ago, sweepstakes said:

My perspective was very biased by the fact that I expected to have to do a lot more work to get it up and running, so I was expecting to have to figure out whether Racket thought it was sending things, and then check out on my synths whether they were receiving things, etc. For troubleshooting, lots of logging can make a huge difference.

Ah, ok. I see where you’re coming from. My own line of thinking is more along the Unix way of doing things: be quiet if thinks work but if they don’t fail loudly. Had you tried to connect to a nonexistent MIDI port, you would have noticed ? .

That said, trouble shooting mode might be useful. I’ll add it*

1 hour ago, sweepstakes said:

As far as selecting the MIDI port, I must have just missed that line of code. As for why I wanted that, file that also under the visual-feedback-to-assist-in-troubleshooting bucket. If I had implemented it, I would've enumerated & logged the available ports and the selected port without even thinking about it, but the fact that you didn't is another thing that keeps the code small.

You’ve found a stupid mistake in the demos. I’ve accidentally removed the bit where it checks the available MIDI ports. Sorry. (rs-m-list-ports) will show you the list of ports. Will fix.

1 hour ago, sweepstakes said:

Yeah I'm not sure where I was coming from with the daemon idea, that's pretty wacky. If you already have a main loop running persisting that connection to the port, there's no reason to make a daemon. Super unnecessary complication.

Ok. Glad we’ve cleared that up ? I thought I missed something really obvious.

3 hours ago, xox said:

Ok! Im ready for this book ?

https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html

(in another life maybe)

Like @sweepstakes I’ve read a few chapters. It’s pretty good, though the focus on mathematical examples obscures the fact that a lot of the ideas in those first chapters have become reasonably commonplace since the book was first published in 1986. Even Java allows has lambdas (of a sort) these days and composing functions is not at all uncommon in Python or JavaScript.

I still mean to finish it someday. However:

* I can’t promise when I’ll next have time to do significant work on this. Might not be before the summer holidays (last week I had a week off so I had time to scratch this itch).

  • Like 1
Link to comment
Share on other sites

29 minutes ago, xox said:

@sweepstakes

even i, who knows nothing about programming, understand how good and influential that book is! I wish i had more time to learn programming. My job (3 parallel jobs/lives actually) is just to time consuming to learn anything else. ?

That's really impressive, actually. I hadn't even heard of it until I had been programming professionally for several years, and even then I just assumed it was arcane knowledge for folks who really want to dig deeper and learn the roots (which, at least in the enterprise world, is pretty rare).

6 minutes ago, rhmilo said:

Ah, ok. I see where you’re coming from. My own line of thinking is more along the Unix way of doing things: be quiet if thinks work but if they don’t fail loudly. Had you tried to connect to a nonexistent MIDI port, you would have noticed ? .

That said, trouble shooting mode might be useful. I’ll add it*

You’ve found a stupid mistake in the demos. I’ve accidentally removed the bit where it checks the available MIDI ports. Sorry. (rs-m-list-ports) will show you the list of ports. Will fix.

Ok. Glad we’ve cleared that up ? I thought I missed something really obvious.

Like @sweepstakes I’ve read a few chapters. It’s pretty good, though the focus on mathematical examples obscures the fact that a lot of the ideas in those first chapters have become reasonably commonplace since the book was first published in 1986. Even Java allows has lambdas (of a sort) these days and composing functions is not at all uncommon in Python or JavaScript.

I still mean to finish it someday. However:

* I can’t promise when I’ll next have time to do significant work on this. Might not be before the summer holidays (last week I had a week off so I had time to scratch this itch).

Thanks for the reply! I'm on board with the small-sharp-tools philosophy.

Functional programming in JavaScript is what made me hungry for learning Lisp in the first place. I've become rather comfortable with the former, but the latter remains unquenched for now. This very moment is probably not the best time for me to dive in, but I've always got an ear to the ground for reasons to dig in.

No worries on not doing any kind of overhauls in the immediate. In the cold light of morning I remember I have a decent number of irons in the fire myself (re-learning guitar from basically square one, WeeklyBeats, beginner/intermediate-level SuperCollider sequencing and synthesis, learning fermentation, and the usual mundane yard/house/paid work) so it'd be irresponsible for me to make any new promises myself. If I do happen to spend a decent amount of time exploring and testing, I'll send you an issue and/or PR.

Before I forget, I wanted to express my appreciation that you chose Racket over Clojure. I do like both of them. However, while Clojure has a lot of nice libraries and a good community, it's always been a bit flaky for me and relying on the JVM has always felt kind of icky. I admire that you kept it lean, FOSS-pure, and platform-agnostic.

  • Like 1
Link to comment
Share on other sites

This isn't TidalCycles but it's somewhat related. Python async audio programming. This seems very low level, wonder if the TidalCycles DSL could be ported to run on a python based back end

 

 

  • Like 1
Link to comment
Share on other sites

3 hours ago, sweepstakes said:

Before I forget, I wanted to express my appreciation that you chose Racket over Clojure. I do like both of them. However, while Clojure has a lot of nice libraries and a good community, it's always been a bit flaky for me and relying on the JVM has always felt kind of icky. I admire that you kept it lean, FOSS-pure, and platform-agnostic.

I was just about to ask if rhmilo had considered Clojure. I'm writing music software in Clojure right now and can recommend it, having access to the Java ecosystem as well as the ability to farm out low-level number-crunching code to Java is a big plus in my experience. I haven't tried doing anything with MIDI though, my software does all the synthesis itself.

  • Like 1
Link to comment
Share on other sites

9 hours ago, Rotwang said:

I was just about to ask if rhmilo had considered Clojure. I'm writing music software in Clojure right now and can recommend it, having access to the Java ecosystem as well as the ability to farm out low-level number-crunching code to Java is a big plus in my experience. I haven't tried doing anything with MIDI though, my software does all the synthesis itself.

No I didn’t but that’s because I’ve never used it, sorry. Would be interested to hear what you come up with, however ?

Edited by rhmilo
Hit Reply too soon
Link to comment
Share on other sites

Not any stupider than the tacit rule that an electronic music live act needs some sort of video to accompany the music ? At least, there's a "what you see is what you hear" take that's honest IMO, rather than occulting the performance the way so many electronic artists do. YMMV / my 2 cents etc...

Link to comment
Share on other sites

21 minutes ago, Nil said:

Not any stupider than the tacit rule that an electronic music live act needs some sort of video to accompany the music ? At least, there's a "what you see is what you hear" take that's honest IMO, rather than occulting the performance the way so many electronic artists do. YMMV / my 2 cents etc...

Agree! 
 

but still, I thought programmers are smarter than that. 

Edited by xox
Link to comment
Share on other sites

I'm not sure it's a matter of intelligence from the coders / musicians, rather a recently enacted, implicit demand from the audience and promoters. I don't blame A/V shows à la Daft Punk, Aphex or Alva Noto* (and countless more). No, I just regret that it has somehow become the norm this last ten years.

* mentioning them as they've offered such shows for decades now.

Link to comment
Share on other sites

47 minutes ago, Nil said:

I'm not sure it's a matter of intelligence from the coders / musicians, rather a recently enacted, implicit demand from the audience and promoters.

So the audience want to see the code while they dance or just stand and listen to music? Ok! Cmon! Isnt that stupid? If yes, who’d what that if not programmers themselves? Id say that’s muuuuch more stupid than to watch some beautiful graphics of alva noto; at least is less intellectual than those graphics. The graphics at least has some abstract connections to music, ideally.

what happens if you notice a mistake in programming on the panel?! How would that influence your dancing?

 ? ️ ? 

would you trying to find a mistake? What if autism kicks in?! 

Edited by xox
Link to comment
Share on other sites

I guess I've expressed my point very poorly. Audiences and promoters alike wants to "see" something during an electronic performance. Showing code is just a way among others to address that demand, with an emphasis on the "score". Or to fill a visual void if you prefer ?

Now, note that live-coding also can encompass visual, and something like Hydra offers real-time algorithmic graphics.

I for one don't care about visuals as long as the music is amazing.

Alva Noto's visuals are mind-blowing, I'm lucky I've seen him live twice. They were icing on the cake, as hearing both TransAll trilogy and Xerrox Vol.1 on great PAs remains what made his sets special. Offering such quality visuals needs skills and resources, and not all artists can offer similarly qualitative AV performance.

I've played countless shows in the past, some badass venues and festival included (some shitty ones too of course), and more often than not, visuals are a bonus to sell your performance to a promoter. And that was ten years ago, I imagine it's almost mandatory nowadays (unfortunately). That fucking sucks.

Don't get me wrong, once again some AV shows are absolutely amazing. I just regret it has almost become the norm. Lets all play in the dark, æ style, or in the fog of a smoke machine à la Tim Hecker.

Ps: I'll add that showing the code is also part of the "open source" / "lets share knowledge" DNA of the Algorave movement.

Ps2: it might also be a way, paradoxically, to shift the attention towards the music rather than on the "how to" ? I mean, I've attended countless gigs where parts of the audience seem to pay more attention to the technical part of the performance rather than on the music itself. Same goes for hardware centric performances, does it even matter to see someone triggering sequences and turning knobs of the music's amazing ? I don't know, if the set-up is exposed and the mystery revealed, is it still worth it to even care about the "how" ? Just thinking out loud here.

Ps3: mistake in code ? If it sounds great then it's not a mistake hehe ?

Edited by Nil
Ps2&3
  • Like 5
Link to comment
Share on other sites

18 hours ago, Nil said:

Ps: I'll add that showing the code is also part of the "open source" / "lets share knowledge" DNA of the Algorave movement.

This. I think it's a great response to the "secret weapon" mentality running through a lot of electronic music.

  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.