Discussion:
wavwrite problems
(too old to reply)
Randy Yates
2007-05-27 01:26:34 UTC
Permalink
I'm using octave 2.9.9 on

[***@localhost inp]$ uname -a
Linux localhost.localdomain 2.6.20-1.2948.fc6 #1 SMP Fri Apr 27 19:18:54 EDT 2007 x86_64 x86_64 x86_64 GNU/Linux

and I'm experiencing two problems with wavwrite():

1. The parameter order changed between version 2.9.8 and 2.9.9. This is
not really a problem, but may be noteworthy.

2. wavwrite() doesn't seem to be able to create a valid .wav file:

[yates] octave
x=2*rand(1,128)-1;
wavwrite('test.wav',x,64000,16);
quit
[yates] play test.wav
sox: Failed reading test.wav: WAVE header not found

What's up with this?
--
% Randy Yates % "The dreamer, the unwoken fool -
%% Fuquay-Varina, NC % in dreams, no pain will kiss the brow..."
%%% 919-577-9882 %
%%%% <***@ieee.org> % 'Eldorado Overture', *Eldorado*, ELO
http://home.earthlink.net/~yatescr
Randy Yates
2007-05-27 03:05:36 UTC
Permalink
Post by Randy Yates
I'm using octave 2.9.9 on
Linux localhost.localdomain 2.6.20-1.2948.fc6 #1 SMP Fri Apr 27 19:18:54 EDT 2007 x86_64 x86_64 x86_64 GNU/Linux
1. The parameter order changed between version 2.9.8 and 2.9.9. This is
not really a problem, but may be noteworthy.
[yates] octave
x=2*rand(1,128)-1;
wavwrite('test.wav',x,64000,16);
quit
[yates] play test.wav
sox: Failed reading test.wav: WAVE header not found
What's up with this?
The problem is caused by bugs in wavwrite.m. Namely, it assumes
lengths for the architecture-dependent data types "short" and "ulong".
I'm including an updated version that is corrected and seems to work.

PS: I believe you have the same problem in ausave() since it gave
the exact same error.
--
% Randy Yates % "And all that I can do
%% Fuquay-Varina, NC % is say I'm sorry,
%%% 919-577-9882 % that's the way it goes..."
%%%% <***@ieee.org> % Getting To The Point', *Balance of Power*, ELO
http://home.earthlink.net/~yatescr

## Copyright (C) 2005 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 2, 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, write to the Free
## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
## 02110-1301, USA.

## -*- texinfo -*-
## @deftypefn {Function File} {} wavwrite(@var{filename}, @var{y})
## Write @var{y} to the canonical RIFF/WAVE sound file @var{filename}. A sample
## rate of 8000 Hz and 16-bit samples are assumed. Each column of the data
## represents a separate channel.
##
## @deftypefnx {Function File} {} wavwrite(@var{filename}, @var{y}, @var{fs})
## Set the sample rate to @var{fs} Hz.
##
## @deftypefnx {Function File} {} wavwrite(@var{filename}, @var{y}, @var{fs}, @var{bits})
## Set the sample rate to @var{fs} Hz and resolution to @var{bits} bits.
## @seealso{wavread}
## @end deftypefn

## Author: Michael Zeising <***@stud.uni-erlangen.de>
## Created: 06 December 2005

function wavwrite (filename, y, samples_per_sec, bits_per_sample)

BYTEORDER = "ieee-le";

if (nargin < 2 || nargin > 4)
usage ("wavwrite (filename, y, samples_per_sec, bits_per_sample)");
endif

## parse arguments
if (nargin < 3)
warning ("wavwrite: sample rate set to 8000 Hz");
samples_per_sec = 8000;
endif

if (nargin < 4)
warning ("wavwrite: sample resolution set to 16-bit");
bits_per_sample = 16;
endif

## determine sample format
switch (bits_per_sample)
case 8
format = "uint8";
case 16
format = "int16";
case 32
format = "int32";
otherwise
error ("wavread: sample resolution not supported");
endswitch

## calculate filesize
channels = size(y)(2);
n = size(y)(1);

## 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

[fid, msg] = fopen (filename, "wb");
if (fid < 0)
error ("wavwrite: %s", msg)
endif

## write RIFF/WAVE header
c = 0;
c += fwrite (fid, "RIFF", "uchar");

## file size - 8
c += fwrite (fid, ck_size + 36, "uint32", 0, BYTEORDER);
c += fwrite (fid, "WAVEfmt ", "uchar");

## size of fmt chunk
c += fwrite (fid, 16, "uint32", 0, BYTEORDER);

## sample format code (PCM)
c += fwrite (fid, 0x0001, "uint16", 0, BYTEORDER);

