shithub: aacenc

Download patch

ref: ca01ea74cb41d154ab90a590c223873f4f6978ac
parent: 1b925ea392c6b968c6550c4179eade1aed307096
author: menno <menno>
date: Fri Apr 16 13:53:34 EDT 2004

New out_faac Winamp output filter code

binary files /dev/null b/plugins/winamp/AudioCoding.bmp differ
--- a/plugins/winamp/CRegistry.cpp
+++ b/plugins/winamp/CRegistry.cpp
@@ -1,6 +1,6 @@
 /*
-FAAC - encoder plugin for Winamp 2
-Copyright (C) 2002 Antonio Foranna
+FAAC - codec plugin for Cooledit
+Copyright (C) 2002-2004 Antonio Foranna
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -16,15 +16,21 @@
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 			
 The author can be contacted at:
-kreel@interfree.it
+ntnfrn_email-temp@yahoo.it
 */
 
 //#include "stdafx.h"
 #include <windows.h>
-#include <string.h>
 #include <stdlib.h>		// malloc, free
+#include <string.h>
 #include "CRegistry.h"
 
+
+
+// *****************************************************************************
+
+
+
 CRegistry::CRegistry()
 {
 	regKey=NULL;
@@ -33,20 +39,22 @@
 
 CRegistry::~CRegistry()
 {
-	if(regKey)
-		RegCloseKey(regKey);
-	if(path)
-		free(path);
+	closeReg();
 }
+
+
+
 // *****************************************************************************
-// *****************************************************************************
-// *****************************************************************************
 
+
+
 #define setPath(SubKey) \
 	if(path) \
 		free(path); \
 	path=strdup(SubKey);
 
+// -----------------------------------------------------------------------------------------------
+
 BOOL CRegistry::openReg(HKEY hKey, char *SubKey)
 {
 	if(regKey)
@@ -63,7 +71,7 @@
 		return FALSE;
 	}
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 BOOL CRegistry::openCreateReg(HKEY hKey, char *SubKey)
 {
@@ -91,7 +99,7 @@
 		}
 	}
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 void CRegistry::closeReg()
 {
@@ -102,15 +110,18 @@
 		delete path; 
 	path=NULL;
 }
+
+
+
 // *****************************************************************************
-// *****************************************************************************
-// *****************************************************************************
 
+
+
 void CRegistry::DeleteRegVal(char *SubKey)
 {
 	RegDeleteValue(regKey,SubKey);
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 void CRegistry::DeleteRegKey(char *SubKey)
 {
@@ -117,10 +128,12 @@
 	RegDeleteKey(regKey,SubKey);
 }
 
+
+
 // *****************************************************************************
-// *****************************************************************************
-// *****************************************************************************
 
+
+
 void CRegistry::setRegBool(char *keyStr , BOOL val)
 {
 BOOL tempVal;
@@ -129,8 +142,18 @@
 		tempVal!=val)
 		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(BOOL));
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
+void CRegistry::setRegBool(char *keyStr , bool val)
+{
+bool tempVal;
+DWORD len;
+	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS ||
+		tempVal!=val)
+		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(bool));
+}
+// -----------------------------------------------------------------------------------------------
+
 void CRegistry::setRegByte(char *keyStr , BYTE val)
 {
 DWORD	t=val;
@@ -140,7 +163,7 @@
 		tempVal!=val)
 		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&t , sizeof(DWORD));
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 void CRegistry::setRegWord(char *keyStr , WORD val)
 {
@@ -151,7 +174,7 @@
 		tempVal!=val)
 		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&t , sizeof(DWORD));
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 void CRegistry::setRegDword(char *keyStr , DWORD val)
 {
@@ -161,7 +184,7 @@
 		tempVal!=val)
 		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&val , sizeof(DWORD));
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 void CRegistry::setRegFloat(char *keyStr , float val)
 {
@@ -171,7 +194,7 @@
 		tempVal!=val)
 		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(float));
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 void CRegistry::setRegStr(char *keyStr , char *valStr)
 {
@@ -193,7 +216,7 @@
 		delete tempVal;
 	}
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 void CRegistry::setRegValN(char *keyStr , BYTE *addr,  DWORD size)
 {
@@ -217,8 +240,6 @@
 
 
 // *****************************************************************************
-// *****************************************************************************
-// *****************************************************************************
 
 
 
@@ -234,8 +255,22 @@
 	}
 	return tempVal;
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
+bool CRegistry::getSetRegBool(char *keyStr, bool val)
+{
+bool tempVal;
+DWORD len=sizeof(bool);
+
+	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS)
+	{
+		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(bool));
+		return val;
+	}
+	return tempVal;
+}
+// -----------------------------------------------------------------------------------------------
+
 BYTE CRegistry::getSetRegByte(char *keyStr, BYTE val)
 {
 DWORD tempVal;
@@ -249,7 +284,7 @@
 	}
 	return (BYTE)tempVal;
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 WORD CRegistry::getSetRegWord(char *keyStr, WORD val)
 {
@@ -264,7 +299,7 @@
 	}
 	return (WORD)tempVal;
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 DWORD CRegistry::getSetRegDword(char *keyStr, DWORD val)
 {
@@ -278,7 +313,7 @@
 	}
 	return (DWORD)tempVal;
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 float CRegistry::getSetRegFloat(char *keyStr, float val)
 {
@@ -292,7 +327,7 @@
 	}
 	return tempVal;
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 int CRegistry::getSetRegStr(char *keyStr, char *tempString, char *dest, int maxLen)
 {
@@ -311,7 +346,7 @@
 	}
 	return tempLen;
 }
-// *****************************************************************************
+// -----------------------------------------------------------------------------------------------
 
 int CRegistry::getSetRegValN(char *keyStr, BYTE *tempAddr, BYTE *addr, DWORD size)
 {
--- a/plugins/winamp/CRegistry.h
+++ b/plugins/winamp/CRegistry.h
@@ -1,3 +1,24 @@
+/*
+FAAC - codec plugin for Cooledit
+Copyright (C) 2002-2004 Antonio Foranna
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation.
+	
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+		
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+			
+The author can be contacted at:
+ntnfrn_email-temp@yahoo.it
+*/
+
 #ifndef registry_h
 #define registry_h
 
@@ -14,6 +35,7 @@
 	void	DeleteRegKey(char *SubKey);
 
 	void	setRegBool(char *keyStr , BOOL val);
+	void	setRegBool(char *keyStr , bool val);
 	void	setRegByte(char *keyStr , BYTE val);
 	void	setRegWord(char *keyStr , WORD val);
 	void	setRegDword(char *keyStr , DWORD val);
@@ -22,6 +44,7 @@
 	void	setRegValN(char *keyStr , BYTE *addr,  DWORD size);
 
 	BOOL	getSetRegBool(char *keyStr, BOOL var);
+	bool	getSetRegBool(char *keyStr, bool var);
 	BYTE	getSetRegByte(char *keyStr, BYTE var);
 	WORD	getSetRegWord(char *keyStr, WORD var);
 	DWORD	getSetRegDword(char *keyStr, DWORD var);
--- /dev/null
+++ b/plugins/winamp/Cfaac.cpp
@@ -1,0 +1,537 @@
+/*
+FAAC - codec plugin for Cooledit
+Copyright (C) 2004 Antonio Foranna
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation.
+	
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+		
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+			
+The author can be contacted at:
+ntnfrn_email-temp@yahoo.it
+*/
+
+#include "Cfaac.h"
+
+
+
+// *********************************************************************************************
+
+
+
+#define FREE_ARRAY(ptr) \
+{ \
+	if(ptr) \
+		free(ptr); \
+	ptr=0; \
+}
+
+// *********************************************************************************************
+
+Cfaac::Cfaac(HANDLE hOut)
+{
+	if(hOut)
+	{
+		hOutput=hOut;
+		return;
+	}
+
+    if(!(hOutput=GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE|GMEM_ZEROINIT,sizeof(MYOUTPUT))))
+		MessageBox(0, "Memory allocation error: hOutput", APP_NAME " plugin", MB_OK|MB_ICONSTOP); \
+/*
+MYOUTPUT *mo;
+
+	if(!(mo=(MYOUTPUT *)GlobalLock(hOutput)))
+		MessageBox(0, "GlobalLock(hOutput)", APP_NAME " plugin", MB_OK|MB_ICONSTOP); \
+
+	GlobalUnlock(hOutput);*/
+}
+// -----------------------------------------------------------------------------------------------
+
+Cfaac::~Cfaac()
+{
+	if(!hOutput)
+		return;
+
+MYOUTPUT *mo;
+
+	GLOBALLOCK(mo,hOutput,MYOUTPUT,return);
+	
+	if(mo->WrittenSamples)
+	{
+	int	BytesWritten;
+		if(mo->bytes_into_buffer>0)
+			memset(mo->bufIn+mo->bytes_into_buffer, 0, (mo->samplesInput*(mo->BitsPerSample>>3))-mo->bytes_into_buffer);
+		do
+		{
+			if((BytesWritten=processData(hOutput,mo->bufIn,mo->bytes_into_buffer))<0)
+				MessageBox(0, "~Cfaac: processData", APP_NAME " plugin", MB_OK|MB_ICONSTOP);
+			mo->bytes_into_buffer=0;
+		}while(BytesWritten>0);
+	}
+
+	if(mo->aacFile)
+	{
+		fclose(mo->aacFile);
+		mo->aacFile=0;
+	}
+	else
+	{
+		MP4Close(mo->MP4File);
+		mo->MP4File=0;
+	}
+	
+	if(mo->hEncoder)
+		faacEncClose(mo->hEncoder);
+	
+	FREE_ARRAY(mo->bitbuf)
+	FREE_ARRAY(mo->buf32bit)
+	FREE_ARRAY(mo->bufIn)
+	
+	GlobalUnlock(hOutput);
+	GlobalFree(hOutput);
+}
+
+// *********************************************************************************************
+//									Utilities
+// *********************************************************************************************
+
+#define SWAP32(x) (((x & 0xff) << 24) | ((x & 0xff00) << 8) \
+	| ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24))
+#define SWAP16(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
+
+void Cfaac::To32bit(int32_t *buf, BYTE *bufi, int size, BYTE samplebytes, BYTE bigendian)
+{
+int i;
+
+	switch(samplebytes)
+	{
+	case 1:
+		// this is endian clean
+		for (i = 0; i < size; i++)
+			buf[i] = (bufi[i] - 128) * 65536;
+		break;
+		
+	case 2:
+#ifdef WORDS_BIGENDIAN
+		if (!bigendian)
+#else
+			if (bigendian)
+#endif
+			{
+				// swap bytes
+				for (i = 0; i < size; i++)
+				{
+					int16_t s = ((int16_t *)bufi)[i];
+					
+					s = SWAP16(s);
+					
+					buf[i] = ((u_int32_t)s) << 8;
+				}
+			}
+			else
+			{
+				// no swap
+				for (i = 0; i < size; i++)
+				{
+					int s = ((int16_t *)bufi)[i];
+					
+					buf[i] = s << 8;
+				}
+			}
+			break;
+			
+	case 3:
+		if (!bigendian)
+		{
+			for (i = 0; i < size; i++)
+			{
+				int s = bufi[3 * i] | (bufi[3 * i + 1] << 8) | (bufi[3 * i + 2] << 16);
+				
+				// fix sign
+				if (s & 0x800000)
+					s |= 0xff000000;
+				
+				buf[i] = s;
+			}
+		}
+		else // big endian input
+		{
+			for (i = 0; i < size; i++)
+			{
+				int s = (bufi[3 * i] << 16) | (bufi[3 * i + 1] << 8) | bufi[3 * i + 2];
+				
+				// fix sign
+				if (s & 0x800000)
+					s |= 0xff000000;
+				
+				buf[i] = s;
+			}
+		}
+		break;
+		
+	case 4:		
+#ifdef WORDS_BIGENDIAN
+		if (!bigendian)
+#else
+			if (bigendian)
+#endif
+			{
+				// swap bytes
+				for (i = 0; i < size; i++)
+				{
+					int s = bufi[i];
+					
+					buf[i] = SWAP32(s);
+				}
+			}
+			else
+				memcpy(buf,bufi,size*sizeof(u_int32_t));
+		/*
+		int exponent, mantissa;
+		float *bufo=(float *)buf;
+			
+			for (i = 0; i < size; i++)
+			{
+				exponent=bufi[(i<<2)+3]<<1;
+				if(bufi[i*4+2] & 0x80)
+					exponent|=0x01;
+				exponent-=126;
+				mantissa=(DWORD)bufi[(i<<2)+2]<<16;
+				mantissa|=(DWORD)bufi[(i<<2)+1]<<8;
+				mantissa|=bufi[(i<<2)];
+				bufo[i]=(float)ldexp(mantissa,exponent);
+			}*/
+			break;
+	}
+}
+
+// *********************************************************************************************
+//									Main functions
+// *********************************************************************************************
+
+void Cfaac::DisplayError(char *ProcName, char *str)
+{
+char buf[100]="";
+
+	if(str && *str)
+	{
+		if(ProcName && *ProcName)
+			sprintf(buf,"%s: ", ProcName);
+		strcat(buf,str);
+		MessageBox(0, buf, APP_NAME " plugin", MB_OK|MB_ICONSTOP);
+	}
+
+MYOUTPUT *mo;
+	GLOBALLOCK(mo,hOutput,MYOUTPUT,return);
+	mo->bytes_into_buffer=-1;
+	GlobalUnlock(hOutput);
+	GlobalUnlock(hOutput);
+}
+// *********************************************************************************************
+
+void Cfaac::getFaacCfg(MY_ENC_CFG *cfg)
+{ 
+CRegistry reg;
+
+	if(reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME "\\FAAC"))
+	{
+		cfg->AutoCfg=reg.getSetRegBool("Auto",true);
+		cfg->SaveMP4=reg.getSetRegBool("Write MP4",false);
+		cfg->EncCfg.mpegVersion=reg.getSetRegDword("MPEG version",MPEG4); 
+		cfg->EncCfg.aacObjectType=reg.getSetRegDword("Profile",LOW); 
+		cfg->EncCfg.allowMidside=reg.getSetRegDword("MidSide",true); 
+		cfg->EncCfg.useTns=reg.getSetRegDword("TNS",true); 
+		cfg->EncCfg.useLfe=reg.getSetRegDword("LFE",false);
+		cfg->UseQuality=reg.getSetRegBool("Use quality",false);
+		cfg->EncCfg.quantqual=reg.getSetRegDword("Quality",100); 
+		cfg->EncCfg.bitRate=reg.getSetRegDword("BitRate",0); 
+		cfg->EncCfg.bandWidth=reg.getSetRegDword("BandWidth",0); 
+		cfg->EncCfg.outputFormat=reg.getSetRegDword("Header",ADTS); 
+	}
+	else
+		MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
+}
+// -----------------------------------------------------------------------------------------------
+
+void Cfaac::setFaacCfg(MY_ENC_CFG *cfg)
+{ 
+CRegistry reg;
+
+	if(reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME "\\FAAC"))
+	{
+		reg.setRegBool("Auto",cfg->AutoCfg); 
+		reg.setRegBool("Write MP4",cfg->SaveMP4); 
+		reg.setRegDword("MPEG version",cfg->EncCfg.mpegVersion); 
+		reg.setRegDword("Profile",cfg->EncCfg.aacObjectType); 
+		reg.setRegDword("MidSide",cfg->EncCfg.allowMidside); 
+		reg.setRegDword("TNS",cfg->EncCfg.useTns); 
+		reg.setRegDword("LFE",cfg->EncCfg.useLfe); 
+		reg.setRegBool("Use quality",cfg->UseQuality); 
+		reg.setRegDword("Quality",cfg->EncCfg.quantqual); 
+		reg.setRegDword("BitRate",cfg->EncCfg.bitRate); 
+		reg.setRegDword("BandWidth",cfg->EncCfg.bandWidth); 
+		reg.setRegDword("Header",cfg->EncCfg.outputFormat); 
+	}
+	else
+		MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
+}
+// *********************************************************************************************
+
+HANDLE Cfaac::Init(LPSTR lpstrFilename,long lSamprate,WORD wBitsPerSample,WORD wChannels,long FileSize)
+{
+MYOUTPUT	*mo;
+MY_ENC_CFG	cfg;
+DWORD		samplesInput,
+			maxBytesOutput;
+
+//	if(wBitsPerSample!=8 && wBitsPerSample!=16) // 32 bit audio from cooledit is in unsupported format
+//		return 0;
+	if(wChannels>48)	// FAAC supports max 48 tracks!
+		return NULL;
+
+	GLOBALLOCK(mo,hOutput,MYOUTPUT,return NULL);
+
+	// open the encoder library
+	if(!(mo->hEncoder=faacEncOpen(lSamprate, wChannels, &samplesInput, &maxBytesOutput)))
+		return ERROR_Init("Can't open library");
+
+	if(!(mo->bitbuf=(unsigned char *)malloc(maxBytesOutput*sizeof(unsigned char))))
+		return ERROR_Init("Memory allocation error: output buffer");
+
+	if(!(mo->bufIn=(BYTE *)malloc(samplesInput*sizeof(int32_t))))
+		return ERROR_Init("Memory allocation error: input buffer");
+
+	if(!(mo->buf32bit=(int32_t *)malloc(samplesInput*sizeof(int32_t))))
+		return ERROR_Init("Memory allocation error: 32 bit buffer");
+
+
+	getFaacCfg(&cfg);
+
+	if(cfg.SaveMP4)
+		if(!strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".aac"))
+			strcpy(lpstrFilename+lstrlen(lpstrFilename)-4,".mp4");
+		else
+			if(strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".mp4"))
+				strcat(lpstrFilename,".mp4");
+	mo->WriteMP4=!strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".mp4");
+
+	if(cfg.AutoCfg)
+	{
+	faacEncConfigurationPtr myFormat=&cfg.EncCfg;
+	faacEncConfigurationPtr CurFormat=faacEncGetCurrentConfiguration(mo->hEncoder);
+		if(mo->WriteMP4)
+			CurFormat->outputFormat=RAW;
+		CurFormat->useLfe=wChannels>=6 ? 1 : 0;
+		if(!faacEncSetConfiguration(mo->hEncoder, CurFormat))
+			return ERROR_Init("Unsupported parameters!");
+	}
+	else
+	{
+	faacEncConfigurationPtr myFormat=&cfg.EncCfg;
+	faacEncConfigurationPtr CurFormat=faacEncGetCurrentConfiguration(mo->hEncoder);
+
+		if(cfg.UseQuality)
+		{
+			CurFormat->quantqual=myFormat->quantqual;
+			CurFormat->bitRate=myFormat->bitRate;
+		}
+		else
+			if(!CurFormat->bitRate)
+				CurFormat->bitRate=myFormat->bitRate;
+			else
+				CurFormat->bitRate*=1000;
+
+		switch(CurFormat->bandWidth)
+		{
+		case 0:
+			break;
+		case 0xffffffff:
+			CurFormat->bandWidth=lSamprate/2;
+			break;
+		default:
+			CurFormat->bandWidth=myFormat->bandWidth;
+			break;
+		}
+/*
+		switch(wBitsPerSample)
+		{
+		case 16:
+			CurFormat->inputFormat=FAAC_INPUT_16BIT;
+			break;
+		case 24:
+			CurFormat->inputFormat=FAAC_INPUT_24BIT;
+			break;
+		case 32:
+			CurFormat->inputFormat=FAAC_INPUT_32BIT;
+			break;
+		default:
+			CurFormat->inputFormat=FAAC_INPUT_NULL;
+			break;
+		}
+*/
+		CurFormat->mpegVersion=myFormat->mpegVersion;
+		CurFormat->outputFormat=mo->WriteMP4 ? 0 : myFormat->outputFormat;
+		CurFormat->mpegVersion=myFormat->mpegVersion;
+		CurFormat->aacObjectType=myFormat->aacObjectType;
+		CurFormat->allowMidside=myFormat->allowMidside;
+		CurFormat->useTns=myFormat->useTns;
+		CurFormat->useLfe=wChannels>=6 ? 1 : 0;
+
+		if(!faacEncSetConfiguration(mo->hEncoder, CurFormat))
+			return ERROR_Init("Unsupported parameters!");
+	}
+
+//	mo->src_size=lSize;
+//	mi->dst_name=strdup(lpstrFilename);
+	mo->Samprate=lSamprate;
+	mo->BitsPerSample=wBitsPerSample;
+	mo->Channels=wChannels;
+	mo->samplesInput=samplesInput;
+	mo->samplesInputSize=samplesInput*(mo->BitsPerSample>>3);
+
+	mo->maxBytesOutput=maxBytesOutput;
+
+    if(mo->WriteMP4) // Create MP4 file --------------------------------------------------------------------------
+	{
+    BYTE *ASC=0;
+    DWORD ASCLength=0;
+
+        if((mo->MP4File=MP4Create(lpstrFilename, 0, 0, 0))==MP4_INVALID_FILE_HANDLE)
+			return ERROR_Init("Can't create file");
+        MP4SetTimeScale(mo->MP4File, 90000);
+        mo->MP4track=MP4AddAudioTrack(mo->MP4File, lSamprate, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE);
+        MP4SetAudioProfileLevel(mo->MP4File, 0x0F);
+        faacEncGetDecoderSpecificInfo(mo->hEncoder, &ASC, &ASCLength);
+        MP4SetTrackESConfiguration(mo->MP4File, mo->MP4track, (unsigned __int8 *)ASC, ASCLength);
+		mo->frameSize=samplesInput/wChannels;
+		mo->ofs=mo->frameSize;
+    }
+	else // Create AAC file -----------------------------------------------------------------------------
+	{
+		// open the aac output file 
+		if(!(mo->aacFile=fopen(lpstrFilename, "wb")))
+			return ERROR_Init("Can't create file");
+
+		// use bufferized stream
+		setvbuf(mo->aacFile,NULL,_IOFBF,32767);
+	}
+
+	showInfo(mo);
+
+	GlobalUnlock(hOutput);
+    return hOutput;
+}
+// *********************************************************************************************
+
+int Cfaac::processData(HANDLE hOutput, BYTE *bufIn, DWORD len)
+{
+	if(!hOutput)
+		return -1;
+
+int bytesWritten=0;
+int bytesEncoded;
+MYOUTPUT far *mo;
+
+	GLOBALLOCK(mo,hOutput,MYOUTPUT,return 0);
+
+int32_t *buf=mo->buf32bit;
+
+	if((int)len<mo->samplesInputSize)
+	{
+		mo->samplesInput=(len<<3)/mo->BitsPerSample;
+		mo->samplesInputSize=mo->samplesInput*(mo->BitsPerSample>>3);
+	}
+	To32bit(buf,bufIn,mo->samplesInput,mo->BitsPerSample>>3,false);
+
+	// call the actual encoding routine
+	if((bytesEncoded=faacEncEncode(mo->hEncoder, (int32_t *)buf, mo->samplesInput, mo->bitbuf, mo->maxBytesOutput))<0)
+		return ERROR_processData("faacEncEncode()");
+
+	// write bitstream to aac file 
+	if(mo->aacFile)
+	{
+		if(bytesEncoded>0)
+		{
+			if((bytesWritten=fwrite(mo->bitbuf, 1, bytesEncoded, mo->aacFile))!=bytesEncoded)
+				return ERROR_processData("fwrite");
+			mo->WrittenSamples=1; // needed into destructor
+		}
+	}
+	else
+	// write bitstream to mp4 file
+	{
+	MP4Duration dur,
+				SamplesLeft;
+		if(len>0)
+		{
+			mo->srcSize+=len;
+			dur=mo->frameSize;
+		}
+		else
+		{
+			mo->TotalSamples=(mo->srcSize<<3)/(mo->BitsPerSample*mo->Channels);
+			SamplesLeft=(mo->TotalSamples-mo->WrittenSamples)+mo->frameSize;
+			dur=SamplesLeft>mo->frameSize ? mo->frameSize : SamplesLeft;
+		}
+		if(bytesEncoded>0)
+		{
+			if(!(bytesWritten=MP4WriteSample(mo->MP4File, mo->MP4track, (unsigned __int8 *)mo->bitbuf, (DWORD)bytesEncoded, dur, mo->ofs, true) ? bytesEncoded : -1))
+				return ERROR_processData("MP4WriteSample");
+			mo->ofs=0;
+			mo->WrittenSamples+=dur;
+		}
+	}
+
+	showProgress(mo);
+
+	GlobalUnlock(hOutput);
+	return bytesWritten;
+}
+// -----------------------------------------------------------------------------------------------
+
+int Cfaac::processDataBufferized(HANDLE hOutput, BYTE *bufIn, long lBytes)
+{
+	if(!hOutput)
+		return -1;
+
+int	bytesWritten=0, tot=0;
+MYOUTPUT far *mo;
+
+	GLOBALLOCK(mo,hOutput,MYOUTPUT,return 0);
+
+	if(mo->bytes_into_buffer>=0)
+		do
+		{
+			if(mo->bytes_into_buffer+lBytes<mo->samplesInputSize)
+			{
+				memmove(mo->bufIn+mo->bytes_into_buffer, bufIn, lBytes);
+				mo->bytes_into_buffer+=lBytes;
+				lBytes=0;
+			}
+			else
+			{
+			int	shift=mo->samplesInputSize-mo->bytes_into_buffer;
+				memmove(mo->bufIn+mo->bytes_into_buffer, bufIn, shift);
+				mo->bytes_into_buffer+=shift;
+				bufIn+=shift;
+				lBytes-=shift;
+
+				tot+=bytesWritten=processData(hOutput,mo->bufIn,mo->bytes_into_buffer);
+				if(bytesWritten<0)
+					return ERROR_processData(0);
+				mo->bytes_into_buffer=0;
+			}
+		}while(lBytes);
+
+	GlobalUnlock(hOutput);
+	return tot;
+}
--- /dev/null
+++ b/plugins/winamp/Cfaac.h
@@ -1,0 +1,130 @@
+/*
+FAAC - codec plugin for Cooledit
+Copyright (C) 2004 Antonio Foranna
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation.
+	
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+		
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+			
+The author can be contacted at:
+ntnfrn_email-temp@yahoo.it
+*/
+
+#ifndef _Cfaac_H
+#define _Cfaac_H
+
+// *********************************************************************************************
+
+#include <mp4.h>		// int32_t, ...
+#include <faad.h>		// FAAD2 version
+#ifdef MAIN
+	#undef MAIN
+#endif
+#ifdef SSR
+	#undef SSR
+#endif
+#ifdef LTP
+	#undef LTP
+#endif
+#include <faac.h>
+#include <win32_ver.h>	// mpeg4ip version
+#include "CRegistry.h"
+#include "Defines.h"	// my defines
+
+// *********************************************************************************************
+
+#ifdef	ADTS
+#undef	ADTS
+#define ADTS 1
+#endif
+
+// *********************************************************************************************
+
+typedef struct mec
+{
+bool					AutoCfg,
+						UseQuality,
+						SaveMP4;
+faacEncConfiguration	EncCfg;
+} MY_ENC_CFG;
+// -----------------------------------------------------------------------------------------------
+
+typedef struct output_tag  // any special vars associated with output file
+{
+// MP4
+MP4FileHandle 	MP4File;
+MP4TrackId		MP4track;
+MP4Duration		TotalSamples,
+				WrittenSamples,
+				encoded_samples;
+DWORD			frameSize,
+				ofs;
+
+// AAC
+FILE			*aacFile;
+
+// GLOBAL
+long			Samprate;
+WORD			BitsPerSample;
+WORD			Channels;
+DWORD			srcSize;
+//char			*dst_name;		// name of compressed file
+
+faacEncHandle	hEncoder;
+int32_t			*buf32bit;
+BYTE			*bufIn;
+unsigned char	*bitbuf;
+long			bytes_into_buffer;
+DWORD			maxBytesOutput;
+long			samplesInput,
+				samplesInputSize;
+bool			WriteMP4;
+} MYOUTPUT;
+
+
+
+// *********************************************************************************************
+
+
+
+class Cfaac
+{
+private:
+	virtual void DisplayError(char *ProcName, char *str);
+	virtual HANDLE ERROR_Init(char *str) { DisplayError("Init", str); return NULL; }
+	virtual int ERROR_processData(char *str) { DisplayError("processData", str); return -1; }
+	virtual void showInfo(MYOUTPUT *mi) {}
+	virtual void showProgress(MYOUTPUT *mi) {}
+	virtual void To32bit(int32_t *buf, BYTE *bufi, int size, BYTE samplebytes, BYTE bigendian);
+
+public:
+    Cfaac(HANDLE hOutput=NULL);
+    virtual ~Cfaac();
+
+	static void getFaacCfg(MY_ENC_CFG *cfg);
+	static void setFaacCfg(MY_ENC_CFG *cfg);
+    virtual HANDLE Init(LPSTR lpstrFilename,long lSamprate,WORD wBitsPerSample,WORD wChannels,long FileSize);
+    virtual int processData(HANDLE hOutput, BYTE *bufIn, DWORD len);
+	virtual int processDataBufferized(HANDLE hOutput, BYTE *bufIn, long lBytes);
+/*
+// AAC
+	bool            BlockSeeking;
+
+// GLOBAL
+	long            newpos_ms;
+	BOOL            IsSeekable;
+	MYINPUT			*mi;
+*/
+	HANDLE			hOutput;
+};
+
+#endif
binary files /dev/null b/plugins/winamp/Email.bmp differ
--- a/plugins/winamp/FAAC.rc
+++ b/plugins/winamp/FAAC.rc
@@ -26,11 +26,13 @@
 // Dialog
 //
 
