awacke1's picture
Update app.py
8519f44 verified
raw
history blame
3.49 kB
import streamlit as st
import numpy as np
from pydub import AudioSegment
from pydub.generators import Sine
import simpleaudio as sa
import time
# Constants
KEYS = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
OCTAVES = [3, 4, 5]
BLUES_PROGRESSIONS = [
['I', 'I', 'I', 'I', 'IV', 'IV', 'I', 'I', 'V', 'IV', 'I', 'V'],
['I', 'IV', 'I', 'I', 'IV', 'IV', 'I', 'I', 'V', 'IV', 'I', 'V'],
['I', 'I', 'I', 'I', 'IV', 'IV', 'I', 'I', 'V', 'V', 'I', 'V'],
['I', 'I', 'I', 'I', 'IV', 'IV', 'I', 'I', 'V', 'IV', 'I', 'I'],
['I', 'IV', 'I', 'V', 'IV', 'IV', 'I', 'V', 'IV', 'IV', 'I', 'V'],
]
def note_to_freq(note):
octave = int(note[-1])
key_index = KEYS.index(note[:-1])
return 440 * (2 ** ((key_index - 9) / 12 + (octave - 4)))
def get_chord_notes(root, chord_type):
root_index = KEYS.index(root)
if chord_type == 'I':
intervals = [0, 4, 7]
elif chord_type == 'IV':
intervals = [5, 9, 0]
elif chord_type == 'V':
intervals = [7, 11, 2]
else:
intervals = [0, 4, 7]
return [KEYS[(root_index + interval) % len(KEYS)] for interval in intervals]
def create_tone(freq, duration_ms):
return Sine(freq).to_audio_segment(duration=duration_ms)
def play_arpeggio(root, chord_type, tempo):
chord_notes = get_chord_notes(root, chord_type)
duration_ms = int(60 / tempo * 250) # 16th notes
arpeggio = AudioSegment.silent(duration=1)
for note in chord_notes:
freq = note_to_freq(f"{note}4")
tone = create_tone(freq, duration_ms)
arpeggio = arpeggio.overlay(tone)
play_obj = sa.play_buffer(
arpeggio.raw_data,
num_channels=arpeggio.channels,
bytes_per_sample=arpeggio.sample_width,
sample_rate=arpeggio.frame_rate
)
play_obj.wait_done()
def main():
st.title("12-Bar Blues Arpeggio Game")
# Sidebar for controls
st.sidebar.header("Controls")
root_key = st.sidebar.selectbox("Select Root Key", KEYS)
tempo = st.sidebar.slider("Tempo (BPM)", 60, 240, 120)
# Main area
if 'blues_progression' not in st.session_state:
st.session_state.blues_progression = BLUES_PROGRESSIONS[0]
if 'current_bar' not in st.session_state:
st.session_state.current_bar = 0
if 'chord_history' not in st.session_state:
st.session_state.chord_history = []
# Display current progression
st.write("Current 12-Bar Blues Progression:")
progression_display = " ".join([f"**{chord}**" if i == st.session_state.current_bar else chord
for i, chord in enumerate(st.session_state.blues_progression)])
st.markdown(progression_display)
# Play/Stop button
if st.button("Play/Stop 12-Bar Blues"):
for i, chord in enumerate(st.session_state.blues_progression):
st.session_state.current_bar = i
play_arpeggio(root_key, chord, tempo)
st.session_state.chord_history.append(f"{root_key}{chord}")
st.session_state.chord_history = st.session_state.chord_history[-12:]
st.experimental_rerun()
# Randomize button
if st.button("Randomize Progression"):
st.session_state.blues_progression = BLUES_PROGRESSIONS[np.random.randint(len(BLUES_PROGRESSIONS))]
st.experimental_rerun()
# Display chord history
st.write("Chord History:")
st.write(" ".join(st.session_state.chord_history))
if __name__ == "__main__":
main()