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

layering works

Browse files
Files changed (4) hide show
  1. app.log +452 -0
  2. app.py +116 -185
  3. config.py +3 -3
  4. sound_library.py +40 -38
app.log ADDED
@@ -0,0 +1,452 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 🧠 EEG Motor Imagery Music Composer
2
+ ==================================================
3
+ Starting Gradio application...
4
+ 🎯 New random sequence (5 movements): Left Leg β†’ Right Leg β†’ Right Hand β†’ Left Hand β†’ Tongue
5
+ Loaded sound for left_hand: 1_SoundHelix-Song-6_(Bass).wav
6
+ Loaded sound for right_hand: 1_SoundHelix-Song-6_(Drums).wav
7
+ Loaded sound for left_leg: 1_SoundHelix-Song-6_(Other).wav
8
+ Loaded sound for tongue: 1_SoundHelix-Song-6_(Vocals).wav
9
+ Loaded sound for right_leg: 1_SoundHelix-Song-6_(Bass).wav
10
+ Dropped auxiliary channels [np.str_('X5')]. Remaining channels: 21
11
+ Creating RawArray with float64 data, n_channels=21, n_times=667600
12
+ Range : 0 ... 667599 = 0.000 ... 3337.995 secs
13
+ Ready.
14
+ Not setting metadata
15
+ 959 matching events found
16
+ No baseline correction applied
17
+ 0 projection items activated
18
+ Using data from preloaded Raw for 959 events and 301 original time points ...
19
+ 0 bad epochs dropped
20
+ Dropped auxiliary channels [np.str_('X5')]. Remaining channels: 21
21
+ Creating RawArray with float64 data, n_channels=21, n_times=681400
22
+ Range : 0 ... 681399 = 0.000 ... 3406.995 secs
23
+ Ready.
24
+ Not setting metadata
25
+ 958 matching events found
26
+ No baseline correction applied
27
+ 0 projection items activated
28
+ Using data from preloaded Raw for 958 events and 301 original time points ...
29
+ 0 bad epochs dropped
30
+ Dropped auxiliary channels [np.str_('X5')]. Remaining channels: 21
31
+ Creating RawArray with float64 data, n_channels=21, n_times=813600
32
+ Range : 0 ... 813599 = 0.000 ... 4067.995 secs
33
+ Ready.
34
+ Not setting metadata
35
+ 960 matching events found
36
+ No baseline correction applied
37
+ 0 projection items activated
38
+ Using data from preloaded Raw for 960 events and 301 original time points ...
39
+ 0 bad epochs dropped
40
+ Not setting metadata
41
+ 2877 matching events found
42
+ No baseline correction applied
43
+ βœ… Pre-trained model loaded successfully from shallow_weights_all.pth
44
+ βœ… Pre-trained model loaded successfully from shallow_weights_all.pth
45
+ Pre-trained Demo: 2877 samples from 3 subjects
46
+ Available sound classes: ['left_hand', 'right_hand', 'neutral', 'left_leg', 'tongue', 'right_leg']
47
+ * Running on local URL: http://0.0.0.0:7867
48
+ * To create a public link, set `share=True` in `launch()`.
49
+ 🎯 New random sequence (5 movements): Right Leg β†’ Tongue β†’ Right Hand β†’ Left Hand β†’ Left Leg
50
+ πŸ”„ Starting Cycle 2
51
+ πŸ’ͺ Let's create your first brain-music composition!
52
+ DEBUG start_automatic_composition: current target = right_leg
53
+ DEBUG: Added layer 1, total layers now: 1
54
+ DEBUG: Composition layers: ['left_leg']
55
+ DEBUG: Current composition has 1 layers: ['left_leg']
56
+ DEBUG: Audio files to mix: ['1_SoundHelix-Song-6_(Other).wav']
57
+ DEBUG: Using base audio file as fallback: 1_SoundHelix-Song-6_(Vocals).wav (FILE SAVING DISABLED)
58
+ βœ“ Cycle 2: Added 1_SoundHelix-Song-6_(Other).wav for left_leg (1/5 complete)
59
+ DEBUG start_automatic_composition: predicted=left_leg, confidence=0.413, sound_added=True
60
+ DEBUG: Available sounds: ['left_hand', 'right_hand', 'left_leg', 'tongue', 'right_leg']
61
+ DEBUG: Completed movements: {'left_leg'}
62
+ DEBUG: Showing individual sounds that will layer together: ['left_leg']
63
+ DEBUG: Left leg playing: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Other).wav
64
+ DEBUG: 1 individual sounds will play together creating layered composition
65
+ DEBUG continue_automatic_composition: current target = right_leg
66
+ DEBUG: Added layer 2, total layers now: 2
67
+ DEBUG: Composition layers: ['left_leg', 'left_hand']
68
+ DEBUG: Current composition has 2 layers: ['left_leg', 'left_hand']
69
+ DEBUG: Audio files to mix: ['1_SoundHelix-Song-6_(Other).wav', '1_SoundHelix-Song-6_(Bass).wav']
70
+ DEBUG: Using base audio file as fallback: 1_SoundHelix-Song-6_(Vocals).wav (FILE SAVING DISABLED)
71
+ βœ“ Cycle 2: Added 1_SoundHelix-Song-6_(Bass).wav for left_hand (2/5 complete)
72
+ DEBUG continue: Available sounds: ['left_hand', 'right_hand', 'left_leg', 'tongue', 'right_leg']
73
+ DEBUG continue: Completed movements: {'left_hand', 'left_leg'}
74
+ DEBUG continue: Showing individual sounds that will layer together: ['left_hand', 'left_leg']
75
+ DEBUG continue: Left hand playing: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Bass).wav
76
+ DEBUG continue: Left leg playing: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Other).wav
77
+ DEBUG continue: 2 individual sounds will play together creating layered composition
78
+ DEBUG continue_automatic_composition: current target = right_leg
79
+ DEBUG: Added layer 3, total layers now: 3
80
+ DEBUG: Composition layers: ['left_leg', 'left_hand', 'right_hand']
81
+ DEBUG: Current composition has 3 layers: ['left_leg', 'left_hand', 'right_hand']
82
+ DEBUG: Audio files to mix: ['1_SoundHelix-Song-6_(Other).wav', '1_SoundHelix-Song-6_(Bass).wav', '1_SoundHelix-Song-6_(Drums).wav']
83
+ DEBUG: Using base audio file as fallback: 1_SoundHelix-Song-6_(Vocals).wav (FILE SAVING DISABLED)
84
+ βœ“ Cycle 2: Added 1_SoundHelix-Song-6_(Drums).wav for right_hand (3/5 complete)
85
+ DEBUG continue: Available sounds: ['left_hand', 'right_hand', 'left_leg', 'tongue', 'right_leg']
86
+ DEBUG continue: Completed movements: {'left_hand', 'left_leg', 'right_hand'}
87
+ DEBUG continue: Showing individual sounds that will layer together: ['left_hand', 'left_leg', 'right_hand']
88
+ DEBUG continue: Left hand playing: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Bass).wav
89
+ DEBUG continue: Right hand playing: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Drums).wav
90
+ DEBUG continue: Left leg playing: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Other).wav
91
+ DEBUG continue: 3 individual sounds will play together creating layered composition
92
+ DEBUG continue_automatic_composition: current target = right_leg
93
+ DEBUG: Added layer 4, total layers now: 4
94
+ DEBUG: Composition layers: ['left_leg', 'left_hand', 'right_hand', 'right_leg']
95
+ DEBUG: Current composition has 4 layers: ['left_leg', 'left_hand', 'right_hand', 'right_leg']
96
+ DEBUG: Audio files to mix: ['1_SoundHelix-Song-6_(Other).wav', '1_SoundHelix-Song-6_(Bass).wav', '1_SoundHelix-Song-6_(Drums).wav', '1_SoundHelix-Song-6_(Bass).wav']
97
+ DEBUG: Using base audio file as fallback: 1_SoundHelix-Song-6_(Vocals).wav (FILE SAVING DISABLED)
98
+ βœ“ Cycle 2: Added 1_SoundHelix-Song-6_(Bass).wav for right_leg (4/5 complete)
99
+ DEBUG continue: Available sounds: ['left_hand', 'right_hand', 'left_leg', 'tongue', 'right_leg']
100
+ DEBUG continue: Completed movements: {'left_hand', 'left_leg', 'right_leg', 'right_hand'}
101
+ DEBUG continue: Showing individual sounds that will layer together: ['left_hand', 'left_leg', 'right_leg', 'right_hand']
102
+ DEBUG continue: Left hand playing: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Bass).wav
103
+ DEBUG continue: Right hand playing: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Drums).wav
104
+ DEBUG continue: Left leg playing: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Other).wav
105
+ DEBUG continue: Right leg playing: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Bass).wav
106
+ DEBUG continue: 4 individual sounds will play together creating layered composition
107
+ DEBUG continue_automatic_composition: current target = right_leg
108
+ DEBUG: Added layer 5, total layers now: 5
109
+ DEBUG: Composition layers: ['left_leg', 'left_hand', 'right_hand', 'right_leg', 'tongue']
110
+ DEBUG: Current composition has 5 layers: ['left_leg', 'left_hand', 'right_hand', 'right_leg', 'tongue']
111
+ DEBUG: Audio files to mix: ['1_SoundHelix-Song-6_(Other).wav', '1_SoundHelix-Song-6_(Bass).wav', '1_SoundHelix-Song-6_(Drums).wav', '1_SoundHelix-Song-6_(Bass).wav', '1_SoundHelix-Song-6_(Vocals).wav']
112
+ DEBUG: Using base audio file as fallback: 1_SoundHelix-Song-6_(Vocals).wav (FILE SAVING DISABLED)
113
+ βœ“ Cycle 2: Added 1_SoundHelix-Song-6_(Vocals).wav for tongue (5/5 complete)
114
+ 🎡 Cycle 2 complete! All 5 movements successfully classified!
115
+ πŸ“€ Using existing audio as mixed composition: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Bass).wav (FILE SAVING DISABLED)
116
+ 🎡 Composition Complete! Transitioning to DJ Effects Phase...
117
+ 🎧 You are now the DJ! Use movements to control effects:
118
+ πŸ‘ˆ Left Hand: Volume Fade
119
+ πŸ‘‰ Right Hand: High Pass Filter
120
+ 🦡 Left Leg: Reverb Effect
121
+ 🦡 Right Leg: Low Pass Filter
122
+ πŸ‘… Tongue: Bass Boost
123
+ DEBUG: Successfully transitioned to DJ phase with 5 completed movements
124
+ DEBUG continue: DJ mode - NEW mixed composition loaded: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Bass).wav
125
+ DEBUG continue_automatic_composition: current target = right_leg
126
+ πŸŽ›οΈ Reverb Effect: ON
127
+ πŸŽ›οΈ Audio processed with effects: rev (FILE SAVING DISABLED)
128
+ DEBUG continue_automatic_composition: current target = right_leg
129
+ πŸŽ›οΈ Reverb Effect: OFF
130
+ πŸŽ›οΈ Audio processed with effects: clean (FILE SAVING DISABLED)
131
+ DEBUG continue_automatic_composition: current target = right_leg
132
+ πŸŽ›οΈ High Pass Filter: ON
133
+ πŸŽ›οΈ Audio processed with effects: hpf (FILE SAVING DISABLED)
134
+ DEBUG continue_automatic_composition: current target = right_leg
135
+ πŸŽ›οΈ Reverb Effect: ON
136
+ πŸŽ›οΈ Audio processed with effects: hpf_rev (FILE SAVING DISABLED)
137
+ DEBUG continue_automatic_composition: current target = right_leg
138
+ πŸŽ›οΈ High Pass Filter: OFF
139
+ πŸŽ›οΈ Audio processed with effects: rev (FILE SAVING DISABLED)
140
+ DEBUG continue_automatic_composition: current target = right_leg
141
+ πŸŽ›οΈ Bass Boost: ON
142
+ πŸŽ›οΈ Audio processed with effects: rev_bass (FILE SAVING DISABLED)
143
+ DEBUG continue_automatic_composition: current target = right_leg
144
+ πŸŽ›οΈ High Pass Filter: ON
145
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_bass (FILE SAVING DISABLED)
146
+ DEBUG continue_automatic_composition: current target = right_leg
147
+ πŸŽ›οΈ Bass Boost: OFF
148
+ πŸŽ›οΈ Audio processed with effects: hpf_rev (FILE SAVING DISABLED)
149
+ DEBUG continue_automatic_composition: current target = right_leg
150
+ 🎡 Cycle 2 complete! All 5 movements successfully classified!
151
+ DEBUG continue_automatic_composition: current target = right_leg
152
+ DEBUG start_automatic_composition: current target = right_leg
153
+ πŸŽ›οΈ High Pass Filter: OFF
154
+ πŸŽ›οΈ Low Pass Filter: ON
155
+ πŸŽ›οΈ Audio processed with effects: rev_lpf (FILE SAVING DISABLED)/Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/app.py:729: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`). Consider using `matplotlib.pyplot.close()`.
156
+ fig, axes = plt.subplots(2, 2, figsize=(12, 8))
157
+
158
+ πŸŽ›οΈ Audio processed with effects: rev_lpf (FILE SAVING DISABLED)
159
+ DEBUG start_automatic_composition: predicted=right_hand, confidence=0.424, sound_added=True
160
+ DEBUG DJ: Playing mixed composition with effects: /Users/sofiafregni/Downloads/portfolio_ML_project/Gradio/sounds/1_SoundHelix-Song-6_(Bass).wav
161
+ DEBUG continue_automatic_composition: current target = right_leg
162
+ πŸŽ›οΈ Reverb Effect: OFF
163
+ πŸŽ›οΈ Audio processed with effects: lpf (FILE SAVING DISABLED)
164
+ DEBUG continue_automatic_composition: current target = right_leg
165
+ πŸŽ›οΈ Reverb Effect: ON
166
+ πŸŽ›οΈ Audio processed with effects: rev_lpf (FILE SAVING DISABLED)
167
+ DEBUG continue_automatic_composition: current target = right_leg
168
+ πŸŽ›οΈ Bass Boost: ON
169
+ πŸŽ›οΈ Audio processed with effects: rev_lpf_bass (FILE SAVING DISABLED)
170
+ DEBUG continue_automatic_composition: current target = right_leg
171
+ πŸŽ›οΈ High Pass Filter: ON
172
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_lpf_bass (FILE SAVING DISABLED)
173
+ DEBUG continue_automatic_composition: current target = right_leg
174
+ πŸŽ›οΈ Reverb Effect: OFF
175
+ πŸŽ›οΈ Audio processed with effects: hpf_lpf_bass (FILE SAVING DISABLED)
176
+ DEBUG continue_automatic_composition: current target = right_leg
177
+ πŸŽ›οΈ High Pass Filter: OFF
178
+ πŸŽ›οΈ Audio processed with effects: lpf_bass (FILE SAVING DISABLED)
179
+ DEBUG continue_automatic_composition: current target = right_leg
180
+ πŸŽ›οΈ High Pass Filter: ON
181
+ πŸŽ›οΈ Audio processed with effects: hpf_lpf_bass (FILE SAVING DISABLED)
182
+ DEBUG continue_automatic_composition: current target = right_leg
183
+ DEBUG continue_automatic_composition: current target = right_leg
184
+ πŸŽ›οΈ Low Pass Filter: OFF
185
+ πŸŽ›οΈ Audio processed with effects: hpf_bass (FILE SAVING DISABLED)
186
+ DEBUG continue_automatic_composition: current target = right_leg
187
+ πŸŽ›οΈ Reverb Effect: ON
188
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_bass (FILE SAVING DISABLED)
189
+ DEBUG continue_automatic_composition: current target = right_leg
190
+ πŸŽ›οΈ High Pass Filter: OFF
191
+ πŸŽ›οΈ Audio processed with effects: rev_bass (FILE SAVING DISABLED)
192
+ DEBUG continue_automatic_composition: current target = right_leg
193
+ πŸŽ›οΈ Bass Boost: OFF
194
+ πŸŽ›οΈ Audio processed with effects: rev (FILE SAVING DISABLED)
195
+ DEBUG continue_automatic_composition: current target = right_leg
196
+ πŸŽ›οΈ Reverb Effect: OFF
197
+ πŸŽ›οΈ Audio processed with effects: clean (FILE SAVING DISABLED)
198
+ DEBUG continue_automatic_composition: current target = right_leg
199
+ πŸŽ›οΈ Reverb Effect: ON
200
+ πŸŽ›οΈ Audio processed with effects: rev (FILE SAVING DISABLED)
201
+ DEBUG continue_automatic_composition: current target = right_leg
202
+ πŸŽ›οΈ High Pass Filter: ON
203
+ πŸŽ›οΈ Audio processed with effects: hpf_rev (FILE SAVING DISABLED)
204
+ DEBUG continue_automatic_composition: current target = right_leg
205
+ πŸŽ›οΈ Bass Boost: ON
206
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_bass (FILE SAVING DISABLED)
207
+ DEBUG continue_automatic_composition: current target = right_leg
208
+ πŸŽ›οΈ High Pass Filter: OFF
209
+ πŸŽ›οΈ Audio processed with effects: rev_bass (FILE SAVING DISABLED)
210
+ DEBUG continue_automatic_composition: current target = right_leg
211
+ πŸŽ›οΈ Low Pass Filter: ON
212
+ πŸŽ›οΈ Audio processed with effects: rev_lpf_bass (FILE SAVING DISABLED)
213
+ DEBUG continue_automatic_composition: current target = right_leg
214
+ DEBUG continue_automatic_composition: current target = right_leg
215
+ πŸŽ›οΈ Bass Boost: OFF
216
+ πŸŽ›οΈ Audio processed with effects: rev_lpf (FILE SAVING DISABLED)
217
+ DEBUG continue_automatic_composition: current target = right_leg
218
+ DEBUG continue_automatic_composition: current target = right_leg
219
+ πŸŽ›οΈ Bass Boost: ON
220
+ πŸŽ›οΈ Audio processed with effects: rev_lpf_bass (FILE SAVING DISABLED)
221
+ DEBUG continue_automatic_composition: current target = right_leg
222
+ πŸŽ›οΈ Low Pass Filter: OFF
223
+ πŸŽ›οΈ Audio processed with effects: rev_bass (FILE SAVING DISABLED)
224
+ DEBUG continue_automatic_composition: current target = right_leg
225
+ πŸŽ›οΈ Reverb Effect: OFF
226
+ πŸŽ›οΈ Audio processed with effects: bass (FILE SAVING DISABLED)
227
+ DEBUG continue_automatic_composition: current target = right_leg
228
+ πŸŽ›οΈ Bass Boost: OFF
229
+ πŸŽ›οΈ Audio processed with effects: clean (FILE SAVING DISABLED)
230
+ DEBUG continue_automatic_composition: current target = right_leg
231
+ πŸŽ›οΈ Bass Boost: ON
232
+ πŸŽ›οΈ Audio processed with effects: bass (FILE SAVING DISABLED)
233
+ DEBUG continue_automatic_composition: current target = right_leg
234
+ πŸŽ›οΈ High Pass Filter: ON
235
+ πŸŽ›οΈ Audio processed with effects: hpf_bass (FILE SAVING DISABLED)
236
+ DEBUG continue_automatic_composition: current target = right_leg
237
+ πŸŽ›οΈ Bass Boost: OFF
238
+ πŸŽ›οΈ Audio processed with effects: hpf (FILE SAVING DISABLED)
239
+ DEBUG continue_automatic_composition: current target = right_leg
240
+ πŸŽ›οΈ Reverb Effect: ON
241
+ πŸŽ›οΈ Audio processed with effects: hpf_rev (FILE SAVING DISABLED)
242
+ DEBUG continue_automatic_composition: current target = right_leg
243
+ πŸŽ›οΈ Bass Boost: ON
244
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_bass (FILE SAVING DISABLED)
245
+ DEBUG continue_automatic_composition: current target = right_leg
246
+ πŸŽ›οΈ Low Pass Filter: ON
247
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_lpf_bass (FILE SAVING DISABLED)
248
+ DEBUG continue_automatic_composition: current target = right_leg
249
+ πŸŽ›οΈ High Pass Filter: OFF
250
+ πŸŽ›οΈ Audio processed with effects: rev_lpf_bass (FILE SAVING DISABLED)
251
+ DEBUG continue_automatic_composition: current target = right_leg
252
+ DEBUG continue_automatic_composition: current target = right_leg
253
+ πŸŽ›οΈ High Pass Filter: ON
254
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_lpf_bass (FILE SAVING DISABLED)
255
+ DEBUG continue_automatic_composition: current target = right_leg
256
+ πŸŽ›οΈ High Pass Filter: OFF
257
+ πŸŽ›οΈ Audio processed with effects: rev_lpf_bass (FILE SAVING DISABLED)
258
+ DEBUG continue_automatic_composition: current target = right_leg
259
+ πŸŽ›οΈ High Pass Filter: ON
260
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_lpf_bass (FILE SAVING DISABLED)
261
+ DEBUG continue_automatic_composition: current target = right_leg
262
+ πŸŽ›οΈ Volume Fade: ON
263
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_rev_lpf_bass (FILE SAVING DISABLED)
264
+ DEBUG continue_automatic_composition: current target = right_leg
265
+ πŸŽ›οΈ Bass Boost: OFF
266
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_rev_lpf (FILE SAVING DISABLED)
267
+ DEBUG continue_automatic_composition: current target = right_leg
268
+ πŸŽ›οΈ Low Pass Filter: OFF
269
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_rev (FILE SAVING DISABLED)
270
+ DEBUG continue_automatic_composition: current target = right_leg
271
+ πŸŽ›οΈ High Pass Filter: OFF
272
+ πŸŽ›οΈ Audio processed with effects: fade_rev (FILE SAVING DISABLED)
273
+ DEBUG continue_automatic_composition: current target = right_leg
274
+ πŸŽ›οΈ High Pass Filter: ON
275
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_rev (FILE SAVING DISABLED)
276
+ DEBUG continue_automatic_composition: current target = right_leg
277
+ πŸŽ›οΈ Reverb Effect: OFF
278
+ πŸŽ›οΈ Audio processed with effects: fade_hpf (FILE SAVING DISABLED)
279
+ DEBUG continue_automatic_composition: current target = right_leg
280
+ πŸŽ›οΈ High Pass Filter: OFF
281
+ πŸŽ›οΈ Audio processed with effects: fade (FILE SAVING DISABLED)
282
+ DEBUG continue_automatic_composition: current target = right_leg
283
+ πŸŽ›οΈ Volume Fade: OFF
284
+ πŸŽ›οΈ Audio processed with effects: clean (FILE SAVING DISABLED)
285
+ DEBUG continue_automatic_composition: current target = right_leg
286
+ πŸŽ›οΈ Bass Boost: ON
287
+ πŸŽ›οΈ Audio processed with effects: bass (FILE SAVING DISABLED)
288
+ DEBUG continue_automatic_composition: current target = right_leg
289
+ πŸŽ›οΈ High Pass Filter: ON
290
+ πŸŽ›οΈ Audio processed with effects: hpf_bass (FILE SAVING DISABLED)
291
+ DEBUG continue_automatic_composition: current target = right_leg
292
+ πŸŽ›οΈ Volume Fade: ON
293
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_bass (FILE SAVING DISABLED)
294
+ DEBUG continue_automatic_composition: current target = right_leg
295
+ πŸŽ›οΈ Volume Fade: OFF
296
+ πŸŽ›οΈ Audio processed with effects: hpf_bass (FILE SAVING DISABLED)
297
+ DEBUG continue_automatic_composition: current target = right_leg
298
+ πŸŽ›οΈ Reverb Effect: ON
299
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_bass (FILE SAVING DISABLED)
300
+ DEBUG continue_automatic_composition: current target = right_leg
301
+ πŸŽ›οΈ Volume Fade: ON
302
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_rev_bass (FILE SAVING DISABLED)
303
+ DEBUG continue_automatic_composition: current target = right_leg
304
+ πŸŽ›οΈ Low Pass Filter: ON
305
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_rev_lpf_bass (FILE SAVING DISABLED)
306
+ DEBUG continue_automatic_composition: current target = right_leg
307
+ DEBUG continue_automatic_composition: current target = right_leg
308
+ πŸŽ›οΈ Low Pass Filter: OFF
309
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_rev_bass (FILE SAVING DISABLED)
310
+ DEBUG continue_automatic_composition: current target = right_leg
311
+ DEBUG continue_automatic_composition: current target = right_leg
312
+ πŸŽ›οΈ Volume Fade: OFF
313
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_bass (FILE SAVING DISABLED)
314
+ DEBUG continue_automatic_composition: current target = right_leg
315
+ DEBUG continue_automatic_composition: current target = right_leg
316
+ DEBUG continue_automatic_composition: current target = right_leg
317
+ πŸŽ›οΈ Bass Boost: OFF
318
+ πŸŽ›οΈ Audio processed with effects: hpf_rev (FILE SAVING DISABLED)
319
+ DEBUG continue_automatic_composition: current target = right_leg
320
+ πŸŽ›οΈ Low Pass Filter: ON
321
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_lpf (FILE SAVING DISABLED)
322
+ DEBUG continue_automatic_composition: current target = right_leg
323
+ πŸŽ›οΈ Reverb Effect: OFF
324
+ πŸŽ›οΈ Audio processed with effects: hpf_lpf (FILE SAVING DISABLED)
325
+ DEBUG continue_automatic_composition: current target = right_leg
326
+ πŸŽ›οΈ High Pass Filter: OFF
327
+ πŸŽ›οΈ Audio processed with effects: lpf (FILE SAVING DISABLED)
328
+ DEBUG continue_automatic_composition: current target = right_leg
329
+ πŸŽ›οΈ Low Pass Filter: OFF
330
+ πŸŽ›οΈ Audio processed with effects: clean (FILE SAVING DISABLED)
331
+ DEBUG continue_automatic_composition: current target = right_leg
332
+ πŸŽ›οΈ Reverb Effect: ON
333
+ πŸŽ›οΈ Audio processed with effects: rev (FILE SAVING DISABLED)
334
+ DEBUG continue_automatic_composition: current target = right_leg
335
+ πŸŽ›οΈ High Pass Filter: ON
336
+ πŸŽ›οΈ Audio processed with effects: hpf_rev (FILE SAVING DISABLED)
337
+ DEBUG continue_automatic_composition: current target = right_leg
338
+ πŸŽ›οΈ Bass Boost: ON
339
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_bass (FILE SAVING DISABLED)
340
+ DEBUG continue_automatic_composition: current target = right_leg
341
+ πŸŽ›οΈ Reverb Effect: OFF
342
+ πŸŽ›οΈ Audio processed with effects: hpf_bass (FILE SAVING DISABLED)
343
+ DEBUG continue_automatic_composition: current target = right_leg
344
+ πŸŽ›οΈ Reverb Effect: ON
345
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_bass (FILE SAVING DISABLED)
346
+ DEBUG continue_automatic_composition: current target = right_leg
347
+ πŸŽ›οΈ Volume Fade: ON
348
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_rev_bass (FILE SAVING DISABLED)
349
+ DEBUG continue_automatic_composition: current target = right_leg
350
+ πŸŽ›οΈ Volume Fade: OFF
351
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_bass (FILE SAVING DISABLED)
352
+ DEBUG continue_automatic_composition: current target = right_leg
353
+ πŸŽ›οΈ Reverb Effect: OFF
354
+ πŸŽ›οΈ Audio processed with effects: hpf_bass (FILE SAVING DISABLED)
355
+ DEBUG continue_automatic_composition: current target = right_leg
356
+ πŸŽ›οΈ Low Pass Filter: ON
357
+ πŸŽ›οΈ Audio processed with effects: hpf_lpf_bass (FILE SAVING DISABLED)
358
+ DEBUG continue_automatic_composition: current target = right_leg
359
+ πŸŽ›οΈ High Pass Filter: OFF
360
+ πŸŽ›οΈ Audio processed with effects: lpf_bass (FILE SAVING DISABLED)
361
+ DEBUG continue_automatic_composition: current target = right_leg
362
+ DEBUG continue_automatic_composition: current target = right_leg
363
+ DEBUG continue_automatic_composition: current target = right_leg
364
+ πŸŽ›οΈ Volume Fade: ON
365
+ πŸŽ›οΈ Audio processed with effects: fade_lpf_bass (FILE SAVING DISABLED)
366
+ DEBUG continue_automatic_composition: current target = right_leg
367
+ DEBUG continue_automatic_composition: current target = right_leg
368
+ πŸŽ›οΈ Reverb Effect: ON
369
+ πŸŽ›οΈ Audio processed with effects: fade_rev_lpf_bass (FILE SAVING DISABLED)
370
+ DEBUG continue_automatic_composition: current target = right_leg
371
+ πŸŽ›οΈ Low Pass Filter: OFF
372
+ πŸŽ›οΈ Audio processed with effects: fade_rev_bass (FILE SAVING DISABLED)
373
+ DEBUG continue_automatic_composition: current target = right_leg
374
+ πŸŽ›οΈ Bass Boost: OFF
375
+ πŸŽ›οΈ Audio processed with effects: fade_rev (FILE SAVING DISABLED)
376
+ DEBUG continue_automatic_composition: current target = right_leg
377
+ 🎡 Cycle 2 complete! All 5 movements successfully classified!
378
+ DEBUG continue_automatic_composition: current target = right_leg
379
+ πŸŽ›οΈ Low Pass Filter: ON
380
+ πŸŽ›οΈ Audio processed with effects: fade_rev_lpf (FILE SAVING DISABLED)
381
+ DEBUG continue_automatic_composition: current target = right_leg
382
+ πŸŽ›οΈ Volume Fade: OFF
383
+ πŸŽ›οΈ Audio processed with effects: rev_lpf (FILE SAVING DISABLED)
384
+ DEBUG continue_automatic_composition: current target = right_leg
385
+ πŸŽ›οΈ High Pass Filter: ON
386
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_lpf (FILE SAVING DISABLED)
387
+ DEBUG continue_automatic_composition: current target = right_leg
388
+ πŸŽ›οΈ Low Pass Filter: OFF
389
+ πŸŽ›οΈ Audio processed with effects: hpf_rev (FILE SAVING DISABLED)
390
+ DEBUG continue_automatic_composition: current target = right_leg
391
+ πŸŽ›οΈ Volume Fade: ON
392
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_rev (FILE SAVING DISABLED)
393
+ DEBUG continue_automatic_composition: current target = right_leg
394
+ DEBUG continue_automatic_composition: current target = right_leg
395
+ πŸŽ›οΈ Low Pass Filter: ON
396
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_rev_lpf (FILE SAVING DISABLED)
397
+ DEBUG continue_automatic_composition: current target = right_leg
398
+ πŸŽ›οΈ Reverb Effect: OFF
399
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_lpf (FILE SAVING DISABLED)
400
+ DEBUG continue_automatic_composition: current target = right_leg
401
+ πŸŽ›οΈ Bass Boost: ON
402
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_lpf_bass (FILE SAVING DISABLED)
403
+ DEBUG continue_automatic_composition: current target = right_leg
404
+ DEBUG continue_automatic_composition: current target = right_leg
405
+ πŸŽ›οΈ High Pass Filter: OFF
406
+ πŸŽ›οΈ Audio processed with effects: fade_lpf_bass (FILE SAVING DISABLED)
407
+ DEBUG continue_automatic_composition: current target = right_leg
408
+ DEBUG continue_automatic_composition: current target = right_leg
409
+ πŸŽ›οΈ Reverb Effect: ON
410
+ πŸŽ›οΈ Audio processed with effects: fade_rev_lpf_bass (FILE SAVING DISABLED)
411
+ DEBUG continue_automatic_composition: current target = right_leg
412
+ πŸŽ›οΈ Volume Fade: OFF
413
+ πŸŽ›οΈ Audio processed with effects: rev_lpf_bass (FILE SAVING DISABLED)
414
+ DEBUG continue_automatic_composition: current target = right_leg
415
+ DEBUG continue_automatic_composition: current target = right_leg
416
+ DEBUG continue_automatic_composition: current target = right_leg
417
+ πŸŽ›οΈ High Pass Filter: ON
418
+ πŸŽ›οΈ Audio processed with effects: hpf_rev_lpf_bass (FILE SAVING DISABLED)
419
+ DEBUG continue_automatic_composition: current target = right_leg
420
+ πŸŽ›οΈ Reverb Effect: OFF
421
+ πŸŽ›οΈ Audio processed with effects: hpf_lpf_bass (FILE SAVING DISABLED)
422
+ DEBUG continue_automatic_composition: current target = right_leg
423
+ πŸŽ›οΈ Volume Fade: ON
424
+ πŸŽ›οΈ Audio processed with effects: fade_hpf_lpf_bass (FILE SAVING DISABLED)
425
+ DEBUG continue_automatic_composition: current target = right_leg
426
+ πŸŽ›οΈ Volume Fade: OFF
427
+ πŸŽ›οΈ Audio processed with effects: hpf_lpf_bass (FILE SAVING DISABLED)
428
+ DEBUG continue_automatic_composition: current target = right_leg
429
+ πŸŽ›οΈ High Pass Filter: OFF
430
+ πŸŽ›οΈ Audio processed with effects: lpf_bass (FILE SAVING DISABLED)
431
+ DEBUG continue_automatic_composition: current target = right_leg
432
+ πŸŽ›οΈ Bass Boost: OFF
433
+ πŸŽ›οΈ Audio processed with effects: lpf (FILE SAVING DISABLED)
434
+ DEBUG continue_automatic_composition: current target = right_leg
435
+ πŸŽ›οΈ Volume Fade: ON
436
+ πŸŽ›οΈ Audio processed with effects: fade_lpf (FILE SAVING DISABLED)
437
+ DEBUG continue_automatic_composition: current target = right_leg
438
+ πŸŽ›οΈ Reverb Effect: ON
439
+ πŸŽ›οΈ Audio processed with effects: fade_rev_lpf (FILE SAVING DISABLED)
440
+ DEBUG continue_automatic_composition: current target = right_leg
441
+ DEBUG continue_automatic_composition: current target = right_leg
442
+ πŸŽ›οΈ Volume Fade: OFF
443
+ πŸŽ›οΈ Audio processed with effects: rev_lpf (FILE SAVING DISABLED)
444
+ DEBUG continue_automatic_composition: current target = right_leg
445
+ πŸŽ›οΈ Bass Boost: ON
446
+ πŸŽ›οΈ Audio processed with effects: rev_lpf_bass (FILE SAVING DISABLED)
447
+ DEBUG continue_automatic_composition: current target = right_leg
448
+ πŸŽ›οΈ Low Pass Filter: OFF
449
+ πŸŽ›οΈ Audio processed with effects: rev_bass (FILE SAVING DISABLED)
450
+ DEBUG continue_automatic_composition: current target = right_leg
451
+ πŸŽ›οΈ Low Pass Filter: ON
452
+ πŸŽ›οΈ Audio processed with effects: rev_lpf_bass (FILE SAVING DISABLED)
app.py CHANGED
@@ -9,6 +9,7 @@ import numpy as np
9
  import matplotlib.pyplot as plt
10
  import time
11
  import threading
 
12
  from typing import Dict, Tuple, Any, List
13
 
14
  # Import our custom modules
@@ -40,14 +41,7 @@ app_state = {
40
  'demo_labels': None,
41
  'classification_history': [],
42
  'composition_active': False,
43
- 'auto_mode': False,
44
- 'last_audio_state': {
45
- 'left_hand_audio': None,
46
- 'right_hand_audio': None,
47
- 'left_leg_audio': None,
48
- 'right_leg_audio': None,
49
- 'tongue_audio': None
50
- }
51
  }
52
 
53
  # Initialize components
@@ -128,23 +122,26 @@ def start_composition():
128
 
129
  # Process classification
130
  result = sound_manager.process_classification(predicted_name, confidence, CONFIDENCE_THRESHOLD)
131
-
 
 
 
 
132
  # Create visualization
133
  fig = create_eeg_plot(epoch_data, target_movement, predicted_name, confidence, result['sound_added'])
134
 
135
- # Initialize all audio components to silent (to clear any previous sounds)
136
- silent_file = "silent.wav"
137
- left_hand_audio = silent_file
138
- right_hand_audio = silent_file
139
- left_leg_audio = silent_file
140
- right_leg_audio = silent_file
141
- tongue_audio = silent_file
142
 
143
  # Debug: Print classification result
144
  print(f"DEBUG start_composition: predicted={predicted_name}, confidence={confidence:.3f}, sound_added={result['sound_added']}")
145
 
146
  # Only play the sound if it was just added and matches the prediction
147
- if result['sound_added']:
148
  sounds = get_movement_sounds()
149
  print(f"DEBUG: Available sounds: {list(sounds.keys())}")
150
  if predicted_name == 'left_hand' and 'left_hand' in sounds:
@@ -215,10 +212,10 @@ def start_automatic_composition():
215
  app_state['composition_active'] = True
216
  app_state['auto_mode'] = True
217
  sound_manager.start_new_cycle() # Reset composition only when starting fresh
218
-
219
  if app_state['demo_data'] is None:
220
- return "❌ No data", "❌ No data", "❌ No data", "❌ No data", None, None, None, None, None, None, "No EEG data available"
221
-
222
  # Get current target
223
  target_movement = sound_manager.get_current_target_movement()
224
  print(f"DEBUG start_automatic_composition: current target = {target_movement}")
@@ -283,74 +280,78 @@ def start_automatic_composition():
283
  # Create visualization
284
  fig = create_eeg_plot(epoch_data, target_movement, predicted_name, confidence, result['sound_added'])
285
 
286
- # Initialize all audio components to silent by default
287
- silent_file = "silent.wav"
288
- left_hand_audio = silent_file
289
- right_hand_audio = silent_file
290
- left_leg_audio = silent_file
291
- right_leg_audio = silent_file
292
- tongue_audio = silent_file
293
 
294
  # Debug: Print classification result
295
  print(f"DEBUG start_automatic_composition: predicted={predicted_name}, confidence={confidence:.3f}, sound_added={result['sound_added']}")
296
 
297
  # Handle audio display based on current phase
298
  if sound_manager.current_phase == "dj_effects":
299
- # DJ Effects Phase - show mixed composition with effects
300
- if result.get('mixed_composition'):
301
- # Show the mixed composition (all sounds combined) in one player
302
- left_hand_audio = result['mixed_composition'] # Use first player for mixed audio
303
- print(f"DEBUG DJ: Playing mixed composition with effects: {result['mixed_composition']}")
304
- else:
305
- # Fallback to showing accumulated sounds
306
- sounds = get_movement_sounds()
307
- completed_movements = sound_manager.movements_completed
308
- if 'left_hand' in completed_movements and 'left_hand' in sounds:
309
- left_hand_audio = sounds['left_hand']
310
- else:
311
- # Building Phase - show ALL accumulated sounds (layered composition)
312
  sounds = get_movement_sounds()
 
 
313
  completed_movements = sound_manager.movements_completed
314
- print(f"DEBUG: Available sounds: {list(sounds.keys())}")
315
- print(f"DEBUG: Completed movements: {completed_movements}")
316
-
317
- # Display all completed movement sounds (cumulative layering)
318
  if 'left_hand' in completed_movements and 'left_hand' in sounds:
319
  left_hand_audio = sounds['left_hand']
320
- print(f"DEBUG: Showing accumulated left_hand_audio: {sounds['left_hand']}")
321
  if 'right_hand' in completed_movements and 'right_hand' in sounds:
322
  right_hand_audio = sounds['right_hand']
323
- print(f"DEBUG: Showing accumulated right_hand_audio: {sounds['right_hand']}")
324
  if 'left_leg' in completed_movements and 'left_leg' in sounds:
325
  left_leg_audio = sounds['left_leg']
326
- print(f"DEBUG: Showing accumulated left_leg_audio: {sounds['left_leg']}")
327
  if 'right_leg' in completed_movements and 'right_leg' in sounds:
328
  right_leg_audio = sounds['right_leg']
329
- print(f"DEBUG: Showing accumulated right_leg_audio: {sounds['right_leg']}")
330
  if 'tongue' in completed_movements and 'tongue' in sounds:
331
  tongue_audio = sounds['tongue']
332
- print(f"DEBUG: Showing accumulated tongue_audio: {sounds['tongue']}")
 
 
 
 
 
 
 
333
 
334
- # If a sound was just added, make sure it's included immediately
335
- if result['sound_added'] and predicted_name in sounds:
336
- if predicted_name == 'left_hand':
 
 
 
 
337
  left_hand_audio = sounds['left_hand']
338
- elif predicted_name == 'right_hand':
 
339
  right_hand_audio = sounds['right_hand']
340
- elif predicted_name == 'left_leg':
 
341
  left_leg_audio = sounds['left_leg']
342
- elif predicted_name == 'right_leg':
 
343
  right_leg_audio = sounds['right_leg']
344
- elif predicted_name == 'tongue':
 
345
  tongue_audio = sounds['tongue']
346
- print(f"DEBUG: Just added {predicted_name} sound: {sounds[predicted_name]}")
 
 
347
 
348
  # Check for phase transition to DJ effects
349
  completed_count = len(sound_manager.movements_completed)
350
  total_count = len(sound_manager.current_movement_sequence)
351
 
352
  # Transition to DJ effects if all movements completed but still in building phase
353
- if completed_count >= 5 and sound_manager.current_phase == "building":
354
  sound_manager.transition_to_dj_phase()
355
 
356
  # Format display based on current phase
@@ -547,123 +548,54 @@ def continue_automatic_composition():
547
  # Create visualization
548
  fig = create_eeg_plot(epoch_data, target_movement, predicted_name, confidence, result['sound_added'])
549
 
550
- # Initialize all audio components to silent by default
551
- silent_file = "silent.wav"
552
- left_hand_audio = silent_file
553
- right_hand_audio = silent_file
554
- left_leg_audio = silent_file
555
- right_leg_audio = silent_file
556
- tongue_audio = silent_file
557
 
558
  # Handle audio differently based on phase
559
  if sound_manager.current_phase == "dj_effects":
560
- # DJ Mode: Play mixed composition with effects in the center position (tongue)
561
- # Keep individual tracks silent to avoid overlapping audio
562
- # Only update audio if the mixed composition file has actually changed
563
- if sound_manager.mixed_composition_file and os.path.exists(sound_manager.mixed_composition_file):
564
- # Only update if the file path has changed from last time
565
- if app_state['last_audio_state']['tongue_audio'] != sound_manager.mixed_composition_file:
566
- tongue_audio = sound_manager.mixed_composition_file
567
- app_state['last_audio_state']['tongue_audio'] = sound_manager.mixed_composition_file
568
- print(f"DEBUG continue: DJ mode - NEW mixed composition loaded: {sound_manager.mixed_composition_file}")
569
- elif app_state['last_audio_state']['tongue_audio'] is not None:
570
- # Use the same file as before to prevent Gradio from restarting audio
571
- tongue_audio = app_state['last_audio_state']['tongue_audio']
572
- # No debug print to reduce spam
573
- else:
574
- # Handle case where cached state is None - use the current file
575
- tongue_audio = sound_manager.mixed_composition_file
576
- app_state['last_audio_state']['tongue_audio'] = sound_manager.mixed_composition_file
577
- print(f"DEBUG continue: DJ mode - Loading mixed composition (state was None): {sound_manager.mixed_composition_file}")
578
- # Note: We don't update with processed effects files to prevent audio restarts
579
  else:
580
- # Building Mode: Show ALL accumulated sounds (layered composition)
 
581
  sounds = get_movement_sounds()
582
  completed_movements = sound_manager.movements_completed
583
  print(f"DEBUG continue: Available sounds: {list(sounds.keys())}")
584
  print(f"DEBUG continue: Completed movements: {completed_movements}")
585
 
586
- # Display all completed movement sounds (cumulative layering) - only update when changed
587
- if 'left_hand' in completed_movements and 'left_hand' in sounds:
588
- new_left_hand = sounds['left_hand']
589
- if app_state['last_audio_state']['left_hand_audio'] != new_left_hand:
590
- left_hand_audio = new_left_hand
591
- app_state['last_audio_state']['left_hand_audio'] = new_left_hand
592
- print(f"DEBUG continue: NEW left_hand_audio: {new_left_hand}")
593
- elif app_state['last_audio_state']['left_hand_audio'] is not None:
594
- left_hand_audio = app_state['last_audio_state']['left_hand_audio']
595
- else:
596
- # Handle case where cached state is None - use the current file
597
- left_hand_audio = new_left_hand
598
- app_state['last_audio_state']['left_hand_audio'] = new_left_hand
599
-
600
- if 'right_hand' in completed_movements and 'right_hand' in sounds:
601
- new_right_hand = sounds['right_hand']
602
- # TEMP FIX: Always update right_hand to test audio issue
603
- right_hand_audio = new_right_hand
604
- app_state['last_audio_state']['right_hand_audio'] = new_right_hand
605
- print(f"DEBUG continue: ALWAYS UPDATE right_hand_audio: {new_right_hand}")
606
-
607
- if 'left_leg' in completed_movements and 'left_leg' in sounds:
608
- new_left_leg = sounds['left_leg']
609
- if app_state['last_audio_state']['left_leg_audio'] != new_left_leg:
610
- left_leg_audio = new_left_leg
611
- app_state['last_audio_state']['left_leg_audio'] = new_left_leg
612
- print(f"DEBUG continue: NEW left_leg_audio: {new_left_leg}")
613
- elif app_state['last_audio_state']['left_leg_audio'] is not None:
614
- left_leg_audio = app_state['last_audio_state']['left_leg_audio']
615
- else:
616
- # Handle case where cached state is None - use the current file
617
- left_leg_audio = new_left_leg
618
- app_state['last_audio_state']['left_leg_audio'] = new_left_leg
619
-
620
- if 'right_leg' in completed_movements and 'right_leg' in sounds:
621
- new_right_leg = sounds['right_leg']
622
- if app_state['last_audio_state']['right_leg_audio'] != new_right_leg:
623
- right_leg_audio = new_right_leg
624
- app_state['last_audio_state']['right_leg_audio'] = new_right_leg
625
- print(f"DEBUG continue: NEW right_leg_audio: {new_right_leg}")
626
- elif app_state['last_audio_state']['right_leg_audio'] is not None:
627
- right_leg_audio = app_state['last_audio_state']['right_leg_audio']
628
- else:
629
- # Handle case where cached state is None - use the current file
630
- right_leg_audio = new_right_leg
631
- app_state['last_audio_state']['right_leg_audio'] = new_right_leg
632
 
633
- if 'tongue' in completed_movements and 'tongue' in sounds:
634
- new_tongue = sounds['tongue']
635
- # Note: Don't update tongue audio in building mode if we're about to transition to DJ mode
636
- if sound_manager.current_phase == "building":
637
- if app_state['last_audio_state']['tongue_audio'] != new_tongue:
638
- tongue_audio = new_tongue
639
- app_state['last_audio_state']['tongue_audio'] = new_tongue
640
- print(f"DEBUG continue: NEW tongue_audio: {new_tongue}")
641
- elif app_state['last_audio_state']['tongue_audio'] is not None:
642
- tongue_audio = app_state['last_audio_state']['tongue_audio']
643
- else:
644
- # Handle case where cached state is None - use the current file
645
- tongue_audio = new_tongue
646
- app_state['last_audio_state']['tongue_audio'] = new_tongue
647
-
648
- # If a sound was just added, make sure it gets updated immediately (override state check)
649
- if result['sound_added'] and predicted_name in sounds:
650
- new_sound = sounds[predicted_name]
651
- if predicted_name == 'left_hand':
652
- left_hand_audio = new_sound
653
- app_state['last_audio_state']['left_hand_audio'] = new_sound
654
- elif predicted_name == 'right_hand':
655
- right_hand_audio = new_sound
656
- app_state['last_audio_state']['right_hand_audio'] = new_sound
657
- elif predicted_name == 'left_leg':
658
- left_leg_audio = new_sound
659
- app_state['last_audio_state']['left_leg_audio'] = new_sound
660
- elif predicted_name == 'right_leg':
661
- right_leg_audio = new_sound
662
- app_state['last_audio_state']['right_leg_audio'] = new_sound
663
- elif predicted_name == 'tongue':
664
- tongue_audio = new_sound
665
- app_state['last_audio_state']['tongue_audio'] = new_sound
666
- print(f"DEBUG continue: Force update - just added {predicted_name} sound: {new_sound}")
667
 
668
  # Format display with progress information
669
  completed_count = len(sound_manager.movements_completed)
@@ -745,27 +677,26 @@ def classify_epoch():
745
  # Create visualization
746
  fig = create_eeg_plot(epoch_data, target_movement, predicted_name, confidence, result['sound_added'])
747
 
748
- # Initialize all audio components to silent (to clear any previous sounds)
749
- silent_file = "silent.wav"
750
- left_hand_audio = silent_file
751
- right_hand_audio = silent_file
752
- left_leg_audio = silent_file
753
- right_leg_audio = silent_file
754
- tongue_audio = silent_file
755
 
756
- # Only play the sound if it was just added and matches the prediction
757
- if result['sound_added']:
758
- sounds = get_movement_sounds()
759
- if predicted_name == 'left_hand' and 'left_hand' in sounds:
760
- left_hand_audio = sounds['left_hand']
761
- elif predicted_name == 'right_hand' and 'right_hand' in sounds:
762
- right_hand_audio = sounds['right_hand']
763
- elif predicted_name == 'left_leg' and 'left_leg' in sounds:
764
- left_leg_audio = sounds['left_leg']
765
- elif predicted_name == 'right_leg' and 'right_leg' in sounds:
766
- right_leg_audio = sounds['right_leg']
767
- elif predicted_name == 'tongue' and 'tongue' in sounds:
768
- tongue_audio = sounds['tongue']
769
 
770
  # Format next target
771
  next_target = sound_manager.get_current_target_movement()
 
9
  import matplotlib.pyplot as plt
10
  import time
11
  import threading
12
+ import os
13
  from typing import Dict, Tuple, Any, List
14
 
15
  # Import our custom modules
 
41
  'demo_labels': None,
42
  'classification_history': [],
43
  'composition_active': False,
44
+ 'auto_mode': False
 
 
 
 
 
 
 
45
  }
46
 
47
  # Initialize components
 
122
 
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']}")
142
 
143
  # Only play the sound if it was just added and matches the prediction
144
+ if result['sound_added']: # might add confidence threshold for sound output here
145
  sounds = get_movement_sounds()
146
  print(f"DEBUG: Available sounds: {list(sounds.keys())}")
147
  if predicted_name == 'left_hand' and 'left_hand' in sounds:
 
212
  app_state['composition_active'] = True
213
  app_state['auto_mode'] = True
214
  sound_manager.start_new_cycle() # Reset composition only when starting fresh
215
+
216
  if app_state['demo_data'] is None:
217
+ return "❌ No data", "❌ No data", "❌ No data", "❌ No data", None, None, None, None, None, None, "No EEG data available", gr.update(visible=True), gr.update(visible=False)
218
+
219
  # Get current target
220
  target_movement = sound_manager.get_current_target_movement()
221
  print(f"DEBUG start_automatic_composition: current target = {target_movement}")
 
280
  # Create visualization
281
  fig = create_eeg_plot(epoch_data, target_movement, predicted_name, confidence, result['sound_added'])
282
 
283
+
284
+ # Initialize all audio components to None (no sound by default)
285
+ left_hand_audio = None
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']}")
293
 
294
  # Handle audio display based on current phase
295
  if sound_manager.current_phase == "dj_effects":
296
+ # DJ Effects Phase - continue showing individual sounds in their players
 
 
 
 
 
 
 
 
 
 
 
 
297
  sounds = get_movement_sounds()
298
+ # Always check for phase transition to DJ effects after each classification
299
+ sound_manager.transition_to_dj_phase()
300
  completed_movements = sound_manager.movements_completed
301
+ # Display each completed movement sound in its respective player (same as building mode)
 
 
 
302
  if 'left_hand' in completed_movements and 'left_hand' in sounds:
303
  left_hand_audio = sounds['left_hand']
304
+ print(f"DEBUG DJ: Left hand playing: {sounds['left_hand']}")
305
  if 'right_hand' in completed_movements and 'right_hand' in sounds:
306
  right_hand_audio = sounds['right_hand']
307
+ print(f"DEBUG DJ: Right hand playing: {sounds['right_hand']}")
308
  if 'left_leg' in completed_movements and 'left_leg' in sounds:
309
  left_leg_audio = sounds['left_leg']
310
+ print(f"DEBUG DJ: Left leg playing: {sounds['left_leg']}")
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
320
+ sounds = get_movement_sounds()
321
+ completed_movements = sound_manager.movements_completed
322
+ print(f"DEBUG: Available sounds: {list(sounds.keys())}")
323
+ print(f"DEBUG: Completed movements: {completed_movements}")
324
 
325
+ # Display individual sounds in their respective players for layered composition
326
+ # All completed movement sounds will play simultaneously, creating natural layering
327
+ if len(completed_movements) > 0:
328
+ print(f"DEBUG: Showing individual sounds that will layer together: {list(completed_movements)}")
329
+
330
+ # Display each completed movement sound in its respective player
331
+ if 'left_hand' in completed_movements and 'left_hand' in sounds:
332
  left_hand_audio = sounds['left_hand']
333
+ print(f"DEBUG: Left hand playing: {sounds['left_hand']}")
334
+ if 'right_hand' in completed_movements and 'right_hand' in sounds:
335
  right_hand_audio = sounds['right_hand']
336
+ print(f"DEBUG: Right hand playing: {sounds['right_hand']}")
337
+ if 'left_leg' in completed_movements and 'left_leg' in sounds:
338
  left_leg_audio = sounds['left_leg']
339
+ print(f"DEBUG: Left leg playing: {sounds['left_leg']}")
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
 
349
  # Check for phase transition to DJ effects
350
  completed_count = len(sound_manager.movements_completed)
351
  total_count = len(sound_manager.current_movement_sequence)
352
 
353
  # Transition to DJ effects if all movements completed but still in building phase
354
+ if completed_count >= total_count and sound_manager.current_phase == "building":
355
  sound_manager.transition_to_dj_phase()
356
 
357
  # Format display based on current phase
 
548
  # Create visualization
549
  fig = create_eeg_plot(epoch_data, target_movement, predicted_name, confidence, result['sound_added'])
550
 
551
+ # Initialize all audio components to None (no sound by default)
552
+ left_hand_audio = None
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":
560
+ # DJ Mode: Show only the full mixed track and route effects to it
561
+ mixed_track = sound_manager.get_current_mixed_composition()
562
+ print(f"DEBUG continue: DJ Mode - Showing full mixed track: {mixed_track}")
563
+ # Hide individual movement sounds by setting them to None
564
+ left_hand_audio = None
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
572
+ # All completed movement sounds will play simultaneously, creating natural layering
573
  sounds = get_movement_sounds()
574
  completed_movements = sound_manager.movements_completed
575
  print(f"DEBUG continue: Available sounds: {list(sounds.keys())}")
576
  print(f"DEBUG continue: Completed movements: {completed_movements}")
577
 
578
+ if len(completed_movements) > 0:
579
+ print(f"DEBUG continue: Showing individual sounds that will layer together: {list(completed_movements)}")
580
+
581
+ # Display each completed movement sound in its respective player
582
+ if 'left_hand' in completed_movements and 'left_hand' in sounds:
583
+ left_hand_audio = sounds['left_hand']
584
+ print(f"DEBUG continue: Left hand playing: {sounds['left_hand']}")
585
+ if 'right_hand' in completed_movements and 'right_hand' in sounds:
586
+ right_hand_audio = sounds['right_hand']
587
+ print(f"DEBUG continue: Right hand playing: {sounds['right_hand']}")
588
+ if 'left_leg' in completed_movements and 'left_leg' in sounds:
589
+ left_leg_audio = sounds['left_leg']
590
+ print(f"DEBUG continue: Left leg playing: {sounds['left_leg']}")
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
 
600
  # Format display with progress information
601
  completed_count = len(sound_manager.movements_completed)
 
677
  # Create visualization
678
  fig = create_eeg_plot(epoch_data, target_movement, predicted_name, confidence, result['sound_added'])
679
 
680
+ # Initialize all audio components to None (no sound by default)
681
+ left_hand_audio = None
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()
689
+ completed_movements = sound_manager.movements_completed
690
+ if 'left_hand' in completed_movements and 'left_hand' in sounds:
691
+ left_hand_audio = sounds['left_hand']
692
+ if 'right_hand' in completed_movements and 'right_hand' in sounds:
693
+ right_hand_audio = sounds['right_hand']
694
+ if 'left_leg' in completed_movements and 'left_leg' in sounds:
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()
config.py CHANGED
@@ -61,9 +61,9 @@ CLASS_DESCRIPTIONS = {
61
 
62
  # Demo data paths (optional) - updated with available files
63
  DEMO_DATA_PATHS = [
64
- "data/raw_mat/HaLTSubjectA1602236StLRHandLegTongue.mat",
65
- "data/raw_mat/HaLTSubjectA1603086StLRHandLegTongue.mat",
66
- "data/raw_mat/HaLTSubjectA1603106StLRHandLegTongue.mat",
67
  ]
68
 
69
  # Gradio settings
 
61
 
62
  # Demo data paths (optional) - updated with available files
63
  DEMO_DATA_PATHS = [
64
+ "data/HaLTSubjectA1602236StLRHandLegTongue.mat",
65
+ "data/HaLTSubjectA1603086StLRHandLegTongue.mat",
66
+ "data/HaLTSubjectA1603106StLRHandLegTongue.mat",
67
  ]
68
 
69
  # Gradio settings
sound_library.py CHANGED
@@ -129,56 +129,43 @@ class AudioEffectsProcessor:
129
 
130
  @staticmethod
131
  def process_with_effects(audio_file: str, active_effects: Dict[str, bool]) -> str:
132
- """Process audio file with active effects and return processed version."""
133
  try:
134
- # Check if audio_file is valid
135
  if not audio_file or not os.path.exists(audio_file):
136
  print(f"Invalid audio file: {audio_file}")
137
  return audio_file
138
-
139
- # Read audio file
140
  data, samplerate = sf.read(audio_file)
141
-
142
- # Handle stereo to mono conversion if needed
143
  if len(data.shape) > 1:
144
  data = np.mean(data, axis=1)
145
-
146
- # Apply effects based on active states
147
  processed_data = np.copy(data)
148
  effect_names = []
149
-
150
- if active_effects.get("left_hand", False): # Volume Fade
151
  processed_data = AudioEffectsProcessor.apply_volume_fade(processed_data, "out")
152
  effect_names.append("fade")
153
-
154
- if active_effects.get("right_hand", False): # High Pass Filter
155
  processed_data = AudioEffectsProcessor.apply_high_pass_filter(processed_data, samplerate)
156
  effect_names.append("hpf")
157
-
158
- if active_effects.get("left_leg", False): # Reverb
159
  processed_data = AudioEffectsProcessor.apply_reverb(processed_data, samplerate)
160
  effect_names.append("rev")
161
-
162
- if active_effects.get("right_leg", False): # Low Pass Filter
163
  processed_data = AudioEffectsProcessor.apply_low_pass_filter(processed_data, samplerate)
164
  effect_names.append("lpf")
165
-
166
- if active_effects.get("tongue", False): # Bass Boost
167
  processed_data = AudioEffectsProcessor.apply_bass_boost(processed_data, samplerate)
168
  effect_names.append("bass")
169
-
170
  # Create unique filename based on active effects
171
  base_name = os.path.splitext(audio_file)[0]
172
  effects_suffix = "_".join(effect_names) if effect_names else "clean"
173
  processed_file = f"{base_name}_fx_{effects_suffix}.wav"
174
-
175
- # Save processed audio
176
- # sf.write(processed_file, processed_data, samplerate)
177
- print(f"πŸŽ›οΈ Audio processed with effects: {effects_suffix} (FILE SAVING DISABLED)")
178
-
179
- # Return absolute path (using original file since saving is disabled)
180
- return os.path.abspath(audio_file)
181
-
182
  except Exception as e:
183
  print(f"Audio processing failed: {e}")
184
  return os.path.abspath(audio_file) if audio_file else None
@@ -281,13 +268,14 @@ class SoundManager:
281
  """Generate a new random sequence of movements for the current cycle."""
282
  import random
283
  # Choose which movements to include based on configuration
284
- movements_for_cycle = self.all_movements.copy() if self.include_neutral_in_cycle else self.active_movements.copy()
 
285
  random.shuffle(movements_for_cycle)
286
- self.current_movement_sequence = movements_for_cycle
287
  self.movements_completed = set()
288
-
289
- cycle_size = len(movements_for_cycle)
290
  print(f"🎯 New random sequence ({cycle_size} movements): {' β†’ '.join([m.replace('_', ' ').title() for m in self.current_movement_sequence])}")
 
291
 
292
  def get_current_target_movement(self) -> str:
293
  """Get the current movement the user should imagine."""
@@ -422,9 +410,15 @@ class SoundManager:
422
 
423
  def transition_to_dj_phase(self):
424
  """Transition from building phase to DJ effects phase."""
425
- if len(self.movements_completed) >= 5: # All movements completed
 
 
 
 
 
 
 
426
  self.current_phase = "dj_effects"
427
- # Create mixed composition for DJ effects
428
  self._create_mixed_composition()
429
  print("🎡 Composition Complete! Transitioning to DJ Effects Phase...")
430
  print("🎧 You are now the DJ! Use movements to control effects:")
@@ -434,6 +428,8 @@ class SoundManager:
434
  print(" 🦡 Right Leg: Low Pass Filter")
435
  print(" πŸ‘… Tongue: Bass Boost")
436
  return True
 
 
437
  return False
438
 
439
  def _create_mixed_composition(self):
@@ -526,10 +522,9 @@ class SoundManager:
526
  if movement not in self.active_effects:
527
  return {"effect_applied": False, "message": f"Unknown movement: {movement}"}
528
 
529
- # Toggle the effect
530
  self.active_effects[movement] = not self.active_effects[movement]
531
  effect_status = "ON" if self.active_effects[movement] else "OFF"
532
-
533
  effect_names = {
534
  "left_hand": "Volume Fade",
535
  "right_hand": "High Pass Filter",
@@ -537,10 +532,8 @@ class SoundManager:
537
  "right_leg": "Low Pass Filter",
538
  "tongue": "Bass Boost"
539
  }
540
-
541
  effect_name = effect_names.get(movement, movement)
542
  print(f"πŸŽ›οΈ {effect_name}: {effect_status}")
543
-
544
  # Process audio with current active effects
545
  if self.mixed_composition_file and os.path.exists(self.mixed_composition_file):
546
  processed_file = AudioEffectsProcessor.process_with_effects(
@@ -559,7 +552,7 @@ class SoundManager:
559
  else:
560
  print("Failed to create mixed composition, using fallback")
561
  processed_file = self.mixed_composition_file
562
-
563
  return {
564
  "effect_applied": True,
565
  "effect_name": effect_name,
@@ -651,6 +644,15 @@ class SoundManager:
651
  first_audio_file = os.path.join(self.sound_dir, audio_files[0])
652
  if os.path.exists(first_audio_file):
653
  print(f"DEBUG: Using first audio file as mixed composition: {os.path.basename(first_audio_file)} (FILE SAVING DISABLED)")
 
 
 
 
 
 
 
 
 
654
  return first_audio_file
655
 
656
  # Fallback: if mixed composition file already exists, use it
 
129
 
130
  @staticmethod
131
  def process_with_effects(audio_file: str, active_effects: Dict[str, bool]) -> str:
132
+ """Process the full track (mixed composition) with DJ effects only."""
133
  try:
 
134
  if not audio_file or not os.path.exists(audio_file):
135
  print(f"Invalid audio file: {audio_file}")
136
  return audio_file
 
 
137
  data, samplerate = sf.read(audio_file)
 
 
138
  if len(data.shape) > 1:
139
  data = np.mean(data, axis=1)
 
 
140
  processed_data = np.copy(data)
141
  effect_names = []
142
+ # Apply DJ effects to the full track
143
+ if active_effects.get("left_hand", False):
144
  processed_data = AudioEffectsProcessor.apply_volume_fade(processed_data, "out")
145
  effect_names.append("fade")
146
+ if active_effects.get("right_hand", False):
 
147
  processed_data = AudioEffectsProcessor.apply_high_pass_filter(processed_data, samplerate)
148
  effect_names.append("hpf")
149
+ if active_effects.get("left_leg", False):
 
150
  processed_data = AudioEffectsProcessor.apply_reverb(processed_data, samplerate)
151
  effect_names.append("rev")
152
+ if active_effects.get("right_leg", False):
 
153
  processed_data = AudioEffectsProcessor.apply_low_pass_filter(processed_data, samplerate)
154
  effect_names.append("lpf")
155
+ if active_effects.get("tongue", False):
 
156
  processed_data = AudioEffectsProcessor.apply_bass_boost(processed_data, samplerate)
157
  effect_names.append("bass")
 
158
  # Create unique filename based on active effects
159
  base_name = os.path.splitext(audio_file)[0]
160
  effects_suffix = "_".join(effect_names) if effect_names else "clean"
161
  processed_file = f"{base_name}_fx_{effects_suffix}.wav"
162
+ try:
163
+ #sf.write(processed_file, processed_data, samplerate)
164
+ print(f"πŸŽ›οΈ Audio processed with effects: {effects_suffix} β†’ {os.path.basename(processed_file)}")
165
+ return os.path.abspath(processed_file)
166
+ except Exception as e:
167
+ print(f"Failed to save processed audio: {e}")
168
+ return os.path.abspath(audio_file)
 
169
  except Exception as e:
170
  print(f"Audio processing failed: {e}")
171
  return os.path.abspath(audio_file) if audio_file else None
 
268
  """Generate a new random sequence of movements for the current cycle."""
269
  import random
270
  # Choose which movements to include based on configuration
271
+ # Always use exactly 5 movements per cycle
272
+ movements_for_cycle = self.active_movements.copy()
273
  random.shuffle(movements_for_cycle)
274
+ self.current_movement_sequence = movements_for_cycle[:5]
275
  self.movements_completed = set()
276
+ cycle_size = len(self.current_movement_sequence)
 
277
  print(f"🎯 New random sequence ({cycle_size} movements): {' β†’ '.join([m.replace('_', ' ').title() for m in self.current_movement_sequence])}")
278
+ print(f"DEBUG: Movement sequence length = {len(self.current_movement_sequence)}")
279
 
280
  def get_current_target_movement(self) -> str:
281
  """Get the current movement the user should imagine."""
 
410
 
411
  def transition_to_dj_phase(self):
412
  """Transition from building phase to DJ effects phase."""
413
+ # Only start DJ mode if all 5 sound layers are present (not just movements completed)
414
+ unique_sounds = set()
415
+ for layer in self.composition_layers:
416
+ if layer.get('sound_file'):
417
+ unique_sounds.add(layer['sound_file'])
418
+ print(f"DEBUG: Unique sound files in composition_layers: {unique_sounds}")
419
+ print(f"DEBUG: Number of unique sounds: {len(unique_sounds)}")
420
+ if len(unique_sounds) >= 5:
421
  self.current_phase = "dj_effects"
 
422
  self._create_mixed_composition()
423
  print("🎡 Composition Complete! Transitioning to DJ Effects Phase...")
424
  print("🎧 You are now the DJ! Use movements to control effects:")
 
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.")
433
  return False
434
 
435
  def _create_mixed_composition(self):
 
522
  if movement not in self.active_effects:
523
  return {"effect_applied": False, "message": f"Unknown movement: {movement}"}
524
 
525
+ # Simple toggle logic, no BPM/beat duration, no auto-off
526
  self.active_effects[movement] = not self.active_effects[movement]
527
  effect_status = "ON" if self.active_effects[movement] else "OFF"
 
528
  effect_names = {
529
  "left_hand": "Volume Fade",
530
  "right_hand": "High Pass Filter",
 
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}")
 
537
  # Process audio with current active effects
538
  if self.mixed_composition_file and os.path.exists(self.mixed_composition_file):
539
  processed_file = AudioEffectsProcessor.process_with_effects(
 
552
  else:
553
  print("Failed to create mixed composition, using fallback")
554
  processed_file = self.mixed_composition_file
555
+
556
  return {
557
  "effect_applied": True,
558
  "effect_name": effect_name,
 
644
  first_audio_file = os.path.join(self.sound_dir, audio_files[0])
645
  if os.path.exists(first_audio_file):
646
  print(f"DEBUG: Using first audio file as mixed composition: {os.path.basename(first_audio_file)} (FILE SAVING DISABLED)")
647
+ # Estimate BPM from the mixed composition audio file
648
+ try:
649
+ import librosa
650
+ y, sr = librosa.load(first_audio_file, sr=None)
651
+ tempo, _ = librosa.beat.beat_track(y=y, sr=sr)
652
+ self.bpm = int(tempo)
653
+ print(f"Estimated BPM from track: {self.bpm}")
654
+ except Exception as e:
655
+ print(f"Could not estimate BPM: {e}")
656
  return first_audio_file
657
 
658
  # Fallback: if mixed composition file already exists, use it