changeset 20519:c8ec0b72b7a6

Deprecate wavread and wavwrite. * NEWS: Announce deprecation and replacement functions. * scripts/deprecated/wavread.m, scripts/deprecated/wavwrite.m: Moved from scripts/audio. Add deprecation message to docstring. Add deprecation warning to m-file. * scripts/audio/module.mk: Remove from build system. * scripts/deprecated/module.mk: Add deprecated versions to build system. * audio.txi: Remove functions from manual.
author Rik <rik@octave.org>
date Sat, 05 Sep 2015 05:00:46 -0700
parents 54eec9c180cb
children f515bac7c7c1
files NEWS doc/interpreter/audio.txi scripts/audio/module.mk scripts/audio/wavread.m scripts/audio/wavwrite.m scripts/deprecated/module.mk scripts/deprecated/wavread.m scripts/deprecated/wavwrite.m
diffstat 8 files changed, 349 insertions(+), 304 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Fri Sep 04 16:26:58 2015 -0400
+++ b/NEWS	Sat Sep 05 05:00:46 2015 -0700
@@ -38,6 +38,28 @@
 
       psi
 
+ ** Deprecated functions.
+
+    The following functions have been deprecated in Octave 4.2 and will
+    be removed from Octave 4.6 (or whatever version is the second major
+    release after 4.2):
+
+      Function             | Replacement
+      ---------------------|------------------
+      wavread              | audioread
+      wavwrite             | audiowrite
+
+ ** The following functions were deprecated in Octave 3.8 and have been
+    removed from Octave 4.2.
+
+      default_save_options    java_new
+      gen_doc_cache           java_unsigned_conversion
+      interp1q                javafields
+      isequalwithequalnans    javamethods
+      java_convert_matrix     re_read_readline_init_file
+      java_debug              read_readline_init_file
+      java_invoke             saving_history
+
 
 Summary of important user-visible changes for version 4.0:
 ---------------------------------------------------------
--- a/doc/interpreter/audio.txi	Fri Sep 04 16:26:58 2015 -0400
+++ b/doc/interpreter/audio.txi	Sat Sep 05 05:00:46 2015 -0700
@@ -182,6 +182,3 @@
 
 @DOCSTRING(soundsc)
 
-@DOCSTRING(wavread)
-
-@DOCSTRING(wavwrite)
--- a/scripts/audio/module.mk	Fri Sep 04 16:26:58 2015 -0400
+++ b/scripts/audio/module.mk	Sat Sep 05 05:00:46 2015 -0700
@@ -8,9 +8,7 @@
   scripts/audio/mu2lin.m \
   scripts/audio/record.m \
   scripts/audio/sound.m \
-  scripts/audio/soundsc.m \
-  scripts/audio/wavread.m \
-  scripts/audio/wavwrite.m
+  scripts/audio/soundsc.m
 
 scripts_audio_@audioplayer_FCN_FILES = \
   scripts/audio/@audioplayer/__get_properties__.m \
