-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Hi there, I'm a bit new to Rust and most probably struggling with the fundamentals of the language, but I'm trying to wire something up in the Tauri backend to handle sending midi output generated from the JS frontend.
Just wondering if you would be able to help me?
I've based my code on what you've provided here, except swapping the MidiInput* stuff with MidiOutput*.
I have the midi events coming through from the f/e fine and the handler on Rust b/e is getting the messages fine, but where I'm struggling is with the MidiState struct, specifically getting access to the output property (sidenote: as I understand it, the reference to the MidiOutputConnection is put into a Mutex in the struct so that it can be accessed in other functions).
Here is my version of open_midi_connection fn that I've adapted:
#[tauri::command]
fn open_midi_connection(
midi_state: tauri::State<'_, MidiState>,
_window: Window<Wry>,
output_idx: usize
) {
// let handle = Arc::new(window).clone();
let midi_out = MidiOutput::new("orca-midi-outputs").unwrap();
let out_ports = midi_out.ports();
let out_port: &MidiOutputPort = match out_ports.len() {
// 0 => return Err(e)"no output port found".into()).unwrap(),
// 0 => Err(e) => {
// println!("no output port found")
// },
1 => {
println!("Choosing the only available output port: {}", midi_out.port_name(&out_ports[0]).unwrap());
&out_ports[0]
},
_ => {
println!("\nAvailable output ports:");
for (i, p) in out_ports.iter().enumerate() {
println!("{}: {}", i, midi_out.port_name(p).unwrap_or("There was a problem\n".to_string()));
}
out_ports.get(output_idx)
.ok_or("invalid output port selected").unwrap()
}
};
println!("\nOpening connection");
let conn_out = midi_out.connect(out_port, "midi_out_connected");
*midi_state.output.lock().unwrap() = Some(conn_out.unwrap());
println!("Connection open. Listen!");
}
So the conn_out holds the connection, and the next line stuffs it into the midi_state data structure (I deduce).
I then have another function trigger_note, which is called from the JS:
#[tauri::command]
fn trigger_note(
c: u8,
n: u8,
v: u8,
midi_state: tauri::State<'_, MidiState>
) {
println!("Hello {}, {}, {}", c,n,v);
// get the output connection from the mutex blahblah
let out_port = midi_state.output.try_lock().unwrap();
const NOTE_ON_MSG: u8 = 0x90;
const NOTE_OFF_MSG: u8 = 0x80;
const VELOCITY: u8 = 0x64;
let _ = out_port.unwrap().send(&[NOTE_ON_MSG, n, VELOCITY]);
}
This line let _ = out_port.unwrap().send(&[NOTE_ON_MSG, n, VELOCITY]); is where I have the problem; it doesn't compile because of some borrowing error, which I can't seem to pin down.
error[E0507]: cannot move out of dereference of `MutexGuard<'_, std::option::Option<MidiOutputConnection>>`
--> src/main.rs:134:11
|
134 | let _ = out_port.unwrap().send(&[NOTE_ON_MSG, n, VELOCITY]);
| ^^^^^^^^^^^^^^^^^ move occurs because value has type `std::option::Option<MidiOutputConnection>`, which does not implement the `Copy` trait
|
help: consider borrowing the `Option`'s content
|
134 | let _ = out_port.unwrap().as_ref().send(&[NOTE_ON_MSG, n, VELOCITY]);
Then on the compiler's advice, I add as_ref():
error[E0599]: no method named `as_ref` found for struct `MidiOutputConnection` in the current scope
--> src/main.rs:134:29
|
134 | let _ = out_port.unwrap().as_ref().send(&[NOTE_ON_MSG, n, VELOCITY]);
| ^^^^^^ method not found in `MidiOutputConnection`
So, I can understand as_ref() is not found in MidiOutputConnection. But why does it ask me to add it in the first place? It ,must be something that I'm not comprehending about the Mutex stuff.
My apologies for the length of this issue, I'm hoping you might be able to give me some pointers? (pun not intended!)
Many thanks