this repo has no description
0
fork

Configure Feed

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

GPT5-high pass 4: spectral whitening pt2

alice 1fa0a86b 7164a4dd

+163 -9
+4 -1
src/api.h
··· 910 910 1, \ 911 911 0, \ 912 912 double, \ 913 - tic_mem*, s32 bin) 913 + tic_mem*, s32 bin) \ 914 + \ 915 + \ 916 + 914 917 915 918 #define TIC_API_DEF(name, _, __, ___, ____, _____, ret, ...) ret tic_api_##name(__VA_ARGS__); 916 919 TIC_API_LIST(TIC_API_DEF)
+76
src/api/luaapi.c
··· 1705 1705 return 0; 1706 1706 } 1707 1707 1708 + static s32 lua_vqtw(lua_State* lua) 1709 + { 1710 + tic_core* core = getLuaCore(lua); 1711 + tic_mem* tic = (tic_mem*)core; 1712 + s32 top = lua_gettop(lua); 1713 + 1714 + if (top >= 1) 1715 + { 1716 + s32 bin = getLuaNumber(lua, 1); 1717 + extern double tic_api_vqtw(tic_mem*, s32); 1718 + lua_pushnumber(lua, tic_api_vqtw(tic, bin)); 1719 + return 1; 1720 + } 1721 + 1722 + luaL_error(lua, "invalid params, vqtw(bin)\n"); 1723 + return 0; 1724 + } 1725 + 1726 + static s32 lua_vqtsw(lua_State* lua) 1727 + { 1728 + tic_core* core = getLuaCore(lua); 1729 + tic_mem* tic = (tic_mem*)core; 1730 + s32 top = lua_gettop(lua); 1731 + 1732 + if (top >= 1) 1733 + { 1734 + s32 bin = getLuaNumber(lua, 1); 1735 + extern double tic_api_vqtsw(tic_mem*, s32); 1736 + lua_pushnumber(lua, tic_api_vqtsw(tic, bin)); 1737 + return 1; 1738 + } 1739 + 1740 + luaL_error(lua, "invalid params, vqtsw(bin)\n"); 1741 + return 0; 1742 + } 1743 + 1744 + static s32 lua_vqtrw(lua_State* lua) 1745 + { 1746 + tic_core* core = getLuaCore(lua); 1747 + tic_mem* tic = (tic_mem*)core; 1748 + s32 top = lua_gettop(lua); 1749 + 1750 + if (top >= 1) 1751 + { 1752 + s32 bin = getLuaNumber(lua, 1); 1753 + extern double tic_api_vqtrw(tic_mem*, s32); 1754 + lua_pushnumber(lua, tic_api_vqtrw(tic, bin)); 1755 + return 1; 1756 + } 1757 + 1758 + luaL_error(lua, "invalid params, vqtrw(bin)\n"); 1759 + return 0; 1760 + } 1761 + 1762 + static s32 lua_vqtrsw(lua_State* lua) 1763 + { 1764 + tic_core* core = getLuaCore(lua); 1765 + tic_mem* tic = (tic_mem*)core; 1766 + s32 top = lua_gettop(lua); 1767 + 1768 + if (top >= 1) 1769 + { 1770 + s32 bin = getLuaNumber(lua, 1); 1771 + extern double tic_api_vqtrsw(tic_mem*, s32); 1772 + lua_pushnumber(lua, tic_api_vqtrsw(tic, bin)); 1773 + return 1; 1774 + } 1775 + 1776 + luaL_error(lua, "invalid params, vqtrsw(bin)\n"); 1777 + return 0; 1778 + } 1779 + 1708 1780 1709 1781 static int lua_dofile(lua_State *lua) 1710 1782 { ··· 1752 1824 #if defined(BUILD_DEPRECATED) 1753 1825 {(lua_CFunction)lua_textri, "textri"}, 1754 1826 #endif 1827 + {(lua_CFunction)lua_vqtw, "vqtw"}, 1828 + {(lua_CFunction)lua_vqtsw, "vqtsw"}, 1829 + {(lua_CFunction)lua_vqtrw, "vqtrw"}, 1830 + {(lua_CFunction)lua_vqtrsw, "vqtrsw"}, 1755 1831 }; 1756 1832 1757 1833 for (s32 i = 0; i < COUNT_OF(ApiItems); i++)
+67 -8
src/ext/vqt.c
··· 282 282 VQT_ApplyKernels(fftReal, fftImag); 283 283 clock_t kernelEnd = clock(); 284 284 285 - // Optional spectral whitening to flatten spectral envelope for clearer peaks 285 + // Spectral whitening: produce whitened copy into vqtWhiteData (raw vqtData remains unmodified) 286 286 #if VQT_SPECTRAL_WHITENING_ENABLED 287 287 { 288 288 const float eps = VQT_WHITENING_EPS; ··· 295 295 float logM[VQT_BINS]; 296 296 float env[VQT_BINS]; 297 297 298 - // Log domain magnitudes 299 298 for (int i = 0; i < VQT_BINS; i++) 300 299 { 301 300 float m = vqtData[i]; ··· 303 302 logM[i] = logf(m + eps); 304 303 } 305 304 306 - // Smooth spectral envelope with a simple box filter of width 'width' 307 305 for (int i = 0; i < VQT_BINS; i++) 308 306 { 309 307 int start = i - half; ··· 316 314 env[i] = count > 0 ? sum / (float)count : logM[i]; 317 315 } 318 316 319 - // Whiten: ratio in log domain, baseline to 0 (exp(w)-1), mix in amplitude domain 320 317 for (int i = 0; i < VQT_BINS; i++) 321 318 { 322 319 float m = vqtData[i]; 323 320 if (!isfinite(m) || m < 0.0f) m = 0.0f; 324 - float wLog = logM[i] - env[i]; // log(m+eps) - log(env) 325 - float wAmp = expf(wLog) - 1.0f; // = (m+eps)/env - 1 → 0 on flat 321 + float wLog = logM[i] - env[i]; 322 + float wAmp = expf(wLog) - 1.0f; 326 323 if (!isfinite(wAmp) || wAmp < 0.0f) wAmp = 0.0f; 327 324 float mp = (1.0f - alpha) * m + alpha * wAmp; 328 325 if (!isfinite(mp) || mp < 0.0f) mp = 0.0f; 329 - vqtData[i] = mp; 326 + vqtWhiteData[i] = mp; 330 327 } 331 328 } 329 + #else 330 + // Whitening disabled: mirror raw into whitened buffers for A/B APIs 331 + for (int i = 0; i < VQT_BINS; i++) vqtWhiteData[i] = vqtData[i]; 332 332 #endif 333 333 334 334 // Calculate times in milliseconds ··· 381 381 vqtSmoothingData[i] = vqtSmoothingData[i] * VQT_SMOOTHING_FACTOR + 382 382 vqtData[i] * (1.0f - VQT_SMOOTHING_FACTOR); 383 383 } 384 + 385 + // Apply smoothing to whitened data 386 + for (int i = 0; i < VQT_BINS; i++) 387 + { 388 + vqtWhiteSmoothingData[i] = vqtWhiteSmoothingData[i] * VQT_SMOOTHING_FACTOR + 389 + vqtWhiteData[i] * (1.0f - VQT_SMOOTHING_FACTOR); 390 + } 384 391 385 392 // Find peak for normalization 386 393 float currentPeak = 0.0f; ··· 404 411 if (vqtPeakSmoothValue < 0.0001f) 405 412 vqtPeakSmoothValue = 0.0001f; 406 413 407 - // Normalize data 414 + // Normalize raw data 408 415 float normalizer = 1.0f / vqtPeakSmoothValue; 409 416 for (int i = 0; i < VQT_BINS; i++) 410 417 { ··· 416 423 if (!isfinite(vqtNormalizedData[i])) 417 424 vqtNormalizedData[i] = 0.0f; 418 425 } 426 + 427 + // Peak for whitened normalization 428 + float currentWhitePeak = 0.0f; 429 + for (int i = 0; i < VQT_BINS; i++) 430 + { 431 + if (vqtWhiteSmoothingData[i] > currentWhitePeak) 432 + currentWhitePeak = vqtWhiteSmoothingData[i]; 433 + } 434 + if (vqtWhitePeakSmoothValue <= 0.0f) 435 + vqtWhitePeakSmoothValue = 0.1f; 436 + if (currentWhitePeak > vqtWhitePeakSmoothValue) 437 + vqtWhitePeakSmoothValue = currentWhitePeak; 438 + else 439 + vqtWhitePeakSmoothValue = vqtWhitePeakSmoothValue * 0.99f + currentWhitePeak * 0.01f; 440 + if (vqtWhitePeakSmoothValue < 0.0001f) 441 + vqtWhitePeakSmoothValue = 0.0001f; 442 + 443 + // Normalize whitened data 444 + float normalizerW = 1.0f / vqtWhitePeakSmoothValue; 445 + for (int i = 0; i < VQT_BINS; i++) 446 + { 447 + vqtWhiteNormalizedData[i] = vqtWhiteSmoothingData[i] * normalizerW; 448 + if (vqtWhiteNormalizedData[i] > 1.0f) 449 + vqtWhiteNormalizedData[i] = 1.0f; 450 + if (!isfinite(vqtWhiteNormalizedData[i])) 451 + vqtWhiteNormalizedData[i] = 0.0f; 452 + } 419 453 } 420 454 421 455 ··· 484 518 485 519 // Return raw smoothed VQT data (non-normalized) 486 520 return vqtSmoothingData[bin]; 521 + } 522 + 523 + // Whitened VQT API 524 + double tic_api_vqtw(tic_mem* memory, s32 bin) 525 + { 526 + if (bin < 0 || bin >= VQT_BINS) return 0.0; 527 + return vqtWhiteData[bin] / vqtWhitePeakSmoothValue; 528 + } 529 + 530 + double tic_api_vqtsw(tic_mem* memory, s32 bin) 531 + { 532 + if (bin < 0 || bin >= VQT_BINS) return 0.0; 533 + return vqtWhiteNormalizedData[bin]; 534 + } 535 + 536 + double tic_api_vqtrw(tic_mem* memory, s32 bin) 537 + { 538 + if (bin < 0 || bin >= VQT_BINS) return 0.0; 539 + return vqtWhiteData[bin]; 540 + } 541 + 542 + double tic_api_vqtrsw(tic_mem* memory, s32 bin) 543 + { 544 + if (bin < 0 || bin >= VQT_BINS) return 0.0; 545 + return vqtWhiteSmoothingData[bin]; 487 546 } 488 547 489 548 #else // TIC80_FFT_UNSUPPORTED
+10
src/vqtdata.c
··· 19 19 // Array of kernels, one per VQT bin 20 20 VqtKernel vqtKernels[VQT_BINS]; 21 21 22 + // Whitened data arrays 23 + float vqtWhiteData[VQT_BINS]; 24 + float vqtWhiteSmoothingData[VQT_BINS]; 25 + float vqtWhiteNormalizedData[VQT_BINS]; 26 + float vqtWhitePeakSmoothValue = 1.0f; 27 + 22 28 23 29 void VQT_Init(void) 24 30 { ··· 26 32 memset(vqtData, 0, sizeof(vqtData)); 27 33 memset(vqtSmoothingData, 0, sizeof(vqtSmoothingData)); 28 34 memset(vqtNormalizedData, 0, sizeof(vqtNormalizedData)); 35 + memset(vqtWhiteData, 0, sizeof(vqtWhiteData)); 36 + memset(vqtWhiteSmoothingData, 0, sizeof(vqtWhiteSmoothingData)); 37 + memset(vqtWhiteNormalizedData, 0, sizeof(vqtWhiteNormalizedData)); 29 38 30 39 // Initialize peak value 31 40 vqtPeakSmoothValue = 1.0f; 41 + vqtWhitePeakSmoothValue = 1.0f; 32 42 33 43 // Zero kernel pointers 34 44 memset(vqtKernels, 0, sizeof(vqtKernels));
+6
src/vqtdata.h
··· 47 47 // Enable flag (tied to fftEnabled initially) 48 48 extern bool vqtEnabled; 49 49 50 + // Whitened VQT data (dual outputs) 51 + extern float vqtWhiteData[VQT_BINS]; 52 + extern float vqtWhiteSmoothingData[VQT_BINS]; 53 + extern float vqtWhiteNormalizedData[VQT_BINS]; 54 + extern float vqtWhitePeakSmoothValue; 55 + 50 56 // Sparse kernel storage structures 51 57 typedef struct { 52 58 float* real; // Real parts of kernel (sparse)