[SCM] brutefir/master: Imported Upstream version 1.0m

mira-guest at users.alioth.debian.org mira-guest at users.alioth.debian.org
Sun Feb 23 16:23:02 UTC 2014


The following commit has been merged in the master branch:
commit 8163a6ac775b9b177cbfb1f8f68ca8ab3735a576
Author: Jaromír Mikeš <mira.mikes at seznam.cz>
Date:   Sun Feb 23 17:20:59 2014 +0100

    Imported Upstream version 1.0m

diff --git a/CHANGES b/CHANGES
index 4dfd506..ca4eda6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,11 @@
+BruteFIR v1.0m                                                 November 27, 2013
+	 * Fixed SSE2 bug introduced in 1.0l.
+	 * Added safety_limit feature to protect speakers.
+	 * Fixed a rare race condition on multi-core.
+	 * More sample format fixing, removed S16_4*, changed S24_4* to
+	   represent low bits in sample, so it matches ALSA formats. If
+	   you used S24_4LE in earlier versions you should now use S32_LE.
+
 BruteFIR v1.0l                                                   October 6, 2013
 	 * Made the code compile well on x86-64.
 	 * Replaced legacy assembler code with new SSE/SSE2 C code,
diff --git a/README b/README
index e47e99d..a78a68c 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
 
-BruteFIR v1.0l
+BruteFIR v1.0m
 ================================================================================
 
 This is the source code for a generic FIR filter (convolution) engine,
@@ -13,4 +13,4 @@ web may be more up to date.
 
 Anders Torger, torger at ludd.ltu.se
 
-October 2013
+November 2013
diff --git a/bfconf.c b/bfconf.c
index 743eb71..6c52582 100644
--- a/bfconf.c
+++ b/bfconf.c
@@ -203,7 +203,8 @@ modules_path: \".\";          # extra path where to find BruteFIR modules\n\
 monitor_rate: false;        # monitor sample rate\n\
 powersave: false;           # pause filtering when input is zero\n\
 lock_memory: true;          # try to lock memory if realtime prio is set\n\
-sdf_length: -1;             # subsample filter half length in samples\n"
+sdf_length: -1;             # subsample filter half length in samples\n\
+safety_limit: 20;           # if non-zero max dB in output before aborting\n"
 #ifdef CONVOLVER_NEEDS_CONFIGFILE
 	    "convolver_config: \"~/.brutefir_convolver\"; # location of "
 	    "convolver config file\n"
