|
|
|
@ -19,11 +19,19 @@ |
|
|
|
********************************************************************************************/ |
|
|
|
|
|
|
|
#include "raylib.h" |
|
|
|
|
|
|
|
#include "raymath.h" |
|
|
|
|
|
|
|
#include <math.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <string.h> |
|
|
|
|
|
|
|
#if defined(PLATFORM_DESKTOP) |
|
|
|
#define GLSL_VERSION 330 |
|
|
|
#else // PLATFORM_ANDROID, PLATFORM_WEB |
|
|
|
#define GLSL_VERSION 100 |
|
|
|
#endif |
|
|
|
|
|
|
|
#define MONO 1 |
|
|
|
#define SAMPLE_RATE 44100 |
|
|
|
#define SAMPLE_RATE_F 44100.0f |
|
|
|
@ -77,7 +85,8 @@ int main(void) |
|
|
|
RenderTexture2D bufferA = LoadRenderTexture(screenWidth, screenHeight); |
|
|
|
Vector2 iResolution = { (float)screenWidth, (float)screenHeight }; |
|
|
|
|
|
|
|
Shader shader = LoadShader(NULL, "resources/fft.glsl"); |
|
|
|
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/fft.fs", GLSL_VERSION)); |
|
|
|
|
|
|
|
int iResolutionLocation = GetShaderLocation(shader, "iResolution"); |
|
|
|
int iChannel0Location = GetShaderLocation(shader, "iChannel0"); |
|
|
|
SetShaderValue(shader, iResolutionLocation, &iResolution, SHADER_UNIFORM_VEC2); |
|
|
|
@ -86,6 +95,7 @@ int main(void) |
|
|
|
InitAudioDevice(); |
|
|
|
SetAudioStreamBufferSizeDefault(AUDIO_STREAM_RING_BUFFER_SIZE); |
|
|
|
|
|
|
|
// WARNING: Memory out-of-bounds on PLATFORM_WEB |
|
|
|
Wave wav = LoadWave("resources/country.mp3"); |
|
|
|
WaveFormat(&wav, SAMPLE_RATE, PER_SAMPLE_BIT_DEPTH, MONO); |
|
|
|
|
|
|
|
@ -95,10 +105,10 @@ int main(void) |
|
|
|
int fftHistoryLen = (int)ceilf(FFT_HISTORICAL_SMOOTHING_DUR/WINDOW_TIME) + 1; |
|
|
|
|
|
|
|
FFTData fft = { |
|
|
|
.spectrum = malloc(sizeof(FFTComplex)o">*FFT_WINDOW_SIZE), |
|
|
|
.workBuffer = malloc(sizeof(FFTComplex)o">*FFT_WINDOW_SIZE), |
|
|
|
.prevMagnitudes = calloc(BUFFER_SIZE, sizeof(float)), |
|
|
|
.fftHistory = calloc(fftHistoryLen, sizeof(float[BUFFER_SIZE])), |
|
|
|
.spectrum = RL_CALLOC(sizeof(FFTComplex)p">, FFT_WINDOW_SIZE), |
|
|
|
.workBuffer = RL_CALLOC(sizeof(FFTComplex)p">, FFT_WINDOW_SIZE), |
|
|
|
.prevMagnitudes = RL_CALLOC(BUFFER_SIZE, sizeof(float)), |
|
|
|
.fftHistory = RL_CALLOC(fftHistoryLen, sizeof(float[BUFFER_SIZE])), |
|
|
|
.fftHistoryLen = fftHistoryLen, |
|
|
|
.historyPos = 0, |
|
|
|
.lastFftTime = 0.0, |
|
|
|
@ -127,15 +137,12 @@ int main(void) |
|
|
|
int right = (wav.channels == 2)? wavPCM16[wavCursor*2 + 1] : left; |
|
|
|
chunkSamples[i] = (short)((left + right)/2); |
|
|
|
|
|
|
|
if (++wavCursor >= wav.frameCount) |
|
|
|
wavCursor = 0; |
|
|
|
|
|
|
|
if (++wavCursor >= wav.frameCount) wavCursor = 0; |
|
|
|
} |
|
|
|
|
|
|
|
UpdateAudioStream(audioStream, chunkSamples, AUDIO_STREAM_RING_BUFFER_SIZE); |
|
|
|
|
|
|
|
for (int i = 0; i < FFT_WINDOW_SIZE; i++) |
|
|
|
audioSamples[i] = (chunkSamples[i*2] + chunkSamples[i*2 + 1])*0.5f/32767.0f; |
|
|
|
for (int i = 0; i < FFT_WINDOW_SIZE; i++) audioSamples[i] = (chunkSamples[i*2] + chunkSamples[i*2 + 1])*0.5f/32767.0f; |
|
|
|
} |
|
|
|
|
|
|
|
CaptureFrame(&fft, audioSamples); |
|
|
|
@ -146,14 +153,16 @@ int main(void) |
|
|
|
// Draw |
|
|
|
//---------------------------------------------------------------------------------- |
|
|
|
BeginDrawing(); |
|
|
|
ClearBackground(BLACK); |
|
|
|
|
|
|
|
ClearBackground(RAYWHITE); |
|
|
|
|
|
|
|
BeginShaderMode(shader); |
|
|
|
SetShaderValueTexture(shader, iChannel0Location, fftTexture); |
|
|
|
DrawTextureRec(bufferA.texture, |
|
|
|
(Rectangle){ 0, 0, (float)screenWidth, (float)-screenHeight }, |
|
|
|
(Vector2){ 0, 0 }, |
|
|
|
WHITE); |
|
|
|
(Vector2){ 0, 0 }, WHITE); |
|
|
|
EndShaderMode(); |
|
|
|
|
|
|
|
EndDrawing(); |
|
|
|
//------------------------------------------------------------------------------ |
|
|
|
} |
|
|
|
@ -168,10 +177,10 @@ int main(void) |
|
|
|
UnloadWave(wav); |
|
|
|
CloseAudioDevice(); |
|
|
|
|
|
|
|
free(fft.spectrum); |
|
|
|
free(fft.workBuffer); |
|
|
|
free(fft.prevMagnitudes); |
|
|
|
free(fft.fftHistory); |
|
|
|
RL_FREE(fft.spectrum); |
|
|
|
RL_FREE(fft.workBuffer); |
|
|
|
RL_FREE(fft.prevMagnitudes); |
|
|
|
RL_FREE(fft.fftHistory); |
|
|
|
|
|
|
|
CloseWindow(); // Close window and OpenGL context |
|
|
|
//---------------------------------------------------------------------------------- |
|
|
|
|