History

clean-ups only

robs committed 18 years ago

Commit d79c8a11 parent 784ea2a3 files · +48 −35Browse files

Showing the changes to src/spectrogram.c (1 of 3 files). Show all

Unified · Split

src/spectrogram.c+45−34
@@ -15,6 +15,11 @@ · 14 unmodified lines
1515 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1616 */
1717
18+/* TODO
19+ * o Two-channel support.
20+ * o Option for a larger font (for use with image down-scaling).
21+ */
22+
1823 #ifdef NDEBUG /* Enable assert always. */
1924 #undef NDEBUG /* Must undef above assert.h or other that might include it. */
2025 #endif
@@ -88,19 +93,28 @@ static enum_item const window_options[] = { · 67 unmodified lines
8893 {0, 0}};
8994
9095 typedef struct {
91− int y_size, dft_size, rows, cols, step_size, block_steps, block_num;
92− int dB_range, gain, style, read, end, end_min, last_end;
93− int spectrum_points, perm;
94− char const * out_name, * title, * comment;
95− sox_bool high_colour, slack_overlap, no_axes, truncated;
96+ /* Parameters */
97+ double pixels_per_sec;
98+ int y_size, dB_range, gain, spectrum_points, perm;
99+ sox_bool monochrome, light_background, high_colour, slack_overlap, no_axes;
96100 win_type_t win_type;
101+ char const * out_name, * title, * comment;
102+
103+ /* Work area */
104+ int WORK; /* Start of work area is marked by this dummy variable. */
105+ int dft_size, step_size, block_steps, block_num, rows, cols, read;
106+ int end, end_min, last_end;
107+ sox_bool truncated;
97108 double buf[MAX_DFT_SIZE], dft_buf[MAX_DFT_SIZE], window[MAX_DFT_SIZE];
98− double pixels_per_sec, block_norm, max, magnitudes[(MAX_DFT_SIZE>>1) + 1];
99− int bit_rev_table[100]; /* For Ooura fft */
109+ double block_norm, max, magnitudes[(MAX_DFT_SIZE>>1) + 1];
110+ int bit_rev_table[100]; /* For Ooura fft */
100111 double sin_cos_table[dft_sc_len(MAX_DFT_SIZE)]; /* ditto */
101112 float * dBfs;
102113 } priv_t;
103114
115+#define secs(cols) \
116+ ((double)(cols) * p->step_size * p->block_steps / effp->in_signal.rate)
117+
104118 #define GETOPT_NUMERIC(ch, name, min, max) case ch:{ \
105119 char * end_ptr; \
106120 double d = strtod(optarg, &end_ptr); \
@@ -134,14 +148,13 @@ static int getopts(sox_effect_t * effp, int argc, char **argv) · 27 unmodified lines
134148 {
135149 priv_t * p = (priv_t *)effp->priv;
136150 int c, callers_optind = optind, callers_opterr = opterr;
137− sox_bool monochrome = sox_false, light_background = sox_false;
138151
139152 assert(array_length(p->bit_rev_table) >= (size_t)dft_br_len(MAX_DFT_SIZE));
140153
141154 --argv, ++argc, optind = 1, opterr = 0; /* re-jig for getopt */
142155 p->pixels_per_sec = 100, p->y_size = 2, p->dB_range = 120;/* non-0 defaults */
143156 p->spectrum_points = 249, p->perm = 1;
144− p->style = 1, p->out_name = "spectrogram.png", p->comment = "Created by SoX";
157+ p->out_name = "spectrogram.png", p->comment = "Created by SoX";
145158
146159 while ((c = getopt(argc, argv, "+x:y:z:Z:q:p:w:st:c:amlho:")) != -1) switch (c) {
147160 GETOPT_NUMERIC('x', pixels_per_sec, 1 , 5000)
@@ -155,15 +168,14 @@ static int getopts(sox_effect_t * effp, int argc, char **argv) · 7 unmodified lines
155168 case 't': p->title = optarg; break;
156169 case 'c': p->comment = optarg; break;
157170 case 'a': p->no_axes = sox_true; break;
158− case 'm': monochrome = sox_true; break;
159− case 'l': light_background = sox_true; break;
171+ case 'm': p->monochrome = sox_true; break;
172+ case 'l': p->light_background = sox_true; break;
160173 case 'h': p->high_colour = sox_true; break;
161174 case 'o': p->out_name = optarg; break;
162175 default: sox_fail("unknown option `-%c'", optopt); return lsx_usage(effp);
163176 }
164− p->gain = - p->gain;
177+ p->gain = -p->gain;
165178 --p->y_size, --p->perm;
166− p->style = 2 * monochrome + light_background;
167179 p->spectrum_points += 2;
168180 argc -= optind, optind = callers_optind, opterr = callers_opterr;
169181 return argc || p->win_type == INT_MAX? lsx_usage(effp) : SOX_SUCCESS;
@@ -198,6 +210,7 @@ static int start(sox_effect_t * effp) · 28 unmodified lines
198210 sox_fail("only 1 channel is supported");
199211 return SOX_EOF;
200212 }
213+ memset(&p->WORK, 0, sizeof(*p) - field_offset(priv_t, WORK));
201214 p->end = p->dft_size = DFT_BASE_SIZE << p->y_size;
202215 p->rows = (p->dft_size >> 1) + 1;
203216 actual = make_window(p, p->last_end = 0);
@@ -222,7 +235,7 @@ static int do_column(sox_effect_t * effp) · 18 unmodified lines
222235 int i;
223236
224237 if (p->cols == MAX_COLS) {
225− sox_warn("PNG truncated at %g seconds", (double)MAX_COLS * p->step_size * p->block_steps / effp->in_signal.rate);
238+ sox_warn("PNG truncated at %g seconds", secs(p->cols));
226239 p->truncated = sox_true;
227240 return SOX_EOF;
228241 }
@@ -231,8 +244,7 @@ static int do_column(sox_effect_t * effp) · 2 unmodified lines
231244 for (i = 0; i < p->rows; ++i) {
232245 double dBfs = 10 * log10(p->magnitudes[i] * p->block_norm);
233246 p->dBfs[(p->cols - 1) * p->rows + i] = dBfs + p->gain;
234− if (dBfs > p->max)
235− p->max = dBfs;
247+ p->max = max(dBfs, p->max);
236248 }
237249 memset(p->magnitudes, 0, p->rows * sizeof(*p->magnitudes));
238250 p->block_num = 0;
@@ -289,8 +301,7 @@ static int drain(sox_effect_t * effp, sox_sample_t * obuf_, sox_size_t * osamp) · 50 unmodified lines
289301 if (left_over >= p->step_size >> 1)
290302 isamp += p->step_size - left_over;
291303 sox_debug("cols=%i left=%i end=%i", p->cols, p->read, p->end);
292− p->end = 0;
293− p->end_min = -p->dft_size;
304+ p->end = 0, p->end_min = -p->dft_size;
294305 if (flow(effp, ibuf, obuf, &isamp, &isamp) == SOX_SUCCESS && p->block_num) {
295306 p->block_norm *= (double)p->block_steps / p->block_num;
296307 do_column(effp);
@@ -316,8 +327,8 @@ static void make_palette(priv_t const * p, png_color * palette) · 19 unmodified lines
316327 {
317328 int i;
318329
319− if (p->style & 1) {
320− memcpy(palette++, (p->style & 2)? "\337\337\337":"\335\330\320", 3);
330+ if (p->light_background) {
331+ memcpy(palette++, (p->monochrome)? "\337\337\337":"\335\330\320", 3);
321332 memcpy(palette++, "\0\0\0" , 3);
322333 memcpy(palette++, "\077\077\077", 3);
323334 memcpy(palette++, "\077\077\077", 3);
@@ -328,9 +339,9 @@ static void make_palette(priv_t const * p, png_color * palette) · 4 unmodified lines
328339 memcpy(palette++, "\177\177\177", 3);
329340 }
330341 for (i = 0; i < p->spectrum_points; ++i) {
331− double c[3] , x = (double)i / (p->spectrum_points - 1);
332− int at = (p->style & 1)? p->spectrum_points - 1 - i : i;
333− if (p->style > 1) {
342+ double c[3], x = (double)i / (p->spectrum_points - 1);
343+ int at = (p->light_background)? p->spectrum_points - 1 - i : i;
344+ if (p->monochrome) {
334345 c[2] = c[1] = c[0] = x;
335346 if (p->high_colour) {
336347 c[(1 + p->perm) % 3] = x < .4? 0 : 5 / 3. * (x - .4);
@@ -345,13 +356,13 @@ static void make_palette(priv_t const * p, png_color * palette) · 8 unmodified lines
345356 if (p->high_colour) {
346357 static const int states[3][7] = {
347358 {4,5,0,0,2,1,1}, {0,0,2,1,1,3,2}, {4,1,1,3,0,0,2}};
348− int j, phase_num = min(6, x * 7);
359+ int j, phase_num = min(7 * x, 6);
349360 for (j = 0; j < 3; ++j) switch (states[j][phase_num]) {
350361 case 0: c[j] = 0; break;
351362 case 1: c[j] = 1; break;
352363 case 2: c[j] = sin((7 * x - phase_num) * M_PI / 2); break;
353364 case 3: c[j] = cos((7 * x - phase_num) * M_PI / 2); break;
354− case 4: c[j] = 7 * x - phase_num; break;
365+ case 4: c[j] = 7 * x - phase_num; break;
355366 case 5: c[j] = 1 - (7 * x - phase_num); break;
356367 }
357368 } else {
@@ -447,13 +458,12 @@ static int stop(sox_effect_t * effp) · 89 unmodified lines
447458 uLong font_len = 96 * font_y;
448459 int rows = below + p->rows + 30 + 20 * !!p->title;
449460 int cols = left + p->cols + between + spectrum_width + right;
450− sox_bool do_frame = !p->no_axes;
451461 png_byte * pixels = malloc(cols * rows * sizeof(*pixels));
452462 png_bytepp png_rows = malloc(rows * sizeof(*png_rows));
453463 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0,0);
454464 png_infop png_info = png_create_info_struct(png);
455465 png_color palette[256];
456− int i, j, step, tick_len = 2 + do_frame;
466+ int i, j, step, tick_len = 3 - p->no_axes;
457467 char text[200], * prefix;
458468 double limit;
459469
@@ -475,7 +485,7 @@ static int stop(sox_effect_t * effp) · 15 unmodified lines
475485 png_set_IHDR(png, png_info, (size_t)cols, (size_t)rows, 8,
476486 PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
477487 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
478− for (j = 0; j < rows; ++j)
488+ for (j = 0; j < rows; ++j) /* Put (0,0) at bottom-left of PNG */
479489 png_rows[rows - 1 - j] = (png_bytep)(pixels + j * cols);
480490
481491 if (p->title && (i = (int)strlen(p->title) * font_X) < cols + 1) /* Title */
@@ -487,20 +497,20 @@ static int stop(sox_effect_t * effp) · 5 unmodified lines
487497 for (j = 0; j < p->rows; ++j) {
488498 for (i = 0; i < p->cols; ++i)
489499 pixel(left + i, below + j) = colour(p, p->dBfs[i*p->rows + j]);
490− if (do_frame) /* Frame verticals */
500+ if (!p->no_axes) /* Y-axis lines */
491501 pixel(left - 1, below + j) = pixel(left + p->cols,below + j) = Grid;
492502 }
493− if (do_frame) for (i = -1; i <= p->cols; ++i) /* Frame horizontals */
503+ if (!p->no_axes) for (i = -1; i <= p->cols; ++i) /* X-axis lines */
494504 pixel(left + i, below - 1) = pixel(left + i, below + p->rows) = Grid;
495505
496506 /* X-axis */
497− step = axis((double)p->cols * p->step_size * p->block_steps / effp->in_signal.rate, p->cols / (font_X * 9 / 2), &limit, &prefix);
507+ step = axis(secs(p->cols), p->cols / (font_X * 9 / 2), &limit, &prefix);
498508 sprintf(text, "Time (%.1ss)", prefix); /* Axis label */
499509 print_at(left + (p->cols - font_X * (int)strlen(text)) / 2, 24, Text, text);
500510 for (i = 0; i <= limit; i += step) {
501511 int y, x = limit? (double)i / limit * p->cols + .5 : 0;
502512 for (y = 0; y < tick_len; ++y) /* Ticks */
503− pixel(left - 1 + x, below - 1 - y) = pixel(left - 1 + x, below + p->rows + y) = Grid;
513+ pixel(left-1+x, below-1-y) = pixel(left-1+x, below+p->rows+y) = Grid;
504514 if (step == 5 && (i%10))
505515 continue;
506516 sprintf(text, "%g", .1 * i); /* Tick labels */
@@ -510,13 +520,14 @@ static int stop(sox_effect_t * effp) · 3 unmodified lines
510520 }
511521
512522 /* Y-axis */
513− step = axis(effp->in_signal.rate / 2, (p->rows - 1) / ((font_y * 3 + 1) >> 1), &limit, &prefix);
523+ step = axis(effp->in_signal.rate / 2,
524+ (p->rows - 1) / ((font_y * 3 + 1) >> 1), &limit, &prefix);
514525 sprintf(text, "Frequency (%.1sHz)", prefix); /* Axis label */
515526 print_up(10, below + (p->rows - font_X * (int)strlen(text)) / 2, Text, text);
516527 for (i = 0; i <= limit; i += step) {
517528 int x, y = limit? (double)i / limit * (p->rows - 1) + .5 : 0;
518529 for (x = 0; x < tick_len; ++x) /* Ticks */
519− pixel(left - 1 - x, below + y) = pixel(left + p->cols + x, below + y) = Grid;
530+ pixel(left-1-x, below+y) = pixel(left+p->cols+x, below+y) = Grid;
520531 if (step == 5 && (i%10))
521532 continue;
522533 sprintf(text, i?"%5g":" DC", .1 * i); /* Tick labels */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t