MIDI and SFX sequencer, designed for compatibility with MusyX audio groups
Go to file
Jack Andersen 3433a70462 Initial SongState, timing is hilariously wrong ATM 2016-05-18 16:19:43 -10:00
driver Initial SongState, timing is hilariously wrong ATM 2016-05-18 16:19:43 -10:00
include/amuse Initial SongState, timing is hilariously wrong ATM 2016-05-18 16:19:43 -10:00
lib Initial SongState, timing is hilariously wrong ATM 2016-05-18 16:19:43 -10:00
CMakeLists.txt Initial SongState, timing is hilariously wrong ATM 2016-05-18 16:19:43 -10:00
LICENSE Add LICENSE 2016-05-02 11:54:23 -10:00
README.md Work on Sequencer 2016-05-15 11:56:23 -10:00

README.md

Amuse

Amuse is a real-time MIDI and SFX sequencer, with basic effects, 3D positional audio and surround-output capabilities.

The project is designed for compatibility with Audio Groups and Song data found in PC/N64/GCN/GBA games using the MusyX audio engine; providing an alternate runtime library to use for sequencing these games' audio libraries.

Library

The Amuse API exposes full interactivity between a client application (game engine) and the sequencer engine. Unlike the interrupt-driven nature of the original console implementations (where the audio chip 'requests' more audio as needed), Amuse is entirely synchronous. This means the client must periodically pump the audio engine (typically once per video frame) to keep the OS' audio system fed.

The client must provide the implementation for allocating and mixing audio voices, since this may drastically differ from target to target. amuse::IBackendVoiceAllocator is the pure-virtual interface to implement for this. Alternatively, if Boo is present in the CMake project tree, Amuse will be compiled with a backend supporting multiple popular low-level audio APIs. Windows, OS X, and Linux all have excellent support this way.

Here's an example usage:

#include <amuse/amuse.hpp>
#include "MyVoiceAllocator.hpp"
#include "MyAudioGroupLoader.hpp"

int main(int argc, char* argv[])
{
    /* Up to the client to implement voice allocation and mixing */
    std::unique_ptr<amuse::IBackendVoiceAllocator> voxAlloc = MakeMyVoiceAllocator();

    /* Application just needs one per audio output (not per channel) */
    amuse::Engine snd(*voxAlloc);

    /* An 'AudioGroup' is an atomically-loadable unit within Amuse. 
     * A client-assigned integer serves as the handle to the group once loaded
     */
    amuse::IntrusiveAudioGroupData data = LoadMyAudioGroup();
    snd.addAudioGroup(data);

    /* Starting a SoundMacro playing is accomplished like so: */
    int sfxId = 0x1337;
    float vol = 1.0f;
    float pan = 0.0f;
    std::shared_ptr<Voice> voice = snd.fxStart(sfxId, vol, pan);

    /* Play for ~5 sec */
    int passedFrames = 0;
    while (passedFrames < 300)
    {
        snd.pumpEngine();
        ++passedFrames;
        WaitForVSync();
    }

    /* Stopping a SoundMacro is accomplished by sending a
     * MIDI-style 'KeyOff' message for the voice
     */
    voice->keyOff();
    
    /* Play for 2 more seconds to allow the macro to gracefully fade-out */
    passedFrames = 0;
    while (passedFrames < 120)
    {
        snd.pumpEngine();
        ++passedFrames;
        WaitForVSync();
    }

    /* Clean up and exit */
    return 0;
}

Tool

In addition to the library, a command-line tool for performing various pipeline tasks is provided. Compilers for audio groups and song data, as well as basic playback functionality is available via the tool.