Author Topic: Microsoft RIFF WAVE file format  (Read 47406 times)

0 Members and 1 Guest are viewing this topic.

Offline James

  • Administrator
  • Hero Member
  • *****
  • Posts: 2132
  • Milliwatts: 47
  • Gender: Male
    • View Profile
    • LaserBoy !!!
Microsoft RIFF WAVE file format
« on: May 05, 2009, 02:24:20 pm »
Hey everybody!

Dean just sent me a draft of a white paper he is working on about the use of the wave file format for multi color laser vector signals. His document outlines additions to the wave file header and data formatting that both his application "LaserWAVE" and LaserBoy can translate back into color laser vector art.

I would like to get this thread going about all of the information that we know and everything we need to know about the wave!

Agent-C has offered up some waves and I think his header is "legal", but I can not open them in LaserBoy.

There is also a variation on the wave header that is totally different than the old-style. It has a wave list in it or some weird stuff....

We should all get together and really figure out what is what!

This thread might also be a good place to declare which wave players out there really know how to deal with 6 and 8 channel wave and which wave editors are good to use for what purposes.

Even if you have no interest in making or playing waves, keep in mind that there are people who are making very unusual laser vector art in that format and YOU might want to be able to read it!

James.  :)
LaserBoy is Sofa King Cool!
But it will never be Alpha King Done!

Offline meandean

  • Sr. Member
  • ****
  • Posts: 466
  • Milliwatts: 13
  • It's about sight AND sound.
    • View Profile
Re: Microsoft RIFF WAVE file format
« Reply #1 on: May 05, 2009, 09:44:06 pm »
 I'd like to check out Agent-C's waves... Have you tried opening them in LW?
"Patience is for the dead."

Offline James

  • Administrator
  • Hero Member
  • *****
  • Posts: 2132
  • Milliwatts: 47
  • Gender: Male
    • View Profile
    • LaserBoy !!!
LaserBoy is Sofa King Cool!
But it will never be Alpha King Done!

Offline BlinkenLights

  • he's just this guy, ya know?
  • Administrator
  • Hero Member
  • *****
  • Posts: 730
  • Milliwatts: 4
  • Gender: Male
  • 'The Messenger' by Will Cascio
    • View Profile
« Last Edit: May 06, 2009, 11:26:43 pm by BlinkenLights »

Offline meandean

  • Sr. Member
  • ****
  • Posts: 466
  • Milliwatts: 13
  • It's about sight AND sound.
    • View Profile
Re: Microsoft RIFF WAVE file format
« Reply #4 on: May 07, 2009, 02:52:17 pm »
  Boids seems to load fine in LB 3900, as well as Cool Edit, Spider & Winamp (and MPlayer11 in XP but not Vista, but that's normal);
the header is the minimal 44 byte PCM type and the color signals are negative, which would make sense for a modified sound card.

  At this point, LB can't read 44 byte headers correctly, except when adding a stereo wave to an existing 6ch rendering, or certain
other wave joining functions.

  If you open Boids in LW plot 3900 (with 6ch generate enabled) it will regenerate a wave that will open in LB. Since the data is not
formatted, it will be clocked into wave frames at the specified frame rate. Suprisingly, the frames don't look much different with
significant changes in rate, 20fps looks fine. It would be interesting to tweak LB's optimization parameters to get a best fit on a
projector. 
"Patience is for the dead."

Offline James

  • Administrator
  • Hero Member
  • *****
  • Posts: 2132
  • Milliwatts: 47
  • Gender: Male
    • View Profile
    • LaserBoy !!!
Re: Microsoft RIFF WAVE file format
« Reply #5 on: May 07, 2009, 06:43:47 pm »
"At this point, LB can't read 44 byte headers correctly"

That what I figured. LaserBoy sucks.

James.  :)
LaserBoy is Sofa King Cool!
But it will never be Alpha King Done!

Offline meandean

  • Sr. Member
  • ****
  • Posts: 466
  • Milliwatts: 13
  • It's about sight AND sound.
    • View Profile
Re: Microsoft RIFF WAVE file format
« Reply #6 on: May 08, 2009, 12:30:14 am »
  Windows Media Player 11 supports ripping of audio CD tracks to a wave file,
but the specific layout of wave utilized places the all-important format chunk
after a LIST chunk containing varying amounts of extra non-audio information.
 
  The RIFF and Data chunks are the same as minimal 44 byte PCM headers, but the Format chunk
