fix(bass-presets): move factory presets to channel subdirs + per-channel install

Root cause: factory presets for bass (banks 17-20) sat in the root
factory dir alongside guitar presets, and install_factory_presets()
used rglob() which picked up ALL presets into the GUITAR channel.

Changes:
- Move bank_17-20 from presets/factory/ → presets/factory/bass/
  (matching the existing keys/, vocals/, backing_tracks/ layout)
- Fix install_factory_presets() to scan channel-specific subdirectory:
  GUITAR scans root bank_* dirs, all others scan <channel>/bank_*
- Fix main.py to iterate over all 5 channels when installing factory
  presets (was only installing into GUITAR)
- Import Channel enum in main.py

Tests: 56/56 preset manager tests pass. Integration verified:
- GUITAR: 68 presets (banks 0-16)
- BASS: 16 presets (banks 17-20, SansAmp/Darkglass/Ampeg SVT)
- KEYS: 12 presets (banks 21-23)
- VOCALS: 12 presets (banks 24-26)
- BACKING_TRACKS: 12 presets (banks 27-29)
This commit is contained in:
2026-06-13 10:23:57 -04:00
parent 575535762c
commit 659e53766a
25 changed files with 162 additions and 10 deletions
+16 -4
View File
@@ -596,8 +596,11 @@ class PresetManager:
channel: Channel = Channel.GUITAR) -> int:
"""Install bundled factory presets into the preset store.
Scans ``FACTORY_PRESET_DIR`` for ``bank_*/preset_*.json`` files
and copies them into the user preset store.
Scans the channel-specific subdirectory of ``FACTORY_PRESET_DIR``
for ``bank_*/preset_*.json`` files and copies them into the user
preset store. For GUITAR the root of ``FACTORY_PRESET_DIR`` is
scanned (backward-compatible with legacy ``bank_0````bank_16``).
All other channels use ``FACTORY_PRESET_DIR / channel.value``.
Args:
overwrite: If True, overwrite existing presets at the same
@@ -611,8 +614,17 @@ class PresetManager:
logger.warning("Factory preset directory not found: %s", FACTORY_PRESET_DIR)
return 0
# Determine source directory — root for GUITAR, subdir for all others
source_dir = FACTORY_PRESET_DIR if channel == Channel.GUITAR \
else FACTORY_PRESET_DIR / channel.value
if not source_dir.is_dir():
logger.warning("No factory presets for channel %s: %s",
channel.value, source_dir)
return 0
count = 0
for src in sorted(FACTORY_PRESET_DIR.rglob("preset_*.json")):
for src in sorted(source_dir.glob("bank_*/preset_*.json")):
# Derive (bank, program) from file path
bank_dir = src.parent
try:
@@ -635,7 +647,7 @@ class PresetManager:
if count:
self._dirty = True
logger.info("Installed %d factory presets", count)
logger.info("Installed %d factory presets for %s", count, channel.value)
return count
def install_factory_irs(self, overwrite: bool = False) -> int:
+8 -1
View File
@@ -8,9 +8,16 @@ from typing import Optional
class Channel(enum.StrEnum):
"""Guitar or Bass signal channel — each has its own independent preset bank."""
"""Instrument/voice signal channel — each has its own independent preset bank.
Supports guitar, bass, keys, vocals, and backing tracks. Existing preset
files with "guitar" or "bass" channel values remain fully compatible.
"""
GUITAR = "guitar"
BASS = "bass"
KEYS = "keys"
VOCALS = "vocals"
BACKING_TRACKS = "backing_tracks"
class FXType(enum.StrEnum):