mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-09-11 04:34:30 +00:00
* Tuner: passive "different tuning" badge cue that names the retune
Building on the coverage check: when you enter a song your current
instrument doesn't cover, the topbar tuner badge gets an amber ring + a
tooltip naming the change (e.g. "retune B->A", or "the reference pitch"
for an A440 vs A432 mismatch). Advisory only -- it never auto-opens the
panel; recomputed on song:ready, cleared on song-load / leaving the
player.
Refactors the coverage check into a structured report
(window._tunerAutoOpen.coverageReport -> { covered, retune:[{from,to}],
reference, cantCover }); the boolean gate now wraps it. The cue is
CSS-free (inline ring + native tooltip, no Tailwind rebuild) and no-ops
when the tuner plugin is absent.
Touches static/v3/badges.js (cue) + plugins/tuner/screen.js (report).
v3-only. Stacked on #656 (issue E stage 2.5/3). The splitscreen-suppress
and no-usable-input guards move to E2 (the playback gate).
Tests: tests/js/tuner_auto_open.test.js (report names the strings,
reference mismatch, badge wiring).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QbexxfTt8q2tAn436MqGWF
* feat(tuner): read/write the live per-instrument working tuning — both-directions retune prompt (working-tuning PR 3) (#660)
The §4 coverage check compared each song against the player's fixed
instrument-profile tuning, so the tuner only ever prompted *away* from a "home"
tuning (E -> Drop C#) and stayed silent coming back (Drop C# -> E), even though
the player had physically retuned.
_playerTuning() now reads the host's live per-instrument working tuning
(window.feedBack.workingTuning, keyed by the selected instrument from
/api/settings) instead of re-deriving from the static settings tuning, so
coverage is measured against what the instrument is ACTUALLY in and prompts both
directions. On clearing an auto-opened tuner, _publishWorkingTuning() writes that
song's tuning as the instrument's live working tuning ('assumed' — PR 4's
explicit "I tuned / Skip" refines the write-point), so the next song is judged
against where the player now is.
Per-instrument (guitar vs bass tracked separately). Feature-detected: falls back
to the static /api/settings tuning when the working-tuning capability is absent,
so the 27 existing coverage tests are unchanged. Builds on PR 1 (host
workingTuning) + PR 2 (instrument->chart routing).
Tests: tests/js/tuner_auto_open.test.js — +2 (both-directions coverage via a live
Drop-D working tuning; publish-on-clear targets the right instrument slot); 29
pass total.
Claude-Session: https://claude.ai/code/session_01QbexxfTt8q2tAn436MqGWF
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* fix(tuner): transactional open + fail-closed auto-open config (tuner-E #655 review) (#681)
Two review fixes for the auto-open opt-in+persist stage:
- enable() wasn't transactional. The panel (with the ×/Skip buttons) is shown
before `await _tunerAudio.start()`, and `_state.enabled` was only set after it.
A ×/Skip dismiss during that await hit disable() with wasEnabled=false, then
enable() completed and flipped enabled on — an enabled-but-hidden zombie. Guard
the open with an `_openGen` token bumped on every enable()/disable(); after the
audio-start await, bail if superseded instead of enabling. Closes #675.
- Config wasn't fail-closed. routes.py normalized the opt-in with
bool(data.get("autoOpenOnTuningChange", False)), so "false"/"0"/junk coerced to
True. Accept only a real JSON boolean. Closes #676.
Tests: tuner_auto_open.test.js (dismiss-mid-open stays disabled — fails without
the token guard), test_config.py (auto-open default-false + fail-closed on
non-bool). 34 JS + 24 config tests green.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(tuner): coverage stays conservative when the instrument is unknown (tuner-E #656 review) (#682)
_playerTuning() is documented as conservative ("missing data → not covered → still
prompt"), but when /api/settings carried no instrument identity (a fresh profile:
_default_settings() omits instrument/string_count/tuning) it invented guitar/6/440/
standard, so an unconfigured player was treated as 6-string E-standard and coverage
suppressed the auto-open (and badge cue) for matching songs. The post-#660 rewrite
only returned null when the whole fetch failed (!s), not when settings existed but
lacked an instrument.
Now return null unless there's a confident identity — any of instrument/string_count/
tuning in settings, or live working-tuning offsets. A configured standard guitar still
covers a standard song (no regression). Closes #677.
Tests: tuner_auto_open.test.js — empty-settings → not covered (fails without the fix);
configured standard guitar → still covered.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(tuner): badge coverage cue staleness + unknown-as-warning + dedupe (tuner-E #657 review) (#683)
Three review fixes for the passive "different tuning" badge cue stage:
- Stale async cue (#678): _refreshCoverageCue awaited coverageReport then wrote the
DOM unconditionally, so a slow /api/settings fetch could restore the previous
song's amber ring after song:loading / leaving the player. Add a monotonic token
bumped on every refresh and both clear paths; apply the awaited report only if the
token still matches.
- "Unknown" rendered as "needs retune" (#679): the plugin returns a conservative
all-false report on a fetch hiccup; the cue painted that as an amber "retune the
reference pitch" ring. Collapse a no-signal report (not covered, no reference /
retune / cantCover) to null (no cue) via _meaningfulReport(). A genuine not-covered
report always carries reference / retune / cantCover, so real cues are preserved.
- Duplicate /api/settings fetch (#680): the auto-open gate and the badge cue both
call coverageReport() per song:ready. Cache the coverage promise per song (keyed by
session + tuning + centOffset) so they share one fetch; invalidate on song:loading,
instrument:changed, and working-tuning-changed so it can't go stale within a song.
Tests: tuner_auto_open.test.js — concurrent reports share one fetch, a new song
refetches (fails without the cache). 34 JS tests green. Codex-reviewed.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Byron Gamatos <xasiklas@gmail.com>
FeedBack Tuner Plugin
A real-time guitar and bass tuner plugin for FeedBack.
This plugin adds a floating "Tuner" button to the FeedBack interface, providing a high-accuracy chromatic tuner with support for multiple presets, custom tunings, and automatic song tuning detection.
Features
- Real-time Pitch Detection: Uses the YIN algorithm for robust and accurate frequency tracking.
- Multiple Presets: Includes common guitar and bass tunings (Standard, Drop D, DADGAD, Open G, etc.).
- Automatic Song Tuning: Detects and selects the correct tuning for the currently playing song in the FeedBack player.
- Manual & Auto Tracking: Automatically estimates the closest string or allows manual selection for focused tuning.
- Visual Feedback: Large cents-deviation gauge, frequency display, and color-coded indicators.
- Custom Tunings: Add your own tunings via note names (e.g., E2, A2) or Hz frequencies in the settings.
- Audio Device Selection: Choose specific input devices and channels (Mono, Left, Right) for professional interfaces.
- Themable UI: Styled with Tailwind CSS to match your FeedBack theme.
- Visualizations: Pick from different visualizations to suit your needs (Currently: Default, Strobe, Analogue Gauge, Mace Fx III, and Toilet Tuner)
Available Visualizations
| Name | Image |
|---|---|
| Default | |
| Strobe | |
| Analogue Gauge | |
| Mace-Fx III | |
| Bender PP-Tiny | |
| CHEF MT-3 | |
| Toilet Tuner |
Installation
Download a Release
- Download one of the Releases
- Extract it to your plugins folder
- Restart FeedBack
Update Manager
The plugin is listed in the official plugin repository, so it can also be installed directly via the Update Manager
Git
cd /path/to/feedBack/plugins
git clone https://github.com/OmikronApex/slopsmith-plugin-tuner.git tuner
# Restart FeedBack (or restart your docker container)
docker compose restart
How to Use
- Click the Tuner button at the bottom-right of the screen (or the "Tuner" button in the player controls).
- The tuner will automatically default to the Current Song tuning if you are in the player.
- Select other presets or custom tunings from the dropdown menu if needed.
- Pluck a string. The tuner will automatically detect the closest string in the selected tuning.
- (Optional) Click a specific note button in the tuner window to lock onto that string (useful for very out-of-tune strings).
- Adjust your tuning until the needle is centered and the indicator turns green.
Configuration
In-App Settings
Click the ⚙️ icon in the tuner window to access:
- Audio Input: Select your preferred microphone or audio interface.
- Channel Selection: Choose between Mono (mixed), Left, or Right channels (ideal for multi-channel audio interfaces).
- Visualization: Choose between different visualization options.
Plugin Manager
Access advanced settings via the FeedBack Plugin Manager (Settings -> Plugins -> Tuner):
- Floating Button: Toggle the visibility of the tuner button on the main interface.
- Tuning Visibility: Toggle which built-in tunings appear in your menu.
- Custom Tunings: Define your own tuning presets by entering a name and a list of notes/frequencies.
Changelog
[1.3.1] - 2026-06-04
- JUCE bridge audio input: when running inside FeedBack Desktop the tuner taps the engine's raw audio stream (
getRawAudioFrame) and runs its own tuning-optimised YIN over it, falling back to the browser microphone pipeline otherwise. - Fixed octave-low / sub-harmonic pitch errors (canonical YIN absolute-threshold selection) and added octave-aware nearest-string matching.
- "Free Tune" is now remembered as your last tuning, so it persists across sessions instead of resetting to a preset each time.
- Relocated visualization SVG assets to
visualization/assets/, served via the dedicated/api/plugins/tuner/viz-assets/route (supersedes the 1.3.0 note about the rootassets/directory). - Removed the legacy Tailwind stylesheet (
assets/plugin.css) and itsstylesmanifest entry — supersedes the 1.3.0 stylesheet note below.
[1.3.0] - 2026-06-01
- Added PP-Tiny visualization: inspired by the Fender PT-100 chromatic tuner panel, with a curved 11-LED arc, 8-segment note display with split centre bar, and always-on BATT. indicator.
- Added CHEF MT-3 visualization: inspired by the BOSS TU-3, featuring a 90° curved glass gauge arc, 51 tick marks, red 7-segment display, and rubber mode/brightness buttons.
- Refactored
screen.jsinto focused modules: audio pipeline extracted toutils/audio.js, UI layer extracted toutils/ui.js(shared-state factory pattern).screen.jsreduced from ~1060 to ~300 lines. - Normalised
DEFAULT_TUNINGSkeys to instrument keys (guitar-6,bass-4, etc.) — removes the internal group-name lookup table. - Added plugin stylesheet (
assets/plugin.css) via the FeedBack styles contract, ensuring arbitrary Tailwind classes render correctly for runtime-installed users. - Moved SVG assets (
Bathroom.svg,Plunger.svg,Toiletbowl.svg) to the rootassets/directory; removed the now-redundant custom asset route fromroutes.py. - Moved Toilet Tuner to the end of the visualization picker list.
[1.2.8] - 2026-05-31
- Added Toilet Tuner visualization: bathroom scene background with a plunger that slides left/right proportional to cents deviation; dips into the toilet bowl when in tune (±2 cents) and shows a 💩 emoji on the wall calendar.
[1.2.7] - 2026-05-31
- Added Mace Fx III visualization: dark navy LCD-style panel with a chromatic tick gauge, inward directional arrows, large note/octave readout, a rotating pink strobe semicircle, and a pixelated grid overlay.
- Improved tuner detection stability: median frequency filtering plus YIN octave correction (rejects both overtone and undertone errors) keeps low strings from jumping octaves as they decay.
- Added pluck-attack warm-up so the noisy string-attack transient no longer shows a wrong pitch before settling.
- Added frame-to-frame octave continuity tracking to eliminate residual octave flips.
[1.2.6] - 2026-05-31
- Added Analogue Gauge visualization: vintage mechanical instrument panel with rotating frequency and note name drums, semicircular needle gauge, and a physical-style in-tune lightbulb.
- Added AUTO mode indicator lamp: lights when Free Tune is active, dims on manual string lock.
- Visualizations now receive tuning mode context (
free/auto/manual) from the core plugin.
[1.2.5] - 2026-05-30
- Improved mic error handling: better error messages and inline error banner instead of browser alert.
- Fixed Real Tone Cable (mono-only USB audio) support when the device is explicitly selected.
- Fixed error banner persisting across screen navigation after a mic failure.
- Fixed stale error banner remaining visible after a successful device switch.
- Fixed silent failure when audio restart fails during device switch.
[1.2.4] - 2026-05-25
- Improved low-frequency detection by lowering minimum detectable frequency to 20Hz.
[1.2.3] - 2026-05-19
- Refactored tuner plugin: simplified script loading, modularized audio pipeline, and improved visualization state management.
- Fixed issue where targeting a specific string was impossible when no audio input was present.
[1.2.2] - 2026-05-18
- Added missing YIN-worker script.
[1.2.1] - 2026-05-18
- Added graceful handling for audio device errors by resetting device ID on exceptions.
[1.2.0] - 2026-05-18
- Introduced Strobe Tuner visualization.
- Modularized visualization handling and improved state management.
- Enhanced tuning synchronization logic.
[1.1.0] - 2026-05-10
- Added 5-string bass tunings.
- Removed unnecessary scroll limit in settings UI.
[1.0.3] - 2026-05-10
- Visual polish for the settings page.
- Added toggle for floating tuner button visibility.
[1.0.2] - 2026-05-10
- Added microphone and channel selection settings.
- Integrated tuner button into the player UI.
- Added dynamic tuning detection within the player.
[1.0.1] - 2026-05-10
- Fixed floating button reappearing on song end.
- Improved tuner button injection in player UI.
[1.0.0] - 2026-05-10
- Initial release.
License
MIT