<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Neural Radio Learning Interface</title>
    <style>
        body {
            background: #000;
            color: #0f0;
            font-family: monospace;
            padding: 20px;
            margin: 0;
        }

        .container {
            max-width: 1000px;
            margin: 0 auto;
        }

        .radio-source {
            border: 1px solid #0f0;
            padding: 10px;
            margin: 10px 0;
        }

        .visualizer {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
            margin: 10px 0;
        }

        canvas {
            background: #111;
            border: 1px solid #0f0;
            width: 100%;
            height: 100px;
        }

        .controls {
            display: flex;
            gap: 10px;
            margin: 10px 0;
        }

        button {
            background: #111;
            color: #0f0;
            border: 1px solid #0f0;
            padding: 10px 20px;
            cursor: pointer;
        }

        button:hover {
            background: #0f0;
            color: #000;
        }

        .status {
            border: 1px solid #0f0;
            padding: 10px;
            margin: 10px 0;
        }

        .meter {
            width: 100%;
            height: 20px;
            background: #111;
            border: 1px solid #0f0;
            margin: 5px 0;
        }

        .meter-fill {
            height: 100%;
            background: #0f0;
            width: 0%;
            transition: width 0.3s;
        }

        .memory-bank {
            border: 1px solid #0f0;
            padding: 10px;
            margin: 10px 0;
            height: 150px;
            overflow-y: auto;
        }

        .neural-response {
            border: 1px solid #0f0;
            padding: 10px;
            margin: 10px 0;
        }

        @keyframes pulse {
            0% { opacity: 1; }
            50% { opacity: 0.5; }
            100% { opacity: 1; }
        }

        .recording {
            color: #f00;
            animation: pulse 1s infinite;
            display: none;
        }

        .active .recording {
            display: inline;
        }
    </style>
