use crate::{RangeError, SettingsError, SynthDescriptor};
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum InterpolationMethod {
None = 0,
Linear = 1,
#[default]
FourthOrder = 4,
SeventhOrder = 7,
}
pub(crate) struct Settings {
pub reverb_active: bool,
pub chorus_active: bool,
pub drums_channel_active: bool,
pub interpolation: InterpolationMethod,
pub polyphony: u16,
pub midi_channels: u8,
pub gain: f32,
pub audio_channels: u8,
pub audio_groups: u8,
pub sample_rate: f32,
pub min_note_length: u16,
pub min_note_length_ticks: usize,
}
struct Range<T> {
min: T,
max: T,
}
impl<T: PartialOrd + Copy> Range<T> {
fn check(&self, v: T) -> Result<T, RangeError<T>> {
if v < self.min {
Err(RangeError::ToSmall {
got: v,
min: self.min,
})
} else if v > self.max {
Err(RangeError::ToBig {
got: v,
max: self.max,
})
} else {
Ok(v)
}
}
}
static POLYPHONY_RANGE: Range<u16> = Range { min: 1, max: 65535 };
static GAIN_RANGE: Range<f32> = Range {
min: 0.0,
max: 10.0,
};
static AUDIO_CHANNELS_RANGE: Range<u8> = Range { min: 1, max: 128 };
static AUDIO_GROUPS_RANGE: Range<u8> = Range { min: 1, max: 128 };
static SAMPLE_RATE_RANGE: Range<f32> = Range {
min: 8000.0,
max: 96000.0,
};
impl Settings {
fn cals_min_note_length_ticks(&mut self) {
self.min_note_length_ticks =
(self.min_note_length as f32 * self.sample_rate / 1000.0) as usize;
}
pub fn set_sample_rate(&mut self, sample_rate: f32) {
self.sample_rate = sample_rate;
self.cals_min_note_length_ticks();
}
}
impl TryFrom<SynthDescriptor> for Settings {
type Error = SettingsError;
fn try_from(desc: SynthDescriptor) -> Result<Self, Self::Error> {
let midi_channels = if desc.midi_channels % 16 != 0 {
log::warn!("Requested number of MIDI channels is not a multiple of 16. Increase the number of channels to the next multiple.");
return Err(SettingsError::MidiChannelsIsNotMultipleOf16);
} else {
desc.midi_channels
};
let polyphony = POLYPHONY_RANGE
.check(desc.polyphony)
.map_err(SettingsError::PolyphonyRange)?;
let gain = GAIN_RANGE
.check(desc.gain)
.map_err(SettingsError::GainRange)?;
let audio_channels = AUDIO_CHANNELS_RANGE
.check(desc.audio_channels)
.map_err(SettingsError::AudioChannelRange)?;
let audio_groups = AUDIO_GROUPS_RANGE
.check(desc.audio_groups)
.map_err(SettingsError::AudioGroupsRange)?;
let sample_rate = SAMPLE_RATE_RANGE
.check(desc.sample_rate)
.map_err(SettingsError::SammpleRateRange)?;
let min_note_length = desc.min_note_length;
let mut settings = Self {
reverb_active: desc.reverb_active,
chorus_active: desc.chorus_active,
drums_channel_active: desc.drums_channel_active,
interpolation: desc.interpolation,
polyphony,
midi_channels,
gain,
audio_channels,
audio_groups,
sample_rate,
min_note_length,
min_note_length_ticks: 0,
};
settings.cals_min_note_length_ticks();
Ok(settings)
}
}