-IDD_ENCODER DIALOG DISCARDABLE  0, 0, 195, 166
+IDD_ENCODER DIALOG DISCARDABLE  0, 0, 195, 167
 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 CAPTION "AAC-MPEG4 options"
 FONT 8, "MS Sans Serif"
 BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,119,148,36,14
+    PUSHBUTTON      "Cancel",IDCANCEL,155,148,36,14
     CONTROL         "Automatic configuration",IDC_CHK_AUTOCFG,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,4,4,90,10
     CONTROL         "MPEG4",IDC_RADIO_MPEG4,"Button",BS_AUTORADIOBUTTON | 
@@ -45,24 +47,19 @@
                     WS_DISABLED,12,97,31,10
     CONTROL         "LTP",IDC_RADIO_LTP,"Button",BS_AUTORADIOBUTTON,12,109,
                     29,10
+    CONTROL         "Raw",IDC_RADIO_RAW,"Button",BS_AUTORADIOBUTTON | 
+                    WS_GROUP,59,30,42,10
+    CONTROL         "ADTS",IDC_RADIO_ADTS,"Button",BS_AUTORADIOBUTTON,59,42,
+                    41,9
     CONTROL         "Allow Mid/Side",IDC_CHK_ALLOWMIDSIDE,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,107,21,63,10
     CONTROL         "Use TNS",IDC_CHK_USETNS,"Button",BS_AUTOCHECKBOX | 
                     WS_TABSTOP,107,34,45,10
