mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-22 02:58:32 +00:00
working
This commit is contained in:
parent
133a1d2e8f
commit
e75ac7b3c0
11
packages/desktopbridge/loggerbridge.mjs
Normal file
11
packages/desktopbridge/loggerbridge.mjs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { listen } from '@tauri-apps/api/event';
|
||||||
|
import { logger } from '../core/logger.mjs';
|
||||||
|
|
||||||
|
// listen for log events from the Tauri backend and log in the UI
|
||||||
|
await listen('log-event', (e) => {
|
||||||
|
if (e.payload == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { message, message_type } = e.payload;
|
||||||
|
logger(message, message_type);
|
||||||
|
});
|
||||||
20
src-tauri/src/loggerbridge.rs
Normal file
20
src-tauri/src/loggerbridge.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
use tauri::Window;
|
||||||
|
|
||||||
|
#[derive(Clone, serde::Serialize)]
|
||||||
|
pub struct LoggerPayload {
|
||||||
|
pub message: String,
|
||||||
|
pub message_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Logger {
|
||||||
|
pub window: Arc<Window>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Logger {
|
||||||
|
pub fn log(&self, message: String, message_type: String) {
|
||||||
|
println!("{}", message);
|
||||||
|
let _ = self.window.emit("log-event", LoggerPayload { message, message_type });
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,9 +3,21 @@
|
|||||||
|
|
||||||
mod midibridge;
|
mod midibridge;
|
||||||
mod oscbridge;
|
mod oscbridge;
|
||||||
|
mod loggerbridge;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::thread::sleep;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use loggerbridge::Logger;
|
||||||
|
use tauri::Manager;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
// the payload type must implement `Serialize` and `Clone`.
|
||||||
|
#[derive(Clone, serde::Serialize)]
|
||||||
|
struct Payload {
|
||||||
|
message: String,
|
||||||
|
message_type: String,
|
||||||
|
}
|
||||||
fn main() {
|
fn main() {
|
||||||
let (async_input_transmitter_midi, async_input_receiver_midi) = mpsc::channel(1);
|
let (async_input_transmitter_midi, async_input_receiver_midi) = mpsc::channel(1);
|
||||||
let (async_output_transmitter_midi, async_output_receiver_midi) = mpsc::channel(1);
|
let (async_output_transmitter_midi, async_output_receiver_midi) = mpsc::channel(1);
|
||||||
@ -20,9 +32,16 @@ fn main() {
|
|||||||
inner: Mutex::new(async_input_transmitter_osc),
|
inner: Mutex::new(async_input_transmitter_osc),
|
||||||
})
|
})
|
||||||
.invoke_handler(tauri::generate_handler![midibridge::sendmidi, oscbridge::sendosc])
|
.invoke_handler(tauri::generate_handler![midibridge::sendmidi, oscbridge::sendosc])
|
||||||
.setup(|_app| {
|
.setup(|app| {
|
||||||
midibridge::init(async_input_receiver_midi, async_output_receiver_midi, async_output_transmitter_midi);
|
let window = Arc::new(app.get_window("main").unwrap());
|
||||||
oscbridge::init(async_input_receiver_osc, async_output_receiver_osc, async_output_transmitter_osc);
|
let logger = Logger { window };
|
||||||
|
midibridge::init(
|
||||||
|
logger.clone(),
|
||||||
|
async_input_receiver_midi,
|
||||||
|
async_output_receiver_midi,
|
||||||
|
async_output_transmitter_midi
|
||||||
|
);
|
||||||
|
oscbridge::init(logger, async_input_receiver_osc, async_output_receiver_osc, async_output_transmitter_osc);
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
|
|||||||
@ -2,10 +2,13 @@ use std::collections::HashMap;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use midir::MidiOutput;
|
use midir::MidiOutput;
|
||||||
|
|
||||||
use tokio::sync::{ mpsc, Mutex };
|
use tokio::sync::{ mpsc, Mutex };
|
||||||
use tokio::time::Instant;
|
use tokio::time::Instant;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
|
|
||||||
|
use crate::loggerbridge::Logger;
|
||||||
pub struct MidiMessage {
|
pub struct MidiMessage {
|
||||||
pub message: Vec<u8>,
|
pub message: Vec<u8>,
|
||||||
pub instant: Instant,
|
pub instant: Instant,
|
||||||
@ -18,6 +21,7 @@ pub struct AsyncInputTransmit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(
|
pub fn init(
|
||||||
|
logger: Logger,
|
||||||
async_input_receiver: mpsc::Receiver<Vec<MidiMessage>>,
|
async_input_receiver: mpsc::Receiver<Vec<MidiMessage>>,
|
||||||
mut async_output_receiver: mpsc::Receiver<Vec<MidiMessage>>,
|
mut async_output_receiver: mpsc::Receiver<Vec<MidiMessage>>,
|
||||||
async_output_transmitter: mpsc::Sender<Vec<MidiMessage>>
|
async_output_transmitter: mpsc::Sender<Vec<MidiMessage>>
|
||||||
@ -50,10 +54,13 @@ pub fn init(
|
|||||||
let mut port_names = Vec::new();
|
let mut port_names = Vec::new();
|
||||||
//TODO: Send these print messages to the UI logger instead of the rust console so the user can see them
|
//TODO: Send these print messages to the UI logger instead of the rust console so the user can see them
|
||||||
if out_ports.len() == 0 {
|
if out_ports.len() == 0 {
|
||||||
println!(" No MIDI devices found. Connect a device or enable IAC Driver.");
|
logger.log(" No MIDI devices found. Connect a device or enable IAC Driver.".to_string(), "".to_string());
|
||||||
|
// logger(window, " No MIDI devices found. Connect a device or enable IAC Driver.".to_string(), None);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
println!("Found {} midi devices!", out_ports.len());
|
// give the frontend couple seconds to load on start, or the log messages will get lost
|
||||||
|
sleep(Duration::from_secs(3));
|
||||||
|
logger.log(format!("Found {} midi devices!", out_ports.len()), "".to_string());
|
||||||
|
|
||||||
// the user could reference any port at anytime during runtime,
|
// the user could reference any port at anytime during runtime,
|
||||||
// so let's go ahead and open them all (same behavior as web app)
|
// so let's go ahead and open them all (same behavior as web app)
|
||||||
@ -63,7 +70,7 @@ pub fn init(
|
|||||||
let ports = midiout.ports();
|
let ports = midiout.ports();
|
||||||
let port = ports.get(i).unwrap();
|
let port = ports.get(i).unwrap();
|
||||||
let port_name = midiout.port_name(port).unwrap();
|
let port_name = midiout.port_name(port).unwrap();
|
||||||
println!("{}", port_name);
|
logger.log(port_name.clone(), "".to_string());
|
||||||
let out_con = midiout.connect(port, &port_name).unwrap();
|
let out_con = midiout.connect(port, &port_name).unwrap();
|
||||||
port_names.insert(i, port_name.clone());
|
port_names.insert(i, port_name.clone());
|
||||||
output_connections.insert(port_name, out_con);
|
output_connections.insert(port_name, out_con);
|
||||||
@ -96,10 +103,10 @@ pub fn init(
|
|||||||
if out_con.is_some() {
|
if out_con.is_some() {
|
||||||
// process the message
|
// process the message
|
||||||
if let Err(err) = (&mut out_con.unwrap()).send(&message.message) {
|
if let Err(err) = (&mut out_con.unwrap()).send(&message.message) {
|
||||||
println!("Midi message send error: {}", err);
|
logger.log(format!("Midi message send error: {}", err), "warning".to_string());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("failed to find midi device: {}", message.requestedport);
|
logger.log(format!("failed to find midi device: {}", message.requestedport), "warning".to_string());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
use rosc::{ encoder, OscTime };
|
use rosc::{ encoder, OscTime };
|
||||||
use rosc::{ OscMessage, OscPacket, OscType, OscBundle };
|
use rosc::{ OscMessage, OscPacket, OscType, OscBundle };
|
||||||
|
|
||||||
use std::net::UdpSocket;
|
use std::net::UdpSocket;
|
||||||
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -7,6 +8,8 @@ use std::sync::Arc;
|
|||||||
use tokio::sync::{ mpsc, Mutex };
|
use tokio::sync::{ mpsc, Mutex };
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
|
|
||||||
|
use crate::loggerbridge::Logger;
|
||||||
pub struct OscMsg {
|
pub struct OscMsg {
|
||||||
pub msg_buf: Vec<u8>,
|
pub msg_buf: Vec<u8>,
|
||||||
pub timestamp: u64,
|
pub timestamp: u64,
|
||||||
@ -22,6 +25,7 @@ const NANOS_PER_SECOND: f64 = 1.0e9;
|
|||||||
const SECONDS_PER_NANO: f64 = 1.0 / NANOS_PER_SECOND;
|
const SECONDS_PER_NANO: f64 = 1.0 / NANOS_PER_SECOND;
|
||||||
|
|
||||||
pub fn init(
|
pub fn init(
|
||||||
|
logger: Logger,
|
||||||
async_input_receiver: mpsc::Receiver<Vec<OscMsg>>,
|
async_input_receiver: mpsc::Receiver<Vec<OscMsg>>,
|
||||||
mut async_output_receiver: mpsc::Receiver<Vec<OscMsg>>,
|
mut async_output_receiver: mpsc::Receiver<Vec<OscMsg>>,
|
||||||
async_output_transmitter: mpsc::Sender<Vec<OscMsg>>
|
async_output_transmitter: mpsc::Sender<Vec<OscMsg>>
|
||||||
@ -64,7 +68,10 @@ pub fn init(
|
|||||||
message_queue.retain(|message| {
|
message_queue.retain(|message| {
|
||||||
let result = sock.send(&message.msg_buf);
|
let result = sock.send(&message.msg_buf);
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
println!("OSC Message failed to send, the server might no longer be available");
|
logger.log(
|
||||||
|
format!("OSC Message failed to send, the server might no longer be available"),
|
||||||
|
"warning".to_string()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -37,14 +37,22 @@ const modules = [
|
|||||||
import('@strudel.cycles/core'),
|
import('@strudel.cycles/core'),
|
||||||
import('@strudel.cycles/tonal'),
|
import('@strudel.cycles/tonal'),
|
||||||
import('@strudel.cycles/mini'),
|
import('@strudel.cycles/mini'),
|
||||||
isTauri() ? import('@strudel/desktopbridge/midibridge.mjs') : import('@strudel.cycles/midi'),
|
|
||||||
import('@strudel.cycles/xen'),
|
import('@strudel.cycles/xen'),
|
||||||
import('@strudel.cycles/webaudio'),
|
import('@strudel.cycles/webaudio'),
|
||||||
isTauri() ? import('@strudel/desktopbridge/oscbridge.mjs') : import('@strudel.cycles/osc'),
|
|
||||||
import('@strudel.cycles/serial'),
|
import('@strudel.cycles/serial'),
|
||||||
import('@strudel.cycles/soundfonts'),
|
import('@strudel.cycles/soundfonts'),
|
||||||
import('@strudel.cycles/csound'),
|
import('@strudel.cycles/csound'),
|
||||||
];
|
];
|
||||||
|
if (isTauri()) {
|
||||||
|
modules.concat([
|
||||||
|
import('@strudel/desktopbridge/loggerbridge.mjs'),
|
||||||
|
import('@strudel/desktopbridge/midibridge.mjs'),
|
||||||
|
import('@strudel/desktopbridge/oscbridge.mjs'),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
modules.concat([import('@strudel.cycles/midi'), import('@strudel.cycles/osc')]);
|
||||||
|
}
|
||||||
|
|
||||||
const modulesLoading = evalScope(
|
const modulesLoading = evalScope(
|
||||||
controls, // sadly, this cannot be exported from core direclty
|
controls, // sadly, this cannot be exported from core direclty
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user