
Combining Effects in a Music Programming Language based on Patterns Andre´ Rauber Du Bois1∗, Rodrigo Geraldo Ribeiro2 1Programa de Pos-Graduac¸´ ao˜ em Computac¸ao˜ Universidade Federal de Pelotas, Pelotas-RS, Brazil 2Programa de Pos-Graduac¸´ ao˜ em Cienciaˆ da Computac¸ao˜ Universidade Federal de Ouro Preto, Ouro Preto - MG, Brazil [email protected],[email protected] Abstract. HMusic is a domain specific language based on to deal with effects. More precisely, the contributions of music patterns that can be used to write music and live this paper are as follows: coding. The main abstractions provided by the language • are patterns and tracks. Code written in HMusic looks like We extend the abstractions of HMusic to incor- patterns and multi-tracks available in music sequencers, porate effects. Basically, two new types of tracks drum machines and DAWs. HMusic provides primitives are added: a track that takes a list of effects that to design and combine patterns generating new patterns. are applied in order to the track’s pattern, and a The objective of this paper is to extend the original de- master track that applies a set of effects to a multi- sign of HMusic to allow effects on tracks. We describe track (Section 3.1) • new abstractions to add effects on individual tracks and HMusic provides two operators for combining in groups of tracks, and how they influence the combina- multi-tracks, a sum operator that takes two multi- tors for track composition and multiplication. HMusic al- tracks and generates a new track that plays the lows the live coding of music and, as it is embedded in the two multi-tracks one after the other, and a mul- Haskell functional programming language, programmers tiplication operator that takes an integer n and a can write functions to manipulate effects on the fly. The multi-track t and generates a track that is n times current implementation of the language is compiled into t. We extend the behaviour of these operations Sonic Pi [1], and we describe how the compiler’s back-end to deal with effects and explain the semantics of was modified to support the new abstractions for effects. track composition in the presence of effects (Sec- HMusic can be and can be downloaded from [2]. tion 3.3) • We show how the new abstractions for effects can be used during a live coding session (Section 4) 1 Introduction • We describe how the new abstractions presented Computer music is usually associated with the use of soft- in this paper can be compiled into Sonic Pi code ware applications to create music, but on the other hand, (Section 4) there is a growing interest in programming languages that To understand the paper the reader needs no pre- let artists write software as an expression of art. There are vious knowledge of Haskell, although some knowledge of a number of programming languages that allow artists to functional programming and recursive definitions would write music, e.g., CSound [3], Max [4, 5], Pure Data [6], help. We try to introduce the concepts and syntax of Supercollider [7], Chuck [8], FAUST [9], to name a few. Haskell needed to understand the paper as we go along. Besides writing songs, all these languages also allow the live coding of music. Live coding is the idea of writing The paper is organized as follows. First we de- programs that represent music while these programs are scribe HMusic and the main constructors for pattern (Sec- still running, and changes in the program affect the music tion 2.1) and track (Section 2.2) design and their basic being played without breaks in the output [10]. operations. Next, the extensions for effects are explained (Section 3.1). In Section 3.3, we examine the semantics of HMusic [11] is a Domain Specific language for track composition, i.e., combining different multi-tracks to music programming and live coding. HMusic is based on form a new track, in the presence of effects. Live coding the abstraction of patterns and tracks where the code looks with effects is explained in Section 4. The compilation of very similar to the grids available in sequencers, drum ma- HMusic with effects into Sonic Pi is described in Section chines and DAWs. The difference is that these abstractions 5. Finally, related work, conclusions and future work are have an inductive definition, hence programmers can write discussed. functions that manipulate these tracks in real time. As the DSL is embedded in Haskell, it is possible to use all the power of functional programming in our benefit to define 2 HMusic new abstractions over patterns of songs. 2.1 HMusic Patterns This paper discusses new abstractions for HMusic HMusic is an algebra (i.e., a set and the respective func- ∗Supported by CAPES. tions on this set) for designing music patterns. The set of 106 17th Brazilian Symposium on Computer Music - SBCM 2019 all music patterns can be described inductively as an alge- 2.2 HMusic Tracks braic data type in Haskell: A track is the HMusic abstraction that associates an instru- data MPattern = X | O ment to a pattern. The Track data type is also defined as | MPattern :| MPattern an algebraic type in Haskell: data Track = The word data creates a new data type, in this MakeTrack Instrument MPattern case, MPattern. This definition says that a pattern can | Track :|| Track be either playing a sample (X), a rest (O), or a sequential composition of patterns using the operator (:|), that takes type Instrument = String as arguments two music patterns and returns a new pattern. A simple track can be created with the As an example, we can define two 4/4 drum pat- MakeTrack constructor, which associates an terns, one with a hit in the 1st beat called kick and another Instrument to a MPattern.A Track can also that hits in the 3rd called snare. be the parallel composition of two tracks, which can be obtained with the :|| operator. Instrument is a type kick :: MPattern synonym for Strings. An instrument can be any audio kick = X :| O :| O :| O file accessible by the Sonic Pi environment (see Section 5). snare :: MPattern Now, we can use the previously defined patterns snare = O :| O :| X :| O kick and snare to create tracks: The symbol (::) is used for type definition in kickTrack :: Track Haskell, and can be read as has type, e.g. kick has type kickTrack = MakeTrack "BassDrum" kick MPattern. snareTrack :: Track As MPattern is a recursive data type, it is pos- snareTrack = sible to write recursive Haskell functions that operate on MakeTrack "AcousticSnare" snare patterns. For example, usually a certain pattern is repeated and also multi-tracks: many times in a song, and a repeat operator (.*) for pat- terns can be defined as follows: rockMTrack :: Track rockMTrack = (.*) :: Int -> MPattern kickTrack :|| -> MPattern snareTrack :|| 1 .* p = p MakeTrack "ClosedHiHat" (X:|X:|X:|X) :|| n .* p = p :| (n-1) .* p MakeTrack "GuitarSample" X The repeat operator takes as arguments an integer 3 Effects in HMusic n and a pattern p, and returns a pattern that is a composi- tion of n times the pattern p. As can be seen in the previous In this paper, the abstractions of HMusic are extended to example, the composition operator (:|) can combine drum incorporate effects. The new abstractions allow to add ef- patterns of any size and shape, e.g.: fects in individual tracks (Section 3.1) and in a group of tracks (Section 3.2). The use of effects in live coding is hihatVerse :: MPattern discussed in Section 4. hihatVerse = 8 .* (X :| O :| X :| O) 3.1 Effects on Tracks hihatChorus :: MPattern hihatChorus = 4 .* (X :| X :| X :| X) To incorporate effects on tracks, the MTrack data type was extend with a new type of track: hihatSong :: MPattern hihatSong = hihatVerse :| data MTrack = (...) hihatChorus :| | MakeTrackE Instrument [Effect] MPattern hihatVerse :| Besides Instruments these tracks can take as hihatChorus argument a list of effects that are applied in order. In the current implementation, effects available in Sonic Pi can or simply: be loaded in tracks (see Section 5), like changing the rate hihatSong :: MPattern of samples, reverb, amp, etc: hihatSong = 2 .* (hihatVerse :| data Effect = Reverb Float | Amp Float hihatChorus) | Attack Float | Rate Float | Sustain Float | (...) In order to make any sound, a pattern must be as- sociated to an instrument hence generating a Track, as For example, we can now write a drum multi- explained in the next Section. track which adds a bit of reverb on the snare: 17th Brazilian Symposium on Computer Music - SBCM 2019 107 drums :: MTrack Where lengthMP recursively calculates the size drums = of a pattern, and lenghtTrack finds out the size of the MakeTrackE "snare" [Reverb 0.3] snare :|| largest pattern in a track, i.e., the size of the track. MakeTrack "kick" kick :|| MakeTrack "hihat" (X:|X:|X:|X) HMusic provides two constructs for composing tracks in sequence, a repetition operator |* and a sequenc- As the MTrack data type has an inductive def- ing operator |+. The repetition operator is similar to .* inition, we can write recursive functions that manipulate but operates on all patterns of a muti-track: effects and tracks (e.g., add, remove, modify) while music |* :: Int -> Track -> Track is being played, as described in Section 4. It takes an integer n and a multi-track t and re- 3.2 Effects on Groups of Tracks peats all patterns in all tracks n times, adding the needed HMusic was also extend to support the addition of effects rest beats at the end of smaller tracks. in a group of tracks: An operator for combining two multi-tracks t1 data MTrack = (...) and t2, generating a new multi-track is also provided: | Master [Effect] MTrack |+ :: Track -> Track -> Track The Master track takes two arguments, a list of When combining two multi-tracks, tracks that use effects and an MTrack, which is possibly a multi-track, the same instruments and effects are merged.
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages8 Page
-
File Size-