[opiate] create and implement crate
parent
37f36421ef
commit
f94653f3ec
|
@ -0,0 +1,15 @@
|
||||||
|
[package]
|
||||||
|
name = "opiate"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# baseplug = { git = "https://github.com/wrl/baseplug.git", rev = "9cec68f31cca9c0c7a1448379f75d92bbbc782a8" }
|
||||||
|
baseplug = { path = "../baseplug" }
|
||||||
|
serde = "1.0.126"
|
||||||
|
pvoc = { path = "../pvoc-rs" }
|
||||||
|
utils = { path = "../utils" }
|
||||||
|
log = "0.4.14"
|
|
@ -0,0 +1,114 @@
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
#![feature(generic_associated_types)]
|
||||||
|
|
||||||
|
// morphing algorithm from https://ccrma.stanford.edu/~jhsu/421b/
|
||||||
|
|
||||||
|
use baseplug::{Plugin, ProcessContext};
|
||||||
|
use pvoc::{Bin, PhaseVocoder};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use utils::logs::*;
|
||||||
|
|
||||||
|
baseplug::model! {
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct OpiateModel {
|
||||||
|
#[model(min = 0.0, max = 1.0)]
|
||||||
|
#[parameter(name = "morph")]
|
||||||
|
morph: f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for OpiateModel {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { morph: 0.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Opiate {
|
||||||
|
pvoc: PhaseVocoder,
|
||||||
|
out_0: Vec<f32>,
|
||||||
|
out_1: Vec<f32>,
|
||||||
|
out_2: Vec<f32>,
|
||||||
|
out_3: Vec<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Plugin for Opiate {
|
||||||
|
const NAME: &'static str = "opiate";
|
||||||
|
const PRODUCT: &'static str = "opiate";
|
||||||
|
const VENDOR: &'static str = "unnieversal";
|
||||||
|
|
||||||
|
const INPUT_CHANNELS: usize = 4;
|
||||||
|
const OUTPUT_CHANNELS: usize = 2;
|
||||||
|
|
||||||
|
type Model = OpiateModel;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn new(sample_rate: f32, _model: &OpiateModel) -> Self {
|
||||||
|
setup_logging("opiate.log");
|
||||||
|
|
||||||
|
Self {
|
||||||
|
pvoc: PhaseVocoder::new(4, sample_rate as f64, 64, 4),
|
||||||
|
out_0: vec![0.0; 300],
|
||||||
|
out_1: vec![0.0; 300],
|
||||||
|
out_2: vec![0.0; 300],
|
||||||
|
out_3: vec![0.0; 300],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn process(&mut self, model: &OpiateModelProcess, ctx: &mut ProcessContext<Self>) {
|
||||||
|
let input = &ctx.inputs[0].buffers;
|
||||||
|
let output = &mut ctx.outputs[0].buffers;
|
||||||
|
|
||||||
|
if input.len() != 4 {
|
||||||
|
for i in 0..ctx.nframes {
|
||||||
|
output[0][i] = 0.0;
|
||||||
|
output[1][i] = 0.0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let out = &mut [
|
||||||
|
&mut self.out_0[..],
|
||||||
|
&mut self.out_1[..],
|
||||||
|
&mut self.out_2[..],
|
||||||
|
&mut self.out_3[..],
|
||||||
|
][..];
|
||||||
|
|
||||||
|
let morph = model.morph[0] as f64;
|
||||||
|
let imorph = 1.0 - morph;
|
||||||
|
self.pvoc.process(
|
||||||
|
input,
|
||||||
|
out,
|
||||||
|
|_channels: usize, bins: usize, input: &[Vec<Bin>], output: &mut [Vec<Bin>]| {
|
||||||
|
for j in 0..bins {
|
||||||
|
// TODO Check if working with the frequencies is the same as working with the phase
|
||||||
|
// i think we might need to try it to make sure it's the same
|
||||||
|
// to do that, we'll need to change how pvoc works
|
||||||
|
|
||||||
|
let mags = morph * (1.0 - input[0][j].amp) + input[0][j].amp;
|
||||||
|
let mags2 = imorph * (1.0 - input[2][j].amp) + input[2][j].amp;
|
||||||
|
let phases = input[0][j].freq - (input[0][j].freq * morph);
|
||||||
|
let phases2 = input[2][j].freq - (input[2][j].freq * imorph);
|
||||||
|
|
||||||
|
output[0][j].amp = mags * mags2;
|
||||||
|
output[0][j].freq = phases + phases2;
|
||||||
|
|
||||||
|
let mags = morph * (1.0 - input[1][j].amp) + input[1][j].amp;
|
||||||
|
let mags2 = imorph * (1.0 - input[3][j].amp) + input[3][j].amp;
|
||||||
|
let phases = input[1][j].freq - (input[1][j].freq * morph);
|
||||||
|
let phases2 = input[3][j].freq - (input[3][j].freq * imorph);
|
||||||
|
|
||||||
|
output[1][j].amp = mags * mags2;
|
||||||
|
output[1][j].freq = phases + phases2;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
for i in 0..ctx.nframes {
|
||||||
|
output[0][i] = self.out_0[i];
|
||||||
|
output[1][i] = self.out_1[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
baseplug::vst2!(Opiate, b"opiu");
|
Loading…
Reference in New Issue