use super::audionode::*;
use super::audiounit::*;
use super::combinator::*;
use super::math::*;
use super::*;
use duplicate::duplicate_item;
use numeric_array::typenum::Unsigned;
use numeric_array::*;
use rsor::Slice;
use std::fs::File;
use std::io::prelude::*;
use std::marker::PhantomData;
use std::path::Path;
use std::sync::Arc;
#[inline]
fn write32<W: Write>(writer: &mut W, x: u32) -> std::io::Result<()> {
writer.write_all(&[x as u8, (x >> 8) as u8, (x >> 16) as u8, (x >> 24) as u8])?;
std::io::Result::Ok(())
}
#[inline]
fn write16<W: Write>(writer: &mut W, x: u16) -> std::io::Result<()> {
writer.write_all(&[x as u8, (x >> 8) as u8])?;
std::io::Result::Ok(())
}
fn write_wav_header<W: Write>(
writer: &mut W,
data_length: usize,
format: u16,
channels: usize,
sample_rate: usize,
) -> std::io::Result<()> {
writer.write_all(b"RIFF")?;
write32(writer, data_length as u32 + 36)?;
writer.write_all(b"WAVE")?;
writer.write_all(b"fmt ")?;
write32(writer, 16)?;
write16(writer, format)?;
write16(writer, channels as u16)?;
write32(writer, sample_rate as u32)?;
let sample_bytes = if format == 1 { 2 } else { 4 };
write32(writer, (sample_rate * channels) as u32 * sample_bytes)?;
write16(writer, channels as u16 * sample_bytes as u16)?;
write16(writer, sample_bytes as u16 * 8)?;
writer.write_all(b"data")?;
write32(writer, data_length as u32)?;
std::io::Result::Ok(())
}
#[duplicate_item(
f48 Wave48 AudioUnit48;
[ f64 ] [ Wave64 ] [ AudioUnit64 ];
[ f32 ] [ Wave32 ] [ AudioUnit32 ];
)]
pub struct Wave48 {
vec: Vec<Vec<f48>>,
sr: f64,
len: usize,
slice: Slice<[f48]>,
}
#[duplicate_item(
f48 Wave48 AudioUnit48;
[ f64 ] [ Wave64 ] [ AudioUnit64 ];
[ f32 ] [ Wave32 ] [ AudioUnit32 ];
)]
impl Clone for Wave48 {
fn clone(&self) -> Self {
Self {
vec: self.vec.clone(),
sr: self.sr,
len: self.len,
slice: Slice::new(),
}
}
}
#[allow(clippy::unnecessary_cast)]
#[duplicate_item(
f48 Wave48 AudioUnit48;
[ f64 ] [ Wave64 ] [ AudioUnit64 ];
[ f32 ] [ Wave32 ] [ AudioUnit32 ];
)]
impl Wave48 {
pub fn new(channels: usize, sample_rate: f64) -> Self {
let mut vec = Vec::with_capacity(channels);
for _i in 0..channels {
vec.push(Vec::new());
}
Self {
vec,
sr: sample_rate,
len: 0,
slice: Slice::new(),
}
}
pub fn with_capacity(channels: usize, sample_rate: f64, capacity: usize) -> Self {
let mut vec = Vec::with_capacity(channels);
for _i in 0..channels {
vec.push(Vec::with_capacity(capacity));
}
Self {
vec,
sr: sample_rate,
len: 0,
slice: Slice::new(),
}
}
pub fn silence(channels: usize, sample_rate: f64, duration: f64) -> Self {
let length = round(duration * sample_rate) as usize;
assert!(channels > 0 || length == 0);
let mut vec = Vec::with_capacity(channels);
for _i in 0..channels {
vec.push(vec![0.0; length]);
}
Self {
vec,
sr: sample_rate,
len: length,
slice: Slice::new(),
}
}
pub fn from_samples(sample_rate: f64, samples: &[f48]) -> Self {
Self {
vec: vec![Vec::from(samples)],
sr: sample_rate,
len: samples.len(),
slice: Slice::new(),
}
}
#[inline]
pub fn sample_rate(&self) -> f64 {
self.sr
}
pub fn set_sample_rate(&mut self, sample_rate: f64) {
self.sr = sample_rate;
}
#[inline]
pub fn channels(&self) -> usize {
self.vec.len()
}
#[inline]
pub fn channel(&self, channel: usize) -> &Vec<f48> {
&self.vec[channel]
}
pub fn push_channel(&mut self, samples: &[f48]) {
assert!(self.channels() == 0 || self.len() == samples.len());
if self.channels() == 0 {
self.len = samples.len();
}
self.vec.push(samples.into());
}
pub fn insert_channel(&mut self, channel: usize, samples: &[f48]) {
assert!(self.channels() == 0 || self.len() == samples.len());
assert!(channel <= self.channels());
if self.channels() == 0 {
self.len = samples.len();
}
self.vec.insert(channel, samples.into());
}
pub fn remove_channel(&mut self, channel: usize) -> Vec<f48> {
assert!(channel < self.channels());
self.vec.remove(channel)
}
pub fn channels_ref(&mut self) -> &[&[f48]] {
self.slice.from_refs(&self.vec)
}
pub fn channels_mut(&mut self) -> &mut [&mut [f48]] {
self.slice.from_muts(&mut self.vec)
}
#[inline]
pub fn at(&self, channel: usize, index: usize) -> f48 {
self.vec[channel][index]
}
#[inline]
pub fn set(&mut self, channel: usize, index: usize, value: f48) {
self.vec[channel][index] = value;
}
#[inline]
pub fn push<T: ConstantFrame<Sample = f48>>(&mut self, frame: T) {
let frame = frame.convert();
if T::Size::USIZE == 1 {
for channel in 0..self.channels() {
self.vec[channel].push(frame[0]);
}
} else {
assert!(self.channels() == T::Size::USIZE);
for channel in 0..self.channels() {
self.vec[channel].push(frame[channel]);
}
}
if self.channels() > 0 {
self.len += 1;
}
}
#[inline]
pub fn length(&self) -> usize {
self.len
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn duration(&self) -> f64 {
self.length() as f64 / self.sample_rate()
}
pub fn resize(&mut self, length: usize) {
assert!(self.channels() > 0);
if length != self.length() {
for channel in 0..self.channels() {
self.vec[channel].resize(length, 0.0);
}
}
self.len = length;
}
pub fn amplitude(&self) -> f48 {
let mut peak = 0.0;
for channel in 0..self.channels() {
for i in 0..self.len() {
peak = max(peak, abs(self.at(channel, i)));
}
}
peak
}
pub fn normalize(&mut self) {
let a = self.amplitude();
if a == 0.0 || a == 1.0 {
return;
}
let z = 1.0 / a;
for channel in 0..self.channels() {
for i in 0..self.len() {
self.set(channel, i, self.at(channel, i) * z);
}
}
}
pub fn fade_in(&mut self, time: f64) {
assert!(time <= self.duration());
let fade_n = round(time * self.sample_rate());
for i in 0..fade_n as usize {
let a = smooth5((i + 1) as f64 / (fade_n + 1.0)) as f48;
for channel in 0..self.channels() {
self.set(channel, i, self.at(channel, i) * a);
}
}
}
pub fn fade_out(&mut self, time: f64) {
assert!(time <= self.duration());
let fade_n = round(time * self.sample_rate());
let fade_i = fade_n as usize;
for i in 0..fade_i {
let a = smooth5((fade_n - i as f64) / (fade_n + 1.0)) as f48;
for channel in 0..self.channels() {
self.set(channel, self.len() - fade_i + i, self.at(channel, i) * a);
}
}
}
pub fn fade(&mut self, time: f64) {
self.fade_in(time);
self.fade_out(time);
}
pub fn render(sample_rate: f64, duration: f64, node: &mut dyn AudioUnit48) -> Self {
assert!(node.inputs() == 0);
assert!(node.outputs() > 0);
assert!(duration >= 0.0);
node.reset(Some(sample_rate));
let length = (duration * sample_rate).round() as usize;
let mut wave = Self::with_capacity(node.outputs(), sample_rate, length);
wave.len = length;
let mut i = 0;
let mut buffer = Self::new(node.outputs(), sample_rate);
let mut reusable_slice = Slice::<[f48]>::with_capacity(node.outputs());
while i < length {
let n = min(length - i, MAX_BUFFER_SIZE);
buffer.resize(n);
node.process(n, &[], reusable_slice.from_muts(&mut buffer.vec));
for channel in 0..node.outputs() {
wave.vec[channel].extend_from_slice(&buffer.vec[channel][..]);
}
i += n;
}
wave
}
pub fn render_latency(sample_rate: f64, duration: f64, node: &mut dyn AudioUnit48) -> Self {
assert!(node.inputs() == 0);
assert!(node.outputs() > 0);
assert!(duration >= 0.0);
let latency = node.latency().unwrap_or_default();
let latency_samples = floor(latency) as usize;
let latency_duration = latency_samples as f64 / sample_rate;
let duration_samples = round(duration * sample_rate) as usize;
let duration = duration_samples as f64 / sample_rate;
if latency_samples > 0 {
let latency_wave = Self::render(sample_rate, duration + latency_duration, node);
let mut wave = Self::silence(node.outputs(), sample_rate, duration);
for channel in 0..wave.channels() {
for i in 0..duration_samples {
wave.set(channel, i, latency_wave.at(channel, i + latency_samples));
}
}
wave
} else {
Self::render(sample_rate, duration, node)
}
}
pub fn filter(&self, duration: f64, node: &mut dyn AudioUnit48) -> Self {
assert!(node.inputs() == self.channels());
assert!(node.outputs() > 0);
assert!(duration >= 0.0);
node.reset(Some(self.sample_rate()));
let total_length = round(duration * self.sample_rate()) as usize;
let input_length = min(total_length, self.length());
let mut wave = Self::with_capacity(node.outputs(), self.sample_rate(), total_length);
wave.len = total_length;
let mut i = 0;
let mut input_buffer = Self::new(self.channels(), self.sample_rate());
let mut reusable_input_slice = Slice::<[f48]>::with_capacity(self.channels());
let mut output_buffer = Self::new(node.outputs(), self.sample_rate());
let mut reusable_output_slice = Slice::<[f48]>::with_capacity(node.outputs());
while i < input_length {
let n = min(input_length - i, MAX_BUFFER_SIZE);
input_buffer.resize(n);
output_buffer.resize(n);
for channel in 0..self.channels() {
for j in 0..n {
input_buffer.set(channel, j, self.at(channel, i + j));
}
}
node.process(
n,
reusable_input_slice.from_refs(&input_buffer.vec),
reusable_output_slice.from_muts(&mut output_buffer.vec),
);
for channel in 0..node.outputs() {
wave.vec[channel].extend_from_slice(&output_buffer.vec[channel][..]);
}
i += n;
}
if i < total_length {
input_buffer.resize(MAX_BUFFER_SIZE);
for channel in 0..self.channels() {
for j in 0..MAX_BUFFER_SIZE {
input_buffer.set(channel, j, 0.0);
}
}
while i < total_length {
let n = min(total_length - i, MAX_BUFFER_SIZE);
input_buffer.resize(n);
output_buffer.resize(n);
node.process(
n,
reusable_input_slice.from_refs(&input_buffer.vec),
reusable_output_slice.from_muts(&mut output_buffer.vec),
);
for channel in 0..node.outputs() {
wave.vec[channel].extend_from_slice(&output_buffer.vec[channel][..]);
}
i += n;
}
}
wave
}
pub fn filter_latency(&self, duration: f64, node: &mut dyn AudioUnit48) -> Self {
assert!(node.inputs() == self.channels());
assert!(node.outputs() > 0);
assert!(duration >= 0.0);
let latency = node.latency().unwrap_or_default();
let latency_samples = floor(latency) as usize;
let latency_duration = latency_samples as f64 / self.sample_rate();
let duration_samples = round(duration * self.sample_rate()) as usize;
let duration = duration_samples as f64 / self.sample_rate();
if latency_samples > 0 {
let latency_wave = self.filter(duration + latency_duration, node);
let mut wave = Self::silence(node.outputs(), self.sample_rate(), duration);
for channel in 0..wave.channels() {
for i in 0..duration_samples {
wave.set(channel, i, latency_wave.at(channel, i + latency_samples));
}
}
wave
} else {
self.filter(duration, node)
}
}
pub fn write_wav16<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
assert!(self.channels() > 0);
write_wav_header(
writer,
2 * self.channels() * self.length(),
1,
self.channels(),
round(self.sample_rate()) as usize,
)?;
for i in 0..self.length() {
for channel in 0..self.channels() {
let sample = round(clamp11(self.at(channel, i)) * 32767.49);
write16(writer, sample.to_i64() as u16)?;
}
}
std::io::Result::Ok(())
}
pub fn write_wav32<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
assert!(self.channels() > 0);
write_wav_header(
writer,
4 * self.channels() * self.length(),
3,
self.channels(),
round(self.sample_rate()) as usize,
)?;
for i in 0..self.length() {
for channel in 0..self.channels() {
let sample = self.at(channel, i);
writer.write_all(&sample.to_f32().to_le_bytes())?;
}
}
std::io::Result::Ok(())
}
pub fn save_wav16<P: AsRef<Path>>(&self, path: P) -> std::io::Result<()> {
assert!(self.channels() > 0);
let mut file = File::create(path.as_ref())?;
self.write_wav16(&mut file)
}
pub fn save_wav32<P: AsRef<Path>>(&self, path: P) -> std::io::Result<()> {
assert!(self.channels() > 0);
let mut file = File::create(path.as_ref())?;
self.write_wav32(&mut file)
}
}
#[duplicate_item(
f48 Wave48 Wave48Player;
[ f64 ] [ Wave64 ] [ Wave64Player ];
[ f32 ] [ Wave32 ] [ Wave32Player ];
)]
#[derive(Clone)]
pub struct Wave48Player<T: Float> {
wave: Arc<Wave48>,
channel: usize,
index: usize,
start_point: usize,
end_point: usize,
loop_point: Option<usize>,
_marker: PhantomData<T>,
}
#[duplicate_item(
f48 Wave48 Wave48Player;
[ f64 ] [ Wave64 ] [ Wave64Player ];
[ f32 ] [ Wave32 ] [ Wave32Player ];
)]
impl<T: Float> Wave48Player<T> {
pub fn new(
wave: &Arc<Wave48>,
channel: usize,
start_point: usize,
end_point: usize,
loop_point: Option<usize>,
) -> Self {
assert!(channel < wave.channels());
assert!(end_point <= wave.length());
Self {
wave: wave.clone(),
channel,
index: start_point,
start_point,
end_point,
loop_point,
_marker: PhantomData::default(),
}
}
}
#[duplicate_item(
f48 Wave48 Wave48Player;
[ f64 ] [ Wave64 ] [ Wave64Player ];
[ f32 ] [ Wave32 ] [ Wave32Player ];
)]
impl<T: Float> AudioNode for Wave48Player<T> {
const ID: u64 = 65;
type Sample = T;
type Inputs = typenum::U0;
type Outputs = typenum::U1;
type Setting = ();
fn reset(&mut self, _sample_rate: Option<f64>) {
self.index = self.start_point;
}
#[inline]
fn tick(
&mut self,
_input: &Frame<Self::Sample, Self::Inputs>,
) -> Frame<Self::Sample, Self::Outputs> {
if self.index < self.end_point {
let value = self.wave.at(self.channel, self.index);
self.index += 1;
if self.index == self.end_point {
if let Some(point) = self.loop_point {
self.index = point;
}
}
[convert(value)].into()
} else {
[T::zero()].into()
}
}
}