{"id":"ajidim","deleted":false,"future_paste":false,"expired":false,"language":"html","created_at":"2026-09-09 07:50:00","expires_at":null,"content":"<!DOCTYPE html>\r\n<html lang=\"de\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\">\r\n    <title>Misa Kitara Mobile - Digital Synth<\/title>\r\n    <style>\r\n        :root {\r\n            --bg-color: #08080c;\r\n            --panel-bg: #12121c;\r\n            --accent-cyan: #00f0ff;\r\n            --accent-magenta: #ff0055;\r\n            --accent-gold: #ffcc00;\r\n            --grid-line: #222233;\r\n        }\r\n\r\n        * {\r\n            box-sizing: border-box;\r\n            user-select: none;\r\n            -webkit-user-select: none;\r\n            touch-action: none;\r\n        }\r\n\r\n        body {\r\n            background-color: var(--bg-color);\r\n            color: #fff;\r\n            font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, monospace;\r\n            margin: 0;\r\n            padding: 8px;\r\n            height: 100vh;\r\n            height: 100dvh;\r\n            display: flex;\r\n            flex-direction: column;\r\n            gap: 8px;\r\n            overflow: hidden;\r\n        }\r\n\r\n        \/* Top Header & Display *\/\r\n        .header {\r\n            background: var(--panel-bg);\r\n            border: 1px solid #333;\r\n            border-radius: 8px;\r\n            padding: 6px 10px;\r\n            display: flex;\r\n            justify-content: space-between;\r\n            align-items: center;\r\n        }\r\n\r\n        .title {\r\n            font-size: 0.9rem;\r\n            font-weight: 900;\r\n            color: var(--accent-cyan);\r\n            letter-spacing: 1px;\r\n        }\r\n\r\n        .status {\r\n            font-size: 0.7rem;\r\n            color: var(--accent-gold);\r\n            font-family: monospace;\r\n        }\r\n\r\n        \/* Fretboard Matrix Area *\/\r\n        .fretboard-container {\r\n            background: var(--panel-bg);\r\n            border: 1px solid #333;\r\n            border-radius: 8px;\r\n            padding: 6px;\r\n            display: flex;\r\n            flex-direction: column;\r\n            gap: 4px;\r\n            flex-shrink: 0;\r\n        }\r\n\r\n        .string-row {\r\n            display: flex;\r\n            align-items: center;\r\n            gap: 4px;\r\n            height: 28px;\r\n        }\r\n\r\n        .string-label {\r\n            width: 24px;\r\n            font-size: 0.65rem;\r\n            font-weight: bold;\r\n            color: var(--accent-cyan);\r\n            text-align: center;\r\n        }\r\n\r\n        .fret-buttons {\r\n            display: flex;\r\n            flex: 1;\r\n            gap: 3px;\r\n            height: 100%;\r\n        }\r\n\r\n        .fret-btn {\r\n            flex: 1;\r\n            background: #1a1a26;\r\n            border: 1px solid #333;\r\n            color: #888;\r\n            font-size: 0.65rem;\r\n            font-weight: bold;\r\n            border-radius: 4px;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            cursor: pointer;\r\n        }\r\n\r\n        .fret-btn.active {\r\n            background: var(--accent-magenta);\r\n            color: #fff;\r\n            border-color: #ff6699;\r\n            box-shadow: 0 0 8px rgba(255, 0, 85, 0.6);\r\n        }\r\n\r\n        \/* Kitara XY Performance Touchpad *\/\r\n        .pad-container {\r\n            flex: 1;\r\n            position: relative;\r\n            background: #040406;\r\n            border: 2px solid var(--accent-cyan);\r\n            border-radius: 10px;\r\n            overflow: hidden;\r\n            box-shadow: inset 0 0 20px rgba(0, 240, 255, 0.15);\r\n        }\r\n\r\n        canvas {\r\n            width: 100%;\r\n            height: 100%;\r\n            display: block;\r\n        }\r\n\r\n        \/* FX Preset Control Bar *\/\r\n        .controls-bar {\r\n            display: flex;\r\n            gap: 6px;\r\n            height: 36px;\r\n        }\r\n\r\n        select, button {\r\n            background: #1a1a26;\r\n            color: #fff;\r\n            border: 1px solid #444;\r\n            border-radius: 6px;\r\n            padding: 4px 8px;\r\n            font-size: 0.75rem;\r\n            font-weight: bold;\r\n            flex: 1;\r\n        }\r\n\r\n        button.active {\r\n            background: var(--accent-cyan);\r\n            color: #000;\r\n        }\r\n    <\/style>\r\n<\/head>\r\n<body>\r\n\r\n    <div class=\"header\">\r\n        <div class=\"title\">KITARA-MOBILE<\/div>\r\n        <div class=\"status\" id=\"status-display\">TOUCH PAD TO PLAY<\/div>\r\n    <\/div>\r\n\r\n    <div class=\"fretboard-container\" id=\"fretboard\"><\/div>\r\n\r\n    <div class=\"pad-container\" id=\"pad-box\">\r\n        <canvas id=\"pad-canvas\"><\/canvas>\r\n    <\/div>\r\n\r\n    <div class=\"controls-bar\">\r\n        <select id=\"synth-sound\">\r\n            <option value=\"lead\">Kitara Cyber Lead<\/option>\r\n            <option value=\"acid\">303 Distorted<\/option>\r\n            <option value=\"poly\">Digital PolySaw<\/option>\r\n            <option value=\"sub\">Sub Bass Heavy<\/option>\r\n        <\/select>\r\n        <button id=\"delay-btn\">DELAY: ON<\/button>\r\n    <\/div>\r\n\r\n<script>\r\n    \/\/ Base Frequencies for 6 Standard Guitar Strings (E2, A2, D3, G3, B3, E4)\r\n    const baseNotes = [40, 45, 50, 55, 59, 64]; \r\n    const availableFrets = [0, 1, 3, 5, 7, 8, 10, 12];\r\n    const stringStates = [0, 0, 0, 0, 0, 0]; \/\/ Selected fret per string\r\n\r\n    let audioCtx = null;\r\n    let masterGain, filterNode, driveNode, delayNode, delayFeedback;\r\n    let delayActive = true;\r\n    let activeVoices = {}; \/\/ Tracks active touch sound voices\r\n\r\n    function midiToFreq(midi) {\r\n        return 440 * Math.pow(2, (midi - 69) \/ 12);\r\n    }\r\n\r\n    \/\/ Audio Engine Setup\r\n    function initAudio() {\r\n        if (audioCtx) return;\r\n        audioCtx = new (window.AudioContext || window.webkitAudioContext)({ latencyHint: 'interactive' });\r\n\r\n        masterGain = audioCtx.createGain();\r\n        masterGain.gain.value = 0.4;\r\n\r\n        filterNode = audioCtx.createBiquadFilter();\r\n        filterNode.type = 'lowpass';\r\n        filterNode.frequency.value = 2500;\r\n        filterNode.Q.value = 4;\r\n\r\n        driveNode = audioCtx.createWaveShaper();\r\n        driveNode.curve = makeDistortionCurve(60);\r\n\r\n        \/\/ Delay FX\r\n        delayNode = audioCtx.createDelay();\r\n        delayNode.delayTime.value = 0.25; \/\/ 1\/8 note vibe\r\n        delayFeedback = audioCtx.createGain();\r\n        delayFeedback.gain.value = 0.4;\r\n\r\n        delayNode.connect(delayFeedback);\r\n        delayFeedback.connect(delayNode);\r\n\r\n        \/\/ Routing\r\n        filterNode.connect(driveNode);\r\n        driveNode.connect(masterGain);\r\n        driveNode.connect(delayNode);\r\n        delayNode.connect(masterGain);\r\n\r\n        masterGain.connect(audioCtx.destination);\r\n    }\r\n\r\n    function makeDistortionCurve(amount) {\r\n        let k = amount, n = 44100, curve = new Float32Array(n), deg = Math.PI \/ 180;\r\n        for (let i = 0; i < n; ++i) {\r\n            let x = i * 2 \/ n - 1;\r\n            curve[i] = (3 + k) * x * 20 * deg \/ (Math.PI + k * Math.abs(x));\r\n        }\r\n        return curve;\r\n    }\r\n\r\n    \/\/ Play Kitara Voice on String Trigger\r\n    function startVoice(touchId, stringIndex, xRatio, yRatio) {\r\n        initAudio();\r\n        if (audioCtx.state === 'suspended') audioCtx.resume();\r\n\r\n        const midiNote = baseNotes[stringIndex] + stringStates[stringIndex];\r\n        const freq = midiToFreq(midiNote);\r\n        const preset = document.getElementById('synth-sound').value;\r\n\r\n        const osc1 = audioCtx.createOscillator();\r\n        const osc2 = audioCtx.createOscillator();\r\n        const voiceGain = audioCtx.createGain();\r\n\r\n        if (preset === 'acid') {\r\n            osc1.type = 'sawtooth'; osc2.type = 'sawtooth';\r\n            osc2.detune.value = 12;\r\n        } else if (preset === 'poly') {\r\n            osc1.type = 'sawtooth'; osc2.type = 'square';\r\n            osc2.detune.value = -7;\r\n        } else if (preset === 'sub') {\r\n            osc1.type = 'triangle'; osc2.type = 'sine';\r\n        } else { \/\/ Kitara Lead\r\n            osc1.type = 'sawtooth'; osc2.type = 'square';\r\n            osc2.detune.value = 5;\r\n        }\r\n\r\n        osc1.frequency.setValueAtTime(freq, audioCtx.currentTime);\r\n        osc2.frequency.setValueAtTime(freq, audioCtx.currentTime);\r\n\r\n        osc1.connect(voiceGain);\r\n        osc2.connect(voiceGain);\r\n        voiceGain.connect(filterNode);\r\n\r\n        \/\/ Fast Attack Envelope\r\n        voiceGain.gain.setValueAtTime(0.01, audioCtx.currentTime);\r\n        voiceGain.gain.linearRampToValueAtTime(0.8, audioCtx.currentTime + 0.01);\r\n\r\n        osc1.start(); osc2.start();\r\n\r\n        activeVoices[touchId] = { osc1, osc2, voiceGain, stringIndex };\r\n        updateSynthParameters(xRatio, yRatio);\r\n    }\r\n\r\n    function updateVoice(touchId, xRatio, yRatio, stringIndex) {\r\n        if (!activeVoices[touchId]) return;\r\n\r\n        \/\/ Pitch shift if finger slides to another string zone\r\n        if (activeVoices[touchId].stringIndex !== stringIndex) {\r\n            const midiNote = baseNotes[stringIndex] + stringStates[stringIndex];\r\n            const freq = midiToFreq(midiNote);\r\n            const now = audioCtx.currentTime;\r\n            activeVoices[touchId].osc1.frequency.setTargetAtTime(freq, now, 0.01);\r\n            activeVoices[touchId].osc2.frequency.setTargetAtTime(freq, now, 0.01);\r\n            activeVoices[touchId].stringIndex = stringIndex;\r\n        }\r\n\r\n        updateSynthParameters(xRatio, yRatio);\r\n    }\r\n\r\n    function stopVoice(touchId) {\r\n        if (!activeVoices[touchId]) return;\r\n        const { osc1, osc2, voiceGain } = activeVoices[touchId];\r\n        const now = audioCtx.currentTime;\r\n\r\n        voiceGain.gain.cancelScheduledValues(now);\r\n        voiceGain.gain.setTargetAtTime(0.001, now, 0.05);\r\n\r\n        setTimeout(() => {\r\n            try { osc1.stop(); osc2.stop(); osc1.disconnect(); osc2.disconnect(); } catch(e){}\r\n        }, 100);\r\n\r\n        delete activeVoices[touchId];\r\n    }\r\n\r\n    function updateSynthParameters(xRatio, yRatio) {\r\n        if (!audioCtx) return;\r\n        const now = audioCtx.currentTime;\r\n\r\n        \/\/ X-Axis controls Filter Cutoff (100 Hz - 8000 Hz)\r\n        const cutoff = 100 * Math.pow(80, xRatio);\r\n        filterNode.frequency.setTargetAtTime(cutoff, now, 0.01);\r\n\r\n        \/\/ Y-Axis controls Resonance & Distortion Gain\r\n        filterNode.Q.setTargetAtTime(2 + (yRatio * 16), now, 0.01);\r\n        \r\n        document.getElementById('status-display').innerText = \r\n            `CUTOFF: ${Math.round(cutoff)}Hz | RES: ${Math.round(2 + yRatio * 16)}`;\r\n    }\r\n\r\n    \/\/ Render Fretboard UI\r\n    const fretboardEl = document.getElementById('fretboard');\r\n    const stringNames = ['E2', 'A2', 'D3', 'G3', 'B3', 'E4'];\r\n\r\n    stringNames.forEach((name, sIdx) => {\r\n        const row = document.createElement('div');\r\n        row.className = 'string-row';\r\n\r\n        const label = document.createElement('div');\r\n        label.className = 'string-label';\r\n        label.innerText = name[0] + name[1];\r\n        row.appendChild(label);\r\n\r\n        const fretContainer = document.createElement('div');\r\n        fretContainer.className = 'fret-buttons';\r\n\r\n        availableFrets.forEach((fret) => {\r\n            const btn = document.createElement('div');\r\n            btn.className = `fret-btn ${fret === 0 ? 'active' : ''}`;\r\n            btn.innerText = fret === 0 ? 'O' : fret;\r\n            btn.dataset.string = sIdx;\r\n            btn.dataset.fret = fret;\r\n\r\n            btn.addEventListener('pointerdown', (e) => {\r\n                e.preventDefault();\r\n                stringStates[sIdx] = fret;\r\n                row.querySelectorAll('.fret-btn').forEach(b => b.classList.remove('active'));\r\n                btn.classList.add('active');\r\n            });\r\n\r\n            fretContainer.appendChild(btn);\r\n        });\r\n\r\n        row.appendChild(fretContainer);\r\n        fretboardEl.appendChild(row);\r\n    });\r\n\r\n    \/\/ Touchpad & Canvas Performance Rendering\r\n    const padBox = document.getElementById('pad-box');\r\n    const canvas = document.getElementById('pad-canvas');\r\n    const ctx = canvas.getContext('2d');\r\n    let touches = [];\r\n\r\n    function resizeCanvas() {\r\n        canvas.width = padBox.clientWidth;\r\n        canvas.height = padBox.clientHeight;\r\n    }\r\n    window.addEventListener('resize', resizeCanvas);\r\n    resizeCanvas();\r\n\r\n    function getPadCoordinates(e) {\r\n        const rect = padBox.getBoundingClientRect();\r\n        const touchList = e.touches ? Array.from(e.touches) : [e];\r\n        return touchList.map(t => {\r\n            const x = Math.max(0, Math.min(rect.width, t.clientX - rect.left));\r\n            const y = Math.max(0, Math.min(rect.height, t.clientY - rect.top));\r\n            const xRatio = x \/ rect.width;\r\n            const yRatio = 1 - (y \/ rect.height);\r\n            \/\/ 6 Virtual String Zones on Y-Axis\r\n            const stringIndex = Math.min(5, Math.floor((y \/ rect.height) * 6));\r\n            return { id: t.identifier ?? 'mouse', x, y, xRatio, yRatio, stringIndex };\r\n        });\r\n    }\r\n\r\n    function handleTouchStart(e) {\r\n        e.preventDefault();\r\n        const currentTouches = getPadCoordinates(e);\r\n        currentTouches.forEach(t => {\r\n            startVoice(t.id, t.stringIndex, t.xRatio, t.yRatio);\r\n        });\r\n        touches = currentTouches;\r\n    }\r\n\r\n    function handleTouchMove(e) {\r\n        e.preventDefault();\r\n        const currentTouches = getPadCoordinates(e);\r\n        currentTouches.forEach(t => {\r\n            updateVoice(t.id, t.xRatio, t.yRatio, t.stringIndex);\r\n        });\r\n        touches = currentTouches;\r\n    }\r\n\r\n    function handleTouchEnd(e) {\r\n        e.preventDefault();\r\n        const remainingTouches = getPadCoordinates(e);\r\n        const remainingIds = new Set(remainingTouches.map(t => t.id));\r\n\r\n        Object.keys(activeVoices).forEach(id => {\r\n            if (!remainingIds.has(id === 'mouse' ? 'mouse' : Number(id))) {\r\n                stopVoice(id);\r\n            }\r\n        });\r\n        touches = remainingTouches;\r\n    }\r\n\r\n    padBox.addEventListener('touchstart', handleTouchStart, { passive: false });\r\n    padBox.addEventListener('touchmove', handleTouchMove, { passive: false });\r\n    padBox.addEventListener('touchend', handleTouchEnd, { passive: false });\r\n\r\n    let isMouseDown = false;\r\n    padBox.addEventListener('mousedown', (e) => { isMouseDown = true; handleTouchStart(e); });\r\n    window.addEventListener('mousemove', (e) => { if (isMouseDown) handleTouchMove(e); });\r\n    window.addEventListener('mouseup', (e) => { if (isMouseDown) { isMouseDown = false; handleTouchEnd(e); } });\r\n\r\n    \/\/ Visualizer Loop\r\n    function drawPad() {\r\n        requestAnimationFrame(drawPad);\r\n        ctx.fillStyle = '#040406';\r\n        ctx.fillRect(0, 0, canvas.width, canvas.height);\r\n\r\n        \/\/ Draw 6 Virtual String Bands (Kitara Style)\r\n        const bandHeight = canvas.height \/ 6;\r\n        ctx.lineWidth = 1;\r\n        for (let i = 0; i < 6; i++) {\r\n            ctx.strokeStyle = '#181828';\r\n            ctx.beginPath();\r\n            ctx.moveTo(0, i * bandHeight);\r\n            ctx.lineTo(canvas.width, i * bandHeight);\r\n            ctx.stroke();\r\n\r\n            \/\/ Highlight Active Fretted String Lines\r\n            ctx.strokeStyle = 'rgba(0, 240, 255, 0.15)';\r\n            ctx.beginPath();\r\n            ctx.moveTo(0, i * bandHeight + bandHeight \/ 2);\r\n            ctx.lineTo(canvas.width, i * bandHeight + bandHeight \/ 2);\r\n            ctx.stroke();\r\n        }\r\n\r\n        \/\/ Draw Touch Pointers\r\n        touches.forEach(t => {\r\n            \/\/ Horizontal \/ Vertical Crosshair\r\n            ctx.strokeStyle = 'rgba(255, 0, 85, 0.4)';\r\n            ctx.beginPath(); ctx.moveTo(t.x, 0); ctx.lineTo(t.x, canvas.height); ctx.stroke();\r\n            ctx.beginPath(); ctx.moveTo(0, t.y); ctx.lineTo(canvas.width, t.y); ctx.stroke();\r\n\r\n            \/\/ Glowing Touch Point\r\n            ctx.fillStyle = '#00f0ff';\r\n            ctx.shadowColor = '#00f0ff';\r\n            ctx.shadowBlur = 12;\r\n            ctx.beginPath();\r\n            ctx.arc(t.x, t.y, 16, 0, Math.PI * 2);\r\n            ctx.fill();\r\n            ctx.shadowBlur = 0;\r\n        });\r\n    }\r\n    drawPad();\r\n\r\n    \/\/ UI Listeners\r\n    document.getElementById('delay-btn').addEventListener('click', (e) => {\r\n        delayActive = !delayActive;\r\n        delayFeedback.gain.value = delayActive ? 0.4 : 0;\r\n        e.target.innerText = `DELAY: ${delayActive ? 'ON' : 'OFF'}`;\r\n        e.target.classList.toggle('active', delayActive);\r\n    });\r\n<\/script>\r\n<\/body>\r\n<\/html>\r\n"}