+    CONTROL         "Write .mp4",IDC_CHK_WRITEMP4,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,107,46,50,10
     CONTROL         "Use LFE channel",IDC_CHK_USELFE,"Button",
-                    BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,107,47,67,10
-    EDITTEXT        IDC_E_BROWSE,4,128,163,14,ES_AUTOHSCROLL
-    PUSHBUTTON      "Browse",IDC_BTN_BROWSE,173,128,18,14,BS_BITMAP | 
-                    BS_FLAT
-    DEFPUSHBUTTON   "OK",IDOK,119,148,36,14
-    PUSHBUTTON      "Cancel",IDCANCEL,155,148,36,14
-    GROUPBOX        "AAC type",IDC_STATIC,4,18,48,38
-    GROUPBOX        "Profile",IDC_STATIC,4,63,48,59
-    CONTROL         "Raw",IDC_RADIO_RAW,"Button",BS_AUTORADIOBUTTON | 
-                    WS_GROUP,59,30,42,10
-    CONTROL         "ADTS",IDC_RADIO_ADTS,"Button",BS_AUTORADIOBUTTON,59,42,
-                    41,9
-    GROUPBOX        "Header",IDC_STATIC,55,18,48,38
+                    BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | 
+                    WS_TABSTOP,4,152,67,10
     CONTROL         "Quality",IDC_RADIO_QUALITY,"Button",BS_AUTORADIOBUTTON | 
                     WS_GROUP,62,74,37,10
     COMBOBOX        IDC_CB_QUALITY,138,72,48,97,CBS_DROPDOWN | WS_VSCROLL | 
@@ -73,6 +70,12 @@
                     WS_TABSTOP
     COMBOBOX        IDC_CB_BANDWIDTH,138,109,48,81,CBS_DROPDOWN | WS_VSCROLL | 
                     WS_TABSTOP
+    EDITTEXT        IDC_E_BROWSE,4,128,163,14,ES_AUTOHSCROLL
+    PUSHBUTTON      "Browse",IDC_BTN_BROWSE,173,128,18,14,BS_BITMAP | 
+                    BS_FLAT
+    GROUPBOX        "AAC type",IDC_STATIC,4,18,48,38
+    GROUPBOX        "Profile",IDC_STATIC,4,63,48,59
+    GROUPBOX        "Header",IDC_STATIC,55,18,48,38
     LTEXT           "Bandwidth",IDC_STATIC,74,112,34,8
     GROUPBOX        "Encoding mode",IDC_STATIC,56,63,135,42
 END
@@ -117,7 +120,7 @@
         LEFTMARGIN, 4
         RIGHTMARGIN, 191
         TOPMARGIN, 4
-        BOTTOMMARGIN, 161
+        BOTTOMMARGIN, 162
     END
 END
 #endif    // APSTUDIO_INVOKED
@@ -137,10 +140,53 @@
 
 /////////////////////////////////////////////////////////////////////////////
 //
+// Dialog
+//
+
+IDD_ABOUT DIALOG DISCARDABLE  0, 0, 192, 230
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
+CAPTION "About"
+FONT 8, "MS Sans Serif"
+BEGIN
+    DEFPUSHBUTTON   "&OK",IDOK,135,209,50,14
+    CONTROL         107,IDC_AUDIOCODING,"Static",SS_BITMAP | SS_NOTIFY | 
+                    SS_SUNKEN,7,7,178,69
+    CONTROL         110,IDC_MPEG4IP,"Static",SS_BITMAP | SS_NOTIFY | 
+                    SS_SUNKEN,7,204,59,19
+    CONTROL         109,IDC_EMAIL,"Static",SS_BITMAP | SS_NOTIFY,77,205,43,
+                    18
+    LTEXT           "Text",IDC_L_ABOUT,7,55,177,142
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE 
+BEGIN
+    IDD_ABOUT, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 185
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 223
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
 // Bitmap
 //
 
 IDB_BROWSE              BITMAP  DISCARDABLE     "Open.bmp"
+IDB_AUDIOCODING         BITMAP  DISCARDABLE     "AudioCoding.bmp"
+IDB_EMAIL               BITMAP  DISCARDABLE     "Email.bmp"
+IDB_MPEG4IP             BITMAP  DISCARDABLE     "mpeg4ip-v.bmp"
 #endif    // Italian (Italy) resources
 /////////////////////////////////////////////////////////////////////////////
 
binary files a/plugins/winamp/Open.bmp b/plugins/winamp/Open.bmp differ
--- a/plugins/winamp/Out_faac.cpp
+++ b/plugins/winamp/Out_faac.cpp
@@ -1,6 +1,6 @@
 /*
-FAAC - encoder plugin for Winamp 2
-Copyright (C) 2002 Antonio Foranna
+FAAC - codec plugin for Cooledit
+Copyright (C) 2002-2004 Antonio Foranna
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -16,31 +16,25 @@
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 			
 The author can be contacted at:
-kreel@interfree.it
+ntnfrn_email-temp@yahoo.it
 */
 
 #include <windows.h>
 #include <shlobj.h>
-#include <stdio.h>  // FILE *
+#include <stdio.h>		// FILE *
+#include <shellapi.h>	// ShellExecute
 #include "resource.h"
 #include "out.h"
-#include <mp4.h>
+/*#include <mp4.h>
 #include <faac.h>
 #include "CRegistry.h"
 #include "defines.h"
+*/
+#include "defines.h"
+#include "Cfaac.h"
 
-#define RAW  0
-#define ADTS 1
 
-#define FREE(ptr) \
-{ \
-	if(ptr) \
-		free(ptr); \
-	ptr=0; \
-}
 
