Aoide: A simple music library that can generate Lilypond and MIDI files.

[ bsd3, composition, library, lilypond, midi, music, program ] [ Propose Tags ] [ Report a vulnerability ]

This library provides data structures and a custom file format for describing music and generates Lilypond and MIDI files. In addition it contains a module with some music-theoretical functions and generates keyboard reductions. The library is focused on the very basics of Western musical notation and does not support dynamic indications, articulation marks, double accidentals, tempo changes, polyrhythms, time signature changes and microtonality.


[Skip to Readme]

Modules

[Last Documentation]

  • Composition
    • Composition.Errors
    • Composition.Keyboard
    • Composition.Lilypond
    • Composition.MIDI
    • Composition.Notation
    • Composition.Notes
    • Composition.Parser
    • Composition.Score
    • Composition.Theory
    • Composition.Write

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.1.0.0, 0.1.0.1, 0.1.0.2, 1.0.0.0, 2.0.0.0
Dependencies barbies, base (<4.22), bytestring, containers, directory, filepath, generic-lens, Kawaii-Parser, lens, mtl, process, transformers [details]
License BSD-3-Clause
Author Liisi Kerik
Maintainer liisikerik@hotmail.com
Uploaded by Liisi_Kerik at 2026-05-20T18:27:39Z
Category Composition, Lilypond, MIDI, Music
Source repo head: git clone https://github.com/liisikerik/aoide.git
Distributions
Executables Aoide
Downloads 907 total (12 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs not available [build log]
All reported builds failed as of 2026-05-20 [all 2 reports]

Readme for Aoide-2.0.0.0

[back to package description]

Aoide

Score file

Score files have to have a .aoi extension.

The best way to learn the syntax is to have a look at the example scores in Scores directory.

Score files aren't indentation-sensitive. Structure field order is fixed - for example, when you create a score the header comes first and the parts come second.

SCORE

Score {
  header = (HEADER)
  parts = [
    (PART)
    (PART)
    (PART)
    ...]}
[(HEADER_FIELD) (HEADER_FIELD) (HEADER_FIELD) ...]

You do not need to use all the possible header fields - use only the ones that you need. Header field order is flexible.

HEADER_FIELD

(HEADER_FIELD_NAME) = ""

HEADER_FIELD_NAME

  • Left_text
  • Overtitle
  • Right_text
  • Subtitle
  • Subsubtitle
  • Title

PART

Part {
  title = ""
  key = (KEY)
  time = (TIME)
  initial_position = (INITIAL_POSITION)
  tempo = 100
  stave_groups = [
    (STAVE_GROUP)
    (STAVE_GROUP)
    (STAVE_GROUP)
    ...]}

KEY

[(NOTE_NAME) (NOTE_NAME) (NOTE_NAME) ...]

You only need to specify the note names that have accidentals.

NOTE_NAME

  • C
  • C#
  • Db
  • ...

TIME

  • Time [2] 2 - 2/2
  • Time [2 2] 4 - 4/4
  • Time [2 2 2] 8 - 8/8
  • Time [2 2 3] 16 - 12/16
  • Time [2 3] 8 - 6/8
  • Time [3] 4 - 3/4
  • Time [3 3] 16 - 9/16
  • ...

INITIAL_POSITION

The timing of the first event relative to the start of the measure. If the piece starts with a full bar, the initial position is 0. If the piece is in 3/4 and starts with a 1/4 pickup bar, the initial position can be written as 1/2 or 2/4.

STAVE_GROUP

[
  (INSTRUMENT_AND_STAVES)
  (INSTRUMENT_AND_STAVES)
  (INSTRUMENT_AND_STAVES)
  ...]

INSTRUMENT_AND_STAVES

(PITCHED_OR_UNPITCHED) Instrument_and_staves {
  instrument_name = ""
  short_instrument_name = ""
  midi_instrument = 0
  velocity = 127
  staves = [
    (STAVE)
    (STAVE)
    (STAVE)
    ...]}

PITCHED_OR_UNPITCHED

  • Pitched
  • Unpitched

STAVE

Stave {
  clef = (CLEF)
  tracks = (TRACKS)}

CLEF

Percussion_clef
Pitched_clef {clef_name = (CLEF_NAME) transposition = 0}

CLEF_NAME

  • Subbass
  • Bass
  • Baritone_F
  • Baritone_C
  • Tenor
  • Alto
  • Mezzosoprano
  • Soprano
  • Treble
  • French

TRACKS

[
  EVENTS]
[
  EVENTS
  EVENTS]

One stave can contain one or two tracks.

EVENTS

[(EVENT) (EVENT) (EVENT) ...]

EVENT

(NOTES)(LENGTH)
(EVENTS)

An event can be notes with a length or a triplet.

NOTES

[(NOTE) (NOTE) (NOTE) ...]
+

Notes can be either a set of new notes or a tie.

NOTE

(NOTE_NAME)(OCTAVE)

LENGTH

(BASIC_LENGTH)(DOTS)

BASIC_LENGTH

  • 1 - Whole
  • 2 - Half
  • 4 - Quarter
  • ...

DOTS

  • .
  • ..
  • ...

Playables file

Playables file is needed if you want to generate keyboard reductions. A default playables file Keyboard.key is provided and you can modify it according to your own preferred style of music (you might need to account for a greater variety of dissonant chords) and your own hand hand span.

PLAYABLES

(PLAYABLE)
(PLAYABLE)
(PLAYABLE)
...

PLAYABLE

[(STEPS) (STEPS) (STEPS) ...] [(KEY) (KEY) (KEY) ...]

Each

Commands

The whole command should be wrapped in quotation marks and given as one string argument to the program. Command argument order is fixed.

File paths should be given with no quotation marks.

Lilypond

Lilypond {source = (FILE_PATH) destination = (FILE_PATH)}

MIDI

MIDI {source = (FILE_PATH) destination = (FILE_PATH)}

Keyboard reduction

Keyboard {playables = (FILE_PATH) source = (FILE_PATH) header = (HEADER) midi_instrument = 0 destination = (FILE_PATH)}