mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-08-07 22:17:07 +02:00
systematizing jack handlers
This commit is contained in:
parent
d627d257ad
commit
4ae62c5bc2
10 changed files with 342 additions and 208 deletions
|
|
@ -7,7 +7,7 @@ pub const ACTIONS: [(&'static str, &'static str);2] = [
|
|||
|
||||
pub struct Sampler {
|
||||
name: String,
|
||||
jack: Jack<self::Notifications>,
|
||||
jack: Jack<SamplerJack>,
|
||||
samples: Arc<Mutex<Vec<Sample>>>,
|
||||
selected_sample: usize,
|
||||
selected_column: usize,
|
||||
|
|
@ -23,57 +23,65 @@ impl Sampler {
|
|||
];
|
||||
let samples = Arc::new(Mutex::new(samples));
|
||||
let input = client.register_port("trigger", ::jack::MidiIn::default())?;
|
||||
let handler: BoxedProcessHandler = Box::new({
|
||||
let exited = exited.clone();
|
||||
let jack = SamplerJack.activate(client, ClosureProcessHandler::new({
|
||||
let exited = exited.clone();
|
||||
let samples = samples.clone();
|
||||
Box::new(move |_: &Client, scope: &ProcessScope| -> Control {
|
||||
if exited.fetch_and(true, Ordering::Relaxed) {
|
||||
return Control::Quit
|
||||
}
|
||||
let mut samples = samples.lock().unwrap();
|
||||
for event in 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Box::new(move |client: &Client, scope: &ProcessScope|{
|
||||
process(client, scope, &exited, &samples, &input);
|
||||
Control::Continue
|
||||
})
|
||||
});
|
||||
}) as BoxedProcessHandler
|
||||
}))?;
|
||||
Ok(DynamicDevice::new(render, handle, |_|{}, Self {
|
||||
name: name.into(),
|
||||
selected_sample: 0,
|
||||
selected_column: 0,
|
||||
samples,
|
||||
jack: client.activate_async(
|
||||
self::Notifications,
|
||||
ClosureProcessHandler::new(handler)
|
||||
)?,
|
||||
jack,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process (
|
||||
client: &Client,
|
||||
scope: &ProcessScope,
|
||||
exited: &Arc<AtomicBool>,
|
||||
samples: &Arc<Mutex<Vec<Sample>>>,
|
||||
input: &Port<MidiIn>
|
||||
) -> Control {
|
||||
if exited.fetch_and(true, Ordering::Relaxed) {
|
||||
return Control::Quit
|
||||
}
|
||||
let mut samples = samples.lock().unwrap();
|
||||
for event in 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 {
|
||||
port: Port<AudioOut>,
|
||||
name: String,
|
||||
|
|
@ -217,9 +225,17 @@ pub fn handle (state: &mut Sampler, event: &EngineEvent) -> Result<(), Box<dyn E
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub struct Notifications;
|
||||
pub struct SamplerJack;
|
||||
|
||||
impl NotificationHandler for Notifications {
|
||||
impl SamplerJack {
|
||||
fn activate <P> (self, client: Client, handler: P) -> Usually<AsyncClient<Self, P>>
|
||||
where P: 'static + Send + ::jack::ProcessHandler
|
||||
{
|
||||
Ok(client.activate_async(self, handler)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl NotificationHandler for SamplerJack {
|
||||
fn thread_init (&self, _: &Client) {
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue