/*////////////////////////////////////////////////////////////////////////////

NAME:
	Qualcomm PureVoice Library Header File

FILE:		Qpl.h
AUTHOR:	Livingstone Song
COMPANY:	QUALCOMM, Inc. Copyright (C) 1997 - 2000

DESCRIPTION:
	This header file contains the necessary defines and COM classes.
	
NOTE:
	Caller is responsible for all memory allocation and de-allocation.

VERSION: 2.0

REVISION:
-11/15/00	Added QPLPvQcpFile1, QPLPvCodec3 - PureVoice Max Full Rate
-08/18/00   Added QPLPvCodec2 - PureVoice Fixed Full Rate
-07/20/00   Added QPLPvCodec1 - PureVoice Max Half Rate (variable rate)
-02/05/99   Added QPLPvCodec - PureVoice Fixed Half Rate
-10/20/97	Initial

/*////////////////////////////////////////////////////////////////////////////
// TAB = 3

#ifndef _QPL_H_
#define _QPL_H_

// INCLUDES
#include "QplCom.h"

// DEFINES
#define QPL_READ			0x00000001
#define QPL_WRITE			0x00000002

#define QPL_ENCODE		0x00000001
#define QPL_DECODE		0x00000002

#define QPL_QCELP_ENCODE_OFFSET(x)	((x)<<16)
#define QPL_QCELP_START			QPL_QCELP_ENCODE_OFFSET(0)
#define QPL_QCELP_FULL_MAX		QPL_QCELP_START
#define QPL_QCELP_FULL_FIXED	QPL_QCELP_FULL_MAX + QPL_QCELP_ENCODE_OFFSET(1)
#define QPL_QCELP_HALF_MAX		QPL_QCELP_FULL_FIXED + QPL_QCELP_ENCODE_OFFSET(1)
#define QPL_QCELP_HALF_FIXED	QPL_QCELP_HALF_MAX + QPL_QCELP_ENCODE_OFFSET(1)
#define QPL_QCELP_END			QPL_QCELP_HALF_FIXED

// For use with IQPLPv*->GetInfo
#ifdef __cplusplus
extern "C" {
#endif
struct QPLPvHrCodecInfo 
{
	UINT16	bytesPerPacket; // size of a packet in bytes 
	UINT16	samplesPerBlock;// size of a block in samples
									 // encoder encodes one block into one packet
								 	 // decoder decodes one packet into one block
	UINT16	samplesPerSec;	 // sps of input needed for the encoder
									 // and output from the decoder
	UINT16	bitsPerSample;	 // bits per sample of the above
};
#ifdef __cplusplus
}
#endif


/*
***								  
*** ok, let's get down to business
***
*/                               


// Our only entry point
// For example, to create an instance of QPLPvQcpFile object, you would do 
// the following:
//
// IQPLConvertFile* pCf;
// QPLCreateInstance( CLSID_QPLPvQcpFile, IID_IQPLConvertFile, 
//							(void**)&pCf );
//

// Returns S_OK if success.
//
HRESULT STDCALL QPLCreateInstance( 
	REFCLSID rclsid,	// class object id
	REFIID riid,		// interface id
	void** ppvObj		// this will contain the requested interface
);

/*///=========================================================================
|*
|*	QPLPvQcpFile
|*
|*	Interfaces:
|*		IQPLConvertFile
|*		IQPLQcpFile
|*
|*	CLSID_QPLPvQcpFile:
|*
|*		{94102930-4A5D-11d1-8896-00805F9E6091}
/*///=========================================================================
DEFINE_GUID(CLSID_QPLPvQcpFile, 
0x94102930, 0x4a5d, 0x11d1, 0x88, 0x96, 0x0, 0x80, 0x5f, 0x9e, 0x60, 0x91);

////////////////////////////////////////////////////////////////////////////// 
//
//	IQPLConvertFile
//
//	Methods:
//		- ConvertFile			convert qcp to wav and vice-versa
//		- GetProgress			get progress of conversion
//
//  IQPLConvertFile:
//
//	{169F1DE0-4A59-11d1-8896-00805F9E6091}
DEFINE_GUID(IID_IQPLConvertFile, 
0x169f1de0, 0x4a59, 0x11d1, 0x88, 0x96, 0x0, 0x80, 0x5f, 0x9e, 0x60, 0x91);

//
// Example(no error checking is done):
// This example converts a wave file (8-kHz 16-bit) to qcp file. 
//
// IQPLConvertFile* pCf;
// QPLCreateInstance( CLSID_QPLPvQcpFile, IID_IQPLConvertFile, 
//							(void**)&pCf );
// pCf->ConvertFile( NameOfWaveFile, NameForQcpFile, QPL_ENCODE );
// pCf->Release(); // we're done, release it

class IQPLConvertFile : public IUnknown
{
public:
	// ConvertFile converts inFileName to outFileName depending on the
	// mode parameter. If mode = QPL_ENCODE then inFileName is assumed to be
	// the file name of a wave file (8-kHz 16-bit PCM) and will be converted
	// to a .qcp file. If mode = QPL_DECODE then inFileName is assumed to be
	// the file name of a .qcp and will be converted to a wave file
	// (8-kHz 16-bit PCM).
	// Returns 0 if success otherwise -1.
	virtual INT32 STDCALL ConvertFile(
		const unsigned char* inFileName,
		const unsigned char* outFileName, 
		UINT32 mode) = 0;

	// GetProgress returns a number between 0 and 100 that corresponds
	// to percent done in ConvertFile.
	virtual UINT32 STDCALL GetProgress() = 0;
};

////////////////////////////////////////////////////////////////////////////// 
//
//	IQPLQcpFile
//
//	Methods:
//		- Open				open file
//		- Close				close file
//		- Read				read and decode
//		- Write				encode and write
//		- GetLength			get file length in milliseconds
//		- GetBlockSize		get size of a block in milliseconds
//
//  IQPLQcpFile:
//
// {2E77C1B0-6DF3-11d1-889E-00805F9E6091}
DEFINE_GUID(IID_IQPLQcpFile, 
0x2e77c1b0, 0x6df3, 0x11d1, 0x88, 0x9e, 0x0, 0x80, 0x5f, 0x9e, 0x60, 0x91);

//
// Example(no error checking is done):
//
// UINT32 lenInSec;
// IQPLQcpFile* pIQcpFile;
// QPLCreateInstance( CLSID_QPLPvFileConvert, IID_IQPLQcpFile, 
//							(void**)&pIQcpFile );
// pIQcpFile->Open( someFileName, QPL_READ );
// // find length of sound in seconds
// lenInSec = pIQcpFile->GetLength() * pIQcpFile->GetBlockSize() / 1000; 
// pIQcpFile->Close();	// we're done, close file
// pIQcpFile->Release(); // we're done, release it from memory

class IQPLQcpFile : public IUnknown
{
public:
	// Open opens .qcp file "fileName" in either QPL_READ or QPL_WRITE mode
	// but not both QPL_READ and QPL_WRITE.
	// Returns TRUE if success, else return FALSE.
	virtual BOOL STDCALL Open( const unsigned char* fileName, UINT32 mode ) = 0;
	
	// Close closes file that was opened with Open.
	// Returns TRUE if success, else return FALSE.
	virtual BOOL STDCALL Close() = 0;

	// Read reads 'blocks' blocks of PureVoice data and decodes
	// it to pcmBuf as linear 8-kHz 16-bit PCM samples.
	// Returns the current file position in blocks.
	// If return == 0 then end of file. 
	// If return < 0 then error in read.
	// Note: Caller must allocate and de-allocate pPcmBuf.
	// PCM samples are assumed to be in little-endian format.
	virtual INT32 STDCALL Read( UINT32 blocks, BYTE* pPcmBuf ) = 0;
	
	// Write encodes 'blocks' blocks of PCM data (linear 8-kHz 16-bit) 
	// in pPcmBuf to PureVoice format and writes it to the file.
	// Returns the current file position in blocks.
	// If return < 0 then error in write.
	// PCM samples are assumed to be in little-endian format.
	virtual INT32 STDCALL Write( UINT32 blocks, const BYTE* pPcmBuf ) = 0;

	// Returns length of file (sound data) in blocks.
	virtual UINT32 STDCALL GetLength() = 0;

	// Returns a block size in milliseconds.
	virtual UINT32 STDCALL GetBlockSize() = 0;
};



// QPLPvQcpFile1 is exactly same as QPLPvQcpFile except that one can specify
// the encoding level to the following:
// - QPL_QCELP_FULL_MAX    full max rate (variable rate 14000 bps max) 
// - QPL_QCELP_FULL_FIXED  full fixed rate (14000 bps)
// - QPL_QCELP_HALF_MAX    half max rate (variable rate 6800 bps max)
// - QPL_QCELP_HALF_FULL   half fixed rate (6800 bps)
// QPL_QCELP_FULL_MAX is default.

/*///=========================================================================
|*
|*	QPLPvQcpFile1
|*
|*	Interfaces:
|*		IQPLConvertFile1
|*		IQPLQcpFile1
|*
|*	CLSID_QPLPvQcpFile1:
|*
|*		{EEDAC6E0-BA67-11d4-94A2-0008C7377505}
/*///=========================================================================
DEFINE_GUID(CLSID_QPLPvQcpFile1,
0xeedac6e0, 0xba67, 0x11d4, 0x94, 0xa2, 0x0, 0x8, 0xc7, 0x37, 0x75, 0x5);

////////////////////////////////////////////////////////////////////////////// 
//
//	IQPLConvertFile1
//
//	Methods:
//		- ConvertFile			convert qcp to wav and vice-versa
//		- GetProgress			get progress of conversion
//
//  IQPLConvertFile1:
//
//	{EEDAC6E1-BA67-11d4-94A2-0008C7377505}
DEFINE_GUID(IID_IQPLConvertFile1, 
0xeedac6e1, 0xba67, 0x11d4, 0x94, 0xa2, 0x0, 0x8, 0xc7, 0x37, 0x75, 0x5);

class IQPLConvertFile1 : public IUnknown
{
public:
	// ConvertFile converts inFileName to outFileName depending on the
	// mode parameter. If mode = QPL_ENCODE then inFileName is assumed to be
	// the file name of a wave file (8-kHz 16-bit PCM) and will be converted
	// to a .qcp file. If mode = QPL_DECODE then inFileName is assumed to be
	// the file name of a .qcp and will be converted to a wave file
	// (8-kHz 16-bit PCM).
	// The mode parameter can also take on additional value in the QPL_ENCODE
	// mode. This additional value specifies the encoding level.
	// These are:
   // - QPL_QCELP_FULL_MAX    full max rate (variable rate 14000 bps max) 
   // - QPL_QCELP_FULL_FIXED  full fixed rate (14000 bps)
   // - QPL_QCELP_HALF_MAX    half max rate (variable rate 6800 bps max)
	// - QPL_QCELP_HALF_FULL   half fixed rate (6800 bps)
	// QPL_QCELP_FULL_MAX is default.
	// Returns 0 if success otherwise -1.

	//
	// Example(no error checking is done):
	// This example converts a wave file (8-kHz 16-bit) to qcp file using 
	// half max rate encoding. 
	//
	// IQPLConvertFile1* pCf;
	// QPLCreateInstance( CLSID_QPLPvQcpFile1, IID_IQPLConvertFile1, 
	//							(void**)&pCf );
	// pCf->ConvertFile( NameOfWaveFile, NameForQcpFile, 
	//							QPL_ENCODE | QPL_QCELP_HALF_MAX);
	// pCf->Release(); // we're done, release it

	virtual INT32 STDCALL ConvertFile(
		const unsigned char* inFileName,
		const unsigned char* outFileName, 
		UINT32 mode) = 0;

	// GetProgress returns a number between 0 and 100 that corresponds
	// to percent done in ConvertFile.
	virtual UINT32 STDCALL GetProgress() = 0;
};

////////////////////////////////////////////////////////////////////////////// 
//
//	IQPLQcpFile1
//
//	Methods:
//		- Open				open file
//		- Close				close file
//		- Read				read and decode
//		- Write				encode and write
//		- GetLength			get file length in milliseconds
//		- GetBlockSize		get size of a block in milliseconds
//
//  IQPLQcpFile1:
//
//	{EEDAC6E2-BA67-11d4-94A2-0008C7377505}
DEFINE_GUID(IID_IQPLQcpFile1, 
0xeedac6e2, 0xba67, 0x11d4, 0x94, 0xa2, 0x0, 0x8, 0xc7, 0x37, 0x75, 0x5);

class IQPLQcpFile1 : public IUnknown
{
public:
	// Open opens .qcp file "fileName" in either QPL_READ or QPL_WRITE mode
	// but not both QPL_READ and QPL_WRITE.
	// The mode parameter can also take on additional value in QPL_WRITE mode
	// This additional value specifies the encoding level.
	// These are:
   // - QPL_QCELP_FULL_MAX    full max rate (variable rate 14000 bps max) 
   // - QPL_QCELP_FULL_FIXED  full fixed rate (14000 bps)
   // - QPL_QCELP_HALF_MAX    half max rate (variable rate 6800 bps max)
	// - QPL_QCELP_HALF_FULL   half fixed rate (6800 bps)
	// QPL_QCELP_FULL_MAX is default.
	// Returns TRUE if success, else return FALSE.

	//
	// Example(no error checking is done):
	// This example opens a new qcp file with encoding level of full fixed
	// rate.
	//
	// IQPLQcpFile1* pIQcpFile;
	// QPLCreateInstance( CLSID_QPLPvFileConvert1, IID_IQPLQcpFile1, 
	//							(void**)&pIQcpFile );
	// pIQcpFile->Open( newFileName, QPL_WRITE | QPL_QCELP_FULL_FIXED );
    
	virtual BOOL STDCALL Open( const unsigned char* fileName, UINT32 mode ) = 0;
	
	// Close closes file that was opened with Open.
	// Returns TRUE if success, else return FALSE.
	virtual BOOL STDCALL Close() = 0;

	// Read reads 'blocks' blocks of PureVoice data and decodes
	// it to pcmBuf as linear 8-kHz 16-bit PCM samples.
	// Returns the current file position in blocks.
	// If return == 0 then end of file. 
	// If return < 0 then error in read.
	// Note: Caller must allocate and de-allocate pPcmBuf.
	// PCM samples are assumed to be in little-endian format.
	virtual INT32 STDCALL Read( UINT32 blocks, BYTE* pPcmBuf ) = 0;
	
	// Write encodes 'blocks' blocks of PCM data (linear 8-kHz 16-bit) 
	// in pPcmBuf to PureVoice format and writes it to the file.
	// Returns the current file position in blocks.
	// If return < 0 then error in write.
	// PCM samples are assumed to be in little-endian format.
	virtual INT32 STDCALL Write( UINT32 blocks, const BYTE* pPcmBuf ) = 0;

	// Returns length of file (sound data) in blocks.
	virtual UINT32 STDCALL GetLength() = 0;

	// Returns a block size in milliseconds.
	virtual UINT32 STDCALL GetBlockSize() = 0;
};



/*///=========================================================================
|*
|*	QPLPvCodec
|*
|*	Interfaces:
|*		IQPLPvHrCodec
|*
|*	CLSID_QPLPvCodec:
|*
|*		{ED117979-5981-11d3-A1B4-00805F9B5695}
/*///=========================================================================
DEFINE_GUID(CLSID_QPLPvCodec, 
0xed117979, 0x5981, 0x11d3, 0xa1, 0xb4, 0x0, 0x80, 0x5f, 0x9b, 0x56, 0x95);

////////////////////////////////////////////////////////////////////////////// 
//
//	IQPLPvHrCodec
//    PureVoice Fixed Half Rate Codec (6800 bps)
//
//	Methods:
//		- Reset				initialize CODEC
//		- GetInfo			get info on CODEC
//		- Convert			encode or decode depending on mode set in Reset
//
//  IQPLPvHrCodec:
//
// {ED11797A-5981-11d3-A1B4-00805F9B5695}
DEFINE_GUID(IID_IQPLPvHrCodec, 
0xed11797a, 0x5981, 0x11d3, 0xa1, 0xb4, 0x0, 0x80, 0x5f, 0x9b, 0x56, 0x95);

class IQPLPvHrCodec : public IUnknown
{
public:
	// Reset initializes the codec (must be performed before Encode/Decode).
	// Parameter mode must be either QPL_ENCODE or QPL_DECODE.
	// Returns TRUE if success else FALSE.
	virtual BOOL STDCALL Reset( UINT32 mode )=0;
	
	// Fills in *pInfo.
	virtual void STDCALL GetInfo( QPLPvHrCodecInfo* pInfo )=0;

	// In ENCODE mode, Convert converts 'blocks' blocks of linear PCM samples
	// in *pSrcBuf to PureVoice Fixed Half Rate data into *pDestBuf.
	// In DECODE mode, Convert converts 'blocks' packets of PureVoice Fixed Half
	// Rate in *pSrcBuf to linear PCM samples data into *pDestBuf.
	// Return TRUE if success else FALSE.
	// Note: Caller must allocate and de-allocate pDestBuf.
	// PCM samples are assumed to be in little-endian format.
	virtual BOOL STDCALL Convert( UINT32 blocks, const BYTE* pSrcBuf, BYTE* pDestBuf )=0;
};



/*///=========================================================================
|*
|*	QPLPvCodec1
|*
|*	Interfaces:
|*		IQPLPvVrHrCodec
|*
|*	CLSID_QPLPvCodec1:
|*
|*		{ED11797B-5981-11d3-A1B4-00805F9B5695}
/*///=========================================================================
DEFINE_GUID(CLSID_QPLPvCodec1, 
0xed11797b, 0x5981, 0x11d3, 0xa1, 0xb4, 0x0, 0x80, 0x5f, 0x9b, 0x56, 0x95);

////////////////////////////////////////////////////////////////////////////// 
//
//	IQPLPvVrHrCodec
//    PureVoice Variable Half Rate Codec (Max 6800 bps)
//
//	Methods:
//		- Reset				initialize CODEC
//		- GetInfo			get info on CODEC
//		- Convert			encode or decode depending on mode set in Reset
//
//  IQPLPvVrHrCodec:
//
// {ED11797C-5981-11d3-A1B4-00805F9B5695}
DEFINE_GUID(IID_IQPLPvVrHrCodec, 
0xed11797c, 0x5981, 0x11d3, 0xa1, 0xb4, 0x0, 0x80, 0x5f, 0x9b, 0x56, 0x95);

class IQPLPvVrHrCodec : public IUnknown
{
public:
	// Reset initializes the codec (must be performed before Encode/Decode).
	// Parameter mode must be either ENCODE or DECODE.
	// Returns TRUE if success else FALSE.
	virtual BOOL STDCALL Reset( UINT32 mode )=0;
	
	// Fills in *pInfo.
	virtual void STDCALL GetInfo( QPLPvHrCodecInfo* pInfo )=0;

	// In ENCODE mode, Convert converts 'blocks' blocks of linear PCM samples
	// in *pSrcBuf to PureVoice Max Half Rate (variable) data into *pDestBuf.
	// The return value contains the actual size of *pDestBuf in bytes.
	// In DECODE mode, Convert converts 'blocks' packets of PureVoice Max Half
	// Rate (variable) in *pSrcBuf to linear PCM samples data into *pDestBuf.
	// The return value contains the actual size of *pDestBuf in bytes. 
	// In DECODE case, this return value will equal to 
	// ['blocks' * samplesPerBlock * bitsPerSample / 8]
	// If return value is -1 then error occurred.
	// Note: Caller must allocate and de-allocate pDestBuf.
	// PCM samples are assumed to be in little-endian format.
	virtual UINT32 STDCALL Convert( UINT32 blocks, const BYTE* pSrcBuf, BYTE* pDestBuf )=0;
};



/*///=========================================================================
|*
|*	QPLPvCodec2
|*
|*	Interfaces:
|*		IQPLPvFrCodec
|*
|*	CLSID_QPLPvCodec2:
|*
|*		{ED11797D-5981-11d3-A1B4-00805F9B5695}
/*///=========================================================================
DEFINE_GUID(CLSID_QPLPvCodec2, 
0xed11797d, 0x5981, 0x11d3, 0xa1, 0xb4, 0x0, 0x80, 0x5f, 0x9b, 0x56, 0x95);

////////////////////////////////////////////////////////////////////////////// 
//
//	IQPLPvFrCodec
//    PureVoice Fixed Full Rate Codec (14000 bps)
//
//	Methods:
//		- Reset				initialize CODEC
//		- GetInfo			get info on CODEC
//		- Convert			encode or decode depending on mode set in Reset
//
//  IQPLPvFrCodec:
//
// {ED11797e-5981-11d3-A1B4-00805F9B5695}
DEFINE_GUID(IID_IQPLPvFrCodec, 
0xed11797e, 0x5981, 0x11d3, 0xa1, 0xb4, 0x0, 0x80, 0x5f, 0x9b, 0x56, 0x95);

class IQPLPvFrCodec : public IUnknown
{
public:
	// Reset initializes the codec (must be performed before Encode/Decode).
	// Parameter mode must be either ENCODE or DECODE.
	// Returns TRUE if success else FALSE.
	virtual BOOL STDCALL Reset( UINT32 mode )=0;
	
	// Fills in *pInfo.
	virtual void STDCALL GetInfo( QPLPvHrCodecInfo* pInfo )=0;

	// In ENCODE mode, Convert converts 'blocks' blocks of linear PCM samples
	// in *pSrcBuf to PureVoice Fixed Full Rate data into *pDestBuf.
	// In DECODE mode, Convert converts 'blocks' packets of PureVoice Fixed Full
	// Rate in *pSrcBuf to linear PCM samples data into *pDestBuf.
	// Return TRUE if success else FALSE.
	// Note: Caller must allocate and de-allocate pDestBuf.
	// PCM samples are assumed to be in little-endian format.
	virtual BOOL STDCALL Convert( UINT32 blocks, const BYTE* pSrcBuf, BYTE* pDestBuf )=0;
};



/*///=========================================================================
|*
|*	QPLPvCodec3
|*
|*	Interfaces:
|*		IQPLPvVrFrCodec
|*
|*	CLSID_QPLPvCodec3:
|*
|*		{ED11797F-5981-11d3-A1B4-00805F9B5695}
/*///=========================================================================
DEFINE_GUID(CLSID_QPLPvCodec3, 
0xed11797f, 0x5981, 0x11d3, 0xa1, 0xb4, 0x0, 0x80, 0x5f, 0x9b, 0x56, 0x95);

////////////////////////////////////////////////////////////////////////////// 
//
//	IQPLPvVrFrCodec
//    PureVoice Variable Full Rate Codec (max 14000 bps)
//
//	Methods:
//		- Reset				initialize CODEC
//		- GetInfo			get info on CODEC
//		- Convert			encode or decode depending on mode set in Reset
//
//  IQPLPvVrFrCodec:
//
// {ED117980-5981-11d3-A1B4-00805F9B5695}
DEFINE_GUID(IID_IQPLPvVrFrCodec, 
0xed117980, 0x5981, 0x11d3, 0xa1, 0xb4, 0x0, 0x80, 0x5f, 0x9b, 0x56, 0x95);

class IQPLPvVrFrCodec : public IUnknown
{
public:
	// Reset initializes the codec (must be performed before Encode/Decode).
	// Parameter mode must be either ENCODE or DECODE.
	// Returns TRUE if success else FALSE.
	virtual BOOL STDCALL Reset( UINT32 mode )=0;
	
	// Fills in *pInfo.
	virtual void STDCALL GetInfo( QPLPvHrCodecInfo* pInfo )=0;

	// In ENCODE mode, Convert converts 'blocks' blocks of linear PCM samples
	// in *pSrcBuf to PureVoice Max Full Rate (variable) data into *pDestBuf.
	// The return value contains the actual size of *pDestBuf in bytes.
	// In DECODE mode, Convert converts 'blocks' packets of PureVoice Max Full
	// Rate (variable) in *pSrcBuf to linear PCM samples data into *pDestBuf.
	// The return value contains the actual size of *pDestBuf in bytes. 
	// In DECODE case, this return value will equal to 
	// ['blocks' * samplesPerBlock * bitsPerSample / 8]
	// If return value is -1 then error occurred.
	// Note: Caller must allocate and de-allocate pDestBuf.
	// PCM samples are assumed to be in little-endian format.
	virtual UINT32 STDCALL Convert( UINT32 blocks, const BYTE* pSrcBuf, BYTE* pDestBuf )=0;
};

#endif