-
-
 void Config(HWND);
 void About(HWND);
 void Init();
@@ -59,49 +53,13 @@
 
 
 
-typedef struct output_tag  // any special vars associated with output file
-{
-FILE  *aacFile;         
-DWORD lSize;
-long  lSamprate;
-WORD  wBitsPerSample;
-WORD  wChannels;
-// DWORD dwDataOffset;
-//BOOL  bWrittenHeader;
-char  szNAME[256];
+Cfaac			*Cpcmaac;
+char			OutDir[MAX_PATH]="";
 
-faacEncHandle hEncoder;
-int32_t			*buffer;
-unsigned char	*bitbuf;
-DWORD maxBytesOutput;
-long  samplesInput;
-BYTE  bStopEnc;
-
-unsigned char *bufIn;
-DWORD full_size; // size of decoded file needed to set the length of progress bar
-DWORD tagsize;
-DWORD bytes_read;		// from file
-DWORD bytes_consumed;	// by faadDecDecode
-DWORD bytes_into_buffer;
-DWORD bytes_Enc;
-} MYOUTPUT;
-
-
-
-typedef struct mc
-{
-bool					AutoCfg;
-bool					UseQuality;
-faacEncConfiguration	EncCfg;
-char					OutDir[MAX_PATH];
-} MY_ENC_CFG;
-
-
-
-static MYOUTPUT mo0,
-				*mo=&mo0; // this is done to copy'n'paste code from CoolEdit plugin
+HINSTANCE		hInstance=NULL;
 static			HBITMAP hBmBrowse=NULL;
 char			config_AACoutdir[MAX_PATH]="";
+
 static int		srate, numchan, bps;
 volatile int	writtentime, w_offset;
 static int		last_pause=0;
@@ -126,7 +84,7 @@
     SetVolume,
     SetPan,
     Flush,
-    GetWrittenTime,
+    GetOutputTime,
     GetWrittenTime
 };
 
@@ -142,180 +100,160 @@
 }
 // *********************************************************************************************
 
-BOOL WINAPI DllMain (HANDLE hInst, DWORD ulReason, LPVOID lpReserved)
+BOOL WINAPI DllMain (HINSTANCE hInst, DWORD ulReason, LPVOID lpReserved)
 {
-   switch(ulReason)
-   {
-      case DLL_PROCESS_ATTACH:
-           DisableThreadLibraryCalls((struct HINSTANCE__ *)hInst);
-           if(!hBmBrowse)
-            hBmBrowse=LoadBitmap((struct HINSTANCE__ *)hInst, MAKEINTRESOURCE(IDB_BROWSE));
-         /* Code from LibMain inserted here.  Return TRUE to keep the
-            DLL loaded or return FALSE to fail loading the DLL.
- 
-            You may have to modify the code in your original LibMain to
-            account for the fact that it may be called more than once.
-            You will get one DLL_PROCESS_ATTACH for each process that
-            loads the DLL. This is different from LibMain which gets
-            called only once when the DLL is loaded. The only time this
-            is critical is when you are using shared data sections.
-            If you are using shared data sections for statically
-            allocated data, you will need to be careful to initialize it
-            only once. Check your code carefully.
- 
-            Certain one-time initializations may now need to be done for
-            each process that attaches. You may also not need code from
-            your original LibMain because the operating system may now
-            be doing it for you.
-         */
-         break;
- 
-      case DLL_THREAD_ATTACH:
-         /* Called each time a thread is created in a process that has
-            already loaded (attached to) this DLL. Does not get called
-            for each thread that exists in the process before it loaded
-            the DLL.
- 
-            Do thread-specific initialization here.
-         */
-         break;
- 
-      case DLL_THREAD_DETACH:
-         /* Same as above, but called when a thread in the process
-            exits.
- 
-            Do thread-specific cleanup here.
-         */
-         break;
- 
-      case DLL_PROCESS_DETACH:
-           if(hBmBrowse)
-           {
+	switch(ulReason)
+	{
+	case DLL_PROCESS_ATTACH:
+		hInstance=hInst;
+		DisableThreadLibraryCalls((struct HINSTANCE__ *)hInst);
+		if(!hBmBrowse)
+			hBmBrowse=(HBITMAP)LoadImage(hInst,MAKEINTRESOURCE(IDB_BROWSE),IMAGE_BITMAP,0,0,/*LR_CREATEDIBSECTION|*/LR_LOADTRANSPARENT|LR_LOADMAP3DCOLORS);
+		
+		/*	Code from LibMain inserted here.  Return TRUE to keep the
+			DLL loaded or return FALSE to fail loading the DLL.
+
+			You may have to modify the code in your original LibMain to
+			account for the fact that it may be called more than once.
+			You will get one DLL_PROCESS_ATTACH for each process that
+			loads the DLL. This is different from LibMain which gets
+			called only once when the DLL is loaded. The only time this
+			is critical is when you are using shared data sections.
+			If you are using shared data sections for statically
+			allocated data, you will need to be careful to initialize it
+			only once. Check your code carefully.
+
+			Certain one-time initializations may now need to be done for
+			each process that attaches. You may also not need code from
+			your original LibMain because the operating system may now
+			be doing it for you.
+		*/
+		break;
+		
+	case DLL_THREAD_ATTACH:
+		/*	Called each time a thread is created in a process that has
+			already loaded (attached to) this DLL. Does not get called
+			for each thread that exists in the process before it loaded
+			the DLL.
+	
+			Do thread-specific initialization here.
+		*/
+		break;
+		
+	case DLL_THREAD_DETACH:
+		/*	Same as above, but called when a thread in the process
+			exits.
+		
+			Do thread-specific cleanup here.
+		*/
+		break;
+		
+	case DLL_PROCESS_DETACH:
+		hInstance=NULL;
+		if(hBmBrowse)
+		{
             DeleteObject(hBmBrowse);
             hBmBrowse=NULL;
-           }
-         /* Code from _WEP inserted here.  This code may (like the
-            LibMain) not be necessary.  Check to make certain that the
-            operating system is not doing it for you.
-         */
-         break;
-   }
- 
-   /* The return value is only used for DLL_PROCESS_ATTACH; all other
-      conditions are ignored.  */
-   return TRUE;   // successful DLL_PROCESS_ATTACH
+		}
+		/*	Code from _WEP inserted here.  This code may (like the
+			LibMain) not be necessary.  Check to make certain that the
+			operating system is not doing it for you.
+		*/
+		break;
+	}
+	
+	/*	The return value is only used for DLL_PROCESS_ATTACH; all other
+		conditions are ignored.
+	*/
+	return TRUE;   // successful DLL_PROCESS_ATTACH
 }
+
 // *********************************************************************************************
+//										Interface
+// *********************************************************************************************
 
