summary refs log tree commit diff
path: root/src/zeal.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/zeal.zig')
-rw-r--r--src/zeal.zig72
1 files changed, 59 insertions, 13 deletions
diff --git a/src/zeal.zig b/src/zeal.zig
index 7103f59..e5984bf 100644
--- a/src/zeal.zig
+++ b/src/zeal.zig
@@ -18,16 +18,20 @@
 
 const Allocator = std.mem.Allocator;
 const SndFile = sf.SndFile;
+const al = @import("al.zig");
+const alc = @import("alc.zig");
 const sf = @import("sf.zig");
 const std = @import("std");
 
-pub const al = @import("al.zig");
-pub const alc = @import("alc.zig");
-
 pub const Error = al.Error || error {
     UncurrentContext,
 };
 
+/// Return version information and error strings.
+pub fn get(comptime attr: alc.Enum) !attr.getType() {
+    return alc.get(null, attr);
+}
+
 pub const Device = struct {
     pimpl: *alc.Device,
 
@@ -35,8 +39,9 @@ pub const Device = struct {
         return Device{ .pimpl = try alc.openDevice(name) };
     }
 
-    pub fn enabledHrtf(self: Device) alc.Error!bool {
-        return 0 != try alc.getInt(self.pimpl, alc.HRTF);
+    /// Return infomation about the device.
+    pub fn get(self: Device, comptime attr: alc.Enum) !attr.getType() {
+        return alc.get(self.pimpl, attr);
     }
 
     pub fn deinit(self: Device) alc.Error!void {
@@ -48,9 +53,49 @@ pub const Context = struct {
     pimpl: *alc.Context,
     device: Device,
 
-    pub fn init(device: Device, attributes: [:0]const i32) alc.Error!Context {
+    pub const Attributes = struct {
+        /// Channel configuration.
+        channels_format: ?alc.ChannelsFormat = null,
+        /// Sample type.
+        sample_type: ?alc.SampleType = null,
+        /// Frequency in hertz.
+        frequency: ?i32 = null,
+
+        /// Ambisonic format layout.
+        ambisonic_layout: ?alc.AmbisonicLayout = null,
+        /// Ambisonic normalization method.
+        ambisonic_scaling: ?alc.AmbisonicScaling = null,
+        /// Ambisonic order.
+        ambisonic_order: ?i32 = null,
+
+        /// Number of mono (3D) sources.
+        mono_sources: ?i32 = null,
+        /// Number of stereo sources.
+        stereo_sources: ?i32 = null,
+        /// Maximum number of auxiliary source sends.
+        max_auxiliary_sends: ?i32 = null,
+        /// Enabling HRTF.
+
+        hrtf: ?alc.Logical = null,
+        /// The HRTF to be used.
+        hrtf_id: ?i32 = null,
+        /// Enabling gain limiter.
+        output_limiter: ?alc.Logical = null,
+        /// Output mode.
+        output_mode: ?i32 = null,
+    };
+
+    pub fn init(device: Device, attributes: Attributes) alc.Error!Context {
+        const fields = @typeInfo(Attributes).Struct.fields;
+        var attr_list = [_]i32{ 0 } ** (fields.len * 2 + 1);
+        var i: u8 = 0;
+        inline for (fields) |f| if (@field(attributes, f.name)) |v| {
+            attr_list[i] = @enumToInt(@field(alc.Enum, f.name));
+            attr_list[i + 1] = if (@TypeOf(v) == i32) v else @enumToInt(v);
+            i += 2;
+        };
         return Context {
-            .pimpl = try alc.createContext(device.pimpl, attributes),
+            .pimpl = try alc.createContext(device.pimpl, attr_list[0..i:0]),
             .device = device,
         };
     }
@@ -160,10 +205,11 @@ pub const Source = struct {
                           @intCast(i32, buffer.reference));
     }
 
-    /// Specify if the source always has 3D spatialization features (al.ON),
-    /// never has 3D spatialization features (al.OFF), or if spatialization
-    /// is enabled based on playing a mono sound or not (al.AUTO, default).
-    pub fn setSpatialize(self: Source, value: i32) Error!void {
+    /// Specify if the source always has 3D spatialization features (true),
+    /// never has 3D spatialization features (false), or if spatialization
+    /// is enabled based on playing a mono sound or not (null, default).
+    pub fn setSpatialize(self: Source, enable: ?bool) Error!void {
+        const value: i32 = if (enable) |b| al.boolToEnum(b) else al.AUTO;
         try al.source.set(self.reference, .spatialize, value);
     }
 
@@ -198,7 +244,7 @@ const expectEqual = std.testing.expectEqual;
 test "Context" {
     const device = try Device.init(null);
     defer device.deinit() catch unreachable;
-    const context = try Context.init(device, &.{ alc.HRTF, alc.TRUE, 0 });
+    const context = try Context.init(device, .{ .hrtf = .true });
     defer context.deinit() catch unreachable;
 
     try expectEqual(Context.getCurrent(), null);
@@ -214,7 +260,7 @@ test "Context" {
 }
 
 test "listener" {
-    const context = try Context.init(try Device.init(null), &.{ 0 });
+    const context = try Context.init(try Device.init(null), .{});
     defer context.device.deinit() catch unreachable;
     defer context.deinit() catch unreachable;