bass-transcribelisted
Install: claude install-skill PerIPan/music-workflow-skills
# Bass Transcribe — played take → MIDI / Live clip / chart
Default is the offline **CREPE** pipeline (validated: CREPE `full`+viterbi beats pyin on
bass and vocals). For in-Live plugin options (NeuralNote, Jam Origin) read
`references/realtime-options.md`.
## 1. Get the audio
- **User points at a file** — wav/mp3/aiff of the take. Mono preferred; DI cleaner than mic.
- **Record in Live** — audio track, arm, record the take. MCP **cannot export audio**:
the user does File → Export, or point at the raw recording under the Set's
`Samples/Recorded/` folder.
- Ask for (or detect) the take's **BPM** if the output will go into a Live clip.
## 2. Default pipeline — CREPE → MIDI
```python
import crepe, librosa, numpy as np, pretty_midi
y, sr = librosa.load(AUDIO, sr=16000, mono=True)
time, freq, conf, _ = crepe.predict(y, sr, model_capacity='full', viterbi=True, step_size=10)
CONF, MIN_LEN, GAP = 0.55, 0.08, 0.05 # confidence gate, min note s, merge gap s
midi_f = 69 + 12*np.log2(freq/440.0)
notes, cur = [], None
for t, m, c in zip(time, midi_f, conf):
p = int(round(m)) if c >= CONF and np.isfinite(m) else None
if cur and p == cur['p'] and t - cur['end'] <= GAP:
cur['end'] = t
else:
if cur and cur['end'] - cur['start'] >= MIN_LEN:
notes.append(cur)
cur = {'p': p, 'start': t, 'end': t} if p is not None else None
if cur and cur['end'] - cur['start'] >= MIN_LEN:
notes.append(cur)
pm = pretty_midi.PrettyMIDI()
inst = pretty