Bringing the Tidalcycles Mini-Notation to the Browser
Total Page:16
File Type:pdf, Size:1020Kb
Bringing the TidalCycles Mini-Notation to the Browser Charles Roberts Mariana Pachon-Puentes Interactive Media & Game Development Department of Computer Science Department of Computer Science Worcester Polytechnic Institute Worcester Polytechnic Institute [email protected] [email protected] ABSTRACT panying library, and their integration into various browser- TidalCycles has rapidly become the most popular system for based creative coding systems. We then discuss techniques many styles of live coding performance, in particular Algo- for visually annotating the playback of TidalCycle patterns, raves. We created a JavaScript dialect of its mini-notation taking advantage of the browser's flexible markup capabili- for pattern, enabling easy integration with creative cod- ties. We conclude with a short discussion of open questions, ing tools. Our research pairs a formalism describing the and possible directions for future work. mini-notation with a small JavaScript library for generat- ing events over time; this library is suitable for generating 2. BACKGROUND events inside of an AudioWorkletProcessor thread and for Live coding is growing in popularity, with new systems in- assisting with scheduling in JavaScript environments more troduced every year and an growing number of local interest generally. We describe integrating the library into the two groups and performances. The browser has become a popu- live coding systems, Gibber and Hydra, and discuss an ac- lar target for many live coding systems, thanks to its ubiq- companying technique for visually annotating the playback uity, powerful graphics capabilities, and increasingly power- of TidalCycles patterns over time. ful audio features. In this section we discuss existing live coding tools and their notations for music|with an empha- 1. INTRODUCTION sis on TidalCycles|and the state of current browser-based live coding systems. In canonical live coding performances, performers create artistic output by programming it in front of an audience, 2.1 TidalCycles often projecting their source code for the audience to follow TidalCycles is a domain-specific language embedded within [21]. Such performances have increased in popularity over Haskell [11]. It has proven to be one of the most popular the years; for example, organizers have promoted hundreds choices for live coding, particularly in the Algorave genre, of concerts in one genre of live coding performance, Algo- perhaps due to its strong emphasis on time and rhythm [10]. rave[4], where performers take turns live coding (predom- For example, in a recent four-day streamed live coding event, inantly) dance music. The browser is a popular platform sixty-five of approximately one hundred and sixty perfor- for developers creating live coding systems, with many en- mances primarily used TidalCycles[19]. The next most pop- vironments that primarily target music, visuals, and chore- ular end-user language in the event was SuperCollider[9], ography, in addition to hybrid systems enabling performers with eighteen live coding performances1. to generate both audio and visual content (see Section 2). TidalCycles outputs OSC or MIDI messages, and perform- Our research takes the pattern mini-notation of TidalCy- ers have used it to control a wide variety of applications. It cles[11] and brings it to JavaScript as a library that can be is most often used to remotely control SuperDirt, an audio incorporated into browser-based live coding environments. sample playback and manipulation engine written in Super- The TidalCycles mini-notation is a terse and expressive way Collider. to describe patterns of values over time, and we hope that bringing this popular representation to the browser will en- 2.2 Live Coding and Patterns courage adoption across many systems. Section 4 describes There are a variety of techniques for generating patterns some of the integrations we and other developers have cre- in live coding systems. In ixi lang[6], a mini-language that ated to date. controls the SuperCollider audio server, patterns (or scores But first we begin by describing the state of live coding in in ixi lang terminology) are defined using strings, with the the browser, alongside a brief introduction to TidalCycles. location of each token determining the timing of notes and We describe our implementation of the parser and accom- sample playback. In both Gibber[15] and in Conductive[3], a Haskell live coding environment where the programmer controls semi-autonomous agents, there are separate pat- terns for values in sequences and controlling the timing of Licensed under a Creative Commons Attribution 4.0 International License (CC BY 4.0). Attribution: owner/author(s). 1Although live coding in the SuperCollider language is ar- Web Audio Conference WAC-2019, December 4–6, 2019, Trondheim, Norway. guably not as popular as live coding in TidalCycles, many © 2019 Copyright held by the owner/author(s). live coding systems provide an alternative language that uses the SuperCollider audio server for synthesis and processing. sequence output. For example, in Listing 1, the pattern it is easy to incorporate into browser-based projects without [0,1,2,3] selects notes from a default global scale while requiring the use of a Haskell compiler5, potentially easing the pattern [1/4,1/2] specifies that these notes will have adoption into other systems. alternating durations of a quarter note and a half note. 3. IMPLEMENTATION syn= Synth() We created two modules, designed to work in tandem, en- syn.note.seq( [0,1,2,3], [1/4,1/2] ) abling the use of the TidalCycles patterns in the browser. Listing 1: A sequence in Gibber The first module is a parser for the TidalCycles mini- notation. This parser was written using the parsing expres- Other systems opt for more verbose temporal recursions sion grammar formalism (or PEG); we have prior experi- (functions that invoke themselves over time[17]) or corou- ence using this formalism to teach workshops on live coding tines that provide low-level control of timing and output. language design [20]. The PEG.js library 6 translates the For example, the Extempore and Imporomptu systems use TidalCycles grammar into a parser that generates appropri- verbose temporal recursions to generate patterns, often ate JavaScript data structures for querying, which is handled based on sampling continuous waveforms [18]. While these by our second module. Following the general structure of the recursions are lengthy to type by hand (at least in the con- TidalCycles library, this module exposes a queryArc func- text of a live performance), the environments include text- tion which accepts three arguments: a pattern, a start time, editing macros that make insertion and editing fast and and a duration 7. From these three arguments a list of val- fluid. Sonic Pi[1] uses a terser design similar to a coroutine ues and timestamps is generated; the timestamps are offsets named the live_loop, where loops can sleep and are ed- from the starting phase argument passed to queryArc and itable. Gibber and Gibberwocky[13] also support temporal the values typically correspond to either indices in a scale recursions, in addition to their shared pattern affordances. denoting a pitch to be played or an identifier for a sam- The mini-notation in TidalCycles is based on the Bol Pro- ple/sound to be triggered. The code example below shows cessor (BP2)[2]. Polyrhythms, polymeter, repetition, and these two modules in use employing the CommonJS module rhythmic subgrouping can all be described quite tersely. For syntax. example, the pattern string ‘[kd sd, ch ch oh]’ describes a pattern where a kick drum and a snare drum are each half a cycle in duration, while the closed hihat and open hihat parser= require(’./dist/tidal.js’) sounds are each a third of a cycle, creating a two against queryArc= require(’./src/queryArc’).queryArc three polyrhythm. The expression of both timing and out- put values in the same text string provides a terseness that pattern= parser.parse(’0 [1 2]’) events= queryArc( pattern, 0, 1 ) lends itself well to live coding. In our experience develop- /∗ ing and performing with Gibber, we found that while defin- ∗ events=[ ing output and timing separately has it merits, we often ∗ { value:0, arc:{ wanted the expressiveness of a combined notation similar to ∗ start:Fraction(0), end:Fraction(1,2)} the TidalCycles mini-notation. ∗ }, ∗ { value:1, arc:{ 2.3 Browser-based Live Coding Environ- ∗ start:Fraction(1,2), end:Fraction(3,4)} ments ∗ }, ∗ { value:2, arc:{ There are at least a dozen browser-based environments for ∗ start:Fraction(3,4), end:Fraction(1)} live coding performance2. Some are geared heavily towards ∗ } audio3, while others emphasize graphics [5, 16], and at least ∗ ] one targets choreography4. Our hope is that the research ∗/ presented here will be broadly applicable to a variety of such Listing 2: Using the parser and query function systems. In this vein, we discuss the integration of our li- brary into two browser-based live coding environments, Hy- We combined the two modules together into a single dra and Gibber, in Section 4. Pattern object for easier use. The Pattern constructor ac- Of particular relevance to this paper is Estuary[12], which cepts an argument pattern written using the TidalCycles provides a projectional editing interface for TidalCycles (in mini-notation; the generated pattern object can then be addition to other live coding systems), and runs in the queried by passing a starting phase and a duration to its browser. The authors developed the software in Haskell, query method. The Pattern.query method also sorts its which was then compiled into JavaScript. One notable ad- output by the temporal proximity of each event to the start vantage of this approach is that almost all of the features time of the query. Listing 3 shows this in action, assuming of TidalCycles were immediately available to the authors, that the Pattern object has been imported into the global while our approach requires implementing each of TidalCy- namespace.