By Ben Owen, 22/08/2009
Revision 2, 24/08/2009
-------------------------------
The VOC format is a fairly straightforward method of storing sound data. It was originally specific to Creative Soundblaster sound cards, but can sometimes be found today when recording sounds using a cheap MP3 player.
A .VOC file consists of a header followed by at least two data blocks, of which the last one will always be an End of Data marker.
header {
char[20] FileType; /* Must be "Creative Voice File" followed by an EOF
* character (0x1A). */
Int16 DataOffset; // Start position of the data block.
Int16 FileVersion; /* File version. First byte is Major, second is
* Minor version number. This document is valid for
* values 0x010A and 0x0114, and apparently 256..*/
Int16 IDcode; // ~FileVersion + 0x1234 :- helps verify VOC file.
}
The data blocks always start with the same 4 bytes (excluding End of Data marker):
datablock {
byte BlockType; // Type of block that follows.
byte[3] BlockLength; // A 3-byte (24-bit) integer, gives block length.
}
Where BlockType is one of the following:
enum VocBlockType : byte {
EndOfData = 0; // End of Data marker. No following length field.
NewSampleData = 1; /* Followed by two bytes indicating Sample Rate
* and Compression Type. The sample rate of the
* sound can be calculated using:
* Sample Rate = (-1000000)/(SR-256), where SR is
* the value read from the file. The compression
* type values are as follows:
* 0 : 8 bits - ie. uncompressed samples
* 1 : 4 bits packed
* 2 : 2.6 bits packed
* 3 : 2 bits packed
* These two bytes are then followed by
* (BlockLength - 2) bytes of sample data.
*/
SampleData = 2; /* Sample data, use same properties as the
* preceeding block in the file.
*/
Silence = 3; /* Followed by 3 bytes. First two indicate duration
* in terms of bytes. Third gives sample rate in
* the same manner as in NewSampleData.
*/
Marker = 4; // Not covered.
ASCIIText = 5; // Not covered.
RepeatStart = 6; // Not covered.
RepeatEnd = 7; // Not covered.
AdditionalInfo = 8; // Not covered.
NewBlockType = 9; // May be covered in a future revision.
}