-#define SWAP32(x) (((x & 0xff) << 24) | ((x & 0xff00) << 8) \
-	| ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24))
-#define SWAP16(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
-
-inline void To32bit(int32_t *buf, BYTE *bufi, int size, BYTE samplebytes, BYTE bigendian)
+static BOOL CALLBACK DialogMsgProcAbout(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
 {
-int i;
-
-	switch(samplebytes)
+	switch(Message)
 	{
-	case 1:
-		// this is endian clean
-		for (i = 0; i < size; i++)
-			buf[i] = (bufi[i] - 128) * 65536;
-		break;
-		
-	case 2:
-#ifdef WORDS_BIGENDIAN
-		if (!bigendian)
-#else
-			if (bigendian)
-#endif
-			{
-				// swap bytes
-				for (i = 0; i < size; i++)
-				{
-					int16_t s = ((int16_t *)bufi)[i];
-					
-					s = SWAP16(s);
-					
-					buf[i] = ((u_int32_t)s) << 8;
-				}
-			}
-			else
-			{
-				// no swap
-				for (i = 0; i < size; i++)
-				{
-					int s = ((int16_t *)bufi)[i];
-					
-					buf[i] = s << 8;
-				}
-			}
-			break;
-			
-	case 3:
-		if (!bigendian)
+	case WM_INITDIALOG:
 		{
-			for (i = 0; i < size; i++)
-			{
-				int s = bufi[3 * i] | (bufi[3 * i + 1] << 8) | (bufi[3 * i + 2] << 16);
-				
-				// fix sign
-				if (s & 0x800000)
-					s |= 0xff000000;
-				
-				buf[i] = s;
-			}
+		  char buf[512];
+		  unsigned long samplesInput, maxBytesOutput;
+
+		  faacEncHandle hEncoder =
+		    faacEncOpen(44100, 2, &samplesInput, &maxBytesOutput);
+		  faacEncConfigurationPtr myFormat =
+		    faacEncGetCurrentConfiguration(hEncoder);
+
+			sprintf(buf,
+					APP_NAME " plugin " APP_VER " by Antonio Foranna\n\n"
+					"Engines used:\n"
+					"\tlibfaac v%s\n"
+//					"\tFAAD2 v" FAAD2_VERSION "\n"
+					"\t" PACKAGE " v" VERSION "\n\n"
+					"This code is given with FAAC package and does not contain executables.\n"
+					"This program is free software and can be distributed/modifyed under the terms of the GNU General Public License.\n"
+					"This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.\n\n"
+					"Compiled on %s\n",
+					(myFormat->version == FAAC_CFG_VERSION) ? myFormat->name : " bad version",
+					__DATE__
+					);
+			SetDlgItemText(hWndDlg, IDC_L_ABOUT, buf);
+			faacEncClose(hEncoder);
 		}
-		else // big endian input
+		break;
+	case WM_COMMAND:
+		switch(LOWORD(wParam))
 		{
-			for (i = 0; i < size; i++)
-			{
-				int s = (bufi[3 * i] << 16) | (bufi[3 * i + 1] << 8) | bufi[3 * i + 2];
-				
-				// fix sign
-				if (s & 0x800000)
-					s |= 0xff000000;
-				
-				buf[i] = s;
-			}
+		case IDOK:
+			EndDialog(hWndDlg, TRUE);
+			break;
+        case IDCANCEL:
+			// Ignore data values entered into the controls and dismiss the dialog window returning FALSE
+			EndDialog(hWndDlg, FALSE);
+			break;
+		case IDC_AUDIOCODING:
+			ShellExecute(hWndDlg, NULL, "http://www.audiocoding.com", NULL, NULL, SW_SHOW);
+			break;
+		case IDC_MPEG4IP:
+			ShellExecute(hWndDlg, NULL, "http://www.mpeg4ip.net", NULL, NULL, SW_SHOW);
+			break;
+		case IDC_EMAIL:
+			ShellExecute(hWndDlg, NULL, "mailto:ntnfrn_email-temp@yahoo.it", NULL, NULL, SW_SHOW);
+			break;
 		}
 		break;
-		
-	case 4:		
-#ifdef WORDS_BIGENDIAN
-		if (!bigendian)
-#else
-			if (bigendian)
-#endif
-			{
-				// swap bytes
-				for (i = 0; i < size; i++)
-				{
-					int s = bufi[i];
-					
-					buf[i] = SWAP32(s);
-				}
-			}
-			else
-				memcpy(buf,bufi,size*sizeof(u_int32_t));
-		/*
-		int exponent, mantissa;
-		float *bufo=(float *)buf;
-			
-			for (i = 0; i < size; i++)
-			{
-				exponent=bufi[(i<<2)+3]<<1;
-				if(bufi[i*4+2] & 0x80)
-					exponent|=0x01;
-				exponent-=126;
-				mantissa=(DWORD)bufi[(i<<2)+2]<<16;
-				mantissa|=(DWORD)bufi[(i<<2)+1]<<8;
-				mantissa|=bufi[(i<<2)];
-				bufo[i]=(float)ldexp(mantissa,exponent);
-			}*/
-			break;
+	default: 
+		return FALSE;
 	}
+
+	return TRUE;
 }
+// -----------------------------------------------------------------------------------------------
+
+void About(HWND hWndDlg)
+{
+	DialogBox(out.hDllInstance, MAKEINTRESOURCE(IDD_ABOUT), hWndDlg, DialogMsgProcAbout);
+
+/*char buf[256];
+  unsigned long samplesInput, maxBytesOutput;
+  faacEncHandle hEncoder =
+    faacEncOpen(44100, 2, &samplesInput, &maxBytesOutput);
+  faacEncConfigurationPtr myFormat =
+    faacEncGetCurrentConfiguration(hEncoder);
+
+	sprintf(buf,
+			APP_NAME " %s by Antonio Foranna\n\n"
+			"This plugin uses FAAC encoder engine v%s\n\n"
+			"Compiled on %s\n",
+			 APP_VER,
+			 myFormat->name,
+			 __DATE__
+			 );
+	faacEncClose(hEncoder);
+	MessageBox(hWndDlg, buf, "About", MB_OK);*/
+}
 // *********************************************************************************************
 
 static int CALLBACK WINAPI BrowseCallbackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
@@ -327,53 +265,29 @@
 	}
 	return 0;
 }
+// -----------------------------------------------------------------------------------------------
 
-void ReadCfgEnc(MY_ENC_CFG *cfg) 
+void ReadCfgEnc()
 { 
 CRegistry reg;
 
 	if(reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME))
-	{
-		cfg->AutoCfg=reg.getSetRegDword("Auto",true) ? true : false; 
-		cfg->EncCfg.mpegVersion=reg.getSetRegDword("MPEG version",MPEG2); 
-		cfg->EncCfg.aacObjectType=reg.getSetRegDword("Profile",LOW); 
-		cfg->EncCfg.allowMidside=reg.getSetRegDword("MidSide",true); 
-		cfg->EncCfg.useTns=reg.getSetRegDword("TNS",true); 
-		cfg->EncCfg.useLfe=reg.getSetRegDword("LFE",false);
-		cfg->UseQuality=reg.getSetRegDword("Use quality",false) ? true : false;
-		cfg->EncCfg.quantqual=reg.getSetRegDword("Quality",100); 
-		cfg->EncCfg.bitRate=reg.getSetRegDword("BitRate",128000); 
-		cfg->EncCfg.bandWidth=reg.getSetRegDword("BandWidth",0); 
-		cfg->EncCfg.outputFormat=reg.getSetRegDword("Header",1); 
-		reg.getSetRegStr("OutDir","",cfg->OutDir,MAX_PATH); 
-	}
+		reg.getSetRegStr("OutDir","",OutDir,MAX_PATH); 
 	else
 		MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
 }
 // -----------------------------------------------------------------------------------------------
 
-void WriteCfgEnc(MY_ENC_CFG *cfg) 
+void WriteCfgEnc()
 { 
 CRegistry reg;
 
 	if(reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME))
-	{
-		reg.setRegDword("Auto",cfg->AutoCfg); 
-		reg.setRegDword("MPEG version",cfg->EncCfg.mpegVersion); 
-		reg.setRegDword("Profile",cfg->EncCfg.aacObjectType); 
-		reg.setRegDword("MidSide",cfg->EncCfg.allowMidside); 
-		reg.setRegDword("TNS",cfg->EncCfg.useTns); 
-		reg.setRegDword("LFE",cfg->EncCfg.useLfe); 
-		reg.setRegDword("Use quality",cfg->UseQuality); 
-		reg.setRegDword("Quality",cfg->EncCfg.quantqual); 
-		reg.setRegDword("BitRate",cfg->EncCfg.bitRate); 
-		reg.setRegDword("BandWidth",cfg->EncCfg.bandWidth); 
-		reg.setRegDword("Header",cfg->EncCfg.outputFormat); 
-		reg.setRegStr("OutDir",cfg->OutDir); 
-	}
+		reg.setRegStr("OutDir",OutDir); 
 	else
 		MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
 }
+// -----------------------------------------------------------------------------------------------
 
 #define INIT_CB(hWnd,nID,list,IdSelected) \
 { \
@@ -392,26 +306,32 @@
 	} \
     EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LTP), FALSE); \
 }
+// -----------------------------------------------------------------------------------------------
 
 #define DISABLE_CTRL(Enabled) \
 { \
-		CheckDlgButton(hWndDlg,IDC_CHK_AUTOCFG, !Enabled); \
-        EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_MPEG4), Enabled); \
-        EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_MPEG2), Enabled); \
-        EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_MAIN), Enabled); \
-        EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LOW), Enabled); \
-        EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LTP), Enabled); \
-        EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_RAW), Enabled); \
-        EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_ADTS), Enabled); \
-        EnableWindow(GetDlgItem(hWndDlg, IDC_ALLOWMIDSIDE), Enabled); \
-        EnableWindow(GetDlgItem(hWndDlg, IDC_USETNS), Enabled); \
-        EnableWindow(GetDlgItem(hWndDlg, IDC_CB_BITRATE), Enabled); \
-        EnableWindow(GetDlgItem(hWndDlg, IDC_CB_BANDWIDTH), Enabled); \
-		if(IsDlgButtonChecked(hWndDlg,IDC_RADIO_MPEG4)) \
-			EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LTP), Enabled); \
-		else \
-			DISABLE_LTP \
+	CheckDlgButton(hWndDlg,IDC_CHK_AUTOCFG, !Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_MPEG4), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_MPEG2), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_RAW), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_ADTS), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_CHK_ALLOWMIDSIDE), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_CHK_USETNS), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_CHK_USELFE), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_CB_QUALITY), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_CB_BITRATE), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_CB_BANDWIDTH), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_QUALITY), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_BITRATE), Enabled); \
+    EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_MAIN), Enabled); \
+    EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LOW), Enabled); \
+    EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LTP), Enabled); \
+	if(IsDlgButtonChecked(hWndDlg,IDC_RADIO_MPEG4)) \
+		EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LTP), Enabled); \
+	else \
+		DISABLE_LTP \
 }
