CREATIVE VOICE FILE (VOC) FORMAT The Creative Voice File is organized in two main blocks, the Header Block and Data Block. The Header Block contains identifier, version number and pointer to the start of the Data Block. The Data Block is divided into sub-blocks of various types. The CT-VOICE driver only processes the Data Block. It is important that you pass the address of the Data Block and not the entire .VOC file when calling this driver to perform digitized sound output. Header Block Offset (Hex) Description 00h - 13h File type description The following message is stored here: "Creative Voice File", 1Ah 14h - 15h Offset of the Data Block from the start of .VOC file. This word points to the Data Block. It helps the application programs to locate the Data Block in case the size of Header Block is changed. For this version, the value here is 1A Hex. 16h - 17h .VOC file format version number. This version number allows your program to identify different organization formats of .VOC file in case of future enhancement. The low and high byte are the minor and major version number respectively. Current version is 1.20 (0114h). 18h - 19h .VOC file identification code. This code allows your program to check that this file is a .VOC file. Its content is the complement of the file format version number, plus 1234 hex. For version of 1.20, it is complement(0114h) + 1234h = 111Fh. Data Block The Data Block is sub-divided into multiple sub-blocks of data. The first byte of each sub-block is called the Block Type. It indicates the type of data contained in the sub-block. The next three bytes is the 24-bit (3-byte) Block Length. It is the number of bytes in the sub-block excluding the Block Type and Block Length fields. The first byte is a lowest byte and the third byte is the highest byte of the length field respectively. All sub-blocks have the Block Type field followed immediately by the block length field except the Terminator sub-block. Your program need not interpret all the Block Types. If unknown Block Type is encountered, it should be ignored and advance to the next sub-block by using the Block Length. The high-level digitized sound drivers handle these data blocks automatically for you. Therefore, you should use these drivers to perform digitized sound I/O operations. Block Type 0 This is a 1-byte sub-block which terminates the entire Data Block. The Block Type identifier is 0. It indicates that there are no other sub-blocks after it. The high-level digitized sound drivers terminate digitized sound output when this Block Type is encountered. This Block Type should be the last block of the .VOC file. Block Type 1 This is a digitized sound data block. The Block Header is organized as follow: BYTE bBlockID; // == 1 BYTE nBlockLen[3]; // 3-byte block length BYTE bTimeConstant; BYTE bPackMethod; // Packing Method The header is followed immediately by the digitized sound data. Here is a discussion of various fields: bBlockID The Block Type identifier is 1. nBlockLen Length of the block (in bytes), excluding the bBlockID and nBlockLen fields. The value here will be the digitized sound data length plus 2. bTimeConstant This is a 1-byte field which indicates the Time Constant of the digitized sound data of this block. The Time Constant is defined as follows: Time Constant = 65536 - (256 000 000 / (channels * sampling rate)) The channels parameter is 1 for mono and 2 for stereo. Only the high byte of the result is stored here. For instance, for a 10000Hz mono digitized sound, the Time Constant is set to 9C hex using the following calculation: Time constant = 65536 - (256 000 000 / 10 000) = 39936 (09C00h) bPackMethod This is an 1 byte field which indicates the packing method used by the digitized sound data of this block. It is defined as: Value Meaning 0 8-bit PCM 1 Creative 8-bit to 4-bit ADPCM 2 Creative 8-bit to 3-bit ADPCM 3 Creative 8-bit to 2-bit ADPCM Some points to note for Block Type 1: 1. If this block is preceded by Block Type 8 (discussed later), the digitized sound attributes on Block Type 8 should be used. The digitized sound attributes in this block should be ignored. 2. If this block is alone, the digitized sound channels should be defaulted to mono. Block Type 2 This is digitized sound continuation block. The Block Header is organized as follows: BYTE bBlockID; // == 2 BYTE nBlockLen[3]; // 3-byte block length The header is followed immediately by the digitized sound data. Here is a discussion of various fields: bBlockID The Block Type identifier is 2. nBlockLen Length of the block (in bytes), excluding the bBlockID and nBlockLen fields. This block type will only be used when the digitized sound data exceeds the 3-byte block length (16 megabytes). Block Type 3 This block specifies the pause period for the digitized sound before next block of digitized sound data is transferred. The Block Header is organized as follows: BYTE bBlockID; // == 3 BYTE nBlockLen[3]; // 3-byte block length WORD wPausePeriod; BYTE bTimeConstant; Here is a discussion of various fields: bBlockID The Block Type identifier is 3. nBlockLen Length of the block (in bytes), excluding the bBlockID and nBlockLen fields. The value is 3. wPausePeriod This is a 2-byte field which specifies the pause period in units of sampling cycles. Total pause cycle is wPausePeriod plus 1. bTimeConstant This is a 1-byte field which indicates the Time Constant of the pause period. The Time Constant calculation is the same as described in Block Type 1. Block Type 4 This is a special block that specifies a Marker in the digitized sound data. The Block Header is organized as follows: BYTE bBlockID; // == 4 BYTE nBlockLen[3]; // 3-byte block length WORD wMarker; // Marker value Here is a discussion of various fields: bBlockID The Block Type identifier is 4. nBlockLen Length of the block (in bytes), excluding the bBlockID and nBlockLen fields. The value is 2. wMarker This is a 2-byte field which specifies the marker value. The marker value can be any value between 1 to 0FFFE hex inclusive. The 0 and 0FFFF hex values are reserved by the digitized sound drivers. During digitized sound output, the CT-VOICE and CTVDSK drivers update the digitized sound status word with this value when the marker is encountered. your program can check for the desired marker value to perform synchronization with the digitized sound output process. Block Type 5 This block enables you to embed a null-terminated ASCII string in the .VOC file. The Block Header is organized as follows: BYTE bBlockID; // == 5 BYTE nBlockLen[3]; // 3-byte block length BYTE szString[]; // Null-terminated string Here is a discussion of various fields: bBlockID The Block Type identifier is 5. nBlockLen Length of the block (in bytes), excluding the bBlockID and nBlockLen fields. The value is the length of the null-terminated ASCII string (null inclusive). szString This is variable length field which specifies a null-terminated ASCII string. The length of this field is the string length (null inclusive). This field is for a program that requires ASCII information on the .VOC file such as name, type of remarks. You may choose to ignore this Block Type during the digitized sound block manipulation. Block Type 6 This block indicates the beginning of a repeat loop. The data block between this block and the next End Repeat Block (Block Type 7) will be repeated. The Block Header is organized as follows: BYTE bBlockID; // == 6 BYTE nBlockLen[3]; // 3-byte block length WORD wRepeatTimes; Here is a discussion of various fields: bBlockID The Block Type identifier is 6. nBlockLen Length of the block (in bytes), excluding the bBlockID and nBlockLen fields. The value is 2. wRepeatTimes This is a 2-byte field which specifies the number of times to repeat. It can be any value between 1 to 0FFFE hex inclusive. If the value is set to 0FFFF hex, an endless loop occurs. Block Type 7 This block indicates the end of a repeat loop. It works in conjunction with Block Type 6. The Block Header is organized as follows: BYTE bBlockID; // == 7 BYTE nBlockLen[3]; // 3-byte block length Here is a discussion of various fields: bBlockID The Block Type identifier is 7. nBlockLen Length of the block (in bytes), excluding the bBlockID and nBlockLen fields. The value is 0. Block Type 8 This is a special block that carries only the digitized sound attributes. It MUST precede Block Type 1. Usually, this block precedes the stereo or high speed digitized sound data. The Block Header is organized as follows: BYTE bBlockID; // == 8 BYTE nBlockLen[3]; // 3-byte block length WORD wTimeConstant; // 2-byte Time Constant BYTE bPackMethod; // Packing Method BYTE bVoiceMode; // Mono or stereo The header is followed immediately by Block Type 1. Here is a discussion of various fields: bBlockID The Block Type identifier is 8. nBlockLen Length of the block (in bytes), excluding the bBlockID and nBlockLen fields. This value is 4. wTimeConstant This is a 2-byte field which indicates the Time Constant of the digitized sound data in the Block Type 1. The calculation of the Time Constant is the same as described on Block Type 1, but the whole word of the result is stored here. For a 44 100Hz sampling rate mono digitized sound, the Time Constant is calculated as follows: Time constant = 65536 - (256 000 000 / 44 100) = 59732 (0E95h) For a 22 050Hz sampling rate stereo digitized sound, the Time Constant is calculated as follows: Time constant = 65536 - (256 000 000 / (2 * 22 050)) = 59732 (0E95h) bPackMethod This is an 1 byte field which indicates the packing method used by the digitized sound data of this block. The meaning of the field is the same as the bPackMethod field in Block Type 1. bVoiceMode This is a 1-byte field which indicates mono or stereo digitized sound (0 for mono and 1 for stereo). After this block, the digitized sound attributes carried by the following Block Type 1 is ignored. Block Type 9 This is a digitized sound data block that supersedes Block Types 1 and 8. The Block Header is organized as follows: BYTE bBlockID; // == 9 BYTE nBlockLen[3]; // 3-byte block length DWORD dwSamplesPerSec; BYTE bBitsPerSample; BYTE bChannels; WORD wFormat; BYTE reserved[4]; // pad with zero The header is followed immediately by the digitized sound data. The four reserved bytes at the end are there for two reasons: 1. Pad the header up to a length of 16 bytes (a convenient size for manipulation). 2. Provide for future expansion. Here is a brief discussion of the various fields: bBlockID The Block Type identifier is 9. nBlockLen Length of the block (in bytes), excluding the bBlockID and nBlockLen fields. The value will be the digitized sound data length plus 12. dwSamplesPerSec This is the actual sampling frequency, not a Time Constant. There is no need to double the value when dealing with stereo I/O (unlike in Block Type 8). bBitsPerSample Actual number of bits per sample after compression (if any). bChannels This is 1 for mono or 2 for stereo. wFormat The currently supported formats are: Value Meaning 0x0000 8-bit unsigned PCM 0x0001 Creative 8-bit to 4-bit ADPCM 0x0002 Creative 8-bit to 3-bit ADPCM 0x0003 Creative 8-bit to 2-bit ADPCM 0x0004 16-bit signed PCM 0x0006 CCITT a-Law 0x0007 CCITT ยต-Law 0x0200 Creative 16-bit to 4-bit ADPCM Some other points to note: 1. This is a new Block Type introduced on .VOC file with version number 1.20 and above. 2. It is intended that this Block Type supersedes Block Types 1 and 8. That is, the new drivers will produce Block Type 9 blocks on recording.