From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-4.4 required=3.0 tests=AWL,BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.sourceforge.net (lists.sourceforge.net [216.105.38.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 120ED1F5B1 for ; Fri, 31 Jul 2020 09:39:32 +0000 (UTC) Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1k1RVg-0005XM-SA; Fri, 31 Jul 2020 09:39:28 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k1RVe-0005XD-MD for sox-devel@lists.sourceforge.net; Fri, 31 Jul 2020 09:39:26 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=K7qA9Hn9wFLsOC4xkyM8kIYeurkm9ccd/wrLPWpqXTk=; b=kaoJ1Fk2eKHHTv6w2sVzkHBLsr W5Emcns4eyv2GiyqeqackY4Q4j48dO3EZj2NSuAueizsWs2LdfhdsUZ09VlOLDtY7IkU1IcFjEOHx h72pJczkzYQ91AGdNmNumUodf4eIbITAuZPeI4cEg0ykgzThYwtlTndWFhY7soARSuDw=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=K7qA9Hn9wFLsOC4xkyM8kIYeurkm9ccd/wrLPWpqXTk=; b=DxWkAO0UTI3WcpJlZcVEHEJbMv +ckhV7lTCPyv2gUFvaozjElbY035Gk4lqOAAjWpHDKEYmzN59zSsOSxwGG83NawD0UoWAjqk/RnGr Z3lPfR4p/2Q0Hnya+YScZIMAwdiMMW8xLM4I77hPUJCsqxRlCVtbbgSx7TV8I9Fh55Do=; Received: from dcvr.yhbt.net ([64.71.152.64]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1k1RVd-00FjGo-BY for sox-devel@lists.sourceforge.net; Fri, 31 Jul 2020 09:39:26 +0000 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 2138D1F8EE; Fri, 31 Jul 2020 09:38:03 +0000 (UTC) From: Eric Wong To: =?UTF-8?q?M=C3=A5ns=20Rullg=C3=A5rd?= Date: Fri, 31 Jul 2020 09:37:59 +0000 Message-Id: <20200731093801.23548-8-normalperson@yhbt.net> In-Reply-To: <20200731093801.23548-1-normalperson@yhbt.net> References: <20200731093801.23548-1-normalperson@yhbt.net> MIME-Version: 1.0 X-Headers-End: 1k1RVd-00FjGo-BY Subject: [PATCH RESEND 7/9] spectrogram: remove arbitrary limit on height of spectrogram X-BeenThere: sox-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: sox-devel@lists.sourceforge.net Cc: Martin Guy , sox-devel@lists.sourceforge.net Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: sox-devel-bounces@lists.sourceforge.net From: Martin Guy 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 --- 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 #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