Add libftw3, receive audio input and perform fft
This receives the audio input, performs the fft on it and has all the nescessary preparations for then binding the audio data to the 2d texture for the GLSL. Signed-off-by: Tyrolyean <tyrolyean@tyrolyean.net>
This commit is contained in:
parent
7e190a5729
commit
72f3e51b7b
2 changed files with 52 additions and 3 deletions
2
Makefile
2
Makefile
|
@ -1,5 +1,5 @@
|
||||||
CFLAGS = -std=c11 -pedantic -Wall -Wextra -O2 -Ofast -D_DEFAULT_SOURCE -D_FORTIFY_SOURCE=2
|
CFLAGS = -std=c11 -pedantic -Wall -Wextra -O2 -Ofast -D_DEFAULT_SOURCE -D_FORTIFY_SOURCE=2
|
||||||
LDFLAGS = -lX11 -lGL -lGLEW -lm -lrt
|
LDFLAGS = -lX11 -lGL -lGLEW -lm -lrt -lfftw3
|
||||||
|
|
||||||
shadermeh: shadermeh.o window.o shader.o
|
shadermeh: shadermeh.o window.o shader.o
|
||||||
|
|
||||||
|
|
53
shadermeh.c
53
shadermeh.c
|
@ -10,6 +10,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#define HAVE_ARCH_STRUCT_FLOCK
|
#define HAVE_ARCH_STRUCT_FLOCK
|
||||||
#include <linux/fcntl.h>
|
#include <linux/fcntl.h>
|
||||||
|
#include <fftw3.h>
|
||||||
|
|
||||||
static GLfloat vertex_buffer[] = {
|
static GLfloat vertex_buffer[] = {
|
||||||
-1.0f, -1.0f, 0.0f, /* lower left corner */
|
-1.0f, -1.0f, 0.0f, /* lower left corner */
|
||||||
|
@ -87,12 +88,46 @@ static int write_retry(int fd, const void *buffer, size_t size)
|
||||||
|
|
||||||
#define SND_BUFFER_SIZE 512
|
#define SND_BUFFER_SIZE 512
|
||||||
|
|
||||||
|
#define BBUFFER_S ((sizeof(float) * SND_BUFFER_SIZE))
|
||||||
|
|
||||||
|
/* Read all available input. This function presumes fd to be O_NONBLOCK */
|
||||||
static int read_audio_buffers(int fd, float buffer[SND_BUFFER_SIZE],
|
static int read_audio_buffers(int fd, float buffer[SND_BUFFER_SIZE],
|
||||||
unsigned int sampling_rate){
|
unsigned int sampling_rate){
|
||||||
|
|
||||||
|
float temp_buf[sampling_rate];
|
||||||
|
size_t n = 0;
|
||||||
|
memset(temp_buf, 0, sizeof(temp_buf));
|
||||||
|
while(true){
|
||||||
|
|
||||||
|
int new_n = read(fd, temp_buf, sizeof(temp_buf));
|
||||||
|
if(new_n < 0){
|
||||||
|
if(errno == EAGAIN || errno == EWOULDBLOCK){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
perror("Read to audio buffer failed");
|
||||||
|
return -1;
|
||||||
|
}else if(new_n == 0){
|
||||||
|
break;
|
||||||
|
} else if(n < sizeof(temp_buf)){
|
||||||
|
n = new_n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Fall through and read the remaining buffer
|
||||||
|
* (last ditch effort to clear pipe)
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
if(n < BBUFFER_S){
|
||||||
|
memmove(buffer, buffer+n, BBUFFER_S - n);
|
||||||
|
memcpy(buffer+ BBUFFER_S - n, temp_buf, n);
|
||||||
|
}else{
|
||||||
|
memcpy(buffer, (temp_buf+n-BBUFFER_S), BBUFFER_S);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* normalize the given input buffer from -1…1 in range (what alsa provides) to
|
||||||
|
* 0…1 in range (what the shadertoy shaders */
|
||||||
static void normalize_audio_buffers(float buffer_in[SND_BUFFER_SIZE],
|
static void normalize_audio_buffers(float buffer_in[SND_BUFFER_SIZE],
|
||||||
float buffer_out[SND_BUFFER_SIZE]){
|
float buffer_out[SND_BUFFER_SIZE]){
|
||||||
|
|
||||||
|
@ -151,6 +186,13 @@ int main(int argc, char **argv)
|
||||||
*/
|
*/
|
||||||
float in_samples[SND_BUFFER_SIZE]; /* Raw input floats from -1...1 */
|
float in_samples[SND_BUFFER_SIZE]; /* Raw input floats from -1...1 */
|
||||||
float norm_samples[SND_BUFFER_SIZE]; /* Normalized samples from 0...1 */
|
float norm_samples[SND_BUFFER_SIZE]; /* Normalized samples from 0...1 */
|
||||||
|
fftw_complex fftw_in[SND_BUFFER_SIZE];
|
||||||
|
fftw_complex fftw_out[SND_BUFFER_SIZE];
|
||||||
|
fftw_plan plan = fftw_plan_dft_1d(SND_BUFFER_SIZE,
|
||||||
|
fftw_in,
|
||||||
|
fftw_out,
|
||||||
|
FFTW_FORWARD,
|
||||||
|
FFTW_ESTIMATE);
|
||||||
|
|
||||||
/******************** parse options ************************/
|
/******************** parse options ************************/
|
||||||
width = 800;
|
width = 800;
|
||||||
|
@ -236,8 +278,8 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sampling_rate != 0 && !isatty(STDIN_FILENO)){
|
if (sampling_rate != 0 && isatty(STDIN_FILENO)){
|
||||||
fputs("Sampling rate specified and STDIN not a tty! "
|
fputs("Sampling rate specified and STDIN a tty! "
|
||||||
"You habe been warnded!\n", stderr);
|
"You habe been warnded!\n", stderr);
|
||||||
}
|
}
|
||||||
if(sampling_rate != 0){
|
if(sampling_rate != 0){
|
||||||
|
@ -367,6 +409,12 @@ int main(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
normalize_audio_buffers(in_samples, norm_samples);
|
normalize_audio_buffers(in_samples, norm_samples);
|
||||||
|
memset(fftw_in, 0, sizeof(fftw_in));
|
||||||
|
memset(fftw_out, 0, sizeof(fftw_out));
|
||||||
|
for(size_t i = 0; i < SND_BUFFER_SIZE; i++){
|
||||||
|
fftw_in[i][0] = norm_samples[i];
|
||||||
|
}
|
||||||
|
fftw_execute(plan);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update timers */
|
/* update timers */
|
||||||
|
@ -399,5 +447,6 @@ int main(int argc, char **argv)
|
||||||
free(fb32);
|
free(fb32);
|
||||||
free(fb24);
|
free(fb24);
|
||||||
window_destroy(wnd);
|
window_destroy(wnd);
|
||||||
|
fftw_destroy_plan(plan);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue