changeset 20017:f9ca80482c41

audiowrite: Scale integer inputs before writing to an audio file * audioread.cc (Faudiowrite): Check for recognized integer input types and scale accordingly to the range [-1,1] before writing. Add clipping of values outside the range [-1,1] after normalizing.
author Mike Miller <mtmiller@ieee.org>
date Sat, 21 Feb 2015 11:31:55 -0500
parents f24d9486e66b
children 879cff0c05dc
files libinterp/dldfcn/audioread.cc
diffstat 1 files changed, 19 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/dldfcn/audioread.cc
+++ b/libinterp/dldfcn/audioread.cc
@@ -311,6 +311,21 @@
   if (error_state)
     return retval;
 
+  double bias = 0.0;
+  double scale = 1.0;
+
+  if (args(1).is_uint8_type ())
+    bias = scale = std::pow (2.0, 7);
+  else if (args(1).is_int16_type ())
+    scale = std::pow (2.0, 15);
+  else if (args(1).is_int32_type ())
+    scale = std::pow (2.0, 31);
+  else if (args(1).is_integer_type ())
+    {
+      gripe_wrong_type_arg ("audiowrite", args(1));
+      return retval;
+    }
+
   int samplerate = args(2).int_value ();
 
   if (error_state)
@@ -327,7 +342,10 @@
   for (int i = 0; i < audio.rows (); i++)
     {
       for (int j = 0; j < audio.columns (); j++)
-        data[idx++] = audio.xelem (i, j);
+        {
+          double elem = (audio.xelem (i, j) - bias) / scale;
+          data[idx++] = std::min (std::max (elem, -1.0), 1.0);
+        }
     }
 
   SF_INFO info;