more hardware detection and adjustment
All checks were successful
Generic zig build / build (push) Successful in 23s
All checks were successful
Generic zig build / build (push) Successful in 23s
This commit is contained in:
parent
1363b2bfc2
commit
b1c2ee20ff
1 changed files with 42 additions and 5 deletions
47
src/stt.zig
47
src/stt.zig
|
|
@ -454,19 +454,56 @@ pub const AlsaCapture = struct {
|
|||
self.sample_rate = actual_rate;
|
||||
}
|
||||
|
||||
// Set buffer size
|
||||
// Get hardware constraints for buffer size
|
||||
// SAFETY: this is set immediately as an out parameter in c API
|
||||
var min_buffer: c.snd_pcm_uframes_t = undefined;
|
||||
// SAFETY: this is set immediately as an out parameter in c API
|
||||
var max_buffer: c.snd_pcm_uframes_t = undefined;
|
||||
_ = c.snd_pcm_hw_params_get_buffer_size_min(hw_params, &min_buffer);
|
||||
_ = c.snd_pcm_hw_params_get_buffer_size_max(hw_params, &max_buffer);
|
||||
|
||||
// Calculate minimum buffer size for ~40ms of audio
|
||||
const calculated_min: u32 = @intCast((self.sample_rate * 40) / 1000);
|
||||
const target_buffer = @max(self.buffer_size, calculated_min);
|
||||
if (target_buffer < min_buffer) {
|
||||
std.log.info("Buffer size {} too small, using minimum {}", .{ target_buffer, min_buffer });
|
||||
self.buffer_size = @intCast(min_buffer);
|
||||
} else if (target_buffer > max_buffer) {
|
||||
std.log.info("Buffer size {} too large, using maximum {}", .{ target_buffer, max_buffer });
|
||||
self.buffer_size = @intCast(max_buffer);
|
||||
} else {
|
||||
self.buffer_size = @intCast(target_buffer);
|
||||
}
|
||||
|
||||
// Set buffer size first
|
||||
var actual_buffer_size: c.snd_pcm_uframes_t = self.buffer_size;
|
||||
err = c.snd_pcm_hw_params_set_buffer_size_near(self.pcm_handle, hw_params, &actual_buffer_size);
|
||||
if (err < 0) return Error.SetBufferSizeError;
|
||||
self.buffer_size = @intCast(actual_buffer_size);
|
||||
|
||||
// Set period size
|
||||
var actual_period_size: c.snd_pcm_uframes_t = self.period_size;
|
||||
err = c.snd_pcm_hw_params_set_period_size_near(self.pcm_handle, hw_params, &actual_period_size, null);
|
||||
// Set period time (in microseconds) instead of period size for better compatibility
|
||||
// Target ~10ms periods (10000 microseconds)
|
||||
var period_time: c_uint = std.time.us_per_ms * 10;
|
||||
var dir: c_int = 0;
|
||||
err = c.snd_pcm_hw_params_set_period_time_near(self.pcm_handle, hw_params, &period_time, &dir);
|
||||
if (err < 0) return Error.SetPeriodSizeError;
|
||||
|
||||
// Get the actual period size that was set
|
||||
// SAFETY: this is set immediately as an out parameter in c API
|
||||
var actual_period_size: c.snd_pcm_uframes_t = undefined;
|
||||
err = c.snd_pcm_hw_params_get_period_size(hw_params, &actual_period_size, null);
|
||||
if (err >= 0) {
|
||||
self.period_size = @intCast(actual_period_size);
|
||||
}
|
||||
|
||||
std.log.debug("ALSA params: rate={}, channels={}, buffer={}, period={}", .{ self.sample_rate, self.channels, actual_buffer_size, self.period_size });
|
||||
|
||||
// Apply hardware parameters
|
||||
err = c.snd_pcm_hw_params(self.pcm_handle, hw_params);
|
||||
if (err < 0) return Error.ApplyParametersError;
|
||||
if (err < 0) {
|
||||
std.log.err("snd_pcm_hw_params failed with error code: {}", .{err});
|
||||
return Error.ApplyParametersError;
|
||||
}
|
||||
|
||||
// Prepare the PCM for use
|
||||
err = c.snd_pcm_prepare(self.pcm_handle);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue