File size: 2,814 Bytes
a0816dc
a5ca18c
 
 
a0816dc
a5ca18c
 
 
 
 
 
a0816dc
a5ca18c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a0816dc
a5ca18c
 
 
 
 
 
 
 
 
 
 
a0816dc
a5ca18c
 
 
a0816dc
a5ca18c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a0816dc
a5ca18c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import streamlit as st
import pandas as pd
import numpy as np
from catboost import CatBoostRegressor

# Page 
st.set_page_config(
    page_title="BPM Predictor",
    page_icon="🎵",
    layout="centered"
)

# Feature Engineering 
def create_features(df):
    df = df.copy()
    # Energy - Rhythm
    df['Energy_x_Rhythm'] = df['Energy'] * df['RhythmScore']
    df['Energy_x_Loudness'] = df['Energy'] * df['AudioLoudness']
    df['Mood_x_Rhythm'] = df['MoodScore'] * df['RhythmScore']
    # Ratios
    df['Inst_Vocal_Ratio'] = df['InstrumentalScore'] / (df['VocalContent'] + 1)
    df['Loudness_Energy_Ratio'] = df['AudioLoudness'] / (df['Energy'] + 1)
    # milliseconds to minutes 
    df['Duration_Min'] = df['TrackDurationMs'] / 60000
    # Squared for importance
    df['Energy_Squared'] = df['Energy'] ** 2
    df['Rhythm_Squared'] = df['RhythmScore'] ** 2
    
    return df

# Load Model 
@st.cache_resource
def load_model():
    model = CatBoostRegressor()
    model.load_model("src/catboost_model.cbm")
    return model
try:
    model = load_model()
except Exception as e:
    st.error(f"Error loading model. Make sure 'catboost_model.cbm' is uploaded. Error: {e}")
    st.stop()

# UI 
st.title("🎵 Song BPM Predictor")
st.write("Enter the audio features of a song to predict its Beats Per Minute (BPM).")

# User Inputs 
with st.form("prediction_form"):
    st.subheader("Audio Features")
    
    col1, col2 = st.columns(2)
    with col1:
        track_duration = st.number_input("Track Duration (ms)", min_value=10000, max_value=1000000, value=200000, step=1000, help="Length of the song in milliseconds")
        energy = st.slider("Energy", 0.0, 1.0, 0.5)
        rhythm = st.slider("Rhythm Score", 0.0, 1.0, 0.5)
        loudness = st.slider("Audio Loudness (dB)", -60.0, 0.0, -10.0)
        vocal = st.slider("Vocal Content", 0.0, 1.0, 0.5)
    with col2:
        acoustic = st.slider("Acoustic Quality", 0.0, 1.0, 0.5)
        instrumental = st.slider("Instrumental Score", 0.0, 1.0, 0.5)
        live = st.slider("Live Performance Likelihood", 0.0, 1.0, 0.5)
        mood = st.slider("Mood Score", 0.0, 1.0, 0.5)
    submitted = st.form_submit_button("Predict BPM 🚀")

# Prediction 
if submitted:
    input_data = pd.DataFrame({
        'RhythmScore': [rhythm],
        'AudioLoudness': [loudness],
        'VocalContent': [vocal],
        'AcousticQuality': [acoustic],
        'InstrumentalScore': [instrumental],
        'LivePerformanceLikelihood': [live],
        'MoodScore': [mood],
        'TrackDurationMs': [track_duration],
        'Energy': [energy]})
    
    processed_data = create_features(input_data)
    
    prediction = model.predict(processed_data)[0]
    
    st.success(f"Predicted Tempo: **{prediction:.2f} BPM**")
    
    st.progress(min(prediction / 200, 1.0))