Showing the changes to src/spectrogram.c (1 of 3 files). Show all
Unified · Split
| @@ -43,7 +43,7 @@ typedef struct { · 42 unmodified lines | ||
| 43 | 43 | double pixels_per_sec, duration, start_time, window_adjust; |
| 44 | 44 | int x_size0, y_size, Y_size, dB_range, gain, spectrum_points, perm; |
| 45 | 45 | sox_bool monochrome, light_background, high_colour, slack_overlap, no_axes; |
| 46 | − sox_bool alt_palette, truncate; | |
| 46 | + sox_bool raw, alt_palette, truncate; | |
| 47 | 47 | win_type_t win_type; |
| 48 | 48 | char const * out_name, * title, * comment; |
| 49 | 49 | |
| @@ -95,7 +95,7 @@ static int getopts(sox_effect_t * effp, int argc, char **argv) · 45 unmodified lines | ||
| 95 | 95 | p->dB_range = 120, p->spectrum_points = 249, p->perm = 1; /* Non-0 defaults */ |
| 96 | 96 | p->out_name = "spectrogram.png", p->comment = "Created by SoX"; |
| 97 | 97 | |
| 98 | − while ((c = lsx_getopt(argc, argv, "+S:d:x:X:y:Y:z:Z:q:p:W:w:st:c:AamlhTo:")) != -1) switch (c) { | |
| 98 | + while ((c = lsx_getopt(argc, argv, "+S:d:x:X:y:Y:z:Z:q:p:W:w:st:c:AarmlhTo:")) != -1) switch (c) { | |
| 99 | 99 | GETOPT_NUMERIC('x', x_size0 , 100, 5000) |
| 100 | 100 | GETOPT_NUMERIC('X', pixels_per_sec, 1 , 5000) |
| 101 | 101 | GETOPT_NUMERIC('y', y_size , 64 , 1200) |
| @@ -109,6 +109,7 @@ static int getopts(sox_effect_t * effp, int argc, char **argv) · 7 unmodified lines | ||
| 109 | 109 | case 's': p->slack_overlap = sox_true; break; |
| 110 | 110 | case 'A': p->alt_palette = sox_true; break; |
| 111 | 111 | case 'a': p->no_axes = sox_true; break; |
| 112 | + case 'r': p->raw = sox_true; break; | |
| 112 | 113 | case 'm': p->monochrome = sox_true; break; |
| 113 | 114 | case 'l': p->light_background = sox_true; break; |
| 114 | 115 | case 'h': p->high_colour = sox_true; break; |
| @@ -489,8 +490,8 @@ static int stop(sox_effect_t * effp) · 374 unmodified lines | ||
| 489 | 490 | uLong font_len = 96 * font_y; |
| 490 | 491 | int chans = effp->in_signal.channels; |
| 491 | 492 | int c_rows = p->rows * chans + chans - 1; |
| 492 | − int rows = below + c_rows + 30 + 20 * !!p->title; | |
| 493 | − int cols = left + p->cols + between + spectrum_width + right; | |
| 493 | + int rows = p->raw? c_rows : below + c_rows + 30 + 20 * !!p->title; | |
| 494 | + int cols = p->raw? p->cols : left + p->cols + between + spectrum_width + right; | |
| 494 | 495 | png_byte * pixels = lsx_malloc(cols * rows * sizeof(*pixels)); |
| 495 | 496 | png_bytepp png_rows = lsx_malloc(rows * sizeof(*png_rows)); |
| 496 | 497 | png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0,0); |
| @@ -518,77 +519,79 @@ static int stop(sox_effect_t * effp) · 21 unmodified lines | ||
| 518 | 519 | for (j = 0; j < rows; ++j) /* Put (0,0) at bottom-left of PNG */ |
| 519 | 520 | png_rows[rows - 1 - j] = (png_bytep)(pixels + j * cols); |
| 520 | 521 | |
| 521 | − if (p->title && (i = (int)strlen(p->title) * font_X) < cols + 1) /* Title */ | |
| 522 | − print_at((cols - i) / 2, rows - font_y, Text, p->title); | |
| 523 | − if ((int)strlen(p->comment) * font_X < cols + 1) /* Footer comment */ | |
| 524 | − print_at(1, font_y, Text, p->comment); | |
| 525 | − | |
| 526 | 522 | /* Spectrogram */ |
| 527 | 523 | for (k = 0; k < chans; ++k) { |
| 528 | 524 | priv_t * q = (priv_t *)(effp - effp->flow + k)->priv; |
| 529 | − base = below + (chans - 1 - k) * (p->rows + 1); | |
| 525 | + base = !p->raw * below + (chans - 1 - k) * (p->rows + 1); | |
| 530 | 526 | for (j = 0; j < p->rows; ++j) { |
| 531 | 527 | for (i = 0; i < p->cols; ++i) |
| 532 | − pixel(left + i, base + j) = colour(p, q->dBfs[i*p->rows + j]); | |
| 533 | − if (!p->no_axes) /* Y-axis lines */ | |
| 528 | + pixel(!p->raw * left + i, base + j) = colour(p, q->dBfs[i*p->rows + j]); | |
| 529 | + if (!p->raw && !p->no_axes) /* Y-axis lines */ | |
| 534 | 530 | pixel(left - 1, base + j) = pixel(left + p->cols, base + j) = Grid; |
| 535 | 531 | } |
| 536 | − if (!p->no_axes) for (i = -1; i <= p->cols; ++i) /* X-axis lines */ | |
| 532 | + if (!p->raw && !p->no_axes) for (i = -1; i <= p->cols; ++i) /* X-axis lines */ | |
| 537 | 533 | pixel(left + i, base - 1) = pixel(left + i, base + p->rows) = Grid; |
| 538 | 534 | } |
| 539 | 535 | |
| 540 | − /* X-axis */ | |
| 541 | − step = axis(secs(p->cols), p->cols / (font_X * 9 / 2), &limit, &prefix); | |
| 542 | − sprintf(text, "Time (%.1ss)", prefix); /* Axis label */ | |
| 543 | − print_at(left + (p->cols - font_X * (int)strlen(text)) / 2, 24, Text, text); | |
| 544 | − for (i = 0; i <= limit; i += step) { | |
| 545 | − int y, x = limit? (double)i / limit * p->cols + .5 : 0; | |
| 546 | − for (y = 0; y < tick_len; ++y) /* Ticks */ | |
| 547 | − pixel(left-1+x, below-1-y) = pixel(left-1+x, below+c_rows+y) = Grid; | |
| 548 | − if (step == 5 && (i%10)) | |
| 549 | − continue; | |
| 550 | − sprintf(text, "%g", .1 * i); /* Tick labels */ | |
| 551 | − x = left + x - 3 * strlen(text); | |
| 552 | − print_at(x, below - 6, Labels, text); | |
| 553 | − print_at(x, below + c_rows + 14, Labels, text); | |
| 554 | − } | |
| 536 | + if (!p->raw) { | |
| 537 | + if (p->title && (i = (int)strlen(p->title) * font_X) < cols + 1) /* Title */ | |
| 538 | + print_at((cols - i) / 2, rows - font_y, Text, p->title); | |
| 555 | 539 | |
| 556 | − /* Y-axis */ | |
| 557 | − step = axis(effp->in_signal.rate / 2, | |
| 558 | − (p->rows - 1) / ((font_y * 3 + 1) >> 1), &limit, &prefix); | |
| 559 | − sprintf(text, "Frequency (%.1sHz)", prefix); /* Axis label */ | |
| 560 | − print_up(10, below + (c_rows - font_X * (int)strlen(text)) / 2, Text, text); | |
| 561 | − for (k = 0; k < chans; ++k) { | |
| 562 | − base = below + k * (p->rows + 1); | |
| 540 | + if ((int)strlen(p->comment) * font_X < cols + 1) /* Footer comment */ | |
| 541 | + print_at(1, font_y, Text, p->comment); | |
| 542 | + | |
| 543 | + /* X-axis */ | |
| 544 | + step = axis(secs(p->cols), p->cols / (font_X * 9 / 2), &limit, &prefix); | |
| 545 | + sprintf(text, "Time (%.1ss)", prefix); /* Axis label */ | |
| 546 | + print_at(left + (p->cols - font_X * (int)strlen(text)) / 2, 24, Text, text); | |
| 563 | 547 | for (i = 0; i <= limit; i += step) { |
| 564 | − int x, y = limit? (double)i / limit * (p->rows - 1) + .5 : 0; | |
| 565 | − for (x = 0; x < tick_len; ++x) /* Ticks */ | |
| 566 | − pixel(left-1-x, base+y) = pixel(left+p->cols+x, base+y) = Grid; | |
| 567 | − if ((step == 5 && (i%10)) || (!i && k && chans > 1)) | |
| 548 | + int y, x = limit? (double)i / limit * p->cols + .5 : 0; | |
| 549 | + for (y = 0; y < tick_len; ++y) /* Ticks */ | |
| 550 | + pixel(left-1+x, below-1-y) = pixel(left-1+x, below+c_rows+y) = Grid; | |
| 551 | + if (step == 5 && (i%10)) | |
| 568 | 552 | continue; |
| 569 | − sprintf(text, i?"%5g":" DC", .1 * i); /* Tick labels */ | |
| 570 | − print_at(left - 4 - font_X * 5, base + y + 5, Labels, text); | |
| 571 | − sprintf(text, i?"%g":"DC", .1 * i); | |
| 572 | − print_at(left + p->cols + 6, base + y + 5, Labels, text); | |
| 553 | + sprintf(text, "%g", .1 * i); /* Tick labels */ | |
| 554 | + x = left + x - 3 * strlen(text); | |
| 555 | + print_at(x, below - 6, Labels, text); | |
| 556 | + print_at(x, below + c_rows + 14, Labels, text); | |
| 573 | 557 | } |
| 574 | − } | |
| 575 | 558 | |
| 576 | − /* Z-axis */ | |
| 577 | − k = min(400, c_rows); | |
| 578 | − base = below + (c_rows - k) / 2; | |
| 579 | − print_at(cols - right - 2 - font_X, base - 13, Text, "dBFS");/* Axis label */ | |
| 580 | − for (j = 0; j < k; ++j) { /* Spectrum */ | |
| 581 | − png_byte b = colour(p, p->dB_range * (j / (k - 1.) - 1)); | |
| 582 | − for (i = 0; i < spectrum_width; ++i) | |
| 583 | − pixel(cols - right - 1 - i, base + j) = b; | |
| 584 | − } | |
| 585 | − step = 10 * ceil(p->dB_range / 10. * (font_y + 2) / (k - 1)); | |
| 586 | − for (i = 0; i <= p->dB_range; i += step) { /* (Tick) labels */ | |
| 587 | − int y = (double)i / p->dB_range * (k - 1) + .5; | |
| 588 | − sprintf(text, "%+i", i - p->gain - p->dB_range); | |
| 589 | − print_at(cols - right + 1, base + y + 5, Labels, text); | |
| 590 | − } | |
| 559 | + /* Y-axis */ | |
| 560 | + step = axis(effp->in_signal.rate / 2, | |
| 561 | + (p->rows - 1) / ((font_y * 3 + 1) >> 1), &limit, &prefix); | |
| 562 | + sprintf(text, "Frequency (%.1sHz)", prefix); /* Axis label */ | |
| 563 | + print_up(10, below + (c_rows - font_X * (int)strlen(text)) / 2, Text, text); | |
| 564 | + for (k = 0; k < chans; ++k) { | |
| 565 | + base = below + k * (p->rows + 1); | |
| 566 | + for (i = 0; i <= limit; i += step) { | |
| 567 | + int x, y = limit? (double)i / limit * (p->rows - 1) + .5 : 0; | |
| 568 | + for (x = 0; x < tick_len; ++x) /* Ticks */ | |
| 569 | + pixel(left-1-x, base+y) = pixel(left+p->cols+x, base+y) = Grid; | |
| 570 | + if ((step == 5 && (i%10)) || (!i && k && chans > 1)) | |
| 571 | + continue; | |
| 572 | + sprintf(text, i?"%5g":" DC", .1 * i); /* Tick labels */ | |
| 573 | + print_at(left - 4 - font_X * 5, base + y + 5, Labels, text); | |
| 574 | + sprintf(text, i?"%g":"DC", .1 * i); | |
| 575 | + print_at(left + p->cols + 6, base + y + 5, Labels, text); | |
| 576 | + } | |
| 577 | + } | |
| 591 | 578 | |
| 579 | + /* Z-axis */ | |
| 580 | + k = min(400, c_rows); | |
| 581 | + base = below + (c_rows - k) / 2; | |
| 582 | + print_at(cols - right - 2 - font_X, base - 13, Text, "dBFS");/* Axis label */ | |
| 583 | + for (j = 0; j < k; ++j) { /* Spectrum */ | |
| 584 | + png_byte b = colour(p, p->dB_range * (j / (k - 1.) - 1)); | |
| 585 | + for (i = 0; i < spectrum_width; ++i) | |
| 586 | + pixel(cols - right - 1 - i, base + j) = b; | |
| 587 | + } | |
| 588 | + step = 10 * ceil(p->dB_range / 10. * (font_y + 2) / (k - 1)); | |
| 589 | + for (i = 0; i <= p->dB_range; i += step) { /* (Tick) labels */ | |
| 590 | + int y = (double)i / p->dB_range * (k - 1) + .5; | |
| 591 | + sprintf(text, "%+i", i - p->gain - p->dB_range); | |
| 592 | + print_at(cols - right + 1, base + y + 5, Labels, text); | |
| 593 | + } | |
| 594 | + } | |
| 592 | 595 | free(font); |
| 593 | 596 | png_set_rows(png, png_info, png_rows); |
| 594 | 597 | png_write_png(png, png_info, PNG_TRANSFORM_IDENTITY, NULL); |
| @@ -619,6 +622,7 @@ sox_effect_handler_t const * lsx_spectrogram_effect_fn(void) · 24 unmodified lines | ||
| 619 | 622 | "\t-W num\tWindow adjust parameter (-10 - 10); applies only to Kaiser", |
| 620 | 623 | "\t-s\tSlack overlap of windows", |
| 621 | 624 | "\t-a\tSuppress axis lines", |
| 625 | + "\t-r\tRaw spectrogram; no axes or legends", | |
| 622 | 626 | "\t-l\tLight background", |
| 623 | 627 | "\t-m\tMonochrome", |
| 624 | 628 | "\t-h\tHigh colour", |