fuck u sonnet
This commit is contained in:
parent
dcdfeac607
commit
50c54c709e
@ -1,6 +1,7 @@
|
||||
import os
|
||||
import tempfile
|
||||
from logging import debug
|
||||
from PyQt5 import QtWidgets
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractScrollArea,
|
||||
QGraphicsPixmapItem,
|
||||
@ -32,6 +33,9 @@ class AlbumArtGraphicsView(QGraphicsView):
|
||||
self.setAcceptDrops(True)
|
||||
self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
||||
self.setMinimumSize(200, 200)
|
||||
self.setMaximumSize(200, 200) # Also set maximum size to maintain square shape
|
||||
# self.setSizePolicy(Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Fixed) # Keep fixed size
|
||||
self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
self.setSizeAdjustPolicy(QAbstractScrollArea.SizeAdjustPolicy.AdjustIgnored)
|
||||
|
||||
@ -23,9 +23,61 @@ class AudioVisualizer(QtWidgets.QWidget):
|
||||
self.amps = np.array([])
|
||||
self._plot_item = None
|
||||
self._x_data = np.arange(self.x_resolution)
|
||||
self.use_decibels = True # Set to True to use decibel scale
|
||||
|
||||
# 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)
|
||||
|
||||
def get_frequency_ticks(self, num_ticks=10):
|
||||
"""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
|
||||
"""
|
||||
# Standard frequency bands for audio visualization
|
||||
standard_freqs = [20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000]
|
||||
|
||||
# Map frequencies to x-axis positions
|
||||
ticks = []
|
||||
for freq in standard_freqs:
|
||||
# Find closest index to this frequency
|
||||
idx = np.argmin(np.abs(self.frequency_values - freq))
|
||||
# Format labels: Hz for <1000, kHz for >=1000
|
||||
if freq < 1000:
|
||||
label = f"{freq}Hz"
|
||||
else:
|
||||
label = f"{freq/1000:.0f}kHz"
|
||||
ticks.append((idx, label))
|
||||
|
||||
return ticks
|
||||
|
||||
def get_frequencies(self):
|
||||
"""Return the frequency values for x-axis"""
|
||||
return self.frequency_values
|
||||
|
||||
def get_amplitudes(self):
|
||||
return self.amps
|
||||
|
||||
def get_decibels(self):
|
||||
"""Convert amplitude values to decibel scale
|
||||
|
||||
Formula: dB = 20 * log10(amplitude)
|
||||
For normalized amplitude values, this gives a range of approx -96dB to 0dB
|
||||
With a noise floor cutoff at around -96dB (for very small values)
|
||||
"""
|
||||
# Avoid log(0) by adding a small epsilon
|
||||
epsilon = 1e-10
|
||||
amplitudes = np.maximum(self.amps, epsilon)
|
||||
# Convert to decibels (20*log10 is the standard formula for amplitude to dB)
|
||||
db_values = 20 * np.log10(amplitudes)
|
||||
# Clip very low values to have a reasonable floor (e.g. -96dB)
|
||||
db_values = np.maximum(db_values, -96)
|
||||
return db_values
|
||||
|
||||
def set_amplitudes(self, amps):
|
||||
self.amps = np.array(amps)
|
||||
|
||||
48
main.py
48
main.py
@ -182,25 +182,32 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
||||
self.timer.start(100)
|
||||
self.timer.timeout.connect(self.move_slider)
|
||||
|
||||
# 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(0, 1, padding=0) # y axis range
|
||||
self.PlotWidget.setLogMode(False, False)
|
||||
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
|
||||
self.PlotWidget.setMouseEnabled(x=False, y=False)
|
||||
# Performance optimizations
|
||||
self.PlotWidget.setAntialiasing(False)
|
||||
self.PlotWidget.setDownsampling(auto=True, mode='peak')
|
||||
self.PlotWidget.setClipToView(True)
|
||||
# Remove x-axis ticks
|
||||
# ticks = ['20', '31.25', '62.5', '125', '250', '500', '1000', '2000', '4000', '10000', '20000']
|
||||
# self.PlotWidget.getAxis("bottom").setTicks([])
|
||||
# self.PlotWidget.getAxis("bottom").setLabel("") # Remove x-axis label
|
||||
# ticks = nparray([0, 31.25, 62.5, 125, 250, 500, 1000, 2000, 4000, 8000, 15000, 20000])
|
||||
|
||||
# Remove y-axis labels and decorations
|
||||
# self.PlotWidget.getAxis("left").setTicks([[(str(tick), tick) for tick in ticks]])
|
||||
# self.PlotWidget.getAxis("left").setTicks([])
|
||||
# self.PlotWidget.getAxis("left").setLabel("") # Remove y-axis label
|
||||
# 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])
|
||||
|
||||
# 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)
|
||||
|
||||
# Connections
|
||||
@ -424,22 +431,29 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
||||
self.albumGraphicsView.load_album_art(album_art_data)
|
||||
|
||||
def update_audio_visualization(self) -> None:
|
||||
"""Handles upading points on the pyqtgraph visual"""
|
||||
"""Handles updating points on the pyqtgraph visual"""
|
||||
if self.audio_visualizer.use_decibels:
|
||||
# Use decibel values instead of raw amplitudes
|
||||
y = self.audio_visualizer.get_decibels()
|
||||
else:
|
||||
y = self.audio_visualizer.get_amplitudes()
|
||||
|
||||
if len(y) == 0:
|
||||
return
|
||||
|
||||
if self.audio_visualizer._plot_item is None:
|
||||
# if self.audio_visualizer._plot_item is None:
|
||||
# thanks cursor sonnet whatever
|
||||
self.PlotWidget.clear()
|
||||
# Use the actual frequency values for x-axis
|
||||
self.audio_visualizer._plot_item = self.PlotWidget.plot(
|
||||
self.audio_visualizer._x_data,
|
||||
self.audio_visualizer._x_data, # We'll keep using indices for drawing
|
||||
y,
|
||||
pen='b', # Use pen instead of fill for better performance
|
||||
fillLevel=0,
|
||||
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)
|
||||
# else:
|
||||
# self.audio_visualizer._plot_item.setData(self.audio_visualizer._x_data, y)
|
||||
|
||||
def clear_audio_visualization(self) -> None:
|
||||
self.PlotWidget.clear()
|
||||
|
||||
16
ui.py
16
ui.py
@ -25,11 +25,19 @@ class Ui_MainWindow(object):
|
||||
self.verticalLayout.setSpacing(6)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.hLayoutHead = QtWidgets.QHBoxLayout()
|
||||
self.hLayoutHead.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
|
||||
self.hLayoutHead.setObjectName("hLayoutHead")
|
||||
self.vlayoutAlbumArt = QtWidgets.QVBoxLayout()
|
||||
self.vlayoutAlbumArt.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
|
||||
self.vlayoutAlbumArt.setObjectName("vlayoutAlbumArt")
|
||||
self.albumGraphicsView = AlbumArtGraphicsView(self.centralwidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.albumGraphicsView.sizePolicy().hasHeightForWidth())
|
||||
self.albumGraphicsView.setSizePolicy(sizePolicy)
|
||||
self.albumGraphicsView.setMinimumSize(QtCore.QSize(200, 200))
|
||||
self.albumGraphicsView.setMaximumSize(QtCore.QSize(200, 200))
|
||||
self.albumGraphicsView.setObjectName("albumGraphicsView")
|
||||
self.vlayoutAlbumArt.addWidget(self.albumGraphicsView)
|
||||
self.hLayoutHead.addLayout(self.vlayoutAlbumArt)
|
||||
@ -37,8 +45,10 @@ class Ui_MainWindow(object):
|
||||
self.vLayoutSongDetails.setObjectName("vLayoutSongDetails")
|
||||
self.hLayoutHead.addLayout(self.vLayoutSongDetails)
|
||||
self.vLayoutPlaybackVisuals = QtWidgets.QVBoxLayout()
|
||||
self.vLayoutPlaybackVisuals.setSizeConstraint(QtWidgets.QLayout.SetMaximumSize)
|
||||
self.vLayoutPlaybackVisuals.setObjectName("vLayoutPlaybackVisuals")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetMaximumSize)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.playbackSlider = QtWidgets.QSlider(self.centralwidget)
|
||||
self.playbackSlider.setOrientation(QtCore.Qt.Horizontal)
|
||||
@ -91,6 +101,12 @@ class Ui_MainWindow(object):
|
||||
self.horizontalLayout.setStretch(3, 1)
|
||||
self.vLayoutPlaybackVisuals.addLayout(self.horizontalLayout)
|
||||
self.PlotWidget = PlotWidget(self.centralwidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Maximum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.PlotWidget.sizePolicy().hasHeightForWidth())
|
||||
self.PlotWidget.setSizePolicy(sizePolicy)
|
||||
self.PlotWidget.setMaximumSize(QtCore.QSize(16777215, 150))
|
||||
self.PlotWidget.setObjectName("PlotWidget")
|
||||
self.vLayoutPlaybackVisuals.addWidget(self.PlotWidget)
|
||||
self.hLayoutHead.addLayout(self.vLayoutPlaybackVisuals)
|
||||
|
||||
45
ui.ui
45
ui.ui
@ -28,13 +28,35 @@
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="hLayoutHead" stretch="1,0,6">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetFixedSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="vlayoutAlbumArt">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetFixedSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="AlbumArtGraphicsView" name="albumGraphicsView"/>
|
||||
<widget class="AlbumArtGraphicsView" name="albumGraphicsView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@ -43,8 +65,14 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="vLayoutPlaybackVisuals">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMaximumSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="4,0,4,1">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMaximumSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSlider" name="playbackSlider">
|
||||
<property name="orientation">
|
||||
@ -137,7 +165,20 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="PlotWidget" name="PlotWidget" native="true"/>
|
||||
<widget class="PlotWidget" name="PlotWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
||||
@ -56,6 +56,9 @@ class FFTAnalyser(QtCore.QThread):
|
||||
start_index : start_index + sample_count
|
||||
] # samples to analyse
|
||||
|
||||
# Use a window function to reduce spectral leakage
|
||||
window = np.hanning(len(v_sample))
|
||||
v_sample = v_sample * window
|
||||
|
||||
# use FFTs to analyse frequency and amplitudes
|
||||
fourier = np.fft.fft(v_sample)
|
||||
@ -117,11 +120,11 @@ class FFTAnalyser(QtCore.QThread):
|
||||
or self.player.state()
|
||||
in (self.player.PausedState, self.player.StoppedState)
|
||||
):
|
||||
self.points[n] -= self.points[n] / 10 # fade out
|
||||
self.points[n] -= self.points[n] / 5 # fade out
|
||||
elif abs(self.points[n] - amp) > self.visual_delta_threshold:
|
||||
self.points[n] = amp
|
||||
if self.points[n] < 1:
|
||||
self.points[n] = 1e-5
|
||||
self.points[n] = 1e-12
|
||||
|
||||
# interpolate points
|
||||
rs = gaussian_filter1d(self.points, sigma=1.5)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user