Skip to content
Moritz Brückner edited this page Apr 2, 2024 · 1 revision

This page contains a more detailed guide on how to use Aura compared to the readme.

Initialize Aura

Before you can use Aura, you must initialize it. Don't forget this step!

EXAMPLE

import aura.Aura;

// ...

Aura.init();

Unless stated otherwise, all examples below only require import aura.Aura imports.

Loading Assets

Before you can play sounds or use HRTFs, you need to load them into memory. To do this, you create an AuraLoadConfig, a set of Kha assets to load.

There are three kinds of assets:

  • uncompressed: Sounds that are uncompressed in memory. These sounds will be uncompressed after loading. This is useful for short sounds that do not require much memory such as sound effects.
  • compressed: Sounds that remain compressed in memory. These sounds will not be uncompressed after loading. This is useful for long sounds that do require a lot of memory such as background music, however, playback of those sounds is a bit more computationally demanding as the sounds are temporarily uncompressed on-the-fly when they are played.
  • hrtf: .mhr files for head-related transfer functions. Please refer to the wiki page on HRTFs.

Within the AuraLoadConfig, you can list the assets by adding their asset names to arrays belonging to the three asset types explained below.

Important

Be aware that Khamake (the build tool used by Kha) may rename some assets:

  • If an asset contains some special characters such as - (which is changed to _; my-sound becomes my_sound for example). Unfortunately, the rules of renaming asset names with special characters are not officially specified (if you don't count the Khamake source code as specification) and might be subject to change at any point in time.
  • If multiple assets at different paths are using the same name.
  • For non-sound assets (blobs) such as .mhr files for HRTFs, Khamake will include the file extension at the end of the asset name, separated by an underscore. For example, a file named myHRTF.mhr becomes myHRTF_mhr.

Thus, if Aura notifies you that an asset could not be loaded, check whether Khamake has renamed the asset. If in doubt about the renaming rules, consult the source code of Khamake.

EXAMPLE

var loadConfig: AuraLoadConfig = {
    // List of sounds to uncompress
    uncompressed: ["MySoundFile"],

    // List of sounds to remain compressed
    compressed: ["AnotherSoundFile"],

    // List of .mhr HRTF files for the HRTFPanner
    hrtf: ["myHRTF_mhr"],
};

Empty asset lists within an AuraLoadConfig can be omitted, so if you do not use HRTFs for example, you do not need to write hrtf: [].

Tip

Instead of referencing sounds by hard-coded names (like it is done in the above example), you can also rely on Kha's asset system and use the IDE's autocompletion for assistance:

kha.Assets.sounds.MySoundFileName; // Note the "Name" ending. This will give you the ID name for this sound
kha.Assets.blobs.myHRTF_mhrName;   // The same works for blobs and all other asset types

As a positive side effect, there will be errors during compile time if an asset does not exist.

To load the assets you specified in an AuraLoadConfig, use Aura.loadAssets():

EXAMPLE

// loadConfig is the AuraLoadConfig from the example above
Aura.loadAssets(loadConfig, () -> {
    // Access a loaded sound
    var mySound: kha.Sound = Aura.getSound("MySoundFile");
}, () -> {
    trace("There was an error while loading the assets");
});

Aura.loadAssets() has two required and one optional parameter:

  1. The AuraLoadConfig.
  2. A callback function that is called when all assets of the given AuraLoadConfig are loaded. Here you can access the assets.
  3. [Optional] A callback function that is called when there was an error loading an asset.

Note that the code within the callbacks might run asynchronously at a later point in time than the call to Aura.loadAssets(). This means that any code run after Aura.loadAssets() might be run before all assets are loaded: EXAMPLE

// loadConfig is the AuraLoadConfig from the examples above
Aura.loadAssets(loadConfig, () -> {
    // Here you can safely access all assets from the given AuraLoadConfig
});

// But here, the assets might not be loaded yet!

Playing Sounds

In Aura, each sound gets assigned a so-called channel, which specifies attributes of the sound such as its volume, effects, and so on. Before playing a sound for the first time, you need to explicitly create a channel for it. Depending on whether the sound remains compressed in memory after loading or is uncompressed (see Loading Assets above), you need to select the type of channel that is used for the sound by calling either Aura.createUncompBufferChannel() or Aura.createCompBufferChannel() which return a handle to a channel or null if creating the channel failed:

EXAMPLE

var mySound: kha.Sound = Aura.getSound("MySoundFile");

// Create a channel for the uncompressed sound `mySound` without repeat
var channelUncomp: Null<UncompBufferChannelHandle> = Aura.createUncompBufferChannel(mySound);

// Create a channel for the uncompressed sound `mySound` with repeat
channelUncomp = Aura.createUncompBufferChannel(mySound, true);

// Create a channel for the uncompressed sound `mySound` without repeat on the predefined "fx" channel (see explanation below)
channelUncomp = Aura.createUncompBufferChannel(mySound, false, Aura.mixChannels["fx"]);

// Create a channel for the compressed sound `mySound` with repeat on the predefined "music" channel (see explanation below)
var channelComp: Null<BaseChannelHandle> = Aura.createCompBufferChannel(mySound, true, Aura.mixChannels["music"]);

Note

While it would be nice to handle the complexity of choosing the correct channel type internally and just use a general-purpose channel handle on the user facing side of Aura, different handle types provide slightly different sets of features in the Aura API and thus require different types to satisfy compile-time type safety.

To control playback of a channel (called myChannel below), you can use the following functions:

  • myChannel.play(retrigger): Play the sound. If the retrigger parameter is true (default: false), restart the playback from the start if the sound is already playing.
  • myChannel.pause(): Pause the playback. The next call to play() will resume playback at the paused playback position.
  • myChannel.stop(): Stop the playback. The next call to play() will start from the beginning of the sound.

This page is work in progress, more coming soon.

Clone this wiki locally