SCORCHED END AUDIO LIBRARY (SEAL)

RPG Maker VX Ace

3D audio rendering library

  • zhangsu
  • 01/26/2013 03:09 AM
  • 3639 views
Scorched End Audio Library

This is an open source project I have been working on for a while and will continue to maintain. I'm also looking for teammates to collaboratively improve this project; check out the "Contribution" section if you are interested.

Scorched End Audio Library (Seal) is a 3D audio rendering library based on top of OpenAL, the audio counterpart of OpenGL. It adds support for decoding Ogg Vorbis, MPEG Audio Layer 1, 2, and 3, and simple uncompressed WAVE formats. It also has an abstraction for streaming audio (through the Stream class), which hides a lot of details programmers have to worry about when trying to stream audio using OpenAL. Finally, it aims to provide helper methods in the future based on user needs. Seal is written in C but also has a Ruby binding. In RGSS, the bridge is the Win32API class, so this library can be used in all versions of RPG Maker.


Comparison with the Default Audio Module

The default Audio module in RGSS supports simple audio playback and the ability to adjust the volume and pitch, and that's it. Seal, through OpenAL, supports simulations of the following special audio effects:


Attenuation

The farther a sound-emitting object is from an observer, the softer the sound observer hears. Conversely, the closer the object is from the observer, the louder the sound observer hears. In RPGs, this can occur, for example, when an NPC moves away from the player and the sound of the NPC's footsteps attenuate.


Doppler Effect

When an ambulance moves toward the observer, the observer hears higher-frequency sound than he does when the ambulance moves away from him.


Spatialization

The ability of an observer to identify where the sound source is relative to him. Attenuation helps identifying the position by giving the observer an estimate of the distance between the sound source and the observer, but it does not gives the direction. OpenAL makes use of the different audio channels and output devices users have to give the user a sense of sound positioning. Depending on how advanced the configuration is, the positioning can be 1D (with only left and right channel), 2D (left, right, front and back speakers), or even 3D (everything a 2D configuration has plus a speaker on the top).


Reverberation

Reverberation happens when reflections of sound waves merge with the original waves moving in reverse directions. In certain environments, the reflections can be again reflected back, creating a complex mix of sound waves. The same object emits different sound in different environments: in a pipe, a house, a forest, a space station, etc.


And other stuff...

Like adjusting volume and pitch during a playback, pausing a playback and replay, getting audio attributes. A lot of stuff is still unimplemented; check out the "TODO's" section.


Programming Model

An audio data file gets loaded by a Buffer or a Stream object -- use buffers for small audio and streams for massive audio. The instances of Buffer or Stream will be associated with a Source object, which represent the sound source. By calling various methods of Source, the original raw audio can be manipulated, processed and filtered.There can be many instances of sources since there could be many objects in games that emit sound, but there is only one observer, which is the singleton instance of Listener. Both sources and the listener have their respective positions and velocities, and updating these values in real-time will automatically apply sound spatialization and attenuation. All the math are handled by the underlying audio engine OpenAL.

The model of Seal can be compared with the graphics programming model of RGSS:

Sources are like Sprite objects in RGSS, except that sprites represent graphics and sources represent audio. Different instances of sprites integrate into a scene, and different instances of sources integrate to the mixer output. Both Source and Sprite are used to dynamically process and render the original associated image and sound data.

Buffer is similar to Bitmap; the former is a container for audio data and the latter is a container for graphics data. Buffers are suitable for loading small audio files that serve as sound effects like the BGS, ME and SE of RPG Maker.

Stream also represents raw audio data, but it is performance-wise different from Buffer. Buffer loads audio data into main memory at once where as Stream loads one chunk at a time and send them to the audio device. Audio data are usually large, much larger than images. A 5-min MP3 will occupy ~50MB of space after decompression, so loading these kind of audio into memory as a whole is a big overhead and reduce memory efficiency. Stream only loads the small chunk that is needed to play at the moment, and free or reuse the previous chunk of memory. This way the occur rate of problems like cache miss, page faults, thrashing can be significant reduced. Streams are usually used for background music, like the BGMs in RPG Maker.

Reverberation is one of the extensions of OpenAL. Seal controls reverberation by using two kinds of objects: EffectSlot and Reverb. Instances of Reverb has various attributes to set for simulating a particular kind of reverberation environment, then they can be loaded into an instance of EffectSlot. The source can "feed" the slot by its audio data, and the sound the source emits will be filtered by the reverberation effect loaded on that slot. EffectSlot can be seen as a filter on the sound rendering pipeline which is in charge of applying reverberation to incoming audio.

Currently the only implemented effect objects is Reverb objects, therefore there can only be Reverb objects loaded onto effect slots. In the future instances of EffectSlot will be able to load different effect objects.


Simple Examples

Check out the "Basic Use" section at http://zhang.su/seal/


Detailed Documentations

Can be found at two places:

http://zhang.su/seal/
http://rubydoc.info/gems/seal

The first one only shows the latest version, the second one has copies of previous versions.

Some command-line demos can be found at:
https://github.com/zhangsu/seal/tree/master/demo


Something to Remember

  • Not all WAVE sub-formats are supported. Simple uncompressed PCM WAVE format is supported for testing purposes, but I strongly recommend you guys to use Ogg Vorbis -- it's an open standard and patent-free format (unlike MP3).
  • When source objects are garbage-collected, the playback associated with the source will also stop. It is the programmer's responsibility to manage the life cycle of source objects.
  • A weird bug that occurs in RPG Maker VX Ace: Seal.startup throws an exception occasionally and I have no idea why. The probability is pretty low though, so a workaround is to use something like the following. Let me know if you have any input to this.
    begin
      Seal.startup
    rescue Seal::SealError
      retry
    end
    



Download

http://dl.dropbox.com/u/69399398/seal.zip

This latest version of Seal is 0.1.2.

This archive has three files:

OpenAL32.dll -- the 32-bit library file of OpenAL compiled by MSVC 2010
seal.dll -- the 32-bit library file of Seal copmiled by MSVC 2010
seal.rb -- the Win32API binding of Seal

The way to use Seal in RGSS is to copy the DLL's to the root directory of the game and copy the content of seal.rb into the script editor. If you need to change the location of the DLLs, you can change the constant under the `SealAPI` class:

LIB_DIR = 'relative_path_to_your_dll_directory'



Seal is also distributed as a Ruby gem named as 'seal'.

TODOs

  • Max and min attenuation distance
  • rolloff factor
  • reference distance
  • Max and min volume
  • direction vector and orientation cone
  • current playback position
  • configurable OpenAL distance model
  • Speed of sound
  • Doppler factor
  • Device enumeration
  • Audio recording
  • filters effect
  • ring modulator effect
  • echo effect
  • prelude
  • Object duplication (Object#clone, Object#dup)


Contribution

Pull requests are welcomed, even if it's just a typo fix; please send pull requests to https://github.com/zhangsu/seal. The GitHub pull request workflow can be found here.

Posts

Pages: 1
The files do not extract from the zip properly.

! C:\Users\Ryan\Documents\seal.zip: Unknown method in OpenAL32.dll
! C:\Users\Ryan\Documents\seal.zip: Unknown method in seal.dll
! C:\Users\Ryan\Documents\seal.zip: Unknown method in seal.rb
! C:\Users\Ryan\Documents\seal.zip: No files to extract
Pages: 1