Concepts

Mélodium language is organized between 5 main concepts: sequences, treatments, models, connections, and tracks.

Sequences & Treatments

Sequences are the main element of the language, they can take parameters. Unlike functions, which list instructions to execute and apply changes on variables, sequences describes treatments and flows. A sequence can be seen as a map, on which paths connects from sources to destinations, browsing through different locations with different purposes. Order of declaration has no importance, treatments will run when there are data ready to be processed, and all treatments can be considered as running simultaneously.

Within sequences are treatments, which are basically other sequences that will take parameters, inputs, and provide outputs to the hosting sequence. Treatments are declared once within a sequence, and then can be connected as many times as needed.

sequence MySequence(var foo: u64, var bar: f64)
{
    TreatmentA(alpha=foo)
    TreatmentB(beta=bar, gamma=0.01)

    TreatmentA.output --> TreatmentB.input
}

Models

Models are elements that live through the whole execution of a program. Can be declared and configured, and then instancied in a sequence declaration.

use std/audio/host::AudioOutput

model HostAudioOutput() : AudioOutput
{
    early_end = false
}

Reference for AudioOutput

Models are instancied by sequences in their prelude.

sequence PlayAudio(const early_end: bool)
  model audioOut: AudioOutput(early_end=early_end)
  input signal: Stream<f32>
{
    SendAudio[output=audioOut]()

    Self.signal -> SendAudio.signal
}

Reference for SendAudio

In most cases, models are instancied internally by sequences and not exposed, user developer can make direct call on model-dependent sequences without instancing its own, just giving required parameters to the sequence. The cases where user may give its own defined model is to configure elements such as external software connections or interfaces.

Connections

Connections are basically paths data will follow. Connection can connect treatments outputs to inputs, but also refers to the inputs and outputs of the hosting sequence itself. A connection always links an output and an input of the same type.

sequence Demonstration()
  input  floating_point_value: Stream<f32>
  output positive_increased_value: Stream<u64>
  output integer_value: Stream<i64>
{
    ToU64()
    ToI64()
    StaticAddU16(value=1)

    Self.floating_point_value -> ToU64.value,value -> StaticAdd.value,value -> Self.positive_increased_value
    Self.floating_point_value -> ToI64.value,value --------------------------> Self.integer_value
}

Reference for ToU64, ToI64, StaticAdd

Multiple connections from the same element are totally legal, however overloading a treatment input or a sequence output is forbidden. Also, while omitting usage of a treatment output is legal, every input must be satisfied. Finally, all outputs of a sequence must be satisfied.

Inputs and outputs (and so connections) are either streaming or blocking. A streaming connection Stream<…> is expected to send continuously values from the specified type. A blocking connection Block<…> is expected to send all-at-once. This distinction mainly rely on the core treatments that are used and the intrinsic logic applied on data. What developer should keep in mind is that streaming is the default unless blocking is required.

A specific kind of connection using the data type void exists. It is useful for transmitting information that something happens or should be triggered, schedule events, Block<void>; or to indicate continuation of something that doesn't convey data by itself, Stream<void>.

Tracks

Tracks are at the same time the more implicit and the more important thing in Mélodium. When developer instanciate models and connects treatments altogether, it creates a potential track. The track is the whole ensemble of treatments and flows between them, that are created together, live together, and disappear together.

A track always takes its origin from a model, who request its initialization when needed and as many times as needed, for each file found, each incoming connection, or whatever the model purpose proposes. Each of them will follow the same defined chain of treatments, but on their own. This is one of the core element providing Mélodium its strong scalability.