is a little longer due to the inclusion of 2 extra format bytes that are probably just spacers.
The added LIST chunk contains a whole block of non-audio text information.
 
''** RIFF chunk 'This chunk is the master and includes all sub-chunks that follow
 
  "RIFF"    (4 byte ASCII)  'ASCII is big endian
 
  Length from here to end of file, FileSize - 8  (4 byte int) 'Integers are little endian
                       
  "WAVE"    (4 byte ASCII)  'RIFF type

''** LIST chunk
 
  "LIST"    (4 byte ASCII) Length form here to the next chunk  (4 byte int)  'Use this to skip past the garbage
 
  LIST info:  Varying amounts of sub-chunks containing everthing from track/title and authorship,
  5-day weather forecast, scientific table of universal constants, and more useless info.

''** format chunk
 
  "fmt "   (4 byte ASCII)  'Don't forget the space
 
  Length from here to the next chunk, 16 + 2 extra format bytes  (4 byte int)
 
  Compression code = 1  (2 byte int)  'A setting of 1 indicates that the data is uncompressed PCM
 
  Number of channels = 2  (2 byte int)
 
  Sample rate in Hz = 44100  (4 byte int)
 
  Bytes per second (4 byte int) = 176400  'NumChannels * 2 * SampleRate
 
  Bytes per sample period (2 byte int) = 4  'NumChannels * 2
 
  Bits per sample (2 byte int) = 16
 
  'Extra Format' bytes (2 total)  'These bytes are set to zero
 

''** data chunk
 
  "data"  (4 byte ASCII)
 
  Total PCM size, TotalTime * BytesPerSecond (4 byte int)  'Length from here to end of the chunk
 
  PCM sample data (2 byte signed int values) 'Left #1, Right #1, Left #2, Right #2, etc.
 
''*********
 
« Last Edit: July 10, 2010, 10:27:03 pm by meandean »
"Patience is for the dead."

Offline James

  • Administrator
  • Hero Member
  • *****
  • Posts: 2132
  • Milliwatts: 47
  • Gender: Male
    • View Profile
    • LaserBoy !!!
Re: Microsoft RIFF WAVE file format
« Reply #7 on: August 22, 2009, 12:05:21 am »
Well, I've just done TONS of work with wave code. So I'm kind-of into the subject at the moment.

I just found out that it _IS_ possible to export single wave files with as many channels as you want from Audacity !!!

This is the first time I've ever seen an application that can do this apart from LaserBoy, LaserWAVE and some other stuff either Dean or I wrote!

.................Excuse me! (Agent-C) and Laser-Agent!  ;)

This is really good news, because Audacity is free and open. It also means that it is likely that it will be able to play back multi channel waves into a device with more that 2 channels of output (I hope!). None of this is really necessary as these things can be done with LaserBoy and Spider Player, but this is a good sign because it proves that these concepts are generic and universal! YES there are very cool things you can do with all tracks in a display and the ability to select and loop the playback. I've done that in another app that is not free.

James.  :)
« Last Edit: August 22, 2009, 12:39:46 am by James »
LaserBoy is Sofa King Cool!
But it will never be Alpha King Done!

Offline James

  • Administrator
  • Hero Member
  • *****
  • Posts: 2132
  • Milliwatts: 47
  • Gender: Male
    • View Profile
    • LaserBoy !!!
Re: Microsoft RIFF WAVE file format
« Reply #8 on: October 01, 2009, 02:58:26 pm »

//----------------------------------------------------------------------------
// Microsoft RIFF WAVE file header
//----------------------------------------------------------------------------
 
"RIFF"             (4 byte literal string)
chunk_size         (32-bit int) = 20 + sub_chunk_1_size + sub_chunk_2_size
"WAVE"             (4 byte literal string)
"fmt "             (4 byte literal string; note the space at the end)
sub_chunk_1_size   (32-bit int) = 16 + sizeof (LaserBoy stuff)
audio_format       (16-bit short) 1
num_channels       (16-bit short) 6 or 8
sample_rate        (32-bit int) 48000
byte_rate          (32-bit int) = sample_rate * num_channels * (bits_per_sample / 8)
block_align        (16-bit short) = num_channels * (bits_per_sample / 8)
bits_per_sample    (16-bit short) 16
 
//----------------------------------------------------------------------------
// stuff added for LaserBoy !!!
//----------------------------------------------------------------------------
 
