sofieff commited on
Commit
aa8d04f
Β·
1 Parent(s): c2929af

4 movements only

Browse files
Files changed (2) hide show
  1. app.py +71 -64
  2. sound_library.py +71 -64
app.py CHANGED
@@ -83,7 +83,7 @@ def get_movement_sounds() -> Dict[str, str]:
83
  """Get the current sound files for each movement."""
84
  sounds = {}
85
  for movement, sound_file in sound_manager.current_sound_mapping.items():
86
- if movement in ['left_hand', 'right_hand', 'left_leg', "right_leg", 'tongue']: # Only show main movements
87
  if sound_file is not None: # Check if sound_file is not None
88
  sound_path = sound_manager.sound_dir / sound_file
89
  if sound_path.exists():
@@ -123,19 +123,28 @@ def start_composition():
123
  # Process classification
124
  result = sound_manager.process_classification(predicted_name, confidence, CONFIDENCE_THRESHOLD)
125
 
 
 
126
  # Always check for DJ mode transition after classification
127
  dj_transitioned = sound_manager.transition_to_dj_phase()
128
  print(f"DEBUG: DJ mode transitioned: {dj_transitioned}, current_phase: {sound_manager.current_phase}")
129
 
130
- # Create visualization
131
- fig = create_eeg_plot(epoch_data, target_movement, predicted_name, confidence, result['sound_added'])
 
 
 
 
 
 
 
132
 
133
  # Initialize all audio components to None (no sound by default)
134
  left_hand_audio = None
135
  right_hand_audio = None
136
  left_leg_audio = None
137
  right_leg_audio = None
138
- tongue_audio = None
139
 
140
  # Debug: Print classification result
141
  print(f"DEBUG start_composition: predicted={predicted_name}, confidence={confidence:.3f}, sound_added={result['sound_added']}")
@@ -156,9 +165,9 @@ def start_composition():
156
  elif predicted_name == 'right_leg' and 'right_leg' in sounds:
157
  right_leg_audio = sounds['right_leg']
158
  print(f"DEBUG: Setting right_leg_audio to {sounds['right_leg']}")
159
- elif predicted_name == 'tongue' and 'tongue' in sounds:
160
- tongue_audio = sounds['tongue']
161
- print(f"DEBUG: Setting tongue_audio to {sounds['tongue']}")
162
  else:
163
  print("DEBUG: No sound added - confidence too low or other issue")
164
 
@@ -187,7 +196,7 @@ def start_composition():
187
  right_hand_audio,
188
  left_leg_audio,
189
  right_leg_audio,
190
- tongue_audio,
191
  status_text
192
  )
193
 
@@ -286,7 +295,7 @@ def start_automatic_composition():
286
  right_hand_audio = None
287
  left_leg_audio = None
288
  right_leg_audio = None
289
- tongue_audio = None
290
 
291
  # Debug: Print classification result
292
  print(f"DEBUG start_automatic_composition: predicted={predicted_name}, confidence={confidence:.3f}, sound_added={result['sound_added']}")
@@ -311,9 +320,9 @@ def start_automatic_composition():
311
  if 'right_leg' in completed_movements and 'right_leg' in sounds:
312
  right_leg_audio = sounds['right_leg']
313
  print(f"DEBUG DJ: Right leg playing: {sounds['right_leg']}")
314
- if 'tongue' in completed_movements and 'tongue' in sounds:
315
- tongue_audio = sounds['tongue']
316
- print(f"DEBUG DJ: Tongue playing: {sounds['tongue']}")
317
  print(f"DEBUG DJ: {len(completed_movements)} individual sounds playing with effects applied")
318
  else:
319
  # Building Phase - create and show layered composition
@@ -340,9 +349,9 @@ def start_automatic_composition():
340
  if 'right_leg' in completed_movements and 'right_leg' in sounds:
341
  right_leg_audio = sounds['right_leg']
342
  print(f"DEBUG: Right leg playing: {sounds['right_leg']}")
343
- if 'tongue' in completed_movements and 'tongue' in sounds:
344
- tongue_audio = sounds['tongue']
345
- print(f"DEBUG: Tongue playing: {sounds['tongue']}")
346
 
347
  print(f"DEBUG: {len(completed_movements)} individual sounds will play together creating layered composition")
348
 
@@ -393,7 +402,7 @@ def start_automatic_composition():
393
  right_hand_audio,
394
  left_leg_audio,
395
  right_leg_audio,
396
- tongue_audio,
397
  status_text,
398
  gr.update(visible=building_visible), # building_instructions
399
  gr.update(visible=dj_visible) # dj_instructions
@@ -433,7 +442,7 @@ def manual_classify():
433
  right_hand_audio = sounds.get('right_hand', None)
434
  left_leg_audio = sounds.get('left_leg', None)
435
  right_leg_audio = sounds.get('right_leg', None)
436
- tongue_audio = sounds.get('tongue', None)
437
 
