cleanup
This commit is contained in:
parent
50c54c709e
commit
a115a3c423
@ -4,14 +4,7 @@ from utils import FFTAnalyser
|
|||||||
|
|
||||||
|
|
||||||
class AudioVisualizer(QtWidgets.QWidget):
|
class AudioVisualizer(QtWidgets.QWidget):
|
||||||
"""_Audio Visualizer component_
|
"""Audio Visualizer component"""
|
||||||
|
|
||||||
Args:
|
|
||||||
QtWidgets (_type_): _description_
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
_type_: _description_
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, media_player, x_resolution):
|
def __init__(self, media_player, x_resolution):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@ -28,14 +21,13 @@ class AudioVisualizer(QtWidgets.QWidget):
|
|||||||
# Generate logarithmic frequency scale (20Hz - 20kHz)
|
# Generate logarithmic frequency scale (20Hz - 20kHz)
|
||||||
self.min_freq = 20
|
self.min_freq = 20
|
||||||
self.max_freq = 23000
|
self.max_freq = 23000
|
||||||
self.frequency_values = np.logspace(np.log10(self.min_freq), np.log10(self.max_freq), self.x_resolution)
|
self.frequency_values = np.logspace(
|
||||||
|
np.log10(self.min_freq), np.log10(self.max_freq), self.x_resolution
|
||||||
|
)
|
||||||
|
|
||||||
def get_frequency_ticks(self, num_ticks=10):
|
def get_frequency_ticks(self):
|
||||||
"""Returns frequency ticks for x-axis display
|
"""Returns frequency ticks for x-axis display
|
||||||
|
|
||||||
Args:
|
|
||||||
num_ticks (int): Approximate number of ticks to display
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: List of tuples with (position, label) for each tick
|
list: List of tuples with (position, label) for each tick
|
||||||
"""
|
"""
|
||||||
@ -51,7 +43,7 @@ class AudioVisualizer(QtWidgets.QWidget):
|
|||||||
if freq < 1000:
|
if freq < 1000:
|
||||||
label = f"{freq}Hz"
|
label = f"{freq}Hz"
|
||||||
else:
|
else:
|
||||||
label = f"{freq/1000:.0f}kHz"
|
label = f"{freq / 1000:.0f}kHz"
|
||||||
ticks.append((idx, label))
|
ticks.append((idx, label))
|
||||||
|
|
||||||
return ticks
|
return ticks
|
||||||
@ -71,7 +63,7 @@ class AudioVisualizer(QtWidgets.QWidget):
|
|||||||
With a noise floor cutoff at around -96dB (for very small values)
|
With a noise floor cutoff at around -96dB (for very small values)
|
||||||
"""
|
"""
|
||||||
# Avoid log(0) by adding a small epsilon
|
# Avoid log(0) by adding a small epsilon
|
||||||
epsilon = 1e-10
|
epsilon = 1e-10
|
||||||
amplitudes = np.maximum(self.amps, epsilon)
|
amplitudes = np.maximum(self.amps, epsilon)
|
||||||
# Convert to decibels (20*log10 is the standard formula for amplitude to dB)
|
# Convert to decibels (20*log10 is the standard formula for amplitude to dB)
|
||||||
db_values = 20 * np.log10(amplitudes)
|
db_values = 20 * np.log10(amplitudes)
|
||||||
|
|||||||
53
main.py
53
main.py
@ -12,7 +12,6 @@ from mutagen.id3._frames import APIC
|
|||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from appdirs import user_config_dir
|
from appdirs import user_config_dir
|
||||||
from numpy import array as nparray
|
|
||||||
from logging import debug, error, warning, basicConfig, INFO, DEBUG
|
from logging import debug, error, warning, basicConfig, INFO, DEBUG
|
||||||
from ui import Ui_MainWindow
|
from ui import Ui_MainWindow
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
@ -163,7 +162,9 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.player: QMediaPlayer = QMediaPlayer() # Audio player object
|
self.player: QMediaPlayer = QMediaPlayer() # Audio player object
|
||||||
self.probe: QAudioProbe = QAudioProbe() # Gets audio data
|
self.probe: QAudioProbe = QAudioProbe() # Gets audio data
|
||||||
self.analyzer_x_resolution = 150
|
self.analyzer_x_resolution = 150
|
||||||
self.audio_visualizer: AudioVisualizer = AudioVisualizer(self.player, self.analyzer_x_resolution)
|
self.audio_visualizer: AudioVisualizer = AudioVisualizer(
|
||||||
|
self.player, self.analyzer_x_resolution
|
||||||
|
)
|
||||||
self.timer = QTimer(self) # Audio timing things
|
self.timer = QTimer(self) # Audio timing things
|
||||||
self.clipboard = clipboard
|
self.clipboard = clipboard
|
||||||
self.tableView.load_qapp(self)
|
self.tableView.load_qapp(self)
|
||||||
@ -185,30 +186,36 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
# Set fixed size for album art
|
# Set fixed size for album art
|
||||||
self.albumGraphicsView.setFixedSize(250, 250)
|
self.albumGraphicsView.setFixedSize(250, 250)
|
||||||
|
|
||||||
# Make sure PlotWidget doesn't exceed album art height
|
|
||||||
self.PlotWidget.setFixedHeight(225) # Adjust to leave room for playback controls
|
|
||||||
|
|
||||||
# Graphics plot
|
# Graphics plot
|
||||||
self.PlotWidget.setXRange(0, self.analyzer_x_resolution, padding=0) # x axis range
|
# Make sure PlotWidget doesn't exceed album art height
|
||||||
self.PlotWidget.setYRange(-96, 0, padding=0) # y axis range for decibels (-96dB to 0dB)
|
# Adjust to leave room for playback controls
|
||||||
self.PlotWidget.setLogMode(x=False, y=False) # Logarithmic x-axis for frequency display
|
self.PlotWidget.setFixedHeight(225)
|
||||||
|
# x range
|
||||||
|
self.PlotWidget.setXRange(0, self.analyzer_x_resolution, padding=0)
|
||||||
|
# y axis range for decibals (-96db to 0db)
|
||||||
|
self.PlotWidget.setYRange(-96, 0, padding=0)
|
||||||
|
# Logarithmic x-axis for frequency display
|
||||||
|
self.PlotWidget.setLogMode(x=False, y=False)
|
||||||
self.PlotWidget.setMouseEnabled(x=False, y=False)
|
self.PlotWidget.setMouseEnabled(x=False, y=False)
|
||||||
|
self.PlotWidget.showGrid(x=True, y=True)
|
||||||
# Performance optimizations
|
# Performance optimizations
|
||||||
self.PlotWidget.setAntialiasing(False)
|
self.PlotWidget.setAntialiasing(False)
|
||||||
self.PlotWidget.setDownsampling(auto=True, mode='peak')
|
self.PlotWidget.setDownsampling(auto=True, mode="peak")
|
||||||
self.PlotWidget.setClipToView(True)
|
self.PlotWidget.setClipToView(True)
|
||||||
|
|
||||||
# Add tick marks for common decibel values (expanded range)
|
# Add tick marks for common decibel values (expanded range)
|
||||||
y_ticks = [(-84, '-84dB'), (-60, '-60dB'),
|
y_ticks = [
|
||||||
(-36, '-36dB'), (-12, '-12dB'), (0, '0dB')]
|
(-84, "-84dB"),
|
||||||
self.PlotWidget.getAxis('left').setTicks([y_ticks])
|
(-60, "-60dB"),
|
||||||
|
(-36, "-36dB"),
|
||||||
|
(-12, "-12dB"),
|
||||||
|
(0, "0dB"),
|
||||||
|
]
|
||||||
|
self.PlotWidget.getAxis("left").setTicks([y_ticks])
|
||||||
|
|
||||||
# Add frequency ticks on x-axis
|
# Add frequency ticks on x-axis
|
||||||
freq_ticks = self.audio_visualizer.get_frequency_ticks()
|
freq_ticks = self.audio_visualizer.get_frequency_ticks()
|
||||||
self.PlotWidget.getAxis('bottom').setTicks([freq_ticks])
|
self.PlotWidget.getAxis("bottom").setTicks([freq_ticks])
|
||||||
|
|
||||||
# Display grid for better readability
|
|
||||||
self.PlotWidget.showGrid(x=True, y=True)
|
|
||||||
|
|
||||||
# Connections
|
# Connections
|
||||||
self.playbackSlider.sliderReleased.connect(
|
self.playbackSlider.sliderReleased.connect(
|
||||||
@ -228,10 +235,8 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.actionExportPlaylist.triggered.connect(self.export_playlist)
|
self.actionExportPlaylist.triggered.connect(self.export_playlist)
|
||||||
|
|
||||||
# EDIT MENU
|
# EDIT MENU
|
||||||
|
self.actionPreferences.triggered.connect(self.open_preferences)
|
||||||
# VIEW MENU
|
# VIEW MENU
|
||||||
self.actionPreferences.triggered.connect(
|
|
||||||
self.open_preferences
|
|
||||||
) # Open preferences menu
|
|
||||||
|
|
||||||
# QUICK ACTIONS MENU
|
# QUICK ACTIONS MENU
|
||||||
self.actionScanLibraries.triggered.connect(self.scan_libraries)
|
self.actionScanLibraries.triggered.connect(self.scan_libraries)
|
||||||
@ -447,10 +452,12 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
# Use the actual frequency values for x-axis
|
# Use the actual frequency values for x-axis
|
||||||
self.audio_visualizer._plot_item = self.PlotWidget.plot(
|
self.audio_visualizer._plot_item = self.PlotWidget.plot(
|
||||||
self.audio_visualizer._x_data, # We'll keep using indices for drawing
|
self.audio_visualizer._x_data, # We'll keep using indices for drawing
|
||||||
y,
|
y,
|
||||||
pen='b', # Use pen instead of fill for better performance
|
pen="b", # Use pen instead of fill for better performance
|
||||||
fillLevel=-96 if self.audio_visualizer.use_decibels else 0, # Fill from -96dB for decibel scale
|
fillLevel=-96
|
||||||
fillBrush=mkBrush("b")
|
if self.audio_visualizer.use_decibels
|
||||||
|
else 0, # Fill from -96dB for decibel scale
|
||||||
|
fillBrush=mkBrush("b"),
|
||||||
)
|
)
|
||||||
# else:
|
# else:
|
||||||
# self.audio_visualizer._plot_item.setData(self.audio_visualizer._x_data, y)
|
# self.audio_visualizer._plot_item.setData(self.audio_visualizer._x_data, y)
|
||||||
|
|||||||
@ -79,12 +79,8 @@ class FFTAnalyser(QtCore.QThread):
|
|||||||
# Logarithmic frequency scaling
|
# Logarithmic frequency scaling
|
||||||
min_freq = np.min(freq[freq > 0]) # minimum positive frequency
|
min_freq = np.min(freq[freq > 0]) # minimum positive frequency
|
||||||
# 20hz
|
# 20hz
|
||||||
# print('min')
|
|
||||||
# print(min_freq * .05 * self.song.frame_rate)
|
|
||||||
max_freq = np.max(freq) # maximum frequency
|
max_freq = np.max(freq) # maximum frequency
|
||||||
# 20khz
|
# 20khz
|
||||||
# print('max')
|
|
||||||
# print(max_freq * .05 * self.song.frame_rate)
|
|
||||||
log_freqs = np.logspace(np.log10(min_freq), np.log10(max_freq), self.resolution)
|
log_freqs = np.logspace(np.log10(min_freq), np.log10(max_freq), self.resolution)
|
||||||
|
|
||||||
point_samples = []
|
point_samples = []
|
||||||
@ -92,10 +88,10 @@ class FFTAnalyser(QtCore.QThread):
|
|||||||
if not data.size:
|
if not data.size:
|
||||||
return
|
return
|
||||||
|
|
||||||
#for i, freq in enumerate(np.arange(0, 1, point_range), start=1):
|
# for i, freq in enumerate(np.arange(0, 1, point_range), start=1):
|
||||||
for i, log_freq in enumerate(log_freqs):
|
for i, log_freq in enumerate(log_freqs):
|
||||||
# get the amps which are in between the frequency range
|
# get the amps which are in between the frequency range
|
||||||
#amps = data[(freq - point_range < data[:, 0]) & (data[:, 0] < freq)]
|
# amps = data[(freq - point_range < data[:, 0]) & (data[:, 0] < freq)]
|
||||||
amps = data[(log_freq - point_range < data[:, 0]) & (data[:, 0] < log_freq)]
|
amps = data[(log_freq - point_range < data[:, 0]) & (data[:, 0] < log_freq)]
|
||||||
if not amps.size:
|
if not amps.size:
|
||||||
point_samples.append(0)
|
point_samples.append(0)
|
||||||
@ -109,7 +105,7 @@ class FFTAnalyser(QtCore.QThread):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Add the point_samples to the self.points array, the reason we have a separate
|
# Add the point_samples to the self.points array, the reason we have a separate
|
||||||
# array (self.bars) is so that we can fade out the previous amplitudes from
|
# array (self.points) is so that we can fade out the previous amplitudes from
|
||||||
# the past
|
# the past
|
||||||
for n, amp in enumerate(point_samples):
|
for n, amp in enumerate(point_samples):
|
||||||
# amp *= 2
|
# amp *= 2
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user