Spaces:
Runtime error
Runtime error
File size: 5,705 Bytes
bb5feba |
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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
#%%
import streamlit as st
import plotly.express as px
import plotly.graph_objects as go
import matplotlib.pyplot as plt
import numpy as np
import librosa
import pandas as pd
from src.st_helper import convert_df, show_readme, get_shift
from src.timbre_analysis import (
spectral_centroid_analysis,
rolloff_frequency_analysis,
spectral_bandwidth_analysis,
harmonic_percussive_source_separation
)
st.title("Timbre Analysis")
#%% 頁面說明
# show_readme("docs/6-Timbre Analysis.md")
#%% 上傳檔案區塊
with st.expander("上傳檔案(Upload Files)"):
file = st.file_uploader("Upload your music library", type=["mp3", "wav", "ogg"])
if file is not None:
st.audio(file, format="audio/ogg")
st.subheader("File information")
st.write(f"File name: `{file.name}`", )
st.write(f"File type: `{file.type}`")
st.write(f"File size: `{file.size}`")
# 載入音檔
y, sr = librosa.load(file, sr=44100)
st.write(f"Sample rate: `{sr}`")
duration = float(np.round(len(y)/sr-0.005, 2)) # 時間長度,取小數點後2位,向下取整避免超過音檔長度
st.write(f"Duration(s): `{duration}`")
y_all = y
#%%
if file is not None:
### Start of 選擇聲音片段 ###
with st.expander("選擇聲音片段(Select a segment of the audio)"):
# 建立一個滑桿,可以選擇聲音片段,使用時間長度為單位
start_time, end_time = st.slider("Select a segment of the audio",
0.0, duration,
(st.session_state.start_time, duration),
0.01
)
st.session_state.start_time = start_time
st.write(f"Selected segment: `{start_time}` ~ `{end_time}`, duration: `{end_time-start_time}`")
# 根據選擇的聲音片段,取出聲音資料
start_index = int(start_time*sr)
end_index = int(end_time*sr)
y_sub = y_all[start_index:end_index]
# 建立一個y_sub的播放器
st.audio(y_sub, format="audio/ogg", sample_rate=sr)
# 計算y_sub所對應時間的x軸
x_sub = np.arange(len(y_sub))/sr
### End of 選擇聲音片段 ###
tab1, tab2, tab3, tab4 = st.tabs(["Spectral Centroid", "Rolloff Frequency", "Spectral Bandwidth", "Harmonic Percussive Source Separation"])
shift_time, shift_array = get_shift(start_time, end_time) # shift_array為y_sub的時間刻度
# spectral_centroid_analysis
with tab1:
st.subheader("Spectral Centroid Analysis")
fig6_1, ax6_1, centroid_value = spectral_centroid_analysis(y_sub, sr, shift_array)
st.pyplot(fig6_1)
df_centroid = pd.DataFrame(centroid_value.T, columns=["Time(s)", "Centroid"])
df_centroid["Time(s)"] = df_centroid["Time(s)"] + shift_time
st.dataframe(df_centroid, use_container_width=True)
st.download_button(
label="Download spectral centroid data",
data=convert_df(df_centroid),
file_name="centroid.csv",
mime="text/csv",
)
# rolloff_frequency_analysis
with tab2:
st.subheader("Rolloff Frequency Analysis")
roll_percent = st.selectbox("Select rolloff frequency", [0.90, 0.95, 0.99])
fig6_2, ax6_2, rolloff_value = rolloff_frequency_analysis(y_sub, sr, roll_percent=roll_percent, shift_array=shift_array)
st.pyplot(fig6_2)
df_rolloff = pd.DataFrame(rolloff_value.T, columns=["Time(s)", "Rolloff", "Rolloff_min"])
df_rolloff["Time(s)"] = df_rolloff["Time(s)"] + shift_time
st.dataframe(df_rolloff, use_container_width=True)
st.download_button(
label="Download rolloff frequency data",
data=convert_df(df_rolloff),
file_name="rolloff.csv",
mime="text/csv",
)
# spectral_bandwidth_analysis
with tab3:
st.subheader("Spectral Bandwidth Analysis")
fig6_3, ax6_3, bandwidth_value = spectral_bandwidth_analysis(y_sub, sr, shift_array)
st.pyplot(fig6_3)
df_bandwidth = pd.DataFrame(bandwidth_value.T, columns=["Time(s)", "Bandwidth"])
df_bandwidth["Time(s)"] = df_bandwidth["Time(s)"] + shift_time
st.dataframe(df_bandwidth, use_container_width=True)
st.download_button(
label="Download spectral bandwidth data",
data=convert_df(df_bandwidth),
file_name="bandwidth.csv",
mime="text/csv",
)
# harmonic_percussive_source_separation
with tab4:
st.subheader("Harmonic Percussive Source Separation")
fig6_4, ax6_4, (Harmonic_data) = harmonic_percussive_source_separation(y_sub, sr, shift_array)
D, H, P, t = Harmonic_data
st.pyplot(fig6_4)
st.download_button(
label="Download Full power spectrogram data",
data=convert_df(pd.DataFrame(D)),
file_name="Full_power_spectrogram.csv",
use_container_width=True,
)
st.download_button(
label="Download Harmonic power spectrogram data",
data=convert_df(pd.DataFrame(H)),
file_name="Harmonic_power_spectrogram.csv",
use_container_width=True,
)
st.download_button(
label="Download Percussive power spectrogram data",
data=convert_df(pd.DataFrame(P)),
file_name="Percussive_power_spectrogram.csv",
use_container_width=True,
)
st.download_button(
label="Download Time data",
data=convert_df(pd.DataFrame(t+shift_time, columns=["Time(s)"])),
file_name="Time_scale.csv",
use_container_width=True,
) |