audio
| Kind | ffi-c |
|---|---|
| Capabilities | ffi file |
| Categories | multimedia audio |
| Keywords | audio sound music playback recording miniaudio |
Cross-platform audio playback and recording for Kit using miniaudio
Files
| File | Description |
|---|---|
.editorconfig | Editor formatting configuration |
.gitignore | Git ignore rules for build artifacts and dependencies |
.tool-versions | asdf tool versions (Zig, Kit) |
LICENSE | MIT license file |
README.md | This file |
c/kit_audio.h | C FFI wrapper for miniaudio |
c/kit_audio_impl.c | C implementation file |
c/miniaudio.h | miniaudio header (single-file library) |
examples/basic.kit | Basic audio playback example |
examples/music.kit | Music player with controls example |
examples/spatial.kit | 3D spatial audio example |
examples/synthesis.kit | Waveform and noise synthesis example |
kit.toml | Package manifest with metadata and dependencies |
src/audio.kit | Main Kit audio module |
tests/audio.test.kit | Tests for audio functionality |
tests/types.test.kit | Tests for audio types and constants |
Dependencies
No Kit package dependencies.
This package bundles miniaudio as a single-file header-only library, so no external installation is required.
Installation
kit add gitlab.com/kit-lang/packages/kit-audio.gitUsage
Basic Audio Playback
import Kit.Audio as Audio
main = fn(env: Env) =>
match Audio.init
| Ok engine ->
match Audio.load engine "sound.wav"
| Ok sound ->
defer Audio.free sound
Audio.play sound
Process.sleep 2000 # Wait for playback
| Err err -> println "Failed to load: ${err}"
Audio.shutdown engine
| Err err -> println "Failed to initialize: ${err}"
mainMusic Playback with Controls
import Kit.Audio as Audio
main = fn(env: Env) =>
match Audio.init
| Ok engine ->
# Load music as stream (better for large files)
match Audio.load-stream engine "music.mp3"
| Ok music ->
println "Duration: ${Float.to-string (Audio.length music)} seconds"
# Set volume
Audio.set-sound-volume music 0.7
# Enable looping
Audio.set-looping music true
# Play
Audio.play music
Process.sleep 5000 # Play for 5 seconds
# Seek to middle
len = Audio.length music
Audio.seek music (len / 2.0)
Audio.stop music
Audio.free music
| Err err -> println "Failed to load: ${err}"
Audio.shutdown engine
| Err err -> println "Failed to initialize: ${err}"
main3D Spatial Audio
import Kit.Audio as Audio
main = fn(env: Env) =>
match Audio.init
| Ok engine ->
# Set up listener
Audio.set-listener-position engine 0.0 0.0 0.0
Audio.set-listener-direction engine 0.0 0.0 (-1.0)
match Audio.load engine "footstep.wav"
| Ok sound ->
# Enable spatialization
Audio.set-spatialization sound true
# Position sound to the left
Audio.set-position sound (-5.0) 0.0 0.0
Audio.play sound
Process.sleep 1000
# Move sound to the right
Audio.set-position sound 5.0 0.0 0.0
Process.sleep 1000
Audio.free sound
| Err err -> println "Failed to load: ${err}"
Audio.shutdown engine
| Err err -> println "Failed to initialize: ${err}"
mainAudio Synthesis
import Kit.Audio as Audio
main = fn(env: Env) =>
match Audio.init
| Ok engine ->
# Create a sine wave at 440Hz (A4)
match Audio.create-waveform engine waveform-sine 440.0 0.3
| Ok tone ->
Process.sleep 1000
Audio.free-waveform tone
| Err err -> println "Failed to create tone: ${err}"
# Create white noise
match Audio.create-noise engine noise-white 0.2
| Ok noise ->
Process.sleep 1000
Audio.free-noise noise
| Err err -> println "Failed to create noise: ${err}"
Audio.shutdown engine
| Err err -> println "Failed to initialize: ${err}"
# Waveform types
waveform-sine = 0
waveform-square = 1
waveform-triangle = 2
waveform-sawtooth = 3
# Noise types
noise-white = 0
noise-pink = 1
noise-brownian = 2
mainDevelopment
Running Examples
Run examples with the interpreter:
kit run examples/basic.kit --allow=ffi,file
kit run examples/music.kit --allow=ffi,file
kit run examples/spatial.kit --allow=ffi,file
kit run examples/synthesis.kit --allow=ffi,fileNote: The audio package requires ffi and file capabilities.
Running Tests
Run the test suite:
kit testRun the test suite with coverage:
kit test --coverageRunning kit dev
Run the standard development workflow (format, check, test):
kit devThis will:
- Format and check source files in
src/ - Run tests in
tests/with coverage
Generating Documentation
Generate API documentation from doc comments:
kit docNote: Kit sources with doc comments (##) will generate HTML documents in docs/*.html
Cleaning Build Artifacts
Remove generated files, caches, and build artifacts:
kit task cleanNote: Defined in kit.toml.
Local Installation
To install this package locally for development:
kit installThis installs the package to ~/.kit/packages/@kit/audio/, making it available for import as Kit.Audio in other projects.
License
This package is released under the MIT License - see LICENSE for details.
miniaudio is also released under the MIT License.
Exported Functions & Types
AudioError
Audio error type with specific variants for different failure modes.
Variants
AudioInitError {message}AudioLoadError {message}AudioCreateError {message}waveform-sine
Waveform type: sine wave
Produces a smooth, pure tone with a single frequency component. Mathematically defined as $y(t) = A \sin(2\pi f t)$ where $A$ is amplitude and $f$ is frequency.
waveform-square
Waveform type: square wave
Produces a harsh tone alternating between maximum and minimum values. Contains odd harmonics: $y(t) = \frac{4A}{\pi}\sum_{k=1,3,5...}^{\infty}\frac{\sin(2\pi kft)}{k}$
waveform-triangle
Waveform type: triangle wave
Produces a softer tone than square wave with linearly ramping values. Contains odd harmonics with faster decay: $y(t) = \frac{8A}{\pi^2}\sum_{k=1,3,5...}^{\infty}\frac{(-1)^{(k-1)/2}\sin(2\pi kft)}{k^2}$
waveform-sawtooth
Waveform type: sawtooth wave
Produces a bright, buzzy tone with a linear ramp from minimum to maximum. Contains all harmonics: $y(t) = \frac{2A}{\pi}\sum_{k=1}^{\infty}\frac{(-1)^{k+1}\sin(2\pi kft)}{k}$
noise-white
Noise type: white noise
Produces random noise with equal energy across all frequencies. Each sample is independent with uniform spectral density.
noise-pink
Noise type: pink noise
Produces noise with equal energy per octave (1/f spectrum). Sounds less harsh than white noise, more natural. Power spectral density decreases by 3 dB per octave.
noise-brownian
Noise type: brownian noise (red noise)
Produces noise with power spectral density decreasing by 6 dB per octave. Lower frequencies dominate, creating a softer, deeper sound than pink noise.
init
init
Initialize the audio engine.
This must be called before any other audio operations. The engine manages the audio device, mixer, and all audio resources.
Returns: AudioResult {ptr: Ptr} - Ok with engine handle on success,Err with message on failure
() -> Result {ptr: Ptr} AudioError
match init()
| Ok engine ->
# Use engine for audio operations
shutdown engine
| Err err ->
print "Failed to initialize: ${err}"shutdown
shutdown
Shutdown the audio engine and release all resources.
This stops all playing sounds and frees the audio device. Should be called when audio is no longer needed.
Parameters:
- engine- Engine handle returned from init()
{ptr: Ptr} -> Unit
match init()
| Ok engine ->
# ... use engine ...
shutdown engine
| Err err -> print errget-volume
get-volume
Get the master volume level.
Parameters:
- engine- Engine handle
Returns: Float - Master volume (0.0 = silent, 1.0 = normal, >1.0 = amplified)
{ptr: Ptr} -> Float
set-volume
set-volume
Set the master volume level.
Affects all sounds playing through this engine. Values above 1.0 will amplify the audio signal but may cause clipping.
Parameters:
- engine- Engine handle- volume- Float - Volume level (0.0 = silent, 1.0 = normal, >1.0 = amplified)
{ptr: Ptr} -> Float -> Unit
set-volume engine 0.5 # Half volume
set-volume engine 1.5 # 50% amplificationget-sample-rate
get-sample-rate
Get the audio engine's sample rate in Hz.
Common sample rates are 44100 Hz (CD quality) and 48000 Hz (professional audio).
Parameters:
- engine- Engine handle
Returns: Int - Sample rate in Hz (e.g., 44100, 48000)
{ptr: Ptr} -> Int
get-channels
get-channels
Get the number of audio channels.
Parameters:
- engine- Engine handle
Returns: Int - Number of channels (1 = mono, 2 = stereo)
{ptr: Ptr} -> Int
load
load
Load a sound file into memory for low-latency playback.
The entire file is decoded immediately. Best for short sounds like effects, UI sounds, and samples that need instant playback. For large files like music, use load-stream instead.
Supported formats: WAV, MP3, FLAC, OGG Vorbis
Parameters:
- engine- Engine handle- path- String - File path to audio file
Returns: AudioResult {ptr: Ptr} - Ok with sound handle on success,Err with message on failure
{ptr: Ptr} -> NonEmptyString -> Result {ptr: Ptr} AudioError
match load engine "explosion.wav"
| Ok sound ->
play sound
free sound
| Err err ->
print "Load failed: ${err}"load-stream
load-stream
Load a sound file for streaming playback.
Audio is decoded on-the-fly during playback, reducing memory usage. Ideal for large files like background music and long recordings. Has slightly higher CPU usage than pre-decoded sounds.
Supported formats: WAV, MP3, FLAC, OGG Vorbis
Parameters:
- engine- Engine handle- path- String - File path to audio file
Returns: AudioResult {ptr: Ptr} - Ok with sound handle on success,Err with message on failure
{ptr: Ptr} -> NonEmptyString -> Result {ptr: Ptr} AudioError
match load-stream engine "music.mp3"
| Ok music ->
set-looping music true
play music
| Err err ->
print "Load failed: ${err}"free
free
Free a sound and release its resources.
The sound is stopped if currently playing. The handle becomes invalid and should not be used after this call.
Parameters:
- sound- Sound handle returned from load() or load-stream()
{ptr: Ptr} -> Unit
play
play
Start playing a sound.
If the sound is already playing, it continues from current position. Use stop() first to restart from the beginning.
Parameters:
- sound- Sound handle
Returns: Unit
{ptr: Ptr} -> Unit
stop
stop
Stop a playing sound and reset to beginning.
Parameters:
- sound- Sound handle
Returns: Unit
{ptr: Ptr} -> Unit
is-playing?
is-playing?
Check if a sound is currently playing.
Parameters:
- sound- Sound handle
Returns: Bool - true if sound is playing, false otherwise
{ptr: Ptr} -> Bool
sound-volume
sound-volume
Get the volume of a specific sound.
This is independent of the master volume set on the engine. Final output volume is: master_volume × sound_volume.
Parameters:
- sound- Sound handle
Returns: Float - Volume level (0.0 = silent, 1.0 = normal, >1.0 = amplified)
{ptr: Ptr} -> Float
set-sound-volume
set-sound-volume
Set the volume of a specific sound.
This is independent of the master volume. Values above 1.0 will amplify the sound but may cause clipping.
Parameters:
- sound- Sound handle- volume- Float - Volume level (0.0 = silent, 1.0 = normal, >1.0 = amplified)
{ptr: Ptr} -> Float -> Unit
set-sound-volume footstep 0.3 # Quiet footsteps
set-sound-volume explosion 1.5 # Loud explosionpitch
pitch
Get the pitch/playback speed of a sound.
Parameters:
- sound- Sound handle
Returns: Float - Pitch multiplier (1.0 = normal, 2.0 = octave up, 0.5 = octave down)
{ptr: Ptr} -> Float
set-pitch
set-pitch
Set the pitch/playback speed of a sound.
Affects both frequency and duration. A pitch of 2.0 plays at double speed and one octave higher. A pitch of 0.5 plays at half speed and one octave lower. For musical intervals, use $2^{n/12}$ where n is semitones (e.g., 1.059463 for one semitone up).
Parameters:
- sound- Sound handle- new-pitch- Float - Pitch multiplier (1.0 = normal, 2.0 = octave up, 0.5 = octave down)
{ptr: Ptr} -> Float -> Unit
set-pitch sound 1.0 # Normal speed
set-pitch sound 2.0 # Double speed, octave up
set-pitch sound 0.5 # Half speed, octave down
set-pitch sound 1.05946 # One semitone uppan
pan
Get the stereo panning position of a sound.
Parameters:
- sound- Sound handle
Returns: Float - Pan position (-1.0 = full left, 0.0 = center, 1.0 = full right)
{ptr: Ptr} -> Float
set-pan
set-pan
Set the stereo panning position of a sound.
Only affects stereo output. For mono output, pan is ignored.
Parameters:
- sound- Sound handle- new-pan- Float - Pan position (-1.0 = full left, 0.0 = center, 1.0 = full right)
{ptr: Ptr} -> Float -> Unit
set-pan sound -1.0 # Full left
set-pan sound 0.0 # Center
set-pan sound 1.0 # Full right
set-pan sound 0.5 # Slight rightis-looping?
is-looping?
Check if a sound is set to loop.
Parameters:
- sound- Sound handle
Returns: Bool - true if sound loops, false otherwise
{ptr: Ptr} -> Bool
set-looping
set-looping
Enable or disable looping for a sound.
When looping is enabled, the sound automatically restarts from the beginning when it reaches the end.
Parameters:
- sound- Sound handle- looping- Bool - true to enable looping, false to disable
{ptr: Ptr} -> Bool -> Unit
set-looping background-music true # Loop forever
set-looping sound-effect false # Play onceseek
seek
Jump to a specific position in the sound.
Parameters:
- sound- Sound handle- seconds- Float - Position in seconds from the start
{ptr: Ptr} -> Float -> Unit
seek sound 0.0 # Jump to beginning
seek sound 30.0 # Jump to 30 seconds
seek sound (length sound - 5.0) # Jump to 5 seconds before endlength
length
Get the total duration of a sound in seconds.
Parameters:
- sound- Sound handle
Returns: Float - Duration in seconds
{ptr: Ptr} -> Float
position
position
Get the current playback position in seconds.
Parameters:
- sound- Sound handle
Returns: Float - Current position in seconds from the start
{ptr: Ptr} -> Float
at-end?
at-end?
Check if a sound has finished playing.
Returns true when playback reaches the end of a non-looping sound. Always returns false for looping sounds.
Parameters:
- sound- Sound handle
Returns: Bool - true if sound has finished, false otherwise
{ptr: Ptr} -> Bool
play-oneshot
Play a sound file immediately (fire and forget).
{ptr: Ptr} -> NonEmptyString -> Unit
set-position
Set sound position in 3D space.
{ptr: Ptr} -> Float -> Float -> Float -> Unit
set-velocity
Set sound velocity (for doppler effect).
{ptr: Ptr} -> Float -> Float -> Float -> Unit
set-direction
Set sound direction.
{ptr: Ptr} -> Float -> Float -> Float -> Unit
set-spatialization
Enable/disable spatialization for a sound.
{ptr: Ptr} -> Bool -> Unit
set-listener-position
Set listener position.
{ptr: Ptr} -> Float -> Float -> Float -> Unit
set-listener-direction
Set listener direction.
{ptr: Ptr} -> Float -> Float -> Float -> Unit
set-listener-velocity
Set listener velocity.
{ptr: Ptr} -> Float -> Float -> Float -> Unit
create-waveform
Create a waveform generator. type: WAVEFORM_SINE, WAVEFORM_SQUARE, WAVEFORM_TRIANGLE, WAVEFORM_SAWTOOTH frequency: Hz (e.g., 440.0 for A4) amplitude: 0.0 to 1.0
{ptr: Ptr} -> Int -> PositiveFloat -> UnitFloat -> Result {ptr: Ptr} AudioError
free-waveform
Free a waveform.
{ptr: Ptr} -> Unit
set-waveform-frequency
Set waveform frequency.
{ptr: Ptr} -> PositiveFloat -> Unit
set-waveform-amplitude
Set waveform amplitude.
{ptr: Ptr} -> UnitFloat -> Unit
create-noise
Create a noise generator. type: NOISE_WHITE, NOISE_PINK, NOISE_BROWNIAN amplitude: 0.0 to 1.0
{ptr: Ptr} -> Int -> UnitFloat -> Result {ptr: Ptr} AudioError
free-noise
Free a noise generator.
{ptr: Ptr} -> Unit
set-noise-amplitude
Set noise amplitude.
{ptr: Ptr} -> UnitFloat -> Unit
create-recorder
Create a recorder. sample-rate: e.g., 44100 channels: 1 (mono) or 2 (stereo) max-seconds: maximum recording length
PositiveInt -> PositiveInt -> PositiveInt -> Result {ptr: Ptr, sample-rate: Int, channels: Int} AudioError
free-recorder
Free a recorder.
{ptr: Ptr, sample-rate: Int, channels: Int} -> Unit
start-recording
Start recording.
{ptr: Ptr, sample-rate: Int, channels: Int} -> Unit
stop-recording
Stop recording.
{ptr: Ptr, sample-rate: Int, channels: Int} -> Unit
is-recording?
Check if currently recording.
{ptr: Ptr, sample-rate: Int, channels: Int} -> Bool
samples-recorded
Get number of samples recorded.
{ptr: Ptr, sample-rate: Int, channels: Int} -> Int
get-sample
Get a specific sample from recording.
{ptr: Ptr, sample-rate: Int, channels: Int} -> NonNegativeInt -> Float
playback-device-count
Get number of playback devices.
() -> Int
capture-device-count
Get number of capture devices.
() -> Int
load-and-play
Load and play a sound, returning the sound handle.
{ptr: Ptr} -> NonEmptyString -> Result {ptr: Ptr} AudioError
load-and-loop
Load and play with looping.
{ptr: Ptr} -> NonEmptyString -> Result {ptr: Ptr} AudioError
play-tone
Play a sine wave at given frequency.
{ptr: Ptr} -> PositiveFloat -> UnitFloat -> Result {ptr: Ptr} AudioError
note-frequency
Play standard musical notes (A4 = 440 Hz).
Int -> Float
A4
A4 note frequency (440 Hz)
Float
C4
C4 note frequency (261.63 Hz)
Float
D4
D4 note frequency (293.66 Hz)
Float
E4
E4 note frequency (329.63 Hz)
Float
F4
F4 note frequency (349.23 Hz)
Float
G4
G4 note frequency (392.00 Hz)
Float
B4
B4 note frequency (493.88 Hz)
Float
C5
C5 note frequency (523.25 Hz)
Float