"LaserBoy11112008" (16 byte literal string, current header version)
LaserBoy_wave_mode (32-bit int)
 
(OPTIONAL if the LASERBOY_WAVE_OFFSETS bit is set)
{
    offset[0]          (32-bit int)
    offset[1]          (32-bit int)
    offset[2]          (32-bit int)
    offset[3]          (32-bit int)
    offset[4]          (32-bit int)
    offset[5]          (32-bit int)
    offset[6]          (32-bit int) (optional, only for 8 channels)
    offset[7]          (32-bit int) (optional, only for 8 channels)
}

(OPTIONAL if you write anything other than X, Y, r, g, b, undefined)
{
    signal_id [0] (16-bit short) LASERBOY_SIGNAL_X_POSITION
    signal_id [1] (16-bit short) LASERBOY_SIGNAL_Y_POSITION
    signal_id [2] (16-bit short) LASERBOY_SIGNAL_RED_ANALOG
    signal_id [3] (16-bit short) LASERBOY_SIGNAL_GREEN_ANALOG
    signal_id [4] (16-bit short) LASERBOY_SIGNAL_BLUE_ANALOG
    signal_id [5] (16-bit short) *** THIS_IS_THE_SIGNAL_YOU_NEED_TO_IDENTIFY ***
    signal_id [6] (16-bit short) LASERBOY_SIGNAL_AUDIO_LEFT   (optional, only for 8 channels)
    signal_id [7] (16-bit short) LASERBOY_SIGNAL_AUDIO_RIGHT  (optional, only for 8 channels)
 
    LSB_tag   [0] (16-bit short) LASERBOY_LSB_NOT_USED
    LSB_tag   [1] (16-bit short) LASERBOY_LSB_NOT_USED
    LSB_tag   [2] (16-bit short) LASERBOY_LSB_END_OF_FRAME (eof is LSB of channel[2])
    LSB_tag   [3] (16-bit short) LASERBOY_LSB_NOT_USED
    LSB_tag   [4] (16-bit short) LASERBOY_LSB_NOT_USED
    LSB_tag   [5] (16-bit short) LASERBOY_LSB_NOT_USED
    LSB_tag   [6] (16-bit short) LASERBOY_LSB_NOT_USED (optional, only for 8 channels)
    LSB_tag   [7] (16-bit short) LASERBOY_LSB_NOT_USED (optional, only for 8 channels)
}
 
(OPTIONAL if the LASERBOY_SIGNAL_BIT_RESOLUTION bit is set)
{
    resolution[0] (8-bit byte)  16
    resolution[1] (8-bit byte)  16
    resolution[2] (8-bit byte)   9
    resolution[3] (8-bit byte)   9
    resolution[4] (8-bit byte)   9
    resolution[5] (8-bit byte)  16 or whatever known signal is
    resolution[6] (8-bit byte)  16 (optional, only for 8 channels)
    resolution[7] (8-bit byte)  16 (optional, only for 8 channels)
}

//----------------------------------------------------------------------------
// end of // stuff added for LaserBoy !!!
//----------------------------------------------------------------------------

"data"             (4 byte literal string)
sub_chunk_2_size   (32-bit int) = num_samples * num_channels * (bits_per_sample / 8)
 
//----------------------------------------------------------------------------
// end of wave header. actual wave data follows...
//----------------------------------------------------------------------------

 
 
for the value of LaserBoy_wave_mode, set these bits to 1 to enable each feature.
#define    LASERBOY_WAVE_NEGATIVE               0
#define    LASERBOY_WAVE_POSITIVE               1
#define    LASERBOY_WAVE_END_OF_FRAME           2
#define    LASERBOY_WAVE_UNIQUE_FRAME           4
#define    LASERBOY_WAVE_UNIQUE_VERTEX          8
#define    LASERBOY_WAVE_OFFSETS                16
#define    LASERBOY_WAVE_OPTIMIZED              32
#define    LASERBOY_WAVE_SIGNAL_MATRIX          64
#define    LASERBOY_SIGNAL_BIT_RESOLUTION       128

Setting the bits for:
LASERBOY_WAVE_OFFSETS
LASERBOY_WAVE_OPTIMIZED
LASERBOY_WAVE_SIGNAL_MATRIX
LASERBOY_SIGNAL_BIT_RESOLUTION
also requires that you store an associated set of values for each of these features.

