From: Pander <pan...@users.sourceforge.net>

references:
https://sourceforge.net/p/sox/mailman/message/33186778/
https://sourceforge.net/p/sox/mailman/message/33175940/
https://sourceforge.net/p/sox/mailman/message/33625255/

Edited-by: Eric Wong <normalper...@yhbt.net>

[ew: removed extraneous whitespace changes,
 squashed re_average initialization fix from Pander,
 removed unnecessary check before free(3) call
 (ref: <5498a2f9.2010...@free.fr>),
 converted fft_average to bool]
---
 sox.1      |  6 ++++++
 src/stat.c | 27 ++++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/sox.1 b/sox.1
index 04ab09b1..d64762af 100644
--- a/sox.1
+++ b/sox.1
@@ -3596,6 +3596,12 @@ audio in SoX's internal buffer.
 This is mainly used to help track down endian problems that
 sometimes occur in cross-platform versions of SoX.
 .SP
+The
+.B \-a
+option
+will output the average input's power spectrum instead of the default
+behavior in which the power spectrum is given for each 4096 point DFT.
+.SP
 See also the
 .B stats
 effect.
diff --git a/src/stat.c b/src/stat.c
index cdea27cc..0ca6c232 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -34,6 +34,7 @@ typedef struct {
   float *re_out;
   unsigned long fft_size;
   unsigned long fft_offset;
+  sox_bool fft_average;
 } priv_t;
 
 
@@ -69,6 +70,8 @@ static int sox_stat_getopts(sox_effect_t * effp, int argc, 
char **argv)
       stat->fft = 1;
     else if (!(strcmp(*argv, "-d")))
       stat->volume = 2;
+    else if (!(strcmp(*argv, "-a")))
+      stat->fft_average = sox_true;
     else {
       lsx_fail("Summary effect: unknown option");
       return SOX_EOF;
@@ -100,6 +103,7 @@ static int sox_stat_start(sox_effect_t * effp)
     stat->bin[i] = 0;
 
   stat->fft_size = 4096;
+  stat->fft_average = sox_false;
   stat->re_in = stat->re_out = NULL;
 
   if (stat->fft) {
@@ -134,6 +138,16 @@ static int sox_stat_flow(sox_effect_t * effp, const 
sox_sample_t *ibuf, sox_samp
   priv_t * stat = (priv_t *) effp->priv;
   int done, x, len = min(*isamp, *osamp);
   short count = 0;
+  float *re_average = NULL;
+  unsigned samples = 0;
+  float ffa = 0.0;
+  unsigned i;
+
+  if (stat->fft_average) {
+      samples = (stat->fft_size / 2);
+      ffa = effp->in_signal.rate / samples;
+      re_average = lsx_malloc(sizeof(float) * (int)samples);
+  }
 
   if (len) {
     if (stat->read == 0)          /* 1st sample */
@@ -146,10 +160,20 @@ static int sox_stat_flow(sox_effect_t * effp, const 
sox_sample_t *ibuf, sox_samp
 
         if (stat->fft_offset >= stat->fft_size) {
           stat->fft_offset = 0;
+          if (stat->fft_average) {
+              lsx_power_spectrum_f((int)samples, stat->re_in, stat->re_out);
+              for (i = 0; i < samples / 2; i++) /* FIXME: should be <= samples 
/ 2 */
+                  re_average[i] += stat->re_out[i];
+          } else {
           print_power_spectrum((unsigned) stat->fft_size, 
effp->in_signal.rate, stat->re_in, stat->re_out);
+          }
         }
 
       }
+      if (stat->fft_average) {
+          for (i = 0; i < samples / 2; i++) /* FIXME: should be <= samples / 2 
*/
+              fprintf(stderr, " %f  %f\n", ffa * i, re_average[i] / len);
+      }
     }
 
     for (done = 0; done < len; done++) {
@@ -192,6 +216,7 @@ static int sox_stat_flow(sox_effect_t * effp, const 
sox_sample_t *ibuf, sox_samp
     stat->read += len;
   }
 
+  free(re_average);
   *isamp = *osamp = len;
   /* Process all samples */
 
@@ -320,7 +345,7 @@ static int sox_stat_stop(sox_effect_t * effp)
 
 static sox_effect_handler_t sox_stat_effect = {
   "stat",
-  "[ -s N ] [ -rms ] [-freq] [ -v ] [ -d ]",
+  "[ -s N ] [ -rms ] [-freq] [ -v ] [ -d ] [ -a ]",
   SOX_EFF_MCHAN | SOX_EFF_MODIFY,
   sox_stat_getopts,
   sox_stat_start,


_______________________________________________
SoX-devel mailing list
SoX-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sox-devel

Reply via email to