--- a/scripts/audio/wavread.m	Fri Sep 04 16:26:58 2015 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-## Copyright (C) 2015 Mike Miller
-## Copyright (C) 2005-2015 Michael Zeising
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn  {Function File} {@var{y} =} wavread (@var{filename})
-## @deftypefnx {Function File} {[@var{y}, @var{fs}, @var{nbits}] =} wavread (@var{filename})
-## @deftypefnx {Function File} {[@dots{}] =} wavread (@var{filename}, @var{n})
-## @deftypefnx {Function File} {[@dots{}] =} wavread (@var{filename}, [@var{n1} @var{n2}])
-## @deftypefnx {Function File} {[@dots{}] =} wavread (@dots{}, @var{datatype})
-## @deftypefnx {Function File} {@var{sz} =} wavread (@var{filename}, "size")
-## @deftypefnx {Function File} {[@var{n_samp}, @var{n_chan}] =} wavread (@var{filename}, "size")
-## Read the audio signal @var{y} from the RIFF/WAVE sound file @var{filename}.
-##
-## If the file contains multichannel data, then @var{y} is a matrix with the
-## channels represented as columns.
-##
-## If @var{n} is specified, only the first @var{n} samples of the file are
-## returned.  If [@var{n1} @var{n2}] is specified, only the range of samples
-## from @var{n1} to @var{n2} is returned.  A value of @code{Inf} can be used
-## to represent the total number of samples in the file.
-##
-## If the option @qcode{"size"} is given, then the size of the audio signal
-## is returned instead of the data.  The size is returned in a row vector of
-## the form [@var{samples} @var{channels}].  If there are two output arguments,
-## the number of samples is assigned to the first and the number of channels
-## is assigned to the second.
-##
-## The optional return value @var{fs} is the sample rate of the audio file in
-## Hz.  The optional return value @var{nbits} is the number of bits per sample
-## as encoded in the file.
-##
-## @seealso{audioread, audiowrite, wavwrite}
-## @end deftypefn
-
-function [y, fs, nbits] = wavread (filename, varargin)
-
-  if (nargin < 1 || nargin > 3)
-    print_usage ();
-  endif
-
-  if (! ischar (filename))
-    error ("wavread: FILENAME must be a character string");
-  endif
-
-  datatype = "double";
-  samples = [1, Inf];
-  do_file_size = false;
-
-  if (nargin == 3)
-    samples = varargin{1};
-    datatype = varargin{2};
-  elseif (nargin == 2)
-    if (strcmp (varargin{1}, "size"))
-      do_file_size = true;
-    elseif (ischar (varargin{1}))
-      datatype = varargin{1};
-    else
-      samples = varargin{1};
-    endif
-  endif
-
-  if (isscalar (samples))
-    samples = [1, samples];
-  endif
-
-  if (! (isrow (samples) && numel (samples) == 2 && all (samples > 0)
-         && all (fix (samples) == samples)))
-    error ("wavread: SAMPLES must be a 1- or 2-element integer row vector");
-  endif
-
-  if (! (ischar (datatype) && any (strcmp (datatype, {"double", "native"}))))
-    error ('wavread: DATATYPE must be either "double" or "native"');
-  endif
-
-  info = audioinfo (filename);
-
-  if (do_file_size)
-    if (nargout > 1)
-      [y, fs] = deal (info.TotalSamples, info.NumChannels);
-    else
-      y = [info.TotalSamples, info.NumChannels];
-    endif
-  else
-    [y, fs] = audioread (filename, samples, datatype);
-    nbits = info.BitsPerSample;
-  endif
-
-endfunction
-
-
-## Functional tests for wavread/wavwrite pair are in wavwrite.m.
-
-## Test input validation
-%!error wavread ()
-%!error wavread (1)
-%!error wavread ("foo.wav", 2, 3, 4)
-%!error wavread ("foo.wav", "foo")
-%!error wavread ("foo.wav", -1)
-%!error wavread ("foo.wav", [1, Inf], "foo");
-
--- a/scripts/audio/wavwrite.m	Fri Sep 04 16:26:58 2015 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-## Copyright (C) 2015 Mike Miller
-## Copyright (C) 2005-2015 Michael Zeising
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- 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{nbits}, @var{filename})
-## Write the audio signal @var{y} to the RIFF/WAVE sound file @var{filename}.
-##
-## If @var{y} is a matrix, the columns represent multiple audio channels.
-##
-## The optional argument @var{fs} specifies the sample rate of the audio signal
-## in Hz.
-##
-## The optional argument @var{nbits} specifies the number of bits per sample
-## to write to @var{filename}.
-##
-## The default sample rate is 8000 Hz and the default bit depth is 16 bits
-## per sample.
-##
-## @seealso{audiowrite, audioread, wavread}
-## @end deftypefn
-
-function wavwrite (y, varargin)
-
-  if (nargin < 2 || nargin > 4)
-    print_usage ();
-  endif
-
-  ## Defaults.
-  fs = 8000;
-  nbits = 16;
-
-  filename = varargin{end};
-  if (nargin > 2)
-    fs = varargin{1};
-    if (nargin > 3)
-      nbits = varargin{2};
-    endif
-  endif
-
-  ## calculate filesize
-  [n, channels] = size (y);
-
-  ## allow y to be a row vector
-  if (n == 1)
-    y = y(:);
-    n = channels;
-    channels = 1;
-  endif
-
-  ## test arguments
-  if (channels < 1)
-    error ("wavwrite: Y must have at least one column");
-  endif
-
-  if (channels > 0x7FFF)
-    error ("wavwrite: Y must have no more than 32767 columns");
-  endif
-
-  if (! (isscalar (fs) && (fs > 0)))
-    error ("wavwrite: sample rate FS must be a positive number");
-  endif
-
-  if (! isscalar (nbits) || isempty (find (nbits == [8, 16, 24, 32])))
-    error ("wavwrite: bit depth NBITS must be 8, 16, 24, or 32");
-  endif
-
-  audiowrite (filename, y, fs, "BitsPerSample", nbits);
-
-endfunction
-
-
-%!shared fname
-%! fname = [tempname() ".wav"];
-
-%!testif HAVE_SNDFILE
-%! A = [-1:0.1:1; -1:0.1:1]';
-%! unwind_protect
-%!   wavwrite (A, fname);
-%!   [B, samples_per_sec, bits_per_sample] = wavread (fname);
-%!   assert (B, A, 2^-14);
-%!   assert (samples_per_sec, 8000);
-%!   assert (bits_per_sample, 16);
-%! unwind_protect_cleanup
-%!   unlink (fname);
-%! end_unwind_protect
-
-%!testif HAVE_SNDFILE
-%! A = [-1:0.1:1; -1:0.1:1]';
-%! unwind_protect
-%!   wavwrite (A, 4000, fname);
-%!   [B, samples_per_sec, bits_per_sample] = wavread (fname);
-%!   assert (B, A, 2^-14);
-%!   assert (samples_per_sec, 4000);
-%!   assert (bits_per_sample, 16);
-%! unwind_protect_cleanup
-%!   unlink (fname);
-%! end_unwind_protect
-
-%!testif HAVE_SNDFILE
-%! A = [-1:0.1:1; -1:0.1:1]';
-%! unwind_protect
-%!   wavwrite (A, 4000, 8, fname);
-%!   [B, samples_per_sec, bits_per_sample] = wavread (fname);
-%!   assert (B, A, 2^-6);
-%!   assert (samples_per_sec, 4000);
-%!   assert (bits_per_sample, 8);
-%! unwind_protect_cleanup
-%!   unlink (fname);
-%! end_unwind_protect
-
-%!testif HAVE_SNDFILE
-%! A = [-2:2]';
-%! unwind_protect
-%!   wavwrite (A, fname);
-%!   B = wavread (fname);
-%!   B *= 32768;
-%!   assert (B, [-32767 -32767 0 32767 32767]');
-%! unwind_protect_cleanup
-%!   unlink (fname);
-%! end_unwind_protect
-
-%!testif HAVE_SNDFILE
-%! A = [-1:0.1:1];
-%! unwind_protect
-%!   wavwrite (A, fname);
-%!   [B, samples_per_sec, bits_per_sample] = wavread (fname);
-%!   assert (B, A', 2^-14);
-%!   assert (samples_per_sec, 8000);
-%!   assert (bits_per_sample, 16);
-%! unwind_protect_cleanup
-%!   unlink (fname);
-%! end_unwind_protect
-
-%!testif HAVE_SNDFILE
-%! A = [-1:0.1:1; -1:0.1:1]';
-%! unwind_protect
-%!   wavwrite (A, fname);
-%!   B = wavread (fname, 15);
-%!   assert (B, A(1:15,:), 2^-14);
-%!   wavwrite (A, fname);
-%!   B = wavread (fname, [10, 20]);
-%!   assert (B, A(10:20,:), 2^-14);
-%! unwind_protect_cleanup
-%!   unlink (fname);
-%! end_unwind_protect
-
-%!testif HAVE_SNDFILE
-%! A = [-1:0.1:1; -1:0.1:1]';
-%! unwind_protect
-%!   wavwrite (A, fname);
-%!   [nsamp, nchan] = wavread (fname, "size");
-%!   assert (nsamp, 21);
-%!   assert (nchan, 2);
-%! unwind_protect_cleanup
-%!   unlink (fname);
-%! end_unwind_protect
-
-## Test input validation
-%!error wavwrite ()
-%!error wavwrite (1)
-%!error wavwrite (1,2,3,4,5)
-%!error wavwrite ([], "foo.wav");
-
--- a/scripts/deprecated/module.mk	Fri Sep 04 16:26:58 2015 -0400
+++ b/scripts/deprecated/module.mk	Sat Sep 05 05:00:46 2015 -0700
@@ -19,7 +19,9 @@
   scripts/deprecated/saveaudio.m \
   scripts/deprecated/setaudio.m \
   scripts/deprecated/syl.m \
-  scripts/deprecated/usage.m
+  scripts/deprecated/usage.m \
+  scripts/deprecated/wavread.m \
+  scripts/deprecated/wavwrite.m
 
 scripts_deprecateddir = $(fcnfiledir)/deprecated
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/wavread.m	Sat Sep 05 05:00:46 2015 -0700
@@ -0,0 +1,129 @@
+## Copyright (C) 2015 Mike Miller
+## Copyright (C) 2005-2015 Michael Zeising
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {@var{y} =} wavread (@var{filename})
+## @deftypefnx {Function File} {[@var{y}, @var{fs}, @var{nbits}] =} wavread (@var{filename})
+## @deftypefnx {Function File} {[@dots{}] =} wavread (@var{filename}, @var{n})
+## @deftypefnx {Function File} {[@dots{}] =} wavread (@var{filename}, [@var{n1} @var{n2}])
+## @deftypefnx {Function File} {[@dots{}] =} wavread (@dots{}, @var{datatype})
+## @deftypefnx {Function File} {@var{sz} =} wavread (@var{filename}, "size")
+## @deftypefnx {Function File} {[@var{n_samp}, @var{n_chan}] =} wavread (@var{filename}, "size")
+##
+## @code{wavread} is deprecated and will be removed in Octave version 4.6.
+## Use @code{audioread} for the equivalent functionality.
+##
+## Read the audio signal @var{y} from the RIFF/WAVE sound file @var{filename}.
+##
+## If the file contains multichannel data, then @var{y} is a matrix with the
+## channels represented as columns.
+##
+## If @var{n} is specified, only the first @var{n} samples of the file are
+## returned.  If [@var{n1} @var{n2}] is specified, only the range of samples
+## from @var{n1} to @var{n2} is returned.  A value of @code{Inf} can be used
+## to represent the total number of samples in the file.
+##
+## If the option @qcode{"size"} is given, then the size of the audio signal
+## is returned instead of the data.  The size is returned in a row vector of
+## the form [@var{samples} @var{channels}].  If there are two output arguments,
+## the number of samples is assigned to the first and the number of channels
+## is assigned to the second.
+##
+## The optional return value @var{fs} is the sample rate of the audio file in
+## Hz.  The optional return value @var{nbits} is the number of bits per sample
+## as encoded in the file.
+##
+## @seealso{audioread, audiowrite, wavwrite}
+## @end deftypefn
+
+## Deprecated in 4.2
+
+function [y, fs, nbits] = wavread (filename, varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "wavread is obsolete and will be removed from a future version of Octave, please use audioread instead");
+  endif
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (! ischar (filename))
+    error ("wavread: FILENAME must be a character string");
+  endif
+
+  datatype = "double";
+  samples = [1, Inf];
+  do_file_size = false;
+
+  if (nargin == 3)
+    samples = varargin{1};
+    datatype = varargin{2};
+  elseif (nargin == 2)
+    if (strcmp (varargin{1}, "size"))
+      do_file_size = true;
+    elseif (ischar (varargin{1}))
+      datatype = varargin{1};
+    else
+      samples = varargin{1};
+    endif
+  endif
+
+  if (isscalar (samples))
+    samples = [1, samples];
+  endif
+
+  if (! (isrow (samples) && numel (samples) == 2 && all (samples > 0)
+         && all (fix (samples) == samples)))
+    error ("wavread: SAMPLES must be a 1- or 2-element integer row vector");
+  endif
+
+  if (! (ischar (datatype) && any (strcmp (datatype, {"double", "native"}))))
+    error ('wavread: DATATYPE must be either "double" or "native"');
+  endif
+
+  info = audioinfo (filename);
+
+  if (do_file_size)
+    if (nargout > 1)
+      [y, fs] = deal (info.TotalSamples, info.NumChannels);
+    else
+      y = [info.TotalSamples, info.NumChannels];
+    endif
+  else
+    [y, fs] = audioread (filename, samples, datatype);
+    nbits = info.BitsPerSample;
+  endif
+
+endfunction
+
+
+## Functional tests for wavread/wavwrite pair are in wavwrite.m.
+
+## Test input validation
+%!error wavread ()
+%!error wavread (1)
+%!error wavread ("foo.wav", 2, 3, 4)
+%!error wavread ("foo.wav", "foo")
+%!error wavread ("foo.wav", -1)
+%!error wavread ("foo.wav", [1, Inf], "foo");
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/wavwrite.m	Sat Sep 05 05:00:46 2015 -0700
@@ -0,0 +1,194 @@
+## Copyright (C) 2015 Mike Miller
+## Copyright (C) 2005-2015 Michael Zeising
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- 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{nbits}, @var{filename})
+##
+## @code{wavwrite} is deprecated and will be removed in Octave version 4.6.
+## Use @code{audiowrite} for the equivalent functionality.
+##
+## Write the audio signal @var{y} to the RIFF/WAVE sound file @var{filename}.
+##
+## If @var{y} is a matrix, the columns represent multiple audio channels.
+##
+## The optional argument @var{fs} specifies the sample rate of the audio signal
+## in Hz.
+##
+## The optional argument @var{nbits} specifies the number of bits per sample
+## to write to @var{filename}.
+##
+## The default sample rate is 8000 Hz and the default bit depth is 16 bits
+## per sample.
+##
+## @seealso{audiowrite, audioread, wavread}
+## @end deftypefn
+
+## Deprecated in 4.2
+
+function wavwrite (y, varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "wavwrite is obsolete and will be removed from a future version of Octave, please use audiowrite instead");
+  endif
+
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  ## Defaults.
+  fs = 8000;
+  nbits = 16;
+
+  filename = varargin{end};
+  if (nargin > 2)
+    fs = varargin{1};
+    if (nargin > 3)
+      nbits = varargin{2};
+    endif
+  endif
+
+  ## calculate filesize
+  [n, channels] = size (y);
+
+  ## allow y to be a row vector
+  if (n == 1)
+    y = y(:);
+    n = channels;
+    channels = 1;
+  endif
+
+  ## test arguments
+  if (channels < 1)
+    error ("wavwrite: Y must have at least one column");
+  endif
+
+  if (channels > 0x7FFF)
+    error ("wavwrite: Y must have no more than 32767 columns");
+  endif
+
+  if (! (isscalar (fs) && (fs > 0)))
+    error ("wavwrite: sample rate FS must be a positive number");
+  endif
+
+  if (! isscalar (nbits) || isempty (find (nbits == [8, 16, 24, 32])))
+    error ("wavwrite: bit depth NBITS must be 8, 16, 24, or 32");
+  endif
+
+  audiowrite (filename, y, fs, "BitsPerSample", nbits);
+
+endfunction
+
+
+%!shared fname
+%! fname = [tempname() ".wav"];
+
+%!testif HAVE_SNDFILE
+%! A = [-1:0.1:1; -1:0.1:1]';
+%! unwind_protect
+%!   wavwrite (A, fname);
+%!   [B, samples_per_sec, bits_per_sample] = wavread (fname);
+%!   assert (B, A, 2^-14);
+%!   assert (samples_per_sec, 8000);
+%!   assert (bits_per_sample, 16);
+%! unwind_protect_cleanup
+%!   unlink (fname);
+%! end_unwind_protect
+
+%!testif HAVE_SNDFILE
+%! A = [-1:0.1:1; -1:0.1:1]';
+%! unwind_protect
+%!   wavwrite (A, 4000, fname);
+%!   [B, samples_per_sec, bits_per_sample] = wavread (fname);
+%!   assert (B, A, 2^-14);
+%!   assert (samples_per_sec, 4000);
+%!   assert (bits_per_sample, 16);
+%! unwind_protect_cleanup
+%!   unlink (fname);
+%! end_unwind_protect
+
+%!testif HAVE_SNDFILE
+%! A = [-1:0.1:1; -1:0.1:1]';
+%! unwind_protect
+%!   wavwrite (A, 4000, 8, fname);
+%!   [B, samples_per_sec, bits_per_sample] = wavread (fname);
+%!   assert (B, A, 2^-6);
+%!   assert (samples_per_sec, 4000);
+%!   assert (bits_per_sample, 8);
+%! unwind_protect_cleanup
+%!   unlink (fname);
+%! end_unwind_protect
+
+%!testif HAVE_SNDFILE
+%! A = [-2:2]';
+%! unwind_protect
+%!   wavwrite (A, fname);
+%!   B = wavread (fname);
+%!   B *= 32768;
+%!   assert (B, [-32767 -32767 0 32767 32767]');
+%! unwind_protect_cleanup
+%!   unlink (fname);
+%! end_unwind_protect
+
+%!testif HAVE_SNDFILE
+%! A = [-1:0.1:1];
+%! unwind_protect
+%!   wavwrite (A, fname);
+%!   [B, samples_per_sec, bits_per_sample] = wavread (fname);
+%!   assert (B, A', 2^-14);
+%!   assert (samples_per_sec, 8000);
+%!   assert (bits_per_sample, 16);
+%! unwind_protect_cleanup
+%!   unlink (fname);
+%! end_unwind_protect
+
+%!testif HAVE_SNDFILE
+%! A = [-1:0.1:1; -1:0.1:1]';
+%! unwind_protect
+%!   wavwrite (A, fname);
+%!   B = wavread (fname, 15);
+%!   assert (B, A(1:15,:), 2^-14);
+%!   wavwrite (A, fname);
+%!   B = wavread (fname, [10, 20]);
+%!   assert (B, A(10:20,:), 2^-14);
+%! unwind_protect_cleanup
+%!   unlink (fname);
+%! end_unwind_protect
+
+%!testif HAVE_SNDFILE
+%! A = [-1:0.1:1; -1:0.1:1]';
+%! unwind_protect
+%!   wavwrite (A, fname);
+%!   [nsamp, nchan] = wavread (fname, "size");
+%!   assert (nsamp, 21);
+%!   assert (nchan, 2);
+%! unwind_protect_cleanup
+%!   unlink (fname);
+%! end_unwind_protect
+
+## Test input validation
+%!error wavwrite ()
+%!error wavwrite (1)
+%!error wavwrite (1,2,3,4,5)
+%!error wavwrite ([], "foo.wav");
+