Skip to content

Commit

Permalink
document audio buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
ianmaclarty committed Jan 23, 2016
1 parent 86e3949 commit 17e1e06
Show file tree
Hide file tree
Showing 5 changed files with 339 additions and 29 deletions.
125 changes: 121 additions & 4 deletions doc/audio.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,78 @@

# Audio

## Audio buffers {#audio-buffers}

An audio buffer is a block of memory that stores an uncompressed
audio sample.

An audio buffer may have any number of channels, although Amulet
will currently only play up to two channels.

An audio buffer also has a sample rate. Amulet currently plays all
audio at a sample rate 44.1kHz and will resample an audio buffer
if it has a different sample rate.

The audio data itself is stored in a [buffer](#buffers-and-views)
as a series of single precision floats (4 bytes each). The samples for
each channel are contiguous. The first channel's data comes first, then
the second channel's data, etc (the channels are not interleaved).
If the sample data is stored in the buffer `buf`, and there are two channels,
then the following code will create [views](#buffers-and-views) that can
be used to update or read the samples for each channel:

~~~ {.lua}
local c = 2 -- channels
local s = #buf / 4 / c -- samples per channel
local left_channel = buf:view("float", 0, 4, s)
local right_channel = buf:view("float", s * 4, 4, s)
~~~

### am.audio_buffer(buffer, channels, sample_rate) {#am.audio_buffer .func-def}

Returns a new audio buffer using the given raw buffer (a buffer
created with [`am.buffer`](#am.buffer)). The audio data should
be layed out as described [above](#audio-buffers).

`channels` is the number of channels and `sample_rate` is the sample rate
in Hz.

### am.load_buffer(filename) {#am.load_buffer .func-def}

Loads the given audio file and returns a new audio buffer.
The file must be a `.ogg` audio file.

## Audio buffer fields

### audio_buffer.channels {#audio_buffer.channels .field-def}

The number of channels. Readonly.

### audio_buffer.sample_rate {#audio_buffer.sample_rate .field-def}

The sample rate in Hz. Readonly.

### audio_buffer.samples_per_channel {#audio_buffer.samples_per_channel .field-def}

The number of samples per channel. Readonly.

### audio_buffer.length {#audio_buffer.length .field-def}

The length of the audio in seconds. Readonly.

### audio_buffer.buffer {#audio_buffer.buffer .field-def}

The underlying raw [buffer](#buffers-and-views) where the audio data is stored. Readonly.

## Playing audio

### am.play(source, loop, pitch, gain)

Returns an action that plays audio.
Like any other action it needs to be attached to a scene
Like any other [action](#node:action) it needs to be attached to a scene
node that's connected to a window to run.

`source` can either be the name of a ".ogg" file
`source` can either be an [audio buffer](#audio-buffers), the name of a ".ogg" file
or a seed generated by the sfxr tool (there's an online
version of that tool in the examples list of the [online editor](http://www.amulet.xyz/editor.html)).

Expand All @@ -21,14 +84,68 @@ swice as fast and 0.5 means play at half the original speed.

`gain` should be between 0 and 1.

**Note**:
When the source is an sfxr seed or a filename, an [audio buffer](#audio-buffers)
is generated behind the scenes and cached. Therefore there might be a short delay the
first time this function is called with a given seed or filename (though for short
audio clips this will probably not be noticable). Also avoid calling
this function many times with different seeds or filenames, because that will cause
unbounded memory growth.

## Generating sound effects

### am.sfxr_synth(settings) {#am.sfxr_synth .func-def}

Returns an audio buffer containing a generated sound effect.

`settings` can either be a table containing any number of the
following fields:

Field Default value Notes
----------------- ---------------- -------------------------------------------------
`wave_type ` `"square"` Can also be `"sawtooth"`, `"sine"` or `"noise"`
`base_freq ` `0.3`
`freq_limit ` `0.0`
`freq_ramp ` `0.0`
`freq_dramp ` `0.0`
`duty ` `0.0`
`duty_ramp ` `0.0`
`vib_strength ` `0.0`
`vib_speed ` `0.0`
`vib_delay ` `0.0`
`env_attack ` `0.0`
`env_sustain ` `0.3`
`env_decay ` `0.4`
`env_punch ` `0.0`
`filter_on ` `false`
`lpf_resonance ` `0.0`
`lpf_freq ` `1.0`
`lpf_ramp ` `0.0`
`hpf_freq ` `0.0`
`hpf_ramp ` `0.0`
`pha_offset ` `0.0`
`pha_ramp ` `0.0`
`repeat_speed ` `0.0`
`arp_speed ` `0.0`
`arp_mod ` `0.0`

Alternatively settings can also be a numeric seed. Use the sfxr example
in the [online editor](http://www.amulet.xyz/editor.html)) to generate seeds.

## Audio graphs

TODO

## Analysing audio
(Amulet has support for building graphs of audio effect nodes,
however it is currently undocumented because it will probably
be changing shortly to use syntax more consistent with the
way scene graphs are constructed.)

## Audio graph nodes

TODO

## Audio node reference
## Analysing audio

TODO

6 changes: 3 additions & 3 deletions doc/buffers.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

# Buffers and views {#buffers-and-views}

![](images/screenshot5.jpg)

# Buffers and views {#buffers-and-views}

Buffers are contiguous blocks of memory. They are used for storing images,
audio and vertex data, or anything else you like.

Expand All @@ -15,7 +15,7 @@ through a *view*. Views provide a typed array-like interface to the buffer.

Returns a new buffer of the given size in bytes.

The buffer's memory will zeroed.
The buffer's memory will be zeroed.

The `#` operator can be used to retrieve the size of a buffer in bytes.

Expand Down
Loading

0 comments on commit 17e1e06

Please sign in to comment.