Skip to content

Commit

Permalink
Move write_voices out of VoicePool to write module
Browse files Browse the repository at this point in the history
  • Loading branch information
PolyMeilex committed Dec 29, 2024
1 parent 61c8061 commit e526d83
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 97 deletions.
3 changes: 3 additions & 0 deletions oxisynth/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ use self::font_bank::FontBank;

use crate::{SettingsError, SynthDescriptor};

const BUFSIZE: usize = 64;
const BUFSIZE_F32: f32 = BUFSIZE as f32;

pub(crate) struct Core {
ticks: usize,
pub font_bank: FontBank,
Expand Down
70 changes: 16 additions & 54 deletions oxisynth/src/core/voice_pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pub(crate) use voice::{EnvelopeStep, Voice, VoiceAddMode, VoiceDescriptor};

use super::channel_pool::Channel;
use super::soundfont::generator::GeneratorType;
use super::write::FxBuf;

#[derive(Copy, Clone)]
struct VoiceId(pub(crate) usize);
Expand All @@ -30,6 +29,10 @@ impl VoicePool {
}
}

pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Voice> {
self.voices.iter_mut()
}

pub fn noteid_add(&mut self) {
self.storeid = self.noteid;
self.noteid += 1;
Expand All @@ -48,11 +51,7 @@ impl VoicePool {
}

pub fn set_gen(&mut self, chan: usize, param: GeneratorType, value: f32) {
for voice in self
.voices
.iter_mut()
.filter(|v| v.get_channel_id() == chan)
{
for voice in self.voices.iter_mut().filter(|v| v.channel_id() == chan) {
voice.set_param(param, value, 0);
}
}
Expand All @@ -68,12 +67,12 @@ impl VoicePool {
.voices
.iter_mut()
.filter(|v| v.is_on())
.filter(|v| v.get_channel_id() == channel.id())
.filter(|v| v.channel_id() == channel.id())
.filter(|v| v.key() == key)
{
log::trace!(
"noteoff\t{}\t{}\t{}\t{}\t{}\t\t{}\t",
voice.get_channel_id(),
voice.channel_id(),
voice.key(),
0,
voice.get_note_id(),
Expand All @@ -88,7 +87,7 @@ impl VoicePool {
for voice in self
.voices
.iter_mut()
.filter(|v| v.get_channel_id() == channel.id())
.filter(|v| v.channel_id() == channel.id())
.filter(|v| v.is_playing())
{
voice.noteoff(channel, min_note_length_ticks);
Expand All @@ -99,7 +98,7 @@ impl VoicePool {
for voice in self
.voices
.iter_mut()
.filter(|v| v.get_channel_id() == chan)
.filter(|v| v.channel_id() == chan)
.filter(|v| v.is_playing())
{
voice.off();
Expand All @@ -117,7 +116,7 @@ impl VoicePool {
for voice in self
.voices
.iter_mut()
.filter(|v| v.get_channel_id() == channel.id())
.filter(|v| v.channel_id() == channel.id())
.filter(|v| v.key() == key)
{
voice.modulate(channel, false, MOD_KEYPRESSURE);
Expand All @@ -128,7 +127,7 @@ impl VoicePool {
for voice in self
.voices
.iter_mut()
.filter(|v| v.get_channel_id() == channel.id())
.filter(|v| v.channel_id() == channel.id())
.filter(|v| v.is_sustained())
{
voice.noteoff(channel, min_note_length_ticks);
Expand All @@ -139,7 +138,7 @@ impl VoicePool {
for voice in self
.voices
.iter_mut()
.filter(|v| v.get_channel_id() == channel.id())
.filter(|v| v.channel_id() == channel.id())
{
voice.modulate(channel, is_cc, ctrl);
}
Expand All @@ -149,7 +148,7 @@ impl VoicePool {
for voice in self
.voices
.iter_mut()
.filter(|v| v.get_channel_id() == channel.id())
.filter(|v| v.channel_id() == channel.id())
{
voice.modulate_all(channel);
}
Expand All @@ -164,7 +163,7 @@ impl VoicePool {
return Some(VoiceId(id));
}
let mut this_voice_prio = 10000.0;
if voice.get_channel_id() == 0xff {
if voice.channel_id() == 0xff {
this_voice_prio -= 2000.0;
}
if voice.is_sustained() {
Expand Down Expand Up @@ -204,7 +203,7 @@ impl VoicePool {
continue;
}

if existing_voice.get_channel_id() != new_voice.get_channel_id() {
if existing_voice.channel_id() != new_voice.channel_id() {
continue;
}

Expand All @@ -228,51 +227,14 @@ impl VoicePool {
for voice in self
.voices
.iter_mut()
.filter(|v| v.get_channel_id() == channel.id())
.filter(|v| v.channel_id() == channel.id())
.filter(|v| v.is_playing())
.filter(|v| v.key() == key)
.filter(|v| v.get_note_id() != noteid)
{
voice.noteoff(channel, min_note_length_ticks);
}
}

#[allow(clippy::too_many_arguments)]
pub(super) fn write_voices(
&mut self,
channels: &[Channel],
min_note_length_ticks: usize,
audio_groups: u8,
(dsp_left_buf, dsp_right_buf): (&mut [[f32; 64]], &mut [[f32; 64]]),
fx_left_buf: &mut FxBuf,
reverb_active: bool,
chorus_active: bool,
) {
for voice in self.voices.iter_mut().filter(|v| v.is_playing()) {
// The output associated with a MIDI channel is wrapped around
// using the number of audio groups as modulo divider. This is
// typically the number of output channels on the 'sound card',
// as long as the LADSPA Fx unit is not used. In case of LADSPA
// unit, think of it as subgroups on a mixer.
//
// For example: Assume that the number of groups is set to 2.
// Then MIDI channel 1, 3, 5, 7 etc. go to output 1, channels 2,
// 4, 6, 8 etc to output 2. Or assume 3 groups: Then MIDI
// channels 1, 4, 7, 10 etc go to output 1; 2, 5, 8, 11 etc to
// output 2, 3, 6, 9, 12 etc to output 3.
let mut auchan = voice.get_channel_id();
auchan %= audio_groups as usize;

voice.write(
&channels[voice.get_channel_id()],
min_note_length_ticks,
(&mut dsp_left_buf[auchan], &mut dsp_right_buf[auchan]),
fx_left_buf,
reverb_active,
chorus_active,
);
}
}
}

impl VoicePool {
Expand Down
48 changes: 25 additions & 23 deletions oxisynth/src/core/voice_pool/voice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ mod envelope;
pub use envelope::EnvelopeStep;
use envelope::{Envelope, EnvelopePortion};

use crate::core::{BUFSIZE, BUFSIZE_F32};

use super::super::{
channel_pool::{Channel, InterpolationMethod},
write::FxBuf,
Expand Down Expand Up @@ -205,7 +207,7 @@ pub(crate) struct Voice {

phase: Phase,

filter_coeff_incr_count: i32,
filter_coeff_incr_count: usize,

a1: f32,
a2: f32,
Expand Down Expand Up @@ -574,7 +576,7 @@ impl Voice {
self.status = VoiceStatus::Off;
}

pub(super) fn get_channel_id(&self) -> usize {
pub(crate) fn channel_id(&self) -> usize {
self.channel_id
}

Expand Down Expand Up @@ -857,7 +859,7 @@ impl Voice {
self.amp_chorus = self.chorus_send * gain / 32768.0;
}

pub(super) fn write(
pub(crate) fn write(
&mut self,
channel: &Channel,
min_note_length_ticks: usize,
Expand Down Expand Up @@ -1026,7 +1028,7 @@ impl Voice {

if let Some(target_amp) = target_amplitude {
// Volume increment to go from voice->amp to target_amp in FLUID_BUFSIZE steps
let amp_incr = (target_amp - self.amp) / 64.0;
let amp_incr = (target_amp - self.amp) / BUFSIZE_F32;
// no volume and not changing? - No need to process
if !(self.amp == 0.0 && amp_incr == 0.0) {
// Calculate the number of samples, that the DSP loop advances
Expand Down Expand Up @@ -1128,13 +1130,13 @@ impl Voice {
// buffer will sacrifice some performance, though. Note: If
// the filter is still too 'grainy', then increase this number
// at will.
self.a1_incr = (a1_temp - self.a1) / 64.0;
self.a2_incr = (a2_temp - self.a2) / 64.0;
self.b02_incr = (b02_temp - self.b02) / 64.0;
self.b1_incr = (b1_temp - self.b1) / 64.0;
self.a1_incr = (a1_temp - self.a1) / BUFSIZE_F32;
self.a2_incr = (a2_temp - self.a2) / BUFSIZE_F32;
self.b02_incr = (b02_temp - self.b02) / BUFSIZE_F32;
self.b1_incr = (b1_temp - self.b1) / BUFSIZE_F32;

// Have to add the increments filter_coeff_incr_count times.
self.filter_coeff_incr_count = 64;
self.filter_coeff_incr_count = BUFSIZE;
}
self.last_fres = fres
}
Expand Down Expand Up @@ -1165,13 +1167,13 @@ impl Voice {
);
}
// turn off voice if short count (sample ended and not looping)
if count < 64 {
if count < BUFSIZE {
self.off();
}
}
}

self.ticks += self.ticks.wrapping_add(64);
self.ticks += BUFSIZE;
}

/// Purpose:
Expand Down Expand Up @@ -1366,7 +1368,7 @@ impl Voice {
}
let seconds = tc2sec(timecents);
// buffers
((self.output_rate as f64 * seconds / 64.0) + 0.5) as i32
((self.output_rate as f64 * seconds / BUFSIZE as f64) + 0.5) as i32
}

/// The value of a generator (gen) has changed. (The different
Expand Down Expand Up @@ -1549,7 +1551,7 @@ impl Voice {
let val = gen_sum!(GeneratorType::ModLfoFreq);

let val = val.clamp(-16000.0, 4500.0);
self.modlfo_incr = 4.0 * 64.0 * act2hz(val) / self.output_rate;
self.modlfo_incr = 4.0 * BUFSIZE_F32 * act2hz(val) / self.output_rate;
}

GeneratorType::VibLfoFreq => {
Expand All @@ -1560,7 +1562,7 @@ impl Voice {
let freq = gen_sum!(GeneratorType::VibLfoFreq);

let freq = freq.clamp(-16000.0, 4500.0);
self.viblfo_incr = 4.0 * 64.0 * act2hz(freq) / self.output_rate;
self.viblfo_incr = 4.0 * BUFSIZE_F32 * act2hz(freq) / self.output_rate;
}

GeneratorType::VibLfoDelay => {
Expand Down Expand Up @@ -1672,7 +1674,7 @@ impl Voice {

let val = val.clamp(-12000.0, 5000.0);

let count = (self.output_rate * tc2sec_delay(val) / 64.0) as u32;
let count = (self.output_rate * tc2sec_delay(val) / BUFSIZE_F32) as u32;

self.volenv_data[EnvelopeStep::Delay] = EnvelopePortion {
count,
Expand All @@ -1689,7 +1691,7 @@ impl Voice {
let val = val.clamp(-12000.0, 8000.0);

let count =
1u32.wrapping_add((self.output_rate * tc2sec_attack(val) / 64.0) as u32);
1u32.wrapping_add((self.output_rate * tc2sec_attack(val) / BUFSIZE_F32) as u32);

self.volenv_data[EnvelopeStep::Attack] = EnvelopePortion {
count,
Expand Down Expand Up @@ -1743,8 +1745,8 @@ impl Voice {

let val = val.clamp(-7200.0, 8000.0);

let count =
1u32.wrapping_add((self.output_rate * tc2sec_release(val) / 64.0) as u32);
let count = 1u32
.wrapping_add((self.output_rate * tc2sec_release(val) / BUFSIZE_F32) as u32);

self.volenv_data[EnvelopeStep::Release] = EnvelopePortion {
count,
Expand All @@ -1761,7 +1763,7 @@ impl Voice {
let val = val.clamp(-12000.0, 5000.0);

self.modenv_data[EnvelopeStep::Delay] = EnvelopePortion {
count: (self.output_rate * tc2sec_delay(val) / 64.0) as u32,
count: (self.output_rate * tc2sec_delay(val) / BUFSIZE_F32) as u32,
coeff: 0.0,
incr: 0.0,
min: -1.0,
Expand All @@ -1775,7 +1777,7 @@ impl Voice {
let val = val.clamp(-12000.0, 8000.0);

let count =
1u32.wrapping_add((self.output_rate * tc2sec_attack(val) / 64.0) as u32);
1u32.wrapping_add((self.output_rate * tc2sec_attack(val) / BUFSIZE_F32) as u32);

self.modenv_data[EnvelopeStep::Attack] = EnvelopePortion {
count,
Expand Down Expand Up @@ -1828,8 +1830,8 @@ impl Voice {

let val = val.clamp(-12000.0, 8000.0);

let count =
1u32.wrapping_add((self.output_rate * tc2sec_release(val) / 64.0) as u32);
let count = 1u32
.wrapping_add((self.output_rate * tc2sec_release(val) / BUFSIZE_F32) as u32);

self.modenv_data[EnvelopeStep::Release] = EnvelopePortion {
count,
Expand Down Expand Up @@ -1889,7 +1891,7 @@ impl Voice {
self.status == VoiceStatus::On && self.volenv_section < EnvelopeStep::Release
}

pub(super) fn is_playing(&self) -> bool {
pub(crate) fn is_playing(&self) -> bool {
matches!(self.status, VoiceStatus::On | VoiceStatus::Sustained)
}

Expand Down
Loading

0 comments on commit e526d83

Please sign in to comment.