summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--build.zig11
-rw-r--r--src/al.zig189
-rw-r--r--src/alc.zig67
-rw-r--r--src/cimport.zig6
-rw-r--r--src/sf.zig35
-rw-r--r--src/zeal.zig4
6 files changed, 159 insertions, 153 deletions
diff --git a/build.zig b/build.zig
index 11c7deb..07007ad 100644
--- a/build.zig
+++ b/build.zig
@@ -35,16 +35,21 @@ fn addExampleStep(comptime name: []const u8, description: []const u8,
     b.step(name, description).dependOn(&cmd.step);
 }
 
+/// Link given library, executable, or object with shared libraries.
+pub fn link(lib_exe_obj: *LibExeObjStep) void {
+    lib_exe_obj.linkSystemLibrary("openal");
+    lib_exe_obj.linkSystemLibrary("sndfile");
+    lib_exe_obj.linkSystemLibrary("c");
+}
+
 pub fn build(b: *Builder) void {
     // Standard release options allow the person running `zig build` to select
     // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
     const mode = b.standardReleaseOptions();
 
     const lib = b.addStaticLibrary("zeal", "src/zeal.zig");
-    lib.linkSystemLibrary("openal");
-    lib.linkSystemLibrary("sndfile");
-    lib.linkSystemLibrary("c");
     lib.setBuildMode(mode);
+    link(lib);
     lib.install();
 
     var main_tests = b.addTest("src/zeal.zig");
diff --git a/src/al.zig b/src/al.zig
index a5164d6..5193df2 100644
--- a/src/al.zig
+++ b/src/al.zig
@@ -20,10 +20,7 @@ const Child = meta.Child;
 const Tag = meta.Tag;
 const meta = @import("std").meta;
 
-usingnamespace @cImport({
-    @cInclude("AL/al.h");
-    @cInclude("AL/alext.h");
-});
+const c = @import("cimport.zig");
 
 pub const Error = error {
     /// Bad name (ID) passed to an OpenAL function.
@@ -39,17 +36,17 @@ pub const Error = error {
 };
 
 // FIXME: turn into enum
-pub const FALSE = AL_FALSE;
-pub const TRUE = AL_TRUE;
-pub const AUTO = AL_AUTO_SOFT;
+pub const FALSE = c.AL_FALSE;
+pub const TRUE = c.AL_TRUE;
+pub const AUTO = c.AL_AUTO_SOFT;
 
 pub const listener = struct {
-    const Property = enum(ALenum) {
-        gain = AL_GAIN,
-        position = AL_POSITION,
-        velocity = AL_VELOCITY,
-        orientation = AL_ORIENTATION,
-        meters_per_unit = AL_METERS_PER_UNIT,
+    const Property = enum(c.ALenum) {
+        gain = c.AL_GAIN,
+        position = c.AL_POSITION,
+        velocity = c.AL_VELOCITY,
+        orientation = c.AL_ORIENTATION,
+        meters_per_unit = c.AL_METERS_PER_UNIT,
     };
 
     /// Set a property for the listener.
@@ -57,20 +54,20 @@ pub const listener = struct {
         const param = @enumToInt(property);
         const T = @TypeOf(value);
         switch (T) {
-            f32 => alListenerf(param, value),
-            i32 => alListeneri(param, value),
+            f32 => c.alListenerf(param, value),
+            i32 => c.alListeneri(param, value),
             else => switch (Child(T)) {
-                f32 => alListenerfv(param, value[0..]),
-                i32 => alListeneriv(param, value[0..]),
+                f32 => c.alListenerfv(param, value[0..]),
+                i32 => c.alListeneriv(param, value[0..]),
                 else => unreachable,
             }
         }
 
-        switch (alGetError()) {
-            AL_NO_ERROR => {},
-            AL_INVALID_VALUE => return Error.InvalidValue,
-            AL_INVALID_ENUM => return Error.InvalidEnum,
-            AL_INVALID_OPERATION => return Error.InvalidOperation,
+        switch (c.alGetError()) {
+            c.AL_NO_ERROR => {},
+            c.AL_INVALID_VALUE => return Error.InvalidValue,
+            c.AL_INVALID_ENUM => return Error.InvalidEnum,
+            c.AL_INVALID_OPERATION => return Error.InvalidOperation,
             else => unreachable,
         }
     }
@@ -91,11 +88,11 @@ 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,
+        c.alGenBuffers(1, &reference);
+        return switch (c.alGetError()) {
+            c.AL_NO_ERROR => reference,
+            c.AL_INVALID_VALUE => Error.InvalidValue,
+            c.AL_OUT_OF_MEMORY => Error.OutOfMemory,
             else => unreachable,
         };
     }
@@ -103,12 +100,12 @@ pub const buffer = struct {
     /// 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,
+        c.alDeleteBuffers(1, reference);
+        switch (c.alGetError()) {
+            c.AL_NO_ERROR => {},
+            c.AL_INVALID_OPERATION => return Error.InvalidOperation,
+            c.AL_INVALID_NAME => return Error.InvalidName,
+            c.AL_INVALID_VALUE => return Error.InvalidValue,
             else => unreachable,
         }
     }
@@ -116,28 +113,28 @@ pub const buffer = struct {
     /// 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,
+            .mono8 => c.AL_FORMAT_MONO8,
+            .mono16 => c.AL_FORMAT_MONO16,
+            .stereo8 => c.AL_FORMAT_STEREO8,
+            .stereo16 => c.AL_FORMAT_STEREO16,
         };
 
         switch (data) {
             .mono8, .stereo8 => |slice| {
                 const size = @intCast(c_int, slice.len);
-                alBufferData(reference, format, slice.ptr, size, freq);
+                c.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);
+                c.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,
+        switch (c.alGetError()) {
+            c.AL_NO_ERROR => {},
+            c.AL_OUT_OF_MEMORY => return Error.OutOfMemory,
+            c.AL_INVALID_VALUE => return Error.InvalidValue,
+            c.AL_INVALID_ENUM => return Error.InvalidEnum,
             else => unreachable,
         }
     }
@@ -147,11 +144,11 @@ 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,
+        c.alGenSources(1, &reference);
+        return switch (c.alGetError()) {
+            c.AL_NO_ERROR => reference,
+            c.AL_INVALID_VALUE => Error.InvalidValue,
+            c.AL_OUT_OF_MEMORY => Error.OutOfMemory,
             else => unreachable,
         };
     }
@@ -159,35 +156,35 @@ pub const source = struct {
     /// 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,
+        c.alDeleteSources(1, reference);
+        switch (c.alGetError()) {
+            c.AL_NO_ERROR => {},
+            c.AL_INVALID_OPERATION => return Error.InvalidOperation,
+            c.AL_INVALID_NAME => return Error.InvalidName,
+            c.AL_INVALID_VALUE => return Error.InvalidValue,
             else => unreachable,
         }
     }
 
-    const Property = enum(ALenum) {
-        pitch = AL_PITCH,
-        gain = AL_GAIN,
-        position = AL_POSITION,
-        velocity = AL_VELOCITY,
-        direction = AL_DIRECTION,
-        relative = AL_SOURCE_RELATIVE,
-        looping = AL_LOOPING,
-        buffer = AL_BUFFER,
-        state = AL_SOURCE_STATE,
-        sec_offset = AL_SEC_OFFSET,
-        spatialize = AL_SOURCE_SPATIALIZE_SOFT,
+    const Property = enum(c.ALenum) {
+        pitch = c.AL_PITCH,
+        gain = c.AL_GAIN,
+        position = c.AL_POSITION,
+        velocity = c.AL_VELOCITY,
+        direction = c.AL_DIRECTION,
+        relative = c.AL_SOURCE_RELATIVE,
+        looping = c.AL_LOOPING,
+        buffer = c.AL_BUFFER,
+        state = c.AL_SOURCE_STATE,
+        sec_offset = c.AL_SEC_OFFSET,
+        spatialize = c.AL_SOURCE_SPATIALIZE_SOFT,
     };
 
     pub const State = enum(i32) {
-        initial = AL_INITIAL,
-        playing = AL_PLAYING,
-        paused = AL_PAUSED,
-        stopped = AL_STOPPED,
+        initial = c.AL_INITIAL,
+        playing = c.AL_PLAYING,
+        paused = c.AL_PAUSED,
+        stopped = c.AL_STOPPED,
     };
 
     /// Set a property for the source.
@@ -195,24 +192,24 @@ pub const source = struct {
         const param = @enumToInt(property);
         const T = @TypeOf(value);
         switch (T) {
-            f32 => alSourcef(reference, param, value),
-            i32 => alSourcei(reference, param, value),
+            f32 => c.alSourcef(reference, param, value),
+            i32 => c.alSourcei(reference, param, value),
             else => switch (@typeInfo(T)) {
-                .Enum => alSourcei(reference, param, @enumToInt(value)),
+                .Enum => c.alSourcei(reference, param, @enumToInt(value)),
                 else => switch (Child(T)) {
-                    f32 => alSourcefv(reference, param, value[0..]),
-                    i32 => alSourceiv(reference, param, value[0..]),
+                    f32 => c.alSourcefv(reference, param, value[0..]),
+                    i32 => c.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,
+        switch (c.alGetError()) {
+            c.AL_NO_ERROR => {},
+            c.AL_INVALID_VALUE => return Error.InvalidValue,
+            c.AL_INVALID_ENUM => return Error.InvalidEnum,
+            c.AL_INVALID_NAME => return Error.InvalidName,
+            c.AL_INVALID_OPERATION => return Error.InvalidOperation,
             else => unreachable,
         }
     }
@@ -222,35 +219,35 @@ pub const source = struct {
         const param = @enumToInt(property);
         var value: T = undefined;
         switch (T) {
-            f32 => alGetSourcef(reference, param, &value),
-            i32 => alGetSourcei(reference, param, &value),
+            f32 => c.alGetSourcef(reference, param, &value),
+            i32 => c.alGetSourcei(reference, param, &value),
             else => switch (@typeInfo(T)) {
                 .Enum => {
                     var raw: i32 = undefined;
-                    alGetSourcei(reference, param, &raw);
+                    c.alGetSourcei(reference, param, &raw);
                     value = @intToEnum(T, raw);
                 },
                 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,
+        return switch (c.alGetError()) {
+            c.AL_NO_ERROR => value,
+            c.AL_INVALID_VALUE => return Error.InvalidValue,
+            c.AL_INVALID_ENUM => return Error.InvalidEnum,
+            c.AL_INVALID_NAME => return Error.InvalidName,
+            c.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,
+        c.alSourcePlay(reference);
+        switch (c.alGetError()) {
+            c.AL_NO_ERROR => {},
+            c.AL_INVALID_NAME => return Error.InvalidName,
+            c.AL_INVALID_OPERATION => return Error.InvalidOperation,
             else => unreachable,
         }
     }
diff --git a/src/alc.zig b/src/alc.zig
index ca83bf6..b493a78 100644
--- a/src/alc.zig
+++ b/src/alc.zig
@@ -16,15 +16,12 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with zeal.  If not, see <https://www.gnu.org/licenses/>.
 
-usingnamespace @cImport({
-    @cInclude("AL/alc.h");
-    @cInclude("AL/alext.h");
-});
+const c = @import("cimport.zig");
 
 /// Opaque device handle.
-pub const Device = ALCdevice;
+pub const Device = c.ALCdevice;
 /// Opaque context handle.
-pub const Context = ALCcontext;
+pub const Context = c.ALCcontext;
 
 pub const Error = error {
     /// Invalid device handle.
@@ -39,21 +36,21 @@ pub const Error = error {
     OutOfMemory,
 };
 
-pub const FALSE = ALC_FALSE;
-pub const TRUE = ALC_TRUE;
-pub const DONT_CARE  = ALC_DONT_CATE_SOFT;
+pub const FALSE = c.ALC_FALSE;
+pub const TRUE = c.ALC_TRUE;
+pub const DONT_CARE  = c.ALC_DONT_CATE_SOFT;
 
 /// Context creation key to specify whether to enable HRTF
 /// (either `FALSE`, `TRUE` or `DONT_CARE`).
-pub const HRTF = ALC_HRTF_SOFT;
+pub const HRTF = c.ALC_HRTF_SOFT;
 
 /// Create and attach a context to the given device.
 pub fn createContext(device: *Device, attrlist: [:0]const i32) Error!*Context {
-    if (alcCreateContext(device, attrlist.ptr)) |context|
+    if (c.alcCreateContext(device, attrlist.ptr)) |context|
         return context;
-    return switch (alcGetError(device)) {
-        ALC_INVALID_DEVICE => Error.InvalidDevice,
-        ALC_INVALID_VALUE => Error.InvalidValue,
+    return switch (c.alcGetError(device)) {
+        c.ALC_INVALID_DEVICE => Error.InvalidDevice,
+        c.ALC_INVALID_VALUE => Error.InvalidValue,
         else => unreachable,
     };
 }
@@ -61,30 +58,30 @@ pub fn createContext(device: *Device, attrlist: [:0]const i32) Error!*Context {
 /// Make the given context the active process-wide context.
 /// Passing NULL clears the active context.
 pub fn makeContextCurrent(context: ?*Context) Error!void {
-    if (alcMakeContextCurrent(context) == TRUE)
+    if (c.alcMakeContextCurrent(context) == TRUE)
         return;
-    if (alcGetError(null) == ALC_INVALID_CONTEXT)
+    if (c.alcGetError(null) == c.ALC_INVALID_CONTEXT)
         return Error.InvalidContext;
     unreachable;
 }
 
 /// Remove a context from its device and destroys it.
 pub fn destroyContext(context: *Context) Error!void {
-    alcDestroyContext(context);
-    if (alcGetError(null) == ALC_INVALID_CONTEXT)
+    c.alcDestroyContext(context);
+    if (c.alcGetError(null) == c.ALC_INVALID_CONTEXT)
         return Error.InvalidContext;
 }
 
 /// Return the currently active context.
 pub fn getCurrentContext() ?*Context {
-    return alcGetCurrentContext();
+    return c.alcGetCurrentContext();
 }
 
 /// Return the device that a particular context is attached to.
 pub fn getContextsDevice(context: *Context) Error!*Device {
-    if (alcGetContextsDevice(context)) |device|
+    if (c.alcGetContextsDevice(context)) |device|
         return device;
-    if (alcGetError(null) == ALC_INVALID_CONTEXT)
+    if (c.alcGetError(null) == c.ALC_INVALID_CONTEXT)
         return Error.InvalidContext;
     unreachable;
 }
@@ -92,33 +89,33 @@ pub fn getContextsDevice(context: *Context) Error!*Device {
 /// Open the named playback 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|
+    if (c.alcOpenDevice(name_ptr)) |device|
         return device;
-    return switch (alcGetError(null)) {
-        ALC_INVALID_VALUE => Error.InvalidValue,
-        ALC_OUT_OF_MEMORY => Error.OutOfMemory,
+    return switch (c.alcGetError(null)) {
+        c.ALC_INVALID_VALUE => Error.InvalidValue,
+        c.ALC_OUT_OF_MEMORY => Error.OutOfMemory,
         else => unreachable,
     };
 }
 
 /// Close the given playback device.
 pub fn closeDevice(device: *Device) Error!void {
-    if (alcCloseDevice(device) == TRUE)
+    if (c.alcCloseDevice(device) == TRUE)
         return;
-    if (alcGetError(device) == ALC_INVALID_DEVICE)
+    if (c.alcGetError(device) == c.ALC_INVALID_DEVICE)
         return Error.InvalidDevice;
     unreachable;
 }
 
-pub fn getInt(device: *Device, param: ALCenum) Error!i32 {
+pub fn getInt(device: *Device, param: c.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,
+    c.alcGetIntegerv(device, param, 1, &data);
+    return switch (c.alcGetError(device)) {
+        c.ALC_NO_ERROR => data,
+        c.ALC_INVALID_VALUE => Error.InvalidValue,
+        c.ALC_INVALID_ENUM => Error.InvalidEnum,
+        c.ALC_INVALID_DEVICE => Error.InvalidDevice,
+        c.ALC_INVALID_CONTEXT => Error.InvalidContext,
         else => unreachable,
     };
 }
diff --git a/src/cimport.zig b/src/cimport.zig
new file mode 100644
index 0000000..dc19cc9
--- /dev/null
+++ b/src/cimport.zig
@@ -0,0 +1,6 @@
+usingnamespace @cImport({
+    @cInclude("AL/al.h");
+    @cInclude("AL/alc.h");
+    @cInclude("AL/alext.h");
+    @cInclude("sndfile.h");
+});
diff --git a/src/sf.zig b/src/sf.zig
index 80cfd9e..96568b6 100644
--- a/src/sf.zig
+++ b/src/sf.zig
@@ -20,7 +20,7 @@ const Allocator = std.mem.Allocator;
 const assert = std.debug.assert;
 const std = @import("std");
 
-usingnamespace @cImport(@cInclude("sndfile.h"));
+const c = @import("cimport.zig");
 
 pub const Mode = enum {
     read,
@@ -36,7 +36,7 @@ pub const Error = Allocator.Error || error {
 };
 
 pub const SndFile = struct {
-    pimpl: *SNDFILE,
+    pimpl: *c.SNDFILE,
     frames: usize,
     sample_rate: c_int,
     channels: c_int,
@@ -47,20 +47,21 @@ pub const SndFile = struct {
     /// Open the sound file at the specified path.
     pub fn open(path: [:0]const u8, mode: Mode) Error!SndFile {
         const c_mode = switch (mode) {
-            .read => SFM_READ,
-            .write => SFM_WRITE,
-            .read_write => SFM_RDWR,
+            .read => c.SFM_READ,
+            .write => c.SFM_WRITE,
+            .read_write => c.SFM_RDWR,
         };
 
-        var info: SF_INFO = undefined;
-        const pimpl = sf_open(path.ptr, c_mode, &info);
-        _ = sf_command(pimpl, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE);
+        var info: c.SF_INFO = undefined;
+        const pimpl = c.sf_open(path.ptr, c_mode, &info);
+        _ = c.sf_command(pimpl, c.SFC_SET_SCALE_FLOAT_INT_READ,
+                         null, c.SF_TRUE);
         return SndFile {
-            .pimpl = pimpl orelse return switch (sf_error(null)) {
-                SF_ERR_UNRECOGNISED_FORMAT => Error.UnrecognizedFormat,
-                SF_ERR_SYSTEM => Error.SystemError,
-                SF_ERR_MALFORMED_FILE => Error.MalformedFile,
-                SF_ERR_UNSUPPORTED_ENCODING => Error.UnsupportedEncoding,
+            .pimpl = pimpl orelse return switch (c.sf_error(null)) {
+                c.SF_ERR_UNRECOGNISED_FORMAT => Error.UnrecognizedFormat,
+                c.SF_ERR_SYSTEM => Error.SystemError,
+                c.SF_ERR_MALFORMED_FILE => Error.MalformedFile,
+                c.SF_ERR_UNSUPPORTED_ENCODING => Error.UnsupportedEncoding,
                 else => unreachable,
             },
             .frames = @intCast(usize, info.frames),
@@ -74,17 +75,17 @@ 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,
+    pub fn read(self: SndFile, allocator: Allocator,
                 frames: usize) Error![]const i16 {
         const items = frames * @intCast(usize, self.channels);
         const memory = try allocator.alloc(i16, items);
         errdefer allocator.free(memory);
-        const n = sf_read_short(self.pimpl, memory.ptr, @intCast(i64, items));
+        const n = c.sf_read_short(self.pimpl, memory.ptr, @intCast(i64, items));
         return try allocator.realloc(memory, @intCast(usize, n));
     }
 
     /// Read the entire file.  The returned memory is managed by the caller.
-    pub fn readAll(self: SndFile, allocator: *Allocator) Error![]const i16 {
+    pub fn readAll(self: SndFile, allocator: Allocator) Error![]const i16 {
         return self.read(allocator, self.frames);
     }
 
@@ -92,6 +93,6 @@ pub const SndFile = struct {
     /// Like std.os.close, this function does not return
     /// any indication of failure.
     pub fn close(self: SndFile) void {
-        assert(sf_close(self.pimpl) == 0);
+        assert(c.sf_close(self.pimpl) == 0);
     }
 };
diff --git a/src/zeal.zig b/src/zeal.zig
index b3126ec..7dc82c5 100644
--- a/src/zeal.zig
+++ b/src/zeal.zig
@@ -99,12 +99,12 @@ pub const listener = struct {
 };
 
 pub const Audio = struct {
-    allocator: *Allocator,
+    allocator: Allocator,
     data: al.Data,
     frequency: i32,
 
     /// Read audio from file.
-    pub fn read(allocator: *Allocator, path: [:0]const u8) sf.Error!Audio {
+    pub fn read(allocator: Allocator, path: [:0]const u8) sf.Error!Audio {
         const sound = try SndFile.open(path, sf.Mode.read);
         defer sound.close();
         const data = try sound.readAll(allocator);