+// -----------------------------------------------------------------------------------------------
 
 static BOOL CALLBACK DIALOGMsgProc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
 {
@@ -425,7 +345,8 @@
 		char *BandWidth[]={"Auto","Full","4000","8000","11025","16000","22050","24000","32000","44100","48000",0};
 		MY_ENC_CFG cfg;
 			
-			ReadCfgEnc(&cfg);
+			ReadCfgEnc();
+			Cfaac::getFaacCfg(&cfg);
 			
 			INIT_CB(hWndDlg,IDC_CB_QUALITY,Quality,0);
 			INIT_CB(hWndDlg,IDC_CB_BITRATE,BitRate,0);
@@ -432,9 +353,9 @@
 			INIT_CB(hWndDlg,IDC_CB_BANDWIDTH,BandWidth,0);
 			
 			SendMessage(GetDlgItem(hWndDlg, IDC_BTN_BROWSE), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBmBrowse);
-			if(!*cfg.OutDir)
-				GetCurrentDirectory(MAX_PATH,cfg.OutDir);
-			SetDlgItemText(hWndDlg, IDC_E_BROWSE, cfg.OutDir);
+			if(!*OutDir)
+				GetCurrentDirectory(MAX_PATH,OutDir);
+			SetDlgItemText(hWndDlg, IDC_E_BROWSE, OutDir);
 			
 			if(cfg.EncCfg.mpegVersion==MPEG4)
 				CheckDlgButton(hWndDlg,IDC_RADIO_MPEG4,TRUE);
@@ -515,6 +436,8 @@
 				break;
 			}
 			
+			CheckDlgButton(hWndDlg, IDC_CHK_WRITEMP4, cfg.SaveMP4);
+
 			CheckDlgButton(hWndDlg,IDC_CHK_AUTOCFG, cfg.AutoCfg);
 			
 			DISABLE_CTRL(!cfg.AutoCfg);
@@ -588,9 +511,12 @@
 					cfg.EncCfg.quantqual=GetDlgItemInt(hWndDlg, IDC_CB_QUALITY, 0, FALSE);
 				}
 				cfg.EncCfg.outputFormat=IsDlgButtonChecked(hWndDlg,IDC_RADIO_RAW) ? RAW : ADTS;
-				GetDlgItemText(hWndDlg, IDC_E_BROWSE, cfg.OutDir, MAX_PATH);
+				GetDlgItemText(hWndDlg, IDC_E_BROWSE, OutDir, MAX_PATH);
 				
-				WriteCfgEnc(&cfg);
+				cfg.SaveMP4=IsDlgButtonChecked(hWndDlg, IDC_CHK_WRITEMP4) ? TRUE : FALSE;
+
+				WriteCfgEnc();
+				Cfaac::setFaacCfg(&cfg);
 				EndDialog(hWndDlg, (DWORD)hCfg);
 			}
 			break;
@@ -647,40 +573,11 @@
 	DialogBox(out.hDllInstance, MAKEINTRESOURCE(IDD_ENCODER), hWnd, DIALOGMsgProc);
 //	dwOptions=DialogBoxParam((HINSTANCE)out.hDllInstance,(LPCSTR)MAKEINTRESOURCE(IDD_ENCODER), (HWND)hWnd, (DLGPROC)DIALOGMsgProc, dwOptions);
 }
-// *********************************************************************************************
 
-void About(HWND hwnd)
-{
-char buf[256];
-  unsigned long samplesInput, maxBytesOutput;
-  faacEncHandle hEncoder =
-    faacEncOpen(44100, 2, &samplesInput, &maxBytesOutput);
-  faacEncConfigurationPtr myFormat =
-    faacEncGetCurrentConfiguration(hEncoder);
-
-	sprintf(buf,
-			APP_NAME " %s by Antonio Foranna\n\n"
-			"This plugin uses FAAC encoder engine v%s\n\n"
-			"Compiled on %s\n",
-			 APP_VER,
-			 myFormat->name,
-			 __DATE__
-			 );
-	faacEncClose(hEncoder);
-	MessageBox(hwnd, buf, "About", MB_OK);
-}
 // *********************************************************************************************
-
-void Init()
-{
-}
+//									Utilities
 // *********************************************************************************************
 
-void Quit()
-{
-}
-// *********************************************************************************************
-
 static char *scanstr_back(char *str, char *toscan, char *defval)
 {
 char *s=str+strlen(str)-1;
@@ -753,6 +650,20 @@
 		wsprintf(lpstrFilename,"%s\\%s.aac",config_AACoutdir,temp2);
 }
 
+// *********************************************************************************************
+//									Main functions
+// *********************************************************************************************
+
+void Init()
+{
+}
+// *********************************************************************************************
+
+void Quit()
+{
+}
+// *********************************************************************************************
+
 #define ERROR_O(msg) \
 { \
 	if(msg) \
@@ -763,11 +674,7 @@
 
 int Open(int lSamprate, int wChannels, int wBitsPerSample, int bufferlenms, int prebufferms)
 {
-MY_ENC_CFG			cfg;
-DWORD			maxBytesOutput;
-unsigned long	samplesInput;
-int				bytesEncoded;
-int				tmp;
+MY_ENC_CFG		cfg;
 char			lpstrFilename[MAX_PATH];
 
 	w_offset = writtentime = 0;
@@ -775,81 +682,16 @@
 	srate = lSamprate;
 	bps = wBitsPerSample;
 
-	ReadCfgEnc(&cfg);
+	ReadCfgEnc();
+	Cfaac::getFaacCfg(&cfg);
 
-	strcpy(config_AACoutdir,cfg.OutDir);
+	strcpy(config_AACoutdir,OutDir);
 	GetNewFileName(lpstrFilename);
 
-	memset(mo,0,sizeof(MYOUTPUT));
-	
-	// open the aac output file
-	if(!(mo->aacFile=fopen(lpstrFilename, "wb")))
-		ERROR_O("Can't create file");
-	
-	// use bufferized stream
-	setvbuf(mo->aacFile,NULL,_IOFBF,32767);
+	Cpcmaac=new Cfaac();
+	if(!Cpcmaac->Init(lpstrFilename,lSamprate,wBitsPerSample,wChannels,-1))
+		ERROR_O(0);
 
-	// open the encoder library
-	if(!(mo->hEncoder=faacEncOpen(lSamprate, wChannels, &samplesInput, &maxBytesOutput)))
-		ERROR_O("Can't init library");
-	
-	if(!(mo->bitbuf=(unsigned char*)malloc(maxBytesOutput*sizeof(unsigned char))))
-		ERROR_O("Memory allocation error: output buffer");
-	
-	if(!(mo->bufIn=(unsigned char*)malloc(samplesInput*(wBitsPerSample>>3))))
-		ERROR_O("Memory allocation error: input buffer");
-
-	if(!(mo->buffer=(int32_t *)malloc(samplesInput*sizeof(int32_t))))
-		ERROR_O("Memory allocation error: input buffer");
-	
-//	ReadCfgEnc(&cfg);
-	if(!cfg.AutoCfg)
-	{
-	faacEncConfigurationPtr myFormat=&cfg.EncCfg;
-	faacEncConfigurationPtr CurFormat=faacEncGetCurrentConfiguration(mo->hEncoder);
-		
-		if(cfg.UseQuality)
-		{
-			myFormat->quantqual=cfg.EncCfg.quantqual;
-			myFormat->bitRate=CurFormat->bitRate;
-		}
-		else
-			if(!myFormat->bitRate)
-				myFormat->bitRate=CurFormat->bitRate;
-		
-		switch(myFormat->bandWidth)
-		{
-		case 0:
-			myFormat->bandWidth=CurFormat->bandWidth;
-			break;
-		case 0xffffffff:
-			myFormat->bandWidth=lSamprate/2;
-			break;
-		default: break;
-		}
-		
-		if(!faacEncSetConfiguration(mo->hEncoder, myFormat))
-			ERROR_O("Unsupported parameters");
-	}
-	
-	mo->lSamprate=lSamprate;
-	mo->wBitsPerSample=wBitsPerSample;
-	mo->wChannels=wChannels;
-	strcpy(mo->szNAME,lpstrFilename);
-	
-	mo->maxBytesOutput=maxBytesOutput;
-	mo->samplesInput=samplesInput;
-	mo->bStopEnc=0;
-	
-	// init flushing process
-    bytesEncoded=faacEncEncode(mo->hEncoder, 0, 0, mo->bitbuf, maxBytesOutput); // initializes the flushing process
-    if(bytesEncoded>0)
-	{
-		tmp=fwrite(mo->bitbuf, 1, bytesEncoded, mo->aacFile);
-		if(tmp!=bytesEncoded)
-			ERROR_O("fwrite()");
-	}
-	
 	return 0;
 }
 // *********************************************************************************************
@@ -856,91 +698,22 @@
 
 void Close()
 {
-	if(mo->bytes_into_buffer)
+	if(Cpcmaac)
 	{
-	int bytesEncoded;
-	int32_t *buf=mo->buffer;
-
-		To32bit(buf,mo->bufIn,mo->samplesInput,mo->wBitsPerSample>>3,false);
-
-		// call the actual encoding routine
-		bytesEncoded=faacEncEncode(mo->hEncoder, (int32_t *)buf, mo->samplesInput, mo->bitbuf, mo->maxBytesOutput);
-		if(bytesEncoded>0)
-			fwrite(mo->bitbuf, 1, bytesEncoded, mo->aacFile);
+		delete Cpcmaac;
+		Cpcmaac=NULL;
 	}
-	
-	if(mo->aacFile)
-	{
-		fclose(mo->aacFile);
-		mo->aacFile=0;
-	}
-	
-	if(mo->hEncoder)
-		faacEncClose(mo->hEncoder);
-	
-	FREE(mo->bitbuf)
-	FREE(mo->bufIn)
-	FREE(mo->buffer)
-	
-//	CloseHandle(outfile);
 }
 // *********************************************************************************************
 
-#define ERROR_W(msg) \
-{ \
-	if(msg) \
-		MessageBox(0, msg, "FAAC plugin", MB_OK); \
-    mo->bStopEnc=1; \
-	return -1; \
-}
-
 int Write(char *wabuf, int len)
 {
-int32_t *buf=mo->buffer;
-BYTE	InputSize=mo->wBitsPerSample>>3;
-int bytesWritten;
-int bytesEncoded;
-int shift=0;
+	writtentime+=len;
 
-	writtentime += len;
+	if(Cpcmaac->processDataBufferized(Cpcmaac->hOutput,(BYTE *)wabuf,len)<0)
+		return -1;
 
-	if(!mo->bStopEnc)
-		do
-		{
-			if(mo->bytes_into_buffer+len<mo->samplesInput*InputSize)
-			{
-				memcpy(mo->bufIn+mo->bytes_into_buffer, wabuf, len);
-				mo->bytes_into_buffer+=len;
-				len=0;
-			}
-			else
-			{
-				shift=mo->samplesInput*InputSize-mo->bytes_into_buffer;
-				memcpy(mo->bufIn+mo->bytes_into_buffer, wabuf, shift);
-				mo->bytes_into_buffer+=shift;
-				wabuf+=shift;
-				len-=shift;
-				
-				To32bit(buf,mo->bufIn,mo->samplesInput,InputSize,false);
-
-				// call the actual encoding routine
-				bytesEncoded=faacEncEncode(mo->hEncoder, (int32_t *)buf, mo->samplesInput, mo->bitbuf, mo->maxBytesOutput);
-
-				mo->bytes_into_buffer=0;
-				if(bytesEncoded>0)
-				{
-					// write bitstream to aac file 
-					bytesWritten=fwrite(mo->bitbuf, 1, bytesEncoded, mo->aacFile);
-					if(bytesWritten!=bytesEncoded)
-						ERROR_W("bytesWritten and bytesEncoded are different");
-				}
-				else
-					if(bytesEncoded<0)
-						ERROR_W("faacEncEncode()");
-			}
-		}while(len);
-
-	Sleep(10);
+//	Sleep(10);
 	return 0;
 }
 // *********************************************************************************************
@@ -985,17 +758,38 @@
 	  w_offset=a;
 }
 // *********************************************************************************************
