From 7315d1ab62b1605143f1f9be0538266938fde68f Mon Sep 17 00:00:00 2001 From: Ali Chraghi Date: Thu, 19 Jan 2023 17:34:21 +0330 Subject: [PATCH] sysaudio: access sample rate from field (except for jack) and add media role option --- libs/sysaudio/src/alsa.zig | 8 ++------ libs/sysaudio/src/dummy.zig | 34 ++++++++++++-------------------- libs/sysaudio/src/jack.zig | 2 ++ libs/sysaudio/src/main.zig | 20 ++++++++++++++++--- libs/sysaudio/src/pulseaudio.zig | 13 +++++------- libs/sysaudio/src/webaudio.zig | 8 ++------ 6 files changed, 41 insertions(+), 44 deletions(-) diff --git a/libs/sysaudio/src/alsa.zig b/libs/sysaudio/src/alsa.zig index 43ea52a8..de6d6ae8 100644 --- a/libs/sysaudio/src/alsa.zig +++ b/libs/sysaudio/src/alsa.zig @@ -422,11 +422,11 @@ pub const Context = struct { .mixer = mixer.?, .selem = selem.?, .mixer_elm = mixer_elm.?, - .sample_rate = sample_rate, .writeFn = writeFn, .user_data = options.user_data, .channels = device.channels, .format = format, + .sample_rate = sample_rate, .write_step = format.frameSize(device.channels.len), }; return .{ .alsa = player }; @@ -446,10 +446,10 @@ pub const Player = struct { mixer_elm: *c.snd_mixer_elem_t, writeFn: main.WriteFn, user_data: ?*anyopaque, - sample_rate: u24, channels: []main.Channel, format: main.Format, + sample_rate: u24, write_step: u8, pub fn deinit(self: *Player) void { @@ -557,10 +557,6 @@ pub const Player = struct { return @intToFloat(f32, vol) / @intToFloat(f32, max_vol - min_vol); } - - pub fn sampleRate(self: Player) u24 { - return self.sample_rate; - } }; fn freeDevice(allocator: std.mem.Allocator, device: main.Device) void { diff --git a/libs/sysaudio/src/dummy.zig b/libs/sysaudio/src/dummy.zig index 7a5bdeea..41e10c4a 100644 --- a/libs/sysaudio/src/dummy.zig +++ b/libs/sysaudio/src/dummy.zig @@ -3,9 +3,6 @@ const main = @import("main.zig"); const backends = @import("backends.zig"); const util = @import("util.zig"); -pub const min_sample_rate = 8_000; // Hz -pub const max_sample_rate = 5_644_800; // Hz - const dummy_playback = main.Device{ .id = "dummy-playback", .name = "Dummy Device", @@ -13,8 +10,8 @@ const dummy_playback = main.Device{ .channels = undefined, .formats = std.meta.tags(main.Format), .sample_rate = .{ - .min = min_sample_rate, - .max = max_sample_rate, + .min = main.min_sample_rate, + .max = main.max_sample_rate, }, }; @@ -25,8 +22,8 @@ const dummy_capture = main.Device{ .channels = undefined, .formats = std.meta.tags(main.Format), .sample_rate = .{ - .min = min_sample_rate, - .max = max_sample_rate, + .min = main.min_sample_rate, + .max = main.max_sample_rate, }, }; @@ -61,16 +58,15 @@ pub const Context = struct { try self.devices_info.list.append(self.allocator, dummy_playback); try self.devices_info.list.append(self.allocator, dummy_capture); - self.devices_info.list.items[0].channels = try self.allocator.alloc(main.Channel, 1); - self.devices_info.list.items[0].channels[0] = .{ - .id = .front_center, - }; - self.devices_info.list.items[1].channels = try self.allocator.alloc(main.Channel, 1); - self.devices_info.list.items[1].channels[0] = .{ - .id = .front_center, - }; + self.devices_info.setDefault(.playback, 0); self.devices_info.setDefault(.capture, 1); + + self.devices_info.list.items[0].channels = try self.allocator.alloc(main.Channel, 1); + self.devices_info.list.items[1].channels = try self.allocator.alloc(main.Channel, 1); + + self.devices_info.list.items[0].channels[0] = .{ .id = .front_center }; + self.devices_info.list.items[1].channels[0] = .{ .id = .front_center }; } pub fn devices(self: Context) []const main.Device { @@ -86,11 +82,11 @@ pub const Context = struct { var player = try self.allocator.create(Player); player.* = .{ .allocator = self.allocator, - .sample_rate = options.sample_rate, .is_paused = false, .vol = 1.0, .channels = device.channels, .format = options.format, + .sample_rate = options.sample_rate, .write_step = 0, }; return .{ .dummy = player }; @@ -99,12 +95,12 @@ pub const Context = struct { pub const Player = struct { allocator: std.mem.Allocator, - sample_rate: u24, is_paused: bool, vol: f32, channels: []main.Channel, format: main.Format, + sample_rate: u24, write_step: u8, pub fn deinit(self: *Player) void { @@ -134,10 +130,6 @@ pub const Player = struct { pub fn volume(self: Player) !f32 { return self.vol; } - - pub fn sampleRate(self: Player) u24 { - return self.sample_rate; - } }; fn freeDevice(allocator: std.mem.Allocator, device: main.Device) void { diff --git a/libs/sysaudio/src/jack.zig b/libs/sysaudio/src/jack.zig index a14bfb99..4895fce2 100644 --- a/libs/sysaudio/src/jack.zig +++ b/libs/sysaudio/src/jack.zig @@ -206,10 +206,12 @@ pub const Player = struct { fn processCallback(n_frames: c.jack_nframes_t, self_opaque: ?*anyopaque) callconv(.C) c_int { const self = @ptrCast(*Player, @alignCast(@alignOf(*Player), self_opaque.?)); + for (self.channels) |*ch, i| { ch.*.ptr = @ptrCast([*]u8, c.jack_port_get_buffer(self.ports[i], n_frames)); } self.writeFn(self.user_data, n_frames); + return 0; } diff --git a/libs/sysaudio/src/main.zig b/libs/sysaudio/src/main.zig index c9b71393..fcfe58b1 100644 --- a/libs/sysaudio/src/main.zig +++ b/libs/sysaudio/src/main.zig @@ -5,6 +5,8 @@ const backends = @import("backends.zig"); pub const default_sample_rate = 44_100; // Hz pub const default_latency = 500 * std.time.us_per_ms; // μs +pub const min_sample_rate = 8_000; // Hz +pub const max_sample_rate = 5_644_800; // Hz pub const Backend = backends.Backend; pub const DeviceChangeFn = *const fn (self: ?*anyopaque) void; @@ -104,9 +106,18 @@ pub const Player = struct { pub const Options = struct { format: Format = .f32, sample_rate: u24 = default_sample_rate, + media_role: MediaRole = .default, user_data: ?*anyopaque = null, }; + pub const MediaRole = enum { + default, + game, + music, + movie, + communication, + }; + data: backends.BackendPlayer, pub fn deinit(self: Player) void { @@ -185,7 +196,7 @@ pub const Player = struct { pub fn write(self: Player, channel: Channel, frame: usize, sample: anytype) void { switch (@TypeOf(sample)) { - f32, u8, i8, i16, i24, i32 => {}, + u8, i8, i16, i24, i32, f32 => {}, else => @compileError( \\invalid sample type. supported types are: \\u8, i8, i16, i24, i32, f32 @@ -239,8 +250,11 @@ pub const Player = struct { } pub fn sampleRate(self: Player) u24 { - return switch (self.data) { - inline else => |b| b.sampleRate(), + return if (@hasField(Backend, "jack")) switch (self.data) { + .jack => |b| b.sampleRate(), + inline else => |b| b.sample_rate, + } else switch (self.data) { + inline else => |b| b.sample_rate, }; } diff --git a/libs/sysaudio/src/pulseaudio.zig b/libs/sysaudio/src/pulseaudio.zig index a809cb76..231f133e 100644 --- a/libs/sysaudio/src/pulseaudio.zig +++ b/libs/sysaudio/src/pulseaudio.zig @@ -282,11 +282,11 @@ pub const Context = struct { .stream = stream.?, .write_ptr = undefined, .vol = 1.0, - .sample_rate = sample_rate, .writeFn = writeFn, .user_data = options.user_data, .channels = device.channels, .format = format, + .sample_rate = sample_rate, .write_step = format.frameSize(device.channels.len), }; return .{ .pulseaudio = player }; @@ -329,24 +329,25 @@ pub const Player = struct { stream: *c.pa_stream, write_ptr: [*]u8, vol: f32, - sample_rate: u24, writeFn: main.WriteFn, user_data: ?*anyopaque, channels: []main.Channel, format: main.Format, + sample_rate: u24, write_step: u8, pub fn deinit(self: *Player) void { c.pa_threaded_mainloop_lock(self.main_loop); - defer c.pa_threaded_mainloop_unlock(self.main_loop); - c.pa_stream_set_write_callback(self.stream, null, null); c.pa_stream_set_state_callback(self.stream, null, null); c.pa_stream_set_underflow_callback(self.stream, null, null); c.pa_stream_set_overflow_callback(self.stream, null, null); _ = c.pa_stream_disconnect(self.stream); c.pa_stream_unref(self.stream); + c.pa_threaded_mainloop_unlock(self.main_loop); + + self.allocator.destroy(self); } pub fn start(self: *Player) !void { @@ -475,10 +476,6 @@ pub const Player = struct { self.vol = @intToFloat(f32, info.*.volume.values[0]) / @intToFloat(f32, c.PA_VOLUME_NORM); } - - pub fn sampleRate(self: Player) u24 { - return self.sample_rate; - } }; fn freeDevice(allocator: std.mem.Allocator, device: main.Device) void { diff --git a/libs/sysaudio/src/webaudio.zig b/libs/sysaudio/src/webaudio.zig index a2c18326..8ed4d873 100644 --- a/libs/sysaudio/src/webaudio.zig +++ b/libs/sysaudio/src/webaudio.zig @@ -112,9 +112,9 @@ pub const Context = struct { .is_paused = false, .writeFn = writeFn, .user_data = options.user_data, - .sample_rate = options.sample_rate, .channels = device.channels, .format = .f32, + .sample_rate = options.sample_rate, .write_step = @sizeOf(f32), }; @@ -138,10 +138,10 @@ pub const Player = struct { is_paused: bool, writeFn: main.WriteFn, user_data: ?*anyopaque, - sample_rate: u24, channels: []main.Channel, format: main.Format, + sample_rate: u24, write_step: u8, pub fn deinit(self: *Player) void { @@ -221,10 +221,6 @@ pub const Player = struct { defer gain.deinit(); return @floatCast(f32, gain.get("value").view(.num)); } - - pub fn sampleRate(self: Player) u24 { - return self.sample_rate; - } }; fn freeDevice(allocator: std.mem.Allocator, device: main.Device) void {