diff options
-rw-r--r-- | build.zig | 6 | ||||
-rw-r--r-- | examples/play.zig | 6 | ||||
-rw-r--r-- | src/alc.zig | 27 | ||||
-rw-r--r-- | src/sf.zig | 13 | ||||
-rw-r--r-- | src/zeal.zig (renamed from src/main.zig) | 32 |
5 files changed, 52 insertions, 32 deletions
diff --git a/build.zig b/build.zig index 472a5cb..afc422f 100644 --- a/build.zig +++ b/build.zig @@ -23,11 +23,11 @@ pub fn build(b: *std.build.Builder) void { // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. const mode = b.standardReleaseOptions(); - const lib = b.addStaticLibrary("zeal", "src/main.zig"); + const lib = b.addStaticLibrary("zeal", "src/zeal.zig"); lib.setBuildMode(mode); lib.install(); - var main_tests = b.addTest("src/main.zig"); + var main_tests = b.addTest("src/zeal.zig"); main_tests.linkSystemLibrary("openal"); main_tests.linkSystemLibrary("sndfile"); main_tests.linkSystemLibrary("c"); @@ -37,7 +37,7 @@ pub fn build(b: *std.build.Builder) void { test_step.dependOn(&main_tests.step); const example_play = b.addExecutable("zeal-play", "examples/play.zig"); - example_play.addPackagePath("zeal", "src/main.zig"); + example_play.addPackagePath("zeal", "src/zeal.zig"); example_play.linkSystemLibrary("openal"); example_play.linkSystemLibrary("sndfile"); example_play.linkSystemLibrary("c"); diff --git a/examples/play.zig b/examples/play.zig index 81403a0..acb5dad 100644 --- a/examples/play.zig +++ b/examples/play.zig @@ -34,11 +34,13 @@ pub fn main() !void { defer device.deinit() catch unreachable; const context = try Context.init(device, &.{}); defer context.deinit() catch unreachable; - try useContext(context); var argv = args(); - _ = argv.next(allocator); + allocator.free(try argv.next(allocator).?); const filename = try argv.next(allocator).?; + defer allocator.free(filename); + + try useContext(context); const buffer = try Buffer.init(allocator, context, filename); defer buffer.deinit() catch unreachable; diff --git a/src/alc.zig b/src/alc.zig index 8e478e8..ca83bf6 100644 --- a/src/alc.zig +++ b/src/alc.zig @@ -48,8 +48,8 @@ pub const DONT_CARE = ALC_DONT_CATE_SOFT; pub const HRTF = ALC_HRTF_SOFT; /// Create and attach a context to the given device. -pub fn createContext(device: *Device, attributes: [:0]const i32) !*Context { - if (alcCreateContext(device, attributes.ptr)) |context| +pub fn createContext(device: *Device, attrlist: [:0]const i32) Error!*Context { + if (alcCreateContext(device, attrlist.ptr)) |context| return context; return switch (alcGetError(device)) { ALC_INVALID_DEVICE => Error.InvalidDevice, @@ -60,7 +60,7 @@ pub fn createContext(device: *Device, attributes: [:0]const i32) !*Context { /// Make the given context the active process-wide context. /// Passing NULL clears the active context. -pub fn makeContextCurrent(context: ?*Context) !void { +pub fn makeContextCurrent(context: ?*Context) Error!void { if (alcMakeContextCurrent(context) == TRUE) return; if (alcGetError(null) == ALC_INVALID_CONTEXT) @@ -69,7 +69,7 @@ pub fn makeContextCurrent(context: ?*Context) !void { } /// Remove a context from its device and destroys it. -pub fn destroyContext(context: *Context) !void { +pub fn destroyContext(context: *Context) Error!void { alcDestroyContext(context); if (alcGetError(null) == ALC_INVALID_CONTEXT) return Error.InvalidContext; @@ -81,7 +81,7 @@ pub fn getCurrentContext() ?*Context { } /// Return the device that a particular context is attached to. -pub fn getContextsDevice(context: *Context) !*Device { +pub fn getContextsDevice(context: *Context) Error!*Device { if (alcGetContextsDevice(context)) |device| return device; if (alcGetError(null) == ALC_INVALID_CONTEXT) @@ -90,7 +90,7 @@ pub fn getContextsDevice(context: *Context) !*Device { } /// Open the named playback device. -pub fn openDevice(name: ?[:0]const u8) !*Device { +pub fn openDevice(name: ?[:0]const u8) Error!*Device { const name_ptr = if (name == null) null else name.?.ptr; if (alcOpenDevice(name_ptr)) |device| return device; @@ -102,10 +102,23 @@ pub fn openDevice(name: ?[:0]const u8) !*Device { } /// Close the given playback device. -pub fn closeDevice(device: *Device) !void { +pub fn closeDevice(device: *Device) Error!void { if (alcCloseDevice(device) == TRUE) return; if (alcGetError(device) == ALC_INVALID_DEVICE) return Error.InvalidDevice; unreachable; } + +pub fn getInt(device: *Device, param: ALCenum) Error!i32 { + var data: i32 = undefined; + alcGetIntegerv(device, param, 1, &data); + return switch (alcGetError(device)) { + ALC_NO_ERROR => data, + ALC_INVALID_VALUE => Error.InvalidValue, + ALC_INVALID_ENUM => Error.InvalidEnum, + ALC_INVALID_DEVICE => Error.InvalidDevice, + ALC_INVALID_CONTEXT => Error.InvalidContext, + else => unreachable, + }; +} diff --git a/src/sf.zig b/src/sf.zig index d38446c..a95999c 100644 --- a/src/sf.zig +++ b/src/sf.zig @@ -16,7 +16,9 @@ // You should have received a copy of the GNU Lesser General Public License // along with zeal. If not, see <https://www.gnu.org/licenses/>. -const Allocator = @import("std").mem.Allocator; +const Allocator = std.mem.Allocator; +const assert = std.debug.assert; +const std = @import("std"); usingnamespace @cImport(@cInclude("sndfile.h")); @@ -26,7 +28,7 @@ pub const Mode = enum { read_write, }; -pub const Error = error { +pub const Error = Allocator.Error || error { UnrecognizedFormat, SystemError, MalformedFile, @@ -72,7 +74,7 @@ pub const SndFile = struct { /// Read the requested number of frames. /// The returned memory is managed by the caller. pub fn read(self: SndFile, allocator: *Allocator, - frames: usize) Allocator.Error![]const i16 { + frames: usize) Error![]const i16 { const items = frames * @intCast(usize, self.channels); const memory = try allocator.alloc(i16, items); const n = sf_read_short(self.pimpl, memory.ptr, @intCast(i64, items)); @@ -80,8 +82,7 @@ pub const SndFile = struct { } /// Read the entire file. The returned memory is managed by the caller. - pub fn readAll(self: SndFile, - allocator: *Allocator) Allocator.Error![]const i16 { + pub fn readAll(self: SndFile, allocator: *Allocator) Error![]const i16 { return self.read(allocator, self.frames); } @@ -89,6 +90,6 @@ pub const SndFile = struct { /// Like std.os.close, this function does not return /// any indication of failure. pub fn close(self: SndFile) void { - _ = sf_close(self.pimpl); + assert(sf_close(self.pimpl) == 0); } }; diff --git a/src/main.zig b/src/zeal.zig index 7e8d8c5..d73c674 100644 --- a/src/main.zig +++ b/src/zeal.zig @@ -23,6 +23,10 @@ pub const alc = @import("alc.zig"); const sf = @import("sf.zig"); const std = @import("std"); +pub const Error = al.Error || error { + UncurrentContext, +}; + pub const Device = struct { pimpl: *alc.Device, @@ -55,7 +59,8 @@ pub const Context = struct { pub fn useContext(context: ?Context) alc.Error!void { try alc.makeContextCurrent(if (context == null) null else context.?.pimpl); } -pub fn currentContext() alc.Error!?Context { + +pub fn currentContext() ?alc.Error!Context { if (alc.getCurrentContext()) |pimpl| return Context { .pimpl = pimpl, @@ -72,12 +77,12 @@ fn checkContext(context: Context) !void { pub const Listener = struct { context: Context, - pub fn setPosition(self: Listener, position: [3]f32) !void { + pub fn setPosition(self: Listener, position: [3]f32) Error!void { try checkContext(self.context); try al.listener.set(al.POSITION, position); } - pub fn setOrientation(self: Listener, at: [3]f32, up: [3]f32) !void { + pub fn setOrientation(self: Listener, at: [3]f32, up: [3]f32) Error!void { try checkContext(self.context); const orientation = [_]f32{ at[0], at[1], at[2], up[0], up[1], up[2] }; try al.listener.set(al.ORIENTATION, orientation); @@ -89,7 +94,7 @@ pub const Buffer = struct { reference: u32, pub fn init(allocator: *Allocator, context: Context, - name: [:0]const u8) !Buffer { + name: [:0]const u8) (Error || sf.Error)!Buffer { try checkContext(context); const snd_file = try SndFile.open(name, sf.Mode.read); defer snd_file.close(); @@ -106,7 +111,7 @@ pub const Buffer = struct { return Buffer{ .context = context, .reference = reference }; } - pub fn deinit(self: Buffer) !void { + pub fn deinit(self: Buffer) Error!void { try checkContext(self.context); try al.buffer.destroy(&self.reference); } @@ -116,29 +121,29 @@ pub const Source = struct { context: Context, reference: u32, - pub fn init(context: Context) !Source { + pub fn init(context: Context) Error!Source { try checkContext(context); const reference = try al.source.create(); return Source{ .context = context, .reference = reference }; } - pub fn deinit(self: Source) !void { + pub fn deinit(self: Source) Error!void { try checkContext(self.context); try al.source.destroy(&self.reference); } - pub fn isPlaying(self: Source) !bool { + pub fn isPlaying(self: Source) Error!bool { try checkContext(self.context); const state = try al.source.get(i32, self.reference, al.SOURCE_STATE); return state == al.PLAYING; } - pub fn getSecOffset(self: Source) !f32 { + pub fn getSecOffset(self: Source) Error!f32 { try checkContext(self.context); return try al.source.get(f32, self.reference, al.SEC_OFFSET); } - pub fn play(self: Source, buffer: Buffer) !void { + pub fn play(self: Source, buffer: Buffer) Error!void { try checkContext(self.context); try al.source.set(self.reference, al.BUFFER, @intCast(i32, buffer.reference)); @@ -151,8 +156,7 @@ test "Device" { try device.deinit(); } -const testing = std.testing; -const expectEqual = testing.expectEqual; +const expectEqual = std.testing.expectEqual; test "Context" { const device = try Device.init(null); @@ -160,13 +164,13 @@ test "Context" { const context = try Context.init(device, &.{ alc.HRTF, alc.TRUE }); defer context.deinit() catch unreachable; - try expectEqual(try currentContext(), null); + try expectEqual(currentContext(), null); if (checkContext(context)) unreachable else |err| switch (err) { error.UncurrentContext => {}, } try useContext(context); - const current_context = (try currentContext()).?; + const current_context = try currentContext().?; try expectEqual(current_context, context); try expectEqual(current_context.device, device); try checkContext(context); |