baouws commited on
Commit
f19fe63
Ā·
verified Ā·
1 Parent(s): 6c19b42

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +148 -29
app.py CHANGED
@@ -87,7 +87,7 @@ with gr.Blocks(title="šŸŽµ Strudel Generator") as app:
87
  lines=8
88
  )
89
 
90
- # Simple audio player
91
  gr.HTML("""
92
  <div id="player" style='
93
  background: linear-gradient(135deg, #FF6B9D, #A855F7);
@@ -122,20 +122,47 @@ with gr.Blocks(title="šŸŽµ Strudel Generator") as app:
122
  transition: all 0.3s;
123
  '>ā¹ļø Stop</button>
124
  <div id="status" style='color: white; margin-top: 10px; font-size: 14px;'>
125
- Generate code and click play!
126
  </div>
127
  </div>
128
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  <script>
130
  let isPlaying = false;
131
- let playTimer = null;
 
132
 
133
  function getCurrentCode() {
134
- // Get code from the textarea
135
- const codeArea = document.querySelector('textarea[data-testid*="code"]') ||
136
- document.querySelector('.code-container textarea') ||
137
- document.querySelector('textarea');
138
- return codeArea ? codeArea.value : '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
 
141
  function updateStatus(message, color = 'white') {
@@ -153,15 +180,42 @@ with gr.Blocks(title="šŸŽµ Strudel Generator") as app:
153
  }
154
  }
155
 
156
- function togglePlay() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  if (isPlaying) {
158
  pausePlay();
159
  } else {
160
- startPlay();
161
  }
162
  }
163
 
164
- function startPlay() {
165
  const code = getCurrentCode();
166
 
167
  if (!code || code.trim() === '' || code.includes('Please describe')) {
@@ -169,37 +223,92 @@ with gr.Blocks(title="šŸŽµ Strudel Generator") as app:
169
  return;
170
  }
171
 
172
- isPlaying = true;
173
- updatePlayButton(true);
174
- updateStatus('šŸŽµ Playing your music...', '#ccffcc');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
- // Simulate playback for 10 seconds
177
- playTimer = setTimeout(() => {
178
- stopPlay();
179
- updateStatus('Playback finished!', 'white');
180
- }, 10000);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  }
182
 
183
  function pausePlay() {
 
 
 
 
184
  isPlaying = false;
185
  updatePlayButton(false);
186
  updateStatus('āøļø Paused', '#ffffcc');
187
-
188
- if (playTimer) {
189
- clearTimeout(playTimer);
190
- playTimer = null;
191
- }
192
  }
193
 
194
  function stopPlay() {
 
 
 
 
 
195
  isPlaying = false;
196
  updatePlayButton(false);
197
  updateStatus('ā¹ļø Stopped', 'white');
198
-
199
- if (playTimer) {
200
- clearTimeout(playTimer);
201
- playTimer = null;
202
- }
203
  }
204
 
205
  // Add hover effects to buttons
@@ -215,6 +324,16 @@ with gr.Blocks(title="šŸŽµ Strudel Generator") as app:
215
  this.style.boxShadow = 'none';
216
  });
217
  });
 
 
 
 
 
 
 
 
 
 
218
  });
219
  </script>
220
  """)
 
87
  lines=8
88
  )
89
 
