From de18cedd3a52caa96ff21604634a898abf19d7cc Mon Sep 17 00:00:00 2001 From: PolyMeilex Date: Sun, 29 Dec 2024 19:59:20 +0100 Subject: [PATCH] Add initial channel InterpolationMethod setting --- oxisynth/src/core/channel_pool/channel.rs | 17 ++----------- oxisynth/src/core/channel_pool/mod.rs | 17 ++++++++++--- oxisynth/src/core/mod.rs | 4 +-- oxisynth/src/core/settings.rs | 20 +++++++++++++++ oxisynth/src/core/voice_pool/voice/mod.rs | 31 ++++++++++------------- oxisynth/src/lib.rs | 5 +++- 6 files changed, 55 insertions(+), 39 deletions(-) diff --git a/oxisynth/src/core/channel_pool/channel.rs b/oxisynth/src/core/channel_pool/channel.rs index c14773a..2c181f9 100644 --- a/oxisynth/src/core/channel_pool/channel.rs +++ b/oxisynth/src/core/channel_pool/channel.rs @@ -4,24 +4,11 @@ use std::sync::Arc; use super::super::soundfont::{Preset, SoundFont}; use crate::arena::Index; +use crate::core::InterpolationMethod; use crate::midi_event::ControlFunction; use crate::GeneratorType; use crate::Tuning; -// Flags to choose the interpolation method -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum InterpolationMethod { - /// No interpolation: Fastest, but questionable audio quality - None = 0, - /// Straight-line interpolation: A bit slower, reasonable audio quality - Linear = 1, - /// Fourth-order interpolation: Requires 50% of the whole DSP processing time, good quality (default) - #[default] - FourthOrder = 4, - /// Seventh-order interpolation - SeventhOrder = 7, -} - #[derive(Clone)] struct CcList([u8; 128]); @@ -106,7 +93,7 @@ impl Channel { cc: CcList([0; 128]), bank_msb: 0, - interp_method: Default::default(), + interp_method: InterpolationMethod::default(), tuning: None, nrpn_select: 0, diff --git a/oxisynth/src/core/channel_pool/mod.rs b/oxisynth/src/core/channel_pool/mod.rs index 02b0367..4ac1513 100644 --- a/oxisynth/src/core/channel_pool/mod.rs +++ b/oxisynth/src/core/channel_pool/mod.rs @@ -1,14 +1,23 @@ mod channel; -pub use channel::{Channel, InterpolationMethod}; +pub(crate) use channel::Channel; use crate::OxiError; +use super::InterpolationMethod; + pub struct ChannelPool(Vec); impl ChannelPool { - pub fn new(len: usize) -> Self { - let channels = (0..len).map(Channel::new).collect(); - Self(channels) + pub fn new(len: usize, interpolation: InterpolationMethod) -> Self { + Self( + (0..len) + .map(|id| { + let mut ch = Channel::new(id); + ch.set_interp_method(interpolation); + ch + }) + .collect(), + ) } pub fn get(&self, id: usize) -> Result<&Channel, OxiError> { diff --git a/oxisynth/src/core/mod.rs b/oxisynth/src/core/mod.rs index 6713091..cb2c24f 100644 --- a/oxisynth/src/core/mod.rs +++ b/oxisynth/src/core/mod.rs @@ -7,7 +7,7 @@ mod settings; mod voice_pool; mod conv; -pub use channel_pool::InterpolationMethod; +pub use settings::InterpolationMethod; pub(crate) use settings::Settings; mod font_bank; @@ -65,7 +65,7 @@ impl Core { font_bank: FontBank::new(), - channels: ChannelPool::new(settings.midi_channels as usize), + channels: ChannelPool::new(settings.midi_channels as usize, settings.interpolation), voices: VoicePool::new(settings.polyphony as usize, settings.sample_rate), output: OutputBuffer::new(nbuf as usize), diff --git a/oxisynth/src/core/settings.rs b/oxisynth/src/core/settings.rs index bc25cd0..a5e4faa 100644 --- a/oxisynth/src/core/settings.rs +++ b/oxisynth/src/core/settings.rs @@ -1,10 +1,29 @@ use crate::{RangeError, SettingsError, SynthDescriptor}; +// Flags to choose the interpolation method +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum InterpolationMethod { + /// No interpolation: Fastest, but questionable audio quality + None = 0, + /// Straight-line interpolation: A bit slower, reasonable audio quality + Linear = 1, + /// Fourth-order interpolation: Requires 50% of the whole DSP processing time, good quality (default) + #[default] + FourthOrder = 4, + /// Seventh-order interpolation + SeventhOrder = 7, +} + pub(crate) struct Settings { pub reverb_active: bool, pub chorus_active: bool, pub drums_channel_active: bool, + /// Interpolation method/quality + // + /// Def: FourthOrder + pub interpolation: InterpolationMethod, + /// Def: 256 /// Min: 1 /// Max: 65535 @@ -122,6 +141,7 @@ impl TryFrom for Settings { reverb_active: desc.reverb_active, chorus_active: desc.chorus_active, drums_channel_active: desc.drums_channel_active, + interpolation: desc.interpolation, polyphony, midi_channels, diff --git a/oxisynth/src/core/voice_pool/voice/mod.rs b/oxisynth/src/core/voice_pool/voice/mod.rs index 8b05e95..cdb7167 100644 --- a/oxisynth/src/core/voice_pool/voice/mod.rs +++ b/oxisynth/src/core/voice_pool/voice/mod.rs @@ -5,26 +5,23 @@ pub use envelope::EnvelopeStep; use envelope::{Envelope, EnvelopePortion}; use crate::{ - core::{BUFSIZE, BUFSIZE_F32}, + core::{ + channel_pool::Channel, + conv::{ + act2hz, atten2amp, cb2amp, ct2hz, ct2hz_real, pan, tc2sec, tc2sec_attack, tc2sec_delay, + tc2sec_release, + }, + soundfont::{ + generator::{Generator, GeneratorList, GeneratorType}, + modulator::Mod, + Sample, + }, + write::FxBuf, + InterpolationMethod, BUFSIZE, BUFSIZE_F32, + }, midi_event::ControlFunction, }; -use super::super::{ - channel_pool::{Channel, InterpolationMethod}, - write::FxBuf, -}; - -use super::super::soundfont::{ - generator::{Generator, GeneratorList, GeneratorType}, - modulator::Mod, - Sample, -}; - -use super::super::conv::{ - act2hz, atten2amp, cb2amp, ct2hz, ct2hz_real, pan, tc2sec, tc2sec_attack, tc2sec_delay, - tc2sec_release, -}; - use soundfont::raw::{ControllerPalette, GeneralPalette}; type Phase = u64; diff --git a/oxisynth/src/lib.rs b/oxisynth/src/lib.rs index 7bffa36..467b505 100644 --- a/oxisynth/src/lib.rs +++ b/oxisynth/src/lib.rs @@ -17,7 +17,7 @@ mod midi_event; mod unsafe_stuff; pub use api::Tuning; -pub use core::{GeneratorType, Preset, SoundFont}; +pub use core::{GeneratorType, InterpolationMethod, Preset, SoundFont}; pub use error::{OxiError, RangeError, SettingsError}; pub use midi_event::MidiEvent; @@ -34,6 +34,8 @@ pub struct SynthDescriptor { pub reverb_active: bool, pub chorus_active: bool, pub drums_channel_active: bool, + // Interpolation method/quality + pub interpolation: InterpolationMethod, /// Def: 256 /// Min: 1 @@ -71,6 +73,7 @@ impl Default for SynthDescriptor { reverb_active: true, chorus_active: true, drums_channel_active: true, + interpolation: InterpolationMethod::default(), polyphony: 256, midi_channels: 16,