diff scripts/audio/wavwrite.m @ 12701:de3e90a420e3 stable

Overhaul wavwrite, wavread and fix normalization problem (Bug #33420). * wavwrite.m: Remove ancient non-Matlab calling form of function. Update tests and add test to verify proper clipping of out-of-range values. * wavread.m: Use correct normalization constant to put values in range [-1,1). Add test to stop fntests.m from reporting this as untested function.
author Rik <octave@nomad.inbox5.com>
date Sat, 04 Jun 2011 07:20:42 -0700
parents c792872f8942
children e9c23efe6fff
line wrap: on
line diff
--- a/scripts/audio/wavwrite.m	Sat Jun 04 07:15:42 2011 -0700
+++ b/scripts/audio/wavwrite.m	Sat Jun 04 07:20:42 2011 -0700
@@ -18,10 +18,10 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} wavwrite (@var{y}, @var{filename})
-## @deftypefnx {Function File} {} wavwrite (@var{y}, @var{fs}, @var{filename})
-## @deftypefnx {Function File} {} wavwrite (@var{y}, @var{fs}, @var{bits}, @var{filename})
+## @deftypefnx {Function File} {} wavwrite (@var{y}, @var{Fs}, @var{filename})
+## @deftypefnx {Function File} {} wavwrite (@var{y}, @var{Fs}, @var{bps}, @var{filename})
 ## Write @var{y} to the canonical RIFF/WAVE sound file @var{filename}
-## with sample rate @var{fs} and bits per sample @var{bits}.  The
+## with sample rate @var{Fs} and bits per sample @var{bps}.  The
 ## default sample rate is 8000 Hz with 16-bits per sample.  Each column
 ## of the data represents a separate channel.
 ## @seealso{wavread}
@@ -34,13 +34,6 @@
 
   BYTEORDER = "ieee-le";
 
-  ## For backward compatibility with previous versions of Octave, also
-  ## accept the inputs
-  ##
-  ##   wavwrite (filename, y)
-  ##   wavwrite (filename, y, fs)
-  ##   wavwrite (filename, y, fs, bits)
-
   if (nargin < 2 || nargin > 4)
     print_usage ();
   endif
@@ -49,22 +42,11 @@
   samples_per_sec = 8000;
   bits_per_sample = 16;
 
-  if (ischar (y))
-    filename = y;
-    y = varargin{1};
-    if (nargin > 2)
-      samples_per_sec = varargin{2};
-      if (nargin > 3)
-        bits_per_sample = varargin{3};
-      endif
-    endif
-  else
-    filename = varargin{end};
-    if (nargin > 2)
-      samples_per_sec = varargin{1};
-      if (nargin > 3)
-        bits_per_sample = varargin{2};
-      endif
+  filename = varargin{end};
+  if (nargin > 2)
+    samples_per_sec = varargin{1};
+    if (nargin > 3)
+      bits_per_sample = varargin{2};
     endif
   endif
 
@@ -72,7 +54,7 @@
   if (columns (y) < 1)
     error ("wavwrite: Y must have at least one column");
   endif
-  if (columns (y) > 2^15-1)
+  if (columns (y) > 0x7FFF)
     error ("wavwrite: Y has more than 32767 columns (too many for a WAV-file)");
   endif
 
@@ -89,17 +71,16 @@
   endswitch
 
   ## calculate filesize
-  [n, channels] = size(y);
+  [n, channels] = size (y);
 
   ## size of data chunk
   ck_size = n*channels*(bits_per_sample/8);
 
-  ## open file for writing binary
-
   if (! ischar (filename))
     error ("wavwrite: expecting FILENAME to be a character string");
   endif
 
+  ## open file for writing binary
   [fid, msg] = fopen (filename, "wb");
   if (fid < 0)
     error ("wavwrite: %s", msg);
@@ -126,8 +107,8 @@
   c += fwrite (fid, samples_per_sec, "uint32", 0, BYTEORDER);
 
   ## bytes per second
-  bps = samples_per_sec*channels*bits_per_sample/8;
-  c += fwrite (fid, bps, "uint32", 0, BYTEORDER);
+  byteps = samples_per_sec*channels*bits_per_sample/8;
+  c += fwrite (fid, byteps, "uint32", 0, BYTEORDER);
 
   ## block align
   c += fwrite (fid, channels*bits_per_sample/8, "uint16", 0, BYTEORDER);
@@ -147,11 +128,11 @@
   ## scale samples
   switch (bits_per_sample)
     case 8
-      yi = round (yi*127 + 128);
+      yi = round (yi*128 + 128);
     case 16
-      yi = round (yi*32767);
+      yi = round (yi*32768);
     case 32
-      yi = round (yi*2147483647);
+      yi = round (yi*2147483648);
   endswitch
 
   ## write to file
@@ -161,29 +142,39 @@
 
 endfunction
 
+
 %!test
-%! A = [1:10; 1:10]/10;
-%! wavwrite("a.wav", A);
-%! [B, samples_per_sec, bits_per_sample] = wavread("a.wav");
-%! assert(A,B, 10^(-4));
+%! A = [-1:0.1:1; -1:0.1:1];
+%! wavwrite (A, "a.wav");
+%! [B, samples_per_sec, bits_per_sample] = wavread ("a.wav");
+%! assert(A,B, 1/2^15);
 %! assert(samples_per_sec, 8000);
 %! assert(bits_per_sample, 16);
 %! delete ("a.wav");
 %
 %!test
-%! A=[1:10; 1:10] / 10;
-%! wavwrite("a.wav", A, 4000);
-%! [B, samples_per_sec, bits_per_sample] = wavread("a.wav");
-%! assert(A,B, 10^(-4));
+%! A = [-1:0.1:1; -1:0.1:1];
+%! wavwrite (A, 4000, "a.wav");
+%! [B, samples_per_sec, bits_per_sample] = wavread ("a.wav");
+%! assert(A,B, 1/2^15);
 %! assert(samples_per_sec, 4000);
 %! assert(bits_per_sample, 16);
 %! delete ("a.wav");
 %
 %!test
-%! A=[1:10; 1:10] / 10;
-%! wavwrite("a.wav", A, 4000, 8);
-%! [B, samples_per_sec, bits_per_sample] = wavread("a.wav");
-%! assert(A,B, 10^(-2));
+%! A = [-1:0.1:1; -1:0.1:1];
+%! wavwrite (A, 4000, 8, "a.wav");
+%! [B, samples_per_sec, bits_per_sample] = wavread ("a.wav");
+%! assert(A,B, 1/128);
 %! assert(samples_per_sec, 4000);
 %! assert(bits_per_sample, 8);
 %! delete ("a.wav");
+%
+%!test
+%! A = [-2:2];
+%! wavwrite (A, "a.wav");
+%! B = wavread ("a.wav");
+%! B *= 32768;
+%! assert(B, [-32768 -32768 0 32767 32767]);
+%! delete ("a.wav");
+