438
  return (
439
  target_text,
@@ -445,7 +454,7 @@ def manual_classify():
445
  right_hand_audio,
446
  left_leg_audio,
447
  right_leg_audio,
448
- tongue_audio
449
  )
450
 
451
  def clear_manual():
@@ -553,7 +562,7 @@ def continue_automatic_composition():
553
  right_hand_audio = None
554
  left_leg_audio = None
555
  right_leg_audio = None
556
- tongue_audio = None
557
 
558
  # Handle audio differently based on phase
559
  if sound_manager.current_phase == "dj_effects":
@@ -565,7 +574,7 @@ def continue_automatic_composition():
565
  right_hand_audio = None
566
  left_leg_audio = None
567
  right_leg_audio = None
568
- tongue_audio = None
569
  # The mixed_track will be shown in a dedicated gr.Audio component in the UI (update UI accordingly)
570
  else:
571
  # Building Mode: Display individual sounds in their respective players for layered composition
@@ -591,9 +600,9 @@ def continue_automatic_composition():
591
  if 'right_leg' in completed_movements and 'right_leg' in sounds:
592
  right_leg_audio = sounds['right_leg']
593
  print(f"DEBUG continue: Right leg playing: {sounds['right_leg']}")
594
- if 'tongue' in completed_movements and 'tongue' in sounds:
595
- tongue_audio = sounds['tongue']
596
- print(f"DEBUG continue: Tongue playing: {sounds['tongue']}")
597
 
598
  print(f"DEBUG continue: {len(completed_movements)} individual sounds will play together creating layered composition")
599
 
@@ -633,7 +642,7 @@ def continue_automatic_composition():
633
  right_hand_audio,
634
  left_leg_audio,
635
  right_leg_audio,
636
- tongue_audio,
637
  status_text,
638
  gr.update(visible=building_visible), # building_instructions
639
  gr.update(visible=dj_visible) # dj_instructions
@@ -682,7 +691,7 @@ def classify_epoch():
682
  right_hand_audio = None
683
  left_leg_audio = None
684
  right_leg_audio = None
685
- tongue_audio = None
686
 
687
  # Always assign all completed movement sounds to their respective audio slots
688
  sounds = get_movement_sounds()
@@ -695,8 +704,8 @@ def classify_epoch():
695
  left_leg_audio = sounds['left_leg']
696
  if 'right_leg' in completed_movements and 'right_leg' in sounds:
697
  right_leg_audio = sounds['right_leg']
698
- if 'tongue' in completed_movements and 'tongue' in sounds:
699
- tongue_audio = sounds['tongue']
700
 
701
  # Format next target
702
  next_target = sound_manager.get_current_target_movement()
@@ -717,7 +726,7 @@ def classify_epoch():
717
  right_hand_audio,
718
  left_leg_audio,
719
  right_leg_audio,
720
- tongue_audio,
721
  status_text
722
  )
723
 
@@ -784,8 +793,6 @@ def create_interface():
784
  **Motor Imagery Training:**
785
  - **Imagine** opening or closing your **right or left hand**
786
  - **Visualize** briefly moving your **right or left leg or foot**
787
- - **Think about** pronouncing **"L"** with your tongue
788
- - **Rest state** (no movement imagination)
789
 
790
  *🌟 Each successful imagination creates a musical layer!*
791
 
@@ -804,7 +811,7 @@ def create_interface():
804
  - πŸ‘‰ **Right Hand**: High Pass Filter On/Off
805
  - 🦡 **Left Leg**: Reverb Effect On/Off
806
  - 🦡 **Right Leg**: Low Pass Filter On/Off
807
- - πŸ‘… **Tongue**: Bass Boost On/Off
808
 
809
  *πŸŽ›οΈ Each movement toggles an effect - Mix your creation!*
