diff --git a/index.html b/index.html index 0e0f766..fbbeaf2 100644 --- a/index.html +++ b/index.html @@ -4262,13 +4262,12 @@ Scroll on a node to adjust Q (bandwidth).
  • - Right-click a node to change its filter type - (Peaking, Low Shelf, High Shelf) or channel mode - (Stereo, Mid, Side). + Right-click a node to change its filter type (Peaking, Low + Shelf, High Shelf) or channel mode (Stereo, Mid, Side).
  • - Right-click empty space or double-click to add a - node. Double-click a node to remove it. + Right-click empty space or double-click to add a node. + Double-click a node to remove it.
  • Save the profile so you can switch between headphones @@ -4301,9 +4300,8 @@ channel mode to Stereo, Mid, or Side.
  • - Right-click empty space or double-click to add a - node at that position. - Double-click a node to delete it. + Right-click empty space or double-click to add a node + at that position. Double-click a node to delete it.
  • Use + Add Band / - Remove Band to change the number of @@ -4322,12 +4320,11 @@ Tip: Lower Q = wider curve, higher Q = narrower surgical cut.

    - Mid/Side tips: Set a band to Mid to EQ only the - center image (vocals, bass, kick). Set it to Side to - EQ only the stereo width (reverb, ambience, panned instruments). - Try cutting low-end on Side below 200 Hz for tighter, mono-compatible - bass - or boost presence on Mid around 2-5 kHz to bring vocals forward - without touching the sides. + Mid/Side tips: Set a band to Mid to EQ only the center image + (vocals, bass, kick). Set it to Side to EQ only the stereo width + (reverb, ambience, panned instruments). Try cutting low-end on Side + below 200 Hz for tighter, mono-compatible bass - or boost presence on + Mid around 2-5 kHz to bring vocals forward without touching the sides.

    @@ -4360,8 +4357,8 @@ Right-click a node to change type or channel mode.
  • - Right-click empty space or double-click to add a - node. Double-click a node to remove it. + Right-click empty space or double-click to add a node. + Double-click a node to remove it.
  • Repeat for each channel, then Export JSON with all channels. diff --git a/js/audio-context.js b/js/audio-context.js index a7678d4..0dec0dc 100644 --- a/js/audio-context.js +++ b/js/audio-context.js @@ -326,7 +326,7 @@ class AudioContextManager { const type = (this.currentTypes && this.currentTypes[i]) || 'peaking'; const q = this.currentQs && this.currentQs[i] > 0 ? this.currentQs[i] : this._calculateQ(i); const ch = (this.currentChannels && this.currentChannels[i]) || 'stereo'; - const gain = ch === 'side' ? 0 : (this.currentGains[i] || 0); + const gain = ch === 'side' ? 0 : this.currentGains[i] || 0; const filter = this.audioContext.createBiquadFilter(); filter.type = type; filter.frequency.value = freq; @@ -339,7 +339,7 @@ class AudioContextManager { const type = (this.currentTypes && this.currentTypes[i]) || 'peaking'; const q = this.currentQs && this.currentQs[i] > 0 ? this.currentQs[i] : this._calculateQ(i); const ch = (this.currentChannels && this.currentChannels[i]) || 'stereo'; - const gain = ch === 'mid' ? 0 : (this.currentGains[i] || 0); + const gain = ch === 'mid' ? 0 : this.currentGains[i] || 0; const filter = this.audioContext.createBiquadFilter(); filter.type = type; filter.frequency.value = freq; @@ -353,7 +353,13 @@ class AudioContextManager { * Destroy M/S parallel filter chains */ _destroyMSFilters() { - const sd = (node) => { try { node?.disconnect(); } catch { /* */ } }; + const sd = (node) => { + try { + node?.disconnect(); + } catch { + /* */ + } + }; this.midFilters.forEach(sd); this.sideFilters.forEach(sd); this.midFilters = []; @@ -660,15 +666,15 @@ class AudioContextManager { // Encode L/R → M/S lastNode.connect(this.msSplitter); - this.msSplitter.connect(this.msEncoderMidL, 0); // L → Mid - this.msSplitter.connect(this.msEncoderMidR, 1); // R → Mid + this.msSplitter.connect(this.msEncoderMidL, 0); // L → Mid + this.msSplitter.connect(this.msEncoderMidR, 1); // R → Mid this.msEncoderMidL.connect(this.msMidInput); - this.msEncoderMidR.connect(this.msMidInput); // Mid = (L+R)*0.5 + this.msEncoderMidR.connect(this.msMidInput); // Mid = (L+R)*0.5 this.msSplitter.connect(this.msEncoderSideL, 0); // L → Side this.msSplitter.connect(this.msEncoderSideR, 1); // R → Side (-0.5) this.msEncoderSideL.connect(this.msSideInput); - this.msEncoderSideR.connect(this.msSideInput); // Side = (L-R)*0.5 + this.msEncoderSideR.connect(this.msSideInput); // Side = (L-R)*0.5 // Mid filter chain this.msMidInput.connect(this.midFilters[0]); @@ -688,12 +694,12 @@ class AudioContextManager { this.midOutputNode.connect(this.msDecoderMidToL); this.sideOutputNode.connect(this.msDecoderSideToL); this.msDecoderMidToL.connect(this.msLMix); - this.msDecoderSideToL.connect(this.msLMix); // L = Mid + Side + this.msDecoderSideToL.connect(this.msLMix); // L = Mid + Side this.midOutputNode.connect(this.msDecoderMidToR); this.sideOutputNode.connect(this.msDecoderSideToR); this.msDecoderMidToR.connect(this.msRMix); - this.msDecoderSideToR.connect(this.msRMix); // R = Mid - Side + this.msDecoderSideToR.connect(this.msRMix); // R = Mid - Side this.msLMix.connect(this.msMerger, 0, 0); this.msRMix.connect(this.msMerger, 0, 1); @@ -1089,7 +1095,8 @@ class AudioContextManager { this.msEnabled = needsMS; if (this.isInitialized && this.audioContext) { - const needsRebuild = msChanged || this.filters.length !== count || (needsMS && this.midFilters.length !== count); + const needsRebuild = + msChanged || this.filters.length !== count || (needsMS && this.midFilters.length !== count); if (needsRebuild) { // M/S state changed or band count changed — full rebuild @@ -1108,11 +1115,11 @@ class AudioContextManager { this._updateFilterChain(this.filters, newFrequencies, newTypes, newQs, newGains, now); // Update mid filters (gain = 0 for side-only bands) - const midGains = newGains.map((g, i) => newChannels[i] === 'side' ? 0 : g); + const midGains = newGains.map((g, i) => (newChannels[i] === 'side' ? 0 : g)); this._updateFilterChain(this.midFilters, newFrequencies, newTypes, newQs, midGains, now); // Update side filters (gain = 0 for mid-only bands) - const sideGains = newGains.map((g, i) => newChannels[i] === 'mid' ? 0 : g); + const sideGains = newGains.map((g, i) => (newChannels[i] === 'mid' ? 0 : g)); this._updateFilterChain(this.sideFilters, newFrequencies, newTypes, newQs, sideGains, now); } else if (this.filters.length === count) { // Normal stereo — update in-place diff --git a/js/settings.js b/js/settings.js index 76ee01e..8384a4a 100644 --- a/js/settings.js +++ b/js/settings.js @@ -2561,7 +2561,12 @@ export async function initializeSettings(scrobbler, player, api, ui) { const bands = getActiveBands(); // Filter type actions - if (action.startsWith('eq-type-') && contextMenuNodeIdx !== null && bands && bands[contextMenuNodeIdx]) { + if ( + action.startsWith('eq-type-') && + contextMenuNodeIdx !== null && + bands && + bands[contextMenuNodeIdx] + ) { const typeMap = { 'eq-type-lowshelf': 'lowshelf', 'eq-type-peaking': 'peaking', @@ -2578,7 +2583,12 @@ export async function initializeSettings(scrobbler, player, api, ui) { } // Channel actions (per-band M/S mode) - if (action.startsWith('eq-channel-') && contextMenuNodeIdx !== null && bands && bands[contextMenuNodeIdx]) { + if ( + action.startsWith('eq-channel-') && + contextMenuNodeIdx !== null && + bands && + bands[contextMenuNodeIdx] + ) { const channelMap = { 'eq-channel-stereo': 'stereo', 'eq-channel-mid': 'mid', @@ -2627,12 +2637,21 @@ export async function initializeSettings(scrobbler, player, api, ui) { if (currentMode === 'autoeq') { autoeqCurrentBands = []; bands = autoeqCurrentBands; - } else { hideEmptyContextMenu(); return; } + } else { + hideEmptyContextMenu(); + return; + } + } + if (bands.length >= 32) { + hideEmptyContextMenu(); + return; } - if (bands.length >= 32) { hideEmptyContextMenu(); return; } const rect = autoeqCanvas.getBoundingClientRect(); - const padLeft = 40, padRight = 10, padTop = 10, padBottom = 30; + const padLeft = 40, + padRight = 10, + padTop = 10, + padBottom = 30; const w = rect.width - padLeft - padRight; const h = rect.height - padTop - padBottom; const dbCenter = isParam ? 0 : 75; @@ -2640,9 +2659,10 @@ export async function initializeSettings(scrobbler, player, api, ui) { const dbMin = dbCenter - dbHalf; const dbMax = dbCenter + dbHalf; const freq = Math.max(20, Math.min(20000, Math.round(xToFreq(pendingAddCoords.x - padLeft, w)))); - const gain = Math.max(-30, Math.min(30, - Math.round((yToDb(pendingAddCoords.y - padTop, h, dbMin, dbMax) - dbCenter) * 10) / 10 - )); + const gain = Math.max( + -30, + Math.min(30, Math.round((yToDb(pendingAddCoords.y - padTop, h, dbMin, dbMax) - dbCenter) * 10) / 10) + ); bands.push({ id: bands.length, type: 'peaking', freq, gain, q: 1.0, enabled: true, channel: 'stereo' }); setActiveBands(bands); @@ -2984,7 +3004,15 @@ export async function initializeSettings(scrobbler, player, api, ui) { const defaultBands = []; for (let i = 0; i < 10; i++) { const freq = 20 * Math.pow(20000 / 20, i / 9); - defaultBands.push({ id: i, type: 'peaking', freq: Math.round(freq), gain: 0, q: 1.0, enabled: true, channel: 'stereo' }); + defaultBands.push({ + id: i, + type: 'peaking', + freq: Math.round(freq), + gain: 0, + q: 1.0, + enabled: true, + channel: 'stereo', + }); } parametricBands = defaultBands; applyBandsToAudio(parametricBands); @@ -5295,7 +5323,15 @@ export async function initializeSettings(scrobbler, player, api, ui) { setActiveBands(bands); } if (bands.length >= 32) return; - bands.push({ id: bands.length, type: 'peaking', freq: 1000, gain: 0, q: 1.0, enabled: true, channel: 'stereo' }); + bands.push({ + id: bands.length, + type: 'peaking', + freq: 1000, + gain: 0, + q: 1.0, + enabled: true, + channel: 'stereo', + }); applyBandsToAudio(bands); renderBandControls(bands); computeCorrectedCurve();