LASERBOY_WAVE_OPTIMIZED indicates that the wave has been optimized for direct
playback to a laser projector. This means that a specific set of processes have
been applied to the vector data before it was written to wave. The set of values
that get stored in the wave header are values that were used in the optimization
process and are probably not useful to anyone outside of the LaserBoy code.

LASERBOY_SIGNAL_BIT_RESOLUTION is enabled by setting the 128 bit.
A set of single, unsigned bytes are stored, one for each channel, that indicate the
actual number of bits of significance in each of the channels.


When you put some data into the sixth channel, you need to set bit 64
in LaserBoy_wave_mode and identify all of the signals. This is done with
two sets of signed 16-bit short integers that follow the offsets.
These are stored one for each channel.
The first set are the signal_id numbers.
The absolute values are shown below in hex.
 
#define    LASERBOY_SIGNAL_NO_SIGNAL            0x00 // zero
#define    LASERBOY_SIGNAL_UNDEFINED            0x01 // not zero
#define    LASERBOY_SIGNAL_X_POSITION           0x10
#define    LASERBOY_SIGNAL_Y_POSITION           0x11
#define    LASERBOY_SIGNAL_Z_POSITION           0x12
#define    LASERBOY_SIGNAL_DX_POSITION          0x13
#define    LASERBOY_SIGNAL_DY_POSITION          0x14
#define    LASERBOY_SIGNAL_X2_POSITION          0x15
#define    LASERBOY_SIGNAL_Y2_POSITION          0x16
#define    LASERBOY_SIGNAL_BEAM_WIDTH           0x20
#define    LASERBOY_SIGNAL_RED_TTL              0x30
#define    LASERBOY_SIGNAL_RED_ANALOG           0x31
#define    LASERBOY_SIGNAL_YELLOW_TTL           0x32
#define    LASERBOY_SIGNAL_YELLOW_ANALOG        0x33
#define    LASERBOY_SIGNAL_GREEN_TTL            0x34
#define    LASERBOY_SIGNAL_GREEN_ANALOG         0x35
#define    LASERBOY_SIGNAL_BLUE_TTL             0x36
#define    LASERBOY_SIGNAL_BLUE_ANALOG          0x37
#define    LASERBOY_SIGNAL_VIOLET_TTL           0x38
#define    LASERBOY_SIGNAL_VIOLET_ANALOG        0x39
#define    LASERBOY_SIGNAL_MONO_TTL             0x3a
#define    LASERBOY_SIGNAL_MONO_OR_ANALOG       0x3b
#define    LASERBOY_SIGNAL_MONO_WEIGHTED_ANALOG 0x3c
#define    LASERBOY_SIGNAL_MONO_AVG_ANALOG      0x3d
#define    LASERBOY_SIGNAL_MONO_O_SCOPE         0x3e
#define    LASERBOY_SIGNAL_AUDIO_SMTPE          0x40
#define    LASERBOY_SIGNAL_AUDIO_MONO           0x41
#define    LASERBOY_SIGNAL_AUDIO_LEFT           0x42
#define    LASERBOY_SIGNAL_AUDIO_RIGHT          0x43
#define    LASERBOY_SIGNAL_AUDIO_CENTER         0x44
#define    LASERBOY_SIGNAL_AUDIO_SUB            0x45
#define    LASERBOY_SIGNAL_AUDIO_S_LEFT         0x46
#define    LASERBOY_SIGNAL_AUDIO_S_RIGHT        0x47
#define    LASERBOY_SIGNAL_AUDIO_R_LEFT         0x48
#define    LASERBOY_SIGNAL_AUDIO_R_RIGHT        0x49

To indicate that an individual signal has been negated with respect
to the global polarity, use the negative value of the signal number.

The second set are the LSB_tag numbers.
These numbers may be stored in any of the channel's LSB_tag values
to indicate that the least significant bit of this channel is used as
a Boolean marker to indicate something special about a particular sample.
 
#define    LASERBOY_LSB_NOT_USED                0
#define    LASERBOY_LSB_BLANKING                1
#define    LASERBOY_LSB_END_OF_FRAME            2
#define    LASERBOY_LSB_UNIQUE_FRAME            3
#define    LASERBOY_LSB_UNIQUE_VERTEX           4

It is not necessary to set and use LASERBOY_WAVE_SIGNAL_MATRIX
to get the benefit of LASERBOY_WAVE_END_OF_FRAME.
In the case where the first is not set and the second is,
it should be assumed that eof marks will be found in the LSB
of the third channel; red.