810
  """)
@@ -845,7 +852,7 @@ def create_interface():
845
  right_hand_sound = gr.Audio(label="πŸ‘‰ Right Hand", interactive=False, autoplay=True, visible=True)
846
  left_leg_sound = gr.Audio(label="🦡 Left Leg", interactive=False, autoplay=True, visible=True)
847
  right_leg_sound = gr.Audio(label="🦡 Right Leg", interactive=False, autoplay=True, visible=True)
848
- tongue_sound = gr.Audio(label="πŸ‘… Tongue", interactive=False, autoplay=True, visible=True)
849
 
850
  # Composition status
851
  composition_status = gr.Textbox(label="Composition Status", interactive=False, lines=5)
@@ -878,7 +885,7 @@ def create_interface():
878
  manual_right_hand_sound = gr.Audio(label="πŸ‘‰ Right Hand", interactive=False, autoplay=False, visible=True)
879
  manual_left_leg_sound = gr.Audio(label="🦡 Left Leg", interactive=False, autoplay=False, visible=True)
880
  manual_right_leg_sound = gr.Audio(label="🦡 Right Leg", interactive=False, autoplay=False, visible=True)
881
- manual_tongue_sound = gr.Audio(label="πŸ‘… Tongue", interactive=False, autoplay=False, visible=True)
882
 
883
  # Session management functions
884
  def start_new_session():
@@ -901,10 +908,10 @@ def create_interface():
901
  result[6], # right_hand_sound
902
  result[7], # left_leg_sound
903
  result[8], # right_leg_sound
904
- result[9], # tongue_sound
905
- result[10], # composition_status
906
- result[11], # building_instructions
907
- result[12], # dj_instructions
908
  gr.update(visible=True), # continue_btn - show it
909
  gr.update(active=True), # timer - activate it
910
  gr.update(visible=False) # session_complete_row - hide it
@@ -926,10 +933,10 @@ def create_interface():
926
  result[6], # right_hand_sound
927
  result[7], # left_leg_sound
928
  result[8], # right_leg_sound
929
- result[9], # tongue_sound
930
- result[10], # composition_status
931
- result[11], # building_instructions
932
- result[12], # dj_instructions
933
  gr.update(visible=True), # continue_btn - show it
934
  gr.update(active=True), # timer - activate it
935
  gr.update(visible=False) # session_complete_row - hide it
@@ -950,10 +957,10 @@ def create_interface():
950
  result[6], # right_hand_sound
951
  result[7], # left_leg_sound
952
  result[8], # right_leg_sound
953
- result[9], # tongue_sound
954
- result[10], # composition_status
955
- result[11], # building_instructions
956
- result[12], # dj_instructions
957
  gr.update(visible=True), # continue_btn - show it
958
  gr.update(active=True) # timer - activate it
959
  )
@@ -975,10 +982,10 @@ def create_interface():
975
  result[6], # right_hand_sound
976
  result[7], # left_leg_sound
977
  result[8], # right_leg_sound
978
- result[9], # tongue_sound
979
- result[10], # composition_status
980
- result[11], # building_instructions
981
- result[12], # dj_instructions
982
  gr.update(active=False), # timer - deactivate it
983
  gr.update(visible=True) # session_complete_row - show options
984
  )
@@ -995,10 +1002,10 @@ def create_interface():
995
  result[6], # right_hand_sound
996
  result[7], # left_leg_sound
997
  result[8], # right_leg_sound
998
- result[9], # tongue_sound
999
- result[10], # composition_status
1000
- result[11], # building_instructions
1001
- result[12], # dj_instructions
1002
  gr.update(active=False), # timer - deactivate it
1003
  gr.update(visible=False) # session_complete_row - keep hidden
1004
  )
@@ -1014,10 +1021,10 @@ def create_interface():
1014
  result[6], # right_hand_sound
1015
  result[7], # left_leg_sound
1016
  result[8], # right_leg_sound
1017
- result[9], # tongue_sound
1018
- result[10], # composition_status
1019
- result[11], # building_instructions
1020
- result[12], # dj_instructions
1021
  gr.update(active=True), # timer - keep active
1022
  gr.update(visible=False) # session_complete_row - keep hidden
1023
  )
@@ -1026,14 +1033,14 @@ def create_interface():
1026
  start_btn.click(
1027
  fn=start_with_timer,
1028
  outputs=[target_display, predicted_display, timer_display, user_prompt, eeg_plot,
1029
- left_hand_sound, right_hand_sound, left_leg_sound, right_leg_sound, tongue_sound, composition_status,
1030
  building_instructions, dj_instructions, continue_btn, timer]
1031
  )
1032
 
1033
  continue_btn.click(
1034
  fn=continue_with_timer,
1035
  outputs=[target_display, predicted_display, timer_display, user_prompt, eeg_plot,
1036
- left_hand_sound, right_hand_sound, left_leg_sound, right_leg_sound, tongue_sound, composition_status,
1037
  building_instructions, dj_instructions, timer, session_complete_row]
1038
  )
1039
 
@@ -1041,7 +1048,7 @@ def create_interface():
1041
  timer.tick(
1042
  fn=continue_with_timer,
1043
  outputs=[target_display, predicted_display, timer_display, user_prompt, eeg_plot,
1044
- left_hand_sound, right_hand_sound, left_leg_sound, right_leg_sound, tongue_sound, composition_status,
1045
  building_instructions, dj_instructions, timer, session_complete_row]
1046
  )
1047
 
@@ -1049,14 +1056,14 @@ def create_interface():
1049
  new_session_btn.click(
1050
  fn=start_new_session,
1051
  outputs=[target_display, predicted_display, timer_display, user_prompt, eeg_plot,
1052
- left_hand_sound, right_hand_sound, left_leg_sound, right_leg_sound, tongue_sound, composition_status,
1053
  building_instructions, dj_instructions, continue_btn, timer, session_complete_row]
1054
  )
1055
 
1056
  extend_session_btn.click(
1057
  fn=extend_current_session,
1058
  outputs=[target_display, predicted_display, timer_display, user_prompt, eeg_plot,
1059
- left_hand_sound, right_hand_sound, left_leg_sound, right_leg_sound, tongue_sound, composition_status,
1060
  building_instructions, dj_instructions, continue_btn, timer, session_complete_row]
1061
  )
1062
 
@@ -1081,13 +1088,13 @@ def create_interface():
1081
  classify_btn.click(
1082
  fn=manual_classify,
1083
  outputs=[manual_target_display, manual_predicted_display, manual_timer_display, manual_eeg_plot, manual_results,
1084
- manual_left_hand_sound, manual_right_hand_sound, manual_left_leg_sound, manual_right_leg_sound, manual_tongue_sound]
1085
  )
1086
 
1087
  clear_btn.click(
1088
  fn=clear_manual,
1089
  outputs=[manual_target_display, manual_predicted_display, manual_timer_display, manual_eeg_plot, manual_results,
1090
- manual_left_hand_sound, manual_right_hand_sound, manual_left_leg_sound, manual_right_leg_sound, manual_tongue_sound]
1091
  )
1092
 
1093
  # Note: No auto-loading of sounds to prevent playing all sounds on startup
 
83
  """Get the current sound files for each movement."""
84
  sounds = {}
85
  for movement, sound_file in sound_manager.current_sound_mapping.items():
86
+ if movement in ['left_hand', 'right_hand', 'left_leg', "right_leg"]: # Only show main movements
87
  if sound_file is not None: # Check if sound_file is not None
88
  sound_path = sound_manager.sound_dir / sound_file
89
  if sound_path.exists():
 
123
  # Process classification
124
  result = sound_manager.process_classification(predicted_name, confidence, CONFIDENCE_THRESHOLD)
125
 
126
+ # Debug: Print composition layers before DJ mode transition
127
+ print(f"DEBUG: composition_layers before DJ check: {[layer['sound_file'] for layer in sound_manager.composition_layers]}")
128
  # Always check for DJ mode transition after classification
129
  dj_transitioned = sound_manager.transition_to_dj_phase()
130
  print(f"DEBUG: DJ mode transitioned: {dj_transitioned}, current_phase: {sound_manager.current_phase}")
131
 
132
+ # Stop EEG visualization if all 4 unique sound layers are present
133
+ unique_sounds = set([layer['sound_file'] for layer in sound_manager.composition_layers if layer.get('sound_file')])
134
+ if len(unique_sounds) >= 4 and sound_manager.current_phase != "dj_effects":
135
+ fig = None
136
+ print("DEBUG: EEG visualization stopped (all sounds present)")
137
+ else:
138
+ fig = create_eeg_plot(epoch_data, target_movement, predicted_name, confidence, result['sound_added'])
139
+ if sound_manager.current_phase == "dj_effects":
140
+ print("DEBUG: EEG visualization restarted for DJ mode")
141
 
142
  # Initialize all audio components to None (no sound by default)
143
  left_hand_audio = None
144
  right_hand_audio = None
145
  left_leg_audio = None
146
  right_leg_audio = None
147
+ #tongue_audio = None
148
 
149
  # Debug: Print classification result
150
  print(f"DEBUG start_composition: predicted={predicted_name}, confidence={confidence:.3f}, sound_added={result['sound_added']}")
 
165
  elif predicted_name == 'right_leg' and 'right_leg' in sounds:
166
  right_leg_audio = sounds['right_leg']
167
  print(f"DEBUG: Setting right_leg_audio to {sounds['right_leg']}")
168
+ # elif predicted_name == 'tongue' and 'tongue' in sounds:
169
+ # tongue_audio = sounds['tongue']
170
+ # print(f"DEBUG: Setting tongue_audio to {sounds['tongue']}")
171
  else:
172
  print("DEBUG: No sound added - confidence too low or other issue")
173
 
 
196
  right_hand_audio,
197
  left_leg_audio,
198
  right_leg_audio,
199
+ #tongue_audio,
200
  status_text
201
  )
202
 
 
295
  right_hand_audio = None
296
  left_leg_audio = None
297
  right_leg_audio = None
298
+ #tongue_audio = None
299
 
300
  # Debug: Print classification result
301
  print(f"DEBUG start_automatic_composition: predicted={predicted_name}, confidence={confidence:.3f}, sound_added={result['sound_added']}")
 
320
  if 'right_leg' in completed_movements and 'right_leg' in sounds:
321
  right_leg_audio = sounds['right_leg']
322
  print(f"DEBUG DJ: Right leg playing: {sounds['right_leg']}")
323
+ # if 'tongue' in completed_movements and 'tongue' in sounds:
324
+ # tongue_audio = sounds['tongue']
325
+ # print(f"DEBUG DJ: Tongue playing: {sounds['tongue']}")
326
  print(f"DEBUG DJ: {len(completed_movements)} individual sounds playing with effects applied")
327
  else:
328
  # Building Phase - create and show layered composition
 
349
  if 'right_leg' in completed_movements and 'right_leg' in sounds:
350
  right_leg_audio = sounds['right_leg']
351
  print(f"DEBUG: Right leg playing: {sounds['right_leg']}")
352
+ # if 'tongue' in completed_movements and 'tongue' in sounds:
353
+ # tongue_audio = sounds['tongue']
354
+ # print(f"DEBUG: Tongue playing: {sounds['tongue']}")
355
 
356
  print(f"DEBUG: {len(completed_movements)} individual sounds will play together creating layered composition")
357
 
 
402
  right_hand_audio,
403
  left_leg_audio,
404
  right_leg_audio,
405
+ #tongue_audio,
406
  status_text,
407
  gr.update(visible=building_visible), # building_instructions
408
  gr.update(visible=dj_visible) # dj_instructions
 
442
  right_hand_audio = sounds.get('right_hand', None)
443
  left_leg_audio = sounds.get('left_leg', None)
444
  right_leg_audio = sounds.get('right_leg', None)
445
+ #tongue_audio = sounds.get('tongue', None)
446
 
447
  return (
448
  target_text,
 
454
  right_hand_audio,
455
  left_leg_audio,
456
  right_leg_audio,
457
+ #tongue_audio
458
  )
459
 
460
  def clear_manual():
 
562
  right_hand_audio = None
563
  left_leg_audio = None
564
  right_leg_audio = None
565
+ #tongue_audio = None
566
 
567
  # Handle audio differently based on phase
568
  if sound_manager.current_phase == "dj_effects":
 
574
  right_hand_audio = None
575
  left_leg_audio = None
576
  right_leg_audio = None
577
+ #tongue_audio = None
578
  # The mixed_track will be shown in a dedicated gr.Audio component in the UI (update UI accordingly)
579
  else:
580
  # Building Mode: Display individual sounds in their respective players for layered composition
 
600
  if 'right_leg' in completed_movements and 'right_leg' in sounds:
601
  right_leg_audio = sounds['right_leg']
602
  print(f"DEBUG continue: Right leg playing: {sounds['right_leg']}")
603
+ # if 'tongue' in completed_movements and 'tongue' in sounds:
604
+ # tongue_audio = sounds['tongue']
605
+ # print(f"DEBUG continue: Tongue playing: {sounds['tongue']}")
606
 
607
  print(f"DEBUG continue: {len(completed_movements)} individual sounds will play together creating layered composition")
608
 
 
642
  right_hand_audio,
643
  left_leg_audio,
644
  right_leg_audio,
645
+ #tongue_audio,
646
  status_text,
647
  gr.update(visible=building_visible), # building_instructions
648
  gr.update(visible=dj_visible) # dj_instructions
 
691
  right_hand_audio = None
692
  left_leg_audio = None
693
  right_leg_audio = None
694
+ #tongue_audio = None
695
 
696
  # Always assign all completed movement sounds to their respective audio slots
697
  sounds = get_movement_sounds()
 
704
  left_leg_audio = sounds['left_leg']
705
  if 'right_leg' in completed_movements and 'right_leg' in sounds:
706
  right_leg_audio = sounds['right_leg']
707
+ # if 'tongue' in completed_movements and 'tongue' in sounds:
708
+ # tongue_audio = sounds['tongue']
709
 
710
  # Format next target
711
  next_target = sound_manager.get_current_target_movement()
 
726
  right_hand_audio,
727
  left_leg_audio,
728
  right_leg_audio,
729
+ ##tongue_audio,
730
  status_text
731
  )
732
 
 
793
  **Motor Imagery Training:**
794
  - **Imagine** opening or closing your **right or left hand**
795
  - **Visualize** briefly moving your **right or left leg or foot**
 
 
796
 
797
  *🌟 Each successful imagination creates a musical layer!*
798
 
 
811
  - πŸ‘‰ **Right Hand**: High Pass Filter On/Off
812
  - 🦡 **Left Leg**: Reverb Effect On/Off
813
  - 🦡 **Right Leg**: Low Pass Filter On/Off
814
+
815
 
816
  *πŸŽ›οΈ Each movement toggles an effect - Mix your creation!*
817
  """)
 
