/*
 * pvr350audio.h:
 *
 * See the README file for copyright information and how to reach the author.
 *
 */

#ifndef __PVR350_AUDIO_H
#define __PVR350_AUDIO_H

extern "C" {
#include <a52dec/a52.h>
#include <a52dec/mm_accel.h>
#define LIBTWOLAME_STATIC
#include <twolame.h>
}

// PES header offsets
#define PESPACKETSTARTCODE1	0
#define PESPACKETSTARTCODE2	1
#define PESPACKETSTARTCODE3	2
#define PESSTREAMID		3
#define PESPACKETLEN1		4
#define PESPACKETLEN2		5
#define PESFLAGS1		6
#define PESFLAGS2		7
#define PESHEADERLENGTH		8
#define PESFIXHEADERLEN		9

#define SUBSTREAM_AC3_STREAMID	0
#define SUBSTREAM_AC3_FRAMECNT	1
#define SUBSTREAM_AC3_FIRSTACC1	2
#define SUBSTREAM_AC3_FIRSTACC2	3

#define AC3_INBUF_SIZE		4096
#define AC3_HEADER_SIZE		7
#define AC3_IDENTIFIER_BYTES	4
#define PCM_BUFFER_SIZE		65536		// #AS# 8KB sollten reichen
#define PCM_BUFFER_WORDS	8192		// 6144 #AS# 4KB sollten reichen
#define PCM_IDENTIFIER_BYTES	7
#define MP2_PES_DATA_SIZE	9216		// #AS# 2KB sollten reichen
#define MP2_PES_BUFFER_SIZE	MP2_PES_DATA_SIZE + 7200
#define MP2_SAMPLESBYFRAME	1152	// for MPEG-1 layer III

#define INBUF_SIZE		2048
#define AUDIO_CHANNELS		2
#define BIAS			384
#define MPEG_AUDIO_STREAM_ID	0xC0

#define AC3_SAMPLERATE		48000
#define MP2_BITRATE		256
#define MP2_HIGHQUALITY		2
#define MP2_MEDIUMQUALITY	5
#define MP2_LOWQUALITY		7

#define SUBSTREAM_MP2_LENGTH	4

// Offsets for MP3 Audio Substream Header
#define SUBSTREAM_MP2_SYNC	0
#define SUBSTREAM_MP2_VERSION	1
#define SUBSTREAM_MP2_BITRATE	2
#define SUBSTREAM_MP2_MODE	3

#define MPEG_AUDIO_SYNC		0xFF
#define MPEG_AUDIO_VERSION	0xFA	// MPEG-1 Layer III (CRC protected)
#define MPEG_AUDIO_BITRATE	0xC4	// 256kbps 48000 Hz
#define MPEG_AUDIO_MODE		0x00

typedef struct	AC3DecodeState {
	uint8_t		inbuf[AC3_INBUF_SIZE];		// input buffer
	uint8_t		*inbuf_ptr;
	int		frame_size;
	int		flags;
	int		channels;
	a52_state_t	*state;
	sample_t	*samples;
	int		sample_rate;
	int		bit_rate;
} AC3DecodeState_t;

class cAC3toMP2
{
private:
	bool		m_Initialized;
	int		m_AC3Channels;
	int		disable_adjust;
	int		disable_dynrng;
	twolame_options	*encodeOptions;
	AC3DecodeState_t        *m_AC3DecodeStatePtr;

protected:
	void float2s16(float *_f, int16_t *s16, int nchannels);
	int convert2wav(sample_t *_samples, int16_t *out_samples, int channels);
	bool A52DecodeInit(AC3DecodeState_t *s);
	void A52DecodeEnd(AC3DecodeState_t *s);
	bool MP2InitLibrary();
	void MP2CloseLibrary();

public:
	cAC3toMP2(AC3DecodeState_t *s);
	~cAC3toMP2();
	int A52DecodeFrame(AC3DecodeState_t *s, int16_t *outbuf, int *outbuf_size,
				 uint8_t *inbuf, int inbuf_size);
	int MP2EncodeFrame(int16_t *inbuf, int inbuf_bytes, uint8_t *outbuf);
};
#endif

