|
Saettler's Ton-O-Info
|
|
of
New Multimedia Data Types and Data Techniques April 15, 1994 Revision: 3.0 Information in this document is subject to change without notice and does not represent a commitment on the part of Microsoft Corporation. The software described in this document is furnished under license agreement or nondisclosure agreement. The software may be used or copied only in the accordance with the terms of the agreement. It is against the law to copy the software on any medium except as specifically allowed in the license or nondisclosure agreement. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying and recording, for any purpose without the express written permission of Microsoft Corporation. This standards update is for informational purposes only. Microsoft makes no warranties, expressed or implied in this Standards Update. Microsoft, MS, MS-DOS, XENIX and the Microsoft logo are registered trademarks and Windows is a trademark of Microsoft Corporation. Other trade names mentioned herein are trademarks of their respective manufacturers. Copyright 1992, 1993, 1994 Microsoft Corporation. All Rights Reserved. OverviewThis standards update presents new and updated information for dealing with multimedia data under Microsoft Windows. This document is also available as part of the Multimedia Developer Registration Kit. The MDRK is used to register multimedia data and ids as well as new MCI command sets.. This document is the result of companies requesting and registering new data types. This document builds on the standard RIFF documentation that is contained in: 1. The Multimedia Development Kit (MDK) 1.0 Programmer's Reference 2. The Windows 3.1 Software Development Kit (SDK)'s Multimedia Programmer's Reference 3. The Multimedia Programmer's Reference book from Microsoft Press 4. Video for Windows 1.1 SDK Programmer's Guide The RIFF file format is a standard published as a joint design document by IBM and Microsoft. This standards document is Multimedia Programming Interface and Data Specifications 1.0 published in August 1991. The first draft of this document was issued in November, 1990. This IBM/Microsoft document is available from the sources listed below. This standards update assumes that the reader has read the concepts defined in these documents. New RIFF file forms and chunks are defined in this document. The new RIFF forms and chunks defined here have been registered with Microsoft. If you want to register your own RIFF forms and chunks, fill out and return the Multimedia Developer Registration Kit included in this kit. In addition, techniques for dealing with multimedia data in the system, such as clipboard data, are defined in this document. Where to Look for InformationAll constants and structures defined in this document are contained in MMREG.H, which is included in this kit. Current versions of this document as well as other technical update and technical notes and sample code are available from the sources listed in the Multimedia Document Overview, included in this kit. Versions of this DocumentThis document is continually being updated and expanded. Eventually the information presented in this document will be placed in the standard reference for the multimedia IDs standards from Microsoft, such as the Multimedia Programmer's Reference from MS-Press. When refering to standards defined in this document, please refer to the data and version number printed on the cover page. Please refer to the document , which is included in this kit, for lists of other documents and sample code.
New RIFF ChunksThese new chunks have been defined for use in any RIFF form. Display ChunkAdded: 05/01/92 Author: Microsoft A DISP chunk contains easily rendered and displayable objects associated with an instance of a more complex object in a RIFF form (e.g. sound file, AVI movie). A DISP chunk is defined as follows: <DISP_ck> DISP( <type> <data> ) <type> is a DWORD (32 bit unsigned quantity in Intel format) that identifies <data> as one of the standard Windows clipboard formats (CF_METAFILE, CF_DIB, CF_TEXT, etc.) as defined in windows.h. The DISP chunk should be used as a direct child of the RIFF chunk so that any RIFF aware application can find it. There can be multiple DISP chunks with each containing different types of displayable data, but all representative of the same object. The DISP chunks should be stored in the file in order of preference (just as in the clipboard). The DISP chunk is especially beneficial when representing OLE data within an application. For example, when pasting a wave file into Excel, the creating application can use the DISP chunk to associate an icon and a text description to represent the embedded wave file. This text should be short so that it can be easily displayed in menu bars and under icons. Note: do not use a CF_TEXT for a description of the data. Bibliographic data chunks will be added to support the standard MARC (Machine Readable Cataloging) data. JUNK (Filler) ChunkAdded: 05/01/92 Author: IBM, Microsoft A JUNK chunk represents , filler or outdated information. It contains no relevant data; it is a space filler of arbitrary size. The JUNK chunk is defined as follows: <JUNK chunk> JUNK( <filler> ) where <filler> contains random data. PAD (Filler) ChunkAdded: 07/15/92 Author: Microsoft A PAD chunk represents padding. It contains no relevant data; it is a space filler of arbitrary size. When duplicating the file, the copier should maintain the padding of the PAD chunk. Specifically, if the PAD chunk makes the next chunk align on a 2K boundary in the physical file, then this alignment should be preserved even if the size of the PAD chunk must change. The PAD chunk is defined as follows: <PAD chunk> PAD( <filler> ) where <filler> contains random data. New NFO list ChunksFor complete AVI file documentation, see the Multimedia Developer Reference, part of the Microsoft Windows SDK. These chunks were added for Video for Windows 1.1, mid 1993: ISMP SMPTE time code of digitization start point expressed as a NULL terminated text string "HH:MM:SS.FF". If performing MCI capture in AVICAP, this chunk will be automatically set based on the MCI start time. IDIT "Digitization Time" Specifies the time and date that digitization commenced. The digitization time is contained in an ASCII string which contains exactly 26 characters and is in the format "Wed Jan 02 02:03:55 1990\n\0". The ctime(), asctime(), functions can be used to create strings in this format. This chunk is automatically added to the capture file based on the current system time at the moment capture is initiated. New FormsAVIThe RIFF AVI file format is defined in the Video for Windows SDK. CPPOAdded: 12/16/92 Author: APPS Software International 4417 North Saddlebag Trail Scottsdale, AZ 85251 DefinitionCPPO RIFF Form Definition (C) Copyright APPS Software International 1992 Revision 1.0 This document provides a new RIFF specification used to provide an object persistance/archival feature for Windows applications doped with C++. This RIFF form preserves not only the content of objects but also all the linkages between objects, providing a mechanism for loading and unloading an entire memory image. <CPPO-form> --> RIFF ( 'CPPO' // RIFF form header <object-list> ) // object list <object-list> --> LIST ( 'obj' <object-ck> ... ) An <object-ck> can be one of the following: 1. an object referent (sub-chunk type 'objr'). 2. an object instance (sub-chunk type 'obji'). 'objr' chunks do not create a new instance of an object, but instead create a reference/pointer to the original instance of the specified object. Each object is numbered in the order that it appears in the file. The special object number zero represents a NULL pointer, thus the first object in the file is given the number 1. <object-ck> --> objr ( <object-number:WORD> ) | // object reference obji ( <object-instance> ) // new object instance <object-instance> --> <class-descr> <member-list> The <class-descr> reduces file size by specifying the class name only once. The first 'clsi' in the file is given the number 1. <class-descr> --> clsr ( <class-number:WORD> ) | // previously defined class clsi ( <class-name:ZSTR> ) // new class definition The remainder of the <object-instance> definition is its member list. A member list is a sequence of primitive data elements and/or object instances/references. <member-list> --> LIST ( 'mbr' <member-ck> ... ) Each class is responsible for parsing its members from the RIFF file. It may choose to specify primitive data as a single 'byte' sub-chunk, or as a sequence of more specific chunks. Each non-primitive member must, however, be in the <object-ck> format. <member-ck> --> <primitive-ck> | // primitive data type <object-ck> // object definition <primitive-ck> --> char ( <CHAR> ... ) | byte ( <BYTE> ... ) | int ( <INT> ... ) | word ( <WORD> ... ) | long ( <LONG> ... ) | dwrd ( <DWORD> ... ) | flt ( <FLOAT> ... ) | dbl ( <DOUBLE> ... ) | str ( <ZSTR> ... ) ExampleCPPO RIFF Form Example (C) Copyright APPS Software International 1992 Revision 1.0 This example stores an 'OrdCollect' object containing two 'String' objects and a NULL pointer. RIFF ( 'CPPO' LIST ( 'INFO' INAM ( "Generic C++ Image"Z ) ICOP ( "(C) Copyright APPS Software Int'l 1992"Z ) ICRD ( "1992-12-10"Z ) ) LIST ( 'obj' obji ( clsi ( "String"Z ) LIST ( 'mbr' str ( "This is the first"Z ) ) ) obji ( clsr ( 1 ) LIST ( 'mbr' str ( "This is the second"Z ) ) ) obji ( clsi ( "OrdCollect"Z ) LIST ( 'mbr' word ( 2 ) objr ( 1 ) objr ( 0 ) objr ( 2 ) ) ) ) ) ACONAdded: 4/13/93 Author: Microsoft Windows NT Animated Cursor RIFF FilesFor Windows NT, an animated cursor is stored in RIFF a file with a form type of 'ACON'. The subcunks of this form of RIFF file are the 'LIST', 'anih', 'rate', and 'seq ' chunks. There are two LIST chunks: the LIST chunk with type 'INFO' contains textual informative details about the animated cursor, the LIST chunk with a type of 'fram' contains 'icon' subchunks. The anih chunk describes the rest of the subchunks in the file. The 'rate' chunk tells how long each step of the animation is to be displayed on the screen. The 'seq ' chunk maps the animation steps into actual icon pictures stored in the .ani file. The 'icon' subchunks in the 'fram' LIST are the actual frames of the cursor animation. The following is a RIFF grammar (as defined in the Microsoft Windows Multimedia Programmer's Reference) that describes the Windows NT animated cursors: RIFF( 'ACON' [LIST( 'INFO' <info_data> )] [<DISP_ck>] anih( <ani_header> ) [rate( <rate_info> )] ['seq '( <sequence_info> )] LIST( 'fram' icon( <icon_file> ) ... ) )
Structure Definitions: typedef DWORD JIF; /* Number of jiffies that a frame typedef struct _ANIHEADER { /* anih */ DWORD cbSizeof; /* Num. bytes in aniheader (incl. cbSizeof) */ DWORD cFrames; /* Number of unique icons in the ani. cursor*/ DWORD cSteps; /* Number of blts before the animation cycles */ DWORD cx, cy; /* reserved, must be 0 */ DWORD cBitCount, cPlanes; /* reserved, must be 0 */ JIF jifRate; /* default rate if rate chunk not present */ DWORD fl; /* flags, see AF_* */ } ANIHEADER, *PANIHEADER; #define AF_ICON 0x0001L /* Windows format icon/cursor animation */ExampleThe following is a partial hex-dump of animated cursor file: banana.ani: 00000000 52 49 46 46 78 2e 00 00 41 43 4F 4E 4c 49 53 54 RIFFx...ACONLIST 00000010 4a 00 00 00 49 4e 46 4f 49 4e 41 4d 0f 00 00 00 J...INFOINAM.... 00000020 50 65 65 6c 69 6e 67 20 42 61 6e 61 6e 61 00 00 Peeling Banana.. 00000030 49 41 52 54 26 00 00 00 4d 69 63 72 6f 73 6f 66 IART&...Microsof 00000040 74 20 43 6f 72 70 6f 72 61 74 69 6f 6e 2c 20 43 t Corporation, C 00000050 6f 70 79 72 69 67 68 74 20 31 39 39 33 00 61 6e opyright 1993.an 00000060 69 68 24 00 00 00 24 00 00 00 0f 00 00 00 10 00 ih$...$......... 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000080 00 00 0f 00 00 00 03 00 00 00 72 61 74 65 40 00 ..........rate@. 00000090 00 00 0f 00 00 00 0f 00 00 00 0f 00 00 00 0f 00 ................ 000000a0 00 00 0f 00 00 00 0f 00 00 00 0f 00 00 00 0f 00 ................ 000000b0 00 00 0f 00 00 00 0f 00 00 00 0f 00 00 00 1e 00 ................ 000000c0 00 00 14 00 00 00 14 00 00 00 32 00 00 00 1e 00 ..........2..... 000000d0 00 00 73 65 71 20 40 00 00 00 00 00 00 00 01 00 ..seq @......... 000000e0 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 ................ 000000f0 00 00 06 00 00 00 07 00 00 00 08 00 00 00 09 00 ................ 00000100 00 00 0a 00 00 00 0b 00 00 00 0c 00 00 00 0d 00 ................ 00000110 00 00 0e 00 00 00 00 00 00 00 4c 49 53 54 5e 2d ..........LIST^- 00000120 00 00 66 72 61 6d 69 63 6f 6e fe 02 00 00 00 00 ..framicon...... 00000130 02 00 01 00 20 20 00 00 10 00 10 00 e8 02 00 00 .... .......... 00000140 16 00 00 00 28 00 00 00 20 00 00 00 40 00 00 00 ....(... ...@... 00000150 01 00 04 00 00 00 00 00 80 02 00 00 00 00 00 00 ................ 00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000170 00 00 80 00 00 80 00 00 00 80 80 00 80 00 00 00 ................ 00000180 80 00 80 00 80 80 00 00 80 80 80 00 c0 c0 c0 00 ................ 00000190 00 00 ff 00 00 ff 00 00 00 ff ff 00 ff 00 00 00 ................ 000001a0 ff 00 ff 00 ff ff 00 00 ff ff ff 00 00 00 00 00 ................ 000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000001e0 00 00 00 00 00 03 33 00 00 00 00 00 00 00 00 00 ......3......... 000001f0 00 00 00 00 03 3b ff 00 00 00 00 00 00 00 00 00 .....;.......... 00000200 00 00 00 00 3b bf fb 30 00 00 00 00 00 00 00 00 ....;..0........ 00000210 00 00 00 03 bb ff b3 00 00 00 00 00 00 00 00 00 ................ 00000220 00 00 00 3b bf fb 30 00 00 00 00 00 00 00 00 00 ...;..0......... 00000230 00 00 03 bb ff b8 00 00 00 00 00 00 00 00 00 00 ................ 00000240 00 00 03 bf fb 83 00 00 00 00 00 00 00 00 00 00 ................ 00000250 00 00 3b bf bb 80 00 00 00 00 00 00 00 00 00 00 ..;............. 00000260 00 00 3b ff b8 30 00 00 00 00 00 00 00 00 00 00 ..;..0.......... 00000270 00 03 bb fb b8 00 00 00 00 00 00 00 00 00 00 00 ................ 00000280 00 03 bf fb b3 00 00 00 00 00 00 00 00 00 00 00 ................ 00000290 00 03 bf bb 83 00 00 00 00 00 00 00 00 00 00 00 ................ 000002a0 00 03 bf bb 80 00 00 00 00 00 00 00 00 00 00 00 ................ 000002b0 00 03 bf bb 30 00 00 00 00 00 00 00 00 00 00 00 ....0........... 000002c0 00 03 bf bb 30 00 00 00 00 00 00 00 00 00 00 00 ....0........... 000002d0 00 03 bf bb 30 00 00 00 00 00 00 00 00 00 00 00 ....0........... 000002e0 00 03 bf bb 30 00 00 00 00 00 00 00 00 00 00 00 ....0........... 000002f0 00 03 bf bb 30 00 00 00 00 00 00 00 00 00 00 00 ....0........... 00000300 00 00 3f fb 30 00 00 00 00 00 00 00 00 00 00 00 ..?.0........... 00000310 00 00 3b fb 30 00 00 00 00 00 00 00 00 00 00 00 ..;.0........... 00000320 00 00 03 ff 30 00 00 00 00 00 00 00 00 00 00 00 ....0........... 00000330 00 00 03 bf 30 00 00 00 00 00 00 00 00 00 00 00 ....0........... 00000340 00 00 00 3f 80 00 00 00 00 00 00 00 00 00 00 00 ...?............ 00000350 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000360 00 00 00 00 33 00 00 00 00 00 00 00 00 00 00 00 ....3........... 00000370 00 00 00 00 03 30 00 00 00 00 00 00 00 00 00 00 .....0.......... 00000380 00 00 00 00 00 30 00 00 00 00 00 00 00 00 00 00 .....0.......... 00000390 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000003a0 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff ................ 000003b0 ff ff ff ff ff ff ff ff ff ff e0 ff ff ff 80 ff ................ 000003c0 ff ff 00 ff ff fe 01 ff ff fc 03 ff ff f8 07 ff ................ 000003d0 ff f8 07 ff ff f0 0f ff ff f0 0f ff ff e0 1f ff ................ 000003e0 ff e0 1f ff ff e0 1f ff ff e0 3f ff ff e0 3f ff ..........?...?. 000003f0 ff e0 3f ff ff e0 3f ff ff e0 3f ff ff e0 3f ff ..?...?...?...?. 00000400 ff f0 3f ff ff f0 3f ff ff f8 3f ff ff f8 3f ff ..?...?...?...?. 00000410 ff fc 3f ff ff fe 3f ff ff ff 1f ff ff ff 8f ff ..?...?......... 00000420 ff ff cf ff ff ff ff ff ff ff ff ff 69 63 6f 6e ............icon 00000430 fe 02 00 00 00 00 02 00 01 00 20 20 00 00 10 00 .......... .... 00000440 10 00 e8 02 00 00 16 00 00 00 28 00 00 00 20 00 ..........(... . 00000450 00 00 40 00 00 00 01 00 04 00 00 00 00 00 80 02 ..@............. 00000460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000470 00 00 00 00 00 00 00 00 80 00 00 80 00 00 00 80 ................ 00000480 80 00 80 00 00 00 80 00 80 00 80 80 00 00 80 80 ................ 00000490 80 00 c0 c0 c0 00 00 00 ff 00 00 ff 00 00 00 ff ................ 000004a0 ff 00 ff 00 00 00 ff 00 ff 00 ff ff 00 00 ff ff ................ 000004b0 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000004d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000004e0 00 00 00 00 00 00 00 00 00 00 00 03 33 00 00 00 ............3... 000004f0 00 00 00 00 00 00 00 00 00 00 03 3b ff 00 00 00 ...........;.... 00000500 00 00 00 00 00 00 00 00 00 00 3b bf fb 30 00 00 ..........;..0.. 00000510 00 00 00 00 00 00 00 00 00 03 bb ff b3 00 00 00 ................ 00000520 00 00 00 00 00 00 00 00 00 3b bf fb 30 00 00 00 .........;..0... 00000530 00 00 00 00 00 00 00 00 03 bb ff b8 00 00 00 00 ................ 00000540 00 00 00 00 00 00 00 00 03 bf fb 83 00 00 00 00 ................ ... (more embedded icon files) ... 00002e40 f8 00 00 7f fc 00 00 ff fe 00 21 ff ff e0 7f ff ..........!..... 00002e50 ff e1 ff ff ff f3 ff ff ff ff ff ff ff ff ff ff ................ 00002e60 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00002e70 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ New WAVE RIFF ChunksAdded: 05/01/92 Author: Microsoft, IBM Most of the information in this section comes directly from the IBM/Microsoft RIFF standard document. The WAVE form is defined as follows. Programs must expect (and ignore) any unknown chunks encountered, as with all RIFF forms. However, <'fmt'ck> must always occur before <wavedata>, and both of these chunks are mandatory in a WAVE file. <WAVE-form> The WAVE chunks are described in the following sections. Fact ChunkThe <fact-ck> stores file dependent information about the contents of the WAVE file. This chunk is defined as follows: <fact-ck> fact( <dwSampleLength:DWORD> ) <dwSampleLength> represents the length of the data in samples. The <nSamplesPerSec> field from the wave format header is used in conjunction with the <dwSampleLength> field to determine the length of the data in seconds. The fact chunk is required for all new WAVE formats. The chunk is not required for the standard WAVE_FORMAT_PCM files. The fact chunk will be expanded to include any other information required by future WAVE formats. Added fields will appear following the <dwSampleLength> field. Applications can use the chunk size field to determine which fields are present. Cue Points ChunkThe <cue-ck> cue-points chunk identifies a series of positions in the waveform data stream. The <cue-ck> is defined as follows: <cue-ck> cue( <dwCuePoints:DWORD> // Count of cue points The <cue-point> fields are as follows:
Examples of File Position ValuesThe following table describes the <cue-point> field values for a WAVE file containing a single 'data' chunk:
Playlist ChunkThe <playlist-ck> playlist chunk specifies a play order for a series of cue points. The <playlist-ck> is defined as follows: <playlist-ck> plst( The <play-segment> fields are as follows:
Associated Data ChunkThe <assoc-data-list> associated data list provides the ability to attach information like labels to sections of the waveform data stream. The <assoc-data-list> is defined as follows: <assoc-data-list> LIST( 'adtl' <labl-ck> // Label <note-ck> // Note <ltxt-ck> } // Text with data length <labl-ck> labl( <dwName:DWORD> <data:ZSTR> ) <note-ck> note( <dwName:DWORD> <data:ZSTR> ) <ltxt-ck> ltxt( <dwName:DWORD> <dwSampleLength:DWORD> <dwPurpose:DWORD> <wCountry:WORD> <wLanguage:WORD> <wDialect:WORD> <wCodePage:WORD> <data:BYTE>... ) Label and Note InformationThe 'labl' and 'note' chunks have similar fields. The 'labl' chunk contains a label, or title, to associate with a cue point. The 'note' chunk contains comment text for a cue point. The fields are as follows:
Text with Data Length InformationThe "ltxt" chunk contains text that is associated with a data segment of
specific length. The chunk fields are as follows:
inst (Instrument) ChunkAdded: 12/29/92 Author: IBM Defined for: WAVE form The WAVE form is NEARLY the perfect file format for storing a sampled sound synthesizer's samples. Bits per sample, sample rate, number of channels, and complex looping can be specified with current WAVE subchunks, but a sample's pitch and its desired volume relative to other samples cannot. The optional instrument subchunk defined below fills in these needed parameters: |<instrument-ck>| inst( <bUnshiftedNote:BYTE> <chFineTune:CHAR> <chGain:CHAR> <bLowNote:BYTE> <bHighNote:BYTE> <bLowVelocity:BYTE> <bHighVelocity:BYTE> )
smpl (Sample) ChunkAdded: 11/09/93 Author: Digidesign, Sonic Foundary, Turtle Beach Defined for: WAVE form The <sample-ck> sampled instrument chunk describes the minimum necessary information needed to allow a sampling keyboard to use a WAVE file as an instrument. Samplers which require more information can save their extended information in the sampler specific data section. The <sample-ck> is defined as follows: |<sample-ck>| smpl( <dwManufacturer:DWORD> <dwProduct:DWORD> <dwSamplePeriod:DWORD> <dwMIDIUnityNote:DWORD> <dwMIDIPitchFraction:DWORD> <dwSMPTEFormat:DWORD> <dwSMPTEOffset:DWORD> <cSampleLoops:DWORD> <cbSamplerData:DWORD> <sample-loop(s)> <sampler-specific-data> ) <sample-loop> struct { DWORD dwIdentifier; DWORD dwType; DWORD dwStart; DWORD dwEnd; DWORD dwFraction; DWORD dwPlayCount; } The <sample-ck> chunk:
The <sample-loop> structure:
New WAVE Types The necessary type, structure and constant defintions are in mmreg.h. All newly defined WAVE types must contain both a fact chunk and an extended wave format description within the 'fmt' chunk. RIFF WAVE files of type WAVE_FORMAT_PCM need not have the extra chunk nor the extended wave format description. Fact ChunkThis chunk stores file dependent information about the contents of the WAVE file. It currently specifies the length of the file in samples. WAVEFORMATEXThe extended wave format structure is used to defined all non-PCM format wave data, and is described as follows in the include file mmreg.h: /* general extended waveform format structure */ /* Use this for all NON PCM formats */ /* (information common to all formats) */ typedef struct waveformat_extended_tag { WORD wFormatTag; /* format type */ WORD nChannels; /* number of channels (i.e. mono, stereo...) */ DWORD nSamplesPerSec; /* sample rate */ DWORD nAvgBytesPerSec; /* for buffer estimation */ WORD nBlockAlign; /* block size of data */ WORD wBitsPerSample; /* Number of bits per sample of mono data */ WORD cbSize; /* The count in bytes of the extra size */} WAVEFORMATEX;
Defined wFormatTags
Unknown Wave TypeAdded: 05/01/92 Author: Microsoft Fact ChunkThis chunk is required for all WAVE formats other than WAVE_FORMAT_PCM. It stores file dependent information about the contents of the WAVE data. It currently specifies the time length of the data in samples. WAVE Format HeaderChanged as of September 5, 1993: This wave format will not be defined. For development purposes, DO NOT USE 0x0000. Instead, USE 0xffff until an ID has been obtained. #define WAVE_FORMAT_UNKNOWN (0x0000)
Microsoft ADPCMAdded 05/01/92 Author: Microsoft Fact ChunkThis chunk is required for all WAVE formats other than WAVE_FORMAT_PCM. It stores file dependent information about the contents of the WAVE data. It currently specifies the time length of the data in samples. WAVE Format Header#define WAVE_FORMAT_ADPCM (0x0002)typedef struct adpcmcoef_tag { int iCoef1; int iCoef2; } ADPCMCOEFSET; typedef struct adpcmwaveformat_tag { WAVEFORMATEX wfxx; WORD wSamplesPerBlock; WORD wNumCoef; ADPCMCOEFSET aCoeff[wNumCoef]; } ADPCMWAVEFORMAT;
Note: 8.8 signed values can be divided by 256 to obtain the integer portion of the value. BlockThe block has three parts, the header, data, and padding. The three together are <nBlockAlign> bytes. typedef struct adpcmblockheader_tag { BYTE bPredictor[nChannels]; int iDelta[nChannels]; int iSamp1[nChannels]; int iSamp2[nChannels]; } ADPCMBLOCKHEADER;
DataThe data is a bit string parsed in groups of (wBitsPerSample * nChannels). For the case of Mono Voice ADPCM (wBitsPerSample = 4, nChannels = 1) we have: <Byte1> <Byte2>...<ByteN> ...<Byte((nSamplesPerBlock-2)/2)> where <ByteN> has <High Order Bit ... Low OrderBit> or < (Sample 2N + 2) (Sample 2N + 3)> <ByteN> = ((4 bit error delta for sample (2 * N) + 2) << 4) | (4 bit error delta for sample (2 * N) + 3) For the case of Stereo Voice ADPCM (wBitsPerSample = 4, nChannels = 2) we have: <Byte1> <Byte2>...<ByteN> ...<Byte(nSamplesPerBlock-2)> where <ByteN> has <High Order Bit ... Low OrderBit> or < (Left Channel of Sample N + 2) (Right Channel of Sample N + 2)> <ByteN> = ((4 bit error delta for left channel of sample N + 2) << 4) | (4 bit error delta for right channel of sample N + 2) PaddingBit Padding is used to round off the block to an exact byte length. The size of the padding (in bits): ((nBlockAlign - (7 * nChannels)) * 8) - (((nSamplesPerBlock - 2) * nChannels) * wBitsPerSample) The padding does not store any data and should be made zero. ADPCM AlgorithmEach channel of the ADPCM file can be encoded/decoded independently. However this should not destroy phase and amplitude information since each channel will track the original. Since the channels are encoded/decoded independently, this document is written as if only one channel is being decoded. Since the channels are interleaved, multiple channels may be encoded/decoded in parallel using independent local storage and temporaries. Note that the process for encoding/decoding one block is independent from the process for the next block. Therefore the process is described for one block only, and may be repeated for other blocks. While some optimizations may relate the process for one block to another, in theory they are still independent. Note that in the description below the number designation appended to iSamp (i.e. iSamp1 and iSamp2) refers to the placement of the sample in relation to the current one being decoded. Thus when you are decoding sample N, iSamp1 would be sample N - 1 and iSamp2 would be sample N - 2. Coef1 is the coefficient for iSamp1 and Coef2 is the coefficient for iSamp2. This numbering is identical to that used in the block and format descriptions above. A sample application will be provided to convert a RIFF waveform file to and from ADPCM and PCM formats. DecodingFirst the predictor coefficients are determined by using the bPredictor field of block header. This value is an index into the aCoef array in the file header. bPredictor = GETBYTE The initial iDelta is also taken from the block header. iDelta = GETWORD Then the first two samples are taken from block header. (They are stored as 16 bit PCM data as iSamp1 and iSamp2. iSamp2 is the first sample of the block, iSamp1 is the second sample.) iSamp1= GETINT iSamp2 = GETINT After taking this initial data from the block header, the process of decoding the rest of the block may begin. It can be done in the following manner: While there are more samples in the block to decode: Predict the next sample from the previous two samples. lPredSamp = ((iSamp1 * iCoef1) + (iSamp2 *iCoef2)) / FIXED_POINT_COEF_BASE Get the 4 bit signed error delta. (iErrorDelta = GETNIBBLE) Add the 'error in prediction' to the predicted next sample and prevent over/underflow errors. (lNewSamp = lPredSample + (iDelta * iErrorDelta) if lNewSample too large, make it the maximum allowable size. if lNewSample too small, make it the minimum allowable size. Output the new sample. OUTPUT( lNewSamp ) Adjust the quantization step size used to calculate the 'error in prediction'. iDelta = iDelta * AdaptionTable[ iErrorDelta] / FIXED_POINT_ADAPTION_BASE if iDelta too small, make it the minimum allowable size. Update the record of previous samples. iSamp2 = iSamp1; iSamp1 = lNewSample. EncodingFor each block, the encoding process can be done through the following steps. (for each channel) Determine the predictor to use for the block. Determine the initial iDelta for the block. Write out the block header. Encode and write out the data. The predictor to use for each block can be determined in many ways. 1. A static predictor for all files. 2. The block can be encoded with each possible predictor. Then the predictor that gave the least error can be chosen. The least error can be determined from: 1. Sum of squares of differences. (from compressed/decompressed to original data) 2. The least average absolute difference. 3. The least average iDelta 3. The predictor that has the smallest initial iDelta can be chosen. (This is an approximation of method 2.3) 4. Statistics from either the previous or current block. (e.g. a linear combination of the first 5 samples of a block that corresponds to the average predicted error.) The starting iDelta for each block can also be determined in a couple of ways. 1. One way is to always start off with the same initial iDelta. 2. Another way is to use the iDelta from the end of the previous block. (Note that for the first block an initial value must then be chosen.) 3. The initial iDelta may also be determined from the first few samples of the block. (iDelta generally fluctuates around the value that makes the absolute value of the encoded output about half maximum absolute value of the encoded output. (for 4 bit error deltas the maximum absolute value is 8. This means the initial iDelta should be set so that the first output is around 4.) 4. Finally the initial iDelta for this block may be determined from the last few samples of the last block. (Note that for the first block an initial value must then be chosen.) Note that different choices for predictor and initial iDelta will result in different audio quality. Once the predictor and starting quantization values are chosen, the block header may be written out. First the choice of predictor is written out. (For each channel.) Then the initial iDelta (quantization scale) is written out. (For each channel.) Then the 16 bit PCM value of the second sample is written out. (iSamp1) (For each channel.) Finally the 16 bit PCM value of the first sample is written out. (iSamp2) (For each channel.) Then the rest of the block may be encoded. (Note that the first encoded value will be for the 3rd sample in the block since the first two are contained in the header.) While there are more samples in the block to decode: Predict the next sample from the previous two samples. lPredSamp = ((iSamp1 * iCoef1) + (iSamp2 *iCoef2)) / FIXED_POINT_COEF_BASE The 4 bit signed error delta is produced and overflow/underflow is prevented.. iErrorDelta = (Sample(n) - lPredSamp) / iDelta if iErrorDelta is too large, make it the maximum allowable size. if iErrorDelta is too small, make it the minimum allowable size. Then the nibble iErrorDelta is written out. PutNIBBLE( iErrorDelta ) Add the 'error in prediction' to the predicted next sample and prevent over/underflow errors. (lNewSamp = lPredSample + (iDelta * iErrorDelta) if lNewSample too large, make it the maximum allowable size. if lNewSample too small, make it the minimum allowable size. Adjust the quantization step size used to calculate the 'error in prediction'. iDelta = iDelta * AdaptionTable[ iErrorDelta] / FIXED_POINT_ADAPTION_BASE if iDelta too small, make it the minimum allowable size. Update the record of previous samples. iSamp2 = iSamp1; iSamp1 = lNewSample. Sample C CodeSample C Code is contained in the file msadpcm.c, which is available with this document in electronic form and separately. See the Overview section for how to obtain this sample code. CVSD Wave TypeAdded 07/21/92 Author: DSP Solutions, formerly Digispeech Fact ChunkThis chunk is required for all WAVE formats other than WAVE_FORMAT_PCM. It stores file dependent information about the contents of the WAVE data. It currently specifies the time length of the data in samples. WAVE Format Header#define WAVE_FORMAT_IBM_CVSD (0x0005)
The Digispeech CVSD compression format is compatible with the IBM PS/2 Speech Adapter, which uses a Motorola MC3418 for CVSD modulation. The Motorola chip uses only one algorithm which can work at variable sampling clock rates. The CVSD algorithm compresses each input audio sample to 1 bit. An acceptable quality of sound is achieved using high sampling rates. The Digispeech DS201 adapter supports six CVSD sampling frequencies, which are being used by most software using the IBM PS/2 Speech Adapter:
The CVSD format is a compression scheme which has been used by IBM and is supported by the IBM PS/2 Speech Adapter card. Digispeech also has a card that uses this compression scheme. It is not Digispeech's policy to disclose any of these algorithms to any third party vendor. CCITT Standard Companded Wave TypesAdded: 05/22/92 Author: Microsoft, DSP Solutions formerly Digispeech, Vocaltec, Artisoft Fact ChunkThis chunk is required for all WAVE formats other than WAVE_FORMAT_PCM. It stores file dependent information about the contents of the WAVE data. It currently specifies the time length of the data in samples. WAVE Format Header#define WAVE_FORMAT_ALAW (0x0006) #define WAVE_FORMAT_MULAW (0x0007)
See the CCITT G.711 specification for details of the data format. This is a CCITT (International Telegraph and Telephone Consultative Committee) specification. Their address is: Palais des Nations CH-1211 Geneva 10, Switzerland Phone: 22 7305111 OKI ADPCM Wave TypesAdded: 05/22/92 Author: DigiSpeech, Vocaltec, Wang Fact ChunkThis chunk is required for all WAVE formats other than WAVE_FORMAT_PCM. It stores file dependent information about the contents of the WAVE data. It currently specifies the time length of the data in samples. WAVE Format Header#define WAVE_FORMAT_OKI_ADPCM (0x0010)typedef struct oki_adpcmwaveformat_tag {
This format is created and read by the OKI APDCM chip set. This chip set is used by a number of card manufacturers. IMA ADPCM Wave TypeThe IMA ADPCM and the DVI ADPCM are identical. Please see the following section on the DVI ADPCM Wave Type for a full description. #define WAVE_FORMAT_IMA_ADPCM (0x0011)DVI ADPCM Wave TypeAdded: 12/16/92 Author: Intel Please note that DVI ADPCM Wave Type is Identical to IMA ADPCM Wave Type. Fact ChunkThis chunk is required for all WAVE formats other than WAVE_FORMAT_PCM. It stores file dependent information about the contents of the WAVE data. It currently specifies the time length of the data in samples. WAVE Format Header#define WAVE_FORMAT_DVI_ADPCM (0x0011)typedef struct dvi_adpcmwaveformat_tag { WORD wSamplesPerBlock;
BlockThe block is defined to be <nBlockAlign> bytes in length. For DVI ADPCM this must be a multiple of 4 bytes since all information in the block is divided on 32 bit word boundaries. The block has two parts, the header and the data. The two together are <nBlockAlign> bytes in length. The following diagram shows the Header and Data parts of one block. Where: M = <nChannels> HeaderThis is a C structure that defines the DVI ADPCM block header. typedef struct dvi_adpcmblockheader_tag { int iSamp0; BYTE bStepTableIndex; BYTE bReserved; } DVI_ADPCMBLOCKHEADER;
A block contains an array of <nChannels> header structures as defined above. This diagram gives a byte level description of the contents of each header word. DataThe data words are interpreted differently depending on the number of bits per sample selected. For 4 bit DVI ADPCM (where <wBitsPerSample> is equal to four) each data word contains eight sample codes as shown in the following diagram. Where: N = A data word for a given channel, in the range of 0 to <nBlockAlign> / ( 4 * <nChannels> ) - <nChannels> - 1 P = ( N * 8 ) + 1 Sample 0 is always included in the block header for the channel. Each Sample is 4 bits in length. Each block contains a total of <wSamplesPerBlock> samples for each channel. For 3 bit DVI ADPCM (where <wBitsPerSample> is equal to three) each data word contains 10.667 sample codes. It takes three words to hold an integral number of sample codes at 3 bits per code. So for 3 bit DVI ADPCM, the number of data words is required to be a multiple of three words (12 bytes). These three words contain 32 sample codes as shown in the following diagram. Where: M = One of the channels, in the range of 1 to <nChannels> N = The first data word in a group of three data words for channelM, in the range of 0 to <nBlockAlign> / ( 4 * <nChannels> ) - <nChannels> - 1 P = ( ( N / 3 ) * 32 ) + 1 Sample 0 is always included in the block header for the channel. Each Sample is 3 bits in length. Each block contains a total of <wSamplesPerBlock> samples for each channel. DVI ADPCM AlgorithmEach channel of the DVI ADPCM file can be encoded/decoded independently. Since the channels are encoded/decoded independently, this document is written as if only one channel is being decoded. Since the channels are interleaved, multiple channels may be encoded/decoded in parallel using independent local storage and temporaries. Note that the process for encoding/decoding one block is independent from the process for the next block. Therefore the process is described for one block only, and may be repeated for other blocks. The processes for encoding and decoding is discussed below. TablesThe DVI ADPCM algorithm relies on two tables to encode and decode audio samples. These are the step table and the index table. The contents of these tables are fixed for this algorithm. The 3 and 4 bit versions of the DVI ADPCM algorithm use the same step table, which is: const int StepTab[ 89 ] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 } But, the index table is different for the different bit rates. For the 4 bit DVI ADPCM the contents of index table is: const int IndexTab[ 16 ] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 }; For 3 bit DVI ADPCM the contents of the index table is: const int IndexTab[ 8 ] = { -1, -1, 1, 2, -1, -1, 1, 2 }; DecodingThis section describes the algorithm used for decoding the 4 bit DVI ADPCM. This procedure must be followed for each block for each channel. Get the first sample, Samp0, from the block header Set the initial step table index, Index, from the block header Output the first sample, Samp0 Set the previous Sample value: SampX-1 = Samp0 While there are still samples to decode Get the next sample code, SampX Code Calculate the new sample: Calculate the difference: Diff = 0 if ( SampX Code & 4 ) Diff = Diff + StepTab[ Index ] if ( SampX Code & 2 ) Diff = Diff + ( StepTab[ Index ] >> 1 ) if ( SampX Code & 1 ) Diff = Diff + ( StepTab[ Index ] >> 2 ) Diff = Diff + ( StepTab[ Index ] >> 3 ) Check the sign bit: if ( SampX Code & 8 ) Diff = -Diff SampX = SampX-1 + Diff Check for overflow and underflow errors: if SampX too large, make it the maximum allowable size (32767) if SampX too small, make it the minimum allowable size (-32768) Output the new sample, SampX Adjust the step table index: Index = Index + IndexTab[ SampX Code ] Check for step table index overflow and underflow: if Index too large, make it the maximum allowable size (88) if Index too small, make it the minimum allowable size (0) Save the previous Sample value: SampX-1 = SampX This section describes the algorithm used for decoding the 3 bit DVI ADPCM. This procedure must be followed for each block for each channel. Get the first sample, Samp0, from the block header Set the initial step table index, Index, from the block header Output the first sample, Samp0 Set the previous Sample value: SampX-1 = Samp0 While there are still samples to decode Get the next sample code, SampX Code Calculate the new sample: Calculate the difference: Diff = 0 if ( SampX Code & 2 ) Diff = Diff + StepTab[ Index ] if ( SampX Code & 1 ) Diff = Diff + ( StepTab[ Index ] >> 1 ) Diff = Diff + ( StepTab[ Index ] >> 2 ) Check the sign bit: if ( SampX Code & 4 ) Diff = -Diff SampX = SampX-1 + Diff Check for overflow and underflow errors: if SampX too large, make it the maximum allowable size (32767) if SampX too small, make it the minimum allowable size (-32768) Output the new sample, SampX Adjust the step table index: Index = Index + IndexTab[ SampX Code ] Check for step table index overflow and underflow: if Index too large, make it the maximum allowable size (88) if Index too small, make it the minimum allowable size (0) Save the previous Sample value: SampX-1 = SampX EncodingThis section describes the algorithm used for encoding the 4 bit DVI ADPCM. This procedure must be followed for each block for each channel. For the first block only, clear the initial step table index: Index = 0 Get the first sample, Samp0 Create the block header: Write the first sample, Samp0, to the header Write the initial step table index, Index, to the header Set the previously predicted sample value: PredSamp = Samp0 While there are still samples to encode, and we're not at the end of the block Get the next sample to encode, SampX Calculate the new sample code: Diff = SampX - PredSamp Set the sign bit: if ( Diff < 0 ) SampX Code = 8 Diff = -Diff else SampX Code = 0 Set the rest of the code: if ( Diff >= StepTab[ Index ] ) SampX Code = SampX Code | 4 Diff = Diff - StepTab[ Index ] if ( Diff >= ( StepTab[ Index ] >> 1 ) SampX Code = SampX Code | 2 Diff = Diff - ( StepTab[ Index ] >> 1 ) if ( Diff >= ( StepTab[ Index ] >> 2 ) SampX Code = SampX Code | 1 Save the sample code, SampX Code in the block Predict the current sample based on the sample code: Calculate the difference: Diff = 0 if ( SampX Code & 4 ) Diff = Diff + StepTab[ Index ] if ( SampX Code & 2 ) Diff = Diff + ( StepTab[ Index ] >> 1 ) if ( SampX Code & 1 ) Diff = Diff + ( StepTab[ Index ] >> 2 ) Diff = Diff + ( StepTab[ Index ] >> 3 ) Check the sign bit: if ( SampX Code & 8 ) Diff = -Diff SampX = SampX-1 + Diff Check for overflow and underflow errors: if PredSamp too large, make it the maximum allowable size (32767) if PredSamp too small, make it the minimum allowable size (-32768) Adjust the step table index: Index = Index + IndexTab[ SampX Code ] Check for step table index overflow and underflow: if Index too large, make it the maximum allowable size (88) if Index too small, make it the minimum allowable size (0) This section describes the algorithm used for encoding the 3 bit DVI ADPCM. This procedure must be followed for each block for each channel. For the first block only, clear the initial step table index: Index = 0 Get the first sample, Samp0 Create the block header: Write the first sample, Samp0, to the header Write the initial step table index, Index, to the header Set the previously predicted sample value: PredSamp = Samp0 While there are still samples to encode, and we're not at the end of the block Get the next sample to encode, SampX Calculate the new sample code: Diff = SampX - PredSamp Set the sign bit: if ( Diff < 0 ) SampX Code = 4 Diff = -Diff else SampX Code = 0 Set the rest of the code: if ( Diff >= StepTab[ Index ] ) SampX Code = SampX Code | 2 Diff = Diff - StepTab[ Index ] if ( Diff >= ( StepTab[ Index ] >> 1 ) SampX Code = SampX Code | 1 Save the sample code, SampX Code in the block Predict the current sample based on the sample code: Calculate the difference: Diff = 0 if ( SampX Code & 2 ) Diff = Diff + StepTab[ Index ] if ( SampX Code & 1 ) Diff = Diff + ( StepTab[ Index ] >> 1 ) Diff = Diff + ( StepTab[ Index ] >> 2 ) Check the sign bit: if ( SampX Code & 4 ) Diff = -Diff SampX = SampX-1 + Diff Check for overflow and underflow errors: if PredSamp too large, make it the maximum allowable size (32767) if PredSamp too small, make it the minimum allowable size (-32768) Adjust the step table index: Index = Index + IndexTab[ SampX Code ] Check for step table index overflow and underflow: if Index too large, make it the maximum allowable size (88) if Index too small, make it the minimum allowable size (0) DSP Solutions formerly Digispeech Wave TypesAdded: 05/22/92 Author: Digispeech Fact ChunkThis chunk is required for all WAVE formats other than WAVE_FORMAT_PCM. It stores file dependent information about the contents of the WAVE data. It currently specifies the time length of the data in samples. WAVE Format Header#define WAVE_FORMAT_DIGISTD (0x0015)
|
| wFormatTag | This must be set to either WAVE_FORMAT_DIGISTD or WAVE_FORMAT_DIGIFIX. |
| nChannels | Number of channels in the wave. (1 for mono) |
| nSamplesPerSec | Frequency the sample rate of the wave file. (8000). This value is also used by the fact chunk to determine the length in time units of the date. |
| nAvgBytesPerSec | Average data rate. (1100 for DIGISTD or 1625 for DigiFix) |
| Playback software can estimate the buffer size using the <nAvgBytesPerSec> value. | |
| nBlockAlign | Block Alignment of 2 for DIGISTD and 26 for DigiFix. |
| Playback software needs to process a multiple of <nBlockAlign> bytes of data at a time, so that the value of <nBlockAlign> can be used for buffer alignment. | |
| wBitsPerSample | This is the number of bits per sample of data. |
| cbSize | The size in bytes of the extra information in the extended WAVE 'fmt' header. This should be zero. |
The definition of the data contained in the Digistd and DigiFix formats are considered proprietary information of Digispeech. They can be contacted at:
DSP Solutions, Inc.
2464 Embarcadero Way
Palo Alto, CA 94303
The DIGISTD is a format used in a compression technique developed by Digispeech, Inc. DIGISTD format provides good speech quality with average rate of about 1100 bytes/second. The blocks (or buffers) in this format cannot be cyclically repeated.
The DigiFix is a format used in a compression technique developed by Digispeech, Inc. DigiFix format provides good speech quality (similar to DIGISTD) with average rate of exactly 1625 bytes/second. This format uses blocks of 26 bytes long.
Added 09/25/92
Author: Yamaha
This chunk is required for all WAVE formats other than WAVE_FORMAT_PCM. It stores file dependent information about the contents of the WAVE data. It currently specifies the time length of the data in samples.
| wFormatTag | This must be set to WAVE_FORMAT_YAMAHA_ADPCM. | |
| nChannels | Number of channels in the wave, 1 for mono, 2 for stereo. | |
| nSamplesPerSec | Frequency of the sample rate of the wave file. This should be 5125, 7350, 9600, 11025, 22050, or 44100 Hz. Other sample rates are not allowed. | |
| nAvgBytesPerSec | Average data rate.. | |
| Playback software can estimate the buffer size using the <nAvgBytesPerSec> value. | ||
| nBlockAlign | This is dependent upon the number of bits per sample. | |
| wBitsPerSample | nBlockAlign | |
| 4 | 1 | |
| 4 | 1 | |
| wBitsPerSample | This is the number of bits per sample of YADPCM. Currently only 4 bits per sample is defined. Other values are reserved. | |
| cbSize | The size in bytes of the extra information in the extended WAVE 'fmt' header. This should be zero. | |
This format is created and read by Yamaha chip included in the Gold Sound Standard (GSS) that is implemented in a number of manufacturers boards. The algorithm and conversion routines are published in the source code provided in YADPCM.C with this technote.
Added 10/21/92
Author: Sound Compression
Sound Compression has developed a new compression algorithm which, unlike ADPCM, is capable of lossless compression of digitized audio files to a degree far greater (50-60%) than that achievable with the other compressors, PKZIP and LHarc. "Lossy" compression is possible with even higher ratios. Information about the algorithm is available form the address below.
This chunk is required for all WAVE formats other than WAVE_FORMAT_PCM. It stores file dependent information about the contents of the WAVE data. It currently specifies the time length of the data in samples.
typedef struct sonarcwaveformat_tag {
WAVEFORMATEX wfx;
WORD wCompType;
} SONARCWAVEFORMAT
| wFormatTag | This must be set to WAVE_FORMAT_SONARC. |
| nChannels | Number of channels in the wave, 1 for mono, 2 for stereo. |
| nSamplesPerSec | Frequency of the sample rate of the wave file. This should be 11025, 22050, or 44100 Hz. Other sample rates are not allowed. |
| nAvgBytesPerSec | Average data rate. |
| Playback software can estimate the buffer size using the <nAvgBytesPerSec> value. | |
| nBlockAlign | The valid values have not been defined. |
| Playback software needs to process a multiple of <nBlockAlign> bytes of data at a time, so that the value of <nBlockAlign> can be used for buffer alignment. | |
| wBitsPerSample | This is the number of bits per sample of SONARC. |
| cbSize | The size in bytes of the extra information in the extended WAVE 'fmt' header. This should |