90
+ # Simple audio player with full Strudel.js
91
  gr.HTML("""
92
  <div id="player" style='
93
  background: linear-gradient(135deg, #FF6B9D, #A855F7);
 
122
  transition: all 0.3s;
123
  '>ā¹ļø Stop</button>
124
  <div id="status" style='color: white; margin-top: 10px; font-size: 14px;'>
125
+ Click to enable audio, then generate code and play!
126
  </div>
127
  </div>
128
 
129
+ <!-- Load Strudel.js libraries -->
130
+ <script type="module">
131
+ import { repl, controls, mini, initAudioOnFirstClick } from 'https://strudel.cc/strudel.mjs';
132
+
133
+ // Make Strudel available globally
134
+ window.strudel = { repl, controls, mini, initAudioOnFirstClick };
135
+ window.strudelReady = true;
136
+
137
+ console.log('Strudel.js loaded successfully!');
138
+ updateStatus('šŸŽµ Strudel.js ready! Generate code and play!', 'white');
139
+ </script>
140
+
141
  <script>
142
  let isPlaying = false;
143
+ let currentPattern = null;
144
+ let strudelInitialized = false;
145
 
146
  function getCurrentCode() {
147
+ // Get code from the textarea - try multiple selectors
148
+ const selectors = [
149
+ 'textarea[data-testid*="code"]',
150
+ '.code-container textarea',
151
+ 'textarea',
152
+ 'code',
153
+ '[data-testid="code"] textarea'
154
+ ];
155
+
156
+ for (let selector of selectors) {
157
+ const element = document.querySelector(selector);
158
+ if (element && (element.value || element.textContent)) {
159
+ const code = element.value || element.textContent;
160
+ if (code && !code.includes('Please describe') && code.includes('cpm')) {
161
+ return code;
162
+ }
163
+ }
164
+ }
165
+ return '';
166
  }
167
 
168
  function updateStatus(message, color = 'white') {
 
180
  }
181
  }
182
 
183
+ async function initializeStrudel() {
184
+ if (strudelInitialized) return true;
185
+
186
+ try {
187
+ // Wait for Strudel to load
188
+ let attempts = 0;
189
+ while (!window.strudelReady && attempts < 50) {
190
+ await new Promise(resolve => setTimeout(resolve, 100));
191
+ attempts++;
192
+ }
193
+
194
+ if (!window.strudel) {
195
+ throw new Error('Strudel failed to load');
196
+ }
197
+
198
+ // Initialize audio on first click
199
+ await window.strudel.initAudioOnFirstClick();
200
+ strudelInitialized = true;
201
+ updateStatus('šŸŽµ Audio ready! Generate code and play!', '#ccffcc');
202
+ return true;
203
+ } catch (error) {
204
+ console.error('Strudel initialization failed:', error);
205
+ updateStatus('āš ļø Audio init failed - using demo mode', '#ffcccc');
206
+ return false;
207
+ }
208
+ }
209
+
210
+ async function togglePlay() {
211
  if (isPlaying) {
212
  pausePlay();
213
  } else {
214
+ await startPlay();
215
  }
216
  }
217
 
218
+ async function startPlay() {
219
  const code = getCurrentCode();
220
 
221
  if (!code || code.trim() === '' || code.includes('Please describe')) {
 
223
  return;
224
  }
225
 
226
+ try {
227
+ // Initialize Strudel if needed
228
+ const initialized = await initializeStrudel();
229
+
230
+ if (!initialized || !window.strudel) {
231
+ // Fallback to demo mode
232
+ updateStatus('šŸŽ® Demo: Playing ' + code.split('\\n')[0] + '...', '#ffffcc');
233
+ isPlaying = true;
234
+ updatePlayButton(true);
235
+
236
+ setTimeout(() => {
237
+ stopPlay();
238
+ updateStatus('Demo playback finished!', 'white');
239
+ }, 8000);
240
+ return;
241
+ }
242
+
243
+ // Stop any current pattern
244
+ if (currentPattern) {
245
+ currentPattern.stop();
246
+ }
247
+
248
+ updateStatus('šŸŽµ Evaluating code...', '#ffffcc');
249
+
250
+ // Clean the code (remove comments)
251
+ const cleanCode = code
252
+ .split('\\n')
253
+ .filter(line => !line.trim().startsWith('//'))
254
+ .join('\\n')
255
+ .trim();
256
+
257
+ console.log('Playing code:', cleanCode);
258
 
259
+ // Evaluate the Strudel pattern
260
+ const pattern = window.strudel.repl.evaluate(cleanCode);
261
+
262
+ if (pattern && typeof pattern.play === 'function') {
263
+ currentPattern = pattern;
264
+ await pattern.play();
265
+
266
+ isPlaying = true;
267
+ updatePlayButton(true);
268
+ updateStatus('šŸŽµ Playing your music! šŸŽ¶', '#ccffcc');
269
+ } else {
270
+ throw new Error('Invalid pattern - check your Strudel syntax');
271
+ }
272
+
273
+ } catch (error) {
274
+ console.error('Playback error:', error);
275
+ updateStatus('āŒ Error: ' + error.message, '#ffcccc');
276
+ isPlaying = false;
277
+ updatePlayButton(false);
278
+
279
+ // Try demo mode as fallback
280
+ setTimeout(() => {
281
+ updateStatus('šŸŽ® Falling back to demo mode...', '#ffffcc');
282
+ isPlaying = true;
283
+ updatePlayButton(true);
284
+
285
+ setTimeout(() => {
286
+ stopPlay();
287
+ updateStatus('Demo playback finished!', 'white');
288
+ }, 5000);
289
+ }, 1000);
290
+ }
291
  }
292
 
293
  function pausePlay() {
294
+ if (currentPattern && typeof currentPattern.stop === 'function') {
295
+ currentPattern.stop();
296
+ }
297
+
298
  isPlaying = false;
299
  updatePlayButton(false);
300
  updateStatus('āøļø Paused', '#ffffcc');
 
 
 
 
 
301
  }
302
 
303
  function stopPlay() {
304
+ if (currentPattern && typeof currentPattern.stop === 'function') {
305
+ currentPattern.stop();
306
+ currentPattern = null;
307
+ }
308
+
309
  isPlaying = false;
310
  updatePlayButton(false);
311
  updateStatus('ā¹ļø Stopped', 'white');
 
 
 
 
 
312
  }
313
 
314
  // Add hover effects to buttons
 
324
  this.style.boxShadow = 'none';
325
  });
326
  });
327
+
328
+ // Initialize on first user interaction
329
+ document.addEventListener('click', initializeStrudel, { once: true });
330
+ });
331
+
332
+ // Handle page visibility changes
333
+ document.addEventListener('visibilitychange', function() {
334
+ if (document.hidden && isPlaying) {
335
+ pausePlay();
336
+ }
337
  });
338
  </script>
339
  """)