shithub: sox

Download patch

ref: 3b1312bec5ba218462ba9e8d3137ae7f30ccba7a
parent: bda25d62bd2459c9eaa855ca3da8cd91ae1e766a
author: robs <robs>
date: Sun Jun 17 10:58:15 EDT 2007

Warn if adpcm state errors are detected

--- a/src/adpcms.c
+++ b/src/adpcms.c
@@ -43,8 +43,12 @@
   state->max_step_index = type? 48 : 88;
   state->steps = type? oki_steps : ima_steps;
   state->mask = type? ~15 : ~0;
+  state->errors = 0;
 }
 
+#define min_sample -0x8000
+#define max_sample 0x7fff
+
 static int adpcm_decode(int code, adpcm_t state)
 {
   int s = ((code & 7) << 1) | 1;
@@ -52,7 +56,15 @@
   if (code & 8)
     s = -s;
   s += state->last_output;
-  s = range_limit(s, -0x8000, 0x7fff);
+  if (s < min_sample || s > max_sample) {
+    int grace = (state->steps[state->step_index] >> 3) & state->mask;
+    if (s < min_sample - grace || s > max_sample + grace) {
+      sox_debug_most("code=%i step=%i grace=%i s=%i", 
+          code & 15, state->steps[state->step_index], grace, s);
+      state->errors++;
+    }
+    s = s < min_sample? min_sample : max_sample;
+  }
   state->step_index += step_changes[code & 0x07];
   state->step_index = range_limit(state->step_index, 0, state->max_step_index);
   return state->last_output = s;
@@ -182,6 +194,8 @@
 
 int sox_adpcm_stopread(sox_format_t * ft UNUSED, adpcm_io_t state)
 {
+  if (state->encoder.errors)
+    sox_warn("%s: ADPCM state errors: %u", ft->filename, state->encoder.errors);
   free(state->file.buf);
 
   return (SOX_SUCCESS);
--- a/src/adpcms.h
+++ b/src/adpcms.h
@@ -23,6 +23,7 @@
   int max_step_index;
   int const * steps;
   int mask;
+  int errors;
 } * adpcm_t;
 
 typedef struct adpcm_io {