</head>
<body>
    <div class="container">
        <h2>Neural Radio Learning Interface</h2>

        <div class="radio-source">
            <h3>Radio Source</h3>
            <audio id="radioStream" crossorigin="anonymous">
                <source src="http://stream.live.vc.bbcmedia.co.uk/bbc_world_service" type="audio/mpeg">
            </audio>
            <div>Status: <span id="radioStatus">Not connected</span></div>
        </div>

        <div class="visualizer">
            <div>
                <div>Input Signal</div>
                <canvas id="inputVisual"></canvas>
            </div>
            <div>
                <div>Radio Signal</div>
                <canvas id="radioVisual"></canvas>
            </div>
        </div>

        <div class="status">
            <div>Neural Learning Progress:</div>
            <div class="meter">
                <div class="meter-fill" id="learningMeter"></div>
            </div>
            <div>Pattern Recognition:</div>
            <div class="meter">
                <div class="meter-fill" id="patternMeter"></div>
            </div>
        </div>

        <div class="controls">
            <button id="startBtn">Start Learning</button>
            <button id="stopBtn">Stop</button>
            <button id="respondBtn">Force Response</button>
            <span class="recording">● Recording</span>
        </div>

        <div class="memory-bank">
            <h3>Memory Bank</h3>
            <div id="memories"></div>
        </div>

        <div class="neural-response">
            <h3>Neural Response</h3>
            <div id="response">Waiting for input...</div>
        </div>
    </div>

    <script>
        class NeuralRadioInterface {
            constructor() {
                this.audioContext = null;
                this.radioAnalyser = null;
                this.micAnalyser = null;
                this.isLearning = false;
                this.memories = [];
                this.learningProgress = 0;
                this.patternStrength = 0;

                this.initializeUI();
                this.setupEventListeners();
            }

            initializeUI() {
                this.inputCanvas = document.getElementById('inputVisual');
                this.radioCanvas = document.getElementById('radioVisual');
                this.learningMeter = document.getElementById('learningMeter');
                this.patternMeter = document.getElementById('patternMeter');
                this.memoriesDiv = document.getElementById('memories');
                this.responseDiv = document.getElementById('response');
                this.radioStatus = document.getElementById('radioStatus');
            }

            setupEventListeners() {
                document.getElementById('startBtn').onclick = () => this.start();
                document.getElementById('stopBtn').onclick = () => this.stop();
                document.getElementById('respondBtn').onclick = () => this.generateResponse();
                
                const radio = document.getElementById('radioStream');
                radio.onplay = () => this.radioStatus.textContent = 'Connected';
                radio.onerror = () => this.radioStatus.textContent = 'Error connecting';
            }

            async start() {
                try {
                    this.audioContext = new AudioContext();
                    
                    // Setup microphone input
                    const micStream = await navigator.mediaDevices.getUserMedia({audio: true});
                    const micSource = this.audioContext.createMediaStreamSource(micStream);
                    this.micAnalyser = this.audioContext.createAnalyser();
                    micSource.connect(this.micAnalyser);

                    // Setup radio input
                    const radio = document.getElementById('radioStream');
                    radio.play();
                    const radioSource = this.audioContext.createMediaElementSource(radio);
                    this.radioAnalyser = this.audioContext.createAnalyser();
                    radioSource.connect(this.radioAnalyser);
                    radioSource.connect(this.audioContext.destination);

                    this.isLearning = true;
                    document.body.classList.add('active');
                    
                    this.learn();
                    this.updateVisuals();
                    this.monitorInput();

                } catch(err) {
                    console.error('Error:', err);
                    this.responseDiv.textContent = 'Error: ' + err.message;
                }
            }

            stop() {
                this.isLearning = false;
                document.getElementById('radioStream').pause();
                document.body.classList.remove('active');
                if(this.audioContext) {
                    this.audioContext.close();
                }
            }

            learn() {
                if(!this.isLearning) return;

                // Simulate learning from radio stream
                if(this.learningProgress < 100) {
                    this.learningProgress += Math.random() * 0.5;
                    this.learningMeter.style.width = this.learningProgress + '%';
                }

                // Store simulated memories
                if(Math.random() < 0.1) {
                    const memory = `Learned pattern ${Math.floor(Math.random() * 1000)} at ${new Date().toLocaleTimeString()}`;
                    this.memories.unshift(memory);
                    if(this.memories.length > 10) this.memories.pop();
                    
                    this.updateMemories();
                }

                setTimeout(() => this.learn(), 100);
            }

            monitorInput() {
                if(!this.isLearning) return;

                const bufferLength = this.micAnalyser.frequencyBinCount;
                const dataArray = new Uint8Array(bufferLength);
                this.micAnalyser.getByteTimeDomainData(dataArray);

                // Analyze input and trigger response
                let sum = 0;
                for(let i = 0; i < bufferLength; i++) {
                    sum += Math.abs(dataArray[i] - 128);
                }
                
                const inputLevel = sum / bufferLength;
                this.patternStrength = Math.min(100, this.patternStrength + (inputLevel > 10 ? 5 : -2));
                this.patternMeter.style.width = this.patternStrength + '%';

                if(this.patternStrength > 80) {
                    this.generateResponse();
                    this.patternStrength = 0;
                }

                setTimeout(() => this.monitorInput(), 100);
            }

            generateResponse() {
                const responses = [
                    'Analyzing input pattern...',
                    'Pattern matched! Generating response...',
                    'Processing neural pathways...',
                    'Synthesizing radio fragments...',
                    'Generating response from learned patterns...'
                ];

                this.responseDiv.textContent = responses[Math.floor(Math.random() * responses.length)];
                
                // Simulate audio response
                const oscillator = this.audioContext.createOscillator();
                const gain = this.audioContext.createGain();
                
                oscillator.connect(gain);
                gain.connect(this.audioContext.destination);
                
                oscillator.frequency.setValueAtTime(440, this.audioContext.currentTime);
                gain.gain.setValueAtTime(0.1, this.audioContext.currentTime);
                gain.gain.exponentialRampToValueAtTime(0.001, this.audioContext.currentTime + 0.5);
                
                oscillator.start();
                oscillator.stop(this.audioContext.currentTime + 0.5);
            }

            updateVisuals() {
                if(!this.isLearning) return;

                // Draw input visualization
                if(this.micAnalyser) {
                    const inputData = new Uint8Array(this.micAnalyser.frequencyBinCount);
                    this.micAnalyser.getByteTimeDomainData(inputData);
                    this.drawWaveform(this.inputCanvas, inputData, '#0f0');
                }

                // Draw radio visualization
                if(this.radioAnalyser) {
                    const radioData = new Uint8Array(this.radioAnalyser.frequencyBinCount);
                    this.radioAnalyser.getByteTimeDomainData(radioData);
                    this.drawWaveform(this.radioCanvas, radioData, '#f00');
                }

                requestAnimationFrame(() => this.updateVisuals());
            }

            drawWaveform(canvas, dataArray, color) {
                const ctx = canvas.getContext('2d');
                const width = canvas.width;
                const height = canvas.height;

                ctx.fillStyle = '#111';
                ctx.fillRect(0, 0, width, height);
                ctx.lineWidth = 2;
                ctx.strokeStyle = color;
                ctx.beginPath();

                const sliceWidth = width / dataArray.length;
                let x = 0;

                for(let i = 0; i < dataArray.length; i++) {
                    const v = dataArray[i] / 128.0;
                    const y = v * height/2;

                    if(i === 0) ctx.moveTo(x, y);
                    else ctx.lineTo(x, y);

                    x += sliceWidth;
                }

                ctx.lineTo(width, height/2);
                ctx.stroke();
            }

            updateMemories() {
                this.memoriesDiv.innerHTML = this.memories
                    .map(m => `<div>${m}</div>`)
                    .join('');
            }
        }

        window.onload = () => new NeuralRadioInterface();
    </script>
</body>
</html>