Mercurial > hg > octave-avbm
changeset 6304:78a3254741b2
[project @ 2007-02-14 21:22:59 by jwe]
author | jwe |
---|---|
date | Wed, 14 Feb 2007 21:22:59 +0000 |
parents | df89e87a1d2e |
children | 48f8af442b8a |
files | scripts/ChangeLog scripts/audio/wavread.m scripts/audio/wavwrite.m |
diffstat | 3 files changed, 69 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,8 @@ +2007-02-14 Thomas Weber <thomas.weber.mail@gmail.com> + + * audio/wavread.m, audio/wavwrite.m: Use types with specific sizes + for reading and writing data. New tests. Improve rounding. + 2007-02-13 John W. Eaton <jwe@octave.org> * plot/stem.m: New file, adapted from OctPlot.
--- a/scripts/audio/wavread.m +++ b/scripts/audio/wavread.m @@ -84,24 +84,24 @@ endwhile ## format chunk size - ck_size = fread (fid, 1, "ulong", 0, BYTEORDER); + ck_size = fread (fid, 1, "uint32", 0, BYTEORDER); ## sample format code - format_tag = fread (fid, 1, "short", 0, BYTEORDER); + format_tag = fread (fid, 1, "uint16", 0, BYTEORDER); if (format_tag != FORMAT_PCM && format_tag != FORMAT_IEEE_FLOAT) fclose (fid); error ("wavread: sample format %#x is not supported", format_tag); endif ## number of interleaved channels - channels = fread (fid, 1, "short", 0, BYTEORDER); + channels = fread (fid, 1, "uint16", 0, BYTEORDER); ## sample rate - samples_per_sec = fread (fid, 1, "ulong", 0, BYTEORDER); + samples_per_sec = fread (fid, 1, "uint32", 0, BYTEORDER); ## bits per sample fseek (fid, 6, SEEK_CUR); - bits_per_sample = fread (fid, 1, "short", 0, BYTEORDER); + bits_per_sample = fread (fid, 1, "uint16", 0, BYTEORDER); ## ignore the rest of the chunk fseek (fid, ck_size-16, SEEK_CUR); @@ -119,7 +119,7 @@ end ## data chunk size - ck_size = fread (fid, 1, "ulong", 0, BYTEORDER); + ck_size = fread (fid, 1, "uint32", 0, BYTEORDER); ## determine sample data type if (format_tag == FORMAT_PCM) @@ -134,7 +134,8 @@ format = "int32"; otherwise fclose (fid); - error ("wavread: %d bits sample resolution is not supported with PCM", bits_per_sample); + error ("wavread: %d bits sample resolution is not supported with PCM", + bits_per_sample); endswitch else switch (bits_per_sample) @@ -144,7 +145,8 @@ format = "float64"; otherwise fclose (fid); - error ("wavread: %d bits sample resolution is not supported with IEEE float", bits_per_sample); + error ("wavread: %d bits sample resolution is not supported with IEEE float", + bits_per_sample); endswitch endif @@ -179,6 +181,12 @@ [yi, n] = fread (fid, length, format, 0, BYTEORDER); fclose (fid); + ## check data + if (mod (numel (yi), channels) != 0) + error ("wavread: data in %s doesn't match the number of channels", + filename); + endif + if (bits_per_sample == 24) yi = reshape (yi, 3, rows(yi)/3)'; yi(yi(:,3) >= 128, 3) -= 256;
--- a/scripts/audio/wavwrite.m +++ b/scripts/audio/wavwrite.m @@ -42,17 +42,23 @@ print_usage (); endif + ## test arguments + if (columns (y) < 1) + error ("wavwrite: Y must have at least one column"); + endif + if (columns (y) > 2^15-1) + error ("wavwrite: Y has more than 32767 columns (too many for a WAV-file)"); + 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 @@ -62,12 +68,11 @@ case 32 format = "int32"; otherwise - error ("wavread: sample resolution not supported"); + error ("wavwrite: sample resolution not supported"); endswitch ## calculate filesize - channels = size(y)(2); - n = size(y)(1); + [n, channels] = size(y); ## size of data chunk ck_size = n*channels*(bits_per_sample/8); @@ -88,35 +93,35 @@ c += fwrite (fid, "RIFF", "uchar"); ## file size - 8 - c += fwrite (fid, ck_size + 36, "ulong", 0, BYTEORDER); + c += fwrite (fid, ck_size + 36, "uint32", 0, BYTEORDER); c += fwrite (fid, "WAVEfmt ", "uchar"); ## size of fmt chunk - c += fwrite (fid, 16, "ulong", 0, BYTEORDER); + c += fwrite (fid, 16, "uint32", 0, BYTEORDER); ## sample format code (PCM) - c += fwrite (fid, 0x0001, "short", 0, BYTEORDER); + c += fwrite (fid, 1, "uint16", 0, BYTEORDER); ## channels - c += fwrite (fid, channels, "short", 0, BYTEORDER); + c += fwrite (fid, channels, "uint16", 0, BYTEORDER); ## sample rate - c += fwrite (fid, samples_per_sec, "ulong", 0, BYTEORDER); + 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, "ulong", 0, BYTEORDER); + c += fwrite (fid, bps, "uint32", 0, BYTEORDER); ## block align - c += fwrite (fid, channels*bits_per_sample/8, "short", 0, BYTEORDER); + c += fwrite (fid, channels*bits_per_sample/8, "uint16", 0, BYTEORDER); - c += fwrite (fid, bits_per_sample, "short", 0, BYTEORDER); + c += fwrite (fid, bits_per_sample, "uint16", 0, BYTEORDER); c += fwrite (fid, "data", "uchar"); - c += fwrite (fid, ck_size, "ulong", 0, BYTEORDER); + c += fwrite (fid, ck_size, "uint32", 0, BYTEORDER); if (c < 25) fclose (fid); - error ("wavread: writing to file failed"); + error ("wavwrite: writing to file failed"); endif ## interleave samples @@ -125,11 +130,11 @@ ## scale samples switch (bits_per_sample) case 8 - yi = round (yi*127.5 + 127.5); + yi = round (yi*128 + 128); case 16 - yi = floor (yi*32767.5); + yi = round (yi*32768); case 32 - yi = floor (yi*2147483647.5); + yi = round (yi*2147483648); endswitch ## write to file @@ -138,3 +143,27 @@ fclose (fid); 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)); +%! assert(samples_per_sec, 8000); +%! assert(bits_per_sample, 16); +% +%!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)); +%! assert(samples_per_sec, 4000); +%! assert(bits_per_sample, 16); +% +%!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)); +%! assert(samples_per_sec, 4000); +%! assert(bits_per_sample, 8);