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_Dirty_A2.nam # 295 KB — Rock crunch
|
||||||
│ ├── Orange_Rocker30_Natural_A2.nam # 289 KB — Clean edge
|
│ ├── Orange_Rocker30_Natural_A2.nam # 289 KB — Clean edge
|
||||||
│ ├── Fender_Bassman_Dimed_A2.nam # 289 KB — Blues/rock breakup
|
│ ├── 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_Bright_A2.nam # 287 KB — Classic rock
|
||||||
│ ├── Hiwatt_DR103_Cornish_A2.nam # 288 KB — Boosted classic rock
|
│ ├── Hiwatt_DR103_Cornish_A2.nam # 288 KB — Boosted classic rock
|
||||||
│ ├── Supro_Black_Magick_M3_A2.nam # 288 KB — Garage/blues
|
│ ├── 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.nam_host import NAMHost
|
||||||
from src.dsp.ir_loader import IRLoader
|
from src.dsp.ir_loader import IRLoader
|
||||||
from src.presets.manager import PresetManager
|
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.midi.handler import MIDIHandler
|
||||||
from src.ui.footswitch import FootswitchController, FootSwitch, SwitchAction
|
from src.ui.footswitch import FootswitchController, FootSwitch, SwitchAction
|
||||||
from src.ui.leds import LEDController, LEDDriver, LEDConfig, LEDPattern
|
from src.ui.leds import LEDController, LEDDriver, LEDConfig, LEDPattern
|
||||||
@@ -170,11 +170,15 @@ class PedalApp:
|
|||||||
audio_pipeline=self.pipeline,
|
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):
|
if pcfg.get("install_factory", True):
|
||||||
installed = self.presets.install_factory_presets(overwrite=False)
|
for ch in Channel:
|
||||||
|
installed = self.presets.install_factory_presets(
|
||||||
|
overwrite=False, channel=ch,
|
||||||
|
)
|
||||||
if installed:
|
if installed:
|
||||||
logger.info("Installed %d factory preset(s)", installed)
|
logger.info("Installed %d factory preset(s) for %s",
|
||||||
|
installed, ch.value)
|
||||||
ir_installed = self.presets.install_factory_irs(overwrite=False)
|
ir_installed = self.presets.install_factory_irs(overwrite=False)
|
||||||
if ir_installed:
|
if ir_installed:
|
||||||
logger.info("Installed %d factory cab IR(s)", 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:
|
channel: Channel = Channel.GUITAR) -> int:
|
||||||
"""Install bundled factory presets into the preset store.
|
"""Install bundled factory presets into the preset store.
|
||||||
|
|
||||||
Scans ``FACTORY_PRESET_DIR`` for ``bank_*/preset_*.json`` files
|
Scans the channel-specific subdirectory of ``FACTORY_PRESET_DIR``
|
||||||
and copies them into the user preset store.
|
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:
|
Args:
|
||||||
overwrite: If True, overwrite existing presets at the same
|
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)
|
logger.warning("Factory preset directory not found: %s", FACTORY_PRESET_DIR)
|
||||||
return 0
|
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
|
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
|
# Derive (bank, program) from file path
|
||||||
bank_dir = src.parent
|
bank_dir = src.parent
|
||||||
try:
|
try:
|
||||||
@@ -635,7 +647,7 @@ class PresetManager:
|
|||||||
|
|
||||||
if count:
|
if count:
|
||||||
self._dirty = True
|
self._dirty = True
|
||||||
logger.info("Installed %d factory presets", count)
|
logger.info("Installed %d factory presets for %s", count, channel.value)
|
||||||
return count
|
return count
|
||||||
|
|
||||||
def install_factory_irs(self, overwrite: bool = False) -> int:
|
def install_factory_irs(self, overwrite: bool = False) -> int:
|
||||||
|
|||||||
@@ -8,9 +8,16 @@ from typing import Optional
|
|||||||
|
|
||||||
|
|
||||||
class Channel(enum.StrEnum):
|
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"
|
GUITAR = "guitar"
|
||||||
BASS = "bass"
|
BASS = "bass"
|
||||||
|
KEYS = "keys"
|
||||||
|
VOCALS = "vocals"
|
||||||
|
BACKING_TRACKS = "backing_tracks"
|
||||||
|
|
||||||
|
|
||||||
class FXType(enum.StrEnum):
|
class FXType(enum.StrEnum):
|
||||||
|
|||||||
Reference in New Issue
Block a user