audio: reduce alsa and pulseaudio latency to 30ms
Closes #928 Change contributed by Ali in https://github.com/hexops/mach/pull/1138 I am just cleaning up the commit. Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
74595362d3
commit
b0d6c88f3b
2 changed files with 11 additions and 8 deletions
|
|
@ -7,7 +7,7 @@ const conv = @import("conv.zig");
|
||||||
pub const Backend = backends.Backend;
|
pub const Backend = backends.Backend;
|
||||||
pub const Range = util.Range;
|
pub const Range = util.Range;
|
||||||
|
|
||||||
pub const default_latency = 500 * std.time.us_per_ms; // μs
|
pub const default_latency = 30 * std.time.us_per_ms; // μs
|
||||||
pub const min_sample_rate = 8_000; // Hz
|
pub const min_sample_rate = 8_000; // Hz
|
||||||
pub const max_sample_rate = 5_644_800; // Hz
|
pub const max_sample_rate = 5_644_800; // Hz
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,9 @@ const Lib = struct {
|
||||||
pa_cvolume_set: *const fn ([*c]c.pa_cvolume, c_uint, c.pa_volume_t) callconv(.C) [*c]c.pa_cvolume,
|
pa_cvolume_set: *const fn ([*c]c.pa_cvolume, c_uint, c.pa_volume_t) callconv(.C) [*c]c.pa_cvolume,
|
||||||
pa_sw_volume_from_linear: *const fn (f64) callconv(.C) c.pa_volume_t,
|
pa_sw_volume_from_linear: *const fn (f64) callconv(.C) c.pa_volume_t,
|
||||||
|
|
||||||
|
pa_usec_to_bytes: *const fn (t: c.pa_usec_t, spec: [*c]const c.pa_sample_spec) usize,
|
||||||
|
pa_stream_get_sample_spec: *const fn (s: ?*c.pa_stream) [*c]const c.pa_sample_spec,
|
||||||
|
|
||||||
pub fn load() !void {
|
pub fn load() !void {
|
||||||
lib.handle = std.DynLib.openZ("libpulse.so") catch return error.LibraryNotFound;
|
lib.handle = std.DynLib.openZ("libpulse.so") catch return error.LibraryNotFound;
|
||||||
inline for (@typeInfo(Lib).Struct.fields[1..]) |field| {
|
inline for (@typeInfo(Lib).Struct.fields[1..]) |field| {
|
||||||
|
|
@ -311,9 +314,10 @@ pub const Context = struct {
|
||||||
var status: StreamStatus = .{ .main_loop = ctx.main_loop, .status = .unknown };
|
var status: StreamStatus = .{ .main_loop = ctx.main_loop, .status = .unknown };
|
||||||
lib.pa_stream_set_state_callback(stream, streamStateOp, &status);
|
lib.pa_stream_set_state_callback(stream, streamStateOp, &status);
|
||||||
|
|
||||||
|
const buffer_len = lib.pa_usec_to_bytes(main.default_latency, lib.pa_stream_get_sample_spec(stream));
|
||||||
const buf_attr = c.pa_buffer_attr{
|
const buf_attr = c.pa_buffer_attr{
|
||||||
.maxlength = std.math.maxInt(u32),
|
.maxlength = std.math.maxInt(u32),
|
||||||
.tlength = std.math.maxInt(u32),
|
.tlength = @intCast(buffer_len),
|
||||||
.prebuf = 0,
|
.prebuf = 0,
|
||||||
.minreq = std.math.maxInt(u32),
|
.minreq = std.math.maxInt(u32),
|
||||||
.fragsize = std.math.maxInt(u32),
|
.fragsize = std.math.maxInt(u32),
|
||||||
|
|
@ -322,8 +326,7 @@ pub const Context = struct {
|
||||||
const flags =
|
const flags =
|
||||||
c.PA_STREAM_START_CORKED |
|
c.PA_STREAM_START_CORKED |
|
||||||
c.PA_STREAM_AUTO_TIMING_UPDATE |
|
c.PA_STREAM_AUTO_TIMING_UPDATE |
|
||||||
c.PA_STREAM_INTERPOLATE_TIMING |
|
c.PA_STREAM_INTERPOLATE_TIMING;
|
||||||
c.PA_STREAM_ADJUST_LATENCY;
|
|
||||||
|
|
||||||
if (lib.pa_stream_connect_playback(stream, device.id.ptr, &buf_attr, flags, null, null) != 0) {
|
if (lib.pa_stream_connect_playback(stream, device.id.ptr, &buf_attr, flags, null, null) != 0) {
|
||||||
return error.OpeningDevice;
|
return error.OpeningDevice;
|
||||||
|
|
@ -378,19 +381,19 @@ pub const Context = struct {
|
||||||
var status: StreamStatus = .{ .main_loop = ctx.main_loop, .status = .unknown };
|
var status: StreamStatus = .{ .main_loop = ctx.main_loop, .status = .unknown };
|
||||||
lib.pa_stream_set_state_callback(stream, streamStateOp, &status);
|
lib.pa_stream_set_state_callback(stream, streamStateOp, &status);
|
||||||
|
|
||||||
|
const buffer_len = lib.pa_usec_to_bytes(main.default_latency, lib.pa_stream_get_sample_spec(stream));
|
||||||
const buf_attr = c.pa_buffer_attr{
|
const buf_attr = c.pa_buffer_attr{
|
||||||
.maxlength = std.math.maxInt(u32),
|
.maxlength = std.math.maxInt(u32),
|
||||||
.tlength = std.math.maxInt(u32),
|
.tlength = std.math.maxInt(u32),
|
||||||
.prebuf = 0,
|
.prebuf = std.math.maxInt(u32),
|
||||||
.minreq = std.math.maxInt(u32),
|
.minreq = std.math.maxInt(u32),
|
||||||
.fragsize = std.math.maxInt(u32),
|
.fragsize = @intCast(buffer_len),
|
||||||
};
|
};
|
||||||
|
|
||||||
const flags =
|
const flags =
|
||||||
c.PA_STREAM_START_CORKED |
|
c.PA_STREAM_START_CORKED |
|
||||||
c.PA_STREAM_AUTO_TIMING_UPDATE |
|
c.PA_STREAM_AUTO_TIMING_UPDATE |
|
||||||
c.PA_STREAM_INTERPOLATE_TIMING |
|
c.PA_STREAM_INTERPOLATE_TIMING;
|
||||||
c.PA_STREAM_ADJUST_LATENCY;
|
|
||||||
|
|
||||||
if (lib.pa_stream_connect_record(stream, device.id.ptr, &buf_attr, flags) != 0) {
|
if (lib.pa_stream_connect_record(stream, device.id.ptr, &buf_attr, flags) != 0) {
|
||||||
return error.OpeningDevice;
|
return error.OpeningDevice;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue