Last active
October 14, 2026 15:40
-
-
Save Notookk/dadd64d9543e6b6445ad49f4f86d4d47 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Telegram Web Voice DSP Pro (Draggable HUD + Deep Hook) | |
| // @namespace http://tampermonkey.net/ | |
| // @version 3.1 | |
| // @description Hard-hook DSP: Intercepts Prototype + RTCPeerConnection with a freely movable floating mixer panel | |
| // @match https://web.telegram.org/* | |
| // @match https://webz.telegram.org/* | |
| // @match https://webk.telegram.org/* | |
| // @grant none | |
| // @run-at document-start | |
| // ==/UserScript== | |
| (function () { | |
| 'use strict'; | |
| const state = { | |
| gain: 12.0, // Extreme digital multiplier | |
| clarity: 9.0, // +9 dB presence at 3kHz | |
| bass: 3.0, // +3 dB warmth | |
| distortion: 0.85 | |
| }; | |
| let activeCtx = null; | |
| let activeGainNode = null; | |
| let activeClarityNode = null; | |
| let activeBassNode = null; | |
| let activeSoftClipNode = null; | |
| function generateSoftClipCurve(knee) { | |
| const samples = 4096; | |
| const curve = new Float32Array(samples); | |
| const safeKnee = Math.max(0.1, Math.min(1.0, knee)); | |
| for (let i = 0; i < samples; ++i) { | |
| const x = (i * 2) / samples - 1; | |
| curve[i] = Math.tanh(x / safeKnee) * safeKnee; | |
| } | |
| return curve; | |
| } | |
| // --- Core Audio Processor --- | |
| function processAudioStream(stream) { | |
| if (!stream || stream.getAudioTracks().length === 0) return stream; | |
| if (stream.__dsp_processed) return stream; | |
| stream.__dsp_processed = true; | |
| try { | |
| const AudioCtx = window.AudioContext || window.webkitAudioContext; | |
| const ctx = new AudioCtx(); | |
| activeCtx = ctx; | |
| // Force resume on mobile audio locks | |
| if (ctx.state === 'suspended') { | |
| const resumeCtx = () => { | |
| ctx.resume(); | |
| ['click', 'touchstart', 'touchend'].forEach(evt => | |
| document.removeEventListener(evt, resumeCtx) | |
| ); | |
| }; | |
| ['click', 'touchstart', 'touchend'].forEach(evt => | |
| document.addEventListener(evt, resumeCtx, { once: true }) | |
| ); | |
| ctx.resume(); | |
| } | |
| const source = ctx.createMediaStreamSource(stream); | |
| // 1. Highpass (Handling rumble cut) | |
| const highPass = ctx.createBiquadFilter(); | |
| highPass.type = 'highpass'; | |
| highPass.frequency.setValueAtTime(90, ctx.currentTime); | |
| // 2. Bass (Vocal body) | |
| const bassFilter = ctx.createBiquadFilter(); | |
| bassFilter.type = 'lowshelf'; | |
| bassFilter.frequency.setValueAtTime(140, ctx.currentTime); | |
| bassFilter.gain.setValueAtTime(state.bass, ctx.currentTime); | |
| activeBassNode = bassFilter; | |
| // 3. Clarity (3 kHz peak) | |
| const clarityFilter = ctx.createBiquadFilter(); | |
| clarityFilter.type = 'peaking'; | |
| clarityFilter.frequency.setValueAtTime(3000, ctx.currentTime); | |
| clarityFilter.Q.setValueAtTime(1.1, ctx.currentTime); | |
| clarityFilter.gain.setValueAtTime(state.clarity, ctx.currentTime); | |
| activeClarityNode = clarityFilter; | |
| // 4. Loudness Pre-Gain | |
| const boostGain = ctx.createGain(); | |
| boostGain.gain.setValueAtTime(state.gain, ctx.currentTime); | |
| activeGainNode = boostGain; | |
| // 5. Saturation / Soft Clip | |
| const softClip = ctx.createWaveShaper(); | |
| softClip.curve = generateSoftClipCurve(state.distortion); | |
| softClip.oversample = '2x'; | |
| activeSoftClipNode = softClip; | |
| // 6. Fast-Attack Limiter | |
| const limiter = ctx.createDynamicsCompressor(); | |
| limiter.threshold.setValueAtTime(-1.5, ctx.currentTime); | |
| limiter.knee.setValueAtTime(0, ctx.currentTime); | |
| limiter.ratio.setValueAtTime(20.0, ctx.currentTime); | |
| limiter.attack.setValueAtTime(0.001, ctx.currentTime); | |
| limiter.release.setValueAtTime(0.04, ctx.currentTime); | |
| const destination = ctx.createMediaStreamDestination(); | |
| source.connect(highPass); | |
| highPass.connect(bassFilter); | |
| bassFilter.connect(clarityFilter); | |
| clarityFilter.connect(boostGain); | |
| boostGain.connect(softClip); | |
| softClip.connect(limiter); | |
| limiter.connect(destination); | |
| const outputStream = destination.stream; | |
| outputStream.__dsp_processed = true; | |
| stream.getVideoTracks().forEach(t => outputStream.addTrack(t)); | |
| const badge = document.getElementById('tg-dsp-status'); | |
| if (badge) { | |
| badge.textContent = '● ACTIVE'; | |
| badge.style.color = '#00ff88'; | |
| } | |
| return outputStream; | |
| } catch (err) { | |
| console.error('[DSP Hook Error]', err); | |
| return stream; | |
| } | |
| } | |
| // --- Dual Hook Layer: Prototype + Instance --- | |
| if (navigator.mediaDevices) { | |
| const origGUM = navigator.mediaDevices.getUserMedia; | |
| navigator.mediaDevices.getUserMedia = async function (constraints) { | |
| const stream = await origGUM.apply(this, arguments); | |
| return processAudioStream(stream); | |
| }; | |
| if (navigator.mediaDevices.constructor && navigator.mediaDevices.constructor.prototype) { | |
| const origProtoGUM = navigator.mediaDevices.constructor.prototype.getUserMedia; | |
| if (origProtoGUM) { | |
| navigator.mediaDevices.constructor.prototype.getUserMedia = async function (constraints) { | |
| const stream = await origProtoGUM.apply(this, arguments); | |
| return processAudioStream(stream); | |
| }; | |
| } | |
| } | |
| } | |
| // --- WebRTC RTCPeerConnection Fallback Hook --- | |
| const OrigPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection; | |
| if (OrigPeerConnection) { | |
| const origAddTrack = OrigPeerConnection.prototype.addTrack; | |
| OrigPeerConnection.prototype.addTrack = function (track, ...streams) { | |
| if (track && track.kind === 'audio' && streams[0] && !streams[0].__dsp_processed) { | |
| const processed = processAudioStream(streams[0]); | |
| const newTrack = processed.getAudioTracks()[0]; | |
| if (newTrack) { | |
| return origAddTrack.call(this, newTrack, processed); | |
| } | |
| } | |
| return origAddTrack.apply(this, arguments); | |
| }; | |
| } | |
| // --- Moveable HUD with Drag Support --- | |
| function mountHUD() { | |
| if (document.getElementById('tg-dsp-hud')) return; | |
| const hud = document.createElement('div'); | |
| hud.id = 'tg-dsp-hud'; | |
| hud.innerHTML = ` | |
| <div id="tg-dsp-header" style="display:flex;justify-content:space-between;align-items:center;font-weight:700;color:#4da6ff;margin-bottom:8px;font-size:12px;cursor:grab;user-select:none;-webkit-user-select:none;"> | |
| <span style="pointer-events:none;">✥ 🎙️ DSP Mixer</span> | |
| <div style="display:flex;align-items:center;gap:6px;"> | |
| <span id="tg-dsp-status" style="font-size:10px;color:#ffaa00;font-weight:bold;pointer-events:none;">STANDBY</span> | |
| <button id="tg-dsp-btn" style="background:none;border:none;color:#aaa;font-size:16px;cursor:pointer;padding:0 4px;">_</button> | |
| </div> | |
| </div> | |
| <div id="tg-dsp-body"> | |
| <label style="display:flex;justify-content:space-between;margin-top:4px;">Loudness: <span id="v-gain">${state.gain}x</span></label> | |
| <input type="range" id="sl-gain" min="1" max="25" step="0.5" value="${state.gain}" style="width:100%;"> | |
| <label style="display:flex;justify-content:space-between;margin-top:4px;">Clarity: <span id="v-clarity">${state.clarity} dB</span></label> | |
| <input type="range" id="sl-clarity" min="-6" max="15" step="1" value="${state.clarity}" style="width:100%;"> | |
| <label style="display:flex;justify-content:space-between;margin-top:4px;">Distortion / Drive: <span id="v-dist">${state.distortion}</span></label> | |
| <input type="range" id="sl-dist" min="0.1" max="1.0" step="0.05" value="${state.distortion}" style="width:100%;"> | |
| <label style="display:flex;justify-content:space-between;margin-top:4px;">Bass Punch: <span id="v-bass">${state.bass} dB</span></label> | |
| <input type="range" id="sl-bass" min="-6" max="12" step="1" value="${state.bass}" style="width:100%;"> | |
| </div> | |
| `; | |
| hud.style.cssText = ` | |
| position: fixed; | |
| top: 80px; | |
| left: 15px; | |
| z-index: 999999; | |
| background: rgba(18, 22, 28, 0.96); | |
| backdrop-filter: blur(10px); | |
| color: #fff; | |
| padding: 12px 14px; | |
| border-radius: 12px; | |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; | |
| font-size: 11px; | |
| width: 215px; | |
| box-shadow: 0 8px 30px rgba(0,0,0,0.85); | |
| border: 1px solid rgba(255,255,255,0.15); | |
| touch-action: none; | |
| `; | |
| document.body.appendChild(hud); | |
| // AudioContext unlocker on panel touch | |
| hud.addEventListener('touchstart', () => { | |
| if (activeCtx && activeCtx.state === 'suspended') { | |
| activeCtx.resume(); | |
| } | |
| }); | |
| // --- Drag and Drop Logic (Touch & Pointer) --- | |
| const header = hud.querySelector('#tg-dsp-header'); | |
| let isDragging = false; | |
| let startX = 0; | |
| let startY = 0; | |
| let initialLeft = 0; | |
| let initialTop = 0; | |
| function onDragStart(e) { | |
| if (e.target.id === 'tg-dsp-btn') return; // Don't drag when clicking minimize button | |
| isDragging = true; | |
| header.style.cursor = 'grabbing'; | |
| const clientX = e.clientX || (e.touches && e.touches[0].clientX); | |
| const clientY = e.clientY || (e.touches && e.touches[0].clientY); | |
| startX = clientX; | |
| startY = clientY; | |
| const rect = hud.getBoundingClientRect(); | |
| initialLeft = rect.left; | |
| initialTop = rect.top; | |
| if (e.type === 'touchstart') { | |
| window.addEventListener('touchmove', onDragMove, { passive: false }); | |
| window.addEventListener('touchend', onDragEnd); | |
| } else { | |
| window.addEventListener('mousemove', onDragMove); | |
| window.addEventListener('mouseup', onDragEnd); | |
| } | |
| } | |
| function onDragMove(e) { | |
| if (!isDragging) return; | |
| if (e.cancelable) e.preventDefault(); | |
| const clientX = e.clientX || (e.touches && e.touches[0].clientX); | |
| const clientY = e.clientY || (e.touches && e.touches[0].clientY); | |
| const deltaX = clientX - startX; | |
| const deltaY = clientY - startY; | |
| let newLeft = initialLeft + deltaX; | |
| let newTop = initialTop + deltaY; | |
| // Keep inside screen viewport boundaries | |
| const maxLeft = window.innerWidth - hud.offsetWidth - 5; | |
| const maxTop = window.innerHeight - hud.offsetHeight - 5; | |
| newLeft = Math.max(5, Math.min(newLeft, maxLeft)); | |
| newTop = Math.max(5, Math.min(newTop, maxTop)); | |
| hud.style.left = `${newLeft}px`; | |
| hud.style.top = `${newTop}px`; | |
| hud.style.right = 'auto'; | |
| hud.style.bottom = 'auto'; | |
| } | |
| function onDragEnd() { | |
| isDragging = false; | |
| header.style.cursor = 'grab'; | |
| window.removeEventListener('mousemove', onDragMove); | |
| window.removeEventListener('mouseup', onDragEnd); | |
| window.removeEventListener('touchmove', onDragMove); | |
| window.removeEventListener('touchend', onDragEnd); | |
| } | |
| header.addEventListener('mousedown', onDragStart); | |
| header.addEventListener('touchstart', onDragStart, { passive: true }); | |
| // Slider controls | |
| const slGain = hud.querySelector('#sl-gain'); | |
| const slClarity = hud.querySelector('#sl-clarity'); | |
| const slDist = hud.querySelector('#sl-dist'); | |
| const slBass = hud.querySelector('#sl-bass'); | |
| const vGain = hud.querySelector('#v-gain'); | |
| const vClarity = hud.querySelector('#v-clarity'); | |
| const vDist = hud.querySelector('#v-dist'); | |
| const vBass = hud.querySelector('#v-bass'); | |
| slGain.oninput = (e) => { | |
| const val = parseFloat(e.target.value); | |
| state.gain = val; | |
| vGain.textContent = `${val.toFixed(1)}x`; | |
| if (activeGainNode && activeCtx) { | |
| activeGainNode.gain.setValueAtTime(val, activeCtx.currentTime); | |
| } | |
| }; | |
| slClarity.oninput = (e) => { | |
| const val = parseFloat(e.target.value); | |
| state.clarity = val; | |
| vClarity.textContent = `${val} dB`; | |
| if (activeClarityNode && activeCtx) { | |
| activeClarityNode.gain.setValueAtTime(val, activeCtx.currentTime); | |
| } | |
| }; | |
| slDist.oninput = (e) => { | |
| const val = parseFloat(e.target.value); | |
| state.distortion = val; | |
| vDist.textContent = val.toFixed(2); | |
| if (activeSoftClipNode) { | |
| activeSoftClipNode.curve = generateSoftClipCurve(val); | |
| } | |
| }; | |
| slBass.oninput = (e) => { | |
| const val = parseFloat(e.target.value); | |
| state.bass = val; | |
| vBass.textContent = `${val} dB`; | |
| if (activeBassNode && activeCtx) { | |
| activeBassNode.gain.setValueAtTime(val, activeCtx.currentTime); | |
| } | |
| }; | |
| const toggleBtn = hud.querySelector('#tg-dsp-btn'); | |
| const body = hud.querySelector('#tg-dsp-body'); | |
| toggleBtn.onclick = () => { | |
| const isHidden = body.style.display === 'none'; | |
| body.style.display = isHidden ? 'block' : 'none'; | |
| toggleBtn.textContent = isHidden ? '_' : '+'; | |
| }; | |
| } | |
| if (document.readyState === 'loading') { | |
| document.addEventListener('DOMContentLoaded', mountHUD); | |
| } else { | |
| mountHUD(); | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment