@@ -338,6 +338,9 @@ fn match_value(data: ColumnData) -> f32 {
338
338
#[ tauri:: command]
339
339
async fn stream_data ( window : Window ) {
340
340
let window_arc = Arc :: new ( Mutex :: new ( window) ) ;
341
+ let initial_load = Arc :: new ( AtomicBool :: new ( false ) ) ;
342
+ let initial_clone = initial_load. clone ( ) ;
343
+
341
344
loop {
342
345
let window_clone = Arc :: clone ( & window_arc) ;
343
346
@@ -448,135 +451,111 @@ async fn stream_data(window: Window) {
448
451
let result = parked. join ( ) ;
449
452
if result. is_err ( ) {
450
453
println ! ( "Thread panicked, program may have dropped data" ) ;
451
- thread:: sleep ( std:: time:: Duration :: from_secs ( 1 ) ) ;
454
+ if !initial_clone. load ( Ordering :: SeqCst ) { //close app if initial load fails (likely proxy disconnect)
455
+ std:: process:: exit ( 1 ) ;
456
+ } else {
457
+ initial_load. store ( true , Ordering :: SeqCst ) ;
458
+ thread:: sleep ( std:: time:: Duration :: from_secs ( 2 ) ) ;
459
+ }
452
460
} ;
453
461
}
454
462
}
455
463
456
464
#[ tauri:: command]
457
465
async fn fft_data ( window : Window ) {
458
- let window_arc = Arc :: new ( Mutex :: new ( window) ) ;
459
- loop {
460
- let window_clone = Arc :: clone ( & window_arc) ;
461
-
462
- let flag = Arc :: new ( AtomicBool :: new ( false ) ) ;
463
- let flag2 = Arc :: clone ( & flag) ;
466
+ let flag = Arc :: new ( AtomicBool :: new ( false ) ) ;
467
+ let flag2 = Arc :: clone ( & flag) ;
468
+
469
+ let args: Vec < String > = env:: args ( ) . collect ( ) ;
470
+ let opts = tio_opts ( ) ;
471
+ let ( _matches, root, route) = tio_parseopts ( opts, & args) ;
472
+
473
+ let mut fft_column = String :: new ( ) ;
474
+ let time_span: u8 = if args. len ( ) > 2 {
475
+ match args[ 2 ] . parse ( ) {
476
+ Ok ( val) => val,
477
+ Err ( _e) => 10
478
+ }
479
+ } else { 10 } ;
464
480
465
- let args: Vec < String > = env:: args ( ) . collect ( ) ;
466
- let opts = tio_opts ( ) ;
467
- let ( _matches, root, route) = tio_parseopts ( opts, & args) ;
481
+ let fft_parked = thread:: spawn ( move || {
482
+ while !flag2. load ( Ordering :: Relaxed ) {
483
+ thread:: park ( ) ;
484
+ }
485
+ unsafe { fft_column = FFT . clone ( ) }
468
486
469
- let mut fft_column = String :: new ( ) ;
470
- let time_span: u8 = if args. len ( ) > 2 {
471
- match args[ 2 ] . parse ( ) {
472
- Ok ( val) => val,
473
- Err ( _e) => 10
474
- }
475
- } else { 10 } ;
487
+ let proxy = proxy:: Interface :: new ( & root) ;
488
+ let device = proxy. device_full ( route) . unwrap ( ) ;
489
+ let mut device = Device :: new ( device) ;
476
490
477
- let fft_parked = thread:: spawn ( move || {
478
- while !flag2. load ( Ordering :: Relaxed ) {
479
- thread:: park ( ) ;
491
+ //get sampling & decimation rate, column metadata
492
+ let meta = device. get_metadata ( ) ;
493
+ let mut sampling_rate: Vec < u32 > = Vec :: new ( ) ;
494
+ let mut complex_ffts: Vec < String > = vec ! [ ] ;
495
+
496
+ for stream in meta. streams . values ( ) {
497
+ for col in & stream. columns {
498
+ if col. name [ ..col. name . len ( ) -1 ] == fft_column[ ..fft_column. len ( ) -1 ] {
499
+ sampling_rate. push ( stream. segment . sampling_rate ) ;
500
+ sampling_rate. push ( stream. segment . decimation ) ;
501
+ if col. name . chars ( ) . nth_back ( 1 ) . unwrap ( ) . is_numeric ( ) {
502
+ match col. name . chars ( ) . last ( ) . unwrap ( ) {
503
+ 'x' => { complex_ffts. push ( col. name . clone ( ) ) ; }
504
+ 'y' => { complex_ffts. push ( col. name . clone ( ) ) ; }
505
+ _ => { }
506
+ }
507
+ }
508
+ }
480
509
}
481
- unsafe { fft_column = FFT . clone ( ) }
510
+ }
511
+ let fs = sampling_rate[ 0 ] / sampling_rate[ 1 ] ;
512
+ let mut fft_signals: Vec < Vec < f32 > > = vec ! [ vec![ ] , vec![ ] ] ;
513
+
514
+ //Emitting FFT Data
515
+ loop {
516
+ let sample = device. next ( ) ;
517
+
518
+ for column in sample. columns {
519
+ //complex fft
520
+ if complex_ffts. contains ( & column. desc . name ) {
521
+ let parts: Vec < & str > = column. desc . name . split ( '.' ) . collect ( ) ;
522
+ match column. desc . name . chars ( ) . last ( ) . unwrap ( ) {
523
+ 'x' => { if let Some ( x_vec) = fft_signals. get_mut ( 0 ) {
524
+ x_vec. push ( match_value ( column. value . clone ( ) ) ) ;
525
+ } }
526
+ 'y' => { if let Some ( y_vec) = fft_signals. get_mut ( 1 ) { y_vec. push ( match_value ( column. value . clone ( ) ) ) ; } }
527
+ _ => { }
528
+ }
482
529
483
- let window = window_clone. lock ( ) . unwrap ( ) ;
484
- let proxy = proxy:: Interface :: new ( & root) ;
485
- let device = proxy. device_full ( route) . unwrap ( ) ;
486
- let mut device = Device :: new ( device) ;
530
+ if fft_signals[ 0 ] . len ( ) > ( fs* time_span as u32 ) . try_into ( ) . unwrap ( ) { fft_signals. iter_mut ( ) . for_each ( |col| { if !col. is_empty ( ) { col. clear ( ) ; } } ) ; }
487
531
488
- //get sampling & decimation rate, column metadata
489
- let meta = device. get_metadata ( ) ;
490
- let mut sampling_rate: Vec < u32 > = Vec :: new ( ) ;
491
- let mut complex_ffts: Vec < String > = vec ! [ ] ;
492
-
493
- for stream in meta. streams . values ( ) {
494
- for col in & stream. columns {
495
- if col. name [ ..col. name . len ( ) -1 ] == fft_column[ ..fft_column. len ( ) -1 ] {
496
- sampling_rate. push ( stream. segment . sampling_rate ) ;
497
- sampling_rate. push ( stream. segment . decimation ) ;
498
- if col. name . chars ( ) . nth_back ( 1 ) . unwrap ( ) . is_numeric ( ) {
499
- match col. name . chars ( ) . last ( ) . unwrap ( ) {
500
- 'x' => { complex_ffts. push ( col. name . clone ( ) ) ; }
501
- 'y' => { complex_ffts. push ( col. name . clone ( ) ) ; }
502
- _ => { }
503
- }
504
- }
505
- }
506
- }
507
- }
508
- let fs = sampling_rate[ 0 ] / sampling_rate[ 1 ] ;
509
- let mut fft_signals: Vec < Vec < f32 > > = vec ! [ vec![ ] , vec![ ] ] ;
510
- let mut fft_freq: Vec < Vec < f32 > > = Vec :: new ( ) ;
511
- let mut fft_power: Vec < Vec < f32 > > = Vec :: new ( ) ;
512
-
513
- //Emitting FFT Data
514
- loop {
515
- let sample = device. next ( ) ;
516
-
517
- for column in sample. columns {
518
- //complex fft
519
- if complex_ffts. contains ( & column. desc . name ) {
520
- let parts: Vec < & str > = column. desc . name . split ( '.' ) . collect ( ) ;
521
- match column. desc . name . chars ( ) . last ( ) . unwrap ( ) {
522
- 'x' => { if let Some ( x_vec) = fft_signals. get_mut ( 0 ) {
523
- x_vec. push ( match_value ( column. value . clone ( ) ) ) ;
524
- } }
525
- 'y' => { if let Some ( y_vec) = fft_signals. get_mut ( 1 ) { y_vec. push ( match_value ( column. value . clone ( ) ) ) ; } }
526
- _ => { }
532
+ if fft_signals[ 0 ] . len ( ) >= ( fs* time_span as u32 -1 ) . try_into ( ) . unwrap ( ) {
533
+ let ( freq, power) = complex_fft ( fs, fft_signals[ 0 ] . to_vec ( ) , fft_signals[ 1 ] . to_vec ( ) ) ;
534
+ if !freq. is_empty ( ) && !power. is_empty ( ) && !freq. iter ( ) . any ( |& x| x. is_nan ( ) ) && !power. iter ( ) . any ( |& x| x. is_nan ( ) ) {
535
+ let _ = window. emit ( & fft_column. clone ( ) . replace ( "." , "" ) , ( & freq, & power) ) ;
527
536
}
528
-
529
- if fft_signals[ 0 ] . len ( ) > fs. try_into ( ) . unwrap ( ) { fft_signals. iter_mut ( ) . for_each ( |col| { if !col. is_empty ( ) { col. clear ( ) ; } } ) ; }
530
-
531
- if fft_signals[ 0 ] . len ( ) >= ( fs-1 ) . try_into ( ) . unwrap ( ) {
532
- let ( freq, power) = complex_fft ( fs, fft_signals[ 0 ] . to_vec ( ) , fft_signals[ 1 ] . to_vec ( ) ) ;
533
- if !freq. is_empty ( ) && !power. is_empty ( ) && !freq. iter ( ) . any ( |& x| x. is_nan ( ) ) && !power. iter ( ) . any ( |& x| x. is_nan ( ) ) {
534
- fft_freq. push ( freq) ;
535
- fft_power. push ( power) ;
536
- }
537
- }
538
- } else if column. desc . name == fft_column { //real fft
539
- if let Some ( fft) = fft_signals. get_mut ( 0 ) { fft. push ( match_value ( column. value . clone ( ) ) ) } ;
540
- if fft_signals[ 0 ] . len ( ) > fs. try_into ( ) . unwrap ( ) { fft_signals. iter_mut ( ) . for_each ( |col| { if !col. is_empty ( ) { col. clear ( ) ; } } ) ; }
541
- if fft_signals[ 0 ] . len ( ) >= ( fs - 1 ) . try_into ( ) . unwrap ( ) {
542
- let ( freq, power) = calc_fft ( fft_signals[ 0 ] . to_vec ( ) , fs as f32 ) ;
543
- if !freq. is_empty ( ) && !power. is_empty ( ) && !freq. iter ( ) . any ( |& x| x. is_nan ( ) ) && !power. iter ( ) . any ( |& x| x. is_nan ( ) ) {
544
- fft_freq. push ( freq) ;
545
- fft_power. push ( power) ;
546
- }
537
+ }
538
+ } else if column. desc . name == fft_column { //real fft
539
+ if let Some ( fft) = fft_signals. get_mut ( 0 ) { fft. push ( match_value ( column. value . clone ( ) ) ) } ;
540
+ if fft_signals[ 0 ] . len ( ) > ( fs* time_span as u32 ) . try_into ( ) . unwrap ( ) { fft_signals. iter_mut ( ) . for_each ( |col| { if !col. is_empty ( ) { col. clear ( ) ; } } ) ; }
541
+ if fft_signals[ 0 ] . len ( ) >= ( fs* time_span as u32 -1 ) . try_into ( ) . unwrap ( ) {
542
+ let ( freq, power) = calc_fft ( fft_signals[ 0 ] . to_vec ( ) , fs as f32 ) ;
543
+ if !freq. is_empty ( ) && !power. is_empty ( ) && !freq. iter ( ) . any ( |& x| x. is_nan ( ) ) && !power. iter ( ) . any ( |& x| x. is_nan ( ) ) {
544
+ let _ = window. emit ( & fft_column. clone ( ) . replace ( "." , "" ) , ( & freq, & power) ) ;
547
545
}
548
546
}
549
547
}
550
- if fft_freq. len ( ) >= ( time_span) . try_into ( ) . unwrap ( ) {
551
- let averaged_freq: Vec < f32 > = ( 0 ..fft_freq[ 0 ] . len ( ) )
552
- . map ( |i| {
553
- let sum: f32 = fft_freq. iter ( ) . map ( |col| col[ i] ) . sum ( ) ;
554
- sum / fft_freq. len ( ) as f32
555
- } )
556
- . collect ( ) ;
557
-
558
- let averaged_power: Vec < f32 > = ( 0 ..fft_power[ 0 ] . len ( ) )
559
- . map ( |i| {
560
- let sum: f32 = fft_power. iter ( ) . map ( |col| col[ i] ) . sum ( ) ;
561
- sum / fft_power. len ( ) as f32
562
- } )
563
- . collect ( ) ;
564
-
565
- let _ = window. emit ( & fft_column. clone ( ) . replace ( "." , "" ) , ( & averaged_freq, & averaged_power) ) ;
566
- fft_freq. clear ( ) ;
567
- fft_power. clear ( ) ;
568
- }
569
- }
570
- } ) ;
571
-
572
- loop {
573
- thread:: sleep ( std:: time:: Duration :: from_millis ( 1000 ) ) ;
574
- unsafe {
575
- if SERIALCONNECTED && !FFT . is_empty ( ) {
576
- flag. store ( true , Ordering :: Relaxed ) ;
577
- fft_parked. thread ( ) . unpark ( ) ;
578
- break ;
579
- }
548
+ }
549
+ }
550
+ } ) ;
551
+
552
+ loop {
553
+ thread:: sleep ( std:: time:: Duration :: from_millis ( 1000 ) ) ;
554
+ unsafe {
555
+ if SERIALCONNECTED && !FFT . is_empty ( ) {
556
+ flag. store ( true , Ordering :: Relaxed ) ;
557
+ fft_parked. thread ( ) . unpark ( ) ;
558
+ break ;
580
559
}
581
560
}
582
561
}
0 commit comments