This project provides a Java library for representing and synthesizing musical pieces. It allows users to define musical notes, silences, and staffs, and to synthesize the sound of a complete musical piece using virtual instruments.
This library is composed of the following classes:
@startuml
hide empty members
skinparam classAttributeIconSize 0
' -------------------- '
' Note representations '
' -------------------- '
enum NoteValue {
+ {static} WHOLE
+ {static} HALF
+ {static} QUARTER
+ {static} EIGHTH
+ {static} SIXTEENTH
+ {static} THIRTY_SECOND
+ {static} SIXTY_FOURTH
+ {static} ONE_HUNDRED_TWENTY_EIGHTH
+ {static} TWO_HUNDRED_FIFTY_SIXTH
- fractionOfWhole
- type
~ NoteValue(fractionOfWhole: double, type: String)
+ duration(tempo: int): int
+ {static} fromString(type: String): NoteValue
}
enum PitchClass {
+ {static} C
+ {static} C_SHARP_D_FLAT
+ {static} D
+ {static} D_SHARP_E_FLAT
+ {static} E
+ {static} F
+ {static} F_SHARP_G_FLAT
+ {static} G
+ {static} G_SHARP_A_FLAT
+ {static} A
+ {static} A_SHARP_B_FLAT
+ {static} B
+ {static} fromName(name: String): PitchClass
}
class NotePitch {
- {static} NB_OCTAVES: int
- {static} NOTE_PITCHES: Map<PitchClass, NotePitch[]>
- pitchClass: PitchClass
- octave: int
- frequency: double
- NotePitch(pitchClass: PitchClass, octave: int, frequency: double)
+ {static} of(pitchClass: PitchClass, octave: int): NotePitch
+ {static} of(pitchClass: PitchClass, octave: int, alteration: int): NotePitch
+ alter(alteration: int): NotePitch
+ flat(): NotePitch
+ sharp(): NotePitch
+ frequency(): double
}
interface Note {
+ {abstract} getFrequency(): double
+ {abstract} getDuration(tempo: int): int
}
interface AbstractNoteFactory {
+ {abstract} createRest(value: NoteValue): Note
+ {abstract} createNote(pitch: NotePitch, value: NoteValue): Note
+ {abstract} createDottedNote(note: Note): Note
+ {abstract} createFermataOn(note: Note): Note
+ {abstract} createTiedNotes(notes: Note[]): Note
+ {abstract} createTiedNotes(notes: List<Note>): Note
}
NotePitch o-- PitchClass
AbstractNoteFactory --> Note : << creates >>
class RestNote implements Note {
- value : NoteValue
+ RestNote(value : NoteValue)
+ getFrequency() : double
+ getDuration(tempo : int): int
}
RestNote ..|> Note
RestNote --> NoteValue : use
class MusicalNote implements Note {
- pitch : NotePitch
- value : NoteValue
+ MusicalNote(pitch : NotePitch, value : NoteValue)
+ getPitch() : NotePitch
+ getValue() : NoteValue
+ getFrequency() : double
+ getDuration(tempo : int) : int
+ toString() : String
}
MusicalNote ..|> Note
MusicalNote --> NotePitch : utilise
MusicalNote --> NoteValue : utilise
class SimpleNoteFactory implements AbstractNoteFactory {
- {static} instance : SimpleNoteFactory
- SimpleNoteFactory()
+ {static} getInstance : SimpleNoteFactory
+ createNote(pitch : NotePitch, value : NoteValue) : Note
+ createRest(value : NoteValue) : Note
+ createDottedNote(note : Note): Note
+ createFermataOn(note : Note): Note
+ createTiedNotes(notes : List<Note>): Note
}
SimpleNoteFactory ..|> AbstractNoteFactory
SimpleNoteFactory --> Note : crée
SimpleNoteFactory --> NotePitch : utilise
SimpleNoteFactory --> NoteValue : utilise
SimpleNoteFactory --> MusicalNote : crée
SimpleNoteFactory --> RestNote : crée
class TiedNote implements Note {
- notes : List<Note>
+ TiedNote(List<Note> notes)
+ getFrequency() : double
+ getDuration(int tempo) : int
}
TiedNote ..|> Note
class Staff {
- instrument : Instrument
- notes : List<Note>
+ Staff(instrument : Instrument)
+ addNote(note : Note) : void
+ getInstrument() : Instrument
+ iterator() : Iterator<Note>
}
Staff ..|> Iterable
Staff --> Instrument
Staff *-- Note
enum Instrument {
- synthesizer : NoteSynthesizer
+ PIANO
+ ORGAN
+ VIOLIN
+ GUITAR
+ FLUTE
+ TAMTAM
+ MARACAS
+ BASS_DRUM
+ TIMPANI
+ SNARE
+ CYMBAL
+ TRIANGLE
+ XYLOPHONE
+ Instrument(synthesizer : NoteSynthesizer)
+ getSynthesizer() : NoteSynthesizer
}
Instrument --> NoteSynthesizer
class Fermata implements Note {
- note : Note
+ Fermata(note : Note)
+ getFrequency() : double
+ getDuration() : int
}
Fermata ..|> Note
class DottedNote implements Note {
- decoratedNote : Note
+ DottedNote(decoratedNote : Note)
+ getFrequency() : double
+ getDuration(tempo : int) : int
}
DottedNote ..|> Note
DottedNote --> Note : << decorates >>
' ------- '
' Parsing '
' ------- '
class MusicXMLSaxParser {
+ MusicXMLSaxParser(noteFactory: AbstractNoteFactory)
+ getTempo(): int
+ getParts(): Map<String,List<Note>>
+ getNotes(partId: String): List<Note>
}
MusicXMLSaxParser --> AbstractNoteFactory : << uses >>
' --------------- '
' Sound synthesis '
' --------------- '
interface NoteSynthesizer {
+ {static} SAMPLE_RATE: int
+ {abstract} synthesize(note: Note, tempo: int, volume: double): double[]
}
class SquareWaveSynthesizer implements NoteSynthesizer {
- {static} INSTANCE : SquareWaveSynthesizer
+ SquareWaveSynthesizer()
+ {static} getInstance() : SquareWaveSynthesizer
+ synthesize(note : Note, tempo : int, volume : double) : double[]
}
SquareWaveSynthesizer ..|> NoteSynthesizer
class TriangleWaveSynthesizer implements NoteSynthesizer {
- {static} INSTANCE : TriangleWaveSynthesizer
- TriangleWaveSynthesizer()
+ {static} getInstance() : TriangleWaveSynthesizer
+ synthesize(note : Note, tempo : int, volume : double) : double[]
}
TriangleWaveSynthesizer ..|> NoteSynthesizer
class SawtoothWaveSynthesizer implements NoteSynthesizer {
- {static} INSTANCE : SawtoothWaveSynthesizer
+ SawtoothWaveSynthesizer()
+ {static} getInstance() : SawtoothWaveSynthesizer
+ synthesize(note : Note, tempo : int, volume : double) : double[]
}
SawtoothWaveSynthesizer ..|> NoteSynthesizer
' ------------------ '
' Timpani Synthesizer '
' ------------------ '
class TimpaniSynthesizer implements NoteSynthesizer {
- {static} INSTANCE : TimpaniSynthesizer
- TimpaniSynthesizer()
+ {static} getInstance() : NoteSynthesizer
+ synthesize(note : Note, tempo : int, volume : double) : double[]
}
TimpaniSynthesizer ..|> NoteSynthesizer
note "Singleton Pattern" as N1
N1 .. TimpaniSynthesizer
' ------------ '
' Main classes '
' ------------ '
class LenSymphony {
- {static} noteFactory: AbstractNoteFactory
+ {static} main(args: String[]): void
}
class LenSymphonyCLI implements Callable<Integer>{
- {static} noteFactory : AbstractNoteFactory
- inputFile : File
- outputFile : File
- play : boolean
- voiceInstruments : Map<Integer, String>
+ call() : Integer
- buildInstrumentList(numberOfParts : int): List<Instrument>
- saveToFile(music : CompositeMusicSynthesizer, file : File) : void
- playMusic(music : CompositeMusicSynthesizer) : void
}
LenSymphonyCLI ..|> Callable<Integer>
LenSymphony --> AbstractNoteFactory : << uses >>
LenSymphony --> MusicXMLSaxParser : << uses >>
LenSymphony --> MusicSynthesizer : << uses >>
LenSymphony --> Score : << uses >>
LenSymphony --> Staff : << uses >>
@enduml
| Features | Design Pattern(s) (?) | Author(s) |
|---|---|---|
| Representation of a note's pitch (name + octave) | ||
| Representation of a note/silence value | ||
| -Representation of a musical note | Killian | |
| -Representation of a silence | Enzo | |
| Representation of a point on a note | Killian | |
| Representation of a tie between notes | Singleton | Léo |
| Representation of a staff | Iterator | Enzo |
| Traversal of notes/silences in a staff | Enzo | |
| Representation of a musical piece | Iterator | Killian |
| -Creation of musical elements (notes, silences) | Killian, Enzo | |
| -Generation of the "pure" sound for a note | Léo | |
| Addition of harmonics to the sound of a note | Decorator | Enzo |
| Application of an ADSR envelope to the sound of a note | Decorator | Killian |
| Application of a vibrato to the sound of a note | Decorator | Léo |
| Addition of random noise to the sound of a note | Decorator | Léo |
| Synthesis of the bass drum sound | Singleton | Killian |
| Synthesis of the snare drum sound | Singleton | Léo |
| Synthesis of the cymbal sound | Singleton | Léo |
| Synthesis of the triangle sound | Singleton | Enzo |
| Synthesis of the timpani sound | Singleton | Killian |
| Synthesis of the xylophone sound | Singleton | Enzo |
| Definition of virtual instruments | Leo | |
| Synthesis of the ensemble piece sound | Enzo | |
| Command line management | Killian |
This project has been developed by:
- Lebas Enzo
- Monsterleet Léo
- Havez Killian