/*
 * 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.
 *
 */

#ifndef _MAS_SOURCE_WAV_H
#define _MAS_SOURCE_WAV_H

#include "riff.h"
#include "playlist.h"

/*** RIFF WAVE chunk ID's ************************************************/
#define WAVE_ID_FORMAT   "fmt "
#define WAVE_ID_DATA     "data"
#define WAVE_ID_LIST     "LIST"
#define WAVE_ID_SILENCE  "slnt"
#define WAVE_ID_FACT     "FACT"
#define WAVE_ID_CUE      "cue "
#define WAVE_ID_PLAYLIST "plst"
#define WAVE_ID_LABEL    "labl"
#define WAVE_ID_NOTE     "note"
#define WAVE_ID_TEXT     "ltxt"
#define WAVE_ID_FILE     "file"

/*** 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

/* WAV_FORMAT_ID chunk *********/
struct fmt_common_fields
{
    uint16  format_tag;
    uint16  channels;
    uint32  samples_per_second;
    uint32  average_bytes_per_second;
    uint16  block_align_bytes;
};

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

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

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

struct cue_chunk_header
{
    uint32 num_cue_points;
};

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


struct playlist_chunk_header
{
    uint32 num_play_segments;
};

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

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

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

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

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

struct wave_track_info
{
    uint32                          length;
    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 */
    uint32                          offset_data_start;
    uint32                          data_length;
    int bpstc;
};


struct wave_state
{
    int32 spf;
};

#endif /* _MAS_SOURCE_WAV_H */