+
+int GetOutputTime()
+{
+int t=srate*numchan,
+	ms=writtentime,
+	l;
+
+	if(t)
+	{
+		l=ms%t;
+		ms /= t;
+		ms *= 1000;
+		ms += (l*1000)/t;
+		if (bps == 16) ms/=2;
+	}
+	return ms + w_offset;
+}
+// *********************************************************************************************
 	
 int GetWrittenTime()
 {
-int t=srate*numchan,l;
-int ms=writtentime;
+int t=srate*numchan,
+	ms=writtentime,
+	l;
 
-	l=ms%t;
-	ms /= t;
-	ms *= 1000;
-	ms += (l*1000)/t;
-	if (bps == 16) ms/=2;
-
+	if(t)
+	{
+		l=ms%t;
+		ms /= t;
+		ms *= 1000;
+		ms += (l*1000)/t;
+		if (bps == 16) ms/=2;
+	}
 	return ms + w_offset;
 }
--- a/plugins/winamp/RESOURCE.H
+++ b/plugins/winamp/RESOURCE.H
@@ -2,10 +2,15 @@
 // Microsoft Developer Studio generated include file.
 // Used by FAAC.rc
 //
+#define IDOK2                           3
 #define IDD_COMPRESSION                 101
 #define IDD_ENCODER                     101
+#define IDD_ABOUT                       102
 #define IDB_LOGO                        104
 #define IDB_BROWSE                      105
+#define IDB_AUDIOCODING                 107
+#define IDB_EMAIL                       109
+#define IDB_MPEG4IP                     110
 #define IDC_RADIO_MPEG4                 1000
 #define IDC_RADIO_MPEG2                 1001
 #define IDC_RADIO_LOW                   1002
@@ -26,7 +31,12 @@
 #define IDC_IMG_LOGO                    1014
 #define IDC_RADIO_RAW                   1014
 #define IDC_BTN_ABOUT                   1015
+#define IDC_L_ABOUT                     1015
 #define IDC_RADIO_ADTS                  1015
+#define IDC_AUDIOCODING                 1016
+#define IDC_CHK_WRITEMP4                1016
+#define IDC_EMAIL                       1017
+#define IDC_MPEG4IP                     1018
 #define IDC_RADIO_BITRATE               1022
 #define IDC_RADIO_QUALITY               1023
 #define IDC_CB_QUALITY                  1024
@@ -35,9 +45,9 @@
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        106
+#define _APS_NEXT_RESOURCE_VALUE        112
 #define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1016
+#define _APS_NEXT_CONTROL_VALUE         1017
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
--- a/plugins/winamp/ReadMe.txt
+++ b/plugins/winamp/ReadMe.txt
@@ -12,7 +12,7 @@
 
 ----------------------------------------------------------------------------
 
-out_AAC is an encoder plugin for Winamp 2.
+out_AAC is an encoder plugin for Winamp 2 and 5.
 
 To use it:
 ----------
@@ -23,4 +23,4 @@
 ----------------------------------------------------------------------------
 
 For suggestions, bugs report, etc., you can contact me at
-kreel@interfree.it
+ntnfrn_email-temp@yahoo.it
--- a/plugins/winamp/defines.h
+++ b/plugins/winamp/defines.h
@@ -1,3 +1,44 @@
-#define APP_NAME "MPEG4-AAC encoder plug-in"
-#define APP_VER "v1.1"
+/*
+FAAC - codec plugin for Cooledit
+Copyright (C) 2002-2004 Antonio Foranna
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation.
+	
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+		
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+			
+The author can be contacted at:
+ntnfrn_email-temp@yahoo.it
+*/
+
+#define APP_NAME "MPEG4-AAC encoder"
+#define APP_VER "v1.3"
 #define REGISTRY_PROGRAM_NAME "SOFTWARE\\4N\\Winamp\\Out_AAC"
+
+// -----------------------------------------------------------------------------------------------
+
+#define FREE_ARRAY(ptr) \
+{ \
+	if(ptr) \
+		free(ptr); \
+	ptr=0; \
+}
+
+// -----------------------------------------------------------------------------------------------
+
+#define GLOBALLOCK(ptr,handle,type,ret) \
+{ \
+	if(!(ptr=(type *)GlobalLock(handle))) \
+	{ \
+		MessageBox(0, "GlobalLock", APP_NAME " plugin", MB_OK|MB_ICONSTOP); \
+		ret; \
+	} \
+}
binary files /dev/null b/plugins/winamp/mpeg4ip-v.bmp differ
--- a/plugins/winamp/out_FAAC.dsp
+++ b/plugins/winamp/out_FAAC.dsp
@@ -25,7 +25,7 @@
 # PROP AllowPerConfigDependencies 0
 # PROP Scc_ProjName ""
 # PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
 MTL=midl.exe
 RSC=rc.exe
 
@@ -51,7 +51,7 @@
 BSC32=bscmake.exe
 # ADD BASE BSC32 /nologo
 # ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/Out_AAC.dll"
 
@@ -69,7 +69,7 @@
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OUT_FAAC_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "../../../faad2/common/mp4v2" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../../faad2/include" /I "../../../faad2/common/faad" /I "../../../faad2/common/mp4v2" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /YX /FD /GZ /c
 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x410 /d "_DEBUG"
@@ -77,9 +77,9 @@
 BSC32=bscmake.exe
 # ADD BASE BSC32 /nologo
 # ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Sound\Gen\Winamp\Plugins\Out_AAC.dll" /pdbtype:sept
+# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Audio\Gen\Winamp\Plugins\Out_AAC.dll" /pdbtype:sept
 
 !ENDIF 
 
@@ -92,6 +92,10 @@
 # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
 # Begin Source File
 
+SOURCE=.\Cfaac.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\CRegistry.cpp
 # End Source File
 # Begin Source File
@@ -112,6 +116,10 @@
 # PROP Default_Filter "h;hpp;hxx;hm;inl"
 # Begin Source File
 
+SOURCE=.\Cfaac.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\CRegistry.h
 # End Source File
 # Begin Source File
@@ -140,7 +148,23 @@
 # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
 # Begin Source File
 
+SOURCE=.\AudioCoding.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Email.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=".\mpeg4ip-v.bmp"
+# End Source File
+# Begin Source File
+
 SOURCE=.\Open.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Open.ico
 # End Source File
 # End Group
 # End Target
--- a/plugins/winamp/out_FAAC.dsw
+++ b/plugins/winamp/out_FAAC.dsw
@@ -3,7 +3,7 @@
 
 ###############################################################################
 
-Project: "Out_FAAC"=.\Out_FAAC.dsp - Package Owner=<4>
+Project: "Out_FAAC"=".\Out_FAAC.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -14,11 +14,26 @@
     Begin Project Dependency
     Project_Dep_Name libfaac
     End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name libmp4v2_st
+    End Project Dependency
 }}}
 
 ###############################################################################
 
-Project: "libfaac"=..\..\libfaac\libfaac.dsp - Package Owner=<4>
+Project: "libfaac"="..\..\libfaac\libfaac.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "libmp4v2_st"="..\..\..\faad2\common\mp4v2\libmp4v2_st60.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{