Music DSL (Domain Specific Language) is a project aimed at providing a unique way to create and manipulate musical compositions programmatically. This project allows users to define musical pieces using a custom syntax and convert these definitions into MIDI files for playback and further processing.
The Music DSL project encompasses a parser for the DSL, a MIDI generator, and various utilities for handling musical elements like noteDTOS, chords, and rhythms. The project is structured into several modules, each responsible for a different aspect of music generation.
git clone git@github.com:TobiasBonifay/dsl-midi_MusicDSL.git
cd dsl-music
mvn clean install
To run the project, use the following command:
java -jar target/music-dsl-1.0-SNAPSHOT-jar-with-dependencies.jar [path-to-dsl-script]
This will generate a MIDI file in the same directory as the DSL script.
The following is a simple example of a DSL script that generates a MIDI file:
signature 4/4
bpm 120
Instruments:
piano ACOUSTIC_GRAND_PIANO volume 50
clip MyPiece:
bar [
track piano:
C4-E4-G4, C5
]
bar [
track piano:
C4, C5, C3
]
Timeline:
MyPiece x 2
You can find some scenarios at antlr/src/main/java/fr/polytech/scenario
Run the script using the command above to generate a MIDI file named MyPiece.mid
.
java -jar target/music-dsl-1.0-SNAPSHOT-jar-with-dependencies.jar src/main/resources/examples/basic.dsl
You can find the BNF of the language in the following file: antlr/src/main/java/fr/polytech/bnf.bnf
// This piece features a simple intro with a piano playing chords and a drum kit on a standard 4/4 time signature at 120 BPM.
signature 4/4
bpm 120 // set the tempo to 120 BPM. Default 140
timeshift 1 // The human like error of time in ticks. A quarter note is 120 ticks on 4/4 time signature. Default is 5.
velocityrandomization 10 // The human like error of velocity. Velocity range is 0-127 depending on the dynamic of the note. Default is 5.
resolution 100 // To define the resolution to use. Default is 480 Ticks. Please use a positive integer.
Instruments: // define the instruments used in the piece. Drums should not be defined here.
piano ACOUSTIC_GRAND_PIANO volume 50 // define the piano instrument with the ACOUSTIC_GRAND_PIANO soundfont and a volume of 50 (0-100).
trackName VIOLIN volume 100 // define the trackName instrument with the VIOLIN soundfont and a volume of 100.
clip Intro <- ppp: // define the Intro clip with a dynamic of ppp (pianississimo) -> noteDTOS are played very softly by default.
bar [ // define the first bar of the Intro clip. Bar must be defined inside a clip.
tempo + 100 // increase the tempo by 100 BPM.
signature 3/4 // change the time signature to 3/4 for this bar only.
track trackName: // a track can be empty.
// empty
track piano:
Do3-DO4-C5, Re#4, mib5 // Note can be played simultaneously by separating them with a '-' or sequentially by separating them with a ','.
]
bar [
track trackName:
// rest is a note that is not played. COULD be writen as 'SILENCE' | 'REST' | 'PAUSE' | 'SILENT' | 'MUTE' in any case.
// Note CAN be defined either by their latin name (Do, Re, Mi, Fa, Sol, La, Si) or by their english name (C, D, E, F, G, A, B).
// Octave MUST be defined after the note name.
// Note CAN be defined with a dynamic (ppp, pp, p, mp, mf (default), f, ff, fff).
// Note CAN'T be defined with an articulation (staccato, tenuto, accent, marcato, fermata).
// Note CAN be defined with a duration (1/32, 1/16, 1/8, 1/4, 1/2, 1 (default), 2, 4).
rest, G4 mf (1/2), G4 mf (1/2), G3, SILENCE
track piano:
// empty
track drums:
LOW_TOM (1/2), LOW_TOM (1/2), COWBELL, LOW_CONGA, COWBELL
// drum patterns can be defined using the following syntax: 'DRUM_NAME (DURATION)'.
// DURATION is optional and can be defined as a fraction (1/4, 1/2, 1 (default)). Default is one per beat.
// BE CAREFUL: DRUM_NAME is case sensitive. No coma is needed between drum patterns.
]
clip Chorus:
bar [
tempo - 70
volume 90
track trackName:
SILENT, G4 mf, G3, SILENT
track piano:
do4 mf, re#4 mf, mib5 ff, REST
track drums:
KICK (1/2), SNARE (1/2), SNARE, KICK, SNARE
]
Timeline: // timeline is needed.
Intro
Chorus x 2 // repeat the Chorus clip twice. Be careful, space before and after 'x' is needed.
main
.For detailed documentation, visit [Project Documentation Link].