From 031c989ec64cc5ae1b7a0df32dda30b4c005174e Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 9 Feb 2011 09:30:24 +0100 Subject: [PATCH] fixed some timing issues --- lib/libfn.c | 30 +++++----- src/fnctl.c | 4 +- src/fnvum_fftw.c | 140 +++++++++++++++++++++++++++++++---------------- 3 files changed, 109 insertions(+), 65 deletions(-) diff --git a/lib/libfn.c b/lib/libfn.c index a570f11..bfb8444 100644 --- a/lib/libfn.c +++ b/lib/libfn.c @@ -5,26 +5,24 @@ #include struct termios fn_init(int fd) { - struct termios oldtio, newtio; - - tcgetattr(fd, &oldtio); /* save current port settings */ - - memset(&newtio, 0, sizeof(newtio)); - newtio.c_cflag = CS8 | CLOCAL | CREAD; - newtio.c_iflag= 0; - newtio.c_oflag= 0; - newtio.c_lflag= 0; + struct termios oldtio, newtio; - newtio.c_cc[VMIN] = 1; - newtio.c_cc[VTIME] = 5; + tcgetattr(fd, &oldtio); /* save current port settings */ + + memset(&newtio, 0, sizeof(newtio)); + newtio.c_cflag = CS8 | CLOCAL | CREAD; + newtio.c_iflag= 0; + newtio.c_oflag= 0; + newtio.c_lflag= 0; + + newtio.c_cc[VMIN] = 1; + newtio.c_cc[VTIME] = 5; cfsetispeed(&newtio, FN_BAUDRATE); cfsetospeed(&newtio, FN_BAUDRATE); - - tcflush(fd, TCIFLUSH); - tcsetattr(fd, TCSANOW, &newtio); - fn_sync(fd); + tcflush(fd, TCIFLUSH); + tcsetattr(fd, TCSANOW, &newtio); return oldtio; } @@ -64,7 +62,7 @@ uint8_t fn_count_devices(int fd) { else { break; } - } + } return msg.address; } diff --git a/src/fnctl.c b/src/fnctl.c index 11e99c0..c0b5595 100644 --- a/src/fnctl.c +++ b/src/fnctl.c @@ -1,6 +1,7 @@ #include /* Standard input/output definitions */ #include #include +#include #include #include @@ -113,7 +114,6 @@ int main(int argc, char ** argv) { char mask[254] = ""; char filename[1024] = ""; - enum connection_t con_mode = RS232; char host[255] = DEFAULT_HOST; char port[255] = DEFAULT_PORT; char device[255] = DEFAULT_DEVICE; @@ -125,6 +125,7 @@ int main(int argc, char ** argv) { memset(&msg, 0, sizeof msg); /* connection */ + enum connection_t con_mode = RS232; int fd; struct addrinfo hints, *res; struct termios oldtio; @@ -264,6 +265,7 @@ int main(int argc, char ** argv) { } fn_sync(fd); + usleep(25000); /* check address */ if (address > FN_MAX_DEVICES+1) { diff --git a/src/fnvum_fftw.c b/src/fnvum_fftw.c index 5079281..60c0160 100644 --- a/src/fnvum_fftw.c +++ b/src/fnvum_fftw.c @@ -18,18 +18,19 @@ #include #include -#define N 512 +#define N 2048 #define SAMPLING_RATE 44100 -#define MIN_FREQ 50 +#define MIN_FREQ 70 #define MAX_FREQ 9000 -#define MIN_K (MIN_FREQ*N/SAMPLING_RATE)+1 +#define MIN_K (MIN_FREQ*N/SAMPLING_RATE) #define MAX_K (MAX_FREQ*N /SAMPLING_RATE) -#define LINE_WIDTH 4 +#define LINE_WIDTH 1 #define SCREEN_WIDTH LINE_WIDTH*(MAX_K - MIN_K) #define SCREEN_HEIGHT SCREEN_WIDTH/2 +#define VUM_HEIGHT SCREEN_HEIGHT/6 #define TITLE "fnordlicht visualization" @@ -37,19 +38,6 @@ double normalize_auditory(double freq, double spl) { return spl; // TODO implement } -void show_level(SDL_Surface *dst, float level) { - SDL_Rect rect = dst->clip_rect; - uint32_t color = SDL_MapRGB(dst->format, 0xff, 0, 0); // TODO define via phase - uint32_t background = SDL_MapRGB(dst->format, 0, 0, 0); - - SDL_FillRect(dst, &rect, background); - - rect.w *= level; - - SDL_FillRect(dst, &rect, color); - SDL_Flip(dst); -} - struct rgb_color_t hsv2rgb(struct hsv_color_t hsv) { struct rgb_color_t rgb; @@ -75,52 +63,103 @@ struct rgb_color_t hsv2rgb(struct hsv_color_t hsv) { return rgb; } -uint32_t phasor2color(complex phasor, SDL_PixelFormat *format) { +struct rgb_color_t phasor2color(complex phasor) { struct hsv_color_t hsv; - struct rgb_color_t rgb; hsv.hue = 180*(carg(phasor)+M_PI)/M_PI; hsv.saturation = 255; hsv.value = 255; - rgb = hsv2rgb(hsv); + return hsv2rgb(hsv); +} - return SDL_MapRGB(format, rgb.red, rgb.green, rgb.blue); +struct rgb_color_t level2color(double level) { + struct hsv_color_t hsv; + + hsv.hue = level * 360; + hsv.saturation = 255; + hsv.value = 255; + + return hsv2rgb(hsv); } void show_spectrum(SDL_Surface * dst, complex * fft_data) { - SDL_Rect rect; + struct rgb_color_t rgb; uint32_t background = SDL_MapRGB(dst->format, 0, 0, 0); - + uint32_t foreground; SDL_FillRect(dst, &dst->clip_rect, background); - + + SDL_Rect rect; rect.w = LINE_WIDTH; int k; for (k = MIN_K; k <= MAX_K; k++) { - double ampl = cabs(fft_data[k]); + double ampl = cabs(fft_data[k]) / 500000; + rect.x = (k - MIN_K) * LINE_WIDTH; + rect.h = ampl * (SCREEN_HEIGHT - VUM_HEIGHT); + rect.y = (SCREEN_HEIGHT - VUM_HEIGHT) - rect.h; - rect.x = (k - MIN_K + 1) * LINE_WIDTH; - - rect.h = (ampl / 900000) * SCREEN_HEIGHT; - rect.y = SCREEN_HEIGHT - rect.h; + rgb = phasor2color(fft_data[k]); + foreground = SDL_MapRGB(dst->format, rgb.red, rgb.green, rgb.blue); - SDL_FillRect(dst, &rect, phasor2color(fft_data[k], dst->format)); + SDL_FillRect(dst, &rect, foreground); } - SDL_Flip(dst); } -void fade_level(int fd, float level) { - struct remote_msg_fade_rgb_t fncmd; - memset(&fncmd, 0, sizeof (struct remote_msg_t)); +void fade_spectrum(int fd, complex * fft_data, int fn_num) { + struct remote_msg_fade_rgb_t fn_cmd; + memset(&fn_cmd, 0, sizeof (struct remote_msg_t)); - fncmd.color.red = fncmd.color.green = fncmd.color.blue = (uint8_t) 255.0 * level; - fncmd.address = 255; - fncmd.cmd = REMOTE_CMD_FADE_RGB; - fncmd.step = 25; - fncmd.delay = 0; + fn_cmd.cmd = REMOTE_CMD_FADE_RGB; + fn_cmd.step = 200; + fn_cmd.delay = 0; - fn_send(fd, (struct remote_msg_t *) &fncmd); + int k; + for (k = 0; k < fn_num; k++) { + double ampl = 0; + int i; + for (i = MIN_K+k*(MAX_K-MIN_K)/fn_num; i < (k+1)*(MAX_K-MIN_K)/fn_num; i++) { + ampl += cabs(fft_data[i]); + } + ampl /= 1000000*fn_num; + + fn_cmd.color.red = 255 * ampl; + fn_cmd.color.green = 255 * ampl; + fn_cmd.color.blue = 255 * ampl; + + fn_cmd.address = k; + fn_send(fd, (struct remote_msg_t *) &fn_cmd); + } +} + +void show_level(SDL_Surface *dst, float level) { + SDL_Rect rect = {0, SCREEN_HEIGHT - VUM_HEIGHT, SCREEN_WIDTH, VUM_HEIGHT}; + + struct rgb_color_t rgb = level2color(level); + uint32_t background = SDL_MapRGB(dst->format, 0, 0, 0); + uint32_t foreground = SDL_MapRGB(dst->format, rgb.red, rgb.green, rgb.blue); + + SDL_FillRect(dst, &rect, background); + rect.w *= level; + SDL_FillRect(dst, &rect, foreground); +} + +void fade_level(int fd, double level) { + struct remote_msg_fade_rgb_t fn_cmd; + struct rgb_color_t rgb = level2color(level); + + memset(&fn_cmd, 0, sizeof (struct remote_msg_t)); + + fn_cmd.color.red = rgb.red * level; + fn_cmd.color.green = rgb.blue * level; + fn_cmd.color.blue = rgb.blue * level; + + fn_cmd.address = 255; + fn_cmd.cmd = REMOTE_CMD_FADE_RGB; + fn_cmd.step = 200; + fn_cmd.delay = 0; + + fn_send(fd, (struct remote_msg_t *) &fn_cmd); } int main(int argc, char *argv[]) { @@ -135,8 +174,7 @@ int main(int argc, char *argv[]) { SDL_Surface *screen = NULL; SDL_Event event; - int error, counter = 0, fd = -1; - uint32_t level; + int error, counter = 0, fd = -1, fn_num; int16_t * pcm_data; complex * fft_data; fftw_plan fft_plan; @@ -150,6 +188,10 @@ int main(int argc, char *argv[]) { } fn_init(fd); + fn_sync(fd); + fn_num = fn_count_devices(fd); + printf("found %d fnordlichts\n", fn_num); + usleep(25000); } /* init screen & window */ @@ -177,7 +219,7 @@ int main(int argc, char *argv[]) { exit(-1); } pa_simple_flush(s, &error); /* flush audio buffer */ - + while (1) { counter++; @@ -206,13 +248,16 @@ int main(int argc, char *argv[]) { fft_data[index] = (double) pcm_data[index]; } - level = (float) sum / (N * pow(2, 15)); - //show_level(screen, level * 1.8); - //fade_level(fd, level); - /* execute fftw plan */ fftw_execute(fft_plan); + level = (float) sum / (N * pow(2, 15)) * 2; + + //if (counter % 2 == 0) fade_spectrum(fd, fft_data, fn_num); + fade_level(fd, level); + show_spectrum(screen, fft_data); + show_level(screen, level); + SDL_Flip(screen); //printf("level: %f \tsum: %d\t max: %d\n", level, sum, max); } @@ -221,7 +266,6 @@ int main(int argc, char *argv[]) { SDL_Quit(); free(pcm_data); fftw_free(fft_data); - fftw_destroy(fft_plan); fftw_cleanup(); return 0;