From: Eric Wong <normalperson@yhbt.net>
To: "Måns Rullgård" <mans@mansr.com>
Cc: Martin Guy <martinwguy@gmail.com>, sox-devel@lists.sourceforge.net
Subject: [PATCH RESEND 7/9] spectrogram: remove arbitrary limit on height of spectrogram
Date: Fri, 31 Jul 2020 09:37:59 +0000 [thread overview]
Message-ID: <20200731093801.23548-8-normalperson@yhbt.net> (raw)
In-Reply-To: <20200731093801.23548-1-normalperson@yhbt.net>
From: Martin Guy <martinwguy@gmail.com>
Sox had an arbitrary limit of 8193 on the vertical axis size
based on MAX_FFT_SIZE=4096 and had fixed-size arrays for its data.
This is both wasteful of memory for smaller FFTs and stops us producing
more detailed output for no obvious reason.
This patch removes the size limit on Y-axis-height by making array
allocation dynamic. In practice, you can't remove the limit as getopt
insists on minimum and maximum values for numeric arguments, so we
copy the similarly arbitrary limit of 200000 from MAX_X_SIZE.
Tested-by: Eric Wong <normalperson@yhbt.net>
---
src/spectrogram.c | 37 +++++++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/src/spectrogram.c b/src/spectrogram.c
index afb0b0e8..b38d2124 100644
--- a/src/spectrogram.c
+++ b/src/spectrogram.c
@@ -36,10 +36,13 @@
#include <io.h>
#endif
-#define MAX_FFT_SIZE 4096
#define is_p2(x) !(x & (x - 1))
+/* These are arbitrary as there is no upper limit, but
+ * sox's getopt() needs an upper limit for each option, so...
+ */
#define MAX_X_SIZE 200000
+#define MAX_Y_SIZE 200000
typedef enum {Window_Hann, Window_Hamming, Window_Bartlett, Window_Rectangular, Window_Kaiser, Window_Dolph} win_type_t;
static lsx_enum_item const window_options[] = {
@@ -71,8 +74,11 @@ typedef struct {
int dft_size, step_size, block_steps, block_num, rows, cols, read;
int x_size, end, end_min, last_end;
sox_bool truncated;
- double buf[MAX_FFT_SIZE], dft_buf[MAX_FFT_SIZE], window[MAX_FFT_SIZE+1];
- double block_norm, max, magnitudes[(MAX_FFT_SIZE>>1) + 1];
+ double * buf; /* [dft_size] */
+ double * dft_buf; /* [dft_size] */
+ double * window; /* [dft_size + 1] */
+ double block_norm, max;
+ double * magnitudes; /* [(dft_size / 2) + 1] */
float * dBfs;
} priv_t;
@@ -114,9 +120,9 @@ static int getopts(sox_effect_t * effp, int argc, char **argv)
while ((c = lsx_getopt(&optstate)) != -1) switch (c) {
GETOPT_NUMERIC(optstate, 'x', x_size0 , 100, MAX_X_SIZE)
- GETOPT_NUMERIC(optstate, 'X', pixels_per_sec, 1 , 5000)
- GETOPT_NUMERIC(optstate, 'y', y_size , 64 , 1200)
- GETOPT_NUMERIC(optstate, 'Y', Y_size , 130, MAX_FFT_SIZE / 2 + 2)
+ GETOPT_NUMERIC(optstate, 'X', pixels_per_sec, 1 , MAX_X_SIZE)
+ GETOPT_NUMERIC(optstate, 'y', y_size , 64 , MAX_Y_SIZE)
+ GETOPT_NUMERIC(optstate, 'Y', Y_size , 130, MAX_Y_SIZE)
GETOPT_NUMERIC(optstate, 'z', dB_range , 20 , 180)
GETOPT_NUMERIC(optstate, 'Z', gain ,-100, 100)
GETOPT_NUMERIC(optstate, 'q', spectrum_points, 0 , p->spectrum_points)
@@ -172,7 +178,7 @@ static double make_window(priv_t * p, int end)
double sum = 0, * w = end < 0? p->window : p->window + end;
int i, n = 1 + p->dft_size - abs(end);
- if (end) memset(p->window, 0, sizeof(p->window));
+ if (end) memset(p->window, 0, sizeof(*(p->window)) * p->dft_size);
for (i = 0; i < n; ++i) w[i] = 1;
switch (p->win_type) {
case Window_Hann: lsx_apply_hann(w, n); break;
@@ -190,10 +196,10 @@ static double make_window(priv_t * p, int end)
return sum;
}
-static double * rdft_init(int n)
+static double * rdft_init(size_t n)
{
double * q = lsx_malloc(2 * (n / 2 + 1) * n * sizeof(*q)), * p = q;
- int i, j;
+ size_t i, j;
for (j = 0; j <= n / 2; ++j) for (i = 0; i < n; ++i)
*p++ = cos(2 * M_PI * j * i / n), *p++ = sin(2 * M_PI * j * i / n);
return q;
@@ -260,11 +266,18 @@ static int start(sox_effect_t * effp)
if (p->y_size) {
p->dft_size = 2 * (p->y_size - 1);
if (!is_p2(p->dft_size) && !effp->flow)
- p->shared = rdft_init(p->dft_size);
+ p->shared = rdft_init((size_t)(p->dft_size));
} else {
int y = max(32, (p->Y_size? p->Y_size : 550) / effp->in_signal.channels - 2);
for (p->dft_size = 128; p->dft_size <= y; p->dft_size <<= 1);
}
+
+ /* Now that dft_size is set, allocate variable-sized elements of priv_t */
+ p->buf = lsx_calloc(p->dft_size, sizeof(*(p->buf)));
+ p->dft_buf = lsx_calloc(p->dft_size, sizeof(*(p->dft_buf)));
+ p->window = lsx_calloc(p->dft_size + 1, sizeof(*(p->window)));
+ p->magnitudes = lsx_calloc((p->dft_size / 2) + 1, sizeof(*(p->magnitudes)));
+
if (is_p2(p->dft_size) && !effp->flow)
lsx_safe_rdft(p->dft_size, 1, p->dft_buf);
lsx_debug("duration=%g x_size=%i pixels_per_sec=%g dft_size=%i", duration, p->x_size, pixels_per_sec, p->dft_size);
@@ -651,6 +664,10 @@ error: png_destroy_write_struct(&png, &png_info);
free(png_rows);
free(pixels);
free(p->dBfs);
+ free(p->buf);
+ free(p->dft_buf);
+ free(p->window);
+ free(p->magnitudes);
return SOX_SUCCESS;
}
_______________________________________________
SoX-devel mailing list
SoX-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sox-devel
next prev parent reply other threads:[~2020-07-31 9:39 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-31 9:37 [PATCH RESEND 0/9] some old accumulated patches Eric Wong
2020-07-31 9:37 ` [PATCH RESEND 1/9] use non-blocking stdin for interactive mode Eric Wong
2020-07-31 9:37 ` [PATCH RESEND 2/9] speed up "|program" inputs on Linux 2.6.35+ Eric Wong
2020-07-31 10:53 ` Måns Rullgård
2020-07-31 9:37 ` [PATCH RESEND 3/9] sox.1: fix section name Eric Wong
2020-07-31 9:37 ` [PATCH RESEND 4/9] sndio: handle 24-bit samples properly on OpenBSD Eric Wong
2020-07-31 10:59 ` Måns Rullgård
2020-07-31 9:37 ` [PATCH RESEND 5/9] Handle vorbis_analysis_headerout errors Eric Wong
2020-07-31 9:37 ` [PATCH RESEND 6/9] fix manpage warning: "table wider than line width" Eric Wong
2020-07-31 9:37 ` Eric Wong [this message]
2020-07-31 14:34 ` [PATCH RESEND 7/9] spectrogram: remove arbitrary limit on height of spectrogram Måns Rullgård
[not found] ` <CAL4-wQpF-qOD=BRVPhgZFC7fjvFDV-rQx1stvwY_xCTyj5uooA@mail.gmail.com>
2020-08-13 16:20 ` Måns Rullgård
2020-08-13 16:30 ` Pander via SoX-devel
2020-08-13 16:38 ` Måns Rullgård
2020-07-31 9:38 ` [PATCH RESEND 8/9] Add spectrogram -n flag to normalise the output to maximum brightness Eric Wong
2020-07-31 9:38 ` [PATCH RESEND 9/9] Added average power spectrum for stat -freq -a Eric Wong
2020-08-01 11:52 ` Måns Rullgård
2020-08-02 1:03 ` Eric Wong
2020-08-02 10:43 ` Måns Rullgård
2020-08-02 10:52 ` Måns Rullgård
2020-08-03 12:44 ` Pander via SoX-devel
2020-08-03 13:41 ` Måns Rullgård
2020-07-31 10:13 ` [PATCH RESEND 0/9] some old accumulated patches Måns Rullgård
2020-07-31 21:16 ` Eric Wong
2020-07-31 21:44 ` Måns Rullgård
2020-08-01 16:57 ` Måns Rullgård
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://lists.sourceforge.net/lists/listinfo/sox-devel
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200731093801.23548-8-normalperson@yhbt.net \
--to=sox-devel@lists.sourceforge.net \
--cc=mans@mansr.com \
--cc=martinwguy@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).