852
  right_hand_sound = gr.Audio(label="πŸ‘‰ Right Hand", interactive=False, autoplay=True, visible=True)
853
  left_leg_sound = gr.Audio(label="🦡 Left Leg", interactive=False, autoplay=True, visible=True)
854
  right_leg_sound = gr.Audio(label="🦡 Right Leg", interactive=False, autoplay=True, visible=True)
855
+ #tongue_sound = gr.Audio(label="πŸ‘… Tongue", interactive=False, autoplay=True, visible=True)
856
 
857
  # Composition status
858
  composition_status = gr.Textbox(label="Composition Status", interactive=False, lines=5)
 
885
  manual_right_hand_sound = gr.Audio(label="πŸ‘‰ Right Hand", interactive=False, autoplay=False, visible=True)
886
  manual_left_leg_sound = gr.Audio(label="🦡 Left Leg", interactive=False, autoplay=False, visible=True)
887
  manual_right_leg_sound = gr.Audio(label="🦡 Right Leg", interactive=False, autoplay=False, visible=True)
888
+ #manual_tongue_sound = gr.Audio(label="πŸ‘… Tongue", interactive=False, autoplay=False, visible=True)
889
 
890
  # Session management functions
891
  def start_new_session():
 
908
  result[6], # right_hand_sound
