octave-maintainers
[Top][All Lists]
Advanced

[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)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]