quantum_entangler/midi/
perform.rs

1use std::thread::sleep;
2use std::time::Duration;
3use crossbeam;
4
5use crate::midi;
6
7// Working rules and example
8
9pub struct Note<'a> {
10  pub output: &'a mut midir::MidiOutputConnection
11}
12
13impl Note<'_> {
14  pub fn new(&mut self, start_index: usize, mut duration: u64, buffer: &mut std::sync::MutexGuard<std::vec::Vec<midi::time::MidiBuffer>>) {
15    // If not a release note
16    // let buffer =  super::time::MIDI_BUFFER.lock().unwrap();
17    let (stop_index, stop_timestamp, stop_message) = find_stop_message(start_index, buffer);
18    crossbeam::scope(|scope| {
19      scope.spawn(|_| {
20        let note_duration = stop_timestamp - buffer[start_index].timestamp;
21    
22        if stop_index <= buffer.len() - 1 && !super::attribute::release_note(buffer[start_index].message.to_vec()) {
23      // println!("{:?}, {:?}", buffer[index_stop].message, buffer[index_start].message);
24
25      
26          println!("{:?} => {:?}", &buffer[start_index].message, &stop_message);
27      
28          let _ = &self.output.send(&buffer[start_index].message).unwrap_or_else(|_| println!("Error when forwarding message ...")); 
29
30          // Note Duration
31          if note_duration <= duration {
32            sleep(Duration::from_micros(note_duration));
33
34            let _ = &self.output.send(&stop_message).unwrap_or_else(|_| println!("Error when forwarding message ..."));
35
36            if stop_index != buffer.len() - 1 && duration != 0 {
37              duration = stop_timestamp - buffer[start_index].timestamp;
38            }
39            // Rest Notes
40            sleep(Duration::from_micros(duration - note_duration));
41          } else {
42            sleep(Duration::from_micros(duration));
43            let _ = &self.output.send(&stop_message).unwrap_or_else(|_| println!("Error when forwarding message ..."));
44          }
45  
46        }
47      });
48    })
49    .expect("A child thread panicked");
50  }
51
52  pub fn forward(&mut self, message: &[u8]) {
53    crossbeam::scope(|scope| {
54      scope.spawn(|_| {
55        println!("{:?}", message);
56    
57        let _ = &self.output.send(message).unwrap_or_else(|_| println!("Error when forwarding message ...")); 
58      });
59    })
60    .expect("A child thread panicked");
61  }
62}
63
64fn find_stop_message<'a>(start_index: usize, buffer: &mut std::sync::MutexGuard<std::vec::Vec<midi::time::MidiBuffer>>) -> (usize, u64, Vec<u8>) {
65  let mut stop_index = start_index + 1;
66  let start_tone = buffer[start_index].message[1];
67  let mut stop_id = buffer[stop_index].message[0];
68
69  while  stop_index < buffer.len() - 1 {
70    if buffer[stop_index].message[1] == start_tone && buffer[stop_index].message[2] == 0 {
71      let stop_message: Vec<u8> = [buffer[stop_index].message[0], buffer[stop_index].message[1], buffer[stop_index].message[2]].to_vec();
72      return (stop_index, buffer[stop_index].timestamp, stop_message)
73    }
74
75    stop_index += 1;
76
77    if stop_id == buffer[start_index].message[0] {
78      stop_id = buffer[stop_index].message[0];
79    }
80  }
81
82  let default_message: Vec<u8> = [stop_id, start_tone, 0].to_vec();
83  let default_stop = midi::time::MidiBuffer {timestamp: buffer[start_index + 1].timestamp, message: default_message};
84  (start_index + 1, default_stop.timestamp, default_stop.message)
85}
86
87pub fn trigger(_timestamp: u64, message: &[u8], properties: &str, buffer_length: usize) -> bool {
88
89  // Trigger on a release midi message
90  if super::attribute::release_note(message.to_vec()) {
91    //^^Should never change^^
92    // custom scripting starts here
93
94    // Working rules and example
95    // use scripting language to proccess properties and trigger
96    let props: Vec<&str> = properties.split("|").collect();
97    match props[0] {
98      "cycle" => return cycle(props[1].parse::<usize>().unwrap(), buffer_length),
99      _ => return false
100    }
101    
102  }
103  false
104}
105
106fn cycle(sequence: usize, buffer_length: usize) -> bool {
107  
108  // let num: usize = sequence.parse().unwrap();
109  
110  if buffer_length % sequence == 0 {
111    return true
112  }
113  false
114}