909
  result[7], # left_leg_sound
910
  result[8], # right_leg_sound
911
+ #result[9], # tongue_sound
912
+ result[9], # composition_status
913
+ result[10], # building_instructions
914
+ result[11], # dj_instructions
915
  gr.update(visible=True), # continue_btn - show it
916
  gr.update(active=True), # timer - activate it
917
  gr.update(visible=False) # session_complete_row - hide it
 
933
  result[6], # right_hand_sound
934
  result[7], # left_leg_sound
935
  result[8], # right_leg_sound
936
+ #result[9], # tongue_sound
937
+ result[9], # composition_status
938
+ result[10], # building_instructions
939
+ result[11], # dj_instructions
940
  gr.update(visible=True), # continue_btn - show it
941
  gr.update(active=True), # timer - activate it
942
  gr.update(visible=False) # session_complete_row - hide it
 
957
  result[6], # right_hand_sound
958
  result[7], # left_leg_sound
959
  result[8], # right_leg_sound
960
+ #result[9], # tongue_sound
961
+ result[9], # composition_status
962
+ result[10], # building_instructions
963
+ result[11], # dj_instructions
964
  gr.update(visible=True), # continue_btn - show it
965
  gr.update(active=True) # timer - activate it
966
  )
 
982
  result[6], # right_hand_sound
