/******************************************************************************
Copyright (c) 2006 Analog Devices, Inc.  All Rights Reserved.  This software is
proprietary and confidential to Analog Devices, Inc. and its licensors.
*******************************************************************************

$Revision: 1.1 $
$Date: 2008/03/17 14:50:34 $
$LastChangedBy: dpowell $

Project:    HE-AAC Decoder
Title:      riff_header.c
Author:     DWP

Description:
            This file is an aid to the riff_header.c functions to provide a common
            set of methods to access riff headers.

References:
            riff_header.c
            Wave File Format [http://www.sonicspot.com/guide/wavefiles.html]


******************************************************************************/
#ifndef RIFF_HEADER_H
#define RIFF_HEADER_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/******************************************************************************
**          #defines
******************************************************************************/
#define RIFF_ID_SZ (4)
#define RIFF_TYPE_SZ (4)
#define CHUNK_ID_SZ (4)

#define MAX_CH 6

/******************************************************************************
**          Typedefs/Enumerations
******************************************************************************/
typedef struct {
    char            riffid[RIFF_ID_SZ];
    unsigned int    riffsize;
    char            rifftype[RIFF_TYPE_SZ];
} riffheader_t;

// common to all chunks
typedef struct {
    char            chunkid[CHUNK_ID_SZ+1];
    unsigned int    chunksize;
    void           *chunkdata;
} chunkheader_t;


typedef struct {
    unsigned short  audioformat;
    unsigned short  numchannels;
    unsigned int    samplerate;
    unsigned int    byterate;
    unsigned short  blockalign;
    unsigned short  bitspersample;
    unsigned short  extraformatsize;
    char           *extraformatdata;
} chunkformat_t;

typedef struct {
    FILE          *fp;
    unsigned char *temporary_buffer;
    int            buffer_len;
    chunkheader_t  metadata;
    chunkformat_t  wavedata;
} wavefile_t;

typedef struct {
    int    buffer_count;
    void **buffer;
    int    buffer_size;
    int    element_step;
} generic_buffers;

/******************************************************************************
**      Structure Declarations
******************************************************************************/


/******************************************************************************
**      Function Declarations
******************************************************************************/

/*
**
** Function:            parse_riff_header
**
** Description:         Examines the given file to ensure that it contains the
**                      expected RIFF container header
**
** Arguments:
**  fd                  file descriptor of the RIFF file
**  rh                  Structure to hold parsed RIFF header data
**
** Outputs:             
**  rh                  parsed RIFF header data is stored in the rh Structure
**                      on success the file descriptor is advanced beyond the header 
**                      DEBUG MODE
**                        prints descriptive text to stdout 
**
** Return value:        
**   0                  Success
**  -1                  Indicates that the first four bytes did not contain the
**                      characters 'R','I','F','F'
**  -2                  Indicates that the file size did not agree with that 
**                      stated in the container header
**  -3                  Indicates that the four bytes at offset 8 did not contain the
**                      characters 'W','A','V','E'
**
** Assumptions:         
**                      sizeof(unsigned int) == 4 bytes
**                      fd can successfully perform fseek(fd,0,SEEK_END) call
**                      fd is currently pointing to RIFF header in file
**
**
*/
int parse_riff_header(FILE *fd, riffheader_t *rh);

/*
**
** Function:            parse_chunk_header
**
** Description:         Examines the file and parses the next chunk header. If a chunk is 
**                      recognized it is parsed by the helper function and and saved into 
**                      memory from the heap and can be located via the chunkdata pointer 
**                      in the chunkheader_t structure.
**                      Currently this function recognizes the following chunks and parses
**                      those with accompanying helper functions
**                      [data]
**                      [fmt ] parse_chunk_format()
**
** Arguments:
**  fd                  file descriptor of the RIFF file
**  ch                  Structure to hold parsed RIFF Chunk data
**
** Outputs:             Fills the chunkheader_t structure and, if recognized, allocates further
**                      memory on the heap to hold the chunk specific header data.
**
** Return value:        
**   0                  Successful Parse
**   return > 0         Return code of helper function 
**  -1                  EOF, if unable to read first eight bytes of expected chunk header
**  -2                  Source Code modified incorrectly
**  -255                Insufficient memory to allocate for chunk header data.
**
** Assumptions:         
**                      sizeof(unsigned int) == 4 bytes
**                      fd can successfully perform fseek rewind call
**                      fd is currently pointing to Chunk header start in file
**
*/
int parse_chunk_header(FILE *fd, chunkheader_t *ch);


/*
**
** Function:            parse_chunk_format
**
** Description:         Helper Function to parse and fill the Chunk Header Data for
**                      a "fmt " chunk. Also allocates any extra memory required for 
**                      the optional ExtraFormatBytes at the end of the header.
**
** Arguments:
**  fd                  file descriptor of the RIFF file
**  cf                  Structure to hold parsed RIFF Chunk fmt
**
** Outputs:             fills the chunkformat_t structure with the data from the file 
**                      and advances the file descriptor beyond the header information.
**
** Return value:        
**   0                  Successful Parse
**  -1                  EOF, if unable to read full expected chunk header
**  -255                Insufficient memory to allocate for chunk header data.
**
** Assumptions:         
**                      Intel Big-Endian byte ordering
**                      fd is currently pointing to Chunk start + 8 bytes
**                      User will free heap memory allocated for ExtraFormatData if exists
**
**
*/
int parse_chunk_format(FILE *fd, chunkformat_t *cf);

/*
**
** Function:            SkipChunk
**
** Description:         Advance the File Descriptor to the beginning of the next chunk, 
**                      assuming that the current position is currently offset 8 bytes from
**                      the beginning of the current chunk. This is necessary as chunks 
**                      must be aligned on word boundaries, and so '\0' bytes are inserted 
**                      after chunks in bitstream to achieve this.
**                      Assumes word size of 4;
**
** Arguments:
**  fd                  file descriptor of the RIFF file
**  ch                  RIFF Chunk Header containing size of chunk to skip
**
** Outputs:             Advanced file descriptor
**
** Assumptions:         
**                      alignment of RIFF file at 4 bytes
**                      fd is currently pointing to Chunk start + 8 bytes
**
*/
void SkipChunk(FILE *fd, chunkheader_t *ch);

// other functions that need documentation
int write_generic_buffer16(wavefile_t *riff, generic_buffers *data, int num_elements);
void write_riff_header(wavefile_t *riff);
void init_riff_file(wavefile_t *riff, FILE *fp, unsigned char *buffer, int buffer_len);

#endif /* RIFF_HEADER_H */

/*
**
** EOF: $HeadURL: svn://dingofiles.spd.analog.com/audio/trunk/common/components/riff/public/riff_header.h $
**
*/
