Interpret sample counts given for spectrogram's -d and -S options correctly. Previously, they were accepted syntactically (because lsx_parsesamples() is used for parsing the argument), but always interpreted according to a sample rate of 100 kHz; i.e., -d 20000s meant 0.2 seconds even when the sample rate was actually 10 kHz. Not really a bug though, because the possibility to specify samples wasn't documented.
Showing the changes to src/spectrogram.c (1 of 2 files). Show all
Unified · Split
| @@ -44,12 +44,13 @@ static lsx_enum_item const window_options[] = { · 43 unmodified lines | ||
| 44 | 44 | |
| 45 | 45 | typedef struct { |
| 46 | 46 | /* Parameters */ |
| 47 | − double pixels_per_sec, duration, start_time, window_adjust; | |
| 47 | + double pixels_per_sec, window_adjust; | |
| 48 | 48 | int x_size0, y_size, Y_size, dB_range, gain, spectrum_points, perm; |
| 49 | 49 | sox_bool monochrome, light_background, high_colour, slack_overlap, no_axes; |
| 50 | 50 | sox_bool raw, alt_palette, truncate; |
| 51 | 51 | win_type_t win_type; |
| 52 | 52 | char const * out_name, * title, * comment; |
| 53 | + char const *duration_str, *start_time_str; | |
| 53 | 54 | sox_bool using_stdout; /* output image to stdout */ |
| 54 | 55 | |
| 55 | 56 | /* Shared work area */ |
| @@ -93,7 +94,7 @@ static unsigned char const alt_palette[] = · 37 unmodified lines | ||
| 93 | 94 | static int getopts(sox_effect_t * effp, int argc, char **argv) |
| 94 | 95 | { |
| 95 | 96 | priv_t * p = (priv_t *)effp->priv; |
| 96 | − uint64_t duration; | |
| 97 | + uint64_t dummy; | |
| 97 | 98 | char const * next; |
| 98 | 99 | int c; |
| 99 | 100 | lsx_getopt_t optstate; |
| @@ -124,15 +125,15 @@ static int getopts(sox_effect_t * effp, int argc, char **argv) · 24 unmodified lines | ||
| 124 | 125 | case 't': p->title = optstate.arg; break; |
| 125 | 126 | case 'c': p->comment = optstate.arg; break; |
| 126 | 127 | case 'o': p->out_name = optstate.arg; break; |
| 127 | − case 'S': next = lsx_parsesamples(1e5, optstate.arg, &duration, 't'); | |
| 128 | − if (next && !*next) {p->start_time = duration * 1e-5; break;} | |
| 128 | + case 'S': next = lsx_parsesamples(1e5, optstate.arg, &dummy, 't'); | |
| 129 | + if (next && !*next) {p->start_time_str = lsx_strdup(optstate.arg); break;} | |
| 129 | 130 | return lsx_usage(effp); |
| 130 | − case 'd': next = lsx_parsesamples(1e5, optstate.arg, &duration, 't'); | |
| 131 | − if (next && !*next) {p->duration = duration * 1e-5; break;} | |
| 131 | + case 'd': next = lsx_parsesamples(1e5, optstate.arg, &dummy, 't'); | |
| 132 | + if (next && !*next) {p->duration_str = lsx_strdup(optstate.arg); break;} | |
| 132 | 133 | return lsx_usage(effp); |
| 133 | 134 | default: lsx_fail("invalid option `-%c'", optstate.opt); return lsx_usage(effp); |
| 134 | 135 | } |
| 135 | − if (!!p->x_size0 + !!p->pixels_per_sec + !!p->duration > 2) { | |
| 136 | + if (!!p->x_size0 + !!p->pixels_per_sec + !!p->duration_str > 2) { | |
| 136 | 137 | lsx_fail("only two of -x, -X, -d may be given"); |
| 137 | 138 | return SOX_EOF; |
| 138 | 139 | } |
| @@ -202,11 +203,22 @@ static void rdft_p(double const * q, double const * in, double * out, int n) · 63 unmodified lines | ||
| 202 | 203 | static int start(sox_effect_t * effp) |
| 203 | 204 | { |
| 204 | 205 | priv_t * p = (priv_t *)effp->priv; |
| 205 | − double actual, duration = p->duration, pixels_per_sec = p->pixels_per_sec; | |
| 206 | + double actual, duration = 0.0, start_time = 0.0, | |
| 207 | + pixels_per_sec = p->pixels_per_sec; | |
| 208 | + uint64_t d; | |
| 206 | 209 | |
| 207 | 210 | memset(&p->WORK, 0, sizeof(*p) - field_offset(priv_t, WORK)); |
| 208 | − | |
| 209 | − p->skip = p->start_time * effp->in_signal.rate + .5; | |
| 211 | + | |
| 212 | + if (p->duration_str) { | |
| 213 | + lsx_parsesamples(effp->in_signal.rate, p->duration_str, &d, 't'); | |
| 214 | + duration = d / effp->in_signal.rate; | |
| 215 | + } | |
| 216 | + if (p->start_time_str) { | |
| 217 | + lsx_parsesamples(effp->in_signal.rate, p->start_time_str, &d, 't'); | |
| 218 | + start_time = d / effp->in_signal.rate; | |
| 219 | + p->skip = d; | |
| 220 | + } | |
| 221 | + | |
| 210 | 222 | p->x_size = p->x_size0; |
| 211 | 223 | while (sox_true) { |
| 212 | 224 | if (!pixels_per_sec && p->x_size && duration) |
| @@ -215,7 +227,7 @@ static int start(sox_effect_t * effp) · 2 unmodified lines | ||
| 215 | 227 | p->x_size = min(5000, (int)(pixels_per_sec * duration + .5)); |
| 216 | 228 | if (!duration && effp->in_signal.length) { |
| 217 | 229 | duration = effp->in_signal.length / (effp->in_signal.rate * effp->in_signal.channels); |
| 218 | − duration -= p->start_time; | |
| 230 | + duration -= start_time; | |
| 219 | 231 | if (duration <= 0) |
| 220 | 232 | duration = 1; |
| 221 | 233 | continue; |