- Set crossorigin="anonymous" as a static HTML attribute on audio/video elements
so all users can use createMediaElementSource (required for Web Audio API)
- Remove window.__tidalOriginExtension guards from AudioContext init/changeSource:
binaural DSP, EQ, M/S processing, and audio graph now active for everyone
- Route direct (non-DASH) stream URLs through getProxyUrl in player.js so
non-extension users get CORS headers from the proxy for lossless/MP4 audio
- Proxy preloader src as well so browser cache warms with the proxied URL
- Add idempotency guard in getProxyUrl to prevent double-proxying when Shaka
retries segment requests (proxied URL still contains "tidal.com" in params)
- Extension users: still bypass proxy and get CDN URLs directly (unchanged)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove stale IIR coefficient JSDoc comment
- Reset M/S channel state on EQ import to prevent stale assignments
- Enforce strictly increasing GEQ frequencies to prevent rounding duplicates
- Guard Q calculation against zero octave spacing (Infinity/NaN)
- Export EQ from stored metadata instead of live BiquadFilterNode state
- Accept .csv in legacy GEQ import file input
- Expose public reconnect() on BinauralDSP instead of calling _connectInternal
- Dispatch binaural-mode-changed on channel count change, not just mode change
- Remove no-op channelCount/channelCountMode on MediaElementAudioSourceNode
- Add void to floating promises (toggleBinaural, notifyBinauralChannelCount, _loadBinauralSettings)
- Wrap binauralDspSettings._setAll in try/catch for QuotaExceededError
- Make generateHRTF synchronous (no awaits, was misleadingly async)
Implement a complete binaural audio processing pipeline that sits before
EQ Studio in the signal chain. Supports multichannel (5.1) HRTF
binauralization for Dolby Atmos and Apple 3D Audio content, with
crossfeed and stereo widening for regular stereo content.
New modules:
- hrtf-generator.js: Procedural HRTF impulse response synthesis using
Woodworth head model (ITD, ILD, head shadow, pinna coloring)
- binaural-dsp.js: BinauralDSP engine with multichannel splitter,
per-channel ConvolverNode HRTF rendering, Bauer-style crossfeed
(low/medium/high), and M/S stereo widener
Integration:
- Audio graph: binaural block inserted before preamp/EQ, multichannel
passthrough via MediaElementSource channelCount=6
- Storage: binauralDspSettings with full persistence (JSON in localStorage)
- UI: toggle + sub-controls (crossfeed level, HRTF preset, width slider)
placed before EQ Studio in settings
- Player: auto-enables binaural DSP when Atmos content detected,
shows binaural badge on Atmos tracks
- Removed unnecessary preconnect link to jsDelivr in index.html.
- Added lazy loading to contribs in app.js for improved performance.
- Implemented dynamic loading of am-lyrics and shaka based on image loading status to reduce lcp
- Introduced waitForImagesLoading function in player.js to ensure all images are loaded before initializing the player
- Enhanced image loading attributes in ui.js to include fetchpriority based on loading strategy.
- Updated package.json to include vite-plugin-purgecss for CSS optimization
- Configured Vite to use purgecss and enabled tree-shaking in vite.config.ts to reduce bundle size
- Add 16-band graphic equalizer with legacy EQ mode
- Add speaker measurement and room correction EQ
- Fix audio skipping with AutoEQ on Android background
- Improve audio performance to prevent skipping under CPU load
- Fix dual EQ applied when switching between legacy and parametric modes
- Remove redundant Equalizer settings tab
- Improve mobile EQ band layout and collapsible database section
Engine & algorithm:
- Use default shelf Q (1/√2) in calculateBiquadResponse for shelf filters
- Compute normalization offset on measurement frequency grid to avoid bias
- Try stale cache for all fetch errors in autoeq-importer, not just timeouts
Audio pipeline:
- Pass postProcessingQuality (preserves Dolby Atmos override) in api.js
- Persist custom band frequencies in equalizerSettings storage
- Restore custom frequencies on _loadSettings instead of regenerating defaults
- Export clamped preamp value in applyAutoEQBands text output
- Propagate filter type and Q values through equalizer import chain
- Update freqRange after importing custom filter frequencies
- Remove return in finally block that hid LOSSLESS fallback failures
Data consistency:
- Normalize artist IDs with String() in blockArtist/unblockArtist
Lint & code quality:
- Annotate empty catch blocks (Atmos codec probes)
- Remove unused catch parameters
Accessibility:
- Add aria-label and for attributes to all AutoEQ form controls
- Add role="status" aria-live="polite" to feedback spans
- Update filter type documentation to reflect shelf support
- Hide parametric-only sections by default to match active tab
UI:
- Move AutoEq button directly under graph
- Hide shared button in Parametric/Speaker modes
- Replace hardcoded white legend dot with theme-adaptive color-mix
- Add pointer-events:none and focus-within to profile delete button
The plugin runs all imported SVG files through svgo.
For index.html, you can use the following syntax:
```html
<use svg="file.svg" size="24" />
```
For scripts, use the `?svg` import query
```javascript
import SVG_FILE from './file.svg?svg&size=24
```
Note: size is shorthand for specifying both width and height individually. You can also set any property of the base SVG element.
You can also use the `?svg&icon` query to return a function that allows dynamically resizing the SVG string.