summary refs log tree commit diff
path: root/src/al.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/al.zig')
-rw-r--r--src/al.zig182
1 files changed, 149 insertions, 33 deletions
diff --git a/src/al.zig b/src/al.zig
index bfb93b6..7b2e6db 100644
--- a/src/al.zig
+++ b/src/al.zig
@@ -33,12 +33,16 @@ pub const Error = error {
     OutOfMemory,
 };
 
+pub const BUFFER = AL_BUFFER;
 pub const POSITION = AL_POSITION;
 pub const ORIENTATION = AL_ORIENTATION;
+pub const PLAYING = AL_PLAYING;
+pub const SEC_OFFSET = AL_SEC_OFFSET;
+pub const SOURCE_STATE = AL_SOURCE_STATE;
 
 pub const listener = struct {
     /// Set a property for the listener.
-    pub fn set(param: ALenum, value: anytype) !void {
+    pub fn set(param: ALenum, value: anytype) Error!void {
         const T = @TypeOf(value);
         switch (T) {
             f32 => alListenerf(param, value),
@@ -60,42 +64,154 @@ pub const listener = struct {
     }
 };
 
-/// Generate one buffer for audio data and return its reference.
-pub fn genBuffer() !u32 {
-    var reference: u32 = undefined;
-    alGenBuffers(1, &reference);
-    return switch (alGetError()) {
-        AL_NO_ERROR => reference,
-        AL_INVALID_VALUE => Error.InvalidValue,
-        AL_OUT_OF_MEMORY => Error.OutOfMemory,
-        else => unreachable,
-    };
-}
-
-// TODO: genBuffers
-
-/// Free resources used by one buffer.
-/// Buffers attached to a source cannot be deleted.
-pub fn deleteBuffer(reference: *const u32) !void {
-    alDeleteBuffers(1, reference);
-    switch (alGetError()) {
-        AL_NO_ERROR => {},
-        AL_INVALID_OPERATION => return Error.InvalidOperation,
-        AL_INVALID_NAME => return Error.InvalidName,
-        AL_INVALID_VALUE => return Error.InvalidValue,
-        else => unreachable,
+pub const Data = union(enum) {
+    /// Unsigned 8-bit mono.
+    mono8: []const u8,
+    /// Signed 16-bit mono.
+    mono16: []const i16,
+    /// Unsigned 8-bit stereo.
+    stereo8: []const u8,
+    /// Signed 16-bit stereo.
+    stereo16: []const i16,
+};
+
+pub const buffer = struct {
+    /// Generate one buffer for audio data and return its reference.
+    pub fn create() Error!u32 {
+        var reference: u32 = undefined;
+        alGenBuffers(1, &reference);
+        return switch (alGetError()) {
+            AL_NO_ERROR => reference,
+            AL_INVALID_VALUE => Error.InvalidValue,
+            AL_OUT_OF_MEMORY => Error.OutOfMemory,
+            else => unreachable,
+        };
+    }
+
+    /// Free resources used by one buffer.
+    /// Buffers attached to a source cannot be deleted.
+    pub fn destroy(reference: *const u32) Error!void {
+        alDeleteBuffers(1, reference);
+        switch (alGetError()) {
+            AL_NO_ERROR => {},
+            AL_INVALID_OPERATION => return Error.InvalidOperation,
+            AL_INVALID_NAME => return Error.InvalidName,
+            AL_INVALID_VALUE => return Error.InvalidValue,
+            else => unreachable,
+        }
+    }
+
+    /// Fill a buffer with audio data.
+    pub fn fill(reference: u32, data: Data, freq: i32) Error!void {
+        const format = switch (data) {
+            .mono8 => AL_FORMAT_MONO8,
+            .mono16 => AL_FORMAT_MONO16,
+            .stereo8 => AL_FORMAT_STEREO8,
+            .stereo16 => AL_FORMAT_STEREO16,
+        };
+
+        switch (data) {
+            .mono8, .stereo8 => |slice| {
+                const size = @intCast(c_int, slice.len);
+                alBufferData(reference, format, slice.ptr, size, freq);
+            },
+            .mono16, .stereo16 => |slice| {
+                const size = @intCast(c_int, slice.len) * 2;
+                alBufferData(reference, format, slice.ptr, size, freq);
+            },
+        }
+
+        switch (alGetError()) {
+            AL_NO_ERROR => {},
+            AL_OUT_OF_MEMORY => return Error.OutOfMemory,
+            AL_INVALID_VALUE => return Error.InvalidValue,
+            AL_INVALID_ENUM => return Error.InvalidEnum,
+            else => unreachable,
+        }
+    }
+};
+
+pub const source = struct {
+    /// Generate one source for audio data and return its reference.
+    pub fn create() Error!u32 {
+        var reference: u32 = undefined;
+        alGenSources(1, &reference);
+        return switch (alGetError()) {
+            AL_NO_ERROR => reference,
+            AL_INVALID_VALUE => Error.InvalidValue,
+            AL_OUT_OF_MEMORY => Error.OutOfMemory,
+            else => unreachable,
+        };
+    }
+
+    /// Free resources used by one source.
+    /// Sources attached to a source cannot be deleted.
+    pub fn destroy(reference: *const u32) Error!void {
+        alDeleteSources(1, reference);
+        switch (alGetError()) {
+            AL_NO_ERROR => {},
+            AL_INVALID_OPERATION => return Error.InvalidOperation,
+            AL_INVALID_NAME => return Error.InvalidName,
+            AL_INVALID_VALUE => return Error.InvalidValue,
+            else => unreachable,
+        }
     }
-}
 
-// TODO: deleteBuffers
+    /// Set a property for the source.
+    pub fn set(reference: u32, param: ALenum, value: anytype) Error!void {
+        const T = @TypeOf(value);
+        switch (T) {
+            f32 => alSourcef(reference, param, value),
+            i32 => alSourcei(reference, param, value),
+            else => switch (Child(T)) {
+                f32 => alSourcefv(reference, param, value[0..]),
+                i32 => alSourceiv(reference, param, value[0..]),
+                else => unreachable,
+            }
+        }
+
+        switch (alGetError()) {
+            AL_NO_ERROR => {},
+            AL_INVALID_VALUE => return Error.InvalidValue,
+            AL_INVALID_ENUM => return Error.InvalidEnum,
+            AL_INVALID_NAME => return Error.InvalidName,
+            AL_INVALID_OPERATION => return Error.InvalidOperation,
+            else => unreachable,
+        }
+    }
+
+    /// Get a scalar property from the source.
+    pub fn get(comptime T: type, reference: u32, param: ALenum) Error!T {
+        var value: T = undefined;
+        switch (T) {
+            f32 => alGetSourcef(reference, param, &value),
+            i32 => alGetSourcei(reference, param, &value),
+            else => unreachable,
+        }
+
+        return switch (alGetError()) {
+            AL_NO_ERROR => value,
+            AL_INVALID_VALUE => return Error.InvalidValue,
+            AL_INVALID_ENUM => return Error.InvalidEnum,
+            AL_INVALID_NAME => return Error.InvalidName,
+            AL_INVALID_OPERATION => return Error.InvalidOperation,
+            else => unreachable,
+        };
+    }
+
+    /// Play the source.
+    pub fn play(reference: u32) Error!void {
+        alSourcePlay(reference);
+        switch (alGetError()) {
+            AL_NO_ERROR => {},
+            AL_INVALID_NAME => return Error.InvalidName,
+            AL_INVALID_OPERATION => return Error.InvalidOperation,
+            else => unreachable,
+        }
+    }
+};
 
-// alBufferData
-// alDeleteSources
-// alGenSources
 // alGetSourcei
-// alSourcef
-// alSourcefv
-// alSourcei
 // alSourcePause
 // alSourcePlay
 // alSourceStop