/*
 * Copyright (c) 2001-2003 Shiman Associates Inc. All Rights Reserved.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */
/*
 * $Id: wav.h,v 1.1.1.1 2003/01/22 13:26:13 rocko Exp $
 *
 * Copyright (c) 2000, 2001 by Shiman Associates Inc. and Sun
 * Microsystems, Inc. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions: The above
 * copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the names of the authors or
 * copyright holders shall not be used in advertising or otherwise to
 * promote the sale, use or other dealings in this Software without
 * prior written authorization from the authors or copyright holders,
 * as applicable.
 *
 * All trademarks and registered trademarks mentioned herein are the
 * property of their respective owners. No right, title or interest in
 * or to any trademark, service mark, logo or trade name of the
 * authors or copyright holders or their licensors is granted.
 *
 */

#ifndef _WAV_H
#define _WAV_H

#include "mas/mas_types.h"

#define WAVE_FILE_HANDLES     255

/*** RIFF chunk ID's ****************************************************/
#define WAV_RIFF_ID     "RIFF"
#define WAV_FORMAT_ID   "fmt "
#define WAV_DATA_ID     "data"
#define WAV_LIST_ID     "LIST"
#define WAV_SILENCE_ID  "slnt"
#define WAV_FACT_ID     "FACT"
#define WAV_CUE_ID      "cue "
#define WAV_PLAYLIST_ID "plst"
#define WAV_LABEL_ID    "labl"
#define WAV_NOTE_ID     "note"
#define WAV_TEXT_ID     "ltxt"
#define WAV_FILE_ID     "file"

/*** Microsoft WAVE format, used in the RIFF chunk ***/
#define WAV_WAVE_ID "WAVE"

/*** known registered RIFF WAVE format tags *****************************/
#define WAVE_FORMAT_UNKNOWN             (0x0000)
#define WAVE_FORMAT_PCM                 (0x0001) 
#define WAVE_FORMAT_ADPCM               (0x0002)
#define WAVE_FORMAT_IEEE_FLOAT          (0x0003)
#define WAVE_FORMAT_ALAW                (0x0006)
#define WAVE_FORMAT_MULAW               (0x0007)
#define WAVE_FORMAT_OKI_ADPCM           (0x0010)
#define WAVE_FORMAT_IMA_ADPCM           (0x0011)
#define WAVE_FORMAT_DIGISTD             (0x0015)
#define WAVE_FORMAT_DIGIFIX             (0x0016)
#define WAVE_FORMAT_DOLBY_AC2           (0x0030)
#define WAVE_FORMAT_GSM610              (0x0031)
#define WAVE_FORMAT_ROCKWELL_ADPCM      (0x003b)
#define WAVE_FORMAT_ROCKWELL_DIGITALK   (0x003c)
#define WAVE_FORMAT_G721_ADPCM          (0x0040)
#define WAVE_FORMAT_G728_CELP           (0x0041)
#define WAVE_FORMAT_MPEG                (0x0050)
#define WAVE_FORMAT_MPEGLAYER3          (0x0055)
#define WAVE_FORMAT_G726_ADPCM          (0x0064)
#define WAVE_FORMAT_G722_ADPCM          (0x0065)

/*** These are the sizes for the structs below.  This allows one to
     set the number of bytes read from the file independently of the
     sizeof(struct) operator that includes padding for
     byte-alignment. */ 
#define FOURCC_SIZE                     4
#define SIZEOF_FOURCC                   FOURCC_SIZE
#define SIZEOF_RIFF_CHUNK_HEADER        8
#define SIZEOF_FMT_COMMON_FIELDS        14
#define SIZEOF_SILENCE_CHUNK            4
#define SIZEOF_FACT_CHUNK               4
#define SIZEOF_CUE_POINT                24
#define SIZEOF_CUE_CHUNK_HEADER         4
#define SIZEOF_PLAY_SEGMENT             12
#define SIZEOF_PLAYLIST_CHUNK_HEADER    4
#define SIZEOF_NOTE_CHUNK_HEADER        4
#define SIZEOF_FILE_CHUNK_HEADER        8
#define SIZEOF_LABEL_CHUNK_HEADER       4
#define SIZEOF_LABEL_TEXT_CHUNK_HEADER  20
#define SIZEOF_FMT_PCM_FIELDS           2

