GUI frame

This commit is contained in:
Mikkeli Matlock
2024-04-10 20:22:59 +09:00
parent 0872d30428
commit e88878a1b3
3 changed files with 166 additions and 124 deletions
+7
View File
@@ -0,0 +1,7 @@
f:/ncmr/vocaloid/randomcovers/zorra/zorra_release1.mp3
f:/ncmr/vocaloid/randomcovers/zorra/zorra_release2.mp3
f:/ncmr/vocaloid/randomcovers/zorra/zorra_release4.mp3
f:/ncmr/vocaloid/randomcovers/silti/silti_release1.mp3
f:/ncmr/vocaloid/northwichcase/transparency/rover_release12.mp3
I:/musiikki/[160518] THE IDOLM@STER CINDERELLA GIRLS STARLIGHT MASTER 02 Tulip [320K]/01. Tulip (M@STER VERSION).mp3
I:/musiikki/556t - MELTING POT/01. ココロ.mp3
+36 -124
View File
@@ -1,128 +1,40 @@
import librosa
import numpy as np
import os
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel
from PyQt5.QtCore import Qt
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.cm as cm
from mutagen.mp3 import MP3
from mutagen.easyid3 import EasyID3
def try_mp3_tags(file_path):
try:
# if there is metadata
audio = MP3(file_path, ID3=EasyID3)
return audio
except Exception as e:
print(f"Error reading ID3 tags: {e}")
return None
def read_mp3_tags(file_path):
if (audio := try_mp3_tags(file_path)) is not None:
print(f"File name: {os.path.basename(file_path)}")
print(f"{audio['artist'][0]} - {audio['title'][0]}")
else:
print(f"File name: {os.path.basename(file_path)}")
def analyze_track_librosa(file_path):
# Load the audio file
# y is the audio time series and sr is the sampling rate
y, sr = librosa.load(file_path)
# Calculate the maximum amplitude
# Librosa's load function normalizes the audio to [-1, 1], so we scale it back
max_amplitude = np.max(np.abs(y))
# Average amplitude
avg_amplitude = np.mean(np.abs(y))
# Convert max amplitude to dBFS
max_amplitude_dBFS = librosa.amplitude_to_db([max_amplitude], ref=1.0)
avg_amplitude_dBFS = librosa.amplitude_to_db([avg_amplitude], ref=1.0)
# Calculate RMS in dB
S, phase = librosa.magphase(librosa.stft(y))
rms_stft = librosa.feature.rms(S=S)
rms = librosa.feature.rms(y=y)
avg_power_dBFS_stft = 20 * np.log10(np.mean(rms_stft))
avg_power_dBFS = 20 * np.log10(np.mean(rms))
return max_amplitude_dBFS[0], avg_amplitude_dBFS[0], avg_power_dBFS, avg_power_dBFS_stft
def plot_macro_time_power_graph(file_path):
# Load the audio file
y, sr = librosa.load(file_path, mono=True)
# Define the window and hop length
# 10 seconds window and 1 second hop
window_length = int(sr * 10) # 10 seconds in samples
hop_length = int(sr * 1) # 1 second in samples
# Calculate RMS over the rolling windows
rms = librosa.feature.rms(y=y, frame_length=window_length, hop_length=hop_length)
# Convert frame indices to time
times = librosa.frames_to_time(np.arange(rms.shape[1]), sr=sr, hop_length=hop_length)
# Normalize RMS for color mapping
norm = mcolors.Normalize(vmin=0, vmax=0.4)
# Choose a colormap
cmap = cm.autumn
# Plot
fig, ax = plt.subplots(figsize=(10, 4))
ax.set_ylim(0., 0.4)
for i in range(len(times)-1):
ax.fill_between(times[i:i+2], 0, rms[0][i], color=cmap(norm(rms[0][i])), edgecolor='none')
class AudioDragDropWidget(QWidget):
def __init__(self):
super().__init__()
self.initUI()
# Adding a colorbar to indicate the scale of RMS values
sm = cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
cbar = plt.colorbar(sm, ax=ax, label='RMS Power')
# cbar.ax.set_yticklabels([f"{x-60.0:.0f} dBFS" for x in cbar.get_ticks()]) # Adjust labels to show true dBFS values
def initUI(self):
self.setWindowTitle('Drag and Drop Audio Analysis')
self.setGeometry(100, 100, 400, 200) # x, y, width, height
self.setAcceptDrops(True)
# Layout and label for displaying messages
layout = QVBoxLayout()
self.label = QLabel('Drag and drop an audio file here', self)
self.label.setAlignment(Qt.AlignCenter)
layout.addWidget(self.label)
self.setLayout(layout)
ax.set_ylabel('Power')
ax.set_xlabel('Time')
ax.set_title(f'{os.path.basename(file_path)}')
# plt.ylabel('Power')
# plt.xlabel('Time (s)')
# plt.title(f'{os.path.basename(file_path)}')
plt.show(block=False)
plt.pause(0.001)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
files = [u.toLocalFile() for u in event.mimeData().urls()]
for file_path in files:
self.label.setText(f'File dropped: {file_path}')
# Here, you would call your plot function with the dropped file path
# For example: plot_macro_time_power_graph_colormap(file_path)
break # This example only processes the first dropped file
def find_mp3_files(directory):
mp3_files = []
# Walk through the directory
for root, dirs, files in os.walk(directory):
# Filter and append .mp3 files
for file in files:
if file.endswith(".mp3"):
mp3_files.append(os.path.join(root, file))
return mp3_files
# Replace 'path/to/your/audiofile.mp3' with the path to your audio file
file_path = []
# file_path.append('f:/ncmr/vocaloid/randomcovers/zorra/zorra_release1.mp3')
# file_path.append('f:/ncmr/vocaloid/randomcovers/zorra/zorra_release2.mp3')
file_path.append('f:/ncmr/vocaloid/randomcovers/zorra/zorra_release4.mp3')
# file_path.append('f:/ncmr/vocaloid/randomcovers/silti/silti_release1.mp3')
# file_path.append('f:/ncmr/vocaloid/northwichcase/transparency/rover_release12.mp3')
file_path.append('I:/musiikki/[160518] THE IDOLM@STER CINDERELLA GIRLS STARLIGHT MASTER 02 Tulip [320K]/01. Tulip (M@STER VERSION).mp3')
file_path.append('I:/musiikki/556t - MELTING POT/01. ココロ.mp3')
for file in file_path:
max_amplitude, avg_amplitude, avg_power, avg_power_stft = analyze_track_librosa(file)
read_mp3_tags(file)
print(f"Maximum Amplitude: {max_amplitude:.2f} dBFS")
print(f"Average Amplitude: {avg_amplitude:.2f} dBFS")
print(f"Average Power: {avg_power:.2f} dBFS")
print(f"Average Power (STFT): {avg_power_stft:.2f} dBFS")
plot_macro_time_power_graph(file)
plt.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = AudioDragDropWidget()
ex.show()
sys.exit(app.exec_())
+123
View File
@@ -0,0 +1,123 @@
import librosa
import numpy as np
import os
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.cm as cm
from mutagen.mp3 import MP3
from mutagen.easyid3 import EasyID3
def try_mp3_tags(file_path):
try:
# if there is metadata
audio = MP3(file_path, ID3=EasyID3)
return audio
except Exception as e:
print(f"Error reading ID3 tags: {e}")
return None
def read_mp3_tags(file_path):
if (audio := try_mp3_tags(file_path)) is not None:
print(f"File name: {os.path.basename(file_path)}")
print(f"{audio['artist'][0]} - {audio['title'][0]}")
else:
print(f"File name: {os.path.basename(file_path)}")
def analyze_track_librosa(file_path):
# Load the audio file
# y is the audio time series and sr is the sampling rate
y, sr = librosa.load(file_path)
# Calculate the maximum amplitude
# Librosa's load function normalizes the audio to [-1, 1], so we scale it back
max_amplitude = np.max(np.abs(y))
# Average amplitude
avg_amplitude = np.mean(np.abs(y))
# Convert max amplitude to dBFS
max_amplitude_dBFS = librosa.amplitude_to_db([max_amplitude], ref=1.0)
avg_amplitude_dBFS = librosa.amplitude_to_db([avg_amplitude], ref=1.0)
# Calculate RMS in dB
S, phase = librosa.magphase(librosa.stft(y))
rms_stft = librosa.feature.rms(S=S)
rms = librosa.feature.rms(y=y)
avg_power_dBFS_stft = 20 * np.log10(np.mean(rms_stft))
avg_power_dBFS = 20 * np.log10(np.mean(rms))
return max_amplitude_dBFS[0], avg_amplitude_dBFS[0], avg_power_dBFS, avg_power_dBFS_stft
def plot_macro_time_power_graph(file_path):
# Load the audio file
y, sr = librosa.load(file_path, mono=True)
# Define the window and hop length
# 10 seconds window and 1 second hop
window_length = int(sr * 10) # 10 seconds in samples
hop_length = int(sr * 1) # 1 second in samples
# Calculate RMS over the rolling windows
rms = librosa.feature.rms(y=y, frame_length=window_length, hop_length=hop_length)
# Convert frame indices to time
times = librosa.frames_to_time(np.arange(rms.shape[1]), sr=sr, hop_length=hop_length)
# Normalize RMS for color mapping
norm = mcolors.Normalize(vmin=0, vmax=0.4)
# Choose a colormap
cmap = cm.autumn
# Plot
fig, ax = plt.subplots(figsize=(10, 4))
ax.set_ylim(0., 0.4)
for i in range(len(times)-1):
ax.fill_between(times[i:i+2], 0, rms[0][i], color=cmap(norm(rms[0][i])), edgecolor='none')
# Adding a colorbar to indicate the scale of RMS values
sm = cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
cbar = plt.colorbar(sm, ax=ax, label='RMS Power')
# cbar.ax.set_yticklabels([f"{x-60.0:.0f} dBFS" for x in cbar.get_ticks()]) # Adjust labels to show true dBFS values
ax.set_ylabel('Power')
ax.set_xlabel('Time')
ax.set_title(f'{os.path.basename(file_path)}')
# plt.ylabel('Power')
# plt.xlabel('Time (s)')
# plt.title(f'{os.path.basename(file_path)}')
plt.show(block=False)
plt.pause(0.001)
def find_mp3_files(directory):
mp3_files = []
# Walk through the directory
for root, dirs, files in os.walk(directory):
# Filter and append .mp3 files
for file in files:
if file.endswith(".mp3"):
mp3_files.append(os.path.join(root, file))
return mp3_files
# Replace 'path/to/your/audiofile.mp3' with the path to your audio file
file_path = []
with open('./files.txt', 'r') as f:
for line in f:
if line[0] != '#':
file_path.append(line.strip())
for file in file_path:
max_amplitude, avg_amplitude, avg_power, avg_power_stft = analyze_track_librosa(file)
read_mp3_tags(file)
print(f"Maximum Amplitude: {max_amplitude:.2f} dBFS")
print(f"Average Amplitude: {avg_amplitude:.2f} dBFS")
print(f"Average Power: {avg_power:.2f} dBFS")
print(f"Average Power (STFT): {avg_power_stft:.2f} dBFS")
plot_macro_time_power_graph(file)
plt.show()