REF / Music API / Choose Your Weapon

Ascene . Agraph . Aengine
Anode . Modulator . Envelope
Songbook . Song . TimeKeeper
Voices . SampleMgr . StreamMgr
Loader . Async . Plot
Random . Rhythm . Util
MIDI . OSC . HID . Piano
Music Theory with Tonal

right-click to navigate to page sections


The language choice, tl;dr:

Use JavaScript unless Lua is your preference or you require headless (no GUI) operation.

Since Hz supports two programming language options, let's quickly touch upon the similarities and differences between the JavaScript and Lua API bindings. With that behind us we'll document the API in JavaScript and expect that the mapping to its Lua equivalent is straightforward.

The primary difference between the language bindings pertain to notations for expressing asynchronous behavior. Asynchronous programming is central to Hz's music programming model and is covered in more detail here. In short, Lua's coroutine support can often be hidden behind the scenes while JavaScript's generators and async functions are necessarily more explicit.

Feature JavaScript Lua
Execution Model interpretted interpretted
Learning Curve Gentle Gentle
Usage widespread slightly obscure
Peformance highly optimized lightweight+fast
GUI Integration built-in indirect via JavaScript
"Headless" Operation no (requires WebView/WebKit) yes
Class Function Notation ClassName.func(…) ClassName.func(…)
Object Method Notation object.method(…) object:method(…)
Coroutine/Fiber separate async and generator coroutine
Multiple Sandboxes yes no (not implemented)

Other differences are implicit in these examples. Code comments highlight the usage differences driven by the hosting language.

// JavaScript example
let scene = await Ascene.BeginFiber(this); // <-- use javascript await keyword
console.notice("Audio scene is initialized.");
let inst = scene.NewAnode("Vital");
let dac = scene.GetDAC();
scene.Chain(inst, dac); // setup our trivial audio graph
await scene.Sync();
let noteDur = scene.Seconds(.1);
for(let key=40;key<60;k++)
{
    console.notice(`key: ${key}`);
    inst.NoteOn(key, .8);
    await scene.Wait(noteDur); // async ("blocking") await
    inst.NoteOff(key, 0);
    yield; // javascript yield keyword to 
}
-- Lua example
local Ascene = require("ascene")
Ascene:init(function(scene) -- <-- scene instance delivered to callback
    Log.notice("Audio scene is initialized.")
    local inst = scene:newAnode("Vital")
    local dac = scene:getDAC()
    scene:chain(inst, dac) -- setup our trivial audio graph
    scene:begin() -- begin yields behind the scenes.
    local noteDur = scene:seconds(.1)
    for key=40,60 do
        Log.notice("key: "..key)
        inst:noteOn(key, .8)
        scene:wait(noteDur) -- wait yields behind the scenes.
        inst:noteOff(key, 0)
    end
end)
home .. topics .. interface .. reference .. examples .. tipjar