Spaces:
Running
Running
Make the keyboard usable: when I click the notes, it'd make correct pitch - Initial Deployment
fbba045
verified
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Vintage Analog Synth</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <script> | |
| tailwind.config = { | |
| theme: { | |
| extend: { | |
| colors: { | |
| synth: { | |
| dark: '#1a1a2e', | |
| panel: '#2d2d44', | |
| knob: '#4a4a6a', | |
| highlight: '#ff6b6b', | |
| wood: '#8b4513', | |
| metal: '#a9a9a9', | |
| label: '#d1d1e9' | |
| } | |
| }, | |
| fontFamily: { | |
| 'orbitron': ['Orbitron', 'sans-serif'], | |
| 'audiowide': ['Audiowide', 'cursive'] | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700&family=Audiowide&display=swap" rel="stylesheet"> | |
| <style> | |
| @keyframes glow { | |
| 0% { box-shadow: 0 0 5px #ff6b6b; } | |
| 50% { box-shadow: 0 0 20px #ff6b6b; } | |
| 100% { box-shadow: 0 0 5px #ff6b6b; } | |
| } | |
| .knob { | |
| position: relative; | |
| width: 60px; | |
| height: 60px; | |
| border-radius: 50%; | |
| background: linear-gradient(135deg, #4a4a6a 0%, #2d2d44 100%); | |
| box-shadow: | |
| inset 0 0 10px rgba(0, 0, 0, 0.5), | |
| 0 5px 15px rgba(0, 0, 0, 0.5); | |
| cursor: pointer; | |
| transition: transform 0.1s; | |
| } | |
| .knob::before { | |
| content: ''; | |
| position: absolute; | |
| top: 5px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| width: 6px; | |
| height: 20px; | |
| background: #ff6b6b; | |
| border-radius: 3px; | |
| } | |
| .knob-label { | |
| position: absolute; | |
| bottom: -25px; | |
| left: 0; | |
| width: 100%; | |
| text-align: center; | |
| font-size: 0.75rem; | |
| color: #d1d1e9; | |
| } | |
| .wood-panel { | |
| background: linear-gradient( | |
| to bottom, | |
| #8b4513 0%, | |
| #5d2e0a 20%, | |
| #8b4513 40%, | |
| #5d2e0a 60%, | |
| #8b4513 80%, | |
| #5d2e0a 100% | |
| ); | |
| border: 2px solid #5d2e0a; | |
| box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5); | |
| } | |
| .metal-frame { | |
| background: linear-gradient(135deg, #c0c0c0 0%, #a9a9a9 100%); | |
| border: 1px solid #888; | |
| box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3); | |
| } | |
| .key-white { | |
| width: 40px; | |
| height: 180px; | |
| background: linear-gradient(to bottom, #fff 0%, #f0f0f0 100%); | |
| border: 1px solid #ccc; | |
| border-radius: 0 0 5px 5px; | |
| box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2); | |
| position: relative; | |
| z-index: 1; | |
| } | |
| .key-black { | |
| width: 28px; | |
| height: 120px; | |
| background: linear-gradient(to bottom, #000 0%, #333 100%); | |
| border: 1px solid #000; | |
| border-radius: 0 0 4px 4px; | |
| position: absolute; | |
| z-index: 2; | |
| margin-left: -14px; | |
| } | |
| .key-white.active { | |
| background: linear-gradient(to bottom, #ffd700 0%, #ffb700 100%); | |
| box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.3); | |
| } | |
| .key-black.active { | |
| background: linear-gradient(to bottom, #ff8c00 0%, #ff6b00 100%); | |
| box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5); | |
| } | |
| .led { | |
| width: 12px; | |
| height: 12px; | |
| border-radius: 50%; | |
| background: #444; | |
| box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5); | |
| } | |
| .led.active { | |
| background: #ff6b6b; | |
| box-shadow: 0 0 10px #ff6b6b; | |
| animation: glow 1.5s infinite; | |
| } | |
| .vintage-label { | |
| font-family: 'Audiowide', cursive; | |
| color: #d1d1e9; | |
| text-shadow: 0 0 5px rgba(255, 107, 107, 0.5); | |
| letter-spacing: 1px; | |
| } | |
| .panel-label { | |
| font-family: 'Audiowide', cursive; | |
| color: #ff6b6b; | |
| text-transform: uppercase; | |
| letter-spacing: 1px; | |
| font-size: 0.9rem; | |
| } | |
| .synth-container { | |
| perspective: 1000px; | |
| } | |
| .synth-body { | |
| transform: rotateX(5deg); | |
| transform-style: preserve-3d; | |
| } | |
| .knob-container { | |
| transform-style: preserve-3d; | |
| } | |
| .knob-shadow { | |
| position: absolute; | |
| bottom: -5px; | |
| left: 5px; | |
| width: 50px; | |
| height: 10px; | |
| background: rgba(0, 0, 0, 0.3); | |
| border-radius: 50%; | |
| filter: blur(5px); | |
| z-index: -1; | |
| } | |
| .lcd-display { | |
| background: linear-gradient(135deg, #0a3f0a 0%, #082908 100%); | |
| border: 2px solid #0f5c0f; | |
| color: #7fff7f; | |
| font-family: 'Audiowide', cursive; | |
| text-shadow: 0 0 5px #7fff7f; | |
| box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5); | |
| } | |
| .lcd-text { | |
| animation: flicker 0.1s infinite alternate; | |
| } | |
| @keyframes flicker { | |
| 0% { opacity: 0.9; } | |
| 100% { opacity: 1; } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-synth-dark min-h-screen flex flex-col items-center justify-center p-4 font-orbitron"> | |
| <div class="synth-container w-full max-w-4xl"> | |
| <div class="synth-body bg-synth-panel rounded-xl p-6 shadow-2xl"> | |
| <!-- Header --> | |
| <div class="text-center mb-6"> | |
| <h1 class="vintage-label text-3xl md:text-4xl mb-2">ANALOG SYNTHESIZER</h1> | |
| <div class="lcd-display rounded-lg p-3 mx-auto max-w-md"> | |
| <div class="lcd-text text-center text-lg">MODEL: V-1978</div> | |
| </div> | |
| </div> | |
| <!-- Main Controls --> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6"> | |
| <!-- Oscillator Section --> | |
| <div class="bg-synth-dark rounded-lg p-4 wood-panel"> | |
| <div class="panel-label text-center mb-3">OSCILLATOR</div> | |
| <div class="grid grid-cols-3 gap-4"> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="osc1-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">WAVE</div> | |
| </div> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="osc2-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">OCTAVE</div> | |
| </div> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="detune-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">DETUNE</div> | |
| </div> | |
| </div> | |
| <div class="flex justify-around mt-4"> | |
| <div class="flex flex-col items-center"> | |
| <div class="led" id="sine-led"></div> | |
| <span class="text-xs mt-1 text-synth-label">SINE</span> | |
| </div> | |
| <div class="flex flex-col items-center"> | |
| <div class="led active" id="saw-led"></div> | |
| <span class="text-xs mt-1 text-synth-label">SAW</span> | |
| </div> | |
| <div class="flex flex-col items-center"> | |
| <div class="led" id="square-led"></div> | |
| <span class="text-xs mt-1 text-synth-label">SQUARE</span> | |
| </div> | |
| <div class="flex flex-col items-center"> | |
| <div class="led" id="triangle-led"></div> | |
| <span class="text-xs mt-1 text-synth-label">TRI</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Filter Section --> | |
| <div class="bg-synth-dark rounded-lg p-4 wood-panel"> | |
| <div class="panel-label text-center mb-3">FILTER</div> | |
| <div class="grid grid-cols-3 gap-4"> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="cutoff-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">CUTOFF</div> | |
| </div> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="resonance-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">RESONANCE</div> | |
| </div> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="env-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">ENV AMT</div> | |
| </div> | |
| </div> | |
| <div class="flex justify-around mt-4"> | |
| <div class="flex flex-col items-center"> | |
| <div class="led active" id="lowpass-led"></div> | |
| <span class="text-xs mt-1 text-synth-label">LOW</span> | |
| </div> | |
| <div class="flex flex-col items-center"> | |
| <div class="led" id="highpass-led"></div> | |
| <span class="text-xs mt-1 text-synth-label">HIGH</span> | |
| </div> | |
| <div class="flex flex-col items-center"> | |
| <div class="led" id="bandpass-led"></div> | |
| <span class="text-xs mt-1 text-synth-label">BAND</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Envelope Section --> | |
| <div class="bg-synth-dark rounded-lg p-4 wood-panel"> | |
| <div class="panel-label text-center mb-3">ENVELOPE</div> | |
| <div class="grid grid-cols-4 gap-3"> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="attack-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">ATTACK</div> | |
| </div> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="decay-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">DECAY</div> | |
| </div> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="sustain-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">SUSTAIN</div> | |
| </div> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="release-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">RELEASE</div> | |
| </div> | |
| </div> | |
| <div class="mt-4 flex justify-center"> | |
| <div class="bg-synth-panel rounded p-2 w-full"> | |
| <div class="h-2 bg-gray-800 rounded-full overflow-hidden"> | |
| <div class="h-full bg-synth-highlight rounded-full w-3/4"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Modulation and Effects --> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6"> | |
| <div class="bg-synth-dark rounded-lg p-4 wood-panel"> | |
| <div class="panel-label text-center mb-3">MODULATION</div> | |
| <div class="grid grid-cols-3 gap-4"> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="lfo-rate-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">RATE</div> | |
| </div> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="lfo-amount-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">AMOUNT</div> | |
| </div> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="lfo-target-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">TARGET</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-synth-dark rounded-lg p-4 wood-panel"> | |
| <div class="panel-label text-center mb-3">EFFECTS</div> | |
| <div class="grid grid-cols-3 gap-4"> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="delay-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">DELAY</div> | |
| </div> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="reverb-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">REVERB</div> | |
| </div> | |
| <div class="knob-container flex flex-col items-center"> | |
| <div class="knob relative" id="distortion-knob"> | |
| <div class="knob-shadow"></div> | |
| </div> | |
| <div class="knob-label">DRIVE</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Keyboard --> | |
| <div class="bg-synth-dark rounded-lg p-4 wood-panel mb-6"> | |
| <div class="panel-label text-center mb-3">KEYBOARD</div> | |
| <div class="relative h-48 flex justify-center"> | |
| <!-- White Keys --> | |
| <div class="flex relative"> | |
| <div class="key-white" data-note="C" data-frequency="261.63"></div> | |
| <div class="key-white" data-note="D" data-frequency="293.66"></div> | |
| <div class="key-white" data-note="E" data-frequency="329.63"></div> | |
| <div class="key-white" data-note="F" data-frequency="349.23"></div> | |
| <div class="key-white" data-note="G" data-frequency="392.00"></div> | |
| <div class="key-white" data-note="A" data-frequency="440.00"></div> | |
| <div class="key-white" data-note="B" data-frequency="493.88"></div> | |
| <div class="key-white" data-note="C2" data-frequency="523.25"></div> | |
| <!-- Black Keys --> | |
| <div class="key-black" style="left: 30px;" data-note="C#" data-frequency="277.18"></div> | |
| <div class="key-black" style="left: 70px;" data-note="D#" data-frequency="311.13"></div> | |
| <div class="key-black" style="left: 150px;" data-note="F#" data-frequency="369.99"></div> | |
| <div class="key-black" style="left: 190px;" data-note="G#" data-frequency="415.30"></div> | |
| <div class="key-black" style="left: 230px;" data-note="A#" data-frequency="466.16"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Footer --> | |
| <div class="flex justify-between items-center"> | |
| <div class="flex items-center"> | |
| <div class="led active mr-2"></div> | |
| <span class="text-sm text-synth-label">POWER ON</span> | |
| </div> | |
| <div class="text-sm text-synth-label"> | |
| <i class="fas fa-copyright mr-1"></i> 1978 ANALOG SYSTEMS | |
| </div> | |
| <div class="flex"> | |
| <button class="metal-frame px-3 py-1 rounded text-synth-label mr-2 hover:bg-synth-highlight hover:text-white transition"> | |
| PRESETS | |
| </button> | |
| <button class="metal-frame px-3 py-1 rounded text-synth-label hover:bg-synth-highlight hover:text-white transition"> | |
| RECORD | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Initialize Web Audio API | |
| const audioContext = new (window.AudioContext || window.webkitAudioContext)(); | |
| let oscillator = null; | |
| let gainNode = null; | |
| let filter = null; | |
| // Initialize synth parameters | |
| const synthParams = { | |
| waveform: 'sawtooth', | |
| octave: 0, | |
| detune: 0, | |
| cutoff: 1000, | |
| resonance: 1, | |
| attack: 0.1, | |
| decay: 0.3, | |
| sustain: 0.7, | |
| release: 0.5 | |
| }; | |
| // Note frequencies | |
| const noteFrequencies = { | |
| 'C': 261.63, | |
| 'C#': 277.18, | |
| 'D': 293.66, | |
| 'D#': 311.13, | |
| 'E': 329.63, | |
| 'F': 349.23, | |
| 'F#': 369.99, | |
| 'G': 392.00, | |
| 'G#': 415.30, | |
| 'A': 440.00, | |
| 'A#': 466.16, | |
| 'B': 493.88, | |
| 'C2': 523.25 | |
| }; | |
| // Initialize knobs | |
| function initKnobs() { | |
| const knobs = document.querySelectorAll('.knob'); | |
| knobs.forEach(knob => { | |
| let isDragging = false; | |
| let startY = 0; | |
| let startRotation = 0; | |
| let currentRotation = 0; | |
| knob.addEventListener('mousedown', (e) => { | |
| isDragging = true; | |
| startY = e.clientY; | |
| startRotation = currentRotation; | |
| knob.style.cursor = 'grabbing'; | |
| }); | |
| document.addEventListener('mousemove', (e) => { | |
| if (isDragging) { | |
| const deltaY = startY - e.clientY; | |
| currentRotation = Math.min(135, Math.max(-135, startRotation + deltaY)); | |
| knob.style.transform = `rotate(${currentRotation}deg)`; | |
| // Simulate sound when adjusting knobs | |
| playKnobSound(); | |
| } | |
| }); | |
| document.addEventListener('mouseup', () => { | |
| if (isDragging) { | |
| isDragging = false; | |
| knob.style.cursor = 'pointer'; | |
| } | |
| }); | |
| knob.addEventListener('touchstart', (e) => { | |
| isDragging = true; | |
| startY = e.touches[0].clientY; | |
| startRotation = currentRotation; | |
| }); | |
| document.addEventListener('touchmove', (e) => { | |
| if (isDragging) { | |
| const deltaY = startY - e.touches[0].clientY; | |
| currentRotation = Math.min(135, Math.max(-135, startRotation + deltaY)); | |
| knob.style.transform = `rotate(${currentRotation}deg)`; | |
| playKnobSound(); | |
| } | |
| }); | |
| document.addEventListener('touchend', () => { | |
| isDragging = false; | |
| }); | |
| }); | |
| } | |
| // Play a sound when turning knobs | |
| function playKnobSound() { | |
| if (oscillator) { | |
| oscillator.stop(); | |
| } | |
| oscillator = audioContext.createOscillator(); | |
| gainNode = audioContext.createGain(); | |
| oscillator.type = 'sine'; | |
| oscillator.frequency.value = 200; | |
| gainNode.gain.value = 0.1; | |
| gainNode.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 0.1); | |
| oscillator.connect(gainNode); | |
| gainNode.connect(audioContext.destination); | |
| oscillator.start(); | |
| oscillator.stop(audioContext.currentTime + 0.1); | |
| } | |
| // Play a note | |
| function playNote(noteElement) { | |
| if (oscillator) { | |
| oscillator.stop(); | |
| } | |
| oscillator = audioContext.createOscillator(); | |
| gainNode = audioContext.createGain(); | |
| filter = audioContext.createBiquadFilter(); | |
| // Get frequency from data attribute | |
| const frequency = parseFloat(noteElement.dataset.frequency) * Math.pow(2, synthParams.octave); | |
| // Set oscillator parameters | |
| oscillator.type = synthParams.waveform; | |
| oscillator.frequency.value = frequency; | |
| oscillator.detune.value = synthParams.detune; | |
| // Set filter parameters | |
| filter.type = 'lowpass'; | |
| filter.frequency.value = synthParams.cutoff; | |
| filter.Q.value = synthParams.resonance; | |
| // Set envelope parameters | |
| const now = audioContext.currentTime; | |
| gainNode.gain.setValueAtTime(0, now); | |
| gainNode.gain.linearRampToValueAtTime(1, now + synthParams.attack); | |
| gainNode.gain.linearRampToValueAtTime(synthParams.sustain, now + synthParams.attack + synthParams.decay); | |
| // Connect nodes | |
| oscillator.connect(filter); | |
| filter.connect(gainNode); | |
| gainNode.connect(audioContext.destination); | |
| oscillator.start(); | |
| } | |
| // Release note | |
| function releaseNote() { | |
| const now = audioContext.currentTime; | |
| gainNode.gain.cancelScheduledValues(now); | |
| gainNode.gain.setValueAtTime(gainNode.gain.value, now); | |
| gainNode.gain.linearRampToValueAtTime(0, now + synthParams.release); | |
| setTimeout(() => { | |
| if (oscillator) { | |
| oscillator.stop(); | |
| } | |
| }, synthParams.release * 1000); | |
| } | |
| // Initialize keyboard | |
| function initKeyboard() { | |
| const keys = document.querySelectorAll('.key-white, .key-black'); | |
| keys.forEach(key => { | |
| key.addEventListener('mousedown', () => { | |
| key.classList.add('active'); | |
| playNote(key); | |
| }); | |
| key.addEventListener('mouseup', () => { | |
| key.classList.remove('active'); | |
| releaseNote(); | |
| }); | |
| key.addEventListener('mouseleave', () => { | |
| if (key.classList.contains('active')) { | |
| key.classList.remove('active'); | |
| releaseNote(); | |
| } | |
| }); | |
| // Touch events for mobile | |
| key.addEventListener('touchstart', (e) => { | |
| e.preventDefault(); | |
| key.classList.add('active'); | |
| playNote(key); | |
| }); | |
| key.addEventListener('touchend', () => { | |
| key.classList.remove('active'); | |
| releaseNote(); | |
| }); | |
| }); | |
| } | |
| // Initialize waveform LEDs | |
| function initWaveformLEDs() { | |
| const leds = document.querySelectorAll('#sine-led, #saw-led, #square-led, #triangle-led'); | |
| leds.forEach(led => { | |
| led.addEventListener('click', () => { | |
| // Remove active class from all | |
| leds.forEach(l => l.classList.remove('active')); | |
| // Add active to clicked | |
| led.classList.add('active'); | |
| // Update waveform | |
| if (led.id === 'sine-led') synthParams.waveform = 'sine'; | |
| if (led.id === 'saw-led') synthParams.waveform = 'sawtooth'; | |
| if (led.id === 'square-led') synthParams.waveform = 'square'; | |
| if (led.id === 'triangle-led') synthParams.waveform = 'triangle'; | |
| playKnobSound(); | |
| }); | |
| }); | |
| } | |
| // Initialize when page loads | |
| document.addEventListener('DOMContentLoaded', () => { | |
| initKnobs(); | |
| initKeyboard(); | |
| initWaveformLEDs(); | |
| // Add slight rotation to knobs for visual effect | |
| const knobs = document.querySelectorAll('.knob'); | |
| knobs.forEach((knob, i) => { | |
| const rotation = -90 + (i * 20); | |
| knob.style.transform = `rotate(${rotation}deg)`; | |
| }); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Tingchenliang/analog-synth" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |