aboutsummaryrefslogtreecommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig76
1 files changed, 58 insertions, 18 deletions
diff --git a/src/main.zig b/src/main.zig
index 21e4f3a..7e8d8c5 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -16,16 +16,17 @@
// 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 al = @import("al.zig");
-const alc = @import("alc.zig");
-const expectEqual = std.testing.expectEqual;
-const eql = std.meta.eql;
+const Allocator = std.mem.Allocator;
+const SndFile = sf.SndFile;
+pub const al = @import("al.zig");
+pub const alc = @import("alc.zig");
+const sf = @import("sf.zig");
const std = @import("std");
pub const Device = struct {
pimpl: *alc.Device,
- pub fn init(name: ?[]const u8) alc.Error!Device {
+ pub fn init(name: ?[:0]const u8) alc.Error!Device {
return Device{ .pimpl = try alc.openDevice(name) };
}
@@ -87,15 +88,61 @@ pub const Buffer = struct {
context: Context,
reference: u32,
- pub fn init(context: Context, name: []const u8) !Buffer {
+ pub fn init(allocator: *Allocator, context: Context,
+ name: [:0]const u8) !Buffer {
try checkContext(context);
- const reference = try al.genBuffer();
+ const snd_file = try SndFile.open(name, sf.Mode.read);
+ defer snd_file.close();
+ const data = try snd_file.readAll(allocator);
+ defer allocator.free(data);
+ const al_data = switch (snd_file.channels) {
+ 1 => al.Data{ .mono16 = data },
+ 2 => al.Data{ .stereo16 = data },
+ else => unreachable,
+ };
+
+ const reference = try al.buffer.create();
+ try al.buffer.fill(reference, al_data, snd_file.sample_rate);
return Buffer{ .context = context, .reference = reference };
}
pub fn deinit(self: Buffer) !void {
try checkContext(self.context);
- try al.deleteBuffer(&self.reference);
+ try al.buffer.destroy(&self.reference);
+ }
+};
+
+pub const Source = struct {
+ context: Context,
+ reference: u32,
+
+ pub fn init(context: Context) !Source {
+ try checkContext(context);
+ const reference = try al.source.create();
+ return Source{ .context = context, .reference = reference };
+ }
+
+ pub fn deinit(self: Source) !void {
+ try checkContext(self.context);
+ try al.source.destroy(&self.reference);
+ }
+
+ pub fn isPlaying(self: Source) !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 {
+ try checkContext(self.context);
+ return try al.source.get(f32, self.reference, al.SEC_OFFSET);
+ }
+
+ pub fn play(self: Source, buffer: Buffer) !void {
+ try checkContext(self.context);
+ try al.source.set(self.reference, al.BUFFER,
+ @intCast(i32, buffer.reference));
+ try al.source.play(self.reference);
}
};
@@ -104,6 +151,9 @@ test "Device" {
try device.deinit();
}
+const testing = std.testing;
+const expectEqual = testing.expectEqual;
+
test "Context" {
const device = try Device.init(null);
defer device.deinit() catch unreachable;
@@ -132,13 +182,3 @@ test "Listener" {
try listener.setPosition(.{ 1, 2, 3 });
try listener.setOrientation(.{ 4, 5, 6 }, .{ 7, 8, 9 });
}
-
-test "Buffer" {
- const context = try Context.init(try Device.init(null), &.{});
- defer context.device.deinit() catch unreachable;
- defer context.deinit() catch unreachable;
-
- try useContext(context);
- const buffer = try Buffer.init(context, "");
- defer buffer.deinit() catch unreachable;
-}