## channels
c += fwrite (fid, channels, "uint16", 0, BYTEORDER);

## sample rate
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);

## block align
c += fwrite (fid, channels*bits_per_sample/8, "uint16", 0, BYTEORDER);

c += fwrite (fid, bits_per_sample, "uint16", 0, BYTEORDER);
c += fwrite (fid, "data", "uchar");
c += fwrite (fid, ck_size, "uint32", 0, BYTEORDER);

if (c < 25)
fclose (fid);
error ("wavread: writing to file failed");
endif

## interleave samples
yi = reshape (y', n*channels, 1);

## scale samples
switch (bits_per_sample)
case 8
yi = round (yi*127.5 + 127.5);
case 16
yi = floor (yi*32767.5);
case 32
yi = floor (yi*2147483647.5);
endswitch

## write to file
c = fwrite (fid, yi, format, 0, BYTEORDER);

fclose (fid);

endfunction
david bateman
2007-05-28 10:24:43 UTC
Permalink
Post by Randy Yates
Post by Randy Yates
I'm using octave 2.9.9 on
Linux localhost.localdomain 2.6.20-1.2948.fc6 #1 SMP Fri Apr 27 19:18:54 EDT 2007 x86_64 x86_64 x86_64 GNU/Linux
1. The parameter order changed between version 2.9.8 and 2.9.9. This is
not really a problem, but may be noteworthy.
[yates] octave
x=2*rand(1,128)-1;
wavwrite('test.wav',x,64000,16);
quit
[yates] play test.wav
sox: Failed reading test.wav: WAVE header not found
What's up with this?
The problem is caused by bugs in wavwrite.m. Namely, it assumes
lengths for the architecture-dependent data types "short" and "ulong".
I'm including an updated version that is corrected and seems to work.
PS: I believe you have the same problem in ausave() since it gave
the exact same error.
--
% Randy Yates % "And all that I can do
%% Fuquay-Varina, NC % is say I'm sorry,
%%% 919-577-9882 % that's the way it goes..."
## Copyright (C) 2005 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 2, 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, write to the Free
## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
## 02110-1301, USA.
## -*- texinfo -*-
## rate of 8000 Hz and 16-bit samples are assumed. Each column of the data
## represents a separate channel.
##
##
## Created: 06 December 2005
function wavwrite (filename, y, samples_per_sec, bits_per_sample)
BYTEORDER = "ieee-le";
if (nargin < 2 || nargin > 4)
usage ("wavwrite (filename, y, samples_per_sec, bits_per_sample)");
endif
## parse arguments
if (nargin < 3)
warning ("wavwrite: sample rate set to 8000 Hz");
samples_per_sec = 8000;
endif
if (nargin < 4)
warning ("wavwrite: sample resolution set to 16-bit");
bits_per_sample = 16;
endif
## determine sample format
switch (bits_per_sample)
case 8
format = "uint8";
case 16
format = "int16";
case 32
format = "int32";
otherwise
error ("wavread: sample resolution not supported");
endswitch
## calculate filesize
channels = size(y)(2);
n = size(y)(1);
## 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
[fid, msg] = fopen (filename, "wb");
if (fid < 0)
error ("wavwrite: %s", msg)
endif
## write RIFF/WAVE header
c = 0;
c += fwrite (fid, "RIFF", "uchar");
## file size - 8
c += fwrite (fid, ck_size + 36, "uint32", 0, BYTEORDER);
c += fwrite (fid, "WAVEfmt ", "uchar");
## size of fmt chunk
c += fwrite (fid, 16, "uint32", 0, BYTEORDER);
## sample format code (PCM)
c += fwrite (fid, 0x0001, "uint16", 0, BYTEORDER);
## channels
c += fwrite (fid, channels, "uint16", 0, BYTEORDER);
## sample rate
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);
## block align
c += fwrite (fid, channels*bits_per_sample/8, "uint16", 0, BYTEORDER);
c += fwrite (fid, bits_per_sample, "uint16", 0, BYTEORDER);
c += fwrite (fid, "data", "uchar");
c += fwrite (fid, ck_size, "uint32", 0, BYTEORDER);
if (c < 25)
fclose (fid);
error ("wavread: writing to file failed");
endif
## interleave samples
yi = reshape (y', n*channels, 1);
## scale samples
switch (bits_per_sample)
case 8
yi = round (yi*127.5 + 127.5);
case 16
yi = floor (yi*32767.5);
case 32
yi = floor (yi*2147483647.5);
endswitch
## write to file
c = fwrite (fid, yi, format, 0, BYTEORDER);
fclose (fid);
endfunction
Randy,

Please send this report to ***@octave.org as this is a bug report in a
core octave function

D.

Loading...