mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +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>>>,
|
||||
selected_sample: usize,
|
||||
selected_column: 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, 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
|
||||
midi_ins: Vec<Port<MidiIn>>,
|
||||
audio_ins: Vec<Port<AudioIn>>,
|
||||
audio_outs: Vec<Port<AudioOut>>,
|
||||
}
|
||||
|
||||
pub struct Sample {
|
||||
|
|
@ -79,6 +27,86 @@ pub struct Sample {
|
|||
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 {
|
||||
|
||||
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