this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

GPT5-high pass 1

alice 10b8b2b7 73051097

+45 -29
+3 -4
src/ext/fft.c
··· 23 23 #include "../vqtdata.h" 24 24 25 25 // Shared audio buffer - must be large enough for both FFT and VQT 26 - // FFT needs FFT_SIZE * 2 (2048) samples, VQT needs VQT_FFT_SIZE samples 27 - #define AUDIO_BUFFER_SIZE (VQT_FFT_SIZE > (FFT_SIZE * 2) ? VQT_FFT_SIZE : (FFT_SIZE * 2)) 28 26 float sampleBuf[AUDIO_BUFFER_SIZE]; 29 27 30 28 void miniaudioLogCallback(void* userData, ma_uint32 level, const char* message) ··· 335 333 #else 336 334 337 335 kiss_fft_cpx out[FFT_SIZE + 1]; 338 - // Align FFT and VQT to start from the same temporal position 339 - kiss_fftr(fftcfg, sampleBuf + AUDIO_BUFFER_SIZE - VQT_FFT_SIZE, out); 336 + // Align FFT and VQT to the same recent audio window 337 + // Use the last 2048 samples for the 2K FFT, not the start of the 8K VQT window 338 + kiss_fftr(fftcfg, sampleBuf + AUDIO_BUFFER_SIZE - (FFT_SIZE * 2), out); 340 339 341 340 float peakValue = fPeakMinValue; 342 341 for (int i = 0; i < FFT_SIZE; i++)
+6 -4
src/ext/vqt.c
··· 17 17 #include <stdio.h> 18 18 #include <time.h> 19 19 20 + // Enable verbose VQT debug prints only for debug builds unless explicitly forced 21 + #if !defined(NDEBUG) && !defined(VQT_DEBUG) 20 22 #define VQT_DEBUG 23 + #endif 21 24 22 25 // FFT configuration for VQT 23 26 static kiss_fftr_cfg vqtFftCfg = NULL; ··· 74 77 // Cleanup 75 78 free(testInput); 76 79 free(testOutput); 77 - free(testCfg); 80 + kiss_fft_free(testCfg); 78 81 } 79 82 80 83 printf("================================\n\n"); ··· 251 254 // Copy audio data from the shared buffer 252 255 // sampleBuf is defined in fft.c as extern 253 256 extern float sampleBuf[]; 254 - // Align FFT and VQT to start from the same temporal position 255 - #define AUDIO_BUFFER_SIZE (VQT_FFT_SIZE > (FFT_SIZE * 2) ? VQT_FFT_SIZE : (FFT_SIZE * 2)) 257 + // Align to the most recent VQT window using centralized AUDIO_BUFFER_SIZE 256 258 memcpy(vqtAudioBuffer, sampleBuf + AUDIO_BUFFER_SIZE - VQT_FFT_SIZE, VQT_FFT_SIZE * sizeof(float)); 257 259 258 260 // Profiling variables ··· 373 375 { 374 376 if (vqtFftCfg) 375 377 { 376 - free(vqtFftCfg); 378 + kiss_fft_free(vqtFftCfg); 377 379 vqtFftCfg = NULL; 378 380 } 379 381
+23 -19
src/ext/vqt_kernel.c
··· 8 8 9 9 #include <stdlib.h> 10 10 #include <string.h> 11 - #include "../ext/kiss_fftr.h" 11 + #include "kiss_fftr.h" 12 12 13 13 // Generate logarithmically spaced center frequencies for musical notes 14 + // Keeps equal-tempered semitone spacing exact (2^(1/12)) without scaling the ladder. 15 + // If the last bin slightly exceeds maxFreq due to floating-point error, adjust the 16 + // base frequency minimally so that the last bin matches maxFreq exactly. 14 17 void VQT_GenerateCenterFrequencies(float* frequencies, int numBins, float minFreq, float maxFreq) 15 18 { 16 - // For musical VQT with 12 bins per octave, we want equal temperament spacing 17 - // Each semitone is a factor of 2^(1/12) ≈ 1.0594631 18 - const float semitone = pow(2.0f, 1.0f / 12.0f); 19 - 20 - for (int i = 0; i < numBins; i++) 19 + const double step = pow(2.0, 1.0 / 12.0); // semitone ratio 20 + const double stepsToTop = (double)(numBins - 1) / 12.0; // octaves to the top bin 21 + 22 + // Compute the ideal top frequency using high precision 23 + double base = (double)minFreq; 24 + double idealTop = base * pow(2.0, stepsToTop); 25 + 26 + // Allow a tiny tolerance for FP error before correcting the base 27 + const double eps = 1e-7; // relative tolerance 28 + if (idealTop > (double)maxFreq * (1.0 + eps)) 21 29 { 22 - // Calculate frequency for each bin based on semitone spacing 23 - frequencies[i] = minFreq * pow(semitone, i); 30 + // Adjust base so that the top bin lands exactly at maxFreq 31 + base = (double)maxFreq / pow(2.0, stepsToTop); 24 32 } 25 - 26 - // Verify we don't exceed maxFreq 27 - if (frequencies[numBins - 1] > maxFreq) 33 + 34 + // Fill frequencies using exact semitone spacing from the (possibly adjusted) base 35 + for (int i = 0; i < numBins; i++) 28 36 { 29 - // Scale down if necessary 30 - float scale = maxFreq / frequencies[numBins - 1]; 31 - for (int i = 0; i < numBins; i++) 32 - { 33 - frequencies[i] *= scale; 34 - } 37 + double f = base * pow(2.0, (double)i / 12.0); 38 + frequencies[i] = (float)f; 35 39 } 36 40 } 37 41 ··· 206 210 free(kernel->indices); 207 211 free(timeKernel); 208 212 free(freqKernel); 209 - free(tempWindow); 213 + // tempWindow was already freed earlier 210 214 return false; 211 215 } 212 216 ··· 283 287 } 284 288 } 285 289 286 - free(fftCfg); 290 + kiss_fft_free(fftCfg); 287 291 free(centerFreqs); 288 292 return success; 289 293 }
+8
src/fftdata.h
··· 1 1 #pragma once 2 2 #include <stdbool.h> 3 + 4 + // FFT configuration 3 5 #define FFT_SIZE 1024 6 + 7 + // For shared audio buffer size, factor in the larger of 8 + // the FFT window (2*FFT_SIZE) and the VQT window (VQT_FFT_SIZE). 9 + // Keep this definition centralized to avoid mismatches. 10 + #include "vqtdata.h" 11 + #define AUDIO_BUFFER_SIZE (VQT_FFT_SIZE > (FFT_SIZE * 2) ? VQT_FFT_SIZE : (FFT_SIZE * 2)) 4 12 extern float fPeakMinValue; 5 13 extern float fPeakSmoothing; 6 14 extern float fPeakSmoothValue;
+5 -2
src/vqtdata.h
··· 5 5 #define VQT_FFT_SIZE 8192 // 8K FFT - optimized variable-Q for responsive visualization, ~5.4 fps 6 6 7 7 // VQT frequency range 8 - #define VQT_MIN_FREQ 20.0f // Sub-bass for electronic music 9 - #define VQT_MAX_FREQ 20480.0f // Nearest note to 20kHz 8 + // Use a musical base note for exact semitone alignment across bins. 9 + // D#0/Eb0 ≈ 19.445 Hz; over 10 octaves (120 semitones) this reaches ≈19.9 kHz. 10 + // This keeps every bin on a real note and fits within the audible band. 11 + #define VQT_MIN_FREQ 19.445f // D#0 / Eb0 base (A4=440) 12 + #define VQT_MAX_FREQ 20480.0f // Upper reference (not used to scale bins) 10 13 11 14 // Smoothing parameters 12 15 #define VQT_SMOOTHING_FACTOR 0.3f // Reduced from 0.7f for more responsive display