This commit is contained in:
tsi-billypom 2025-03-31 11:22:53 -04:00
parent 50c54c709e
commit a115a3c423
3 changed files with 40 additions and 45 deletions

View File

@ -4,14 +4,7 @@ from utils import FFTAnalyser
class AudioVisualizer(QtWidgets.QWidget):
"""_Audio Visualizer component_
Args:
QtWidgets (_type_): _description_
Returns:
_type_: _description_
"""
"""Audio Visualizer component"""
def __init__(self, media_player, x_resolution):
super().__init__()
@ -28,14 +21,13 @@ class AudioVisualizer(QtWidgets.QWidget):
# Generate logarithmic frequency scale (20Hz - 20kHz)
self.min_freq = 20
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
Args:
num_ticks (int): Approximate number of ticks to display
Returns:
list: List of tuples with (position, label) for each tick
"""

51
main.py
View File

@ -12,7 +12,6 @@ from mutagen.id3._frames import APIC
from configparser import ConfigParser
from pathlib import Path
from appdirs import user_config_dir
from numpy import array as nparray
from logging import debug, error, warning, basicConfig, INFO, DEBUG
from ui import Ui_MainWindow
from PyQt5.QtWidgets import (
@ -163,7 +162,9 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.player: QMediaPlayer = QMediaPlayer() # Audio player object
self.probe: QAudioProbe = QAudioProbe() # Gets audio data
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.clipboard = clipboard
self.tableView.load_qapp(self)
@ -185,30 +186,36 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
# Set fixed size for album art
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
self.PlotWidget.setXRange(0, self.analyzer_x_resolution, padding=0) # x axis range
self.PlotWidget.setYRange(-96, 0, padding=0) # y axis range for decibels (-96dB to 0dB)
self.PlotWidget.setLogMode(x=False, y=False) # Logarithmic x-axis for frequency display
# Make sure PlotWidget doesn't exceed album art height
# Adjust to leave room for playback controls
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.showGrid(x=True, y=True)
# Performance optimizations
self.PlotWidget.setAntialiasing(False)
self.PlotWidget.setDownsampling(auto=True, mode='peak')
self.PlotWidget.setDownsampling(auto=True, mode="peak")
self.PlotWidget.setClipToView(True)
# Add tick marks for common decibel values (expanded range)
y_ticks = [(-84, '-84dB'), (-60, '-60dB'),
(-36, '-36dB'), (-12, '-12dB'), (0, '0dB')]
self.PlotWidget.getAxis('left').setTicks([y_ticks])
y_ticks = [
(-84, "-84dB"),
(-60, "-60dB"),
(-36, "-36dB"),
(-12, "-12dB"),
(0, "0dB"),
]
self.PlotWidget.getAxis("left").setTicks([y_ticks])
# Add frequency ticks on x-axis
freq_ticks = self.audio_visualizer.get_frequency_ticks()
self.PlotWidget.getAxis('bottom').setTicks([freq_ticks])
# Display grid for better readability
self.PlotWidget.showGrid(x=True, y=True)
self.PlotWidget.getAxis("bottom").setTicks([freq_ticks])
# Connections
self.playbackSlider.sliderReleased.connect(
@ -228,10 +235,8 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.actionExportPlaylist.triggered.connect(self.export_playlist)
# EDIT MENU
self.actionPreferences.triggered.connect(self.open_preferences)
# VIEW MENU
self.actionPreferences.triggered.connect(
self.open_preferences
) # Open preferences menu
# QUICK ACTIONS MENU
self.actionScanLibraries.triggered.connect(self.scan_libraries)
@ -448,9 +453,11 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.audio_visualizer._plot_item = self.PlotWidget.plot(
self.audio_visualizer._x_data, # We'll keep using indices for drawing
y,
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
fillBrush=mkBrush("b")
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
fillBrush=mkBrush("b"),
)
# else:
# self.audio_visualizer._plot_item.setData(self.audio_visualizer._x_data, y)

View File

@ -79,12 +79,8 @@ class FFTAnalyser(QtCore.QThread):
# Logarithmic frequency scaling
min_freq = np.min(freq[freq > 0]) # minimum positive frequency
# 20hz
# print('min')
# print(min_freq * .05 * self.song.frame_rate)
max_freq = np.max(freq) # maximum frequency
# 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)
point_samples = []
@ -109,7 +105,7 @@ class FFTAnalyser(QtCore.QThread):
)
# 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
for n, amp in enumerate(point_samples):
# amp *= 2