Guitar / src /streamlit_app.py
dummydj2633's picture
Update src/streamlit_app.py
5dd19f7 verified
import streamlit as st
import numpy as np
import librosa
import soundfile as sf
import crepe
from fpdf import FPDF
import os
st.set_page_config(page_title="Guitar Tab Generator", layout="centered")
st.title("🎸 Guitar Audio to Tablature Generator")
# Define mapping from string to base note
standard_tuning = {
6: 'E2',
5: 'A2',
4: 'D3',
3: 'G3',
2: 'B3',
1: 'E4',
}
notes = ['C', 'C#', 'D', 'D#', 'E', 'F',
'F#', 'G', 'G#', 'A', 'A#', 'B']
# Convert frequency to note
def freq_to_note(freq):
A4 = 440
if freq == 0:
return "-"
half_steps = round(12 * np.log2(freq / A4))
note_index = (half_steps + 9) % 12
octave = 4 + ((half_steps + 9) // 12)
return notes[note_index] + str(octave)
# Generate fretboard dictionary
def generate_fretboard():
fretboard = {}
for string, base_note in standard_tuning.items():
base_idx = notes.index(base_note[:-1])
octave = int(base_note[-1])
fretboard[string] = []
for fret in range(0, 13): # frets 0-12
n = (base_idx + fret) % 12
o = octave + (base_idx + fret) // 12
fretboard[string].append(notes[n] + str(o))
return fretboard
# Match note to fret
def note_to_fret(note, fretboard):
for string in fretboard:
for fret, n in enumerate(fretboard[string]):
if n == note:
return string, fret
return None, None
# Display tab as strings
def generate_tab(notes_played):
fretboard = generate_fretboard()
tab_lines = {1: "e|", 2: "B|", 3: "G|", 4: "D|", 5: "A|", 6: "E|"}
for note in notes_played:
string, fret = note_to_fret(note, fretboard)
for i in range(6, 0, -1):
if i == string:
tab_lines[i] += f"-{fret}-"
else:
tab_lines[i] += "---"
return "\n".join([tab_lines[i] for i in range(1, 7)][::-1])
# Upload audio
uploaded_file = st.file_uploader("πŸŽ™οΈ Upload a mono guitar recording (WAV, 16kHz recommended)", type=["wav"])
if uploaded_file:
with open("temp_audio.wav", "wb") as f:
f.write(uploaded_file.read())
y, sr = librosa.load("temp_audio.wav", sr=16000, mono=True)
st.info("⏳ Detecting pitch...")
_, frequency, confidence, _ = crepe.predict(y, sr, viterbi=True)
thresholded = [(f, c) for f, c in zip(frequency, confidence) if c > 0.8]
if not thresholded:
st.error("❌ No strong pitch detected. Try a cleaner mono guitar track.")
else:
filtered_freqs = [f for f, c in thresholded[::10]] # reduce to fewer notes
notes_detected = [freq_to_note(f) for f in filtered_freqs]
tab_result = generate_tab(notes_detected)
st.subheader("🎼 Generated Guitar Tablature:")
st.code(tab_result)
# Export as PDF
if st.button("πŸ“„ Export as PDF"):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Courier", size=12)
for line in tab_result.split("\n"):
pdf.cell(200, 10, txt=line, ln=True)
pdf.output("Guitar_Tab.pdf")
with open("Guitar_Tab.pdf", "rb") as f:
st.download_button("Download PDF", f, "Guitar_Tab.pdf")