983
  result[7], # left_leg_sound
984
  result[8], # right_leg_sound
985
+ #result[9], # tongue_sound
986
+ result[9], # composition_status
987
+ result[10], # building_instructions
988
+ result[11], # dj_instructions
989
  gr.update(active=False), # timer - deactivate it
990
  gr.update(visible=True) # session_complete_row - show options
991
  )
 
1002
  result[6], # right_hand_sound
1003
  result[7], # left_leg_sound
1004
  result[8], # right_leg_sound
1005
+ #result[9], # tongue_sound
1006
+ result[9], # composition_status
1007
+ result[10], # building_instructions
1008
+ result[11], # dj_instructions
1009
  gr.update(active=False), # timer - deactivate it
1010
  gr.update(visible=False) # session_complete_row - keep hidden
1011
  )
 
1021
  result[6], # right_hand_sound
1022
  result[7], # left_leg_sound
1023
  result[8], # right_leg_sound
1024
+ #result[9], # tongue_sound
1025
+ result[9], # composition_status
1026
+ result[10], # building_instructions
1027
+ result[11], # dj_instructions
1028
  gr.update(active=True), # timer - keep active
1029
  gr.update(visible=False) # session_complete_row - keep hidden
1030
  )
 
1033
  start_btn.click(
1034
  fn=start_with_timer,
1035
  outputs=[target_display, predicted_display, timer_display, user_prompt, eeg_plot,
1036
+ left_hand_sound, right_hand_sound, left_leg_sound, right_leg_sound, composition_status,
1037
  building_instructions, dj_instructions, continue_btn, timer]
1038
  )
1039
 
1040
  continue_btn.click(
1041
  fn=continue_with_timer,
1042
  outputs=[target_display, predicted_display, timer_display, user_prompt, eeg_plot,
1043
+ left_hand_sound, right_hand_sound, left_leg_sound, right_leg_sound, composition_status,
1044
  building_instructions, dj_instructions, timer, session_complete_row]
1045
  )
1046
 
 
1048
  timer.tick(
1049
  fn=continue_with_timer,
1050
  outputs=[target_display, predicted_display, timer_display, user_prompt, eeg_plot,
1051
+ left_hand_sound, right_hand_sound, left_leg_sound, right_leg_sound, composition_status,
1052
  building_instructions, dj_instructions, timer, session_complete_row]
1053
  )
1054
 
 
1056
  new_session_btn.click(
1057
  fn=start_new_session,
1058
  outputs=[target_display, predicted_display, timer_display, user_prompt, eeg_plot,
1059
+ left_hand_sound, right_hand_sound, left_leg_sound, right_leg_sound, composition_status,
1060
  building_instructions, dj_instructions, continue_btn, timer, session_complete_row]
1061
  )
1062
 
