- 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
- Rename section header to EQ Studio with updated description
- Add ST/M/S channel select dropdown to each parametric band control
- Move Parametric EQ tab before AutoEQ
- Hide Original/Target/Corrected legend in parametric mode
- Add per-band M/S processing with full encoder/decoder matrix in Web Audio API
- Right-click context menu on EQ nodes for filter type and channel switching
- Right-click empty graph space to add nodes
- Remove nearest-node snap-click interaction
- Replace IIR shelf filters with native BiquadFilter for glitch-free updates
- Add 6 M/S showcase presets with research-informed mastering values
- Add 5 shelf-based stereo presets (Warm, Bright, Hi-Fi, Dark, Radio Ready)
- Standard presets now reset all bands to stereo/peaking
- Graph contrast fix for light themes using color-mix()
- Colored help button and rewritten how-to documentation
- Default graph zoom changed to ±16 dB
- Add Bands/Min Hz/Max Hz controls to legacy EQ section
- Dynamic frequency generation with log spacing and auto-scaling Q
- Import/export handles variable band counts, Q optional for shelves
- Custom presets interpolate across different band counts
- Update legacy EQ tutorial for new controls
- Add Export APO button to legacy graphic EQ (GraphicEQ config line format)
- Fix shelf filters ignoring Q: use IIR filters with RBJ cookbook coefficients
- Update graph visualization to use actual Q for shelf curves
- Omit Q from shelf filters in all EQ text exports
Save button prompts for a name and stores the current 16-band gains
as a custom preset in localStorage. Custom presets appear in an
optgroup at the bottom of the preset dropdown. Delete button shows
when a custom preset is selected.
https://claude.ai/code/session_01AgSx7SP1dH5KFmpGXCAUvU
Export outputs EqualizerAPO-compatible format with all 16 bands.
Import accepts EqualizerAPO format or simple freq/gain pairs,
maps to nearest GEQ band by log-frequency distance, and ignores
Q values since legacy mode uses fixed dB sliders.
https://claude.ai/code/session_01AgSx7SP1dH5KFmpGXCAUvU
* Refine fullscreen player to look more like apple music
* fix: buttons when in visualizer only mode
* fix: mobile sizing
* Update styles.css
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update js/ui.js
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* feat: refine fullscreen apple player
* fix: add lyrics toggle for mobile
* add lyrics toggle for mobile
* wrong branch oops 😭
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- 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
Android:
- Fix stale wake lock detection by checking isHeld() before reacquiring
- Wrap startForegroundService in try-catch to handle launch exceptions
- Add START/STOP intent actions to prevent stop/start race condition
HTML/Accessibility:
- Convert preset and preamp spans to proper <label> elements
- Add aria-controls to database collapse button
- Sync aria-expanded state when toggling database panel
JavaScript:
- Guard auto-resume with source check to avoid resuming when not playing
- Add _calculateQ() fallback in fast-path EQ filter updates
- Persist graphic EQ gains and preamp to storage from setters
- Include 'legacy' in EQ mode restoration check
- Clear container before rebuilding GEQ bands for idempotency
- Use AbortController for document-level listener cleanup
- Apply gain calculation for non-parametric modes in touch snap
- Validate stored GEQ values are finite numbers
CSS:
- Remove non-standard appearance: slider-vertical property
- 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
This will write each artist separately to the metadata rather than as a single concatenated string. This allows for better library searching if the player supports it.
If multiple artists are written to an m4a file, iTunes will only show the first artist.
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