From 72f3e51b7bfb22b7fdd2e203d5c34293d6af7469 Mon Sep 17 00:00:00 2001 From: Tyrolyean Date: Tue, 19 Jul 2022 00:23:43 +0200 Subject: [PATCH] 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 --- Makefile | 2 +- shadermeh.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 27c87e3..2dc7129 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ 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 diff --git a/shadermeh.c b/shadermeh.c index 6dd8681..3b1bf32 100644 --- a/shadermeh.c +++ b/shadermeh.c @@ -10,6 +10,7 @@ #include #define HAVE_ARCH_STRUCT_FLOCK #include +#include static GLfloat vertex_buffer[] = { -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 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], 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; } +/* 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], 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 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 ************************/ width = 800; @@ -236,8 +278,8 @@ int main(int argc, char **argv) } } } - if (sampling_rate != 0 && !isatty(STDIN_FILENO)){ - fputs("Sampling rate specified and STDIN not a tty! " + if (sampling_rate != 0 && isatty(STDIN_FILENO)){ + fputs("Sampling rate specified and STDIN a tty! " "You habe been warnded!\n", stderr); } if(sampling_rate != 0){ @@ -367,6 +409,12 @@ int main(int argc, char **argv) break; } 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 */ @@ -399,5 +447,6 @@ int main(int argc, char **argv) free(fb32); free(fb24); window_destroy(wnd); + fftw_destroy_plan(plan); return EXIT_SUCCESS; }