1063
  extend_session_btn.click(
1064
  fn=extend_current_session,
1065
  outputs=[target_display, predicted_display, timer_display, user_prompt, eeg_plot,
1066
+ left_hand_sound, right_hand_sound, left_leg_sound, right_leg_sound, composition_status,
1067
  building_instructions, dj_instructions, continue_btn, timer, session_complete_row]
1068
  )
1069
 
 
1088
  classify_btn.click(
1089
  fn=manual_classify,
1090
  outputs=[manual_target_display, manual_predicted_display, manual_timer_display, manual_eeg_plot, manual_results,
1091
+ manual_left_hand_sound, manual_right_hand_sound, manual_left_leg_sound, manual_right_leg_sound]
1092
  )
1093
 
1094
  clear_btn.click(
1095
  fn=clear_manual,
1096
  outputs=[manual_target_display, manual_predicted_display, manual_timer_display, manual_eeg_plot, manual_results,
1097
+ manual_left_hand_sound, manual_right_hand_sound, manual_left_leg_sound, manual_right_leg_sound]
1098
  )
1099
 
1100
  # Note: No auto-loading of sounds to prevent playing all sounds on startup
sound_library.py CHANGED
@@ -103,7 +103,7 @@ class AudioEffectsProcessor:
103
  """Apply bass boost using low-frequency shelving filter."""
104
  try:
105
  # Design low-shelf filter for bass boost
106
- freq = 250.0 # Bass frequency cutoff
107
  nyquist = samplerate / 2
108
  normalized_freq = freq / nyquist
109
 
@@ -177,67 +177,74 @@ class SoundManager:
177
  """
178
 
179
  def __init__(self, sound_dir: str = "sounds", include_neutral_in_cycle: bool = False):
180
- self.sound_dir = Path(sound_dir)
181
- self.include_neutral_in_cycle = include_neutral_in_cycle
182
-
183
- # Composition state
184
- self.composition_layers = [] # All layers across all cycles
185
- self.current_cycle = 0
186
- self.current_step = 0 # Current step within cycle (0-5)
187
- self.cycle_complete = False
188
- self.completed_cycles = 0 # Track completed cycles for session management
189
- self.max_cycles = 2 # Rehabilitation session limit
190
-
191
- # DJ Effects phase management
192
- self.current_phase = "building" # "building" or "dj_effects"
193
- self.mixed_composition_file = None # Path to current mixed composition
194
- self.active_effects = { # Track which effects are currently active
195
- "left_hand": False, # Volume fade
196
- "right_hand": False, # Filter sweep
197
- "left_leg": False, # Reverb
198
- "right_leg": False, # Tempo modulation
199
- "tongue": False # Bass boost
200
- }
201
-
202
- # All possible movements (neutral is optional for composition)
203
- self.all_movements = ["left_hand", "right_hand", "neutral", "left_leg", "tongue", "right_leg"]
204
-
205
- # Active movements that contribute to composition (excluding neutral)
206
- self.active_movements = ["left_hand", "right_hand", "left_leg", "tongue", "right_leg"]
207
-
208
- # Current cycle's random movement sequence (shuffled each cycle)
209
- self.current_movement_sequence = []
210
- self.movements_completed = set() # Track which movements have been successfully completed
211
- self._generate_new_sequence()
212
-
213
- # User-customizable sound mapping (can be updated after each cycle)
214
- self.current_sound_mapping = {
215
- "left_hand": "1_SoundHelix-Song-6_(Bass).wav",
216
- "right_hand": "1_SoundHelix-Song-6_(Drums).wav",
217
- "neutral": None, # No sound for neutral/rest state
218
- "left_leg": "1_SoundHelix-Song-6_(Other).wav",
219
- "tongue": "1_SoundHelix-Song-6_(Vocals).wav",
220
- "right_leg": "1_SoundHelix-Song-6_(Bass).wav" # Can be remapped
221
- }
222
-
223
- # Available sound files
224
- self.available_sounds = [
225
- "1_SoundHelix-Song-6_(Bass).wav",
226
- "1_SoundHelix-Song-6_(Drums).wav",
227
- "1_SoundHelix-Song-6_(Other).wav",
228
- "1_SoundHelix-Song-6_(Vocals).wav"
229
- ]
230
-
231
- # Load sound files
232
- self.loaded_sounds = {}
233
- self._load_sound_files()
234
-
235
- # Cycle statistics
236
- self.cycle_stats = {
237
- 'total_cycles': 0,
238
- 'successful_classifications': 0,
239
- 'total_attempts': 0
240
- }
 
 
 
 
 
 
 
241
 
242
  def _load_sound_files(self):
243
  """Load all available sound files into memory."""
@@ -426,7 +433,7 @@ class SoundManager:
426
  print(" πŸ‘‰ Right Hand: High Pass Filter")
427
  print(" 🦡 Left Leg: Reverb Effect")
428
  print(" 🦡 Right Leg: Low Pass Filter")
429
- print(" πŸ‘… Tongue: Bass Boost")
430
  return True
431
  else:
432
  print("DEBUG: Not enough unique sounds to transition to DJ mode.")
@@ -530,7 +537,7 @@ class SoundManager:
530
  "right_hand": "High Pass Filter",
531
  "left_leg": "Reverb Effect",
532
  "right_leg": "Low Pass Filter",
533
- "tongue": "Bass Boost"
534
  }
535
  effect_name = effect_names.get(movement, movement)
536
  print(f"πŸŽ›οΈ {effect_name}: {effect_status}")
 
103
  """Apply bass boost using low-frequency shelving filter."""
104
  try:
105
  # Design low-shelf filter for bass boost
106
+ freq = 200.0 # Bass frequency cutoff
107
  nyquist = samplerate / 2
108
  normalized_freq = freq / nyquist
109
 
 
177
  """
178
 
179
  def __init__(self, sound_dir: str = "sounds", include_neutral_in_cycle: bool = False):
180
+ # Available sound files (define FIRST)
181
+ self.available_sounds = [
182
+ "1_SoundHelix-Song-6_(Bass).wav",
183
+ "1_SoundHelix-Song-6_(Drums).wav",
184
+ "1_SoundHelix-Song-6_(Other).wav",
185
+ "1_SoundHelix-Song-6_(Vocals).wav"
186
+ ]
187
+
188
+ self.sound_dir = Path(sound_dir)
189
+ self.include_neutral_in_cycle = include_neutral_in_cycle
190
+
191
+ # Composition state
192
+ self.composition_layers = [] # All layers across all cycles
193
+ self.current_cycle = 0
194
+ self.current_step = 0 # Current step within cycle (0-5)
195
+ self.cycle_complete = False
196
+ self.completed_cycles = 0 # Track completed cycles for session management
197
+ self.max_cycles = 2 # Rehabilitation session limit
198
+
199
+ # DJ Effects phase management
200
+ self.current_phase = "building" # "building" or "dj_effects"
201
+ self.mixed_composition_file = None # Path to current mixed composition
202
+ self.active_effects = { # Track which effects are currently active
203
+ "left_hand": False, # Volume fade
204
+ "right_hand": False, # Filter sweep
205
+ "left_leg": False, # Reverb
206
+ "right_leg": False, # Tempo modulation
207
+ #"tongue": False # Bass boost
208
+ }
209
+
210
+ # All possible movements (neutral is optional for composition)
211
+ self.all_movements = ["left_hand", "right_hand", "neutral", "left_leg", "tongue", "right_leg"]
212
+
213
+ # Active movements that contribute to composition (excluding neutral)
214
+ self.active_movements = ["left_hand", "right_hand", "left_leg", "right_leg"]
215
+
216
+ # Current cycle's random movement sequence (shuffled each cycle)
217
+ self.current_movement_sequence = []
218
+ self.movements_completed = set() # Track which movements have been successfully completed
219
+ self._generate_new_sequence()
220
+
221
+ # User-customizable sound mapping (can be updated after each cycle)
222
+ # Assign each movement a unique sound file from available_sounds
223
+ import random
224
+ movements = ["left_hand", "right_hand", "left_leg", "right_leg"]
225
+ sounds = self.available_sounds.copy()
226
+ random.shuffle(sounds)
227
+ self.current_sound_mapping = {movement: sound for movement, sound in zip(movements, sounds)}
228
+ self.current_sound_mapping["neutral"] = None # No sound for neutral/rest state
229
+
230
+ # Available sound files
231
+ self.available_sounds = [
232
+ "1_SoundHelix-Song-6_(Bass).wav",
233
+ "1_SoundHelix-Song-6_(Drums).wav",
234
+ "1_SoundHelix-Song-6_(Other).wav",
235
+ "1_SoundHelix-Song-6_(Vocals).wav"
236
+ ]
237
+
238
+ # Load sound files
239
+ self.loaded_sounds = {}
240
+ self._load_sound_files()
241
+
242
+ # Cycle statistics
243
+ self.cycle_stats = {
244
+ 'total_cycles': 0,
245
+ 'successful_classifications': 0,
246
+ 'total_attempts': 0
247
+ }
248
 
249
  def _load_sound_files(self):
250
  """Load all available sound files into memory."""
 
433
  print(" πŸ‘‰ Right Hand: High Pass Filter")
434
  print(" 🦡 Left Leg: Reverb Effect")
435
  print(" 🦡 Right Leg: Low Pass Filter")
436
+ #print(" πŸ‘… Tongue: Bass Boost")
437
  return True
438
  else:
439
  print("DEBUG: Not enough unique sounds to transition to DJ mode.")
 
537
  "right_hand": "High Pass Filter",
538
  "left_leg": "Reverb Effect",
539
  "right_leg": "Low Pass Filter",
540
+ #"tongue": "Bass Boost"
541
  }
542
  effect_name = effect_names.get(movement, movement)
543
  print(f"πŸŽ›οΈ {effect_name}: {effect_status}")