mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
impl PortList for Sampler
This commit is contained in:
parent
9351887ae6
commit
1038e24ceb
1 changed files with 83 additions and 55 deletions
|
|
@ -11,61 +11,9 @@ pub struct Sampler {
|
||||||
samples: Arc<Mutex<Vec<Sample>>>,
|
samples: Arc<Mutex<Vec<Sample>>>,
|
||||||
selected_sample: usize,
|
selected_sample: usize,
|
||||||
selected_column: usize,
|
selected_column: usize,
|
||||||
}
|
midi_ins: Vec<Port<MidiIn>>,
|
||||||
|
audio_ins: Vec<Port<AudioIn>>,
|
||||||
impl Sampler {
|
audio_outs: Vec<Port<AudioOut>>,
|
||||||
pub fn new (name: &str) -> Result<DynamicDevice<Self>, Box<dyn Error>> {
|
|
||||||
let (client, _) = Client::new(name, ClientOptions::NO_START_SERVER)?;
|
|
||||||
let samples = vec![
|
|
||||||
Sample::new("Kick", &client, 1, 35)?,
|
|
||||||
Sample::new("Snare", &client, 1, 38)?,
|
|
||||||
];
|
|
||||||
let samples = Arc::new(Mutex::new(samples));
|
|
||||||
let input = client.register_port("trigger", ::jack::MidiIn::default())?;
|
|
||||||
Ok(DynamicDevice::new(render, handle, process, Self {
|
|
||||||
name: name.into(),
|
|
||||||
input,
|
|
||||||
selected_sample: 0,
|
|
||||||
selected_column: 0,
|
|
||||||
samples,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn process (
|
|
||||||
state: &mut Sampler,
|
|
||||||
_: &Client,
|
|
||||||
scope: &ProcessScope,
|
|
||||||
) -> Control {
|
|
||||||
let mut samples = state.samples.lock().unwrap();
|
|
||||||
for event in state.input.iter(scope) {
|
|
||||||
let len = 3.min(event.bytes.len());
|
|
||||||
let mut data = [0; 3];
|
|
||||||
data[..len].copy_from_slice(&event.bytes[..len]);
|
|
||||||
if (data[0] >> 4) == 0b1001 { // note on
|
|
||||||
let channel = data[0] & 0b00001111;
|
|
||||||
let note = data[1];
|
|
||||||
let velocity = data[2];
|
|
||||||
for sample in samples.iter_mut() {
|
|
||||||
if sample.trigger.0 == channel && sample.trigger.1 == note {
|
|
||||||
sample.play(velocity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for sample in samples.iter_mut() {
|
|
||||||
if let Some(playing) = sample.playing {
|
|
||||||
for (index, value) in sample.port.as_mut_slice(scope).iter_mut().enumerate() {
|
|
||||||
*value = *sample.data[0].get(playing + index).unwrap_or(&0f32);
|
|
||||||
}
|
|
||||||
if playing + scope.n_frames() as usize > sample.data[0].len() {
|
|
||||||
sample.playing = None
|
|
||||||
} else {
|
|
||||||
sample.playing = Some(playing + scope.n_frames() as usize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Control::Continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Sample {
|
pub struct Sample {
|
||||||
|
|
@ -79,6 +27,86 @@ pub struct Sample {
|
||||||
playing: Option<usize>,
|
playing: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Sampler {
|
||||||
|
pub fn new (name: &str) -> Result<DynamicDevice<Self>, Box<dyn Error>> {
|
||||||
|
let (client, _) = Client::new(name, ClientOptions::NO_START_SERVER)?;
|
||||||
|
let samples = vec![
|
||||||
|
Sample::new("Kick", &client, 1, 35)?,
|
||||||
|
Sample::new("Snare", &client, 1, 38)?,
|
||||||
|
];
|
||||||
|
let samples = Arc::new(Mutex::new(samples));
|
||||||
|
let input = client.register_port("trigger", ::jack::MidiIn::default())?;
|
||||||
|
Ok(DynamicDevice::new(render, handle, Self::process, Self {
|
||||||
|
name: name.into(),
|
||||||
|
input,
|
||||||
|
selected_sample: 0,
|
||||||
|
selected_column: 0,
|
||||||
|
samples,
|
||||||
|
midi_ins: vec![],
|
||||||
|
audio_ins: vec![],
|
||||||
|
audio_outs: vec![],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
||||||
|
let mut samples = self.samples.lock().unwrap();
|
||||||
|
for event in self.input.iter(scope) {
|
||||||
|
let len = 3.min(event.bytes.len());
|
||||||
|
let mut data = [0; 3];
|
||||||
|
data[..len].copy_from_slice(&event.bytes[..len]);
|
||||||
|
if (data[0] >> 4) == 0b1001 { // note on
|
||||||
|
let channel = data[0] & 0b00001111;
|
||||||
|
let note = data[1];
|
||||||
|
let velocity = data[2];
|
||||||
|
for sample in samples.iter_mut() {
|
||||||
|
if sample.trigger.0 == channel && sample.trigger.1 == note {
|
||||||
|
sample.play(velocity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for sample in samples.iter_mut() {
|
||||||
|
if let Some(playing) = sample.playing {
|
||||||
|
for (index, value) in sample.port.as_mut_slice(scope).iter_mut().enumerate() {
|
||||||
|
*value = *sample.data[0].get(playing + index).unwrap_or(&0f32);
|
||||||
|
}
|
||||||
|
if playing + scope.n_frames() as usize > sample.data[0].len() {
|
||||||
|
sample.playing = None
|
||||||
|
} else {
|
||||||
|
sample.playing = Some(playing + scope.n_frames() as usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Control::Continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_sample (&mut self, path: &str) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PortList for Sampler {
|
||||||
|
fn audio_ins (&self) -> Usually<Vec<String>> {
|
||||||
|
let mut ports = vec![];
|
||||||
|
for port in self.audio_ins.iter() {
|
||||||
|
ports.push(port.name()?);
|
||||||
|
}
|
||||||
|
Ok(ports)
|
||||||
|
}
|
||||||
|
fn audio_outs (&self) -> Usually<Vec<String>> {
|
||||||
|
let mut ports = vec![];
|
||||||
|
for port in self.audio_outs.iter() {
|
||||||
|
ports.push(port.name()?);
|
||||||
|
}
|
||||||
|
Ok(ports)
|
||||||
|
}
|
||||||
|
fn midi_ins (&self) -> Usually<Vec<String>> {
|
||||||
|
let mut ports = vec![];
|
||||||
|
for port in self.midi_ins.iter() {
|
||||||
|
ports.push(port.name()?);
|
||||||
|
}
|
||||||
|
Ok(ports)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Sample {
|
impl Sample {
|
||||||
|
|
||||||
pub fn new (name: &str, client: &Client, channel: u8, note: u8) -> Result<Self, Box<dyn Error>> {
|
pub fn new (name: &str, client: &Client, channel: u8, note: u8) -> Result<Self, Box<dyn Error>> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue