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:
@@ -0,0 +1,124 @@
|
||||
# Bass Genre Tones — NAM Model Research & Artist Chain Configs
|
||||
|
||||
_Researched: 2026-06-13_
|
||||
_Source: Tone3000 (tone3000.com) — the primary NAM capture repository_
|
||||
|
||||
## Overview
|
||||
|
||||
We have **10 bass cabinet IRs** already installed but **5 bass NAM models already on disk** (Bank 7):
|
||||
|
||||
| File | Type |
|
||||
|------|------|
|
||||
| `Ampeg_PF20T_A2.nam` | Small tube combo (Ampeg) |
|
||||
| `Aguilar_Tone_Hammer_500_A2.nam` | Modern preamp |
|
||||
| `GK_800RB_Line_A2.nam` | Classic solid-state |
|
||||
| `Aguilar_DB751_Cab_A2.nam` | Bass amp DI |
|
||||
| `Fender_Bassman_Dimed_A2.nam` | Bassman growl |
|
||||
|
||||
**Gaps:** SansAmp BDDI, Darkglass B3K/B7K, Ampeg SVT-CL, Geddy Lee DI-2112.
|
||||
|
||||
---
|
||||
|
||||
## Part 1: Available Bass NAM Models on Tone3000
|
||||
|
||||
### 1.1 Tech 21 SansAmp
|
||||
|
||||
| Capture | Creator | Tone3000 URL |
|
||||
|---------|---------|-------------|
|
||||
| SansAmp BDDI v1 | jackspirited | `/tones/sansamp-bddi-v1-39232` |
|
||||
| Tech21 SansAmp VT Bass DI | salamiexcerpt5j | `/tones/tech21-sansamp-vt-bass-di-30406` |
|
||||
| Geddy Lee SansAmp DI-2112 | jakegideon | `/tones/geddy-lee-sansamp-di-2112-5989` |
|
||||
|
||||
### 1.2 Darkglass Electronics
|
||||
|
||||
| Capture | Creator | URL |
|
||||
|---------|---------|-----|
|
||||
| Darkglass B3K (A1+A2) | santo | `/tones/darkglass-microtubes-b3k-26546` |
|
||||
| Darkglass B7K | tmrecprod | `/tones/darkglass-b7k-71080` |
|
||||
| Darkglass B7K Ultra | darkglass | `/tones/darkglass-b7k-ultra-27698` |
|
||||
| Darkglass Alpha-Omega | darkglass | `/tones/darkglass-alpha-omega-27697` |
|
||||
| Darkglass Vintage Deluxe | darkglass | `/tones/darkglass-vintage-deluxe-27696` |
|
||||
| Darkglass ADAM | fctwingov6 | `/tones/darkglass-adam-65168` |
|
||||
|
||||
### 1.3 Ampeg
|
||||
|
||||
| Capture | Creator | URL |
|
||||
|---------|---------|-----|
|
||||
| Ampeg SVT-CL Bass Head | deathblossomaudio | `/tones/ampeg-svt-cl-bass-head-45809` |
|
||||
| Ampeg SVT-4 Pro | noamp | `/tones/ampeg-svt-4-pro-29376` |
|
||||
| Ampeg B-15 Fliptop | tone3000 | `/tones/ampeg-b-15-fliptop-26828` |
|
||||
| Ampeg SGT-DI | plingubus | `/tones/ampeg-sgt-di-34631` |
|
||||
|
||||
### 1.4 Aguilar
|
||||
|
||||
| Capture | Creator | URL |
|
||||
|---------|---------|-----|
|
||||
| Aguilar Tone Hammer (pedal) | wolffire99 | `/tones/aguilar-tone-hammer-45991` |
|
||||
| Aguilar DB751 | dudubxt | `/tones/aguilar-db751-39531` |
|
||||
| Aguiler Plugin Suite (Feather!) | jindrich | `/tones/aguilar-plugin-suite-feather-full-rig-collection-41096` |
|
||||
|
||||
### 1.5 Gallien-Krueger
|
||||
|
||||
| Capture | Creator | URL |
|
||||
|---------|---------|-----|
|
||||
| GK 800 | siddonfer | `/tones/gk-800--2608` |
|
||||
| Gallien Krueger 800 RB | joeformat | `/tones/gallien-krueger-800-rb-56782` |
|
||||
|
||||
### 1.6 Fender Bassman
|
||||
|
||||
| Capture | Creator | URL |
|
||||
|---------|---------|-----|
|
||||
| Fender Bassman 5F6A Series | neampmod | `/tones/fender-bassman-5f6a-series-26082` |
|
||||
| 1971 Fender Bassman | maestrodimusica | `/tones/1971-fender-bassman-13776` |
|
||||
|
||||
### Full Captures Report
|
||||
See `/home/oplabs/nam_bass_captures_report.md` for complete list (80+ captures).
|
||||
|
||||
---
|
||||
|
||||
## Part 2: Artist Tone Matrix
|
||||
|
||||
| Artist | Primary Model | Secondary Model | Best IR |
|
||||
|--------|--------------|-----------------|---------|
|
||||
| **Cliff Burton** (Metallica) | Ampeg SVT-CL | SansAmp BDDI v1 | bass-thick_classic |
|
||||
| **Geddy Lee** (70s) | Ampeg SVT-CL (clean) | — | bass-classic |
|
||||
| **Geddy Lee** (80s+) | Geddy Lee SansAmp DI-2112 | SansAmp BDDI v1 + SVT-CL | bass-balanced |
|
||||
| **Justin Chancellor** (Tool) | Darkglass B3K | GK 800 | bass-more_mids |
|
||||
| **John Paul Jones** (Led Zep) | Ampeg SVT-CL (clean) | Fender Bassman 5F6A | bass-classic |
|
||||
| **Flea** (RHCP) | SansAmp BDDI v1 | Ampeg SVT-CL | bass-thick_classic |
|
||||
| **Les Claypool** (Primus) | Darkglass Vintage Deluxe + B7K | SansAmp BDDI + SVT-CL | bass-more_mids |
|
||||
| **Tim Commerford** (RATM) | SansAmp BDDI v1 | Ampeg SVT-CL | bass-classic |
|
||||
| **Robert Trujillo** (Metallica) | Darkglass B7K | Ampeg SVT-CL | bass-clanky |
|
||||
|
||||
---
|
||||
|
||||
## Part 3: Priority Download List
|
||||
|
||||
1. **Ampeg SVT-CL** (deathblossomaudio) — foundation, used by almost every artist
|
||||
2. **SansAmp BDDI v1** (jackspirited) — versatile preamp
|
||||
3. **Darkglass B3K** (santo, A2) — modern growl
|
||||
4. **Darkglass B7K** (tmrecprod) — versatile distortion
|
||||
5. **Geddy Lee SansAmp DI-2112** (jakegideon) — direct Geddy rig capture
|
||||
6. **Fender Bassman 5F6A** (neampmod) — vintage bass
|
||||
7. **Aguilar Tone Hammer pedal** (wolffire99) — warm modern preamp
|
||||
8. **GK 800** (siddonfer) — punchy solid-state
|
||||
|
||||
**10 bass IRs already available** at `~/.pedal/irs/bass-*.wav`.
|
||||
|
||||
---
|
||||
|
||||
## Part 4: Chain Architecture
|
||||
|
||||
```
|
||||
Bass → NAM Model (preamp/amp) → Cab IR (bass-specific) → Output
|
||||
```
|
||||
|
||||
- **Pedal captures** (SansAmp, Darkglass B3K, Tone Hammer) need a bass cab IR after them
|
||||
- **Amp head captures** (SVT-CL, GK 800) also need a bass cab IR
|
||||
- **Full rig captures** already include cab — skip IR
|
||||
- **Compression** should be before the NAM model (not modeled by NAM)
|
||||
- All captures are from Tone3000 — download URLs in full report
|
||||
|
||||
### No BDDI v2 / No SVT-VR
|
||||
- BDDI v2 NOT found; v1 is close (different headroom/EQ curve)
|
||||
- SVT-VR NOT found; SVT-CL is equivalent (same circuit, different era)
|
||||
@@ -382,6 +382,11 @@ The following Archive.org sources returned 404 when last checked (2026-06-13):
|
||||
│ ├── Orange_Rocker30_Dirty_A2.nam # 295 KB — Rock crunch
|
||||
│ ├── Orange_Rocker30_Natural_A2.nam # 289 KB — Clean edge
|
||||
│ ├── Fender_Bassman_Dimed_A2.nam # 289 KB — Blues/rock breakup
|
||||
│ │
|
||||
│ └── 🎸 Bass Genre Research:
|
||||
│ └── Full artist tone chain configs → `docs/bass-tone-research.md`
|
||||
│ Available on Tone3000 (needs download): SansAmp BDDI v1, Darkglass B3K/B7K,
|
||||
│ Ampeg SVT-CL, Geddy Lee SansAmp DI-2112
|
||||
│ ├── Hiwatt_DR103_Bright_A2.nam # 287 KB — Classic rock
|
||||
│ ├── Hiwatt_DR103_Cornish_A2.nam # 288 KB — Boosted classic rock
|
||||
│ ├── Supro_Black_Magick_M3_A2.nam # 288 KB — Garage/blues
|
||||
|
||||
@@ -28,7 +28,7 @@ from src.dsp.pipeline import AudioPipeline
|
||||
from src.dsp.nam_host import NAMHost
|
||||
from src.dsp.ir_loader import IRLoader
|
||||
from src.presets.manager import PresetManager
|
||||
from src.presets.types import MIDIMapping, Preset
|
||||
from src.presets.types import Channel, MIDIMapping, Preset
|
||||
from src.midi.handler import MIDIHandler
|
||||
from src.ui.footswitch import FootswitchController, FootSwitch, SwitchAction
|
||||
from src.ui.leds import LEDController, LEDDriver, LEDConfig, LEDPattern
|
||||
@@ -170,11 +170,15 @@ class PedalApp:
|
||||
audio_pipeline=self.pipeline,
|
||||
)
|
||||
|
||||
# Install factory presets (non-destructive by default)
|
||||
# Install factory presets for all channels (non-destructive by default)
|
||||
if pcfg.get("install_factory", True):
|
||||
installed = self.presets.install_factory_presets(overwrite=False)
|
||||
if installed:
|
||||
logger.info("Installed %d factory preset(s)", installed)
|
||||
for ch in Channel:
|
||||
installed = self.presets.install_factory_presets(
|
||||
overwrite=False, channel=ch,
|
||||
)
|
||||
if installed:
|
||||
logger.info("Installed %d factory preset(s) for %s",
|
||||
installed, ch.value)
|
||||
ir_installed = self.presets.install_factory_irs(overwrite=False)
|
||||
if ir_installed:
|
||||
logger.info("Installed %d factory cab IR(s)", ir_installed)
|
||||
|
||||
+16
-4
@@ -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,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):
|
||||
|
||||
Reference in New Issue
Block a user