[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
24-bit wav files and other observations
From: |
Daniel J Sebald |
Subject: |
24-bit wav files and other observations |
Date: |
Thu, 21 Feb 2008 16:06:28 -0600 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.3) Gecko/20041020 |
Dave, Paul,
I wanted to read a WAV file with 24 bit data width using auload()--rather than
the 8, 16, or 32-bit facility. I've made some simple changes (see attached
patch), which brings up a few issues.
1) The fread() routine always returns a variable of type 'double'. You'd
think that the variable would have the native format. E.g.,
data = fread(file, samples, 'uint8', 0, arch);
would mean 'data' to be of type 'uint8'. I suppose it is a compatibility
issue, and it isn't that big of deal. In some instances it is a convenience, I
suppose. Other times not.
2) Why does Octave/Matlab not have 'uint24' throughout? For example, there'd
be nothing unusual about
data = fread(file, samples, 'int24', 0, arch);
and a type 'int24'.
3) Dave, have I done this conversion as efficiently as possible? Are there
better ways of doing casting in the patch that are more direct?
4) I tried implementing the behavior of the following line:
data1 = data(1:3:end) + data(2:3:end) * 2^8 +
cast(typecast(cast(data(3:3:end), 'uint8'), 'int8'), 'double') * 2^16;
as bit shifts in the following way:
data = bitor(bitor(data(1:3:end), bitshift(data(2:3:end), 8)),
bitshift(cast(typecast(cast(data(3:3:end), 'uint8'), 'int8'), 'double'), 16));
so I can double check for proper 24-bit construction. However, this bit shift
method doesn't work. It comes down to the following quandary. This looks
correct:
octave:52> bitor(2, 1)
ans = 3
but when working with negative numbers, the following doesn't look correct:
octave:53> bitor(-2, 1)
ans = 1
I would think that bitor(-2,1) should be -1. Is this a bug?
5) Is the documentation for "who" correct?
-- Command: who options pattern ...
-- Command: whos options pattern ...
List currently defined symbols matching the given patterns. The
following are valid options. They may be shortened to one
character but may not be combined.
`-all'
List all currently defined symbols.
`-builtins'
List built-in functions. This includes all currently
compiled function files, but does not include all function
files that are in the search path.
`-functions'
List user-defined functions.
`-long'
Print a long listing including the type and dimensions of any
symbols. The symbols in the first column of output indicate
whether it is possible to redefine the symbol, and whether it
is possible for it to be cleared.
The options don't work. I get:
octave:48> who x
Variables in the current scope:
x
octave:49> whos x
Variables in the current scope:
Attr Name Size Bytes Class
==== ==== ==== ===== =====
x 2209792x2 35356672 double
Total is 4419584 elements using 35356672 bytes
octave:50> who -l x
warning: who: unrecognized option `-l'
Variables in the current scope:
x
Dan
--- auload.m.orig 2008-02-21 00:37:27.000000000 -0600
+++ auload.m 2008-02-21 15:49:04.337754060 -0600
@@ -132,6 +132,10 @@
sampleformat = 'int16';
precision = 'int16';
samples = len/2;
+ elseif bits == 24
+ sampleformat = 'int24';
+ precision = 'int24';
+ samples = len/3;
elseif bits == 32
sampleformat = 'int32';
precision = 'int32';
@@ -325,7 +329,16 @@
## suck in all the samples
if (samples <= 0) samples = Inf; end
- data = fread(file, samples, precision, 0, arch);
+ if (precision == 'int24')
+ data = fread(file, 3*samples, 'uint8', 0, arch);
+ if (arch == 'ieee-le')
+ data = data(1:3:end) + data(2:3:end) * 2^8 +
cast(typecast(cast(data(3:3:end), 'uint8'), 'int8'), 'double') * 2^16;
+ else
+ data = data(3:3:end) + data(2:3:end) * 2^8 +
cast(typecast(cast(data(1:3:end), 'uint8'), 'int8'), 'double') * 2^16;
+ endif
+ else
+ data = fread(file, samples, precision, 0, arch);
+ endif
fclose(file);
## convert samples into range [-1, 1)
- 24-bit wav files and other observations,
Daniel J Sebald <=