typedef u_int32 FourCC;  /* From the .WAV specs.  Four 8-bit
			    characters forming a four character tag
			    string. */ 

/* Common to all RIFF chunks.  A four-character ID and a 32-bit length. */
struct riff_chunk_header
{
    FourCC   id;
    u_int32  length;
};

/* WAV_FORMAT_ID chunk *********/
struct fmt_common_fields
{
    u_int16  format_tag;
    u_int16  channels;
    u_int32  samples_per_second;
    u_int32  average_bytes_per_second;
    u_int16  block_align_bytes;
};

/* WAV_SILENCE_ID chunk **********/
struct silence_chunk
{
    u_int32 samples;
};

/* WAV_FACT_ID chunk **********/
struct fact_chunk
{
    u_int32 file_size;
};

/* WAV_CUE_ID chunk **********/
struct cue_point
{
    u_int32 name;
    u_int32 position;
    FourCC  chunk_name;
    u_int32 chunk_start;
    u_int32 block_start;
    u_int32 sample_offset;
};

struct cue_chunk_header
{
    u_int32 num_cue_points;
};

/* WAV_PLAYLIST_ID chunk **********/
struct play_segment
{
    u_int32 name;
    u_int32 length;
    u_int32 loops;
};


struct playlist_chunk_header
{
    u_int32 num_play_segments;
};

/* WAV_LABEL_ID chunk **********/
struct label_chunk_header
{
    u_int32 name;
};

/* WAV_NOTE_ID chunk **********/
struct note_chunk_header
{
    u_int32 name;
};

/* WAV_TEXT_ID chunk **********/
struct label_text_chunk_header
{
    u_int32 name;
    u_int32 sample_length;
    u_int32 purpose;
    u_int16 country;
    u_int16 language;
    u_int16 dialect;
    u_int16 codepage;
};

/* WAV_FILE_ID chunk **********/
struct file_chunk_header
{
    u_int32 name;
    u_int32 media_type;
};

/*** Format specific structures ****************************************/
struct fmt_pcm_fields
{
    u_int16  bits_per_sample;
};


/**** Used internally in the .WAV reading code *************************/
struct wave_info
{
    u_int32                          length;
    char*                            name;
    struct  fmt_common_fields*       fmt;
    struct  cue_chunk_header*        cue_header;
    struct  cue_point*               cue_points;
    struct  playlist_chunk_header*   playlist_header;
    struct  play_segment*            play_segments;
    struct  label_chunk_header*      label_header;
    char*                            label_data;
    struct  note_chunk_header*       note_header;
    char*                            note_data;
    struct  label_text_chunk_header* label_text_header;
    char*                            label_text_data;
    struct  file_chunk_header*       file_header;
    char*                            file_data;
    struct  fmt_pcm_fields*          pcm_fields; /* used only for PCM */
    u_int32                          offset_data_start;
    u_int32                          data_length;
};

struct wave_file_handle_node
{
    FILE *fp;
    struct wave_info* info;
    struct wave_file_handle_node* next;
    struct wave_file_handle_node* prev;
};

/******** PUBLIC FUNCTIONS ********************************************/
extern int32   riff_begin_read   ( char* , FILE** );
extern char*   wav_format_string ( int format );
extern int32 wav_get_format(FILE *fp, u_int16* );
extern int32 wav_get_channels(FILE *fp, u_int16* );
extern int32 wav_get_samples_per_second(FILE *fp, u_int32* );
extern int32 wav_get_average_bytes_per_second(FILE *fp, u_int32* );
extern int32 wav_get_block_align_bytes(FILE *fp, u_int16* );
extern int32 wav_pcm_get_bits_per_sample(FILE *fp, u_int16* );
extern int32 wav_get_length(FILE *fp, u_int32*);
extern int32 wav_get_wave_info(FILE *fp, struct wave_info** );


#endif /* _MAS_TYPES_H */
