Lines Matching +full:1 +full:p
39 #define is_p2(x) !(x & (x - 1))
117 double *window; /* [dft_size + 1] */
120 double *magnitudes; /* [dft_size / 2 + 1] */
125 ((double)(cols) * p->step_size * p->block_steps / effp->in_signal.rate)
189 priv_t *p = effp->priv; in getopts() local
195 lsx_getopt_init(argc, argv, "+S:d:x:X:y:Y:z:Z:q:p:W:w:st:c:AarmnlhTo:", in getopts()
196 NULL, lsx_getopt_flag_none, 1, &optstate); in getopts()
198 p->dB_range = 120; in getopts()
199 p->spectrum_points = 249; in getopts()
200 p->perm = 1; in getopts()
201 p->out_name = "spectrogram.png"; in getopts()
202 p->comment = "Created by SoX"; in getopts()
204 while ((c = lsx_getopt(&optstate)) != -1) { in getopts()
207 GETOPT_NUMERIC(optstate, 'X', pixels_per_sec, 1, 5000) in getopts()
212 GETOPT_NUMERIC(optstate, 'q', spectrum_points, 0, p->spectrum_points) in getopts()
213 GETOPT_NUMERIC(optstate, 'p', perm, 1, 6) in getopts()
215 case 'w': p->win_type = lsx_enum_option(c, optstate.arg, window_options); in getopts()
217 case 's': p->slack_overlap = sox_true; break; in getopts()
218 case 'A': p->alt_palette = sox_true; break; in getopts()
219 case 'a': p->no_axes = sox_true; break; in getopts()
220 case 'r': p->raw = sox_true; break; in getopts()
221 case 'm': p->monochrome = sox_true; break; in getopts()
222 case 'n': p->normalize = sox_true; break; in getopts()
223 case 'l': p->light_background = sox_true; break; in getopts()
224 case 'h': p->high_colour = sox_true; break; in getopts()
225 case 'T': p->truncate = sox_true; break; in getopts()
226 case 't': p->title = optstate.arg; break; in getopts()
227 case 'c': p->comment = optstate.arg; break; in getopts()
228 case 'o': p->out_name = optstate.arg; break; in getopts()
232 p->start_time_str = lsx_strdup(optstate.arg); in getopts()
237 next = lsx_parsesamples(1e5, optstate.arg, &dummy, 't'); in getopts()
239 p->duration_str = lsx_strdup(optstate.arg); in getopts()
249 if (!!p->x_size0 + !!p->pixels_per_sec + !!p->duration_str > 2) { in getopts()
254 if (p->y_size && p->Y_size) { in getopts()
259 p->gain = -p->gain; in getopts()
260 --p->perm; in getopts()
261 p->spectrum_points += 2; in getopts()
262 if (p->alt_palette) in getopts()
263 p->spectrum_points = min(p->spectrum_points, alt_palette_len); in getopts()
264 p->shared_ptr = &p->shared; in getopts()
266 if (!strcmp(p->out_name, "-")) { in getopts()
273 p->using_stdout = sox_true; in getopts()
276 return optstate.ind != argc || p->win_type == INT_MAX ? in getopts()
280 static double make_window(priv_t *p, int end) in make_window() argument
283 double *w = end < 0 ? p->window : p->window + end; in make_window()
285 int n = 1 + p->dft_size - abs(end); in make_window()
289 memset(p->window, 0, sizeof(*p->window) * (p->dft_size + 1)); in make_window()
292 w[i] = 1; in make_window()
294 switch (p->win_type) { in make_window()
300 beta = lsx_kaiser_beta((p->dB_range + p->gain) * in make_window()
301 (1.1 + p->window_adjust / 50), .1); in make_window()
305 lsx_apply_dolph(w, n, (p->dB_range + p->gain) * in make_window()
306 (1.005 + p->window_adjust / 50) + 6); in make_window()
309 for (i = 0; i < p->dft_size; ++i) in make_window()
310 sum += p->window[i]; in make_window()
313 for (--n, i = 0; i < p->dft_size; ++i) in make_window()
314 p->window[i] *= 2 / sum * sqr((double)n / p->dft_size); in make_window()
321 double *q = lsx_malloc(2 * (n / 2 + 1) * n * sizeof(*q)); in rdft_init()
322 double *p = q; in rdft_init() local
327 *p++ = cos(2 * M_PI * j * i / n); in rdft_init()
328 *p++ = sin(2 * M_PI * j * i / n); in rdft_init()
355 priv_t *p = effp->priv; in start() local
359 double pixels_per_sec = p->pixels_per_sec; in start()
362 memset(&p->WORK, 0, sizeof(*p) - field_offset(priv_t, WORK)); in start()
364 if (p->duration_str) { in start()
365 lsx_parsesamples(effp->in_signal.rate, p->duration_str, &d, 't'); in start()
369 if (p->start_time_str) { in start()
373 if (!lsx_parseposition(effp->in_signal.rate, p->start_time_str, &d, in start()
380 p->skip = d; in start()
383 p->x_size = p->x_size0; in start()
386 if (!pixels_per_sec && p->x_size && duration) in start()
387 pixels_per_sec = min(5000, p->x_size / duration); in start()
388 else if (!p->x_size && pixels_per_sec && duration) in start()
389 p->x_size = min(MAX_X_SIZE, (int)(pixels_per_sec * duration + .5)); in start()
396 duration = 1; in start()
398 } else if (!p->x_size) { in start()
399 p->x_size = 800; in start()
408 if (p->y_size) { in start()
409 p->dft_size = 2 * (p->y_size - 1); in start()
410 if (!is_p2(p->dft_size) && !effp->flow) in start()
411 p->shared = rdft_init(p->dft_size); in start()
413 int y = max(32, (p->Y_size? p->Y_size : 550) / effp->in_signal.channels - 2); in start()
414 for (p->dft_size = 128; p->dft_size <= y; p->dft_size <<= 1); in start()
418 p->buf = lsx_calloc(p->dft_size, sizeof(*p->buf)); in start()
419 p->dft_buf = lsx_calloc(p->dft_size, sizeof(*p->dft_buf)); in start()
420 p->window = lsx_calloc(p->dft_size + 1, sizeof(*p->window)); in start()
421 p->magnitudes = lsx_calloc(p->dft_size / 2 + 1, sizeof(*p->magnitudes)); in start()
423 if (is_p2(p->dft_size) && !effp->flow) in start()
424 lsx_safe_rdft(p->dft_size, 1, p->dft_buf); in start()
427 duration, p->x_size, pixels_per_sec, p->dft_size); in start()
429 p->end = p->dft_size; in start()
430 p->rows = (p->dft_size >> 1) + 1; in start()
431 actual = make_window(p, p->last_end = 0); in start()
432 lsx_debug("window_density=%g", actual / p->dft_size); in start()
433 p->step_size = (p->slack_overlap ? sqrt(actual * p->dft_size) : actual) + 0.5; in start()
434 p->block_steps = effp->in_signal.rate / pixels_per_sec; in start()
435 p->step_size = in start()
436 p->block_steps / ceil((double)p->block_steps / p->step_size) + 0.5; in start()
437 p->block_steps = floor((double)p->block_steps / p->step_size + 0.5); in start()
438 p->block_norm = 1.0 / p->block_steps; in start()
439 actual = effp->in_signal.rate / p->step_size / p->block_steps; in start()
442 lsx_debug("step_size=%i block_steps=%i", p->step_size, p->block_steps); in start()
443 p->max = -p->dB_range; in start()
444 p->read = (p->step_size - p->dft_size) / 2; in start()
451 priv_t *p = effp->priv; in do_column() local
454 if (p->cols == p->x_size) { in do_column()
455 p->truncated = sox_true; in do_column()
457 lsx_report("PNG truncated at %g seconds", secs(p->cols)); in do_column()
458 return p->truncate ? SOX_EOF : SOX_SUCCESS; in do_column()
461 ++p->cols; in do_column()
462 p->dBfs = lsx_realloc(p->dBfs, p->cols * p->rows * sizeof(*p->dBfs)); in do_column()
465 for (i = 0; i < p->rows; ++i) { in do_column()
466 double dBfs = 10 * log10(p->magnitudes[i] * p->block_norm); in do_column()
467 p->dBfs[(p->cols - 1) * p->rows + i] = dBfs + p->gain; in do_column()
468 p->max = max(dBfs, p->max); in do_column()
471 memset(p->magnitudes, 0, p->rows * sizeof(*p->magnitudes)); in do_column()
472 p->block_num = 0; in do_column()
481 priv_t *p = effp->priv; in flow() local
487 if (p->skip) { in flow()
488 if (p->skip >= len) { in flow()
489 p->skip -= len; in flow()
492 ibuf += p->skip; in flow()
493 len -= p->skip; in flow()
494 p->skip = 0; in flow()
497 while (!p->truncated) { in flow()
498 if (p->read == p->step_size) { in flow()
499 memmove(p->buf, p->buf + p->step_size, in flow()
500 (p->dft_size - p->step_size) * sizeof(*p->buf)); in flow()
501 p->read = 0; in flow()
504 for (; len && p->read < p->step_size; --len, ++p->read, --p->end) in flow()
505 p->buf[p->dft_size - p->step_size + p->read] = in flow()
508 if (p->read != p->step_size) in flow()
511 if ((p->end = max(p->end, p->end_min)) != p->last_end) in flow()
512 make_window(p, p->last_end = p->end); in flow()
514 for (i = 0; i < p->dft_size; ++i) in flow()
515 p->dft_buf[i] = p->buf[i] * p->window[i]; in flow()
517 if (is_p2(p->dft_size)) { in flow()
518 lsx_safe_rdft(p->dft_size, 1, p->dft_buf); in flow()
519 p->magnitudes[0] += sqr(p->dft_buf[0]); in flow()
521 for (i = 1; i < p->dft_size >> 1; ++i) in flow()
522 p->magnitudes[i] += sqr(p->dft_buf[2*i]) + sqr(p->dft_buf[2*i+1]); in flow()
524 p->magnitudes[p->dft_size >> 1] += sqr(p->dft_buf[1]); in flow()
527 rdft_p(*p->shared_ptr, p->dft_buf, p->magnitudes, p->dft_size); in flow()
529 if (++p->block_num == p->block_steps && do_column(effp) == SOX_EOF) in flow()
538 priv_t *p = effp->priv; in drain() local
540 if (!p->truncated) { in drain()
541 sox_sample_t * ibuf = lsx_calloc(p->dft_size, sizeof(*ibuf)); in drain()
542 sox_sample_t * obuf = lsx_calloc(p->dft_size, sizeof(*obuf)); in drain()
543 size_t isamp = (p->dft_size - p->step_size) / 2; in drain()
544 int left_over = (isamp + p->read) % p->step_size; in drain()
546 if (left_over >= p->step_size >> 1) in drain()
547 isamp += p->step_size - left_over; in drain()
549 lsx_debug("cols=%i left=%i end=%i", p->cols, p->read, p->end); in drain()
551 p->end = 0, p->end_min = -p->dft_size; in drain()
553 if (flow(effp, ibuf, obuf, &isamp, &isamp) == SOX_SUCCESS && p->block_num) { in drain()
554 p->block_norm *= (double)p->block_steps / p->block_num; in drain()
558 lsx_debug("flushed cols=%i left=%i end=%i", p->cols, p->read, p->end); in drain()
576 static unsigned colour(const priv_t *p, double x) in colour() argument
578 unsigned c = x < -p->dB_range ? 0 : x >= 0 ? p->spectrum_points - 1 : in colour()
579 1 + (1 + x / p->dB_range) * (p->spectrum_points - 2); in colour()
583 static void make_palette(const priv_t *p, png_color *palette) in make_palette() argument
594 if (p->light_background) { in make_palette()
595 memcpy(palette++, p->monochrome ? mbgnd : lbgnd, 3); in make_palette()
606 for (i = 0; i < p->spectrum_points; ++i) { in make_palette()
608 double x = (double)i / (p->spectrum_points - 1); in make_palette()
609 int at = p->light_background ? p->spectrum_points - 1 - i : i; in make_palette()
611 if (p->monochrome) { in make_palette()
612 c[2] = c[1] = c[0] = x; in make_palette()
613 if (p->high_colour) { in make_palette()
614 c[(1 + p->perm) % 3] = x < .4? 0 : 5 / 3. * (x - .4); in make_palette()
615 if (p->perm < 3) in make_palette()
616 c[(2 + p->perm) % 3] = x < .4? 0 : 5 / 3. * (x - .4); in make_palette()
619 palette[at].green= .5 + 255 * c[1]; in make_palette()
624 if (p->high_colour) { in make_palette()
626 { 4, 5, 0, 0, 2, 1, 1 }, in make_palette()
627 { 0, 0, 2, 1, 1, 3, 2 }, in make_palette()
628 { 4, 1, 1, 3, 0, 0, 2 }, in make_palette()
635 case 1: c[j] = 1; break; in make_palette()
639 case 5: c[j] = 1 - (7 * x - phase_num); break; in make_palette()
642 } else if (p->alt_palette) { in make_palette()
643 int n = (double)i / (p->spectrum_points - 1) * (alt_palette_len - 1) + .5; in make_palette()
645 c[1] = alt_palette[3 * n + 1] / 255.; in make_palette()
649 else if (x < .73) c[0] = 1 * sin((x - .13) / .60 * M_PI / 2); in make_palette()
650 else c[0] = 1; in make_palette()
651 if (x < .60) c[1] = 0; in make_palette()
652 else if (x < .91) c[1] = 1 * sin((x - .60) / .31 * M_PI / 2); in make_palette()
653 else c[1] = 1; in make_palette()
659 palette[at].red = .5 + 255 * c[p->perm % 3]; in make_palette()
660 palette[at].green= .5 + 255 * c[(1 + p->perm + (p->perm % 2)) % 3]; in make_palette()
661 palette[at].blue = .5 + 255 * c[(2 + p->perm - (p->perm % 2)) % 3]; in make_palette()
710 #define font_X (font_x + 1)
714 #define print_up(x,y,c,t) print_at_(pixels,cols,x,y,c,t,1)
720 int pos = ((*text < ' ' || *text > '~'? '~' + 1 : *text) - ' ') * font_y; in print_at_()
725 for (j = 0; j < font_x; ++j, line <<= 1) { in print_at_()
729 case 1: pixel(x + i, y + j) = c; break; in print_at_()
737 case 1: y += font_X; break; in print_at_()
744 double scale = 1, step = max(1, 10 * to); in axis()
752 for (i = 5; i; i >>= 1) { in axis()
755 log_10 -= i > 1; in axis()
777 priv_t *p = effp->priv; in stop() local
781 int c_rows = p->rows * chans + chans - 1; in stop()
782 int rows = p->raw? c_rows : below + c_rows + 30 + 20 * !!p->title; in stop()
783 int cols = p->raw? p->cols : left + p->cols + between + spectrum_width + right; in stop()
792 int tick_len = 3 - p->no_axes; in stop()
798 free(p->shared); in stop()
800 if (p->using_stdout) { in stop()
804 file = fopen(p->out_name, "wb"); in stop()
806 lsx_fail("failed to create `%s': %s", p->out_name, strerror(errno)); in stop()
811 lsx_debug("signal-max=%g", p->max); in stop()
816 make_palette(p, palette); in stop()
820 png_set_PLTE(png, png_info, palette, fixed_palette + p->spectrum_points); in stop()
826 png_rows[rows - 1 - j] = pixels + j * cols; in stop()
830 if (p->normalize) in stop()
834 autogain = -p->max; in stop()
839 if (p->normalize) { in stop()
841 for (i = p->rows * p->cols; i > 0; i--) in stop()
845 base = !p->raw * below + (chans - 1 - k) * (p->rows + 1); in stop()
847 for (j = 0; j < p->rows; ++j) { in stop()
848 for (i = 0; i < p->cols; ++i) in stop()
849 pixel(!p->raw * left + i, base + j) = colour(p, q->dBfs[i*p->rows + j]); in stop()
851 if (!p->raw && !p->no_axes) /* Y-axis lines */ in stop()
852 pixel(left - 1, base + j) = pixel(left + p->cols, base + j) = Grid; in stop()
855 if (!p->raw && !p->no_axes) /* X-axis lines */ in stop()
856 for (i = -1; i <= p->cols; ++i) in stop()
857 pixel(left + i, base - 1) = pixel(left + i, base + p->rows) = Grid; in stop()
860 if (!p->raw) { in stop()
861 if (p->title && (i = strlen(p->title) * font_X) < cols + 1) /* Title */ in stop()
862 print_at((cols - i) / 2, rows - font_y, Text, p->title); in stop()
864 if (strlen(p->comment) * font_X < cols + 1) /* Footer comment */ in stop()
865 print_at(1, font_y, Text, p->comment); in stop()
868 step = axis(secs(p->cols), p->cols / (font_X * 9 / 2), &limit, &prefix); in stop()
869 sprintf(text, "Time (%.1ss)", prefix); /* Axis label */ in stop()
870 print_at(left + (p->cols - font_X * strlen(text)) / 2, 24, Text, text); in stop()
873 int x = limit ? (double)i / limit * p->cols + .5 : 0; in stop()
877 pixel(left-1+x, below-1-y) = pixel(left-1+x, below+c_rows+y) = Grid; in stop()
882 sprintf(text, "%g", .1 * i); /* Tick labels */ in stop()
890 (p->rows - 1) / ((font_y * 3 + 1) >> 1), &limit, &prefix); in stop()
891 sprintf(text, "Frequency (%.1sHz)", prefix); /* Axis label */ in stop()
895 base = below + k * (p->rows + 1); in stop()
898 int y = limit ? (double)i / limit * (p->rows - 1) + .5 : 0; in stop()
902 pixel(left-1-x, base+y) = pixel(left+p->cols+x, base+y) = Grid; in stop()
904 if ((step == 5 && (i%10)) || (!i && k && chans > 1)) in stop()
907 sprintf(text, i?"%5g":" DC", .1 * i); /* Tick labels */ in stop()
909 sprintf(text, i?"%g":"DC", .1 * i); in stop()
910 print_at(left + p->cols + 6, base + y + 5, Labels, text); in stop()
919 png_byte b = colour(p, p->dB_range * (j / (k - 1.) - 1)); in stop()
921 pixel(cols - right - 1 - i, base + j) = b; in stop()
924 step = 10 * ceil(p->dB_range / 10. * (font_y + 2) / (k - 1)); in stop()
926 for (i = 0; i <= p->dB_range; i += step) { /* (Tick) labels */ in stop()
927 int y = (double)i / p->dB_range * (k - 1) + .5; in stop()
928 sprintf(text, "%+i", i - p->gain - p->dB_range - (int)(autogain+0.5)); in stop()
929 print_at(cols - right + 1, base + y + 5, Labels, text); in stop()
938 if (!p->using_stdout) in stop()
945 free(p->dBfs); in stop()
946 free(p->buf); in stop()
947 free(p->dft_buf); in stop()
948 free(p->window); in stop()
949 free(p->magnitudes); in stop()
956 priv_t *p = effp->priv; in end() local
961 free(p->dBfs); in end()
984 "\t-y num\tY-axis size in pixels (per channel); slow if not 1 + 2^n", in lsx_spectrogram_effect_fn()
998 "\t-p num\tPermute colours (1 - 6); default 1", in lsx_spectrogram_effect_fn()
1003 "\t-d time\tAudio duration to fit to X-axis; e.g. 1:00, 48", in lsx_spectrogram_effect_fn()