Skip to content

Enzo-2206/LenSymphony

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

256 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LenSymphony - A simple music synthesizer library developed in Lens

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.

Overview

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


Feature list

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

Team

This project has been developed by:

  • Lebas Enzo
  • Monsterleet Léo
  • Havez Killian

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages