Git Product home page Git Product logo

aura's Introduction

aura_banner.png

Aura is a fast and lightweight 3D audio engine for Kha to ease creating realistic sound atmospheres for your games and applications.

Table of Content

Features

  • Multiple attenuation models for 3D sound
  • Mix channels for modifying groups of sounds together
  • Doppler effect
  • Noise generator channels
  • Built-in DSP filters:
    • High-/band-/lowpass filter
    • Haas effect
    • Per-channel source effects, e.g. to generate variations using Velvet noise (original paper)
  • Extendable DSP system – easily write your own filters
  • [Experimental] Support for HRTFs (head-related transfer functions)

Setup

  1. In your project directory, create a folder called Subprojects.

  2. Open a command line in that folder and execute the following command (Git must be installed on your machine):

    git clone https://github.com/MoritzBrueckner/aura.git
  3. Add the following line to your project's khafile.js (if you're using Armory 3D, you can skip this step):

    await project.addProject("Subprojects/aura");
  4. [Optional] If you're using Iron, but not Armory 3D, please also add the following to your Khafile to be able to use Iron's vector classes with Aura:

    project.addDefine("AURA_WITH_IRON");

Usage

  • Load sounds (and automatically uncompress them when needed):

    import aura.Aura;
    
    ...
    
    Aura.init(); // <-- Don't forget this!
    
    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, if used (empty lists can be omitted)
        hrtf: ["myHRTF_mhr"],
    };
    
    Aura.loadSounds(loadConfig, () -> {
        // Access a loaded sound
        var mySound: kha.Sound = Aura.getSound("MySoundFile");
    });

    Note
    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.

  • Play a sound:

    // Plays the uncompressed sound `mySound` without repeat on the master channel
    Aura.createUncompBufferChannel(mySound).play();
    
    // Plays the uncompressed sound `mySound` with repeat on the master channel
    Aura.createUncompBufferChannel(mySound, true).play();
    
    // Plays the uncompressed sound `mySound` without repeat on the predefined fx channel
    Aura.createUncompBufferChannel(mySound, false, Aura.mixChannels["fx"]).play();

    You can also play audio from compressed sounds without having to uncompress them first (Kha calls this "streaming"). This is useful for longer sounds such as background music, they need less memory and load faster if they do not need to be uncompressed, but on the other side this is more computationally demanding than playing uncompressed sounds. Whether a sound can be streamed highly depends on the target, please consult the Kha sources if in doubt.

    Aura.createCompBufferChannel(mySound, false, Aura.mixChannels["music"]).play();

    Both Aura.createUncompBufferChannel() and Aura.createCompBufferChannel() return so-called handle objects with which you can control channel playback and relevant parameters.

  • Create a MixChannelHandle to control a group of sounds:

    // Create a channel for all voices for example and store a handle to it in `voiceChannel`.
    // The channel can also be accessed with `Aura.mixChannels["voice"]`
    var voiceChannel = Aura.createMixChannel("voice");
    
    // Mix the output of `voiceChannel` into the master channel
    voiceChannel.setMixChannel(Aura.masterChannel);
    
    // Create a new channel handle for `mySound` and mix the output of that channel into the voice mix channel
    Aura.createUncompBufferChannel(mySound, false, voiceChannel).play();
  • Add a lowpass filter to the master channel:

    import aura.dsp.Filter;
    
    ...
    
    Aura.createUncompBufferChannel(mySound).play();
    
    var lowPass = new Filter(LowPass);
    lowPass.setCutoffFreq(1000); // Frequency in Hertz
    
    // Aura.masterChannel is short for Aura.mixChannels["master"]
    Aura.masterChannel.addInsert(lowPass);
    
  • 2D sound:

    import aura.dsp.panner.StereoPanner;
    
    ...
    
    var mySoundHandle = Aura.createUncompBufferChannel(mySound);
    var panner = StereoPanner(mySoundHandle);
    
    // Some utility constants
    panner.setBalance(LEFT);
    panner.setBalance(CENTER); // Default
    panner.setBalance(RIGHT);
    
    // Set angle in degrees between -90 (left) and 90 (right)
    // You can also use Rad(value) for radians in [-pi/2, pi/2]
    panner.setBalance(Deg(30));
  • 3D sound:

    import aura.dsp.panner.HRTFPanner;
    import aura.dsp.panner.StereoPanner;
    
    ...
    
    var mySoundHandle = Aura.createUncompBufferChannel(mySound);
    
    // Create a panner for the sound handle (choose one)
    new StereoPanner(channel); // Simple left-right panner
    new HRTFPanner(channel, Aura.getHRTF("myHRTF_mhr"));  // More realistic panning using head-related transfer functions, but slower to calculate
    
    // Set the 3D location and view direction of the listener
    var cam = getCurrentCamera(); // <-- dummy function
    Aura.listener.set(cam.worldPosition, cam.look, cam.right);
    
    // Set the 3D location of the sound independent of the math API used
    mySoundHandle.panner.setLocation(new kha.math.FastVector3(-1.0, 1.0, 0.2));
    mySoundHandle.panner.setLocation(new iron.math.Vec3(-1.0, 1.0, 0.2));
    mySoundHandle.panner.setLocation(new aura.math.Vec3(-1.0, 1.0, 0.2));
    
    // Apply the changes to the sound to make them audible (!)
    mySoundHandle.panner.update3D();
    
    // Switch back to 2D sound. The sound's saved location will not be reset, but
    // you won't hear it at that location anymore. The panner however still exists
    // and can be re-enabled via update3D().
    mySoundHandle.panner.reset3D();

    Aura's own Vec3 type can be implicitly converted from and to Kha or Iron vectors (3D and 4D)!

Platform Support

Thanks to Haxe and Kha, Aura runs almost everywhere!

The following targets were tested so far:

Target Tested environments Supported Notes
Armorcore (Krom) Windows 10
HTML5 Electron, Firefox - No dedicated audio thread for non-streaming playback
- If kha.SystemImpl.mobileAudioPlaying is true, streamed playback is not included in the Aura mix pipeline (no DSP etc.)
Hashlink/C Windows 10
hxcpp Windows 10

License

This work is licensed under multiple licences, which are specified at .reuse/dep5 (complying to the REUSE recommendations). The license texts can be found in the LICENSES directory, or in case of submodules in their respective repositories.

Short summary:

  • The entire source code in Sources/aura is licensed under the Zlib license which is a very permissive license also used by Kha and Armory at the time of writing this. This is the important license for you if you include Aura code in your project.
  • This readme file and other configuration files are licensed under CC0-1.0.
  • All files in .img/ are licensed under CC-BY-4.0.

aura's People

Contributors

moritzbrueckner avatar tong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aura's Issues

Questions for usage

Hello, sorry for asking

what would be the easiest way to get this to work with armory engine? I mean with loading the compressed or uncompressed file, do i put my audio file somewhere? For instance test.wav, would that be uncompressed: ["test"] ?

Mix channels not working when added to Aura.masterChannel.

When I try to play an audio, it only plays when is assigned to the 'master' channel or without any channel assigned, some examples:

Aura.createUncompBufferChannel(music, true).play() -> works
Aura.createUncompBufferChannel(music, true, Aura.mixChannels["master"]).play() -> works
Aura.createUncompBufferChannel(music, true, Aura.mixChannels["music"]).play() -> doesn't work
Aura.createUncompBufferChannel(music, true, Aura.mixChannels["fx"]).play() -> doesn't work

or

var customMixChannel = Aura.createMixChannel("custom");
customMixChannel.setMixChannel(Aura.masterChannel);
Aura.createUncompBufferChannel(music, true, customMixChannel).play(); -> doesn't work

There are no errors in the console and I also traced Aura.mixChannels, which returned me a dictionary with all the channels: "master", "music", "fx" and "custom".

Using Aura in Armory 2024.02.

Channels finished notifier

I have seen MixChannel.hx has a finished property to check if a track is finished but I'd like to delete an channel as soon as it's finished playing, something like play(destroyOnFinished: bool = true) or soundChannel.onFinished(?callback:Void), instead of checking soundChannel.finished each frame. Is it possible to do this with the current version of Aura or does it need to be implemented?

For context, I'm trying to implement randomized 'steps foley' sounds and uncommented the bit of code in line 113 if (inputChannels[i] == null || inputChannels[i].finished) from MixChannel.hx for a temporary solution.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.