use core::ffi::c_int;
use bela_sys::BelaInitSettings;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Settings {
period_size: Option<u32>,
use_analog: Option<bool>,
use_digital: Option<bool>,
num_analog_in_channels: Option<u32>,
num_analog_out_channels: Option<u32>,
num_digital_channels: Option<u32>,
detect_underruns: Option<bool>,
verbose: Option<bool>,
high_performance_mode: Option<bool>,
uniform_sample_rate: Option<bool>,
stop_button_pin: Option<i32>,
}
impl Settings {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub const fn period_size(mut self, frames: u32) -> Self {
self.period_size = Some(frames);
self
}
#[must_use]
pub const fn use_analog(mut self, enabled: bool) -> Self {
self.use_analog = Some(enabled);
self
}
#[must_use]
pub const fn use_digital(mut self, enabled: bool) -> Self {
self.use_digital = Some(enabled);
self
}
#[must_use]
pub const fn num_analog_in_channels(mut self, channels: u32) -> Self {
self.num_analog_in_channels = Some(channels);
self
}
#[must_use]
pub const fn num_analog_out_channels(mut self, channels: u32) -> Self {
self.num_analog_out_channels = Some(channels);
self
}
#[must_use]
pub const fn num_digital_channels(mut self, channels: u32) -> Self {
self.num_digital_channels = Some(channels);
self
}
#[must_use]
pub const fn detect_underruns(mut self, enabled: bool) -> Self {
self.detect_underruns = Some(enabled);
self
}
#[must_use]
pub const fn verbose(mut self, enabled: bool) -> Self {
self.verbose = Some(enabled);
self
}
#[must_use]
pub const fn high_performance_mode(mut self, enabled: bool) -> Self {
self.high_performance_mode = Some(enabled);
self
}
#[must_use]
pub const fn uniform_sample_rate(mut self, enabled: bool) -> Self {
self.uniform_sample_rate = Some(enabled);
self
}
#[must_use]
pub const fn stop_button_pin(mut self, pin: i32) -> Self {
self.stop_button_pin = Some(pin);
self
}
pub fn apply_to(&self, raw: &mut BelaInitSettings) {
if let Some(v) = self.period_size {
raw.periodSize = to_c_int(v);
}
if let Some(v) = self.use_analog {
raw.useAnalog = c_int::from(v);
}
if let Some(v) = self.use_digital {
raw.useDigital = c_int::from(v);
}
if let Some(v) = self.num_analog_in_channels {
raw.numAnalogInChannels = to_c_int(v);
}
if let Some(v) = self.num_analog_out_channels {
raw.numAnalogOutChannels = to_c_int(v);
}
if let Some(v) = self.num_digital_channels {
raw.numDigitalChannels = to_c_int(v);
}
if let Some(v) = self.detect_underruns {
raw.detectUnderruns = c_int::from(v);
}
if let Some(v) = self.verbose {
raw.verbose = c_int::from(v);
}
if let Some(v) = self.high_performance_mode {
raw.highPerformanceMode = c_int::from(v);
}
if let Some(v) = self.uniform_sample_rate {
raw.uniformSampleRate = c_int::from(v);
}
if let Some(v) = self.stop_button_pin {
raw.stopButtonPin = v;
}
}
}
fn to_c_int(value: u32) -> c_int {
c_int::try_from(value).unwrap_or(c_int::MAX)
}
#[cfg(test)]
mod tests {
use core::mem;
use super::*;
fn fake_defaults() -> BelaInitSettings {
let mut raw: BelaInitSettings = unsafe { mem::zeroed() };
raw.periodSize = 16;
raw.useAnalog = 1;
raw.uniformSampleRate = 1;
raw.stopButtonPin = 115;
raw.verbose = 0;
raw
}
#[test]
fn empty_settings_leave_defaults_untouched() {
let mut raw = fake_defaults();
Settings::new().apply_to(&mut raw);
assert_eq!(raw.periodSize, 16);
assert_eq!(raw.useAnalog, 1);
assert_eq!(raw.uniformSampleRate, 1);
assert_eq!(raw.stopButtonPin, 115);
}
#[test]
fn set_fields_override_defaults() {
let mut raw = fake_defaults();
Settings::new()
.period_size(64)
.use_analog(false)
.verbose(true)
.stop_button_pin(-1)
.apply_to(&mut raw);
assert_eq!(raw.periodSize, 64);
assert_eq!(raw.useAnalog, 0);
assert_eq!(raw.verbose, 1);
assert_eq!(raw.stopButtonPin, -1);
assert_eq!(raw.uniformSampleRate, 1);
}
#[test]
fn bools_map_to_c_ints() {
let mut raw = fake_defaults();
Settings::new()
.use_digital(true)
.detect_underruns(false)
.high_performance_mode(true)
.uniform_sample_rate(false)
.apply_to(&mut raw);
assert_eq!(raw.useDigital, 1);
assert_eq!(raw.detectUnderruns, 0);
assert_eq!(raw.highPerformanceMode, 1);
assert_eq!(raw.uniformSampleRate, 0);
}
}