Skip to content

Commit 5fdf178

Browse files
committed
REVIEWED: audio_fft_spectrum_visualizer, not working on web
1 parent e3738c1 commit 5fdf178

File tree

5 files changed

+133
-49
lines changed

5 files changed

+133
-49
lines changed

examples/audio/audio_fft_spectrum_visualizer.c

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,19 @@
1919
********************************************************************************************/
2020

2121
#include "raylib.h"
22+
2223
#include "raymath.h"
24+
2325
#include <math.h>
2426
#include <stdlib.h>
2527
#include <string.h>
2628

29+
#if defined(PLATFORM_DESKTOP)
30+
#define GLSL_VERSION 330
31+
#else // PLATFORM_ANDROID, PLATFORM_WEB
32+
#define GLSL_VERSION 100
33+
#endif
34+
2735
#define MONO 1
2836
#define SAMPLE_RATE 44100
2937
#define SAMPLE_RATE_F 44100.0f
@@ -77,7 +85,8 @@ int main(void)
7785
RenderTexture2D bufferA = LoadRenderTexture(screenWidth, screenHeight);
7886
Vector2 iResolution = { (float)screenWidth, (float)screenHeight };
7987

80-
Shader shader = LoadShader(NULL, "resources/fft.glsl");
88+
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/fft.fs", GLSL_VERSION));
89+
8190
int iResolutionLocation = GetShaderLocation(shader, "iResolution");
8291
int iChannel0Location = GetShaderLocation(shader, "iChannel0");
8392
SetShaderValue(shader, iResolutionLocation, &iResolution, SHADER_UNIFORM_VEC2);
@@ -86,6 +95,7 @@ int main(void)
8695
InitAudioDevice();
8796
SetAudioStreamBufferSizeDefault(AUDIO_STREAM_RING_BUFFER_SIZE);
8897

98+
// WARNING: Memory out-of-bounds on PLATFORM_WEB
8999
Wave wav = LoadWave("resources/country.mp3");
90100
WaveFormat(&wav, SAMPLE_RATE, PER_SAMPLE_BIT_DEPTH, MONO);
91101

@@ -95,10 +105,10 @@ int main(void)
95105
int fftHistoryLen = (int)ceilf(FFT_HISTORICAL_SMOOTHING_DUR/WINDOW_TIME) + 1;
96106

97107
FFTData fft = {
98-
.spectrum = malloc(sizeof(FFTComplex)*FFT_WINDOW_SIZE),
99-
.workBuffer = malloc(sizeof(FFTComplex)*FFT_WINDOW_SIZE),
100-
.prevMagnitudes = calloc(BUFFER_SIZE, sizeof(float)),
101-
.fftHistory = calloc(fftHistoryLen, sizeof(float[BUFFER_SIZE])),
108+
.spectrum = RL_CALLOC(sizeof(FFTComplex), FFT_WINDOW_SIZE),
109+
.workBuffer = RL_CALLOC(sizeof(FFTComplex), FFT_WINDOW_SIZE),
110+
.prevMagnitudes = RL_CALLOC(BUFFER_SIZE, sizeof(float)),
111+
.fftHistory = RL_CALLOC(fftHistoryLen, sizeof(float[BUFFER_SIZE])),
102112
.fftHistoryLen = fftHistoryLen,
103113
.historyPos = 0,
104114
.lastFftTime = 0.0,
@@ -127,15 +137,12 @@ int main(void)
127137
int right = (wav.channels == 2)? wavPCM16[wavCursor*2 + 1] : left;
128138
chunkSamples[i] = (short)((left + right)/2);
129139

130-
if (++wavCursor >= wav.frameCount)
131-
wavCursor = 0;
132-
140+
if (++wavCursor >= wav.frameCount) wavCursor = 0;
133141
}
134142

135143
UpdateAudioStream(audioStream, chunkSamples, AUDIO_STREAM_RING_BUFFER_SIZE);
136144

137-
for (int i = 0; i < FFT_WINDOW_SIZE; i++)
138-
audioSamples[i] = (chunkSamples[i*2] + chunkSamples[i*2 + 1])*0.5f/32767.0f;
145+
for (int i = 0; i < FFT_WINDOW_SIZE; i++) audioSamples[i] = (chunkSamples[i*2] + chunkSamples[i*2 + 1])*0.5f/32767.0f;
139146
}
140147

