@@ -189,18 +189,18 @@ fn main() -> Result<(), Box<dyn Error>> {
189189 } ) ) ;
190190
191191 let mut tui = Tui :: new ( ) ?;
192- if let Err ( err) = run_tui ( & mut tui. terminal , app_state, initial_stream) {
192+ if let Err ( err) = run_tui ( & mut tui. terminal , app_state, initial_stream, args . mic ) {
193193 eprintln ! ( "App error: {:?}" , err) ;
194194 }
195195 } else {
196- pollster:: block_on ( run_gui ( app_state, initial_stream, args. fullscreen , args. gpu_fft , args. bench ) ) ;
196+ pollster:: block_on ( run_gui ( app_state, initial_stream, args. fullscreen , args. gpu_fft , args. bench , args . mic ) ) ;
197197 }
198198
199199 Ok ( ( ) )
200200}
201201
202202#[ allow( unused_variables, unused_assignments) ]
203- async fn run_gui ( app_state : Arc < Mutex < AppState > > , mut active_stream : Option < audio:: PlaybackHandle > , is_fullscreen : bool , use_gpu_fft : bool , bench : Option < u32 > ) {
203+ async fn run_gui ( app_state : Arc < Mutex < AppState > > , mut active_stream : Option < audio:: PlaybackHandle > , is_fullscreen : bool , use_gpu_fft : bool , bench : Option < u32 > , is_mic_launch : bool ) {
204204 if use_gpu_fft {
205205 let mut state = app_state. lock ( ) . unwrap ( ) ;
206206 state. gpu_fft = true ;
@@ -566,6 +566,23 @@ async fn run_gui(app_state: Arc<Mutex<AppState>>, mut active_stream: Option<audi
566566 let load_path = {
567567 let mut state = app_state. lock ( ) . unwrap ( ) ;
568568
569+ if state. audio_device_lost {
570+ state. audio_device_lost = false ;
571+ let reload_path = if is_mic_launch {
572+ "" . to_string ( )
573+ } else if state. playlist_index < state. playlist . len ( ) {
574+ state. playlist [ state. playlist_index ] . clone ( )
575+ } else {
576+ state. song_title . clone ( )
577+ } ;
578+
579+ if !reload_path. is_empty ( ) || is_mic_launch {
580+ state. load_request = Some ( reload_path) ;
581+ state. osd_text = Some ( "Audio Device Reconnected" . to_string ( ) ) ;
582+ state. osd_timer = 3.0 ;
583+ }
584+ }
585+
569586 if state. track_ended {
570587 state. track_ended = false ;
571588 if state. load_request . is_none ( ) {
@@ -580,8 +597,9 @@ async fn run_gui(app_state: Arc<Mutex<AppState>>, mut active_stream: Option<audi
580597 } ;
581598
582599 if let Some ( path) = load_path {
600+ let is_mic = is_mic_launch && path. is_empty ( ) ;
583601 // Check if the path exists first!
584- let path_exists = if path. starts_with ( "http" ) {
602+ let path_exists = if path. starts_with ( "http" ) || is_mic {
585603 true
586604 } else {
587605 std:: path:: Path :: new ( & path) . exists ( )
@@ -621,31 +639,44 @@ async fn run_gui(app_state: Arc<Mutex<AppState>>, mut active_stream: Option<audi
621639
622640 // We rely entirely on DSP thread messages to update tracker string state
623641 let mut loaded_stream = None ;
642+ let mut last_err = None ;
624643 for _ in 0 ..5 {
625- if let Ok ( stream) = audio:: start_audio_thread ( & path, false , Arc :: clone ( & app_state) ) {
626- loaded_stream = Some ( stream) ;
627- break ;
644+ match audio:: start_audio_thread ( & path, is_mic, Arc :: clone ( & app_state) ) {
645+ Ok ( stream) => {
646+ loaded_stream = Some ( stream) ;
647+ break ;
648+ }
649+ Err ( e) => {
650+ last_err = Some ( e) ;
651+ }
628652 }
629653 std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 50 ) ) ;
630654 }
631655
632656 if let Some ( stream) = loaded_stream {
633657 let mut state = app_state. lock ( ) . unwrap ( ) ;
634658 state. file_loaded = true ;
635- state. song_title = path. clone ( ) ;
659+ state. song_title = if is_mic { "Microphone Input" . to_string ( ) } else { path. clone ( ) } ;
636660 state. track_ended = false ;
637661 active_stream = Some ( stream) ;
638662 } else {
639663 let mut state = app_state. lock ( ) . unwrap ( ) ;
640- state. osd_text = Some ( format ! ( "Load Failed: {}" , std:: path:: Path :: new( & path) . file_name( ) . unwrap_or_default( ) . to_string_lossy( ) ) ) ;
641- state. osd_timer = 3.0 ;
664+ let err_msg = last_err. map ( |e| format ! ( "{:?}" , e) ) . unwrap_or_else ( || "Unknown error" . to_string ( ) ) ;
665+ let file_name = if is_mic { "Microphone" . to_string ( ) } else { std:: path:: Path :: new ( & path) . file_name ( ) . unwrap_or_default ( ) . to_string_lossy ( ) . into_owned ( ) } ;
666+ state. osd_text = Some ( format ! ( "Load Failed: {}\n {}" , file_name, err_msg) ) ;
667+ state. osd_timer = 5.0 ;
642668
643- state. playlist_index += 1 ;
644- if state. playlist_index < state. playlist . len ( ) {
645- state. load_request = Some ( state. playlist [ state. playlist_index ] . clone ( ) ) ;
669+ if !is_mic {
670+ state. playlist_index += 1 ;
671+ if state. playlist_index < state. playlist . len ( ) {
672+ state. load_request = Some ( state. playlist [ state. playlist_index ] . clone ( ) ) ;
673+ } else {
674+ state. file_loaded = false ;
675+ state. artist = "Load Failed" . to_string ( ) ;
676+ }
646677 } else {
647678 state. file_loaded = false ;
648- state. artist = "Load Failed" . to_string ( ) ;
679+ state. artist = "Mic Failed" . to_string ( ) ;
649680 }
650681 }
651682 }
@@ -1374,6 +1405,7 @@ fn run_tui<B: Backend>(
13741405 terminal : & mut Terminal < B > ,
13751406 app_state : Arc < Mutex < AppState > > ,
13761407 mut active_stream : Option < audio:: PlaybackHandle > ,
1408+ is_mic_launch : bool ,
13771409) -> io:: Result < ( ) >
13781410where std:: io:: Error : From < <B as Backend >:: Error >
13791411{
@@ -1390,6 +1422,23 @@ where std::io::Error: From<<B as Backend>::Error>
13901422 let load_path = {
13911423 let mut state = app_state. lock ( ) . unwrap ( ) ;
13921424
1425+ if state. audio_device_lost {
1426+ state. audio_device_lost = false ;
1427+ let reload_path = if is_mic_launch {
1428+ "" . to_string ( )
1429+ } else if state. playlist_index < state. playlist . len ( ) {
1430+ state. playlist [ state. playlist_index ] . clone ( )
1431+ } else {
1432+ state. song_title . clone ( )
1433+ } ;
1434+
1435+ if !reload_path. is_empty ( ) || is_mic_launch {
1436+ state. load_request = Some ( reload_path) ;
1437+ state. osd_text = Some ( "Audio Device Reconnected" . to_string ( ) ) ;
1438+ state. osd_timer = 3.0 ;
1439+ }
1440+ }
1441+
13931442 if state. track_ended {
13941443 state. track_ended = false ;
13951444 if state. load_request . is_none ( ) {
@@ -1404,8 +1453,9 @@ where std::io::Error: From<<B as Backend>::Error>
14041453 } ;
14051454
14061455 if let Some ( path) = load_path {
1456+ let is_mic = is_mic_launch && path. is_empty ( ) ;
14071457 // Check if the path exists first!
1408- let path_exists = if path. starts_with ( "http" ) {
1458+ let path_exists = if path. starts_with ( "http" ) || is_mic {
14091459 true
14101460 } else {
14111461 std:: path:: Path :: new ( & path) . exists ( )
@@ -1432,28 +1482,44 @@ where std::io::Error: From<<B as Backend>::Error>
14321482 active_stream = None ; // DROP OLD STREAM FIRST
14331483
14341484 let mut loaded_stream = None ;
1485+ let mut last_err = None ;
14351486 for _ in 0 ..5 {
1436- if let Ok ( stream) = audio:: start_audio_thread ( & path, false , Arc :: clone ( & app_state) ) {
1437- loaded_stream = Some ( stream) ;
1438- break ;
1487+ match audio:: start_audio_thread ( & path, is_mic, Arc :: clone ( & app_state) ) {
1488+ Ok ( stream) => {
1489+ loaded_stream = Some ( stream) ;
1490+ break ;
1491+ }
1492+ Err ( e) => {
1493+ last_err = Some ( e) ;
1494+ }
14391495 }
14401496 std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 50 ) ) ;
14411497 }
14421498
14431499 if let Some ( stream) = loaded_stream {
14441500 let mut state = app_state. lock ( ) . unwrap ( ) ;
14451501 state. file_loaded = true ;
1446- state. song_title = path. clone ( ) ;
1502+ state. song_title = if is_mic { "Microphone Input" . to_string ( ) } else { path. clone ( ) } ;
14471503 state. track_ended = false ;
14481504 active_stream = Some ( stream) ;
14491505 } else {
14501506 let mut state = app_state. lock ( ) . unwrap ( ) ;
1451- state. playlist_index += 1 ;
1452- if state. playlist_index < state. playlist . len ( ) {
1453- state. load_request = Some ( state. playlist [ state. playlist_index ] . clone ( ) ) ;
1507+ let err_msg = last_err. map ( |e| format ! ( "{:?}" , e) ) . unwrap_or_else ( || "Unknown error" . to_string ( ) ) ;
1508+ let file_name = if is_mic { "Microphone" . to_string ( ) } else { std:: path:: Path :: new ( & path) . file_name ( ) . unwrap_or_default ( ) . to_string_lossy ( ) . into_owned ( ) } ;
1509+ state. osd_text = Some ( format ! ( "Load Failed: {}\n {}" , file_name, err_msg) ) ;
1510+ state. osd_timer = 5.0 ;
1511+
1512+ if !is_mic {
1513+ state. playlist_index += 1 ;
1514+ if state. playlist_index < state. playlist . len ( ) {
1515+ state. load_request = Some ( state. playlist [ state. playlist_index ] . clone ( ) ) ;
1516+ } else {
1517+ state. file_loaded = false ;
1518+ state. artist = format ! ( "Load Failed: {}" , err_msg) ;
1519+ }
14541520 } else {
14551521 state. file_loaded = false ;
1456- state. artist = "Load Failed" . to_string ( ) ;
1522+ state. artist = format ! ( "Mic Failed: {}" , err_msg ) ;
14571523 }
14581524 }
14591525 }
0 commit comments