Use the default value of 16 for sub_chunk_1_size PLUS the following:
16 bytes for sizeof "LaserBoymmddCCYY"
4 bytes for sizeof (int)LaserBoy_wave_mode
4 bytes EACH for n channels of offsets (only if you use them!)
4 bytes EACH (2 * 16-bit) for n channels of signal_ID and LSB_tag (only if you use them!)
1 byte  EACH for n channels of signal bit resolution (only if you use them!)




Some of you......  %)
might get a little weirded-out by the repeated appearance of the word LaserBoy (or LASERBOY) in all of the above. There is only ONE time that the word LaserBoy appears in the actual wave header that you must create in order to make waves that are compatible with this format. That is "LaserBoy11112008"; which is the current version of this arrangement of data. All of the other instances of the word are nothing but numerical value tokens, used only in the LaserBoy code, provided here to share their values.

"LaserBoy" is NOT a brand name!

It is a FREE and OPEN concept for extending the utility of the wave file format.

James.  :)
 
« Last Edit: October 11, 2009, 11:39:58 pm by James »
LaserBoy is Sofa King Cool!
But it will never be Alpha King Done!

Offline Fanny Pack

  • Hero Member
  • *****
  • Posts: 645
  • Milliwatts: -20
  • Gender: Male
    • View Profile
Re: Microsoft RIFF WAVE file format
« Reply #9 on: October 02, 2009, 06:56:22 am »
Consider making a Windows DLL that encodes/decodes all of that from/to useable objects.

Offline cfavreau

  • Newbie
  • *
  • Posts: 37
  • Milliwatts: 1
    • View Profile
Re: Microsoft RIFF WAVE file format
« Reply #10 on: October 02, 2009, 03:07:34 pm »
Or just a set of C functions... or C++ classes... that would be awesome!  Thanks for posting your work!

Offline James

  • Administrator
  • Hero Member
  • *****
  • Posts: 2132
  • Milliwatts: 47
  • Gender: Male
    • View Profile
    • LaserBoy !!!
Re: Microsoft RIFF WAVE file format
« Reply #11 on: October 02, 2009, 03:13:03 pm »
Take a look at LaserBoy_wave.hpp and LaserBoy_wave.cpp !!!  ;D

(A lot of things are defined in LaserBoy_macros.hpp)

The classes are pretty straight forward. Writing to wave file headers in this form is also easy to see in the code. The code for reading the header back into memory is a bit complicated due to the fact that it knows how to read several earlier versions of added, non-standard, wave header information.

I would really like to help anyone else who might want to work with rendering to waves that use these concepts and constructs.

Please feel free to ask questions. It will help flesh it out for everyone.

James.  :)
« Last Edit: October 02, 2009, 06:41:22 pm by James »
LaserBoy is Sofa King Cool!
But it will never be Alpha King Done!

Agent C

  • Guest
Re: Microsoft RIFF WAVE file format
« Reply #12 on: October 11, 2009, 05:49:08 pm »
I'm all about this.  I need to add wave writing back in as an option.

Offline James

  • Administrator
  • Hero Member
  • *****
  • Posts: 2132
  • Milliwatts: 47
  • Gender: Male
    • View Profile
    • LaserBoy !!!
Re: Microsoft RIFF WAVE file format
« Reply #13 on: October 11, 2009, 06:23:50 pm »
Hold the phone....

I'm in that code right now!

I just figured out a problem with my copy constructors for the wave header in certain uses.

I'm on it!

In the mean time, if you have any general Qs or Cs let me know.

James.  :)
LaserBoy is Sofa King Cool!
But it will never be Alpha King Done!

Offline James

  • Administrator
  • Hero Member
  • *****
  • Posts: 2132
  • Milliwatts: 47
  • Gender: Male
    • View Profile
    • LaserBoy !!!
Re: Microsoft RIFF WAVE file format
« Reply #14 on: October 24, 2009, 12:43:51 am »
Check this out!

This is Audacity.

This is a great way to open, examine, edit, invert, normalize, organize and SAVE multi channel wave files!  ;D

It's free and it works exactly the same in every OS!  ;D

James.  :)
« Last Edit: October 24, 2009, 02:28:19 am by James »
LaserBoy is Sofa King Cool!
But it will never be Alpha King Done!

 

SMF spam blocked by CleanTalk
SimplePortal 2.3.7 © 2008-2024, SimplePortal