Skip to content

An embedded Scala DSL for expressive music composition. This was part of my MS in Software Engineering research.

License

Notifications You must be signed in to change notification settings

gmoe/dsl-prototype

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

31 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Music DSL Prototype

This is a prototype Scala-embedded domain specific language for composing and transforming music, which aims to be expressive and intuitive for non-programmers. The DSL also contains generative modules that can be pulled in by the composer when necessary, such as Xenakis sieves and Markov chains. Examples of these can be found in the wiki.

Examples

Here is a use case demonstrating how to create modulations from one key to another using function composition:

scala> import PitchClass._, RomanNum._
import PitchClass._
import RomanNum._

scala> C`_`4
res0: rc.dsl.Primitives.Pitch = Cβ‚„

scala> (F`#`4) != (G`b`4)
res1: Boolean = true

scala> (F`#`4).isEnharmonic(G`b`4) // can also use (F`#`4) ~= (G`b`4)
res2: Boolean = true

scala> val cMajor = Ionian(res0)
cMajor: rc.dsl.Ionian = Ionian(C)

scala> val fSharpMajor = Ionian(F`#`4)
fSharpMajor: rc.dsl.Ionian = Ionian(Fβ™―)

scala> val modulate = fSharpMajor.to compose cMajor.from
modulate: rc.dsl.Primitives.Pitch => rc.dsl.Primitives.Pitch = <function1>

scala> modulate(D`#`4)
res3: rc.dsl.Primitives.Pitch = Gπ„ͺβ‚„

Another goal of this DSL is to be able to start from small ideas, like a rhythm, and be able to build onto it. Here is an example of zipping together a list of beats with a list of pitches to form notes:

scala> val pitches = List(C`_`4, E`_`4, G`_`4, B`_`4)
pitches: List[rc.dsl.Primitives.Pitch] = List(Cβ‚„, Eβ‚„, Gβ‚„, Bβ‚„)

scala> val beats = List(Beat(4), Beat(4), Beat(8), Beat(8))
beats: List[rc.dsl.Primitives.Beat] = List(Quarter, Quarter, Eighth, Eighth)

scala> val notes = (pitches zip beats).collect { case (p:Pitch,b:Beat) => Note(p,b) }
notes: List[rc.dsl.Primitives.Note] = List(Note(Cβ‚„,Quarter), Note(Eβ‚„,Quarter), Note(Gβ‚„,Eighth), Note(Bβ‚„,Eighth))

scala> val measure = Measure(TimeSignature(3,4), notes:_*)
measure: rc.dsl.Structures.Measure = Measure(TimeSignature(3,4),List(Note(Cβ‚„,Quarter), Note(Eβ‚„,Quarter), Note(Gβ‚„,Eighth), Note(Bβ‚„,Eighth)))

Here is another example of functional composition, which threads a starting pitch through a sequence of musical intervals:

scala> import IntervalQuality._
import IntervalQuality._

scala> val steps = List(Interval(2,Major), Interval(5,Perfect), Interval(-3, Minor), Interval(2,Minor))
steps: List[rc.dsl.Interval] = List(M2, P5, -m3, m2)

scala> val melody = thread(C`_`4)(steps)
melody: List[rc.dsl.Primitives.Pitch] = List(Cβ‚„, Dβ‚„, Aβ‚„, Fβ™―β‚„, Gβ‚„)

Examples for additional DSL modules can be found in the wiki.

About

An embedded Scala DSL for expressive music composition. This was part of my MS in Software Engineering research.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published