141148
CaptureFrame(&fft, audioSamples);
@@ -146,14 +153,16 @@ int main(void)
146153
// Draw
147154
//----------------------------------------------------------------------------------
148155
BeginDrawing();
149-
ClearBackground(BLACK);
156+
157+
ClearBackground(RAYWHITE);
158+
150159
BeginShaderMode(shader);
151160
SetShaderValueTexture(shader, iChannel0Location, fftTexture);
152161
DrawTextureRec(bufferA.texture,
153162
(Rectangle){ 0, 0, (float)screenWidth, (float)-screenHeight },
154-
(Vector2){ 0, 0 },
155-
WHITE);
163+
(Vector2){ 0, 0 }, WHITE);
156164
EndShaderMode();
165+
157166
EndDrawing();
158167
//------------------------------------------------------------------------------
159168
}
@@ -168,10 +177,10 @@ int main(void)
168177
UnloadWave(wav);
169178
CloseAudioDevice();
170179

171-
free(fft.spectrum);
172-
free(fft.workBuffer);
173-
free(fft.prevMagnitudes);
174-
free(fft.fftHistory);
180+
RL_FREE(fft.spectrum);
181+
RL_FREE(fft.workBuffer);
182+
RL_FREE(fft.prevMagnitudes);
183+
RL_FREE(fft.fftHistory);
175184

176185
CloseWindow(); // Close window and OpenGL context
177186
//----------------------------------------------------------------------------------

examples/audio/resources/fft.glsl

Lines changed: 0 additions & 32 deletions
This file was deleted.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#version 100
2+
3+
precision mediump float;
4+
5+
// Input vertex attributes (from vertex shader)
6+
varying vec2 fragTexCoord;
7+
varying vec4 fragColor;
8+
9+
// Input uniform values
10+
uniform vec2 iResolution;
11+
uniform sampler2D iChannel0;
12+
13+
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
14+
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
15+
const float FFT_ROW = 0.0;
16+
const float NUM_OF_BINS = 512.0;
17+
18+
void main()
19+
{
20+
vec2 fragCoord = fragTexCoord*iResolution;
21+
float cellWidth = iResolution.x/NUM_OF_BINS;
22+
float binIndex = floor(fragCoord.x/cellWidth);
23+
float localX = mod(fragCoord.x, cellWidth);
24+
float barWidth = cellWidth - 1.0;
25+
vec4 color = WHITE;
26+
27+
if (localX <= barWidth)
28+
{
29+
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
30+
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
31+
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
32+
33+
if (fragTexCoord.y < amplitude) color = BLACK;
34+
}
35+
36+
gl_FragColor = color;
37+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#version 120
2+
3+
// Input vertex attributes (from vertex shader)
4+
varying vec2 fragTexCoord;
5+
varying vec4 fragColor;
6+
7+
// Input uniform values
8+
uniform vec2 iResolution;
9+
uniform sampler2D iChannel0;
10+
11+
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
12+
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
13+
const float FFT_ROW = 0.0;
14+
const float NUM_OF_BINS = 512.0;
15+
16+
void main()
17+
{
18+
vec2 fragCoord = fragTexCoord*iResolution;
19+
float cellWidth = iResolution.x/NUM_OF_BINS;
20+
float binIndex = floor(fragCoord.x/cellWidth);
21+
float localX = mod(fragCoord.x, cellWidth);
22+
float barWidth = cellWidth - 1.0;
23+
vec4 color = WHITE;
24+
25+
if (localX <= barWidth)
26+
{
27+
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
28+
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
29+
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
30+
31+
if (fragTexCoord.y < amplitude) color = BLACK;
32+
}
33+
34+
gl_FragColor = color;
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#version 330
2+
3+
in vec2 fragTexCoord;
4+
in vec4 fragColor;
5+
6+
out vec4 finalColor;
7+
8+
uniform vec2 iResolution;
9+
uniform sampler2D iChannel0;
10+
11+
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
12+
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
13+
const float FFT_ROW = 0.0;
14+
const float NUM_OF_BINS = 512.0;
15+
16+
void main()
17+
{
18+
vec2 fragCoord = fragTexCoord*iResolution;
19+
float cellWidth = iResolution.x/NUM_OF_BINS;
20+
float binIndex = floor(fragCoord.x/cellWidth);
21+
float localX = mod(fragCoord.x, cellWidth);
22+
float barWidth = cellWidth - 1.0;
23+
vec4 color = WHITE;
24+
25+
if (localX <= barWidth)
26+
{
27+
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
28+
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
29+
float amplitude = texture(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
30+
31+
if (fragTexCoord.y < amplitude) color = BLACK;
32+
}
33+
34+
finalColor = color;
35+
}

0 commit comments

Comments
 (0)