Mercurial > audlegacy-plugins
diff src/paranormal/wave.c @ 193:4b48e6e9b3cb trunk
[svn] - rewrite line drawing algorithm for speed
- use lines instead of dots by default in horizontal and vertical waveforms
author | nenolod |
---|---|
date | Fri, 03 Nov 2006 02:54:12 -0800 |
parents | 0d826917c56f |
children | 5e8cf0611af3 |
line wrap: on
line diff
--- a/src/paranormal/wave.c Thu Nov 02 22:19:05 2006 -0800 +++ b/src/paranormal/wave.c Fri Nov 03 02:54:12 2006 -0800 @@ -12,11 +12,12 @@ {"channels", "Which sound channels to use: negative = channel 1, \npositive = channel 2, " "zero = both (two wave-forms.)", OPT_TYPE_INT, {ival: -1} }, {"value", "The colour value to use.", OPT_TYPE_INT, {ival: 255} }, + {"lines", "Use lines instead of dots.", OPT_TYPE_BOOLEAN, {bval: TRUE} }, { NULL } }; static void -wave_horizontal_exec (const struct pn_actuator_option *opts, +wave_horizontal_exec_dots (const struct pn_actuator_option *opts, gpointer data) { int i; @@ -51,6 +52,71 @@ } } +void +wave_horizontal_exec_lines (const struct pn_actuator_option *opts, + gpointer data) +{ + int channel = ( opts[0].val.ival < 0 ) ? 0 : 1; + guchar value = (opts[1].val.ival < 0 || opts[1].val.ival > 255) ? 255 : opts[1].val.ival; + int *x_pos, *y_pos; /* dynamic tables which store the positions for the line */ + int *x2_pos, *y2_pos; /* dynamic tables which store the positions for the line */ + int i; + + x_pos = g_new0(int, pn_image_data->width + 1); + y_pos = g_new0(int, pn_image_data->width + 1); + x2_pos = g_new0(int, pn_image_data->width + 1); + y2_pos = g_new0(int, pn_image_data->width + 1); + + /* calculate the line. */ + for (i = 0; i < pn_image_data->width; i++) + { + if (opts[0].val.ival != 0) + { + x_pos[i] = i; + y_pos[i] = (pn_image_data->height>>1) - + CAP (pn_sound_data->pcm_data[channel][i*512/pn_image_data->width]>>8, + (pn_image_data->height>>1)-1); + } + else + { + x_pos[i] = i; + y_pos[i] = (pn_image_data->height>>2) - + CAP (pn_sound_data->pcm_data[0][i*512/pn_image_data->width]>>9, + (pn_image_data->height>>2)-1); + + x2_pos[i] = i; + y2_pos[i] = 3*(pn_image_data->height>>2) - + CAP (pn_sound_data->pcm_data[1][i*512/pn_image_data->width]>>9, + (pn_image_data->height>>2)-1); + + } + } + + /* draw the line. */ + for (i = 1; i < pn_image_data->width; i++) + { + pn_draw_line(x_pos[i - 1], y_pos[i - 1], x_pos[i], y_pos[i], value); + + if ( opts[0].val.ival == 0 ) + pn_draw_line(x2_pos[i - 1], y2_pos[i - 1], x2_pos[i], y2_pos[i], value); + } + + g_free(x_pos); + g_free(y_pos); + g_free(x2_pos); + g_free(y2_pos); +} + +static void +wave_horizontal_exec (const struct pn_actuator_option *opts, + gpointer data) +{ + if (opts[2].val.bval == TRUE) + wave_horizontal_exec_lines(opts, data); + else + wave_horizontal_exec_dots(opts, data); +} + struct pn_actuator_desc builtin_wave_horizontal = { "wave_horizontal", "Horizontal Waveform", @@ -66,11 +132,12 @@ {"channels", "Which sound channels to use: negative = channel 1, \npositive = channel 2, " "zero = both (two wave-forms.)", OPT_TYPE_INT, {ival: -1} }, {"value", "The colour value to use.", OPT_TYPE_INT, {ival: 255} }, + {"lines", "Use lines instead of dots.", OPT_TYPE_BOOLEAN, {bval: TRUE} }, { NULL } }; static void -wave_vertical_exec (const struct pn_actuator_option *opts, +wave_vertical_exec_dots (const struct pn_actuator_option *opts, gpointer data) { int i; @@ -101,6 +168,72 @@ } } +static void +wave_vertical_exec_lines (const struct pn_actuator_option *opts, + gpointer data) +{ + int channel = ( opts[0].val.ival < 0 ) ? 0 : 1; + guchar value = (opts[1].val.ival < 0 || opts[1].val.ival > 255) ? 255 : opts[1].val.ival; + int *x_pos, *y_pos; /* dynamic tables which store the positions for the line */ + int *x2_pos, *y2_pos; /* dynamic tables which store the positions for the line */ + int i; + + x_pos = g_new0(int, pn_image_data->height + 1); + y_pos = g_new0(int, pn_image_data->height + 1); + x2_pos = g_new0(int, pn_image_data->height + 1); + y2_pos = g_new0(int, pn_image_data->height + 1); + + /* calculate the line. */ + for (i = 0; i < pn_image_data->height; i++) + { + if (opts[0].val.ival != 0) + { + x_pos[i] = (pn_image_data->width>>1) - + CAP (pn_sound_data->pcm_data[channel] + [i*512/pn_image_data->height]>>8, + (pn_image_data->width>>1)-1); + y_pos[i] = i; + } + else + { + x_pos[i] = (pn_image_data->width>>2) + - CAP (pn_sound_data->pcm_data[0] + [i*512/pn_image_data->height]>>9, + (pn_image_data->width>>2)-1); + y_pos[i] = i; + + x2_pos[i] = 3*(pn_image_data->width>>2) + - CAP (pn_sound_data->pcm_data[1] + [i*512/pn_image_data->height]>>9, + (pn_image_data->width>>2)-1); + y2_pos[i] = i; + } + } + + /* draw the line. */ + for (i = 1; i < pn_image_data->width; i++) + { + pn_draw_line(x_pos[i - 1], y_pos[i - 1], x_pos[i], y_pos[i], value); + + if ( opts[0].val.ival == 0 ) + pn_draw_line(x2_pos[i - 1], y2_pos[i - 1], x2_pos[i], y2_pos[i], value); + } + + g_free(x_pos); + g_free(y_pos); + g_free(x2_pos); + g_free(y2_pos); +} + +static void +wave_vertical_exec (const struct pn_actuator_option *opts, + gpointer data) +{ + if (opts[2].val.bval == TRUE) + wave_vertical_exec_lines(opts, data); + else + wave_vertical_exec_dots(opts, data); +} struct pn_actuator_desc builtin_wave_vertical = { @@ -221,6 +354,7 @@ { "base_radius", " ", OPT_TYPE_FLOAT, { fval: 0 } }, {"value", "The colour value to use.", OPT_TYPE_INT, {ival: 255} }, +/* {"lines", "Use lines instead of dots.", OPT_TYPE_BOOLEAN, {bval: TRUE} }, */ { NULL } };