baouws commited on
Commit
f39d666
Β·
verified Β·
1 Parent(s): a7003ac

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +528 -201
app.py CHANGED
@@ -2,7 +2,7 @@ import gradio as gr
2
  import random
3
  import time
4
 
5
- # Matrix Music Hacker - Fixed Voice Recognition Version
6
  def create_interface():
7
 
8
  # Matrix-themed CSS
@@ -48,11 +48,19 @@ def create_interface():
48
  function() {
49
  console.log('🎡 Matrix Music Hacker v2.1 - Initializing...');
50
 
51
- // Global variables
52
  let audioContext = null;
53
  let currentOscillators = [];
54
  let recognition = null;
55
  let isListening = false;
 
 
 
 
 
 
 
 
56
 
57
  // Initialize audio context
58
  function initAudio() {
@@ -328,7 +336,7 @@ def create_interface():
328
  currentOscillators = [];
329
  }
330
 
331
- // Enhanced speech recognition with better error handling
332
  function initSpeechRecognition() {
333
  if (isListening) {
334
  stopSpeechRecognition();
@@ -345,42 +353,48 @@ def create_interface():
345
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
346
  recognition = new SpeechRecognition();
347
 
348
- recognition.continuous = false;
349
- recognition.interimResults = false;
350
  recognition.lang = 'en-US';
351
  recognition.maxAlternatives = 1;
352
 
353
  recognition.onstart = function() {
354
  isListening = true;
355
  console.log('🎀 Speech recognition started');
356
- updateStatus('🎀 LISTENING... Speak your command!');
357
  };
358
 
359
  recognition.onresult = function(event) {
360
- const command = event.results[0][0].transcript.toLowerCase().trim();
361
- const confidence = event.results[0][0].confidence;
362
- console.log('Voice command received:', command, 'Confidence:', confidence);
363
-
364
- processVoiceCommand(command);
 
 
 
 
365
  };
366
 
367
  recognition.onerror = function(event) {
368
  console.error('Speech recognition error:', event.error);
369
- isListening = false;
370
 
371
  let errorMessage = '❌ VOICE ERROR: ';
372
  switch(event.error) {
373
  case 'no-speech':
374
- errorMessage += 'No speech detected. Try again.';
375
  break;
376
  case 'audio-capture':
377
  errorMessage += 'Microphone not accessible.';
 
378
  break;
379
  case 'not-allowed':
380
  errorMessage += 'Microphone permission denied.';
 
381
  break;
382
  case 'network':
383
  errorMessage += 'Network error occurred.';
 
384
  break;
385
  default:
386
  errorMessage += event.error;
@@ -389,12 +403,20 @@ def create_interface():
389
  };
390
 
391
  recognition.onend = function() {
392
- isListening = false;
393
  console.log('Speech recognition ended');
394
- if (document.querySelector('[data-testid="textbox"]')) {
 
395
  setTimeout(() => {
396
- updateStatus('πŸ”° MATRIX ONLINE - READY FOR VOICE INPUT');
397
- }, 2000);
 
 
 
 
 
 
 
 
398
  }
399
  };
400
 
@@ -419,245 +441,550 @@ def create_interface():
419
  function processVoiceCommand(command) {
420
  console.log('Processing command:', command);
421
 
422
- let soundType = '';
423
- let codePattern = '';
424
  let statusMessage = '';
 
425
 
426
- if (command.includes('deep house') || command.includes('house') || command.includes('deep')) {
427
- soundType = 'deep_house';
428
- codePattern = 'sound("bd").n("[0,2,4,6]").gain(0.8).room(0.3)';
429
- statusMessage = '🏠 DEEP HOUSE PATTERN ACTIVATED';
430
- } else if (command.includes('cyberpunk') || command.includes('synth') || command.includes('cyber')) {
431
- soundType = 'cyberpunk';
432
- codePattern = 'sound("lead").n("[0,2,7,12]").fast(2).lpf(1200)';
433
- statusMessage = '⚑ CYBERPUNK SYNTH WAVE ENGAGED';
434
- } else if (command.includes('bass') || command.includes('underground') || command.includes('sub')) {
435
- soundType = 'bass';
436
- codePattern = 'sound("bass").n("0,3,7").slow(2).lpf(200)';
437
- statusMessage = 'πŸ”Š UNDERGROUND BASS SEQUENCE ACTIVE';
438
- } else if (command.includes('ambient') || command.includes('atmosphere') || command.includes('pad')) {
439
- soundType = 'ambient';
440
- codePattern = 'sound("pad").n("0,4,7,11").slow(4).room(0.8).lpf(800)';
441
- statusMessage = '🌌 AMBIENT MATRIX SOUNDSCAPE ONLINE';
442
- } else if (command.includes('breakbeat') || command.includes('rave') || command.includes('break') || command.includes('beat')) {
443
- soundType = 'breakbeat';
444
- codePattern = 'sound("bd,sd").n("0,2,4,6").fast(1.5).gain(0.7)';
445
- statusMessage = 'πŸ’₯ BREAKBEAT RAVE SEQUENCE INITIATED';
446
- } else if (command.includes('stop') || command.includes('terminate') || command.includes('halt')) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
447
  stopAllSounds();
448
- updateStatus('⏹️ ALL MATRIX SOUNDS TERMINATED');
449
- updateCodeDisplay('// All oscillators terminated by voice command');
450
- return;
451
- } else {
452
- statusMessage = `❓ UNKNOWN COMMAND: "${command}" - Try: deep house, cyberpunk, bass, ambient, breakbeat`;
 
 
 
453
  updateStatus(statusMessage);
454
  return;
455
  }
456
 
457
- // Play the sound and update displays
458
- if (soundType) {
459
- playMatrixSound(soundType);
460
- updateStatus(statusMessage);
461
- updateCodeDisplay(codePattern);
462
  }
 
 
463
  }
464
 
465
- function updateStatus(message) {
466
- const statusElement = document.querySelector('[data-testid="textbox"] textarea');
467
- if (statusElement) {
468
- statusElement.value = message;
469
- statusElement.dispatchEvent(new Event('input', { bubbles: true }));
 
 
 
 
 
 
 
470
  }
 
 
471
  }
472
 
473
- function updateCodeDisplay(code) {
474
- // Find the code element and update it
475
- const codeElements = document.querySelectorAll('.gr-code pre code');
476
- codeElements.forEach(element => {
477
- if (element.textContent.includes('Voice commands will generate') ||
478
- element.textContent.includes('sound(') ||
479
- element.textContent.includes('//')) {
480
- element.textContent = code;
 
 
481
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
482
  });
483
  }
484
 
485
- // Store functions globally for Gradio to access
486
- window.playMatrixSound = playMatrixSound;
487
- window.stopAllSounds = stopAllSounds;
488
- window.initSpeechRecognition = initSpeechRecognition;
489
- window.stopSpeechRecognition = stopSpeechRecognition;
490
- window.updateStatus = updateStatus;
491
- window.updateCodeDisplay = updateCodeDisplay;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
492
 
493
- // Initialize matrix rain effect after a short delay
494
- setTimeout(createMatrixRain, 1000);
495
 
496
- return "🎡 Matrix Music Hacker v2.1 - FULLY OPERATIONAL";
497
  }
498
  """
499
 
500
- with gr.Blocks(
501
- title="Matrix Music Hacker v2.1",
502
- css=custom_css,
503
- js=matrix_js
504
- ) as interface:
505
-
506
- gr.Markdown("""
507
- # 🎡 Matrix Music Hacker v2.1
508
- ### *Cyberpunk Voice-Controlled Music Synthesizer*
509
-
510
- > "Wake up, Neo... The Matrix has you... But now you have the beats."
 
 
 
 
511
  """)
512
 
513
- with gr.Row():
514
- with gr.Column(scale=2):
515
- # Control buttons
516
- voice_btn = gr.Button("🎀 INITIATE VOICE HACK", variant="primary", size="lg")
517
-
518
- with gr.Row():
519
- deep_house_btn = gr.Button("🏠 Deep House", variant="secondary")
520
- cyberpunk_btn = gr.Button("⚑ Cyberpunk", variant="secondary")
521
- bass_btn = gr.Button("πŸ”Š Underground Bass", variant="secondary")
522
-
523
- with gr.Row():
524
- ambient_btn = gr.Button("🌌 Ambient", variant="secondary")
525
- breakbeat_btn = gr.Button("πŸ’₯ Breakbeat", variant="secondary")
526
- stop_btn = gr.Button("⏹️ TERMINATE", variant="stop")
527
-
528
- with gr.Column(scale=1):
529
- status_display = gr.Textbox(
530
- label="πŸ”° SYSTEM STATUS",
531
- value="πŸ”° MATRIX ONLINE - READY FOR VOICE INPUT",
532
- interactive=False,
533
- lines=3,
534
- elem_id="voice-status"
535
- )
536
-
537
- # Code display
538
- code_display = gr.Code(
539
- label="πŸ”§ GENERATED STRUDEL CODE",
540
- language="javascript",
541
- value="// Voice commands will generate Strudel patterns here...\n// Try: 'play deep house drums' or 'make cyberpunk synth'\n// Commands: deep house, cyberpunk, bass, ambient, breakbeat, stop",
542
- lines=6
543
  )
544
 
545
- gr.Markdown("""
546
- ### 🎯 Voice Commands to Try:
547
- - **"play deep house"** / **"deep house drums"** - Generate deep house patterns
548
- - **"create underground bass"** / **"bass"** - Synthesize bass lines
549
- - **"make cyberpunk synth"** / **"cyberpunk"** - Create cyberpunk leads
550
- - **"play ambient sounds"** / **"ambient"** - Generate ambient textures
551
- - **"start breakbeat"** / **"rave"** - Create breakbeat rhythms
552
- - **"stop"** / **"terminate"** - Stop all sounds
553
-
554
- ### ⚑ Features:
555
- - 🎀 **Enhanced Voice Recognition** - Better error handling & feedback
556
- - 🎡 **Improved Audio Synthesis** - Web Audio API with filters & effects
557
- - πŸ’» **Responsive Matrix Rain** - Adaptive background animation
558
- - πŸŽ›οΈ **Manual Controls** - Click buttons for instant sounds
559
- - πŸ”Š **Full Cyberpunk Experience** - Complete Matrix aesthetic
560
-
561
- ### πŸš€ Quick Start:
562
- 1. **Click "INITIATE VOICE HACK"** and allow microphone access when prompted
563
- 2. **Wait for "LISTENING..."** status message
564
- 3. **Speak clearly**: "play deep house" or "make cyberpunk synth"
565
- 4. **Watch the magic happen** - code generates and beats play!
566
- 5. **Use manual buttons** if voice isn't working in your environment
567
-
568
- ### πŸ”§ Troubleshooting:
569
- - **Chrome/Firefox work best** for voice recognition
570
- - **Allow microphone permissions** when prompted
571
- - **Speak clearly** and wait for the listening status
572
- - **Try manual buttons** if voice fails
573
- - **Check browser console** for detailed error messages
574
- """)
575
-
576
- # Event handlers with improved error handling
577
- def handle_voice():
578
- return "🎀 INITIALIZING VOICE HACK... Allow microphone access!"
579
 
580
- def handle_deep_house():
581
- return "🏠 DEEP HOUSE SEQUENCE ACTIVATED", "sound(\"bd\").n(\"[0,2,4,6]\").gain(0.8).room(0.3)"
 
 
 
 
 
 
582
 
583
- def handle_cyberpunk():
584
- return "⚑ CYBERPUNK SYNTH WAVE ENGAGED", "sound(\"lead\").n(\"[0,2,7,12]\").fast(2).lpf(1200)"
585
 
586
- def handle_bass():
587
- return "πŸ”Š UNDERGROUND BASS PUMPING", "sound(\"bass\").n(\"0,3,7\").slow(2).lpf(200)"
 
 
588
 
589
- def handle_ambient():
590
- return "🌌 AMBIENT MATRIX SOUNDSCAPE ONLINE", "sound(\"pad\").n(\"0,4,7,11\").slow(4).room(0.8).lpf(800)"
 
 
591
 
592
- def handle_breakbeat():
593
- return "πŸ’₯ BREAKBEAT RAVE SEQUENCE INITIATED", "sound(\"bd,sd\").n(\"0,2,4,6\").fast(1.5).gain(0.7)"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
594
 
595
- def handle_stop():
596
- return "⏹️ ALL MATRIX SOUNDS TERMINATED", "// All oscillators terminated - Matrix silence restored"
 
 
 
 
597
 
598
- # Connect buttons with enhanced JavaScript integration
599
- voice_btn.click(
600
- handle_voice,
601
- outputs=[status_display]
602
- ).then(
603
- lambda: None,
604
- js="() => { window.initSpeechRecognition && window.initSpeechRecognition(); }"
605
  )
606
 
607
  deep_house_btn.click(
608
- handle_deep_house,
609
- outputs=[status_display, code_display]
610
- ).then(
611
- lambda: None,
612
- js="() => { window.playMatrixSound && window.playMatrixSound('deep_house'); }"
613
  )
614
 
615
  cyberpunk_btn.click(
616
- handle_cyberpunk,
617
- outputs=[status_display, code_display]
618
- ).then(
619
- lambda: None,
620
- js="() => { window.playMatrixSound && window.playMatrixSound('cyberpunk'); }"
621
  )
622
 
623
  bass_btn.click(
624
- handle_bass,
625
- outputs=[status_display, code_display]
626
- ).then(
627
- lambda: None,
628
- js="() => { window.playMatrixSound && window.playMatrixSound('bass'); }"
629
  )
630
 
631
  ambient_btn.click(
632
- handle_ambient,
633
- outputs=[status_display, code_display]
634
- ).then(
635
- lambda: None,
636
- js="() => { window.playMatrixSound && window.playMatrixSound('ambient'); }"
637
  )
638
 
639
  breakbeat_btn.click(
640
- handle_breakbeat,
641
- outputs=[status_display, code_display]
642
- ).then(
643
- lambda: None,
644
- js="() => { window.playMatrixSound && window.playMatrixSound('breakbeat'); }"
645
  )
646
 
647
- stop_btn.click(
648
- handle_stop,
649
- outputs=[status_display, code_display]
650
- ).then(
651
- lambda: None,
652
- js="() => { window.stopAllSounds && window.stopAllSounds(); }"
653
  )
654
 
 
 
 
 
 
 
655
  return interface
656
 
 
657
  if __name__ == "__main__":
658
- interface = create_interface()
659
- interface.launch(
 
 
 
 
660
  server_name="0.0.0.0",
661
  server_port=7860,
662
- share=False
 
 
663
  )
 
2
  import random
3
  import time
4
 
5
+ # Matrix Music Hacker - Complete Voice Recognition Version
6
  def create_interface():
7
 
8
  # Matrix-themed CSS
 
48
  function() {
49
  console.log('🎡 Matrix Music Hacker v2.1 - Initializing...');
50
 
51
+ // Global variables for music code building
52
  let audioContext = null;
53
  let currentOscillators = [];
54
  let recognition = null;
55
  let isListening = false;
56
+ let currentMusicCode = []; // Array to store building music code
57
+ let musicParams = { // Current music parameters
58
+ tempo: 120,
59
+ volume: 0.7,
60
+ key: 'C',
61
+ scale: 'major',
62
+ effects: []
63
+ };
64
 
65
  // Initialize audio context
66
  function initAudio() {
 
336
  currentOscillators = [];
337
  }
338
 
339
+ // Enhanced continuous speech recognition
340
  function initSpeechRecognition() {
341
  if (isListening) {
342
  stopSpeechRecognition();
 
353
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
354
  recognition = new SpeechRecognition();
355
 
356
+ recognition.continuous = true; // Enable continuous listening
357
+ recognition.interimResults = true; // Show interim results
358
  recognition.lang = 'en-US';
359
  recognition.maxAlternatives = 1;
360
 
361
  recognition.onstart = function() {
362
  isListening = true;
363
  console.log('🎀 Speech recognition started');
364
+ updateStatus('🎀 CONTINUOUS LISTENING ACTIVE - Speak your commands!');
365
  };
366
 
367
  recognition.onresult = function(event) {
368
+ for (let i = event.resultIndex; i < event.results.length; i++) {
369
+ if (event.results[i].isFinal) {
370
+ const command = event.results[i][0].transcript.toLowerCase().trim();
371
+ const confidence = event.results[i][0].confidence;
372
+ console.log('Voice command received:', command, 'Confidence:', confidence);
373
+
374
+ processVoiceCommand(command);
375
+ }
376
+ }
377
  };
378
 
379
  recognition.onerror = function(event) {
380
  console.error('Speech recognition error:', event.error);
 
381
 
382
  let errorMessage = '❌ VOICE ERROR: ';
383
  switch(event.error) {
384
  case 'no-speech':
385
+ errorMessage += 'No speech detected. Still listening...';
386
  break;
387
  case 'audio-capture':
388
  errorMessage += 'Microphone not accessible.';
389
+ isListening = false;
390
  break;
391
  case 'not-allowed':
392
  errorMessage += 'Microphone permission denied.';
393
+ isListening = false;
394
  break;
395
  case 'network':
396
  errorMessage += 'Network error occurred.';
397
+ isListening = false;
398
  break;
399
  default:
400
  errorMessage += event.error;
 
403
  };
404
 
405
  recognition.onend = function() {
 
406
  console.log('Speech recognition ended');
407
+ if (isListening) {
408
+ // Restart recognition if we're still supposed to be listening
409
  setTimeout(() => {
410
+ if (isListening) {
411
+ try {
412
+ recognition.start();
413
+ } catch (e) {
414
+ console.error('Failed to restart recognition:', e);
415
+ isListening = false;
416
+ updateStatus('❌ VOICE RECOGNITION STOPPED - Click button to restart');
417
+ }
418
+ }
419
+ }, 1000);
420
  }
421
  };
422
 
 
441
  function processVoiceCommand(command) {
442
  console.log('Processing command:', command);
443
 
 
 
444
  let statusMessage = '';
445
+ let codeAdded = false;
446
 
447
+ // Parse different types of commands
448
+ if (command.includes('clear') || command.includes('reset') || command.includes('start over')) {
449
+ clearMusicCode();
450
+ statusMessage = 'πŸ—‘οΈ MUSIC CODE CLEARED - Starting fresh session';
451
+ }
452
+ else if (command.includes('tempo') || command.includes('speed') || command.includes('bpm')) {
453
+ handleTempoCommand(command);
454
+ codeAdded = true;
455
+ }
456
+ else if (command.includes('volume') || command.includes('loud') || command.includes('quiet') || command.includes('gain')) {
457
+ handleVolumeCommand(command);
458
+ codeAdded = true;
459
+ }
460
+ else if (command.includes('reverb') || command.includes('room') || command.includes('echo')) {
461
+ handleReverbCommand(command);
462
+ codeAdded = true;
463
+ }
464
+ else if (command.includes('filter') || command.includes('low pass') || command.includes('high pass') || command.includes('lpf') || command.includes('hpf')) {
465
+ handleFilterCommand(command);
466
+ codeAdded = true;
467
+ }
468
+ else if (command.includes('delay')) {
469
+ handleDelayCommand(command);
470
+ codeAdded = true;
471
+ }
472
+ else if (command.includes('add') || command.includes('layer') || command.includes('include')) {
473
+ handleAddCommand(command);
474
+ codeAdded = true;
475
+ }
476
+ else if (command.includes('remove') || command.includes('delete') || command.includes('drop')) {
477
+ handleRemoveCommand(command);
478
+ codeAdded = true;
479
+ }
480
+ else if (command.includes('change key') || command.includes('transpose')) {
481
+ handleKeyCommand(command);
482
+ codeAdded = true;
483
+ }
484
+ // Base sound commands
485
+ else if (command.includes('deep house') || command.includes('house') || command.includes('deep')) {
486
+ addMusicCode('deep_house', 'sound("bd").n("[0,2,4,6]").gain(' + musicParams.volume + ')');
487
+ playMatrixSound('deep_house');
488
+ statusMessage = '🏠 DEEP HOUSE PATTERN ADDED TO SESSION';
489
+ codeAdded = true;
490
+ }
491
+ else if (command.includes('cyberpunk') || command.includes('synth') || command.includes('cyber')) {
492
+ addMusicCode('cyberpunk', 'sound("lead").n("[0,2,7,12]").fast(2)');
493
+ playMatrixSound('cyberpunk');
494
+ statusMessage = '⚑ CYBERPUNK SYNTH LAYER ADDED';
495
+ codeAdded = true;
496
+ }
497
+ else if (command.includes('bass') || command.includes('underground') || command.includes('sub')) {
498
+ addMusicCode('bass', 'sound("bass").n("0,3,7").slow(2)');
499
+ playMatrixSound('bass');
500
+ statusMessage = 'πŸ”Š BASS LINE INTEGRATED INTO SESSION';
501
+ codeAdded = true;
502
+ }
503
+ else if (command.includes('ambient') || command.includes('atmosphere') || command.includes('pad')) {
504
+ addMusicCode('ambient', 'sound("pad").n("0,4,7,11").slow(4)');
505
+ playMatrixSound('ambient');
506
+ statusMessage = '🌌 AMBIENT LAYER WOVEN INTO MATRIX';
507
+ codeAdded = true;
508
+ }
509
+ else if (command.includes('breakbeat') || command.includes('rave') || command.includes('break') || command.includes('beat')) {
510
+ addMusicCode('breakbeat', 'sound("bd,sd").n("0,2,4,6").fast(1.5)');
511
+ playMatrixSound('breakbeat');
512
+ statusMessage = 'πŸ’₯ BREAKBEAT RHYTHM LOCKED INTO GRID';
513
+ codeAdded = true;
514
+ }
515
+ else if (command.includes('drums') || command.includes('kick') || command.includes('snare')) {
516
+ addMusicCode('drums', 'sound("bd,sd,hh").n("0,[2,6],4")');
517
+ playMatrixSound('breakbeat');
518
+ statusMessage = 'πŸ₯ DRUM PATTERN SYNCHRONIZED';
519
+ codeAdded = true;
520
+ }
521
+ else if (command.includes('stop') || command.includes('terminate') || command.includes('halt')) {
522
  stopAllSounds();
523
+ statusMessage = '⏹️ ALL MATRIX SOUNDS TERMINATED - Code preserved';
524
+ }
525
+ else if (command.includes('play') || command.includes('start') || command.includes('begin')) {
526
+ playCurrentCode();
527
+ statusMessage = '▢️ PLAYING CURRENT MUSIC CODE SESSION';
528
+ }
529
+ else {
530
+ statusMessage = `❓ UNKNOWN COMMAND: "${command}"`;
531
  updateStatus(statusMessage);
532
  return;
533
  }
534
 
535
+ // Update displays if code was modified
536
+ if (codeAdded || statusMessage.includes('CLEARED')) {
537
+ updateCodeDisplay(buildFullMusicCode());
 
 
538
  }
539
+
540
+ updateStatus(statusMessage);
541
  }
542
 
543
+ function handleTempoCommand(command) {
544
+ let tempo = musicParams.tempo;
545
+ if (command.includes('faster') || command.includes('speed up') || command.includes('quick')) {
546
+ tempo = Math.min(200, musicParams.tempo + 20);
547
+ } else if (command.includes('slower') || command.includes('slow down')) {
548
+ tempo = Math.max(60, musicParams.tempo - 20);
549
+ } else {
550
+ // Try to extract specific BPM
551
+ const bpmMatch = command.match(/(\d+)/);
552
+ if (bpmMatch) {
553
+ tempo = Math.max(60, Math.min(200, parseInt(bpmMatch[1])));
554
+ }
555
  }
556
+ musicParams.tempo = tempo;
557
+ updateStatus(`🎡 TEMPO SET TO ${tempo} BPM`);
558
  }
559
 
560
+ function handleVolumeCommand(command) {
561
+ let volume = musicParams.volume;
562
+ if (command.includes('louder') || command.includes('up')) {
563
+ volume = Math.min(1.0, musicParams.volume + 0.2);
564
+ } else if (command.includes('quieter') || command.includes('down') || command.includes('soft')) {
565
+ volume = Math.max(0.1, musicParams.volume - 0.2);
566
+ } else {
567
+ const volumeMatch = command.match(/(\d+)/);
568
+ if (volumeMatch) {
569
+ volume = Math.max(0.1, Math.min(1.0, parseInt(volumeMatch[1]) / 100));
570
  }
571
+ }
572
+ musicParams.volume = volume;
573
+ updateStatus(`πŸ”Š VOLUME ADJUSTED TO ${Math.round(volume * 100)}%`);
574
+ }
575
+
576
+ function handleReverbCommand(command) {
577
+ const reverbAmount = command.includes('more') || command.includes('heavy') ? '0.8' : '0.4';
578
+ const effect = `.room(${reverbAmount})`;
579
+ if (!musicParams.effects.includes('room')) {
580
+ musicParams.effects.push('room');
581
+ addEffectToLastCode(effect);
582
+ updateStatus(`🌊 REVERB EFFECT APPLIED (${reverbAmount})`);
583
+ }
584
+ }
585
+
586
+ function handleFilterCommand(command) {
587
+ let filterCode = '';
588
+ if (command.includes('low pass') || command.includes('lpf') || command.includes('warm')) {
589
+ filterCode = '.lpf(800)';
590
+ updateStatus('πŸŽ›οΈ LOW-PASS FILTER ENGAGED');
591
+ } else if (command.includes('high pass') || command.includes('hpf') || command.includes('bright')) {
592
+ filterCode = '.hpf(200)';
593
+ updateStatus('πŸŽ›οΈ HIGH-PASS FILTER ACTIVATED');
594
+ }
595
+ if (filterCode) {
596
+ addEffectToLastCode(filterCode);
597
+ }
598
+ }
599
+
600
+ function handleDelayCommand(command) {
601
+ const delayAmount = command.includes('long') || command.includes('heavy') ? '0.25' : '0.125';
602
+ const effect = `.delay(${delayAmount})`;
603
+ if (!musicParams.effects.includes('delay')) {
604
+ musicParams.effects.push('delay');
605
+ addEffectToLastCode(effect);
606
+ updateStatus(`⏰ DELAY EFFECT SYNCHRONIZED (${delayAmount})`);
607
+ }
608
+ }
609
+
610
+ function handleAddCommand(command) {
611
+ if (command.includes('hihat') || command.includes('hi hat')) {
612
+ addMusicCode('hihat', 'sound("hh").n("0,2,4,6,8,10,12,14").gain(0.3)');
613
+ updateStatus('🎩 HI-HAT PATTERN ADDED');
614
+ } else if (command.includes('clap')) {
615
+ addMusicCode('clap', 'sound("cp").n("[~,2,~,6]").gain(0.5)');
616
+ updateStatus('πŸ‘ CLAP TRACK INTEGRATED');
617
+ } else if (command.includes('open hat')) {
618
+ addMusicCode('openhat', 'sound("oh").n("[~,~,4,~]").gain(0.4)');
619
+ updateStatus('🎩 OPEN HAT ACCENT ADDED');
620
+ } else if (command.includes('arpeggios') || command.includes('arp')) {
621
+ addMusicCode('arp', 'sound("arpy").n("0,2,4,7,9").fast(4).gain(0.6)');
622
+ updateStatus('🎹 ARPEGGIOS CASCADING');
623
+ } else if (command.includes('strings')) {
624
+ addMusicCode('strings', 'sound("string").n("0,4,7").slow(8).room(0.6)');
625
+ updateStatus('🎻 STRING SECTION HARMONIZING');
626
+ }
627
+ }
628
+
629
+ function handleRemoveCommand(command) {
630
+ if (command.includes('bass')) {
631
+ removeMusicCode('bass');
632
+ updateStatus('πŸ”‡ BASS LAYER REMOVED');
633
+ } else if (command.includes('drums')) {
634
+ removeMusicCode('drums');
635
+ removeMusicCode('breakbeat');
636
+ updateStatus('πŸ₯ DRUM LAYERS REMOVED');
637
+ } else if (command.includes('synth') || command.includes('lead')) {
638
+ removeMusicCode('cyberpunk');
639
+ updateStatus('⚑ SYNTH LAYER REMOVED');
640
+ } else if (command.includes('ambient') || command.includes('pad')) {
641
+ removeMusicCode('ambient');
642
+ updateStatus('🌌 AMBIENT LAYER REMOVED');
643
+ } else if (command.includes('last')) {
644
+ removeLastMusicCode();
645
+ updateStatus('πŸ—‘οΈ LAST ADDITION REMOVED');
646
+ }
647
+ }
648
+
649
+ function handleKeyCommand(command) {
650
+ const keys = ['C', 'D', 'E', 'F', 'G', 'A', 'B'];
651
+ for (const key of keys) {
652
+ if (command.includes(key.toLowerCase()) || command.includes(`key of ${key.toLowerCase()}`)) {
653
+ musicParams.key = key;
654
+ updateStatus(`🎹 KEY CHANGED TO ${key} MAJOR`);
655
+ break;
656
+ }
657
+ }
658
+ }
659
+
660
+ function addMusicCode(type, code) {
661
+ // Remove existing code of the same type
662
+ currentMusicCode = currentMusicCode.filter(item => item.type !== type);
663
+ // Add new code
664
+ currentMusicCode.push({ type, code, timestamp: Date.now() });
665
+ }
666
+
667
+ function removeMusicCode(type) {
668
+ currentMusicCode = currentMusicCode.filter(item => item.type !== type);
669
+ }
670
+
671
+ function removeLastMusicCode() {
672
+ if (currentMusicCode.length > 0) {
673
+ currentMusicCode.pop();
674
+ }
675
+ }
676
+
677
+ function addEffectToLastCode(effect) {
678
+ if (currentMusicCode.length > 0) {
679
+ const lastIndex = currentMusicCode.length - 1;
680
+ if (!currentMusicCode[lastIndex].code.includes(effect.split('(')[0])) {
681
+ currentMusicCode[lastIndex].code += effect;
682
+ }
683
+ }
684
+ }
685
+
686
+ function clearMusicCode() {
687
+ currentMusicCode = [];
688
+ musicParams = {
689
+ tempo: 120,
690
+ volume: 0.7,
691
+ key: 'C',
692
+ scale: 'major',
693
+ effects: []
694
+ };
695
+ }
696
+
697
+ function buildFullMusicCode() {
698
+ if (currentMusicCode.length === 0) {
699
+ return '// Voice commands will build your music code here...\n// Try: "play deep house", then "add bass", then "make it faster"';
700
+ }
701
+
702
+ let fullCode = `// 🎡 Matrix Music Session - ${currentMusicCode.length} layers active\n`;
703
+ fullCode += `// Tempo: ${musicParams.tempo} BPM | Volume: ${Math.round(musicParams.volume * 100)}% | Key: ${musicParams.key}\n\n`;
704
+
705
+ if (currentMusicCode.length === 1) {
706
+ fullCode += currentMusicCode[0].code;
707
+ } else {
708
+ fullCode += 'stack(\n';
709
+ currentMusicCode.forEach((item, index) => {
710
+ const indent = ' ';
711
+ fullCode += `${indent}${item.code}`;
712
+ if (index < currentMusicCode.length - 1) {
713
+ fullCode += ',';
714
+ }
715
+ fullCode += ` // ${item.type}\n`;
716
+ });
717
+ fullCode += ')';
718
+ }
719
+
720
+ // Add global effects
721
+ if (musicParams.tempo !== 120) {
722
+ fullCode += `.cpm(${musicParams.tempo})`;
723
+ }
724
+ if (musicParams.volume !== 0
725
+ // Add global effects
726
+ if (musicParams.tempo !== 120) {
727
+ fullCode += `.cpm(${musicParams.tempo})`;
728
+ }
729
+ if (musicParams.volume !== 0.7) {
730
+ fullCode += `.gain(${musicParams.volume})`;
731
+ }
732
+
733
+ return fullCode;
734
+ }
735
+
736
+ function playCurrentCode() {
737
+ // Play all current sounds in sequence
738
+ currentMusicCode.forEach((item, index) => {
739
+ setTimeout(() => {
740
+ if (item.type === 'deep_house') playMatrixSound('deep_house');
741
+ else if (item.type === 'cyberpunk') playMatrixSound('cyberpunk');
742
+ else if (item.type === 'bass') playMatrixSound('bass');
743
+ else if (item.type === 'ambient') playMatrixSound('ambient');
744
+ else if (item.type === 'breakbeat' || item.type === 'drums') playMatrixSound('breakbeat');
745
+ }, index * 200);
746
  });
747
  }
748
 
749
+ function updateCodeDisplay(code) {
750
+ const codeElement = document.querySelector('#music-code textarea');
751
+ if (codeElement) {
752
+ codeElement.value = code;
753
+ // Trigger change event to update Gradio
754
+ codeElement.dispatchEvent(new Event('input', { bubbles: true }));
755
+ }
756
+ }
757
+
758
+ function updateStatus(message) {
759
+ const statusElement = document.querySelector('#voice-status');
760
+ if (statusElement) {
761
+ statusElement.textContent = message;
762
+ console.log('Status:', message);
763
+ }
764
+ }
765
+
766
+ // Initialize everything
767
+ createMatrixRain();
768
+
769
+ // Global functions for button callbacks
770
+ window.startVoiceRecognition = function() {
771
+ const success = initSpeechRecognition();
772
+ return success ? "🎀 Voice Recognition Active" : "❌ Voice Recognition Failed";
773
+ };
774
+
775
+ window.stopVoiceRecognition = function() {
776
+ stopSpeechRecognition();
777
+ return "⏹️ Voice Recognition Stopped";
778
+ };
779
+
780
+ window.playDeepHouse = function() {
781
+ playMatrixSound('deep_house');
782
+ return "🏠 Deep House Activated";
783
+ };
784
+
785
+ window.playCyberpunk = function() {
786
+ playMatrixSound('cyberpunk');
787
+ return "⚑ Cyberpunk Synth Engaged";
788
+ };
789
+
790
+ window.playBass = function() {
791
+ playMatrixSound('bass');
792
+ return "πŸ”Š Bass Line Active";
793
+ };
794
+
795
+ window.playAmbient = function() {
796
+ playMatrixSound('ambient');
797
+ return "🌌 Ambient Atmosphere";
798
+ };
799
+
800
+ window.playBreakbeat = function() {
801
+ playMatrixSound('breakbeat');
802
+ return "πŸ’₯ Breakbeat Rhythm";
803
+ };
804
+
805
+ window.stopAll = function() {
806
+ stopAllSounds();
807
+ return "⏹️ All Sounds Stopped";
808
+ };
809
+
810
+ window.clearCode = function() {
811
+ clearMusicCode();
812
+ updateCodeDisplay(buildFullMusicCode());
813
+ return "πŸ—‘οΈ Music Code Cleared";
814
+ };
815
 
816
+ console.log('🎡 Matrix Music Hacker v2.1 - Ready for voice commands!');
817
+ console.log('Voice commands: "play deep house", "add bass", "make it faster", "add reverb", etc.');
818
 
819
+ return "🎡 Matrix Music Hacker v2.1 - Initialization Complete";
820
  }
821
  """
822
 
823
+ # Create the Gradio interface
824
+ with gr.Blocks(css=custom_css, js=matrix_js, title="🎡 Matrix Music Hacker v2.1") as interface:
825
+
826
+ gr.HTML("""
827
+ <div style="text-align: center; padding: 20px;">
828
+ <h1 style="color: #00ff00; text-shadow: 0 0 20px #00ff00; font-size: 2.5em; margin-bottom: 10px;">
829
+ 🎡 MATRIX MUSIC HACKER v2.1
830
+ </h1>
831
+ <p style="color: #00ff00; font-size: 1.2em; text-shadow: 0 0 10px #00ff00;">
832
+ Voice-Controlled Music Generation System
833
+ </p>
834
+ <p style="color: #66ff66; font-size: 1em;">
835
+ Speak your commands: "play deep house", "add bass", "make it faster", "add reverb"
836
+ </p>
837
+ </div>
838
  """)
839
 
840
+ # Voice Status Display
841
+ voice_status = gr.Textbox(
842
+ value="🎀 Click 'Start Voice Recognition' to begin",
843
+ label="πŸŽ™οΈ VOICE STATUS",
844
+ elem_id="voice-status",
845
+ interactive=False,
846
+ max_lines=2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
847
  )
848
 
849
+ # Voice Control Buttons
850
+ with gr.Row():
851
+ start_voice_btn = gr.Button("🎀 START VOICE RECOGNITION", variant="primary")
852
+ stop_voice_btn = gr.Button("⏹️ STOP VOICE RECOGNITION", variant="secondary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
853
 
854
+ # Music Code Display
855
+ music_code = gr.Code(
856
+ value="// Voice commands will build your music code here...\n// Try: \"play deep house\", then \"add bass\", then \"make it faster\"",
857
+ label="🎼 GENERATED MUSIC CODE",
858
+ language="javascript",
859
+ elem_id="music-code",
860
+ lines=15
861
+ )
862
 
863
+ # Manual Sound Triggers
864
+ gr.HTML("<h3 style='color: #00ff00; text-align: center; margin-top: 30px;'>πŸŽ›οΈ MANUAL SOUND TRIGGERS</h3>")
865
 
866
+ with gr.Row():
867
+ deep_house_btn = gr.Button("🏠 Deep House", variant="primary")
868
+ cyberpunk_btn = gr.Button("⚑ Cyberpunk", variant="primary")
869
+ bass_btn = gr.Button("πŸ”Š Bass", variant="primary")
870
 
871
+ with gr.Row():
872
+ ambient_btn = gr.Button("🌌 Ambient", variant="primary")
873
+ breakbeat_btn = gr.Button("πŸ’₯ Breakbeat", variant="primary")
874
+ stop_all_btn = gr.Button("⏹️ Stop All", variant="secondary")
875
 
876
+ # Utility Buttons
877
+ with gr.Row():
878
+ clear_btn = gr.Button("πŸ—‘οΈ Clear Code", variant="secondary")
879
+
880
+ # Voice Commands Help
881
+ gr.HTML("""
882
+ <div style="margin-top: 30px; padding: 20px; border: 1px solid #00ff00; border-radius: 10px;">
883
+ <h3 style="color: #00ff00; text-align: center;">πŸŽ™οΈ VOICE COMMAND REFERENCE</h3>
884
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 15px;">
885
+ <div>
886
+ <h4 style="color: #66ff66;">🎡 Sound Commands:</h4>
887
+ <ul style="color: #ccffcc;">
888
+ <li>"play deep house" - Add house pattern</li>
889
+ <li>"add bass" / "play bass" - Add bass line</li>
890
+ <li>"play cyberpunk" - Add synth lead</li>
891
+ <li>"add ambient" - Add atmospheric pad</li>
892
+ <li>"play breakbeat" - Add drum pattern</li>
893
+ <li>"add drums" - Add percussion</li>
894
+ </ul>
895
+ </div>
896
+ <div>
897
+ <h4 style="color: #66ff66;">πŸŽ›οΈ Control Commands:</h4>
898
+ <ul style="color: #ccffcc;">
899
+ <li>"make it faster" / "slow it down"</li>
900
+ <li>"louder" / "quieter" / "volume 80"</li>
901
+ <li>"add reverb" / "add delay"</li>
902
+ <li>"low pass filter" / "high pass filter"</li>
903
+ <li>"stop" - Stop all sounds</li>
904
+ <li>"clear" / "reset" - Clear session</li>
905
+ </ul>
906
+ </div>
907
+ </div>
908
+ <div style="margin-top: 15px;">
909
+ <h4 style="color: #66ff66;">🎹 Advanced Commands:</h4>
910
+ <ul style="color: #ccffcc;">
911
+ <li>"add hihat" / "add clap" / "add strings"</li>
912
+ <li>"remove bass" / "remove drums"</li>
913
+ <li>"change key to G" / "transpose to F"</li>
914
+ <li>"tempo 140" - Set specific BPM</li>
915
+ </ul>
916
+ </div>
917
+ </div>
918
+ """)
919
 
920
+ # Button Event Handlers
921
+ start_voice_btn.click(
922
+ fn=None,
923
+ js="() => window.startVoiceRecognition()",
924
+ outputs=voice_status
925
+ )
926
 
927
+ stop_voice_btn.click(
928
+ fn=None,
929
+ js="() => window.stopVoiceRecognition()",
930
+ outputs=voice_status
 
 
 
931
  )
932
 
933
  deep_house_btn.click(
934
+ fn=None,
935
+ js="() => window.playDeepHouse()",
936
+ outputs=voice_status
 
 
937
  )
938
 
939
  cyberpunk_btn.click(
940
+ fn=None,
941
+ js="() => window.playCyberpunk()",
942
+ outputs=voice_status
 
 
943
  )
944
 
945
  bass_btn.click(
946
+ fn=None,
947
+ js="() => window.playBass()",
948
+ outputs=voice_status
 
 
949
  )
950
 
951
  ambient_btn.click(
952
+ fn=None,
953
+ js="() => window.playAmbient()",
954
+ outputs=voice_status
 
 
955
  )
956
 
957
  breakbeat_btn.click(
958
+ fn=None,
959
+ js="() => window.playBreakbeat()",
960
+ outputs=voice_status
 
 
961
  )
962
 
963
+ stop_all_btn.click(
964
+ fn=None,
965
+ js="() => window.stopAll()",
966
+ outputs=voice_status
 
 
967
  )
968
 
969
+ clear_btn.click(
970
+ fn=None,
971
+ js="() => window.clearCode()",
972
+ outputs=[voice_status, music_code]
973
+ )
974
+
975
  return interface
976
 
977
+ # Launch the application
978
  if __name__ == "__main__":
979
+ demo = create_interface()
980
+ print("🎡 Starting Matrix Music Hacker v2.1...")
981
+ print("🎀 Voice commands ready!")
982
+ print("🌐 Opening in browser...")
983
+
984
+ demo.launch(
985
  server_name="0.0.0.0",
986
  server_port=7860,
987
+ share=True, # Creates public link
988
+ debug=True,
989
+ show_error=True
990
  )