This commit is contained in:
2025-07-14 22:52:15 +03:00
parent f1343ea200
commit 96de65cde0
9 changed files with 174 additions and 25 deletions

View File

@ -1,6 +1,6 @@
// custom build and feature flags
#ifdef DEBUG
#define OPENGL_DEBUG 1
#define OPENGL_DEBUG 0
#define FULLSCREEN 0
#define DESPERATE 0
#define BREAK_COMPATIBILITY 0
@ -29,6 +29,7 @@
#include "shaders/post.inl"
#endif
#include "fft.h"
#pragma data_seg(".pids")
// static allocation saves a few bytes
@ -74,13 +75,13 @@ int __cdecl main(int argc, char* argv[])
#if POST_PASS
pidPost = ((PFNGLCREATESHADERPROGRAMVPROC)wglGetProcAddress("glCreateShaderProgramv"))(GL_FRAGMENT_SHADER, 1, &post_frag);
#endif
#ifdef SU_LOAD_GMDLS
su_load_gmdls();
#endif // SU_LOAD_GMDLS
// initialize sound
#ifndef EDITOR_CONTROLS
#if USE_AUDIO
LPDIRECTSOUND direct_sound;
LPDIRECTSOUNDBUFFER direct_sound_buffer;
DirectSoundCreate(0, &direct_sound, 0);
@ -91,6 +92,7 @@ int __cdecl main(int argc, char* argv[])
LPVOID p1;
DWORD l1;
IDirectSoundBuffer_Lock(direct_sound_buffer, 0, SU_LENGTH_IN_SAMPLES * SU_CHANNEL_COUNT * SU_SAMPLE_SIZE, &p1, &l1, NULL, NULL, 0);
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)su_render_song, p1, 0, 0);
#endif
@ -108,13 +110,26 @@ int __cdecl main(int argc, char* argv[])
long playCursor = 0;
long lastPlayCursor = -1;
// main loop
volatile float maximum = 0.0; // Helper variable to calculate maximum fft output for normalization
// Unlock buffer for next use
IDirectSoundBuffer_Unlock(direct_sound_buffer, p1, SU_LENGTH_IN_SAMPLES * SU_CHANNEL_COUNT * SU_SAMPLE_SIZE, NULL, NULL);
// Play sound
direct_sound_buffer->Play(0, 0, 0);
static float syncs[1 + SU_NUMSYNCS];
// Init FFT
init_hamming_window();
// FFT buffers
static float fft_input[FFT_SIZE];
static float fft_output[FFT_SIZE / 2]; // Magnitudes
static float fft_uniform[FFT_SIZE / 4];
do
{
direct_sound_buffer->GetCurrentPosition((DWORD*)&playCursor, NULL);
float syncs[1 + SU_NUMSYNCS];
#if !(DESPERATE)
// do minimal message handling so windows doesn't kill your application
@ -144,7 +159,39 @@ int __cdecl main(int argc, char* argv[])
#endif
syncs[0] = (float)playCursor / (2 * sizeof(SUsample));
/******************
* FFT
*******************/
LPVOID audio_ptr = NULL;
DWORD audio_size = 0;
// Read audio
HRESULT hr = IDirectSoundBuffer_Lock(direct_sound_buffer, 0, FFT_SIZE * sizeof(SUsample), &audio_ptr, &audio_size, NULL, NULL, DSBLOCK_FROMWRITECURSOR);
if (SUCCEEDED(hr) && audio_ptr) {
SUsample* samples = (SUsample*)audio_ptr;
for (int i = 0; i < FFT_SIZE; ++i) {
fft_input[i] = (float)samples[i];
}
IDirectSoundBuffer_Unlock(direct_sound_buffer, audio_ptr, audio_size, NULL, 0);
}
// Calculate FFT
compute_fft(fft_input, fft_output);
// Normalize output
for (int i = 0; i < (FFT_SIZE / 2); i++)
{
maximum = max(fft_output[i], maximum);
fft_output[i] = fft_output[i] / maximum;
if (i < (FFT_SIZE / 4)) // Limit uniform fft size. High frequencys contain nothing interesing.
{
fft_uniform[i] = fft_output[i];
}
}
syncs[0] = (float)playCursor / (2 * sizeof(SUsample));
for (int i = 0; i < SU_NUMSYNCS; ++i)
{
@ -153,6 +200,7 @@ int __cdecl main(int argc, char* argv[])
PFNGLUNIFORM1FVPROC glUniform1fvProc = ((PFNGLUNIFORM1FVPROC)wglGetProcAddress("glUniform1fv"));
glUniform1fvProc(0, SU_NUMSYNCS + 1, syncs);
glUniform1fvProc(8, FFT_SIZE / 4, fft_uniform);
glRects(-1, -1, 1, 1);