/******************************************************************************
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:14:36 $
$LastChangedBy: cjakob $

Project:    HE-AAC Decoder
Title:      riff_format.c
Author:     Cong Van Nguyen

Description:
            Write out WAV-RIFF file

References:
            RIFFheader.c
            REPAACPP-006 HE-AAC Decoder Test System Modifications.doc

******************************************************************************/

#include "riff_format.h"

/*****************************************************************************
 *          #defines                                                         *
 *****************************************************************************/

#define MAX_CH 6

/*****************************************************************************
 *          typedefs/Enumerations                                            *
 *****************************************************************************/


/*****************************************************************************
 *          Local variables                                                  *
 *****************************************************************************/


/*****************************************************************************
 *          Local function declaration                                       *
 *****************************************************************************/


/*****************************************************************************
 *          Function Definitions                                                 *
 *****************************************************************************/

/*
**
** Function:            write_riff_buffer()
**
** Description:         Convert the output buffer of HE-AAC decoder to WAV-RIFF format
**
** Arguments:
**
**  fp1                 Handle of output WAV-RIFF file
**  x                   Output buffer of HE-AAC decoder
**  outbuf              Buffer for WAV-RIFF format
**  ch_dist             Distance (in 16-bit words) between channels in x
**  numSample           Number of samples in the buffer
**  chan                Number of channels
**  mono_dup            Indicate if the mono channel will be duplicated
**
**
** Outputs:             When chan>1, the data contained in seperate channels (in x)
**                      is multiplexed sample by sample according to the structure
**                      of WAV-RIFF PCM format, and then written out to the WAV-RIFF 
**                      file. When chan=1 and mono_dup=0, the single channel is simply
**                      written out. When chan=1 and mono_dup=1, the single channel is 
**                      duplicated before being written out.
**
** Return value:        0 is returned if data is written out successfully.
**                      -1 is returned if the parameter combination is illegal.
**
**
**
*/

int write_riff_buffer(FILE  *fp1,
                       short *x,                       
                       short *outbuf,
                       int   ch_dist,
                       int   numSample,
                       int   chan,
                       int   mono_dup)
{
	short *dst,*src[MAX_CH];
	int i,ch;
	
	if (((1 < chan) && (ch_dist < numSample)) || (chan < 1))
		return -1;
	
	dst = outbuf;
	for (ch = 0; ch < chan; ch++)
		src[ch] = &x[ch * ch_dist];
	
	if ((mono_dup != 0) && (chan == 1))	/* CVN 2006May27 */
	{
		chan = 2;
		src[1] = x;
	}
	
	for (i = 0; i < numSample; i++)
		for (ch = 0; ch < chan; ch++)
			*dst++ = *((src[ch])++);
		
	fwrite(outbuf,sizeof(short),numSample * chan,fp1);
	return 0;
}

/*
**
** Function:            initialize_riff_header()
**
** Description:         Initialise the RIFF header for the output WAV-RIFF file
**
** Arguments:
**
**  fp1                 Handle of output WAV-RIFF file
**
**
** Outputs:             44 bytes in the beginnning of the WAV-RIFF file is
**                      reserved for the RIFF header, which is updated later
**                      when finalize_riff_header() is called.
**
** Return value:        None
**
**
**
*/

void initialize_riff_header(FILE *fp1)
{
	fseek(fp1,44L,SEEK_SET);//reserving 44 bytes for header
}

/*
**
** Function:            finalize_riff_header()
**
** Description:         Finalise the RIFF header for the output WAV-RIFF file
**
** Arguments:
**
**  fp1                 Handle of output WAV-RIFF file
**  fs                  Sampling frequency (in Hz)
**  chan                Number of channels
**  mono_dup            Indicate if the mono channel will be duplicated
**
**
** Outputs:             The RIFF header is created after the whole audio sequence 
**                      is decoded.
**
** Return value:        None
**
**
**
*/

void finalize_riff_header(FILE *fp1,int fs,int chan,int mono_dup)
{
	long int m;
	int k;
	unsigned short temp1;
	unsigned int temp2;
	
	if ((mono_dup != 0) && (chan == 1))	/* CVN 2006May27 */
		chan = 2;
	
	m=ftell(fp1);//finding the entire file size in terms of bytes

	fseek(fp1,0L,SEEK_SET);//go to start of the file
	
	fprintf(fp1,"RIFF");//the characters riff indicate the start of the riff header

	k=m-8;//this is the size of the entire file following this data 
	      //i.e., the size of the rest of the file
	fwrite(&k,sizeof(int),1,fp1);

	fprintf(fp1,"WAVE");//the characters wave indicate the format of the data

	fprintf(fp1,"fmt ");//the fmt chatacters specify that this is the section of the file       
					   //describing the format

	k=16;//size of the waveformatex data flow
	fwrite(&k,sizeof(int),1,fp1);

	temp1=1;//w format tag only pcm data is supported in this sample
	fwrite(&temp1,sizeof(short),1,fp1);

	temp1=chan;//number of channels in 1 for mono 2 for stereo
	fwrite(&temp1,sizeof(short),1,fp1);

	temp2=fs;//sampling rate of the wave form in samples for second
	fwrite(&temp2,sizeof(int),1,fp1);

	temp2=fs*chan*2;//fs*chan*2;//average bytes per sec which can be used to determine 
	                //the time-wise length of the audio
	fwrite(&temp2,sizeof(int),1,fp1);

	temp1=chan*2;//specifies how each audio block must be aligned in bytes
	fwrite(&temp1,sizeof(short),1,fp1);

	temp1=16;//how many bits represents a single sample
	fwrite(&temp1,sizeof(short),1,fp1);

	fprintf(fp1,"data");//the data characters specifies that the audio data is next in the file

	temp2=m-44;//the length of the data in bytes
	fwrite(&temp2,sizeof(int),1,fp1);
}

/*
**
** EOF: $HeadURL: svn://dingofiles.spd.analog.com/audio/branches/aac-decoder/0.2.0/demo/bf533/riff_format.c $
**
*/

