From 87137bcd366d5f56bdaa28a4b82ff28c6c95ff3a Mon Sep 17 00:00:00 2001 From: billypom on debian Date: Wed, 2 Apr 2025 20:48:07 -0400 Subject: [PATCH] idk whats going on man --- sines up.mp3 | Bin 0 -> 2309757 bytes utils/fft_analyser.py | 11 ++-- utils/fft_analyzer.py.ai | 117 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 sines up.mp3 create mode 100644 utils/fft_analyzer.py.ai diff --git a/sines up.mp3 b/sines up.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..ab83a26e88b3b85b65b25e989b3a58353dcbcbb0 GIT binary patch literal 2309757 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 points[n] - {amp} > {self.points[n]}') # Set a lower threshold to properly reach zero - if self.points[n] < 1e-2: - self.points[n] = 0 + if self.points[n] < 1: + self.points[n] = 1e-5 - print(self.points) + # print(self.points) # interpolate points rs = gaussian_filter1d(self.points, sigma=2) diff --git a/utils/fft_analyzer.py.ai b/utils/fft_analyzer.py.ai new file mode 100644 index 0000000..53e60ad --- /dev/null +++ b/utils/fft_analyzer.py.ai @@ -0,0 +1,117 @@ +# Credit +# https://github.com/ravenkls/MilkPlayer/blob/master/audio/fft_analyser.py + +import time +from PyQt5 import QtCore +from pydub import AudioSegment +import numpy as np +from scipy.ndimage.filters import gaussian_filter1d +from logging import debug, info + + +class FFTAnalyser(QtCore.QThread): + """Analyses a song using FFTs.""" + + calculatedVisual = QtCore.pyqtSignal(np.ndarray) + calculatedVisualRs = QtCore.pyqtSignal(np.ndarray) + + def __init__(self, player, x_resolution): # noqa: F821 + super().__init__() + self.player = player + self.reset_media() + self.player.currentMediaChanged.connect(self.reset_media) + + self.resolution = x_resolution + # this length is a number, in seconds, of how much audio is sampled to determine the frequencies + # of the audio at a specific point in time + # in this case, it takes 5% of the samples at some point in time + self.sampling_window_length = 0.05 + self.visual_delta_threshold = 1000 + self.sensitivity = 0.2 + + def reset_media(self): + """Resets the media to the currently playing song.""" + audio_file = self.player.currentMedia().canonicalUrl().path() + # if os.name == "nt" and audio_file.startswith("/"): + # audio_file = audio_file[1:] + if audio_file: + try: + self.song = AudioSegment.from_file(audio_file).set_channels(1) + except PermissionError: + self.start_animate = False + else: + self.samples = np.array(self.song.get_array_of_samples()) + + self.max_sample = self.samples.max() + self.points = np.zeros(self.resolution) + self.start_animate = True + else: + self.start_animate = False + + def calculate_amps(self): + """Calculates the amplitudes used for visualising the media.""" + + sample_count = int(self.song.frame_rate * self.sampling_window_length) + start_index = int((self.player.position() / 1000) * self.song.frame_rate) + # samples to analyse + v_sample = self.samples[start_index : start_index + sample_count] + + # 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) + freq = np.fft.fftfreq(fourier.size, d=1/self.song.frame_rate) + amps = np.abs(fourier)[:len(fourier)//2] # Only take positive frequencies + freq = freq[:len(fourier)//2] # Match frequencies to amplitudes + + # Define frequency bands (in Hz) + bands = np.logspace(np.log10(10), np.log10(23000), self.resolution + 1) + point_samples = np.zeros(self.resolution) + + # Calculate average amplitude for each frequency band + for i in range(len(bands) - 1): + mask = (freq >= bands[i]) & (freq < bands[i+1]) + if np.any(mask): + point_samples[i] = np.mean(amps[mask]) + + # Calculate RMS of the sample for dynamic sensitivity + rms = np.sqrt(np.mean(np.square(v_sample))) + rms_ratio = min(0.2, rms / (0.01 * self.max_sample)) # Smooth transition near silence + + # Normalize and apply sensitivity with RMS-based scaling + if np.max(point_samples) > 0: + point_samples = point_samples / np.max(point_samples) + point_samples = point_samples * self.sensitivity * rms_ratio + else: + point_samples = np.zeros(self.resolution) + + # Update visualization points with decay + for n in range(self.resolution): + amp = point_samples[n] + if self.player.state() in (self.player.PausedState, self.player.StoppedState): + self.points[n] *= 0.95 # Fast decay when paused/stopped + elif amp < self.points[n]: + # More aggressive decay for very quiet signals + decay_factor = 0.7 if rms_ratio < 0.1 else 0.9 + self.points[n] = max(amp, self.points[n] * decay_factor) + else: + self.points[n] = amp + + # Apply Gaussian smoothing + rs = gaussian_filter1d(self.points, sigma=1) + + # Emit the smoothed data + self.calculatedVisual.emit(rs) + + def run(self): + """Runs the animate function depending on the song.""" + while True: + if self.start_animate: + try: + self.calculate_amps() + except ValueError: + self.calculatedVisual.emit(np.zeros(self.resolution)) + self.start_animate = False + time.sleep(0.033)