- 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
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
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
Previously, the code was setting isInitialized = true on iOS even though
no AudioContext was created. This caused isReady() to return true, which
led other code to try to use the non-existent audio context.
Now isInitialized remains false on iOS, so isReady() returns false and
the code properly falls back to using the standard HTMLAudioElement APIs.