@@ -391,20 +392,6 @@ parse_sample_format(struct sample_format *sf,
 	sf->bytes = 2;
 	sf->sbytes = 2;
         native_endian = true;
-    } else if (strcasecmp(s, "S16_4LE") == 0) {
-	sf->format = BF_SAMPLE_FORMAT_S16_4LE;
-	sf->bytes = 4;
-	sf->sbytes = 2;
-    } else if (strcasecmp(s, "S16_4BE") == 0) {
-	sf->format = BF_SAMPLE_FORMAT_S16_4BE;
-	sf->bytes = 4;
-	sf->sbytes = 2;
-	little_endian = false;
-    } else if (strcasecmp(s, "S16_4NE") == 0) {
-	sf->format = BF_SAMPLE_FORMAT_S16_4NE;
-	sf->bytes = 4;
-	sf->sbytes = 2;
-        native_endian = true;
     } else if (strcasecmp(s, "S24_LE") == 0 || strcasecmp(s, "S24_3LE") == 0) {
 	sf->format = BF_SAMPLE_FORMAT_S24_LE;
 	sf->bytes = 3;
@@ -485,7 +472,7 @@ parse_sample_format(struct sample_format *sf,
     if (sf->isfloat) {
 	sf->scale = 1.0;
     } else {
-	sf->scale = 1.0 / (double)(1 << ((sf->sbytes << 3) - 1));
+	sf->scale = 1.0 / (double)((uint64_t)1 << ((sf->sbytes << 3) - 1));
     }
 #ifdef __BIG_ENDIAN__
     if (native_endian) {
@@ -494,9 +481,6 @@ parse_sample_format(struct sample_format *sf,
         case BF_SAMPLE_FORMAT_S16_NE:
             sf->format = BF_SAMPLE_FORMAT_S16_BE;
             break;
-        case BF_SAMPLE_FORMAT_S16_4NE:
-            sf->format = BF_SAMPLE_FORMAT_S16_4LE;
-            break;
         case BF_SAMPLE_FORMAT_S24_NE:
             sf->format = BF_SAMPLE_FORMAT_S24_BE;
             break;
@@ -523,9 +507,6 @@ parse_sample_format(struct sample_format *sf,
         case BF_SAMPLE_FORMAT_S16_NE:
             sf->format = BF_SAMPLE_FORMAT_S16_LE;
             break;
-        case BF_SAMPLE_FORMAT_S16_4NE:
-            sf->format = BF_SAMPLE_FORMAT_S16_4LE;
-            break;
         case BF_SAMPLE_FORMAT_S24_NE:
             sf->format = BF_SAMPLE_FORMAT_S24_LE;
             break;
@@ -1643,6 +1624,15 @@ parse_setting(char field[],
 	    unexpected_token(EOS, token);
 	    break;
 	}
+    } else if (strcmp(field, "safety_limit") == 0) {
+	field_repeat_test(repeat_bitset, 18);
+	get_token(REAL);
+	bfconf->safety_limit = pow(10.0, yylval.real / 20.0);
+        if (!isfinite(bfconf->safety_limit)) {
+            fprintf(stderr, "invalid safety_limit.\n");
+            exit(BF_EXIT_INVALID_CONFIG);
+        }
+	get_token(EOS);
     } else {
 	parse_error("unrecognised setting name.\n");
     }
@@ -1814,13 +1804,13 @@ raw_read(FILE *stream,
     }
     realbuf = emalloc((*totitems) * realsize);
     if (realsize == 4) {
-        raw2realf(realbuf, rawbuf, sf->bytes, (sf->bytes - sf->sbytes) << 3,
+        raw2realf(realbuf, rawbuf, sf->bytes,
                   sf->isfloat, 1, sf->swap, *totitems);
         for (n_items = 0; n_items < *totitems; n_items++) {
             ((float *)realbuf)[n_items] *= (float)sf->scale;
         }
     } else {
-        raw2reald(realbuf, rawbuf, sf->bytes, (sf->bytes - sf->sbytes) << 3,
+        raw2reald(realbuf, rawbuf, sf->bytes,
                   sf->isfloat, 1, sf->swap, *totitems);
         for (n_items = 0; n_items < *totitems; n_items++) {
             ((double *)realbuf)[n_items] *= sf->scale;
@@ -2372,6 +2362,7 @@ bfconf_init(char filename[],
     bfconf->sdf_length = -1;
     bfconf->quiet = quiet;
     bfconf->realsize = sizeof(float);
+    bfconf->safety_limit = 0;
 
     if (!nodefault) {
         get_defaults();
diff --git a/bfconf.h b/bfconf.h
index 8d9cfb7..7fdd9c7 100644
--- a/bfconf.h
+++ b/bfconf.h
@@ -1,5 +1,5 @@
 /*
- * (c) Copyright 2001 - 2004, 2006 -- Anders Torger
+ * (c) Copyright 2001 - 2004, 2006, 2013 -- Anders Torger
  *
  * This program is open source. For license terms, see the LICENSE file.
  *
@@ -76,6 +76,7 @@ struct bfconf {
     int *subdelay[2];
     int sdf_length;
     double sdf_beta;
+    double safety_limit;
 };
 
 extern struct bfconf *bfconf;
diff --git a/bfio_alsa.c b/bfio_alsa.c
index 955dcab..0daa32c 100644
--- a/bfio_alsa.c
+++ b/bfio_alsa.c
@@ -110,12 +110,10 @@ set_params(snd_pcm_t *handle,
 	format = SND_PCM_FORMAT_S24_BE;
 	*sample_size = 4;
 	break;
-    case BF_SAMPLE_FORMAT_S16_4LE:
     case BF_SAMPLE_FORMAT_S32_LE:
 	format = SND_PCM_FORMAT_S32_LE;
 	*sample_size = 4;
 	break;
-    case BF_SAMPLE_FORMAT_S16_4BE:
     case BF_SAMPLE_FORMAT_S32_BE:
 	format = SND_PCM_FORMAT_S32_BE;
 	*sample_size = 4;
diff --git a/bfio_oss.c b/bfio_oss.c
index 39c61cb..ebccca3 100644
--- a/bfio_oss.c
+++ b/bfio_oss.c
@@ -83,12 +83,10 @@ set_params(int fd,
 	break;
 #endif        
 #ifdef AFMT_S32_LE
-    case BF_SAMPLE_FORMAT_S16_4LE:
     case BF_SAMPLE_FORMAT_S24_4LE:
     case BF_SAMPLE_FORMAT_S32_LE:
 	format = AFMT_S32_LE;
 	break;
-    case BF_SAMPLE_FORMAT_S16_4BE:
     case BF_SAMPLE_FORMAT_S24_4BE:
     case BF_SAMPLE_FORMAT_S32_BE:
 	format = AFMT_S32_BE;
diff --git a/bfmod.h b/bfmod.h
index 0b5d004..a70b9e9 100644
--- a/bfmod.h
+++ b/bfmod.h
@@ -34,8 +34,8 @@ extern "C" {
 #define BF_SAMPLE_FORMAT_S8 1
 #define BF_SAMPLE_FORMAT_S16_LE 2
 #define BF_SAMPLE_FORMAT_S16_BE 3
-#define BF_SAMPLE_FORMAT_S16_4LE 4
-#define BF_SAMPLE_FORMAT_S16_4BE 5
+#define BF_SAMPLE_FORMAT_S16_4LE 4 // unused since 1.0m
+#define BF_SAMPLE_FORMAT_S16_4BE 5 // unused since 1.0m
 #define BF_SAMPLE_FORMAT_S24_LE 6
 #define BF_SAMPLE_FORMAT_S24_BE 7
 #define BF_SAMPLE_FORMAT_S24_4LE 8
@@ -51,7 +51,7 @@ extern "C" {
 
 /* macro sample formats */    
 #define BF_SAMPLE_FORMAT_S16_NE 16
-#define BF_SAMPLE_FORMAT_S16_4NE 17
+#define BF_SAMPLE_FORMAT_S16_4NE 17 // unused since 1.0m
 #define BF_SAMPLE_FORMAT_S24_NE 18
 #define BF_SAMPLE_FORMAT_S24_4NE 19
 #define BF_SAMPLE_FORMAT_S32_NE 20
diff --git a/bfrun.c b/bfrun.c
index 4f56cad..1dad9ce 100644
--- a/bfrun.c
+++ b/bfrun.c
@@ -983,13 +983,35 @@ apply_subdelay(void *realbuf,
 }
 
 static void
+synch_filter_processes(int filter_readfd,
+                       int filter_writefd[],
+                       int process_index)
+{
+    int n;
+    char dummydata[bfconf->n_processes - 1];
+    if (bfconf->n_processes > 1) {
+        for (n = 0; n < bfconf->n_processes; n++) {
+            if (n != process_index) {
+                dummydata[0] = 0;
+                if (!writefd(filter_writefd[n], dummydata, 1)) {
+                    bf_exit(BF_EXIT_OTHER);
+                }
+            }
+        }
+        if (!readfd(filter_readfd, dummydata, bfconf->n_processes - 1)) {
+            bf_exit(BF_EXIT_OTHER);
+        }
+    }
+}
+
+static void
 filter_process(struct bfaccess *bfaccess,
                void *inbuf[2],
 	       void *outbuf[2],
 	       void *input_freqcbuf[],
 	       void *output_freqcbuf[],
 	       int filter_readfd,
-	       int filter_writefd,
+	       int filter_writefd[],
 	       int input_readfd,
                int cb_input_readfd,
 	       int output_writefd,
@@ -1101,13 +1123,7 @@ filter_process(struct bfaccess *bfaccess,
     if (!readfd(input_readfd, dummydata, 1)) { /* for init */
         bf_exit(BF_EXIT_OTHER);
     }
-    if (bfconf->n_processes > 1) {
-        if (!writefd(filter_writefd, dummydata, 1) ||
-            !readfd(filter_readfd, dummydata, 1))
-        {
-            bf_exit(BF_EXIT_OTHER);
-        }
-    }
+    synch_filter_processes(filter_readfd, filter_writefd, process_index);
 
     /* allocate input delay buffers */
     for (n = j = 0; n < n_procinputs; n++) {
@@ -1434,20 +1450,9 @@ filter_process(struct bfaccess *bfaccess,
                     tv = period_start;
                     events.block_start[i](bfaccess, blockcounter, &tv);
                 }
-                if (bfconf->n_processes > 1) {
-                    if (!writefd(filter_writefd, dummydata, 1) ||
-                        !readfd(filter_readfd, dummydata, 1))
-                    {
-                        bf_exit(BF_EXIT_OTHER);
-                    }
-                }
-            } else {
-                if (!readfd(filter_readfd, dummydata, 1) ||
-                    !writefd(filter_writefd, dummydata, 1))
-                {
-                    bf_exit(BF_EXIT_OTHER);
-                }
             }
+            synch_filter_processes(filter_readfd, filter_writefd,
+                                   process_index);
         }
         
         /* get all shared memory data we need where mutex is important */
@@ -1554,13 +1559,7 @@ filter_process(struct bfaccess *bfaccess,
 	}
 
         timestamp(&icomm->debug.f[dbg_pos].fsynch_fd.ts_call);
-	if (bfconf->n_processes > 1) {
-	    if (!writefd(filter_writefd, dummydata, 1) ||
-                !readfd(filter_readfd, dummydata, 1))
-            {
-                bf_exit(BF_EXIT_OTHER);
-            }
-	}
+        synch_filter_processes(filter_readfd, filter_writefd, process_index);
         timestamp(&icomm->debug.f[dbg_pos].fsynch_fd.ts_ret);
 
 	for (n = 0; n < n_filters; n++) {
@@ -1870,13 +1869,7 @@ filter_process(struct bfaccess *bfaccess,
 	t[4] += t2 - t1;
 	
         timestamp(&icomm->debug.f[dbg_pos].fsynch_td.ts_call);
-	if (bfconf->n_processes > 1) {
-	    if (!writefd(filter_writefd, dummydata, 1) ||
-                !readfd(filter_readfd, dummydata, 1))
-            {
-                bf_exit(BF_EXIT_OTHER);
-            }
-	}
+        synch_filter_processes(filter_readfd, filter_writefd, process_index);
         timestamp(&icomm->debug.f[dbg_pos].fsynch_td.ts_ret);
 
 	mixbuf_is_filled = false;
@@ -2141,12 +2134,13 @@ bfrun(void)
     int synch_pipe[2];
     int bl_input_2_filter[2];
     int filter_2_bl_output[2], filter2filter_pipes[bfconf->n_processes][2];
+    int filter_writefd[bfconf->n_processes];
     char dummydata[bfconf->n_processes];
     void *buffers[2][2];
     void *input_freqcbuf[bfconf->n_channels[IN]], *input_freqcbuf_base;
     void *output_freqcbuf[bfconf->n_channels[OUT]], *output_freqcbuf_base;
     int nc[2], cpos[2], channels[2][BF_MAXCHANNELS];
-    int n, i, j, prev, cbufsize, physch;
+    int n, i, j, cbufsize, physch;
     bool_t checkdrift, trigger;
     struct bfaccess bfaccess;
     pid_t pid;
@@ -2277,7 +2271,7 @@ bfrun(void)
 	    reset_overflow[n].max = 1.0;
 	} else {
 	    reset_overflow[n].max = (double)
-		(1 << ((dai_buffer_format[OUT]->bf[physch].
+		((uint64_t)1 << ((dai_buffer_format[OUT]->bf[physch].
 			sf.sbytes << 3) - 1)) - 1;
 	}
         icomm->overflow[n] = reset_overflow[n];
@@ -2334,8 +2328,6 @@ bfrun(void)
 	switch (pid = fork()) {
 	case 0:
             
-	    prev = (n == 0) ? bfconf->n_processes - 1 : n - 1;
-
             close(bl_output_2_bl_input[0]);
             close(bl_output_2_bl_input[1]);
             close(bl_input_2_filter[1]);
@@ -2343,13 +2335,12 @@ bfrun(void)
             close(cb_input_2_filter[1]);
             close(filter_2_cb_output[0]);
             for (i = 0; i < bfconf->n_processes; i++) {
-                if (i == prev) {
+                if (i == n) {
+                    filter_writefd[i] = -1;
                     close(filter2filter_pipes[i][1]);
-                } else if (i == n) {
-                    close(filter2filter_pipes[i][0]);
                 } else {
                     close(filter2filter_pipes[i][0]);
-                    close(filter2filter_pipes[i][1]);
+                    filter_writefd[i] = filter2filter_pipes[i][1];
                 }
             }
 
@@ -2358,8 +2349,8 @@ bfrun(void)
 			   buffers[OUT],
 			   input_freqcbuf,
 			   output_freqcbuf,
-			   filter2filter_pipes[prev][0],
-			   filter2filter_pipes[n][1],
+			   filter2filter_pipes[n][0],
+			   filter_writefd,
 			   bl_input_2_filter[0],
                            cb_input_2_filter[0],
 			   filter_2_bl_output[1],
diff --git a/brutefir.c b/brutefir.c
index c1d4d18..c9d08cb 100644
--- a/brutefir.c
+++ b/brutefir.c
@@ -19,7 +19,7 @@
 
 #define PRESENTATION_STRING \
 "\n\
-BruteFIR v1.0l (October 2013)                                 \
+BruteFIR v1.0m (November 2013)                                \
 (c) Anders Torger\n\
 \n"
 
diff --git a/brutefir.html b/brutefir.html
index 9c6850e..646808d 100644
--- a/brutefir.html
+++ b/brutefir.html
@@ -6,7 +6,7 @@
 </head>
 <body>
 <h1>BruteFIR</h1>
-<em>last updated 2013-10-06</em>
+<em>last updated 2013-11-29</em>
 <hr>
 <h2>Table of contents</h2>
 <ul>
@@ -67,6 +67,23 @@
 <p>
 
 <h2><a name="news">News</a></h2>
+<strong>2013-11-29</strong><br>
+There was still a typo in the last uploaded 1.0m affecting
+SSE2. Uploaded fix.
+<p>
+<strong>2013-11-28</strong><br>
+There was a typo in the last uploaded 1.0m release causing the
+S24_LE/S24_3LE formats to break for input. So if you downloaded 1.0m
+yesterday please do it again.
+<p>
+<strong>2013-11-27</strong><br>
+BruteFIR v1.0m. Fixed an SSE2 bug introduced in 1.0l. Added
+'safety_limit' feature which can be used to protect your expensive
+speakers (and sensitive ears). Also fixed a rare race condition bug
+and further synchronized sample formats with ALSA, so now S24_4LE
+means low 24 bits of 32 bit word. Thus if you used S24_4LE before you
+should use S32_LE now to get the old behavior.
+<p>
 <strong>2013-10-06</strong><br>
 BruteFIR v1.0l. Refreshed code to compile well on x86-64, dropped
 3Dnow support and replaced the hand-coded SSE with SSE C code, and
@@ -736,8 +753,8 @@ non-portable Intel Native signalling processing library <a
 href="brutefir.html#nsp">[19]</a>.
 
 <h2><a name="download">Where can I get it?</a></h2>
-You are free to <a href="files/brutefir-1.0l.tar.gz">download version
-1.0l</a>.
+You are free to <a href="files/brutefir-1.0m.tar.gz">download version
+1.0m</a>.
 <p>
 The package contains the source-code, you will need a supported
 platform to run it on (Linux is recommended, but FreeBSD or Solaris
@@ -1110,6 +1127,7 @@ lock_memory: <BOOLEAN: try to lock memory if realtime prio is set>;
 sdf_length: <NUMBER: sub-sample delay filter half length in samples>[, <NUMBER: kaiser window beta>];
 convolver_config: <STRING: file to store FFTW wisdom in>;
 benchmark: <BOOLEAN: start in benchmark mode (can only be used in main config file)>;
+safety_limit: <NUMBER: if non-zero max dB in output before aborting>;
 </pre>
 <p>
 The <tt>filter_length</tt> setting specifies how long the filters
@@ -1256,6 +1274,12 @@ response is flat up to 19 kHz, and then a soft rolloff begins which
 reaches -0.20 dB at 20 kHz, which is good enough for most needs. The
 next natural step, 63, keeps a flat response up to about 20500 Hz,
 with -0.20 dB at 21 kHz.
+<p>
+The purpose of the <tt>safety_limit</tt> setting is to protect your
+ears and expensive speakers, it's active if set to a non-zero
+value. Every output sample is checked and if it exceeds this value (in
+dB) BruteFIR will immediately exit with an error message, before any
+sound is sent to the output.
 
 <h3><a name="config_2">General structure syntax</a></h3>
 <pre>
diff --git a/fftw_convolver.c b/fftw_convolver.c
index 308d0a8..8fc3c0e 100644
--- a/fftw_convolver.c
+++ b/fftw_convolver.c
@@ -178,11 +178,11 @@ convolver_raw2cbuf(void *rawbuf,
 {
     if (realsize == 4) {
         raw2realf(next_cbuf, (void *)&((uint8_t *)rawbuf)[bf->byte_offset],
-                  bf->sf.bytes, (bf->sf.bytes - bf->sf.sbytes) << 3,
+                  bf->sf.bytes,
                   bf->sf.isfloat, bf->sample_spacing, bf->sf.swap, n_fft2);
     } else {
         raw2reald(next_cbuf, (void *)&((uint8_t *)rawbuf)[bf->byte_offset],
-                  bf->sf.bytes, (bf->sf.bytes - bf->sf.sbytes) << 3,
+                  bf->sf.bytes,
                   bf->sf.isfloat, bf->sample_spacing, bf->sf.swap, n_fft2);
     }
     if (postprocess != NULL) {
@@ -254,7 +254,8 @@ convolver_convolve_add(void *input_cbuf,
 		       void *coeffs,
 		       void *output_cbuf)
 {
-/*
+    /*
+#define real_t double
     real_t *_b = (real_t *)emallocaligned(n_fft * sizeof(real_t));
     real_t *_c = (real_t *)emallocaligned(n_fft * sizeof(real_t));
     real_t *_d = (real_t *)emallocaligned(n_fft * sizeof(real_t));
@@ -262,7 +263,7 @@ convolver_convolve_add(void *input_cbuf,
     memcpy(_b, input_cbuf, n_fft * sizeof(real_t));
     memcpy(_c, coeffs, n_fft * sizeof(real_t));
     memcpy(_d, output_cbuf, n_fft * sizeof(real_t));
-*/
+    */
     switch (opt_code) {
 #if defined(__ARCH_IA32__) || defined(__ARCH_X86_64__)
     case OPT_CODE_SSE:
@@ -272,7 +273,7 @@ convolver_convolve_add(void *input_cbuf,
 #ifdef __SSE2__
     case OPT_CODE_SSE2:
 	convolver_sse2_convolve_add(input_cbuf, coeffs, output_cbuf,
-                                    n_fft >> 4);
+                                    n_fft >> 3);
 	break;
 #endif
 #endif	
@@ -284,7 +285,7 @@ convolver_convolve_add(void *input_cbuf,
             convolve_addd(input_cbuf, coeffs, output_cbuf);
         }
     }
-/*
+    /*
     {
 	real_t d1s, d2s, err, e;
 	int n;
@@ -314,12 +315,15 @@ convolver_convolve_add(void *input_cbuf,
                 err += e;
             }
         }
-        fprintf(stderr, "err: %.10e\n", err);
+        if (err > 0.0) {
+            fprintf(stderr, "err: %.10e\n", err);
+        }
         efree(_b);
         efree(_c);
         efree(_d);
+#undef real_t
     }
-*/
+    */
 }
 
 void
@@ -487,13 +491,11 @@ convolver_cbuf2raw(void *cbuf,
             dither_preloop_real2int_hp_tpdf(dither_state, n_fft2);
             real2rawf_hp_tpdf((void *)&((uint8_t *)outbuf)[bf->byte_offset],
                               cbuf, bf->sf.sbytes << 3, bf->sf.bytes,
-                              (bf->sf.bytes - bf->sf.sbytes) << 3,
                               bf->sf.isfloat, bf->sample_spacing,
                               bf->sf.swap, n_fft2, overflow, dither_state);
         } else {
             real2rawf_no_dither((void *)&((uint8_t *)outbuf)[bf->byte_offset],
                                 cbuf, bf->sf.sbytes << 3, bf->sf.bytes,
-                                (bf->sf.bytes - bf->sf.sbytes) << 3,
                                 bf->sf.isfloat, bf->sample_spacing,
                                 bf->sf.swap, n_fft2, overflow);
         }
@@ -502,14 +504,12 @@ convolver_cbuf2raw(void *cbuf,
             dither_preloop_real2int_hp_tpdf(dither_state, n_fft2);
             real2rawd_hp_tpdf((void *)&((uint8_t *)outbuf)[bf->byte_offset],
                               cbuf, bf->sf.sbytes << 3, bf->sf.bytes,
-                              (bf->sf.bytes - bf->sf.sbytes) << 3,
                               bf->sf.isfloat, bf->sample_spacing,
                               bf->sf.swap, n_fft2, overflow, dither_state);
         } else {
             real2rawd_no_dither((void *)&((uint8_t *)outbuf)[bf->byte_offset],
                                 cbuf, bf->sf.sbytes << 3,
                                 bf->sf.bytes,
-                                (bf->sf.bytes - bf->sf.sbytes) << 3,
                                 bf->sf.isfloat, bf->sample_spacing,
                                 bf->sf.swap, n_fft2, overflow);
         }
diff --git a/raw2real.h b/raw2real.h
index fbbc436..09bcaa6 100644
--- a/raw2real.h
+++ b/raw2real.h
@@ -1,5 +1,5 @@
 /*
- * (c) Copyright 2001 - 2004 -- Anders Torger
+ * (c) Copyright 2001 - 2004, 2013 -- Anders Torger
  *
  * This program is open source. For license terms, see the LICENSE file.
  *
@@ -8,7 +8,6 @@ static void
 RAW2REAL_NAME(void *_realbuf,
               void *_rawbuf,
               int bytes,
-              int shift,
               bool_t isfloat,
               int spacing,
               bool_t swap,
@@ -20,10 +19,6 @@ RAW2REAL_NAME(void *_realbuf,
     realbuf = (numunion_t *)_realbuf;
     rawbuf = (numunion_t *)_rawbuf;
     if (isfloat) {
-	if (shift != 0) {
-	    fprintf(stderr, "Shift must be zero for floating point formats.\n");
-	    bf_exit(BF_EXIT_OTHER);
-	}
 #if REALSIZE == 4
 #define RXX r32
 #define REAL_T float        
@@ -98,46 +93,32 @@ RAW2REAL_NAME(void *_realbuf,
 	}
 	break;
     case 2:
-	if (shift == 0) {
-	    if (swap) {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    realbuf->RXX[n] = (REAL_T)((int16_t)SWAP16(rawbuf->u16[i]));
-		}
-	    } else {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    realbuf->RXX[n] = (REAL_T)rawbuf->i16[i];
-		}
-	    }
-	} else {
-	    if (swap) {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    realbuf->RXX[n] =
-                        (REAL_T)((int16_t)SWAP16(rawbuf->u16[i]) >> shift);
-		}
-	    } else {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    realbuf->RXX[n] = (REAL_T)(rawbuf->i16[i] >> shift);
-		}
-	    }
-	}
+        if (swap) {
+            for (n = i = 0; n < n_samples; n++, i += spacing) {
+                realbuf->RXX[n] = (REAL_T)((int16_t)SWAP16(rawbuf->u16[i]));
+            }
+        } else {
+            for (n = i = 0; n < n_samples; n++, i += spacing) {
+                realbuf->RXX[n] = (REAL_T)rawbuf->i16[i];
+            }
+        }
 	break;
     case 3:
 	spacing = spacing * 3 - 3;
-        shift += 8;
 #ifdef __BIG_ENDIAN__
         if (swap) {
             for (n = i = 0; n < n_samples; n++, i += spacing) {
                 sample.u8[2] = rawbuf->u8[i++];
                 sample.u8[1] = rawbuf->u8[i++];
                 sample.u8[0] = rawbuf->u8[i++];
-                realbuf->RXX[n] = (REAL_T)(sample.i32[0] >> shift);
+                realbuf->RXX[n] = (REAL_T)(sample.i32[0] >> 8);
             }
         } else {
             for (n = i = 0; n < n_samples; n++, i += spacing) {
                 sample.u8[0] = rawbuf->u8[i++];
                 sample.u8[1] = rawbuf->u8[i++];
                 sample.u8[2] = rawbuf->u8[i++];
-                realbuf->RXX[n] = (REAL_T)(sample.i32[0] >> shift);
+                realbuf->RXX[n] = (REAL_T)(sample.i32[0] >> 8);
             }
 	}
 #endif        
@@ -147,41 +128,28 @@ RAW2REAL_NAME(void *_realbuf,
                 sample.u8[3] = rawbuf->u8[i++];
                 sample.u8[2] = rawbuf->u8[i++];
                 sample.u8[1] = rawbuf->u8[i++];
-                realbuf->RXX[n] = (REAL_T)(sample.i32[0] >> shift);
+                realbuf->RXX[n] = (REAL_T)(sample.i32[0] >> 8);
             }
         } else {
             for (n = i = 0; n < n_samples; n++, i += spacing) {
                 sample.u8[1] = rawbuf->u8[i++];
                 sample.u8[2] = rawbuf->u8[i++];
                 sample.u8[3] = rawbuf->u8[i++];
-                realbuf->RXX[n] = (REAL_T)(sample.i32[0] >> shift);
+                realbuf->RXX[n] = (REAL_T)(sample.i32[0] >> 8);
             }
         }
 #endif
 	break;
     case 4:
-	if (shift == 0) {
-	    if (swap) {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    realbuf->RXX[n] = (REAL_T)((int32_t)SWAP32(rawbuf->u32[i]));
-		}
-	    } else {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    realbuf->RXX[n] = (REAL_T)rawbuf->i32[i];
-		}
-	    }
-	} else {
-	    if (swap) {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    realbuf->RXX[n] =
-                        (REAL_T)((int32_t)SWAP32(rawbuf->u32[i]) >> shift);
-		}
-	    } else {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    realbuf->RXX[n] = (REAL_T)(rawbuf->i32[i] >> shift);
-		}
-	    }
-	}
+        if (swap) {
+            for (n = i = 0; n < n_samples; n++, i += spacing) {
+                realbuf->RXX[n] = (REAL_T)((int32_t)SWAP32(rawbuf->u32[i]));
+            }
+        } else {
+            for (n = i = 0; n < n_samples; n++, i += spacing) {
+                realbuf->RXX[n] = (REAL_T)rawbuf->i32[i];
+            }
+        }
 	break;
     default:
     raw2real_invalid_byte_size:
diff --git a/real2raw.h b/real2raw.h
index 5f12ef0..1c8d647 100644
--- a/real2raw.h
+++ b/real2raw.h
@@ -1,5 +1,5 @@
 /*
- * (c) Copyright 2001 - 2004 -- Anders Torger
+ * (c) Copyright 2001 - 2004, 2013 -- Anders Torger
  *
  * This program is open source. For license terms, see the LICENSE file.
  *
@@ -15,6 +15,32 @@
  #error invalid REALSIZE
 #endif        
 
+#ifndef CONCAT_EVAL_
+#define CONCAT_EVAL_(a, b) a ## b
+#define CONCAT_(a, b) CONCAT_EVAL_(a, b)
+#endif
+#define REAL2RAW_SAMPLE_TEST CONCAT_(REAL2RAW_NAME, _sample_test)
+
+static inline void
+REAL2RAW_SAMPLE_TEST(REAL_T real_sample, struct bfoverflow *overflow)
+{
+    if (!isfinite(real_sample)) {
+        fprintf(stderr, "NaN or Inf values in the output! Bad output. "
+                        "Aborting.\n");
+        abort();
+    }
+    if (bfconf->safety_limit != 0.0 &&
+        (real_sample < -bfconf->safety_limit * overflow->max ||
+         real_sample > bfconf->safety_limit * overflow->max))
+    {
+        fprintf(stderr, "Safety limit exceeded on output (%.2f > %.2f). "
+                "Aborting.\n",
+                20.0 * log10(fabs(real_sample / overflow->max)),
+                20.0 * log10(bfconf->safety_limit));
+        bf_exit(BF_EXIT_OTHER);
+    }
+}
+
 #define REAL_OVERFLOW_UPDATE                                                   \
     if (realbuf->RXX[n] < 0.0) {                                               \
         if (realbuf->RXX[n] < rmin) {                                          \
@@ -37,7 +63,6 @@ REAL2RAW_NAME(void *_rawbuf,
 	      void *_realbuf,
 	      int bits,
 	      int bytes,
-	      int shift,
 	      bool_t isfloat,
 	      int spacing,
 	      bool_t swap,
@@ -59,20 +84,18 @@ REAL2RAW_NAME(void *_rawbuf,
     if (isfloat) {
         rmin = -overflow->max;
         rmax = overflow->max;
-	if (shift != 0) {
-	    fprintf(stderr, "Shift must be zero for floating point formats.\n");
-	    bf_exit(BF_EXIT_OTHER);
-	}
 #if REALSIZE == 4
         switch (bytes) {
         case 4:
             if (swap) {
                 for (n = i = 0; n < n_samples; n++, i += spacing) {
+                    REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
                     REAL_OVERFLOW_UPDATE;
                     rawbuf->u32[i] = SWAP32(realbuf->u32[n]);
                 }
             } else {
                 for (n = i = 0; n < n_samples; n++, i += spacing) {
+                    REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
                     REAL_OVERFLOW_UPDATE;
                     rawbuf->r32[i] = realbuf->r32[n];
                 }
@@ -81,12 +104,14 @@ REAL2RAW_NAME(void *_rawbuf,
         case 8:
             if (swap) {
                 for (n = i = 0; n < n_samples; n++, i += spacing) {
+                    REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
                     REAL_OVERFLOW_UPDATE;
                     sample.r64[0] = (double)realbuf->r32[n];
                     rawbuf->u64[i] = SWAP64(sample.u64[0]);
                 }
             } else {
                 for (n = i = 0; n < n_samples; n++, i += spacing) {
+                    REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
                     REAL_OVERFLOW_UPDATE;
                     rawbuf->r64[i] = (double)realbuf->r32[n];
                 }
@@ -100,12 +125,14 @@ REAL2RAW_NAME(void *_rawbuf,
         case 4:
             if (swap) {
                 for (n = i = 0; n < n_samples; n++, i += spacing) {
+                    REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
                     REAL_OVERFLOW_UPDATE;
                     sample.r32[0] = (float)realbuf->r64[n];
                     rawbuf->u32[i] = SWAP32(sample.u32[0]);
                 }
             } else {
                 for (n = i = 0; n < n_samples; n++, i += spacing) {
+                    REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
                     REAL_OVERFLOW_UPDATE;
                     rawbuf->r32[i] = (float)realbuf->r64[n];
                 }
@@ -114,11 +141,13 @@ REAL2RAW_NAME(void *_rawbuf,
         case 8:
             if (swap) {
                 for (n = i = 0; n < n_samples; n++, i += spacing) {
+                    REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
                     REAL_OVERFLOW_UPDATE;
                     rawbuf->u64[i] = SWAP64(realbuf->u64[n]);
                 }
             } else {
                 for (n = i = 0; n < n_samples; n++, i += spacing) {
+                    REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
                     REAL_OVERFLOW_UPDATE;
                     rawbuf->r64[i] = realbuf->r64[n];
                 }
@@ -133,138 +162,85 @@ REAL2RAW_NAME(void *_rawbuf,
 	return;
     }
     
-    imin = -(1 << (bits - 1));
-    imax = (1 << (bits - 1)) - 1;
+    imin = -((uint64_t)1 << (bits - 1));
+    imax = ((uint64_t)1 << (bits - 1)) - 1;
     rmin = (REAL_T)imin;
     rmax = (REAL_T)imax;
     switch (bytes) {
     case 1:
 	for (n = i = 0; n < n_samples; n++, i += spacing) {
+            REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
 	    rawbuf->i8[i] = (int8_t)REAL2INT_CALL;
 	}
 	break;
     case 2:
-	if (shift == 0) {
-	    if (swap) {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    sample.i16[0] = (int16_t)REAL2INT_CALL;
-		    rawbuf->u16[i] = SWAP16(sample.u16[0]);
-		}
-	    } else {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    rawbuf->i16[i] = (int16_t)REAL2INT_CALL;
-		}
-	    }
-	} else {
-	    if (swap) {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    sample.i16[0] = (int16_t)(REAL2INT_CALL << shift);
-		    rawbuf->u16[i] = SWAP16(sample.u16[0]);
-		}
-	    } else {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    rawbuf->i16[i] = (int16_t)(REAL2INT_CALL << shift);
-		}
-	    }
-	}
+        if (swap) {
+            for (n = i = 0; n < n_samples; n++, i += spacing) {
+                REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
+                sample.i16[0] = (int16_t)REAL2INT_CALL;
+                rawbuf->u16[i] = SWAP16(sample.u16[0]);
+            }
+        } else {
+            for (n = i = 0; n < n_samples; n++, i += spacing) {
+                REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
+                rawbuf->i16[i] = (int16_t)REAL2INT_CALL;
+            }
+        }
 	break;
     case 3:
 	spacing = spacing * 3 - 3;
 #ifdef __BIG_ENDIAN__
-	if (shift == 0) {
-	    if (swap) {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    sample.i32[0] = REAL2INT_CALL;
-		    rawbuf->u8[i++] = sample.u8[3];
-		    rawbuf->u8[i++] = sample.u8[2];
-		    rawbuf->u8[i++] = sample.u8[1];
-		}
-	    } else {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    sample.i32[0] = REAL2INT_CALL;
-		    rawbuf->u8[i++] = sample.u8[1];
-		    rawbuf->u8[i++] = sample.u8[2];
-		    rawbuf->u8[i++] = sample.u8[3];
-		}
-	    }
-	} else {
-	    if (swap) {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    sample.i32[0] = REAL2INT_CALL << shift;
-		    rawbuf->u8[i++] = sample.u8[3];
-		    rawbuf->u8[i++] = sample.u8[2];
-		    rawbuf->u8[i++] = sample.u8[1];
-		}
-	    } else {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    sample.i32[0] = REAL2INT_CALL << shift;
-		    rawbuf->u8[i++] = sample.u8[1];
-		    rawbuf->u8[i++] = sample.u8[2];
-		    rawbuf->u8[i++] = sample.u8[3];
-		}
-	    }
-	}
+        if (swap) {
+            for (n = i = 0; n < n_samples; n++, i += spacing) {
+                REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
+                sample.i32[0] = REAL2INT_CALL;
+                rawbuf->u8[i++] = sample.u8[3];
+                rawbuf->u8[i++] = sample.u8[2];
+                rawbuf->u8[i++] = sample.u8[1];
+            }
+        } else {
+            for (n = i = 0; n < n_samples; n++, i += spacing) {
+                REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
+                sample.i32[0] = REAL2INT_CALL;
+                rawbuf->u8[i++] = sample.u8[1];
+                rawbuf->u8[i++] = sample.u8[2];
+                rawbuf->u8[i++] = sample.u8[3];
+            }
+        }
 #endif        
 #ifdef __LITTLE_ENDIAN__
-	if (shift == 0) {
-	    if (swap) {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    sample.i32[0] = REAL2INT_CALL;
-		    rawbuf->u8[i++] = sample.u8[2];
-		    rawbuf->u8[i++] = sample.u8[1];
-		    rawbuf->u8[i++] = sample.u8[0];
-		}
-	    } else {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    sample.i32[0] = REAL2INT_CALL;
-		    rawbuf->u8[i++] = sample.u8[0];
-		    rawbuf->u8[i++] = sample.u8[1];
-		    rawbuf->u8[i++] = sample.u8[2];
-		}
-	    }
-	} else {
-	    if (swap) {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    sample.i32[0] = REAL2INT_CALL << shift;
-		    rawbuf->u8[i++] = sample.u8[2];
-		    rawbuf->u8[i++] = sample.u8[1];
-		    rawbuf->u8[i++] = sample.u8[0];
-		}
-	    } else {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    sample.i32[0] = REAL2INT_CALL << shift;
-		    rawbuf->u8[i++] = sample.u8[0];
-		    rawbuf->u8[i++] = sample.u8[1];
-		    rawbuf->u8[i++] = sample.u8[2];
-		}
-	    }
-	}
+        if (swap) {
+            for (n = i = 0; n < n_samples; n++, i += spacing) {
+                REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
+                sample.i32[0] = REAL2INT_CALL;
+                rawbuf->u8[i++] = sample.u8[2];
+                rawbuf->u8[i++] = sample.u8[1];
+                rawbuf->u8[i++] = sample.u8[0];
+            }
+        } else {
+            for (n = i = 0; n < n_samples; n++, i += spacing) {
+                REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
+                sample.i32[0] = REAL2INT_CALL;
+                rawbuf->u8[i++] = sample.u8[0];
+                rawbuf->u8[i++] = sample.u8[1];
+                rawbuf->u8[i++] = sample.u8[2];
+            }
+        }
 #endif
 	break;
     case 4:	
-	if (shift == 0) {
-	    if (swap) {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    sample.i32[0] = REAL2INT_CALL;
-		    rawbuf->u32[i] = SWAP32(sample.u32[0]);
-		}
-	    } else {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    rawbuf->i32[i] = REAL2INT_CALL;
-		}
-	    }
-	} else {
-	    if (swap) {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    sample.i32[0] = REAL2INT_CALL << shift;
-		    rawbuf->u32[i] = SWAP32(sample.u32[0]);
-		}
-	    } else {
-		for (n = i = 0; n < n_samples; n++, i += spacing) {
-		    rawbuf->i32[i] = REAL2INT_CALL << shift;
-		}
-	    }
-	}
+        if (swap) {
+            for (n = i = 0; n < n_samples; n++, i += spacing) {
+                REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
+                sample.i32[0] = REAL2INT_CALL;
+                rawbuf->u32[i] = SWAP32(sample.u32[0]);
+            }
+        } else {
+            for (n = i = 0; n < n_samples; n++, i += spacing) {
+                REAL2RAW_SAMPLE_TEST(realbuf->RXX[n], overflow);
+                rawbuf->i32[i] = REAL2INT_CALL;
+            }
+        }
 	break;
     default:
     real2raw_invalid_byte_size:

-- 
brutefir packaging



More information about the pkg-multimedia-commits mailing list