cardinal_gui/
e_midi.rs

1#[cfg(all(feature = "uses_e_midi", not(target_arch = "wasm32")))]
2use e_midi::MidiPlayer;
3#[cfg(feature = "uses_e_midi")]
4pub fn init() {
5    // Initialize e_midi functionality here
6}
7
8#[cfg(feature = "uses_e_midi")]
9#[allow(unused_imports)]
10use std::sync::{mpsc, Arc, atomic::{AtomicBool, Ordering}};
11#[cfg(feature = "uses_e_midi")]
12use std::thread;
13
14#[cfg(feature = "uses_e_midi")]
15#[allow(dead_code)]
16pub struct MidiPlayerThread {
17    handle: thread::JoinHandle<()>,
18    shutdown_tx: mpsc::Sender<()>,
19}
20
21#[cfg(all(feature = "uses_e_midi", not(target_arch = "wasm32")))]
22impl MidiPlayerThread {
23    pub fn start() -> Self {
24        let (shutdown_tx, shutdown_rx) = mpsc::channel();
25        let running = Arc::new(AtomicBool::new(true));
26        let running_clone = running.clone();
27
28        let handle = thread::spawn(move || {
29            let mut player = match MidiPlayer::new() {
30                Ok(p) => p,
31                Err(e) => {
32                    eprintln!("Failed to create MidiPlayer: {e}");
33                    return;
34                }
35            };
36            let numsongs = player.get_total_song_count();
37            println!("Total songs: {numsongs}");
38
39            'outer: for i in 0..numsongs {
40                println!("Playing song {}", i + 1);
41                if let Err(e) = player.play_song(i, None, None) {
42                    eprintln!("Failed to play song {}: {e}", i + 1);
43                    continue;
44                }
45                // Wait until the song finishes or shutdown is requested
46                loop {
47                    // Check for shutdown signal
48                    if shutdown_rx.try_recv().is_ok() {
49                        running_clone.store(false, Ordering::SeqCst);
50                        // Stop playback immediately if playing
51                        // if player.is_playing() {
52                        player.stop_playback();
53                        // }
54                        break 'outer;
55                    }
56                    if !player.is_playing() {
57                        break;
58                    }
59                    std::thread::yield_now();
60                    // std::thread::sleep(std::time::Duration::from_millis(100));
61                }
62            }
63            // Optionally: stop playback if still playing
64            if player.is_playing() {
65                player.stop_playback();
66            }
67        });
68
69        MidiPlayerThread { handle, shutdown_tx }
70    }
71
72    pub fn shutdown(self) {
73        println!("Shutting down MidiPlayerThread...");
74        let _ = self.shutdown_tx.send(());
75        // Wait a short time to allow the thread to break out of its loop
76        std::thread::sleep(std::time::Duration::from_millis(200));
77        let _ = self.handle.join();
78        println!("MidiPlayerThread has shut down.");
79        // std::process::exit(0); // Remove this, let the main thread exit naturally
80    }
81}