use crate::core::Synth;
impl Synth {
fn clear_buffers(&mut self) {
self.left_buf.iter_mut().for_each(|buff| buff.fill(0.0));
self.right_buf.iter_mut().for_each(|buff| buff.fill(0.0));
self.fx_left_buf.reverb.fill(0.0);
self.fx_left_buf.chorus.fill(0.0);
self.fx_right_buf.reverb.fill(0.0);
self.fx_right_buf.chorus.fill(0.0);
}
fn one_block(&mut self, do_not_mix_fx_to_out: bool) {
self.clear_buffers();
self.voices.write_voices(
&self.channels,
self.min_note_length_ticks,
self.settings.audio_groups,
(&mut self.left_buf, &mut self.right_buf),
&mut self.fx_left_buf,
self.reverb.active(),
self.chorus.active(),
);
if do_not_mix_fx_to_out {
if self.reverb.active() {
self.reverb
.process_replace(&mut self.fx_left_buf.reverb, &mut self.fx_right_buf.reverb);
}
if self.chorus.active() {
self.chorus
.process_replace(&mut self.fx_left_buf.chorus, &mut self.fx_right_buf.chorus);
}
} else {
if self.reverb.active() {
self.reverb.process_mix(
&mut self.fx_left_buf.reverb,
&mut self.left_buf[0],
&mut self.right_buf[0],
);
}
if self.chorus.active() {
self.chorus.process_mix(
&mut self.fx_left_buf.chorus,
&mut self.left_buf[0],
&mut self.right_buf[0],
);
}
}
self.ticks = self.ticks.wrapping_add(64);
}
pub fn read_next(&mut self) -> (f32, f32) {
if self.cur == 64 {
self.one_block(false);
self.cur = 0;
}
let out = (self.left_buf[0][self.cur], self.right_buf[0][self.cur]);
self.cur += 1;
out
}
pub fn write<F: FnMut(usize, f32, f32)>(&mut self, len: usize, incr: usize, mut cb: F) {
for i in 0..len {
let next = self.read_next();
cb(i * incr, next.0, next.1);
}
}
pub fn write_f32(
&mut self,
len: usize,
left_out: &mut [f32],
loff: usize,
lincr: usize,
right_out: &mut [f32],
roff: usize,
rincr: usize,
) {
for i in 0..len {
let next = self.read_next();
left_out[loff + i * lincr] = next.0;
right_out[roff + i * rincr] = next.1;
}
}
pub fn write_f64(
&mut self,
len: usize,
left_out: &mut [f64],
loff: usize,
lincr: usize,
right_out: &mut [f64],
roff: usize,
rincr: usize,
) {
for i in 0..len {
let next = self.read_next();
left_out[loff + i * lincr] = f64::from(next.0);
right_out[roff + i * rincr] = f64::from(next.1);
}
}
#[cfg(feature = "i16-out")]
pub fn write_s16(
&mut self,
len: usize,
left_out: &mut [i16],
loff: usize,
lincr: usize,
right_out: &mut [i16],
roff: usize,
rincr: usize,
) {
let mut di: i32 = self.dither_index;
let mut cur = self.cur;
let mut i: usize = 0;
let mut j = loff;
let mut k = roff;
while i < len {
if cur == 64 {
self.one_block(false);
cur = 0;
}
let mut left_sample = f32::round(
self.left_buf[0][cur as usize] * 32766.0f32
+ RAND_TABLE[0 as i32 as usize][di as usize],
);
let mut right_sample = f32::round(
self.right_buf[0][cur as usize] * 32766.0f32
+ RAND_TABLE[1 as i32 as usize][di as usize],
);
di += 1;
if di >= 48000 as i32 {
di = 0 as i32
}
if left_sample > 32767.0f32 {
left_sample = 32767.0f32
}
if left_sample < -32768.0f32 {
left_sample = -32768.0f32
}
if right_sample > 32767.0f32 {
right_sample = 32767.0f32
}
if right_sample < -32768.0f32 {
right_sample = -32768.0f32
}
left_out[j as usize] = left_sample as i16;
right_out[k as usize] = right_sample as i16;
i += 1;
cur += 1;
j += lincr;
k += rincr
}
self.cur = cur;
self.dither_index = di;
}
}
#[cfg(feature = "i16-out")]
lazy_static! {
static ref RAND_TABLE: [[f32; 48000]; 2] = {
let mut rand: [[f32; 48000]; 2] = [[0.; 48000]; 2];
for c in 0..2 {
let mut dp = 0.0;
for i in 0..(48000 - 1) {
let r: i32 = rand::random();
let d = r as f32 / 2147483647.0 - 0.5;
rand[c][i] = d - dp;
dp = d;
}
rand[c][48000 - 1] = 0.0 - dp;
}
rand
};
}