shithub: aacdec

Download patch

ref: 2108cdfee01328b35c50d8f260870c661d5d2711
parent: 8498be7f35f42ef1d32c4de67428dbf05a6057bf
author: aforanna <aforanna>
date: Mon Oct 25 17:53:54 EDT 2004

no message

binary files /dev/null b/common/Cfaac/AudioCoding.bmp differ
--- /dev/null
+++ b/common/Cfaac/CRegistry.cpp
@@ -1,0 +1,361 @@
+/*
+CRegistry class
+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:
[email protected]
+*/
+
+#include "CRegistry.h"
+
+//************************************************************************************************
+
+CRegistry::CRegistry()
+{
+	regKey=NULL;
+	path=NULL;
+}
+//------------------------------------------------------------------------------------------------
+
+CRegistry::~CRegistry()
+{
+	Close();
+}
+//************************************************************************************************
+/*
+void CRegistry::ShowLastError(char *Caption)
+{
+LPVOID MsgBuf;
+	if(FormatMessage( 
+		FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+		FORMAT_MESSAGE_FROM_SYSTEM | 
+		FORMAT_MESSAGE_IGNORE_INSERTS,
+		NULL,
+		GetLastError(),
+		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+		(LPTSTR) &MsgBuf,
+		0,
+		NULL 
+	))
+		MessageBox(NULL, (LPCTSTR)MsgBuf, Caption, MB_OK|MB_ICONSTOP);
+	if(MsgBuf)
+		LocalFree(MsgBuf);
+}*/
+//************************************************************************************************
+
+#define setPath(SubKey) \
+{ \
+	if(path) \
+		free(path); \
+	path=strdup(SubKey); \
+}
+
+BOOL CRegistry::Open(HKEY hKey, char *SubKey)
+{
+	if(regKey)
+		RegCloseKey(regKey);
+	if(RegOpenKeyEx(hKey, SubKey, 0, KEY_ALL_ACCESS, &regKey)==ERROR_SUCCESS)
+	{
+		setPath(SubKey);
+		return TRUE;
+	}
+	else // can't open the key -> error
+	{
+		regKey=0;
+		setPath("");
+		return FALSE;
+	}
+}
+//************************************************************************************************
+
+BOOL CRegistry::OpenCreate(HKEY hKey, char *SubKey)
+{
+	if(regKey)
+		RegCloseKey(regKey);
+	if(RegOpenKeyEx(hKey, SubKey, 0, KEY_ALL_ACCESS, &regKey)==ERROR_SUCCESS)
+	{
+		setPath(SubKey);
+		return TRUE;
+	}
+	else // open failed -> create the key
+	{
+	DWORD disp;
+		RegCreateKeyEx(hKey, SubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &regKey, &disp);
+		if(disp==REG_CREATED_NEW_KEY) 
+		{
+			setPath(SubKey);
+			return TRUE;
+		}
+		else // can't create the key -> error
+		{
+			regKey=0;
+			setPath("");
+			return FALSE;
+		}
+	}
+}
+//************************************************************************************************
+
+void CRegistry::Close()
+{
+	if(regKey)
+		RegCloseKey(regKey);
+	regKey=NULL;
+	if(path) 
+		free(path); 
+	path=NULL;
+}
+//************************************************************************************************
+//************************************************************************************************
+//************************************************************************************************
+
+void CRegistry::DeleteVal(char *SubKey)
+{
+	RegDeleteValue(regKey,SubKey);
+}
+//************************************************************************************************
+
+void CRegistry::DeleteKey(char *SubKey)
+{
+	RegDeleteKey(regKey,SubKey);
+}
+
+//************************************************************************************************
+//************************************************************************************************
+//************************************************************************************************
+
+void CRegistry::SetBool(char *keyStr, bool val)
+{
+bool tempVal;
+DWORD len=sizeof(bool);
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
+		tempVal!=val)
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, (BYTE *)&val, sizeof(bool));
+}
+//************************************************************************************************
+
+void CRegistry::SetByte(char *keyStr, BYTE val)
+{
+DWORD	t=val;
+DWORD	tempVal;
+DWORD	len;
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
+		tempVal!=val)
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&t, sizeof(DWORD));
+}
+//************************************************************************************************
+
+void CRegistry::SetWord(char *keyStr, WORD val)
+{
+DWORD	t=val;
+DWORD	tempVal;
+DWORD	len;
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
+		tempVal!=val)
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&t, sizeof(DWORD));
+}
+//************************************************************************************************
+
+void CRegistry::SetDword(char *keyStr, DWORD val)
+{
+DWORD tempVal;
+DWORD len;
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
+		tempVal!=val)
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&val, sizeof(DWORD));
+}
+//************************************************************************************************
+
+void CRegistry::SetFloat(char *keyStr, float val)
+{
+float tempVal;
+DWORD len;
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
+		tempVal!=val)
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, (BYTE *)&val, sizeof(float));
+}
+//************************************************************************************************
+
+void CRegistry::SetStr(char *keyStr, char *valStr)
+{
+DWORD len;
+DWORD slen=strlen(valStr)+1;
+
+	if(!valStr || !*valStr)
+		return;
+
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, NULL, &len )!=ERROR_SUCCESS ||
+		len!=slen)
+		RegSetValueEx(regKey, keyStr, 0, REG_SZ, (BYTE *)valStr, slen);
+	else
+	{
+	char *tempVal=new char[slen];
+		if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)tempVal, &len )!=ERROR_SUCCESS ||
+			strcmpi(tempVal,valStr))
+			RegSetValueEx(regKey, keyStr, 0, REG_SZ, (BYTE *)valStr, slen);
+		delete tempVal;
+	}
+}
+//************************************************************************************************
+
+void CRegistry::SetValN(char *keyStr, BYTE *addr,  DWORD size)
+{
+DWORD len;
+	if(!addr || !size)
+		return;
+
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, NULL, &len )!=ERROR_SUCCESS ||
+		len!=size)
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, addr, size);
+	else
+	{
+	BYTE *tempVal=new BYTE[size];
+		if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)tempVal, &len )!=ERROR_SUCCESS ||
+			memcmp(tempVal,addr,len))
+			RegSetValueEx(regKey, keyStr, 0, REG_BINARY, addr, size);
+		delete tempVal;
+	}
+}
+
+
+
+//************************************************************************************************
+//************************************************************************************************
+//************************************************************************************************
+
+
+
+bool CRegistry::GetSetBool(char *keyStr, bool val)
+{
+bool tempVal;
+DWORD len=sizeof(bool);
+
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
+	{
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, (BYTE *)&val, sizeof(bool));
+		return val;
+	}
+	return tempVal;
+}
+//************************************************************************************************
+
+BYTE CRegistry::GetSetByte(char *keyStr, BYTE val)
+{
+DWORD tempVal;
+DWORD len=sizeof(DWORD);
+
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
+	{
+		tempVal=val;
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&tempVal, sizeof(DWORD));
+		return val;
+	}
+	return (BYTE)tempVal;
+}
+//************************************************************************************************
+
+WORD CRegistry::GetSetWord(char *keyStr, WORD val)
+{
+DWORD tempVal;
+DWORD len=sizeof(DWORD);
+
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
+	{
+		tempVal=val;
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&tempVal, sizeof(DWORD));
+		return val;
+	}
+	return (WORD)tempVal;
+}
+//************************************************************************************************
+
+DWORD CRegistry::GetSetDword(char *keyStr, DWORD val)
+{
+DWORD tempVal;
+DWORD len=sizeof(DWORD);
+
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
+	{
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&val, sizeof(DWORD));
+		return val;
+	}
+	return (DWORD)tempVal;
+}
+//************************************************************************************************
+
+float CRegistry::GetSetFloat(char *keyStr, float val)
+{
+float tempVal;
+DWORD len=sizeof(float);
+
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
+	{
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, (BYTE *)&val, sizeof(float));
+		return val;
+	}
+	return tempVal;
+}
+//************************************************************************************************
+
+char *CRegistry::GetSetStr(char *keyStr, char *String)
+{
+long	retVal;
+DWORD	Len;
+char	*dest=NULL;
+	
+	if((retVal=RegQueryValueEx(regKey , keyStr , NULL , NULL, NULL, &Len))==ERROR_SUCCESS)
+		if(dest=(char *)malloc(Len+1))
+			retVal=RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)dest , &Len);
+	if(retVal!=ERROR_SUCCESS)
+	{
+		if(dest)
+			free(dest);
+		if(!String)
+			return NULL;
+
+		Len=strlen(String)+1;
+		if(!(dest=strdup(String)))
+			return NULL;
+		RegSetValueEx(regKey , keyStr , NULL , REG_SZ , (BYTE *)dest , Len);
+	}
+	return dest;
+}
+// -----------------------------------------------------------------------------------------------
+
+int CRegistry::GetSetValN(char *keyStr, BYTE *defData, DWORD defSize, BYTE **dest)
+{
+long	retVal;
+DWORD	size;
+
+	dest=NULL;
+	if((retVal=RegQueryValueEx(regKey , keyStr , NULL , NULL, NULL, &size))==ERROR_SUCCESS)
+		if(*dest=(BYTE *)malloc(size+1))
+			retVal=RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)*dest , &size);
+	if(retVal!=ERROR_SUCCESS)
+	{
+		if(dest)
+			free(dest);
+		if(!defData)
+			return 0;
+
+		size=defSize;
+		if(!(*dest=(BYTE *)malloc(size)))
+			return 0;
+		memcpy(*dest,defData,size);
+		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)*dest , size);
+	}
+	return size;
+}
--- /dev/null
+++ b/common/Cfaac/CRegistry.h
@@ -1,0 +1,64 @@
+/*
+CRegistry class
+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:
[email protected]
+*/
+
+//---------------------------------------------------------------------------
+#ifndef CRegistryH
+#define CRegistryH
+//---------------------------------------------------------------------------
+
+#include <windows.h>
+#include <stdlib.h>
+#include <string.h>
+//#include <memory.h>
+
+class CRegistry 
+{
+public:
+			CRegistry();
+			~CRegistry();
+
+	BOOL	Open(HKEY hKey, char *SubKey);
+	BOOL	OpenCreate(HKEY hKey, char *SubKey);
+	void	Close();
+	void	DeleteVal(char *SubKey);
+	void	DeleteKey(char *SubKey);
+
+	void	SetBool(char *keyStr , bool val);
+	void	SetByte(char *keyStr , BYTE val);
+	void	SetWord(char *keyStr , WORD val);
+	void	SetDword(char *keyStr , DWORD val);
+	void	SetFloat(char *keyStr , float val);
+	void	SetStr(char *keyStr , char *valStr);
+	void	SetValN(char *keyStr , BYTE *addr,  DWORD size);
+
+	bool	GetSetBool(char *keyStr, bool var);
+	BYTE	GetSetByte(char *keyStr, BYTE var);
+	WORD	GetSetWord(char *keyStr, WORD var);
+	DWORD	GetSetDword(char *keyStr, DWORD var);
+	float	GetSetFloat(char *keyStr, float var);
+	char	*GetSetStr(char *keyStr, char *String);
+	int		GetSetValN(char *keyStr, BYTE *defData, DWORD defSize, BYTE **dest);
+
+	HKEY	regKey;
+	char	*path;
+};
+
+#endif
--- /dev/null
+++ b/common/Cfaac/CTag.cpp
@@ -1,0 +1,346 @@
+/*
+CTag - Class to read/write id3v2/mp4 tags
+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:
[email protected]
+*/
+
+#include <stdlib.h>
+#include <mp4.h>
+#include <faac.h>
+#include "CTag.h"
+
+
+
+// *********************************************************************************************
+//										CMP4Tag
+// *********************************************************************************************
+
+CMP4Tag::CMP4Tag()
+{
+//	memset(this,0,sizeof(*this));
+	copyright=NULL;
+	artist=title=album=year=genre=writer=comment=NULL;
+	trackno=ntracks=discno=ndiscs=0;
+	compilation=0;
+	artFilename=NULL;
+	art.pictureType=0; // = other
+	memset(&art,0,sizeof(art));
+}
+// *********************************************************************************************
+
+void CMP4Tag::FreeTag()
+{
+	FREE_ARRAY(artist);
+	FREE_ARRAY(title);
+	FREE_ARRAY(album);
+	FREE_ARRAY(year);
+	FREE_ARRAY(genre);
+	FREE_ARRAY(writer);
+	FREE_ARRAY(comment);
+	FREE_ARRAY(artFilename);
+	FREE_ARRAY(art.data);
+	FREE_ARRAY(art.description);
+	FREE_ARRAY(art.mimeType);
+	FREE_ARRAY(art.format);
+}
+// ***********************************************************************************************
+
+int CMP4Tag::check_image_header(const char *buf)
+{
+	if(!strncmp(buf, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8))
+		return 1; /* PNG */
+	if(!strncmp(buf, "\xFF\xD8\xFF\xE0", 4) &&
+		!strncmp(buf + 6, "JFIF\0",	5))
+		return 2; /* JPEG */
+	if(!strncmp(buf, "GIF87a", 6)	|| !strncmp(buf, "GIF89a", 6))
+		return 3; /* GIF */
+
+	return 0;
+}
+// -----------------------------------------------------------------------------------------------
+
+int CMP4Tag::ReadCoverArtFile(char *pCoverArtFile, char **artData)
+{
+FILE *artFile;
+
+	if(!pCoverArtFile || !*pCoverArtFile)
+		return 0;
+
+	if(!(artFile=fopen(pCoverArtFile, "rb")))
+	{
+	char buf[25+MAX_PATH+1];
+		sprintf(buf,"ReadCoverArtFile: can't open \"%s\"",pCoverArtFile);
+		MessageBox(NULL,buf,NULL,MB_OK);
+		return 0;
+	}
+
+int r;
+char *art;
+int	artSize=0;
+
+	fseek(artFile, 0, SEEK_END);
+	artSize=ftell(artFile);
+	fseek(artFile, 0, SEEK_SET);
+
+	if(!(art=(char *)malloc(artSize)))
+	{
+		fclose(artFile);
+		MessageBox(NULL,"ReadCoverArtFile: Memory allocation error!", NULL, MB_OK);
+		return 0;
+	}
+
+	r=fread(art, 1, artSize, artFile);
+	if(r!=artSize)
+	{
+		free(art);
+		fclose(artFile);
+		MessageBox(NULL,"ReadCoverArtFile: Error reading cover art file!", NULL, MB_OK);
+		return 0;
+	}
+	else
+		if(artSize<12 || !check_image_header(art))
+		{
+			// the above expression checks the image signature
+			free(art);
+			fclose(artFile);
+			MessageBox(NULL,"ReadCoverArtFile: Unsupported cover image file format!", NULL, MB_OK);
+			return 0;
+		}
+
+	FREE_ARRAY(*artData);
+	*artData=art;
+	fclose(artFile);
+	return artSize;
+}
+// *********************************************************************************************
+
+int CMP4Tag::WriteMP4Tag(MP4FileHandle MP4File)
+{
+char	buf[512], *faac_id_string, *faac_copyright_string;
+
+	if(MP4File==NULL)
+	{
+		MessageBox(NULL,"WriteMp4Tag: can't open file!",NULL,MB_OK);
+		return 1;
+	}
+
+	sprintf(buf, "FAAC v%s", (faacEncGetVersion(&faac_id_string, &faac_copyright_string)==FAAC_CFG_VERSION) ? faac_id_string : " wrong libfaac version");
+	MP4SetMetadataTool(MP4File, buf);
+
+	if(artist) MP4SetMetadataArtist(MP4File, artist);
+	if(writer) MP4SetMetadataWriter(MP4File, writer);
+	if(title) MP4SetMetadataName(MP4File, title);
+	if(album) MP4SetMetadataAlbum(MP4File, album);
+	if(trackno>0) MP4SetMetadataTrack(MP4File, trackno, ntracks);
+	if(discno>0) MP4SetMetadataDisk(MP4File, discno, ndiscs);
+	if(compilation) MP4SetMetadataCompilation(MP4File, compilation);
+	if(year) MP4SetMetadataYear(MP4File, year);
+	if(genre) MP4SetMetadataGenre(MP4File, genre);
+	if(comment) MP4SetMetadataComment(MP4File, comment);
+	if(art.size=ReadCoverArtFile(artFilename,&art.data))
+	{
+		MP4SetMetadataCoverArt(MP4File, (unsigned __int8 *)art.data, art.size);
+		FREE_ARRAY(art.data);
+	}
+	return 0;
+}
+// *********************************************************************************************
+
+int CMP4Tag::ReadMp4Tag(char *Filename)						 
+{
+MP4FileHandle MP4File;
+
+	if(!(MP4File=MP4Read(Filename, 0)))
+	{
+	char buf[25+MAX_PATH+1];
+		sprintf(buf,"ReadMp4Tag: can't open \"%s\"",Filename);
+		MessageBox(NULL,buf,NULL,MB_OK);
+		return 1;
+	}
+
+	FREE_ARRAY(copyright);
+	MP4GetMetadataTool(MP4File, &copyright);
+
+	FREE_ARRAY(artist);
+	MP4GetMetadataArtist(MP4File, &artist);
+	FREE_ARRAY(writer);
+	MP4GetMetadataWriter(MP4File, &writer);
+	FREE_ARRAY(title);
+	MP4GetMetadataName(MP4File, &title);
+	FREE_ARRAY(album);
+	MP4GetMetadataAlbum(MP4File, &album);
+	MP4GetMetadataTrack(MP4File, (unsigned __int16 *)&trackno, (unsigned __int16 *)&ntracks);
+	MP4GetMetadataDisk(MP4File, (unsigned __int16 *)&discno, (unsigned __int16 *)&ndiscs);
+	MP4GetMetadataCompilation(MP4File, (unsigned __int8 *)&compilation);
+	FREE_ARRAY(year);
+	MP4GetMetadataYear(MP4File, &year);
+	FREE_ARRAY(genre);
+	MP4GetMetadataGenre(MP4File, &genre);
+	FREE_ARRAY(comment);
+	MP4GetMetadataComment(MP4File, &comment);
+	FREE_ARRAY(art.data);
+	MP4GetMetadataCoverArt(MP4File, (unsigned __int8 **)&art.data, (u_int32_t *)&art.size);
+
+	MP4Close(MP4File);
+/*
+	FILE *f=fopen("D:\\prova.jpg","wb");
+		fwrite(artFile,1,artSize,f);
+		fclose(f);*/
+	return 0;
+}
+// *********************************************************************************************
+
+#define DEL_FIELD(id3Tag,ID3FID) \
+{ \
+ID3_Frame *Frame=id3Tag.Find(ID3FID); \
+	if(Frame!=NULL) \
+		id3Tag.RemoveFrame(Frame); \
+}
+// -----------------------------------------------------------------------------------------------
+
+#define ADD_FIELD(id3Tag,ID3FID,ID3FN,data) \
+{ \
+ID3_Frame *NewFrame=new ID3_Frame(ID3FID); \
+	NewFrame->Field(ID3FN)=data; \
+	DEL_FIELD(id3Tag,ID3FID); \
+	id3Tag.AttachFrame(NewFrame); \
+}
+// -----------------------------------------------------------------------------------------------
+
+int CMP4Tag::WriteAacTag(char *Filename)
+{
+char	buf[512], *faac_id_string, *faac_copyright_string;
+ID3_Tag id3Tag;
+FILE *file;
+
+	if((file=fopen(Filename,"r"))==NULL)
+	{
+	char buf[25+MAX_PATH+1];
+		sprintf(buf,"WriteAacTag: can't open \"%s\"",Filename);
+		MessageBox(NULL,buf,NULL,MB_OK);
+		return 1;
+	}
+	else
+		fclose(file);
+	id3Tag.Link(Filename);
+
+	sprintf(buf, "FAAC v%s", (faacEncGetVersion(&faac_id_string, &faac_copyright_string)==FAAC_CFG_VERSION) ? faac_id_string : " wrong libfaac version");
+	ADD_FIELD(id3Tag,ID3FID_ENCODEDBY,ID3FN_TEXT,buf);
+
+	ADD_FIELD(id3Tag,ID3FID_LEADARTIST,ID3FN_TEXT,artist);
+	ADD_FIELD(id3Tag,ID3FID_COMPOSER,ID3FN_TEXT,writer);
+	ADD_FIELD(id3Tag,ID3FID_TITLE,ID3FN_TEXT,title);
+	ADD_FIELD(id3Tag,ID3FID_ALBUM,ID3FN_TEXT,album);
+	sprintf(buf,"%d",trackno);
+	ADD_FIELD(id3Tag,ID3FID_TRACKNUM,ID3FN_TEXT,buf);
+	ADD_FIELD(id3Tag,ID3FID_YEAR,ID3FN_TEXT,year);
+	ADD_FIELD(id3Tag,ID3FID_CONTENTTYPE,ID3FN_TEXT,genre);
+	ADD_FIELD(id3Tag,ID3FID_COMMENT,ID3FN_TEXT,comment);
+	art.size=ReadCoverArtFile(artFilename,&art.data);
+	if(art.size)
+	{
+	ID3_Frame *NewFrame=new ID3_Frame(ID3FID_PICTURE);
+	char name[_MAX_FNAME], ext[_MAX_EXT];
+		_splitpath(artFilename,NULL,NULL,name,ext);
+
+		NewFrame->Field(ID3FN_DESCRIPTION)=name;
+	char buf[15];
+		sprintf(buf,"image/%s",check_image_header(art.data)==2 ? "jpeg" : strlwr(ext+1));
+		NewFrame->Field(ID3FN_MIMETYPE)=buf;
+//		NewFrame->Field(ID3FN_IMAGEFORMAT)=;
+		NewFrame->Field(ID3FN_PICTURETYPE)=(DWORD)art.pictureType;
+		NewFrame->Field(ID3FN_DATA).Set((BYTE *)art.data,art.size);
+		id3Tag.AttachFrame(NewFrame);
+	}
+
+	// setup all our rendering parameters
+    id3Tag.SetUnsync(false);
+    id3Tag.SetExtendedHeader(true);
+    id3Tag.SetCompression(true);
+    id3Tag.SetPadding(true);
+ 
+	// write any changes to the file
+    id3Tag.Update();
+
+	FREE_ARRAY(art.data);
+	return 0;
+}
+// *********************************************************************************************
+
+#define GET_FIELD_STR(id3Tag,ID3FID,ID3FN,data) \
+{ \
+	Frame=id3Tag.Find(ID3FID); \
+	if(Frame!=NULL) \
+	{ \
+	DWORD size=Frame->Field(ID3FN).Size(); \
+		FREE_ARRAY(data); \
+		if(data=(char *)malloc(size+1)) \
+			Frame->Field(ID3FN).Get(data,size+1); \
+	} \
+	else \
+		FREE_ARRAY(data); \
+}
+// -----------------------------------------------------------------------------------------------
+
+int CMP4Tag::ReadAacTag(char *Filename)
+{
+char	*buf=NULL;
+ID3_Tag id3Tag;
+ID3_Frame *Frame;
+
+	if(!id3Tag.Link(Filename))
+	{
+	char buf[25+MAX_PATH+1];
+		sprintf(buf,"ReadAacTag: can't open \"%s\"",Filename);
+		MessageBox(NULL,buf,NULL,MB_OK);
+		return 1;
+	}
+
+	GET_FIELD_STR(id3Tag,ID3FID_ENCODEDBY,ID3FN_TEXT,copyright);
+
+	GET_FIELD_STR(id3Tag,ID3FID_LEADARTIST,ID3FN_TEXT,artist);
+	GET_FIELD_STR(id3Tag,ID3FID_COMPOSER,ID3FN_TEXT,writer);
+	GET_FIELD_STR(id3Tag,ID3FID_TITLE,ID3FN_TEXT,title);
+	GET_FIELD_STR(id3Tag,ID3FID_ALBUM,ID3FN_TEXT,album);
+
+	GET_FIELD_STR(id3Tag,ID3FID_TRACKNUM,ID3FN_TEXT,buf);
+	if(buf)
+		trackno=atoi(buf);
+	FREE_ARRAY(buf);
+	GET_FIELD_STR(id3Tag,ID3FID_YEAR,ID3FN_TEXT,year);
+	GET_FIELD_STR(id3Tag,ID3FID_CONTENTTYPE,ID3FN_TEXT,genre);
+	GET_FIELD_STR(id3Tag,ID3FID_COMMENT,ID3FN_TEXT,comment);
+
+	if(Frame=id3Tag.Find(ID3FID_PICTURE))
+	{
+		art.size=Frame->Field(ID3FN_DATA).Size();
+		FREE_ARRAY(art.data);
+		if(art.data=(char *)malloc(art.size))
+			memcpy(art.data,Frame->Field(ID3FN_DATA).GetBinary(),art.size);
+
+		GET_FIELD_STR(id3Tag,ID3FID_PICTURE,ID3FN_MIMETYPE,art.mimeType);
+		GET_FIELD_STR(id3Tag,ID3FID_PICTURE,ID3FN_DESCRIPTION,art.description);
+		GET_FIELD_STR(id3Tag,ID3FID_PICTURE,ID3FN_IMAGEFORMAT,art.format);
+		art.pictureType=Frame->Field(ID3FN_PICTURETYPE).Get();
+/*
+	FILE *f=fopen("D:\\prova.jpg","wb");
+		fwrite(artFile,1,artSize,f);
+		fclose(f);*/
+	}
+	return 0;
+}
\ No newline at end of file
--- /dev/null
+++ b/common/Cfaac/CTag.h
@@ -1,0 +1,86 @@
+/*
+CTag - Class to read/write id3v2/mp4 tags
+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:
[email protected]
+*/
+
+#ifndef _CTag_H
+#define _CTag_H
+
+// *********************************************************************************************
+
+#include <mp4.h>
+#include <id3/tag.h>	// id3 tag
+#include "CRegistry.h"
+#include "Defines.h"
+
+// *********************************************************************************************
+
+#define REG_TAGON "Tag On"
+#define REG_TAGIMPORT "Tag import"
+#define REG_ARTIST "Tag Artist"
+#define REG_TITLE "Tag Title"
+#define REG_ALBUM "Tag Album"
+#define REG_YEAR "Tag Year"
+#define REG_GENRE "Tag Genre"
+#define REG_WRITER "Tag Writer"
+#define REG_COMMENT "Tag Comment"
+#define REG_TRACK "Tag Track"
+#define REG_NTRACKS "Tag Tracks"
+#define REG_DISK "Tag Disk"
+#define REG_NDISKS "Tag Disks"
+#define REG_COMPILATION "Tag Compilation"
+#define REG_ARTFILE "Tag Art file"
+
+// *********************************************************************************************
+
+typedef struct
+{
+	char	*data;
+	DWORD	size;
+	DWORD	pictureType; // front, back, icon, ...
+	char	*mimeType, // jpg, png, gif
+			*format, // ???
+			*description; // text description
+} id3Picture;
+
+class CMP4Tag
+{
+private:
+	int check_image_header(const char *buf);
+	int ReadCoverArtFile(char *pCoverArtFile, char **artBuf);
+
+public:
+	CMP4Tag();
+	virtual ~CMP4Tag() { FreeTag(); }
+
+	virtual void FreeTag();
+	virtual int WriteMP4Tag(MP4FileHandle MP4File);
+	virtual int WriteAacTag(char *Filename);
+	virtual int ReadMp4Tag(char *Filename);
+	virtual int ReadAacTag(char *Filename);
+
+	char	*copyright; // used in Cfaad
+	char	*artist, *title, *album, *year, *genre, *writer, *comment;
+	WORD	trackno,ntracks, discno,ndiscs;
+	BYTE	compilation;
+	char	*artFilename;
+	id3Picture art; // used in ReadAacTag(). Remark: field not stored into registry
+};
+
+#endif
\ No newline at end of file
--- /dev/null
+++ b/common/Cfaac/Cfaac.cpp
@@ -1,0 +1,719 @@
+/*
+CFAAC - set of classes to import/export .aac/.mp4 files
+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:
[email protected]
+*/
+
+#include "Cfaac.h"
+
+
+
+// *********************************************************************************************
+//										CMyEncCfg
+// *********************************************************************************************
+
+void CMyEncCfg::getCfg(CMyEncCfg *cfg)
+{ 
+CRegistry reg;
+
+	if(reg.OpenCreate(HKEY_CURRENT_USER, REGISTRY_PROGRAM_NAME "\\FAAC"))
+	{
+		cfg->AutoCfg=reg.GetSetBool(REG_AUTO,DEF_AUTO);
+		cfg->SaveMP4=reg.GetSetByte(REG_WRITEMP4,DEF_WRITEMP4);
+		cfg->EncCfg.mpegVersion=reg.GetSetDword(REG_MPEGVER,DEF_MPEGVER); 
+		cfg->EncCfg.aacObjectType=reg.GetSetDword(REG_PROFILE,DEF_PROFILE); 
+		cfg->EncCfg.allowMidside=reg.GetSetDword(REG_MIDSIDE,DEF_MIDSIDE); 
+		cfg->EncCfg.useTns=reg.GetSetDword(REG_TNS,DEF_TNS); 
+		cfg->EncCfg.useLfe=reg.GetSetDword(REG_LFE,DEF_LFE);
+		cfg->UseQuality=reg.GetSetBool(REG_USEQUALTY,DEF_USEQUALTY);
+		cfg->EncCfg.quantqual=reg.GetSetDword(REG_QUALITY,DEF_QUALITY); 
+		cfg->EncCfg.bitRate=reg.GetSetDword(REG_BITRATE,DEF_BITRATE); 
+		cfg->EncCfg.bandWidth=reg.GetSetDword(REG_BANDWIDTH,DEF_BANDWIDTH); 
+		cfg->EncCfg.outputFormat=reg.GetSetDword(REG_HEADER,DEF_HEADER); 
+
+		FREE_ARRAY(cfg->OutDir);
+		cfg->OutDir=reg.GetSetStr(REG_OutFolder,"");
+
+		cfg->TagOn=reg.GetSetByte(REG_TAGON,0);
+#ifdef USE_IMPORT_TAG
+		cfg->TagImport=reg.GetSetByte(REG_TAGIMPORT,0);
+	#ifdef USE_PATHEXT
+		FREE_ARRAY(cfg->TagSrcPath);
+		FREE_ARRAY(cfg->TagSrcExt);
+		cfg->TagSrcPath=reg.GetSetStr(REG_InFolder,"");
+		cfg->TagSrcExt=reg.GetSetStr(REG_SrcExt,"");
+	#endif
+#endif
+		cfg->Tag.artist=reg.GetSetStr(REG_ARTIST,"");
+		cfg->Tag.title=reg.GetSetStr(REG_TITLE,"");
+		cfg->Tag.album=reg.GetSetStr(REG_ALBUM,"");
+		cfg->Tag.year=reg.GetSetStr(REG_YEAR,"");
+		cfg->Tag.genre=reg.GetSetStr(REG_GENRE,"");
+		cfg->Tag.writer=reg.GetSetStr(REG_WRITER,"");
+		cfg->Tag.comment=reg.GetSetStr(REG_COMMENT,"");
+		cfg->Tag.trackno=reg.GetSetWord(REG_TRACK,0);
+		cfg->Tag.ntracks=reg.GetSetWord(REG_NTRACKS,0);
+		cfg->Tag.discno=reg.GetSetWord(REG_DISK,0);
+		cfg->Tag.ndiscs=reg.GetSetWord(REG_NDISKS,0);
+		cfg->Tag.compilation=reg.GetSetByte(REG_COMPILATION,0);
+		cfg->Tag.artFilename=reg.GetSetStr(REG_ARTFILE,"");
+	}
+	else
+		MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
+}
+// -----------------------------------------------------------------------------------------------
+
+void CMyEncCfg::setCfg(CMyEncCfg *cfg)
+{ 
+CRegistry reg;
+
+	if(reg.OpenCreate(HKEY_CURRENT_USER, REGISTRY_PROGRAM_NAME "\\FAAC"))
+	{
+		reg.SetBool(REG_AUTO,cfg->AutoCfg);
+		reg.SetByte(REG_WRITEMP4,cfg->SaveMP4);
+		reg.SetDword(REG_MPEGVER,cfg->EncCfg.mpegVersion);
+		reg.SetDword(REG_PROFILE,cfg->EncCfg.aacObjectType);
+		reg.SetDword(REG_MIDSIDE,cfg->EncCfg.allowMidside);
+		reg.SetDword(REG_TNS,cfg->EncCfg.useTns);
+		reg.SetDword(REG_LFE,cfg->EncCfg.useLfe);
+		reg.SetBool(REG_USEQUALTY,cfg->UseQuality);
+		reg.SetDword(REG_QUALITY,cfg->EncCfg.quantqual);
+		reg.SetDword(REG_BITRATE,cfg->EncCfg.bitRate);
+		reg.SetDword(REG_BANDWIDTH,cfg->EncCfg.bandWidth);
+		reg.SetDword(REG_HEADER,cfg->EncCfg.outputFormat);
+
+		reg.SetStr(REG_OutFolder,cfg->OutDir);
+
+		reg.SetByte(REG_TAGON,cfg->TagOn);
+#ifdef USE_IMPORT_TAG
+		reg.SetByte(REG_TAGIMPORT,cfg->TagImport);
+	#ifdef USE_PATHEXT
+		reg.SetStr(REG_InFolder,cfg->TagSrcPath);
+		reg.SetStr(REG_SrcExt,cfg->TagSrcExt);
+	#endif
+#endif
+		reg.SetStr(REG_ARTIST,cfg->Tag.artist);
+		reg.SetStr(REG_TITLE,cfg->Tag.title);
+		reg.SetStr(REG_ALBUM,cfg->Tag.album);
+		reg.SetStr(REG_YEAR,cfg->Tag.year);
+		reg.SetStr(REG_GENRE,cfg->Tag.genre);
+		reg.SetStr(REG_WRITER,cfg->Tag.writer);
+		reg.SetStr(REG_COMMENT,cfg->Tag.comment);
+		reg.SetWord(REG_TRACK,cfg->Tag.trackno);
+		reg.SetWord(REG_NTRACKS,cfg->Tag.ntracks);
+		reg.SetWord(REG_DISK,cfg->Tag.discno);
+		reg.SetWord(REG_NDISKS,cfg->Tag.ndiscs);
+		reg.SetByte(REG_COMPILATION,cfg->Tag.compilation);
+		reg.SetStr(REG_ARTFILE,cfg->Tag.artFilename);
+	}
+	else
+		MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
+}
+
+// *********************************************************************************************
+//											Cfaac
+// *********************************************************************************************
+
+
+
+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); \
+		return;
+	}
+//	dontAskGetFilename=false;
+}
+// -----------------------------------------------------------------------------------------------
+
+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;
+
+	CMyEncCfg cfg(false);
+		if(cfg.TagOn && mo->OutFilename)
+		{
+		int error=0;
+#ifdef USE_IMPORT_TAG
+			if(cfg.TagImport && mo->InFilename)
+			{
+			int l=strlen(mo->InFilename);
+				if(	!strcmpi(mo->InFilename+l-4,".mp4") ||
+					!strcmpi(mo->InFilename+l-4,".m4a") ||
+					!strcmpi(mo->InFilename+l-4,".m4b"))
+					error=cfg.Tag.ReadMp4Tag(mo->InFilename);
+				else
+					error=cfg.Tag.ReadAacTag(mo->InFilename);
+			}
+#endif
+			if(!error)
+				cfg.Tag.WriteAacTag(mo->OutFilename);
+		}
+	}
+	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)
+
+	FREE_ARRAY(mo->OutFilename)
+	FREE_ARRAY(mo->InFilename)
+
+	GlobalUnlock(hOutput);
+	GlobalFree(hOutput);
+}
+
+// *********************************************************************************************
+//									Utilities
+// *********************************************************************************************
+
+char *Cfaac::getSourceFilename(char *path, char *src, char *ext)
+{
+char	*dst, chExt,
+		*pname, *pext;
+
+
+	if(!src)
+		return NULL;
+	if(!path)
+		path="";
+	if(!ext)
+		ext="";
+	pname=pext=src+strlen(src);
+
+	while(pname!=src && *pname!='\\' && *pname!='/')
+		pname--;
+	if(*pname=='\\' || *pname=='/')
+		pname++;
+	while(pext!=src && *pext!='.')
+		pext--;
+	chExt=*pext;
+	if(chExt=='.')
+		*pext='\0';
+
+	if(*path)
+	{
+	int l;
+		if(!(dst=(char *)malloc(strlen(path)+strlen(pname)+strlen(ext)+3))) // '\0','\\','.'
+			return dst;
+		l=strlen(path);
+		if(l>0 && path[l-1]=='\\')
+			sprintf(dst,"%s%s.%s",path,pname,ext);
+		else
+			sprintf(dst,"%s\\%s.%s",path,pname,ext);
+	}
+	else
+	{
+		if(!(dst=(char *)malloc(strlen(pname)+strlen(ext)+2)))
+			return dst;
+		sprintf(dst,"%s.%s",pname,ext);
+	}
+	*pext=chExt;
+
+	if(!strcmpi(src,dst))
+	{
+//		if(!dontAskGetFilename)
+		{
+		char buf[MAX_PATH+100];
+			sprintf(buf,"%s\nSource file=Destination file...aborting!\n\n\tSuppress this warning?",dst);
+//			if(MessageBox(NULL,buf,NULL,MB_YESNO)==IDYES)
+//				dontAskGetFilename=true;
+		}
+		FREE_ARRAY(dst);
+		return NULL;
+	}
+
+	return dst;
+}
+// *********************************************************************************************
+
+#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);
+}
+// *********************************************************************************************
+
+HANDLE Cfaac::Init(LPSTR InFileName, LPSTR OutFileName,long lSamprate,WORD wBitsPerSample,WORD wChannels,long FileSize)
+{
+MYOUTPUT	*mo;
+CMyEncCfg	cfg(false);
+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");
+
+	if(cfg.SaveMP4)// || cfg.Tag.On)
+	{
+	int ExtPos=0, // append new ext
+		fnLen=lstrlen(OutFileName);
+//		if(OutFileName[lstrlen(OutFileName)-4]=='.')
+		if(	fnLen>=4 &&
+			(!strcmpi(OutFileName+fnLen-4,".aac") ||
+			!strcmpi(OutFileName+fnLen-4,".mp4") ||
+			!strcmpi(OutFileName+fnLen-4,".m4a") ||
+			!strcmpi(OutFileName+fnLen-4,".m4b"))) // no aac/mp4 ext => append new ext
+			if(	(cfg.SaveMP4==1 && strcmpi(OutFileName+fnLen-4,".mp4")) ||
+				(cfg.SaveMP4==2 && strcmpi(OutFileName+fnLen-4,".m4a")) ||
+				(cfg.SaveMP4==3 && strcmpi(OutFileName+fnLen-4,".m4b")))
+				ExtPos=4; // wrong ext => replace it
+			else
+				ExtPos=-1; // correct ext => no action
+		if(ExtPos!=-1)
+		{
+			switch(cfg.SaveMP4)
+			{
+			case 1:	strcpy(OutFileName+fnLen-ExtPos,".mp4"); break;
+			case 2: strcpy(OutFileName+fnLen-ExtPos,".m4a"); break;
+			case 3: strcpy(OutFileName+fnLen-ExtPos,".m4b"); break;
+			}
+		FILE *f=fopen(OutFileName,"rb");
+			if(f)
+			{
+			char buf[MAX_PATH+20];
+				sprintf(buf,"Overwrite \"%s\" ?",OutFileName);
+				fclose(f);
+				if(MessageBox(NULL,buf,"File already exists!",MB_YESNO|MB_ICONQUESTION)==IDNO)
+					return ERROR_Init(0);//"User abort");
+			}
+		}
+	}
+	mo->WriteMP4=	!strcmpi(OutFileName+lstrlen(OutFileName)-4,".mp4") ||
+					!strcmpi(OutFileName+lstrlen(OutFileName)-4,".m4a") ||
+					!strcmpi(OutFileName+lstrlen(OutFileName)-4,".m4b");
+
+faacEncConfigurationPtr CurFormat=faacEncGetCurrentConfiguration(mo->hEncoder);
+	CurFormat->inputFormat=FAAC_INPUT_32BIT;
+/*	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;
+	}*/
+	if(!cfg.AutoCfg)
+	{
+	faacEncConfigurationPtr myFormat=&cfg.EncCfg;
+
+		if(cfg.UseQuality)
+		{
+			CurFormat->quantqual=myFormat->quantqual;
+			CurFormat->bitRate=0;//myFormat->bitRate;
+		}
+		else
+		{
+			CurFormat->bitRate=(myFormat->bitRate*1000)/wChannels;
+			CurFormat->quantqual=100;
+		}
+
+		switch(CurFormat->bandWidth)
+		{
+		case 0: // Auto
+			break;
+		case 0xffffffff: // Full
+			CurFormat->bandWidth=lSamprate/2;
+			break;
+		default:
+			CurFormat->bandWidth=myFormat->bandWidth;
+			break;
+		}
+		CurFormat->mpegVersion=myFormat->mpegVersion;
+		CurFormat->outputFormat=myFormat->outputFormat;
+		CurFormat->mpegVersion=myFormat->mpegVersion;
+		CurFormat->aacObjectType=myFormat->aacObjectType;
+		CurFormat->allowMidside=myFormat->allowMidside;
+//		CurFormat->useTns=myFormat->useTns;
+		CurFormat->useTns=false;
+	}
+	else
+	{
+		CurFormat->mpegVersion=DEF_MPEGVER;
+		CurFormat->aacObjectType=DEF_PROFILE;
+		CurFormat->allowMidside=DEF_MIDSIDE;
+//		CurFormat->useTns=DEF_TNS;
+		CurFormat->useTns=false;
+		CurFormat->useLfe=DEF_LFE;
+		CurFormat->quantqual=DEF_QUALITY;
+		CurFormat->bitRate=DEF_BITRATE;
+		CurFormat->bandWidth=DEF_BANDWIDTH;
+		CurFormat->outputFormat=DEF_HEADER;
+	}
+	if(mo->WriteMP4)
+		CurFormat->outputFormat=RAW;
+	CurFormat->useLfe=wChannels>=6 ? 1 : 0;
+	if(!faacEncSetConfiguration(mo->hEncoder, CurFormat))
+		return ERROR_Init("Unsupported parameters!");
+
+//	mo->src_size=lSize;
+//	mi->dst_name=strdup(OutFileName);
+	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(OutFileName, 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;
+
+		if(cfg.TagOn)
+		{
+		int error=0;
+#ifdef USE_IMPORT_TAG
+			if(cfg.TagImport && InFileName)
+			{
+			int l=strlen(InFileName);
+				if(	!strcmpi(InFileName+l-4,".mp4") ||
+					!strcmpi(InFileName+l-4,".m4a") ||
+					!strcmpi(InFileName+l-4,".m4b"))
+					error=cfg.Tag.ReadMp4Tag(InFileName);
+				else
+					error=cfg.Tag.ReadAacTag(InFileName);
+			}
+#endif
+			if(!error)
+				cfg.Tag.WriteMP4Tag(mo->MP4File);
+		}
+	}
+	else // Create AAC file -----------------------------------------------------------------------------
+	{
+		// open the aac output file 
+		if(!(mo->aacFile=fopen(OutFileName, "wb")))
+			return ERROR_Init("Can't create file");
+
+		// use bufferized stream
+		setvbuf(mo->aacFile,NULL,_IOFBF,32767);
+
+		mo->InFilename=strdup(InFileName);
+		mo->OutFilename=strdup(OutFileName);
+	}
+
+	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);
+	}
+//	if(mo->BitsPerSample==8 || mo->BitsPerSample==32)
+		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("Write failed!");
+			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/common/Cfaac/Cfaac.h
@@ -1,0 +1,184 @@
+/*
+CFAAC - set of classes to import/export .aac/.mp4 files
+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:
[email protected]
+*/
+
+#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 "CTag.h"
+#include "Defines.h"	// my defines
+
+// *********************************************************************************************
+
+#ifdef	ADTS
+#undef	ADTS
+#define ADTS 1
+#endif
+
+// *********************************************************************************************
+
+#define REG_AUTO "Auto"
+#define DEF_AUTO true
+#define REG_WRITEMP4 "Write MP4"
+#define DEF_WRITEMP4 0
+#define REG_MPEGVER "MPEG version"
+#define DEF_MPEGVER MPEG4
+#define REG_PROFILE "Profile"
+#define DEF_PROFILE LOW
+#define REG_MIDSIDE "MidSide"
+#define DEF_MIDSIDE true
+#define REG_TNS "TNS"
+#define DEF_TNS true
+#define REG_LFE "LFE"
+#define DEF_LFE false
+#define REG_USEQUALTY "Use quality"
+#define DEF_USEQUALTY true
+#define REG_QUALITY "Quality"
+#define DEF_QUALITY 100
+#define REG_BITRATE "BitRate"
+#define DEF_BITRATE 0 /* quality on */
+#define REG_BANDWIDTH "BandWidth"
+#define DEF_BANDWIDTH 0
+#define REG_HEADER "Header"
+#define DEF_HEADER ADTS
+
+#define REG_OutFolder "Output folder"
+#define REG_InFolder "Source folder"
+#define REG_SrcExt "Source extensions"
+
+// *********************************************************************************************
+
+class CMyEncCfg
+{
+private:
+
+	bool SaveCfgOnDestroy;
+
+public:
+
+	CMyEncCfg(bool SaveOnDestroy=true) { OutDir=TagSrcPath=TagSrcExt=NULL; getCfg(this); SaveCfgOnDestroy=SaveOnDestroy; }
+	virtual ~CMyEncCfg() { if(SaveCfgOnDestroy) setCfg(this); FreeCfg(this); }
+
+	void FreeCfg(CMyEncCfg *cfg) { Tag.FreeTag(); FREE_ARRAY(OutDir); FREE_ARRAY(TagSrcPath); FREE_ARRAY(TagSrcExt); }
+	void getCfg(CMyEncCfg *cfg);
+	void setCfg(CMyEncCfg *cfg);
+
+	bool					AutoCfg,
+							UseQuality;
+	BYTE					SaveMP4;
+	char					*OutDir;
+	faacEncConfiguration	EncCfg;
+	CMP4Tag					Tag;
+	BYTE					TagOn;
+	BYTE					TagImport;
+	char					*TagSrcPath,
+							*TagSrcExt;
+};
+// -----------------------------------------------------------------------------------------------
+
+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;
+char			*InFilename,
+				*OutFilename;
+
+// 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) {}
+	void To32bit(int32_t *buf, BYTE *bufi, int size, BYTE samplebytes, BYTE bigendian);
+
+public:
+    Cfaac(HANDLE hOutput=NULL);
+    virtual ~Cfaac();
+
+	virtual char *getSourceFilename(char *path, char *src, char *ext);
+
+	virtual HANDLE Init(LPSTR InFilename,LPSTR OutFilename,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;
+//	bool			dontAskGetFilename;
+};
+
+#endif
--- /dev/null
+++ b/common/Cfaac/Cfaad.cpp
@@ -1,0 +1,807 @@
+/*
+CFAAC - set of classes to import/export .aac/.mp4 files
+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:
[email protected]
+*/
+
+#include "Cfaad.h"
+
+
+
+// *********************************************************************************************
+
+
+
+Cfaad::Cfaad(HANDLE hIn)
+{
+	ShowDlg4RawAAC=NULL;
+	pCfg=NULL;
+
+	if(hIn)
+	{
+		hInput=hIn;
+		return;
+	}
+
+MYINPUT *mi;
+
+	if(!(hInput=GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE|GMEM_ZEROINIT,sizeof(MYINPUT))))
+		MessageBox(0, "Memory allocation error: hInput", APP_NAME " plugin", MB_OK|MB_ICONSTOP); \
+	if(!(mi=(MYINPUT *)GlobalLock(hInput)))
+		MessageBox(0, "GlobalLock(hInput)", APP_NAME " plugin", MB_OK|MB_ICONSTOP); \
+/*
+	mi->mp4File=0;
+	mi->aacFile=0;
+    mi->hDecoder=0;
+    mi->buffer=0;
+	mi->bytes_read=0;*/
+	mi->BitsPerSample=16;
+	mi->FindBitrate=FALSE;
+	newpos_ms=-1;
+	mi->seek_table=NULL;
+	mi->seek_table_length=0;
+	mi->LockSeeking=false;
+	GlobalUnlock(hInput);
+}
+// -----------------------------------------------------------------------------------------------
+
+Cfaad::~Cfaad()
+{
+MYINPUT *mi;
+
+	if(!hInput)
+		return;
+
+	GLOBALLOCK(mi,hInput,MYINPUT,return);
+
+	if(mi->mp4File)
+		MP4Close(mi->mp4File);
+	if(mi->aacFile)
+		fclose(mi->aacFile);
+	if(mi->hDecoder)
+		faacDecClose(mi->hDecoder);
+	FREE_ARRAY(mi->buffer);
+	FREE_ARRAY(mi->seek_table);
+
+	GlobalUnlock(hInput);
+	GlobalFree(hInput);
+}
+
+// *********************************************************************************************
+//									Utilities
+// *********************************************************************************************
+
+int Cfaad::GetAACTrack(MP4FileHandle infile)
+{
+// find AAC track
+int i, rc;
+int numTracks = MP4GetNumberOfTracks(infile, NULL, 0);
+
+	for (i = 0; i < numTracks; i++)
+    {
+    MP4TrackId trackId = MP4FindTrackId(infile, i, NULL, 0);
+    const char* trackType = MP4GetTrackType(infile, trackId);
+
+        if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE))
+        {
+        unsigned char *buff = NULL;
+        unsigned __int32 buff_size = 0;
+        mp4AudioSpecificConfig mp4ASC;
+
+			MP4GetTrackESConfiguration(infile, trackId, (unsigned __int8 **)&buff, &buff_size);
+
+            if (buff)
+            {
+                rc = AudioSpecificConfig(buff, buff_size, &mp4ASC);
+                free(buff);
+
+                if (rc < 0)
+                    return -1;
+                return trackId;
+            }
+        }
+    }
+
+    // can't decode this
+    return -1;
+}
+// *********************************************************************************************
+
+int Cfaad::IsMP4(LPSTR lpstrFilename)
+{
+DWORD	mp4file = 0;
+FILE	*hMP4File = fopen(lpstrFilename, "rb");
+BYTE	header[8];
+    if(!hMP4File)
+		return -1;
+    fread(header, 1, 8, hMP4File);
+    fclose(hMP4File);
+    if(header[4]=='f' && header[5]=='t' && header[6]=='y' && header[7]=='p')
+		return 1;
+
+	return 0;
+}
+// *********************************************************************************************
+long Cfaad::id3v2_TagSize(unsigned char *buffer)
+{
+	if(StringComp((const char *)buffer, "ID3", 3) == 0)
+	{
+	unsigned long tagsize;
+
+	// high bit is not used
+		tagsize =	(buffer[6] << 21) | (buffer[7] << 14) |
+					(buffer[8] <<  7) | (buffer[9] <<  0);
+		tagsize += 10;
+		return tagsize;
+	}
+	return 0;
+}
+/*
+long Cfaad::id3v2_TagSize(aac_buffer *b)
+{
+DWORD    tagsize = 0;
+    if (!memcmp(b->buffer, "ID3", 3))
+    {
+        // high bit is not used
+        tagsize = (b->buffer[6] << 21) | (b->buffer[7] << 14) |
+            (b->buffer[8] <<  7) | (b->buffer[9] <<  0);
+
+        tagsize += 10;
+        advance_buffer(b, tagsize);
+        fill_buffer(b);
+    }
+	return tagsize;
+}
+// *********************************************************************************************
+
+int Cfaad::fill_buffer(aac_buffer *b)
+{
+    int bread;
+
+    if (b->bytes_consumed > 0)
+    {
+        if (b->bytes_into_buffer)
+        {
+            memmove((void*)b->buffer, (void*)(b->buffer + b->bytes_consumed),
+                b->bytes_into_buffer*sizeof(unsigned char));
+        }
+
+        if (!b->at_eof)
+        {
+            bread = fread((void*)(b->buffer + b->bytes_into_buffer), 1,
+                b->bytes_consumed, b->infile);
+
+            if (bread != b->bytes_consumed)
+                b->at_eof = 1;
+
+            b->bytes_into_buffer += bread;
+        }
+
+        b->bytes_consumed = 0;
+
+        if (b->bytes_into_buffer > 3)
+        {
+            if (memcmp(b->buffer, "TAG", 3) == 0)
+                b->bytes_into_buffer = 0;
+        }
+        if (b->bytes_into_buffer > 11)
+        {
+            if (memcmp(b->buffer, "LYRICSBEGIN", 11) == 0)
+                b->bytes_into_buffer = 0;
+        }
+        if (b->bytes_into_buffer > 8)
+        {
+            if (memcmp(b->buffer, "APETAGEX", 8) == 0)
+                b->bytes_into_buffer = 0;
+        }
+    }
+
+    return 1;
+}
+// *********************************************************************************************
+
+void Cfaad::advance_buffer(aac_buffer *b, int bytes)
+{
+    b->file_offset += bytes;
+    b->bytes_consumed = bytes;
+    b->bytes_into_buffer -= bytes;
+}
+// *********************************************************************************************
+
+static int adts_sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0};
+
+int Cfaad::adts_parse(aac_buffer *b, int *bitrate, float *length)
+{
+    int frames, frame_length;
+    int t_framelength = 0;
+    int samplerate;
+    float frames_per_sec, bytes_per_frame;
+
+    // Read all frames to ensure correct time and bitrate
+    for (frames = 0; ; frames++)
+    {
+        fill_buffer(b);
+
+        if (b->bytes_into_buffer > 7)
+        {
+            // check syncword 
+            if (!((b->buffer[0] == 0xFF)&&((b->buffer[1] & 0xF6) == 0xF0)))
+                break;
+
+            if (frames == 0)
+                samplerate = adts_sample_rates[(b->buffer[2]&0x3c)>>2];
+
+            frame_length = ((((unsigned int)b->buffer[3] & 0x3)) << 11)
+                | (((unsigned int)b->buffer[4]) << 3) | (b->buffer[5] >> 5);
+
+            t_framelength += frame_length;
+
+            if (frame_length > b->bytes_into_buffer)
+                break;
+
+            advance_buffer(b, frame_length);
+        } else {
+            break;
+        }
+    }
+
+    frames_per_sec = (float)samplerate/1024.0f;
+    if (frames != 0)
+        bytes_per_frame = (float)t_framelength/(float)(frames*1000);
+    else
+        bytes_per_frame = 0;
+    *bitrate = (int)(8. * bytes_per_frame * frames_per_sec + 0.5);
+    if (frames_per_sec != 0)
+        *length = (float)frames/frames_per_sec;
+    else
+        *length = 1;
+
+    return 1;
+}
+// *********************************************************************************************
+
+// get AAC infos for printing 
+void Cfaad::GetAACInfos(aac_buffer *b, DWORD *header_type, float *song_length, int *pbitrate, long filesize)
+{
+int		bitrate=0;
+float	length=0;
+int		bread;
+long	tagsize=id3v2_TagSize(b);
+
+	*header_type = 0;
+	b->file_offset=tagsize;
+
+    if ((b->buffer[0] == 0xFF) && ((b->buffer[1] & 0xF6) == 0xF0))
+    {
+        adts_parse(b, &bitrate, &length);
+        fseek(b->infile, tagsize, SEEK_SET);
+
+        bread = fread(b->buffer, 1, FAAD_MIN_STREAMSIZE*MAX_CHANNELS, b->infile);
+        if (bread != FAAD_MIN_STREAMSIZE*MAX_CHANNELS)
+            b->at_eof = 1;
+        else
+            b->at_eof = 0;
+        b->bytes_into_buffer = bread;
+        b->bytes_consumed = 0;
+        b->file_offset = tagsize;
+
+        *header_type = 1;
+    } else if (memcmp(b->buffer, "ADIF", 4) == 0) {
+        int skip_size = (b->buffer[4] & 0x80) ? 9 : 0;
+        bitrate = ((unsigned int)(b->buffer[4 + skip_size] & 0x0F)<<19) |
+            ((unsigned int)b->buffer[5 + skip_size]<<11) |
+            ((unsigned int)b->buffer[6 + skip_size]<<3) |
+            ((unsigned int)b->buffer[7 + skip_size] & 0xE0);
+
+        length = (float)filesize;
+        if (length != 0)
+        {
+            length = ((float)length*8.f)/((float)bitrate) + 0.5f;
+        }
+
+        bitrate = (int)((float)bitrate/1000.0f + 0.5f);
+
+        *header_type = 2;
+    }
+
+    *song_length = length;
+	*pbitrate=bitrate;
+}
+
+void Cfaad::GetAACInfos(char *Filename, aac_buffer *b, DWORD *header_type, float *song_length, int *pbitrate)
+{
+	if(!(b->infile=fopen(Filename,"rb")))
+	{
+		MessageBox(NULL,"Error opening file",NULL,MB_OK);
+		return;
+	}
+	fseek(b->infile, 0, SEEK_END);
+long	src_size=ftell(b->infile);
+	fseek(b->infile, 0, SEEK_SET);
+	if(!(b->buffer=(BYTE *)malloc(FAAD_STREAMSIZE)))
+	{
+		MessageBox(NULL,"Memory allocation error: b->buffer",NULL,MB_OK);
+		return;
+	}
+
+int	tread=src_size<FAAD_STREAMSIZE ? src_size : FAAD_STREAMSIZE;
+	b->bytes_into_buffer=fread(b->buffer, 1, tread, b->infile);
+	if(b->bytes_into_buffer!=tread)
+	{
+		MessageBox(NULL,"Read failed!",NULL,MB_OK);
+		return;
+	}
+	b->bytes_consumed=0;
+	b->file_offset=0;
+	b->at_eof=(b->bytes_into_buffer!=tread) ? 1 : 0;
+
+	*header_type = 0;
+	b->file_offset=0;
+
+	GetAACInfos(b,header_type,song_length,pbitrate,src_size);
+
+	free(b->buffer);
+	fclose(b->infile);
+}
+*/
+// *********************************************************************************************
+//									Main functions
+// *********************************************************************************************
+
+void CMyDecCfg::getCfg(CMyDecCfg *cfg) 
+{ 
+CRegistry reg;
+
+if(reg.OpenCreate(HKEY_CURRENT_USER, REGISTRY_PROGRAM_NAME "\\FAAD"))
+	{
+		cfg->DefaultCfg=reg.GetSetBool(REG_DEFAULT,true);
+		cfg->DecCfg.defObjectType=reg.GetSetByte(REG_PROFILE,LC);
+		cfg->DecCfg.defSampleRate=reg.GetSetDword(REG_SAMPLERATE,44100);
+		cfg->DecCfg.outputFormat=reg.GetSetByte(REG_BPS,FAAD_FMT_16BIT);
+		cfg->DecCfg.downMatrix=reg.GetSetByte(REG_DOWNMATRIX,0);
+		cfg->DecCfg.useOldADTSFormat=reg.GetSetByte(REG_OLDADTS,0);
+		cfg->DecCfg.dontUpSampleImplicitSBR=reg.GetSetByte(REG_DONTUPSAMPLESBR,1);
+//		cfg->Channels=reg.GetSetByte("Channels",2);
+	}
+	else
+		MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
+}
+// -----------------------------------------------------------------------------------------------
+
+void CMyDecCfg::setCfg(CMyDecCfg *cfg)
+{ 
+CRegistry reg;
+
+	if(reg.OpenCreate(HKEY_CURRENT_USER, REGISTRY_PROGRAM_NAME "\\FAAD"))
+	{
+		reg.SetBool(REG_DEFAULT,cfg->DefaultCfg);
+		reg.SetByte(REG_PROFILE,cfg->DecCfg.defObjectType);
+		reg.SetDword(REG_SAMPLERATE,cfg->DecCfg.defSampleRate);
+		reg.SetByte(REG_BPS,cfg->DecCfg.outputFormat);
+		reg.SetByte(REG_DOWNMATRIX,cfg->DecCfg.downMatrix);
+		reg.SetByte(REG_OLDADTS,cfg->DecCfg.useOldADTSFormat);
+		reg.SetByte(REG_DONTUPSAMPLESBR,cfg->DecCfg.dontUpSampleImplicitSBR);
+//		reg.SetByte("Channels",cfg->Channels);
+	}
+	else
+		MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
+}
+// *********************************************************************************************
+
+void Cfaad::setFaadCfg(faacDecHandle hDecoder, CMyDecCfg Cfg)
+{
+faacDecConfigurationPtr	config=faacDecGetCurrentConfiguration(hDecoder);
+
+	if(!Cfg.DefaultCfg)
+	{
+		config->defObjectType=Cfg.DecCfg.defObjectType;
+		config->outputFormat=Cfg.DecCfg.outputFormat;
+		config->defSampleRate=Cfg.DecCfg.defSampleRate;
+		config->downMatrix=Cfg.DecCfg.downMatrix;
+		config->useOldADTSFormat=Cfg.DecCfg.useOldADTSFormat;
+		config->dontUpSampleImplicitSBR=1;
+	}
+	else
+	{
+		config->defObjectType=LC;
+		config->outputFormat=FAAD_FMT_16BIT;
+		config->defSampleRate=44100;
+		config->downMatrix=0;
+		config->useOldADTSFormat=0;
+		config->dontUpSampleImplicitSBR=1;
+	}
+	faacDecSetConfiguration(hDecoder, config);
+}
+// -----------------------------------------------------------------------------------------------
+
+void Cfaad::setDefaultFaadCfg(faacDecHandle hDecoder, BOOL showDlg)
+{
+	if(showDlg && ShowDlg4RawAAC)
+		ShowDlg4RawAAC();
+
+CMyDecCfg Cfg(false);
+	setFaadCfg(hDecoder,Cfg);
+}
+// -----------------------------------------------------------------------------------------------
+
+void Cfaad::DisplayError(char *ProcName, char *str)
+{
+MYINPUT *mi;
+char buf[100]="";
+
+	GlobalUnlock(hInput); // it wasn't done in getInfos()
+	GLOBALLOCK(mi,hInput,MYINPUT,return);
+
+	if(ProcName && *ProcName)
+		sprintf(buf,"%s: ", ProcName);
+	if(str && *str)
+		strcat(buf,str);
+	if(*buf && str)
+		MessageBox(0, buf, APP_NAME " plugin", MB_OK|MB_ICONSTOP);
+
+	mi->bytes_into_buffer=-1;
+	GlobalUnlock(hInput);
+}
+// *********************************************************************************************
+
+HANDLE Cfaad::getInfos(LPSTR lpstrFilename)
+{
+MYINPUT *mi;
+
+// test tags
+//CMyDecCfg cfg;	cfg.Tag.ReadMp4Tag(lpstrFilename);
+//CMyDecCfg cfg;	cfg.Tag.ReadAacTag(lpstrFilename);
+
+	GLOBALLOCK(mi,hInput,MYINPUT,return NULL);
+
+//	mi->IsAAC=strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".aac")==0;
+	if((mi->IsMP4=IsMP4(lpstrFilename))==-1)
+		return ERROR_getInfos("Error opening file");
+
+	if(mi->IsMP4) // MP4 file ---------------------------------------------------------------------
+	{
+	MP4Duration			length;
+	unsigned __int32	buffer_size;
+	DWORD				timeScale;
+	BYTE				sf;
+    mp4AudioSpecificConfig mp4ASC;
+
+		if(!(mi->mp4File=MP4Read(lpstrFilename, 0)))
+			return ERROR_getInfos("Error opening file");
+
+		if((mi->track=GetAACTrack(mi->mp4File))<0)
+			return ERROR_getInfos(0); //"Unable to find correct AAC sound track");
+
+		if(!(mi->hDecoder=faacDecOpen()))
+			return ERROR_getInfos("Error initializing decoder library");
+
+		MP4GetTrackESConfiguration(mi->mp4File, mi->track, (unsigned __int8 **)&mi->buffer, &buffer_size);
+		if(!mi->buffer)
+			return ERROR_getInfos("MP4GetTrackESConfiguration()");
+		AudioSpecificConfig(mi->buffer, buffer_size, &mp4ASC);
+
+        timeScale = mp4ASC.samplingFrequency;
+        mi->Channels=mp4ASC.channelsConfiguration;
+        sf = mp4ASC.samplingFrequencyIndex;
+        mi->type = mp4ASC.objectTypeIndex;
+//        mi->SBR=mp4ASC.sbr_present_flag;
+
+		if(faacDecInit2(mi->hDecoder, mi->buffer, buffer_size, &mi->Samprate, &mi->Channels) < 0)
+			return ERROR_getInfos("Error initializing decoder library");
+		FREE_ARRAY(mi->buffer);
+
+		length=MP4GetTrackDuration(mi->mp4File, mi->track);
+		mi->len_ms=(DWORD)MP4ConvertFromTrackDuration(mi->mp4File, mi->track, length, MP4_MSECS_TIME_SCALE);
+		mi->file_info.bitrate=MP4GetTrackBitRate(mi->mp4File, mi->track);
+		mi->file_info.version=MP4GetTrackAudioType(mi->mp4File, mi->track)==MP4_MPEG4_AUDIO_TYPE ? 4 : 2;
+		mi->numSamples=MP4GetTrackNumberOfSamples(mi->mp4File, mi->track);
+		mi->sampleId=1;
+
+		mi->IsSeekable=true;
+		mi->LockSeeking=!mi->IsSeekable;
+	}
+	else // AAC file ------------------------------------------------------------------------------
+	{   
+	DWORD			read,
+					tmp;
+	BYTE			Channels4Raw=0;
+
+		if(!(mi->aacFile=fopen(lpstrFilename,"rb")))
+			return ERROR_getInfos("Error opening file"); 
+
+		// use bufferized stream
+		setvbuf(mi->aacFile,NULL,_IOFBF,32767);
+
+		// get size of file
+		fseek(mi->aacFile, 0, SEEK_END);
+		mi->src_size=ftell(mi->aacFile);
+		fseek(mi->aacFile, 0, SEEK_SET);
+
+		if(!(mi->buffer=(BYTE *)malloc(FAAD_STREAMSIZE)))
+			return ERROR_getInfos("Memory allocation error: mi->buffer");
+
+		tmp=mi->src_size<FAAD_STREAMSIZE ? mi->src_size : FAAD_STREAMSIZE;
+		read=fread(mi->buffer, 1, tmp, mi->aacFile);
+		if(read==tmp)
+		{
+			mi->bytes_read=read;
+			mi->bytes_into_buffer=read;
+		}
+		else
+			return ERROR_getInfos("Read failed!");
+
+		// skip Tag
+	long tagsize;
+		if(tagsize=id3v2_TagSize(mi->buffer))
+		{
+			if(tagsize>(long)mi->src_size)
+				ERROR_getInfos("Corrupt stream!");
+			if(tagsize<mi->bytes_into_buffer)
+			{
+				mi->bytes_into_buffer-=tagsize;
+				memcpy(mi->buffer,mi->buffer+tagsize,mi->bytes_into_buffer);
+			}
+			else
+			{
+				mi->bytes_read=tagsize;
+				mi->bytes_into_buffer=0;
+				if(tagsize>mi->bytes_into_buffer)
+					fseek(mi->aacFile, tagsize, SEEK_SET);
+			}
+			if(mi->src_size<mi->bytes_read+FAAD_STREAMSIZE-mi->bytes_into_buffer)
+				tmp=mi->src_size-mi->bytes_read;
+			else
+				tmp=FAAD_STREAMSIZE-mi->bytes_into_buffer;
+			read=fread(mi->buffer+mi->bytes_into_buffer, 1, tmp, mi->aacFile);
+			if(read==tmp)
+			{
+				mi->bytes_read+=read;
+				mi->bytes_into_buffer+=read;
+			}
+			else
+				ERROR_getInfos("Read failed!");
+		}
+
+		if(get_AAC_format(lpstrFilename, &mi->file_info, &mi->seek_table, &mi->seek_table_length, 0))
+			ERROR_getInfos("get_AAC_format()");
+		mi->IsSeekable=mi->file_info.headertype==ADTS && mi->seek_table && mi->seek_table_length>0;
+		mi->LockSeeking=!mi->IsSeekable;
+/*
+	aac_buffer	b;
+	float		fLength;
+	DWORD		headertype;
+		b.infile=mi->aacFile;
+		b.buffer=mi->buffer;
+	    b.bytes_into_buffer=read;
+		b.bytes_consumed=mi->bytes_consumed;
+		b.file_offset=0;
+		b.at_eof=(read!=tmp) ? 1 : 0;
+		GetAACInfos(&b,&headertype,&fLength,&mi->file_info.bitrate,mi->src_size);
+		mi->file_info.bitrate*=1024;
+		mi->file_info.headertype=headertype;
+        mi->bytes_into_buffer=b.bytes_into_buffer;
+        mi->bytes_consumed=b.bytes_consumed;
+		IsSeekable=false; // only mp4 can be seeked
+*/
+		if(!mi->FindBitrate) // open a new instance to get info from decoder
+		{
+		MYINPUT *miTmp;
+		Cfaad	*NewInst;
+			if(!(NewInst=new Cfaad()))
+				return ERROR_getInfos("Memory allocation error: NewInst");
+
+			GLOBALLOCK(miTmp,NewInst->hInput,MYINPUT,return 0);
+			miTmp->FindBitrate=TRUE;
+			NewInst->ShowDlg4RawAAC=ShowDlg4RawAAC;
+			NewInst->pCfg=pCfg;
+			if(!NewInst->getInfos(lpstrFilename))
+				return ERROR_getInfos(0);
+			mi->Channels=miTmp->frameInfo.channels;
+			if(mi->file_info.headertype==RAW)
+				mi->file_info.bitrate=miTmp->file_info.bitrate;//*mi->Channels;
+			mi->Samprate=miTmp->Samprate;
+			mi->file_info.headertype=miTmp->file_info.headertype;
+			mi->file_info.object_type=miTmp->file_info.object_type;
+			mi->file_info.version=miTmp->file_info.version;
+			GlobalUnlock(NewInst->hInput);
+			delete NewInst;
+		}
+
+		if(!(mi->hDecoder=faacDecOpen()))
+			return ERROR_getInfos("Can't open library");
+		if(mi->file_info.headertype==RAW)
+			if(pCfg)
+				setFaadCfg(mi->hDecoder,*pCfg);
+			else
+				setDefaultFaadCfg(mi->hDecoder,mi->FindBitrate);
+	BYTE Channels; // faacDecInit doesn't report correctly the number of channels in raw aac files
+		if((mi->bytes_consumed=faacDecInit(mi->hDecoder, mi->buffer, mi->bytes_into_buffer, &mi->Samprate, &Channels))<0)
+			return ERROR_getInfos("faacDecInit()");
+		mi->bytes_into_buffer-=mi->bytes_consumed;
+
+		if(mi->FindBitrate) // get info from decoder
+		{
+		DWORD	Samples,
+				BytesConsumed;
+
+			if(!processData(hInput,0,0))
+				return ERROR_getInfos(0);
+			Samples=mi->frameInfo.samples/sizeof(short);
+			BytesConsumed=mi->frameInfo.bytesconsumed;
+			if(mi->file_info.headertype==RAW || !mi->file_info.bitrate)
+				mi->file_info.bitrate=(BytesConsumed*8*mi->Samprate)/(Samples*2);
+			if(!mi->file_info.bitrate)
+				return ERROR_getInfos("Can't determine the bitrate");
+		}
+
+		mi->len_ms=(DWORD)((mi->src_size<<3)/(mi->file_info.bitrate>>10));
+//		mi->len_ms=(DWORD)((1000*((float)mi->src_size*8))/mi->file_info.bitrate);
+	}
+
+	if(mi->len_ms)
+		mi->dst_size=(DWORD)(mi->len_ms*((float)mi->Samprate/1000)*mi->Channels*(mi->BitsPerSample/8));
+	else
+		return ERROR_getInfos("Can't determine the length");
+
+	showInfo(mi);
+
+	GlobalUnlock(hInput);
+    return hInput;
+}
+// *********************************************************************************************
+
+int Cfaad::processData(HANDLE hInput, unsigned char far *bufout, long lBytes)
+{
+BYTE	*buffer;
+DWORD	BytesDecoded=0;
+char	*sample_buffer=0;
+int		read;
+MYINPUT	*mi;
+
+	GLOBALLOCK(mi,hInput,MYINPUT,return 0);
+
+	if(mi->LockSeeking)
+	{
+		NoSeek();
+		mi->LockSeeking=false;
+	}
+
+	if(mi->IsMP4) // MP4 file --------------------------------------------------------------------------
+	{   
+	unsigned __int32 buffer_size=0;
+    int rc;
+
+		if(newpos_ms>-1)
+		{
+		MP4Duration duration=MP4ConvertToTrackDuration(mi->mp4File,mi->track,newpos_ms,MP4_MSECS_TIME_SCALE);
+		MP4SampleId sampleId=MP4GetSampleIdFromTime(mi->mp4File,mi->track,duration,0);
+			mi->bytes_read=(DWORD)(((float)newpos_ms*mi->file_info.bitrate)/(8*1000));
+			if(seek(mi->bytes_read))  // update the slider
+				return ERROR_processData(0);
+			newpos_ms=-1;
+		}
+		do
+		{
+			buffer=NULL;
+			if(mi->sampleId>=mi->numSamples)
+				return ERROR_processData(0);
+
+			rc=MP4ReadSample(mi->mp4File, mi->track, mi->sampleId++, (unsigned __int8 **)&buffer, &buffer_size, NULL, NULL, NULL, NULL);
+			if(rc==0 || buffer==NULL)
+			{
+				FREE_ARRAY(buffer);
+				return ERROR_processData("MP4ReadSample()");
+			}
+
+			sample_buffer=(char *)faacDecDecode(mi->hDecoder,&mi->frameInfo,buffer,buffer_size);
+			BytesDecoded=mi->frameInfo.samples*sizeof(short);
+			if(BytesDecoded>(DWORD)lBytes)
+				BytesDecoded=lBytes;
+			memmove(bufout,sample_buffer,BytesDecoded);
+			FREE_ARRAY(buffer);
+			// to update the slider
+			mi->bytes_read+=buffer_size;
+			if(seek(mi->bytes_read))
+				return ERROR_processData(0);
+		}while(!BytesDecoded && !mi->frameInfo.error);
+	}
+	else // AAC file --------------------------------------------------------------------------
+	{   
+		if(newpos_ms>-1)
+		{
+			if(mi->IsSeekable)
+			{
+			DWORD normalized=mi->len_ms/(mi->seek_table_length-1);
+				if(normalized<1000)
+					normalized=1000;
+				mi->bytes_read=mi->seek_table[newpos_ms/normalized];
+				fseek(mi->aacFile, mi->bytes_read, SEEK_SET);
+				if(seek(mi->bytes_read))  // update the slider
+					return ERROR_processData(0);
+				mi->bytes_into_buffer=0;
+				mi->bytes_consumed=FAAD_STREAMSIZE;
+			}
+			newpos_ms=-1;
+		}
+		buffer=mi->buffer;
+		do
+		{
+			if(mi->bytes_consumed>0)
+			{
+				if(mi->bytes_into_buffer)
+					memmove(buffer,buffer+mi->bytes_consumed,mi->bytes_into_buffer);
+
+				if(mi->bytes_read<mi->src_size)
+				{
+				int tmp;
+					if(mi->bytes_read+mi->bytes_consumed<mi->src_size)
+						tmp=mi->bytes_consumed;
+					else
+						tmp=mi->src_size-mi->bytes_read;
+					read=fread(buffer+mi->bytes_into_buffer, 1, tmp, mi->aacFile);
+					if(read==tmp)
+					{
+						mi->bytes_read+=read;
+						mi->bytes_into_buffer+=read;
+					}
+				}
+				else
+					if(mi->bytes_into_buffer)
+						memset(buffer+mi->bytes_into_buffer, 0, mi->bytes_consumed);
+
+				mi->bytes_consumed=0;
+
+				if(	(mi->bytes_into_buffer>3 && !memcmp(mi->buffer, "TAG", 3)) ||
+					(mi->bytes_into_buffer>11 && !memcmp(mi->buffer, "LYRICSBEGIN", 11)) ||
+					(mi->bytes_into_buffer>8 && !memcmp(mi->buffer, "APETAGEX", 8)))
+					return ERROR_processData(0);
+			}
+
+			if(mi->bytes_into_buffer<1)
+				if(mi->bytes_read<mi->src_size)
+					return ERROR_processData("Buffer empty!");
+				else
+					return ERROR_processData(0);
+
+			sample_buffer=(char *)faacDecDecode(mi->hDecoder,&mi->frameInfo,buffer,mi->bytes_into_buffer);
+			BytesDecoded=mi->frameInfo.samples*sizeof(short);
+			if(bufout)
+			{
+				if(BytesDecoded>(DWORD)lBytes)
+					BytesDecoded=lBytes;
+				if(sample_buffer && BytesDecoded && !mi->frameInfo.error)
+					memmove(bufout,sample_buffer,BytesDecoded);
+			}
+			else // Data needed to decode Raw files
+			{
+				mi->Channels=mi->frameInfo.channels;
+				mi->file_info.object_type=mi->frameInfo.object_type;
+			}
+		    mi->bytes_consumed+=mi->frameInfo.bytesconsumed;
+			mi->bytes_into_buffer-=mi->bytes_consumed;
+		}while(!BytesDecoded && !mi->frameInfo.error);
+	} // END AAC file --------------------------------------------------------------------------
+
+	if(mi->frameInfo.error)
+		return ERROR_processData((char *)faacDecGetErrorMessage(mi->frameInfo.error));
+
+	showProgress(mi);
+
+	GlobalUnlock(hInput);
+    return BytesDecoded;
+}
--- /dev/null
+++ b/common/Cfaac/Cfaad.h
@@ -1,0 +1,200 @@
+/*
+CFAAC - set of classes to import/export .aac/.mp4 files
+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:
[email protected]
+*/
+
+#ifndef _Cfaad_H
+#define _Cfaad_H
+
+#include <mp4.h>
+#include <faac.h>
+
+#ifdef MAIN
+	#undef MAIN
+#endif
+#ifdef SSR
+	#undef SSR
+#endif
+#ifdef LTP
+	#undef LTP
+#endif
+
+#include <faad.h>
+extern "C" {
+	#include <aacinfo.h>    // get_AAC_format()
+}
+#include "Defines.h"
+#include "CRegistry.h"
+#include "CTag.h"
+
+
+
+// *********************************************************************************************
+
+// make this higher to support files with more channels
+#define MAX_CHANNELS 6
+#if FAAD_MIN_STREAMSIZE<2048
+#undef FAAD_MIN_STREAMSIZE
+// 960 for LD or else 1024 (expanded to 2048 for HE-AAC)
+#define FAAD_MIN_STREAMSIZE 2048
+#endif
+
+#define	FAAD_STREAMSIZE	(FAAD_MIN_STREAMSIZE*MAX_CHANNELS)
+
+// -----------------------------------------------------------------------------------------------
+
+#define REG_DEFAULT "Default"
+#define REG_PROFILE "Profile"
+#define REG_SAMPLERATE "SampleRate"
+#define REG_BPS "Bps"
+#define REG_DOWNMATRIX "Downmatrix"
+#define REG_OLDADTS "Old ADTS"
+#define REG_DONTUPSAMPLESBR "Don\'t upsample implicit SBR"
+
+// *********************************************************************************************
+
+
+
+/* FAAD file buffering routines */
+/*typedef struct {
+    long bytes_into_buffer;
+    long bytes_consumed;
+    long file_offset;
+    unsigned char *buffer;
+    int at_eof;
+    FILE *infile;
+} aac_buffer;
+// -----------------------------------------------------------------------------------------------
+
+typedef struct {
+    int version;
+    int channels;
+    int sampling_rate;
+    int bitrate;
+    int length;
+    int object_type;
+    int headertype;
+} faadAACInfo;
+*/
+
+// *********************************************************************************************
+
+class CMyDecCfg
+{
+private:
+
+	bool SaveCfgOnDestroy;
+
+public:
+
+	CMyDecCfg(bool SaveOnDestroy=true) { getCfg(this); SaveCfgOnDestroy=SaveOnDestroy; }
+	virtual ~CMyDecCfg() { if(SaveCfgOnDestroy) setCfg(this); FreeCfg(this); }
+
+	void FreeCfg(CMyDecCfg *cfg) { cfg->Tag.FreeTag(); }
+	void FreeCfg() { this->Tag.FreeTag(); }
+	void getCfg(CMyDecCfg *cfg);
+	void getCfg() { getCfg(this); }
+	void setCfg(CMyDecCfg *cfg);
+	void setCfg() { setCfg(this); }
+
+	bool					DefaultCfg;
+	BYTE					Channels;
+	DWORD					BitRate;
+	faacDecConfiguration	DecCfg;
+	CMP4Tag					Tag;
+};
+// -----------------------------------------------------------------------------------------------
+
+typedef struct input_tag // any special vars associated with input file
+{
+//MP4
+MP4FileHandle	mp4File;
+MP4SampleId		sampleId,
+				numSamples;
+int				track;
+BYTE			type;
+
+//AAC
+FILE			*aacFile;
+DWORD			src_size;		// size of compressed file
+long			tagsize;
+DWORD			bytes_read;		// from file
+long			bytes_consumed;	// from buffer by faadDecDecode
+long			bytes_into_buffer;
+unsigned char	*buffer;
+DWORD			*seek_table;
+int				seek_table_length;
+
+// Raw AAC
+BOOL			FindBitrate;
+
+// GLOBAL
+faacDecHandle	hDecoder;
+faadAACInfo		file_info;
+faacDecFrameInfo	frameInfo;
+DWORD			len_ms;			// length of file in milliseconds
+BYTE			Channels;
+DWORD			Samprate;
+WORD			BitsPerSample;
+DWORD			dst_size;		// size of decoded file. Cooledit needs it to update its progress bar
+//char			*src_name;		// name of compressed file
+int				IsMP4;
+bool			LockSeeking,
+				IsSeekable;
+} MYINPUT;
+// -----------------------------------------------------------------------------------------------
+
+class Cfaad
+{
+private:
+	virtual int GetAACTrack(MP4FileHandle infile);
+	long id3v2_TagSize(unsigned char *buffer);
+/*	long id3v2_TagSize(aac_buffer *b);
+	int fill_buffer(aac_buffer *b);
+	void advance_buffer(aac_buffer *b, int bytes);
+	int adts_parse(aac_buffer *b, int *bitrate, float *length);
+	void GetAACInfos(aac_buffer *b, DWORD *header_type, float *song_length, int *pbitrate, long filesize);
+*/
+	virtual void DisplayError(char *ProcName, char *str);
+	virtual HANDLE ERROR_getInfos(char *str) { DisplayError("getInfos", str); return NULL; }
+	virtual int ERROR_processData(char *str) { DisplayError("processData", str); return 0; }
+	virtual void showInfo(MYINPUT *mi) {}
+	virtual void showProgress(MYINPUT *mi) {}
+	virtual void setDefaultFaadCfg(faacDecHandle hDecoder, BOOL showDlg);
+	virtual void setFaadCfg(faacDecHandle hDecoder, CMyDecCfg Cfg);
+	virtual int seek(int newpos_bytes) { return 0; } // !=0 => error
+	virtual void NoSeek() {} // put here the code to block seeking of player
+
+public:
+    Cfaad(HANDLE hInput=NULL);
+    virtual ~Cfaad();
+
+	int (*ShowDlg4RawAAC)(); // set this to show your dialog (to decode raw aac files)
+	int IsMP4(LPSTR lpstrFilename);
+	inline bool CanSeek() { MYINPUT	*mi; GLOBALLOCK(mi,hInput,MYINPUT,return 0); bool IsSeekable=mi->IsSeekable; GlobalUnlock(hInput); return IsSeekable; }
+//	virtual void GetAACInfos(char *Filename, aac_buffer *b, DWORD *header_type, float *song_length, int *pbitrate);
+    virtual HANDLE getInfos(LPSTR lpstrFilename);
+    virtual int processData(HANDLE hInput, unsigned char far *bufout, long lBytes);
+
+// GLOBAL
+	long            newpos_ms; // set this to change position
+	HANDLE			hInput;
+	CMyDecCfg		*pCfg; // set this to use your cfg (to decode raw aac files)
+};
+#endif
--- /dev/null
+++ b/common/Cfaac/DecDialog.cpp
@@ -1,0 +1,214 @@
+/*
+CFAAC - set of classes to import/export .aac/.mp4 files
+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:
[email protected]
+*/
+
+#include <windows.h>
+#include "resource.h"
+#include <Defines.h>	// my defines
+#include "Cfaad.h"
+#include "DecDialog.h"
+#include "EncDialog.h"
+
+// *********************************************************************************************
+
+extern HINSTANCE hInstance;
+extern HBITMAP hBmBrowse;
+
+// -----------------------------------------------------------------------------------------------
+
+#ifndef FAAD_FMT_64BIT
+#define FAAD_FMT_64BIT 5
+#endif
+
+// *********************************************************************************************
+
+int ShowDlg4RawAAC()
+{
+	return DialogBoxParam((HINSTANCE)hInstance,(LPCSTR)MAKEINTRESOURCE(IDD_DECODER),(HWND)NULL, (DLGPROC)DialogMsgProcDec, 0);
+//	return DialogBoxParam((HINSTANCE)hInstance,(LPCSTR)MAKEINTRESOURCE(IDD_DECODER),(HWND)hWnd, (DLGPROC)DialogMsgProcDec, (DWORD)&cfg);
+}
+
+// *********************************************************************************************
+
+#define INIT_CB(hWnd,nID,list,IdSelected) \
+{ \
+	for(int i=0; list[i]; i++) \
+		SendMessage(GetDlgItem(hWnd, nID), CB_ADDSTRING, 0, (LPARAM)list[i]); \
+	SendMessage(GetDlgItem(hWnd, nID), CB_SETCURSEL, IdSelected, 0); \
+}
+// -----------------------------------------------------------------------------------------------
+
+//	EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_SSR), Enabled);
+#define DISABLE_CTRLS_DEC(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_CHK_DOWNMATRIX), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_CHK_OLDADTS), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_CB_SAMPLERATE), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_CB_BITSPERSAMPLE), Enabled); \
+}
+// -----------------------------------------------------------------------------------------------
+
+BOOL DialogMsgProcDec(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
+{
+	switch(Message)
+	{
+	case WM_INITDIALOG:
+		{
+/*			if(!lParam)
+			{
+				MessageBox(hWndDlg,"Pointer==NULL",0,MB_OK|MB_ICONSTOP);
+				EndDialog(hWndDlg, 0);
+				return TRUE;
+			}
+*/
+		char buf[50];
+		char	*SampleRate[]={"6000","8000","16000","22050","32000","44100","48000","64000","88200","96000","192000",0},
+				*BitsPerSample[]={"16","24","32","32 bit FLOAT","64 bit FLOAT",0};
+		CMyDecCfg cfg(false);
+
+			SetWindowPos(GetDlgItem(hWndDlg,IDC_CHK_DEFAULTCFG),GetDlgItem(hWndDlg,IDC_GRP_DEFAULT),0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
+
+			INIT_CB(hWndDlg,IDC_CB_BITSPERSAMPLE,BitsPerSample,0);
+			INIT_CB(hWndDlg,IDC_CB_SAMPLERATE,SampleRate,5);
+			sprintf(buf,"%lu",cfg.DecCfg.defSampleRate);
+			SetDlgItemText(hWndDlg, IDC_CB_SAMPLERATE, buf);
+
+			switch(cfg.DecCfg.defObjectType)
+			{
+			case MAIN:
+				CheckDlgButton(hWndDlg,IDC_RADIO_MAIN,TRUE);
+				break;
+			case LC:
+				CheckDlgButton(hWndDlg,IDC_RADIO_LOW,TRUE);
+				break;
+			case SSR:
+				CheckDlgButton(hWndDlg,IDC_RADIO_SSR,TRUE);
+				break;
+			case LTP:
+				CheckDlgButton(hWndDlg,IDC_RADIO_LTP,TRUE);
+				break;
+			case HE_AAC:
+				CheckDlgButton(hWndDlg,IDC_RADIO_HE,TRUE);
+				break;
+			}
+
+			switch(cfg.DecCfg.outputFormat)
+			{
+			case FAAD_FMT_16BIT:
+				SendMessage(GetDlgItem(hWndDlg, IDC_CB_BITSPERSAMPLE), CB_SETCURSEL, 0, 0);
+				break;
+			case FAAD_FMT_24BIT:
+				SendMessage(GetDlgItem(hWndDlg, IDC_CB_BITSPERSAMPLE), CB_SETCURSEL, 1, 0);
+				break;
+			case FAAD_FMT_32BIT:
+				SendMessage(GetDlgItem(hWndDlg, IDC_CB_BITSPERSAMPLE), CB_SETCURSEL, 2, 0);
+				break;
+			case FAAD_FMT_FLOAT:
+				SendMessage(GetDlgItem(hWndDlg, IDC_CB_BITSPERSAMPLE), CB_SETCURSEL, 3, 0);
+				break;
+			case FAAD_FMT_64BIT:
+				SendMessage(GetDlgItem(hWndDlg, IDC_CB_BITSPERSAMPLE), CB_SETCURSEL, 4, 0);
+				break;
+			}
+
+			CheckDlgButton(hWndDlg,IDC_CHK_DOWNMATRIX, cfg.DecCfg.downMatrix);
+			CheckDlgButton(hWndDlg,IDC_CHK_OLDADTS, cfg.DecCfg.useOldADTSFormat);
+
+			CheckDlgButton(hWndDlg,IDC_CHK_DEFAULTCFG, cfg.DefaultCfg);
+			DISABLE_CTRLS_DEC(!cfg.DefaultCfg);
+		}
+		break; // End of WM_INITDIALOG                                 
+
+	case WM_CLOSE:
+		// Closing the Dialog behaves the same as Cancel               
+		PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0);
+		break; // End of WM_CLOSE                                      
+
+	case WM_COMMAND:
+		switch(LOWORD(wParam))
+		{
+		case IDC_CHK_DEFAULTCFG:
+			{
+			char Enabled=!IsDlgButtonChecked(hWndDlg,IDC_CHK_DEFAULTCFG);
+				DISABLE_CTRLS_DEC(Enabled);
+			}
+			break;
+
+		case IDOK:
+			{
+		CMyDecCfg cfg;
+				if(IsDlgButtonChecked(hWndDlg,IDC_RADIO_MAIN))
+					cfg.DecCfg.defObjectType=MAIN;
+				if(IsDlgButtonChecked(hWndDlg,IDC_RADIO_LOW))
+					cfg.DecCfg.defObjectType=LC;
+				if(IsDlgButtonChecked(hWndDlg,IDC_RADIO_SSR))
+					cfg.DecCfg.defObjectType=SSR;
+				if(IsDlgButtonChecked(hWndDlg,IDC_RADIO_LTP))
+					cfg.DecCfg.defObjectType=LTP;
+				if(IsDlgButtonChecked(hWndDlg,IDC_RADIO_HE))
+					cfg.DecCfg.defObjectType=HE_AAC;
+				switch(SendMessage(GetDlgItem(hWndDlg, IDC_CB_BITSPERSAMPLE), CB_GETCURSEL, 0, 0))
+				{
+				case 0:
+					cfg.DecCfg.outputFormat=FAAD_FMT_16BIT;
+					break;
+				case 1:
+					cfg.DecCfg.outputFormat=FAAD_FMT_24BIT;
+					break;
+				case 2:
+					cfg.DecCfg.outputFormat=FAAD_FMT_32BIT;
+					break;
+				case 3:
+					cfg.DecCfg.outputFormat=FAAD_FMT_FLOAT;
+					break;
+				case 4:
+					cfg.DecCfg.outputFormat=FAAD_FMT_64BIT;
+					break;
+				}
+
+				cfg.DecCfg.defSampleRate=GetDlgItemInt(hWndDlg, IDC_CB_SAMPLERATE, 0, FALSE);
+				cfg.DecCfg.downMatrix=IsDlgButtonChecked(hWndDlg,IDC_CHK_DOWNMATRIX) ? TRUE : FALSE;
+				cfg.DecCfg.useOldADTSFormat=IsDlgButtonChecked(hWndDlg,IDC_CHK_OLDADTS) ? TRUE : FALSE;
+				cfg.DefaultCfg=IsDlgButtonChecked(hWndDlg,IDC_CHK_DEFAULTCFG) ? TRUE : FALSE;
+
+				EndDialog(hWndDlg, (DWORD)TRUE);
+			}
+			break;
+
+        case IDCANCEL:
+			// Ignore data values entered into the controls        
+			// and dismiss the dialog window returning FALSE
+			EndDialog(hWndDlg, (DWORD)FALSE);
+			break;
+
+		case IDC_BTN_ABOUT:
+				DialogBox((HINSTANCE)hInstance,(LPCSTR)MAKEINTRESOURCE(IDD_ABOUT), (HWND)hWndDlg, (DLGPROC)DialogMsgProcAbout);
+			break;
+		}
+		break; // End of WM_COMMAND
+	default: 
+		return FALSE;
+	}
+ 
+	return TRUE;
+}
--- /dev/null
+++ b/common/Cfaac/DecDialog.h
@@ -1,0 +1,39 @@
+extern BOOL DialogMsgProcDec(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam);
+extern int ShowDlg4RawAAC();
+
+static const char* mpeg4AudioNames[]=
+{
+	"Raw PCM",
+	"AAC Main",
+	"AAC LC (Low Complexity)",
+	"AAC SSR",
+	"AAC LTP (Long Term Prediction)",
+	"AAC HE (High Efficiency)",
+	"AAC Scalable",
+	"TwinVQ",
+	"CELP",
+	"HVXC",
+	"Reserved",
+	"Reserved",
+	"TTSI",
+	"Main synthetic",
+	"Wavetable synthesis",
+	"General MIDI",
+	"Algorithmic Synthesis and Audio FX",
+// defined in MPEG-4 version 2
+	"ER AAC LC (Low Complexity)",
+	"Reserved",
+	"ER AAC LTP (Long Term Prediction)",
+	"ER AAC Scalable",
+	"ER TwinVQ",
+	"ER BSAC",
+	"ER AAC LD (Low Delay)",
+	"ER CELP",
+	"ER HVXC",
+	"ER HILN",
+	"ER Parametric",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Reserved"
+};
binary files /dev/null b/common/Cfaac/Email.bmp differ
--- /dev/null
+++ b/common/Cfaac/EncDialog.cpp
@@ -1,0 +1,945 @@
+/*
+CFAAC - set of classes to import/export .aac/.mp4 files
+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:
[email protected]
+*/
+
+#include <windows.h>
+#include <shlobj.h>		// Browse
+#include <shellapi.h>	// ShellExecute
+#include <Commdlg.h>
+#include "resource.h"
+#include "Defines.h"	// my defines
+#include "CTag.h"
+#include "Cfaac.h"
+#include "EncDialog.h"
+
+#include <commctrl.h>
+#include <id3v2tag.h>
+//#include <id3\globals.h> // ID3LIB_RELEASE
+
+// *********************************************************************************************
+
+#ifdef USE_OUTPUT_FOLDER
+extern char	config_AACoutdir[MAX_PATH];
+#endif
+
+extern HINSTANCE hInstance;
+extern HBITMAP hBmBrowse;
+
+// *********************************************************************************************
+
+/*
+DWORD PackCfg(MY_ENC_CFG *cfg)
+{
+DWORD dwOptions=0;
+
+	if(cfg->AutoCfg)
+		dwOptions=1<<31;
+	dwOptions|=(DWORD)cfg->EncCfg.mpegVersion<<30;
+	dwOptions|=(DWORD)cfg->EncCfg.aacObjectType<<28;
+	dwOptions|=(DWORD)cfg->EncCfg.allowMidside<<27;
+	dwOptions|=(DWORD)cfg->EncCfg.useTns<<26;
+	dwOptions|=(DWORD)cfg->EncCfg.useLfe<<25;
+	dwOptions|=(DWORD)cfg->EncCfg.outputFormat<<24;
+	if(cfg->UseQuality)
+		dwOptions|=(((DWORD)cfg->EncCfg.quantqual>>1)&0xff)<<16; // [2,512]
+	else
+		dwOptions|=(((DWORD)cfg->EncCfg.bitRate>>1)&0xff)<<16; // [2,512]
+	if(cfg->UseQuality)
+		dwOptions|=1<<15;
+	dwOptions|=((DWORD)cfg->EncCfg.bandWidth>>1)&&0x7fff; // [0,65536]
+
+	return dwOptions;
+}
+// -----------------------------------------------------------------------------------------------
+
+void UnpackCfg(MY_ENC_CFG *cfg, DWORD dwOptions)
+{
+	cfg->AutoCfg=dwOptions>>31;
+	cfg->EncCfg.mpegVersion=(dwOptions>>30)&1;
+	cfg->EncCfg.aacObjectType=(dwOptions>>28)&3;
+	cfg->EncCfg.allowMidside=(dwOptions>>27)&1;
+	cfg->EncCfg.useTns=(dwOptions>>26)&1;
+	cfg->EncCfg.useLfe=(dwOptions>>25)&1;
+	cfg->EncCfg.outputFormat=(dwOptions>>24)&1;
+	cfg->EncCfg.bitRate=((dwOptions>>16)&0xff)<<1;
+	cfg->UseQuality=(dwOptions>>15)&1;
+	cfg->EncCfg.bandWidth=(dwOptions&0x7fff)<<1;
+}*/
+// -----------------------------------------------------------------------------------------------
+
+#define INIT_CB(hWnd,nID,list,FillList,IdSelected) \
+{ \
+	if(FillList) \
+		for(int i=0; list[i]; i++) \
+			SendMessage(GetDlgItem(hWnd, nID), CB_ADDSTRING, 0, (LPARAM)list[i]); \
+	SendMessage(GetDlgItem(hWnd, nID), CB_SETCURSEL, IdSelected, 0); \
+}
+// -----------------------------------------------------------------------------------------------
+
+#define INIT_CB_GENRES(hWnd,nID,ID3Genres,IdSelected) \
+{ \
+	for(int i=0; i<(sizeof(ID3Genres)/sizeof(ID3Genres[0])); i++) \
+		SendMessage(GetDlgItem(hWnd, nID), CB_ADDSTRING, 0, (LPARAM)ID3Genres[i].name); \
+	SendMessage(GetDlgItem(hWnd, nID), CB_SETCURSEL, IdSelected, 0); \
+}
+// -----------------------------------------------------------------------------------------------
+
+#define DISABLE_LTP \
+{ \
+	if(IsDlgButtonChecked(hWndDlg,IDC_RADIO_MPEG2) && \
+	   IsDlgButtonChecked(hWndDlg,IDC_RADIO_LTP)) \
+	{ \
+		CheckDlgButton(hWndDlg,IDC_RADIO_LTP,FALSE); \
+		CheckDlgButton(hWndDlg,IDC_RADIO_MAIN,TRUE); \
+	} \
+    EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LTP), FALSE); \
+}
+// -----------------------------------------------------------------------------------------------
+
+//        EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_SSR), Enabled);
+//        EnableWindow(GetDlgItem(hWndDlg, IDC_CHK_USELFE), Enabled);
+#define DISABLE_CTRLS_ENC(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_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 \
+}
+// -----------------------------------------------------------------------------------------------
+
+#define ENABLE_TAG(Enabled) \
+{ \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_ARTIST), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_TITLE), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_ALBUM), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_YEAR), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_CB_GENRE), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_WRITER), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_COMMENT), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_COMPILATION), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_CHK_COMPILATION), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_TRACK), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_NTRACKS), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_DISK), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_NDISKS), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_ARTFILE), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_BTN_ARTFILE), Enabled); \
+}
+// -----------------------------------------------------------------------------------------------
+
+#define ENABLE_AACTAGS(Enabled) \
+{ \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_COMPILATION), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_CHK_COMPILATION), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_NTRACKS), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_DISK), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_NDISKS), Enabled); \
+}
+// -----------------------------------------------------------------------------------------------
+
+#ifdef USE_OUTPUT_FOLDER
+static int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
+{
+	if (uMsg == BFFM_INITIALIZED)
+	{
+		SetWindowText(hwnd,"Select folder");
+		SendMessage(hwnd,BFFM_SETSELECTION,(WPARAM)TRUE,(LPARAM)lpData);
+	}
+	return 0;
+}
+#else
+	#ifdef USE_IMPORT_TAG
+	static int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
+	{
+		if (uMsg == BFFM_INITIALIZED)
+		{
+			SetWindowText(hwnd,"Select folder");
+			SendMessage(hwnd,BFFM_SETSELECTION,(WPARAM)TRUE,(LPARAM)lpData);
+		}
+		return 0;
+	}
+	#endif
+#endif
+
+// -----------------------------------------------------------------------------------------------
+
+BOOL DialogMsgProcAbout(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
+{
+	switch(Message)
+	{
+	case WM_INITDIALOG:
+		{
+		char buf[512];
+		char *faac_id_string, *faac_copyright_string;
+
+		sprintf(buf,
+					APP_NAME " plugin " APP_VER " by Antonio Foranna\n\n"
+					"Libraries used:\n"
+					"\tlibfaac v%s\n"
+					"\tFAAD2 v" FAAD2_VERSION "\n"
+					"\t" PACKAGE " v" VERSION "\n"
+					"\tid3v2 \n\n" //"\t %s v %s \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",
+				(faacEncGetVersion(&faac_id_string, &faac_copyright_string)==FAAC_CFG_VERSION) ? faac_id_string : " wrong libfaac version",
+//					ID3LIB_FULL_NAME, ID3LIB_RELEASE,
+					__DATE__
+					);
+			SetDlgItemText(hWndDlg, IDC_L_ABOUT, buf);
+		}
+		break;
+	case WM_COMMAND:
+		switch(LOWORD(wParam))
+		{
+		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_ID3:
+			ShellExecute(hWndDlg, NULL, "http://id3lib.sourceforge.net", NULL, NULL, SW_SHOW);
+			break;
+		case IDC_EMAIL:
+			ShellExecute(hWndDlg, NULL, "mailto:[email protected]", NULL, NULL, SW_SHOW);
+			break;
+		}
+		break;
+	default: 
+		return FALSE;
+	}
+
+	return TRUE;
+}
+// -----------------------------------------------------------------------------------------------
+
+// ripped from id3v2tag.c
+ID3GENRES ID3Genres[]=
+{
+    123,    "Acapella",
+    34,     "Acid",
+    74,     "Acid Jazz",
+    73,     "Acid Punk",
+    99,     "Acoustic",
+    20,     "Alternative",
+    40,     "AlternRock",
+    26,     "Ambient",
+    90,     "Avantgarde",
+    116,    "Ballad",
+    41,     "Bass",
+    85,     "Bebob",
+    96,     "Big Band",
+    89,     "Bluegrass",
+    0,      "Blues",
+    107,    "Booty Bass",
+    65,     "Cabaret",
+    88,     "Celtic",
+    104,    "Chamber Music",
+    102,    "Chanson",
+    97,     "Chorus",
+    61,     "Christian Rap",
+    1,      "Classic Rock",
+    32,     "Classical",
+    112,    "Club",
+    57,     "Comedy",
+    2,      "Country",
+    58,     "Cult",
+    3,      "Dance",
+    125,    "Dance Hall",
+    50,     "Darkwave",
+    254,    "Data",
+    22,     "Death Metal",
+    4,      "Disco",
+    55,     "Dream",
+    122,    "Drum Solo",
+    120,    "Duet",
+    98,     "Easy Listening",
+    52,     "Electronic",
+    48,     "Ethnic",
+    124,    "Euro-House",
+    25,     "Euro-Techno",
+    54,     "Eurodance",
+    84,     "Fast Fusion",
+    80,     "Folk",
+    81,     "Folk-Rock",
+    115,    "Folklore",
+    119,    "Freestyle",
+    5,      "Funk",
+    30,     "Fusion",
+    36,     "Game",
+    59,     "Gangsta",
+    38,     "Gospel",
+    49,     "Gothic",
+    91,     "Gothic Rock",
+    6,      "Grunge",
+    79,     "Hard Rock",
+    7,      "Hip-Hop",
+    35,     "House",
+    100,    "Humour",
+    19,     "Industrial",
+    33,     "Instrumental",
+    46,     "Instrumental Pop",
+    47,     "Instrumental Rock",
+    8,      "Jazz",
+    29,     "Jazz+Funk",
+    63,     "Jungle",
+    86,     "Latin",
+    71,     "Lo-Fi",
+    45,     "Meditative",
+    9,      "Metal",
+    77,     "Musical",
+    82,     "National Folk",
+    64,     "Native American",
+    10,     "New Age",
+    66,     "New Wave",
+    39,     "Noise",
+    255,    "Not Set",
+    11,     "Oldies",
+    103,    "Opera",
+    12,     "Other",
+    75,     "Polka",
+    13,     "Pop",
+    62,     "Pop/Funk",
+    53,     "Pop-Folk",
+    109,    "Porn Groove",
+    117,    "Power Ballad",
+    23,     "Pranks",
+    108,    "Primus",
+    92,     "Progressive Rock",
+    67,     "Psychadelic",
+    93,     "Psychedelic Rock",
+    43,     "Punk",
+    121,    "Punk Rock",
+    14,     "R&B",
+    15,     "Rap",
+    68,     "Rave",
+    16,     "Reggae",
+    76,     "Retro",
+    87,     "Revival",
+    118,    "Rhythmic Soul",
+    17,     "Rock",
+    78,     "Rock & Roll",
+    114,    "Samba",
+    110,    "Satire",
+    69,     "Showtunes",
+    21,     "Ska",
+    111,    "Slow Jam",
+    95,     "Slow Rock",
+    105,    "Sonata",
+    42,     "Soul",
+    37,     "Sound Clip",
+    24,     "Soundtrack",
+    56,     "Southern Rock",
+    44,     "Space",
+    101,    "Speech",
+    83,     "Swing",
+    94,     "Symphonic Rock",
+    106,    "Symphony",
+    113,    "Tango",
+    18,     "Techno",
+    51,     "Techno-Industrial",
+    60,     "Top 40",
+    70,     "Trailer",
+    31,     "Trance",
+    72,     "Tribal",
+    27,     "Trip-Hop",
+    28,     "Vocal"
+};
+
+BOOL CALLBACK DIALOGMsgProcEnc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
+{
+	switch(Message)
+	{
+	case WM_INITDIALOG:
+		{
+		char buf[50];
+		char FillList=wParam||lParam ? 1 : 0;
+		char *Quality[]={"Default (100)","10","20","30","40","50","60","70","80","90","100","110","120","130","140","150","200","300","400","500",0};
+		char *BitRate[]={"Auto","8","16","18","20","24","32","40","48","56","64","80","96","112","128","160","192","224","256","320","384",0};
+		char *BandWidth[]={"Auto","Full","4000","8000","11025","16000","22050","24000","32000","44100","48000",0};
+		char *Ext[]={".aac",".mp4",".m4a",".m4b",0};
+		CMyEncCfg cfg(false);
+			
+//			sprintf(Quality[0]+8,"%3d",3);
+
+			SetWindowPos(GetDlgItem(hWndDlg,IDC_CHK_TAG),GetDlgItem(hWndDlg,IDC_GRP_TAG),0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
+
+			INIT_CB(hWndDlg,IDC_CB_QUALITY,Quality,FillList,0);
+			INIT_CB(hWndDlg,IDC_CB_BITRATE,BitRate,FillList,0);
+			INIT_CB(hWndDlg,IDC_CB_BANDWIDTH,BandWidth,FillList,0);
+			INIT_CB(hWndDlg,IDC_CB_EXT,Ext,FillList,0);
+
+			INIT_CB_GENRES(hWndDlg,IDC_CB_GENRE,ID3Genres,0);
+
+			SendMessage(GetDlgItem(hWndDlg, IDC_BTN_ARTFILE), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBmBrowse);
+#ifdef USE_OUTPUT_FOLDER			
+			SendMessage(GetDlgItem(hWndDlg, IDC_BTN_BROWSE), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBmBrowse);
+			if(!cfg.OutDir || !*cfg.OutDir)
+			{
+				GetCurrentDirectory(MAX_PATH,config_AACoutdir);
+				FREE_ARRAY(cfg.OutDir);
+				cfg.OutDir=strdup(config_AACoutdir);
+			}
+			else
+				strcpy(config_AACoutdir,cfg.OutDir);
+			SetDlgItemText(hWndDlg, IDC_E_BROWSE, cfg.OutDir);
+#else
+			ShowWindow(GetDlgItem(hWndDlg, IDC_BTN_BROWSE),SW_HIDE);
+			ShowWindow(GetDlgItem(hWndDlg, IDC_E_BROWSE),SW_HIDE);
+			ShowWindow(GetDlgItem(hWndDlg, IDC_L_BROWSE),SW_HIDE);
+#endif
+			CheckDlgButton(hWndDlg,IDC_RADIO_MPEG4,FALSE);
+			CheckDlgButton(hWndDlg,IDC_RADIO_MPEG2,FALSE);
+			if(cfg.EncCfg.mpegVersion==MPEG4)
+				CheckDlgButton(hWndDlg,IDC_RADIO_MPEG4,TRUE);
+			else
+				CheckDlgButton(hWndDlg,IDC_RADIO_MPEG2,TRUE);
+			
+			CheckDlgButton(hWndDlg,IDC_RADIO_MAIN,FALSE);
+			CheckDlgButton(hWndDlg,IDC_RADIO_LOW,FALSE);
+			CheckDlgButton(hWndDlg,IDC_RADIO_SSR,FALSE);
+			CheckDlgButton(hWndDlg,IDC_RADIO_LTP,FALSE);
+			switch(cfg.EncCfg.aacObjectType)
+			{
+			case MAIN:
+				CheckDlgButton(hWndDlg,IDC_RADIO_MAIN,TRUE);
+				break;
+			case LOW:
+				CheckDlgButton(hWndDlg,IDC_RADIO_LOW,TRUE);
+				break;
+			case SSR:
+				CheckDlgButton(hWndDlg,IDC_RADIO_SSR,TRUE);
+				break;
+			case LTP:
+				CheckDlgButton(hWndDlg,IDC_RADIO_LTP,TRUE);
+				DISABLE_LTP
+				break;
+			}
+			
+			CheckDlgButton(hWndDlg,IDC_RADIO_RAW,FALSE);
+			CheckDlgButton(hWndDlg,IDC_RADIO_ADTS,FALSE);
+			switch(cfg.EncCfg.outputFormat)
+			{
+			case RAW:
+				CheckDlgButton(hWndDlg,IDC_RADIO_RAW,TRUE);
+				break;
+			case ADTS:
+				CheckDlgButton(hWndDlg,IDC_RADIO_ADTS,TRUE);
+				break;
+			}
+			
+			CheckDlgButton(hWndDlg, IDC_CHK_ALLOWMIDSIDE, cfg.EncCfg.allowMidside);
+			CheckDlgButton(hWndDlg, IDC_CHK_USETNS, cfg.EncCfg.useTns);
+			CheckDlgButton(hWndDlg, IDC_CHK_USELFE, cfg.EncCfg.useLfe);
+
+			if(cfg.UseQuality)
+				CheckDlgButton(hWndDlg,IDC_RADIO_QUALITY,TRUE);
+			else
+				CheckDlgButton(hWndDlg,IDC_RADIO_BITRATE,TRUE);
+
+			switch(cfg.EncCfg.quantqual)
+			{
+			case 100:
+				SendMessage(GetDlgItem(hWndDlg, IDC_CB_QUALITY), CB_SETCURSEL, 0, 0);
+				break;
+			default:
+				if(cfg.EncCfg.quantqual<10)
+					cfg.EncCfg.quantqual=10;
+				if(cfg.EncCfg.quantqual>500)
+					cfg.EncCfg.quantqual=500;
+				sprintf(buf,"%lu",cfg.EncCfg.quantqual);
+				SetDlgItemText(hWndDlg, IDC_CB_QUALITY, buf);
+				break;
+			}
+			switch(cfg.EncCfg.bitRate)
+			{
+			case 0:
+				SendMessage(GetDlgItem(hWndDlg, IDC_CB_BITRATE), CB_SETCURSEL, 0, 0);
+				break;
+			default:
+				sprintf(buf,"%lu",cfg.EncCfg.bitRate);
+				SetDlgItemText(hWndDlg, IDC_CB_BITRATE, buf);
+				break;
+			}
+			switch(cfg.EncCfg.bandWidth)
+			{
+			case 0:
+				SendMessage(GetDlgItem(hWndDlg, IDC_CB_BANDWIDTH), CB_SETCURSEL, 0, 0);
+				break;
+			case 0xffffffff:
+				SendMessage(GetDlgItem(hWndDlg, IDC_CB_BANDWIDTH), CB_SETCURSEL, 1, 0);
+				break;
+			default:
+				sprintf(buf,"%lu",cfg.EncCfg.bandWidth);
+				SetDlgItemText(hWndDlg, IDC_CB_BANDWIDTH, buf);
+				break;
+			}
+			
+			SendMessage(GetDlgItem(hWndDlg, IDC_CB_EXT), CB_SETCURSEL, cfg.SaveMP4, 0);
+
+			if(wParam|lParam)
+			{
+				CheckDlgButton(hWndDlg,IDC_CHK_AUTOCFG, cfg.AutoCfg);
+				DISABLE_CTRLS_ENC(!cfg.AutoCfg);
+			}
+#ifdef USE_IMPORT_TAG
+			CheckDlgButton(hWndDlg,IDC_CHK_IMPORTTAG, cfg.TagImport);
+			cfg.TagImport=IsDlgButtonChecked(hWndDlg,IDC_CHK_IMPORTTAG) ? 1 : 0;
+			ShowWindow(GetDlgItem(hWndDlg, IDC_CHK_IMPORTTAG),SW_SHOW);
+	#ifdef USE_PATHEXT
+			SetDlgItemText(hWndDlg, IDC_E_SOURCEPATH, cfg.TagSrcPath);
+			SetDlgItemText(hWndDlg, IDC_E_SOURCEEXT, cfg.TagSrcExt);
+			SendMessage(GetDlgItem(hWndDlg, IDC_BTN_BROWSEIMPORT), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBmBrowse);
+			ShowWindow(GetDlgItem(hWndDlg, IDC_E_SOURCEEXT),SW_SHOW);
+			ShowWindow(GetDlgItem(hWndDlg, IDC_E_SOURCEPATH),SW_SHOW);
+			ShowWindow(GetDlgItem(hWndDlg, IDC_BTN_BROWSEIMPORT),SW_SHOW);
+	#endif
+#endif
+			CheckDlgButton(hWndDlg,IDC_CHK_TAG, cfg.TagOn);
+			ENABLE_TAG(cfg.TagOn && !cfg.TagImport);
+			ENABLE_AACTAGS(cfg.TagOn && !cfg.TagImport && cfg.SaveMP4);
+			SetDlgItemText(hWndDlg, IDC_E_ARTIST, cfg.Tag.artist);
+			SetDlgItemText(hWndDlg, IDC_E_TITLE, cfg.Tag.title);
+			SetDlgItemText(hWndDlg, IDC_E_ALBUM, cfg.Tag.album);
+			SetDlgItemText(hWndDlg, IDC_E_YEAR, cfg.Tag.year);
+			SetDlgItemText(hWndDlg, IDC_CB_GENRE, cfg.Tag.genre);
+			SetDlgItemText(hWndDlg, IDC_E_WRITER, cfg.Tag.writer);
+			SetDlgItemText(hWndDlg, IDC_E_COMMENT, cfg.Tag.comment);
+			SetDlgItemText(hWndDlg, IDC_E_ARTFILE, cfg.Tag.artFilename);
+			SetDlgItemInt(hWndDlg, IDC_E_TRACK, cfg.Tag.trackno, FALSE);
+			SetDlgItemInt(hWndDlg, IDC_E_NTRACKS, cfg.Tag.ntracks, FALSE);
+			SetDlgItemInt(hWndDlg, IDC_E_DISK, cfg.Tag.discno, FALSE);
+			SetDlgItemInt(hWndDlg, IDC_E_NDISKS, cfg.Tag.ndiscs, FALSE);
+			SetDlgItemInt(hWndDlg, IDC_E_COMPILATION, cfg.Tag.compilation, FALSE);
+			CheckDlgButton(hWndDlg, IDC_CHK_COMPILATION, cfg.Tag.compilation);
+		}
+		break; // End of WM_INITDIALOG                                 
+		
+	case WM_CLOSE:
+		// Closing the Dialog behaves the same as Cancel               
+		PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
+		break; // End of WM_CLOSE                                      
+		
+	case WM_COMMAND:
+		switch(LOWORD(wParam))
+		{
+		case IDOK:
+			{
+//			HANDLE hCfg=(HANDLE)lParam;
+			char buf[50];
+			CMyEncCfg cfg;
+
+				cfg.AutoCfg=IsDlgButtonChecked(hWndDlg,IDC_CHK_AUTOCFG) ? TRUE : FALSE;
+				if(!cfg.AutoCfg)
+				{
+					cfg.EncCfg.mpegVersion=IsDlgButtonChecked(hWndDlg,IDC_RADIO_MPEG4) ? MPEG4 : MPEG2;
+					if(IsDlgButtonChecked(hWndDlg,IDC_RADIO_MAIN))
+						cfg.EncCfg.aacObjectType=MAIN;
+					if(IsDlgButtonChecked(hWndDlg,IDC_RADIO_LOW))
+						cfg.EncCfg.aacObjectType=LOW;
+					if(IsDlgButtonChecked(hWndDlg,IDC_RADIO_SSR))
+						cfg.EncCfg.aacObjectType=SSR;
+					if(IsDlgButtonChecked(hWndDlg,IDC_RADIO_LTP))
+						cfg.EncCfg.aacObjectType=LTP;
+					cfg.EncCfg.allowMidside=IsDlgButtonChecked(hWndDlg, IDC_CHK_ALLOWMIDSIDE);
+					cfg.EncCfg.useTns=IsDlgButtonChecked(hWndDlg, IDC_CHK_USETNS);
+					cfg.EncCfg.useLfe=IsDlgButtonChecked(hWndDlg, IDC_CHK_USELFE);
+					
+					GetDlgItemText(hWndDlg, IDC_CB_BITRATE, buf, 50);
+					switch(*buf)
+					{
+					case 'A': // Auto
+						cfg.EncCfg.bitRate=0;
+						break;
+					default:
+						cfg.EncCfg.bitRate=GetDlgItemInt(hWndDlg, IDC_CB_BITRATE, 0, FALSE);
+					}
+					GetDlgItemText(hWndDlg, IDC_CB_BANDWIDTH, buf, 50);
+					switch(*buf)
+					{
+					case 'A': // Auto
+						cfg.EncCfg.bandWidth=0;
+						break;
+					case 'F': // Full
+						cfg.EncCfg.bandWidth=0xffffffff;
+						break;
+					default:
+						cfg.EncCfg.bandWidth=GetDlgItemInt(hWndDlg, IDC_CB_BANDWIDTH, 0, FALSE);
+					}
+					cfg.UseQuality=IsDlgButtonChecked(hWndDlg,IDC_RADIO_QUALITY) ? TRUE : FALSE;
+					GetDlgItemText(hWndDlg, IDC_CB_QUALITY, buf, 50);
+					switch(*buf)
+					{
+					case 'D': // Default
+						cfg.EncCfg.quantqual=100;
+						break;
+					default:
+						cfg.EncCfg.quantqual=GetDlgItemInt(hWndDlg, IDC_CB_QUALITY, 0, FALSE);
+					}
+				}
+
+				cfg.EncCfg.outputFormat=IsDlgButtonChecked(hWndDlg,IDC_RADIO_RAW) ? RAW : ADTS;
+#ifdef USE_OUTPUT_FOLDER
+				GetDlgItemText(hWndDlg, IDC_E_BROWSE, config_AACoutdir, MAX_PATH);
+				FREE_ARRAY(cfg.OutDir);
+				cfg.OutDir=strdup(config_AACoutdir);
+#endif
+				cfg.SaveMP4=(BYTE)SendMessage(GetDlgItem(hWndDlg, IDC_CB_EXT), CB_GETCURSEL, 0, 0);
+
+				cfg.TagOn=IsDlgButtonChecked(hWndDlg,IDC_CHK_TAG) ? 1 : 0;
+			char buffer[MAX_PATH];
+#ifdef USE_IMPORT_TAG
+				cfg.TagImport=IsDlgButtonChecked(hWndDlg,IDC_CHK_IMPORTTAG) ? 1 : 0;
+	#ifdef USE_PATHEXT
+				GetDlgItemText(hWndDlg, IDC_E_SOURCEPATH, buffer, MAX_PATH);
+				cfg.TagSrcPath=strdup(buffer);
+				GetDlgItemText(hWndDlg, IDC_E_SOURCEEXT, buffer, MAX_PATH);
+				cfg.TagSrcExt=strdup(buffer);
+	#endif
+#endif
+				GetDlgItemText(hWndDlg, IDC_E_ARTIST, buffer, MAX_PATH);
+				cfg.Tag.artist=strdup(buffer);
+				GetDlgItemText(hWndDlg, IDC_E_TITLE, buffer, MAX_PATH);
+				cfg.Tag.title=strdup(buffer);
+				GetDlgItemText(hWndDlg, IDC_E_ALBUM, buffer, MAX_PATH);
+				cfg.Tag.album=strdup(buffer);
+				GetDlgItemText(hWndDlg, IDC_E_YEAR, buffer, MAX_PATH);
+				cfg.Tag.year=strdup(buffer);
+				GetDlgItemText(hWndDlg, IDC_CB_GENRE, buffer, MAX_PATH);
+				cfg.Tag.genre=strdup(buffer);
+				GetDlgItemText(hWndDlg, IDC_E_WRITER, buffer, MAX_PATH);
+				cfg.Tag.writer=strdup(buffer);
+				GetDlgItemText(hWndDlg, IDC_E_COMMENT, buffer, MAX_PATH);
+				cfg.Tag.comment=strdup(buffer);
+				GetDlgItemText(hWndDlg, IDC_E_ARTFILE, buffer, MAX_PATH);
+				cfg.Tag.artFilename=strdup(buffer);
+				cfg.Tag.trackno=GetDlgItemInt(hWndDlg, IDC_E_TRACK, 0, FALSE);
+				cfg.Tag.ntracks=GetDlgItemInt(hWndDlg, IDC_E_NTRACKS, 0, FALSE);
+				cfg.Tag.discno=GetDlgItemInt(hWndDlg, IDC_E_DISK, 0, FALSE);
+				cfg.Tag.ndiscs=GetDlgItemInt(hWndDlg, IDC_E_NDISKS, 0, FALSE);
+				cfg.Tag.compilation=(BYTE)GetDlgItemInt(hWndDlg, IDC_E_COMPILATION, 0, FALSE);
+				cfg.Tag.compilation=IsDlgButtonChecked(hWndDlg, IDC_CHK_COMPILATION) ? 1 : 0;
+				EndDialog(hWndDlg, TRUE);//(DWORD)hCfg);
+			}
+			break;
+			
+        case IDCANCEL:
+			// Ignore data values entered into the controls        
+			// and dismiss the dialog window returning FALSE
+			EndDialog(hWndDlg, FALSE);
+			break;
+
+		case IDC_BTN_ABOUT:
+			DialogBox((HINSTANCE)hInstance,(LPCSTR)MAKEINTRESOURCE(IDD_ABOUT), (HWND)hWndDlg, (DLGPROC)DialogMsgProcAbout);
+			break;
+
+		case IDC_BTN_LICENSE:
+			{
+			char *license =
+				"\nPlease note that the use of this software may require the payment of patent royalties.\n"
+				"You need to consider this issue before you start building derivative works.\n"
+				"We are not warranting or indemnifying you in any way for patent royalities!\n"
+				"YOU ARE SOLELY RESPONSIBLE FOR YOUR OWN ACTIONS!\n"
+				"\n"
+				"FAAC is based on the ISO MPEG-4 reference code. For this code base the\n"
+				"following license applies:\n"
+				"\n"
+/*				"This software module was originally developed by\n"
+				"\n"
+				"FirstName LastName (CompanyName)\n"
+				"\n"
+				"and edited by\n"
+				"\n"
+				"FirstName LastName (CompanyName)\n"
+				"FirstName LastName (CompanyName)\n"
+				"\n"
+*/				"in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard\n"
+				"ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an\n"
+				"implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools\n"
+				"as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives\n"
+				"users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this\n"
+				"software module or modifications thereof for use in hardware or\n"
+				"software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio\n"
+				"standards. Those intending to use this software module in hardware or\n"
+				"software products are advised that this use may infringe existing\n"
+				"patents. The original developer of this software module and his/her\n"
+				"company, the subsequent editors and their companies, and ISO/IEC have\n"
+				"no liability for use of this software module or modifications thereof\n"
+				"in an implementation. Copyright is not released for non MPEG-2\n"
+				"NBC/MPEG-4 Audio conforming products. The original developer retains\n"
+				"full right to use the code for his/her own purpose, assign or donate\n"
+				"the code to a third party and to inhibit third party from using the\n"
+				"code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This\n"
+				"copyright notice must be included in all copies or derivative works.\n"
+				"\n"
+				"Copyright (c) 1997.\n"
+				"\n"
+				"For the changes made for the FAAC project the GNU Lesser General Public\n"
+				"License (LGPL), version 2 1991 applies:\n"
+				"\n"
+				"FAAC - Freeware Advanced Audio Coder\n"
+				"Copyright (C) 2001-2004 The individual contributors\n"
+				"\n"
+				"This library is free software; you can redistribute it and/or modify it under the terms of\n"
+				"the GNU Lesser General Public License as published by the Free Software Foundation;\n"
+				"either version 2.1 of the License, or (at your option) any later version.\n"
+				"\n"
+				"This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n"
+				"without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+				"See the GNU Lesser General Public License for more details.\n"
+				"\n"
+				"You should have received a copy of the GNU Lesser General Public\n"
+				"License along with this library; if not, write to the Free Software\n"
+				"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n";
+
+				MessageBox(hWndDlg,license,"FAAC libray License",MB_OK|MB_ICONINFORMATION);
+			}
+			break;
+
+#ifdef USE_OUTPUT_FOLDER
+		case IDC_BTN_BROWSE:
+			{
+			BROWSEINFO bi;
+			ITEMIDLIST *idlist;
+
+				GetDlgItemText(hWndDlg, IDC_E_BROWSE, config_AACoutdir, MAX_PATH);
+				bi.hwndOwner = hWndDlg;
+				bi.pidlRoot = 0;
+				bi.pszDisplayName = config_AACoutdir;
+				bi.lpszTitle = "Select a directory for aac/mp4 file output:";
+				bi.ulFlags = BIF_RETURNONLYFSDIRS;
+				bi.lpfn = BrowseCallbackProc;
+				bi.lParam = (LPARAM)config_AACoutdir;
+				
+				idlist = SHBrowseForFolder(&bi);
+				if(idlist)
+				{
+					SHGetPathFromIDList(idlist, config_AACoutdir);
+					SetDlgItemText(hWndDlg, IDC_E_BROWSE, config_AACoutdir);
+				}
+			}
+			break;
+#endif			
+		case IDC_BTN_ARTFILE:
+			{
+			OPENFILENAME ofn;
+			char ArtFilename[MAX_PATH]="";
+
+				GetDlgItemText(hWndDlg, IDC_E_ARTFILE, ArtFilename, MAX_PATH);
+				ofn.lStructSize			= sizeof(OPENFILENAME);
+				ofn.hwndOwner			= (HWND)hWndDlg;
+				ofn.lpstrFilter			= "Cover art files (*.gif,*jpg,*.png)\0*.gif;*.jpg;*.png\0";
+				ofn.lpstrCustomFilter	= NULL;
+				ofn.nFilterIndex		= 1;
+				ofn.lpstrFile			= ArtFilename;
+				ofn.nMaxFile			= MAX_PATH; //sizeof ArtFilename;
+				ofn.lpstrFileTitle		= NULL;
+				ofn.nMaxFileTitle		= 0;
+				ofn.lpstrInitialDir		= NULL;
+				ofn.lpstrTitle			= "Select cover art file";
+				ofn.Flags				= OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ENABLESIZING;
+				ofn.lpstrDefExt			= NULL;//"jpg";
+				ofn.hInstance			= hInstance;
+
+				if(GetOpenFileName(&ofn))
+					SetDlgItemText(hWndDlg, IDC_E_ARTFILE, ArtFilename);
+			}
+			break;
+
+#ifdef USE_IMPORT_TAG
+		case IDC_BTN_BROWSEIMPORT:
+			{
+			char path[MAX_PATH];
+			BROWSEINFO bi;
+			ITEMIDLIST *idlist;
+
+				GetDlgItemText(hWndDlg, IDC_E_SOURCEPATH, path, MAX_PATH);
+				bi.hwndOwner = hWndDlg;
+				bi.pidlRoot = 0;
+				bi.pszDisplayName = path;
+				bi.lpszTitle = "Select the folder where source files are stored:";
+				bi.ulFlags = BIF_RETURNONLYFSDIRS;
+				bi.lpfn = BrowseCallbackProc;
+				bi.lParam = (LPARAM)path;
+				
+				idlist=SHBrowseForFolder(&bi);
+				if(idlist)
+				{
+					SHGetPathFromIDList(idlist, path);
+					SetDlgItemText(hWndDlg, IDC_E_SOURCEPATH, path);
+				}
+			}
+			break;
+#endif			
+		case IDC_RADIO_MPEG4:
+			EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LTP), !IsDlgButtonChecked(hWndDlg,IDC_CHK_AUTOCFG));
+			break;
+			
+		case IDC_RADIO_MPEG2:
+			EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LTP), FALSE);
+			DISABLE_LTP
+			break;
+
+		case IDC_CHK_AUTOCFG:
+			{
+			BYTE Enabled=IsDlgButtonChecked(hWndDlg,IDC_CHK_AUTOCFG);
+				DISABLE_CTRLS_ENC(!Enabled);
+				if(!Enabled)
+					SendMessage(hWndDlg, WM_INITDIALOG, 0L, 0L);
+				else
+				{
+					SetDlgItemInt(hWndDlg, IDC_CB_QUALITY, DEF_QUALITY, FALSE);
+					SetDlgItemInt(hWndDlg, IDC_CB_BITRATE, DEF_BITRATE, FALSE);
+					SetDlgItemInt(hWndDlg, IDC_CB_BANDWIDTH, DEF_BANDWIDTH, FALSE);
+
+					CheckDlgButton(hWndDlg,IDC_RADIO_MPEG4,FALSE);
+					CheckDlgButton(hWndDlg,IDC_RADIO_MPEG2,FALSE);
+					if(DEF_MPEGVER==MPEG4)
+						CheckDlgButton(hWndDlg,IDC_RADIO_MPEG4,TRUE);
+					else
+						CheckDlgButton(hWndDlg,IDC_RADIO_MPEG2,TRUE);
+					
+					CheckDlgButton(hWndDlg,IDC_RADIO_MAIN,FALSE);
+					CheckDlgButton(hWndDlg,IDC_RADIO_LOW,FALSE);
+					CheckDlgButton(hWndDlg,IDC_RADIO_SSR,FALSE);
+					CheckDlgButton(hWndDlg,IDC_RADIO_LTP,FALSE);
+					switch(DEF_PROFILE)
+					{
+					case MAIN:
+						CheckDlgButton(hWndDlg,IDC_RADIO_MAIN,TRUE);
+						break;
+					case LOW:
+						CheckDlgButton(hWndDlg,IDC_RADIO_LOW,TRUE);
+						break;
+					case SSR:
+						CheckDlgButton(hWndDlg,IDC_RADIO_SSR,TRUE);
+						break;
+					case LTP:
+						CheckDlgButton(hWndDlg,IDC_RADIO_LTP,TRUE);
+						DISABLE_LTP
+						break;
+					}
+					
+					CheckDlgButton(hWndDlg,IDC_RADIO_RAW,FALSE);
+					CheckDlgButton(hWndDlg,IDC_RADIO_ADTS,FALSE);
+					switch(DEF_HEADER)
+					{
+					case RAW:
+						CheckDlgButton(hWndDlg,IDC_RADIO_RAW,TRUE);
+						break;
+					case ADTS:
+						CheckDlgButton(hWndDlg,IDC_RADIO_ADTS,TRUE);
+						break;
+					}
+					
+					CheckDlgButton(hWndDlg, IDC_CHK_ALLOWMIDSIDE, DEF_MIDSIDE);
+					CheckDlgButton(hWndDlg, IDC_CHK_USETNS, DEF_TNS);
+					CheckDlgButton(hWndDlg, IDC_CHK_USELFE, DEF_LFE);
+
+					if(DEF_USEQUALTY)
+						CheckDlgButton(hWndDlg,IDC_RADIO_QUALITY,true);
+					else
+						CheckDlgButton(hWndDlg,IDC_RADIO_BITRATE,true);
+
+					if(DEF_QUALITY<10)
+						SetDlgItemInt(hWndDlg, IDC_CB_QUALITY, 10, FALSE);
+					else
+						if(DEF_QUALITY>500)
+							SetDlgItemInt(hWndDlg, IDC_CB_QUALITY, 500, FALSE);
+						else
+							SetDlgItemInt(hWndDlg, IDC_CB_QUALITY, DEF_QUALITY, FALSE);
+
+					switch(DEF_BITRATE)
+					{
+					case 0:
+						SendMessage(GetDlgItem(hWndDlg, IDC_CB_BITRATE), CB_SETCURSEL, 0, 0);
+//						SetDlgItemInt(hWndDlg, IDC_CB_BITRATE, 128, FALSE);
+						break;
+					default:
+						SetDlgItemInt(hWndDlg, IDC_CB_BITRATE, DEF_BITRATE, FALSE);
+						break;
+					}
+					switch(DEF_BANDWIDTH)
+					{
+					case 0:
+						SendMessage(GetDlgItem(hWndDlg, IDC_CB_BANDWIDTH), CB_SETCURSEL, 0, 0);
+						break;
+					case 0xffffffff:
+						SendMessage(GetDlgItem(hWndDlg, IDC_CB_BANDWIDTH), CB_SETCURSEL, 1, 0);
+						break;
+					default:
+						SetDlgItemInt(hWndDlg, IDC_CB_BANDWIDTH, DEF_BANDWIDTH, FALSE);
+						break;
+					}
+					
+					SendMessage(GetDlgItem(hWndDlg, IDC_CB_EXT), CB_SETCURSEL, DEF_WRITEMP4, 0);
+//					DISABLE_CTRLS_ENC(!Enabled);
+				}
+			}
+			break;
+
+		case IDC_CHK_TAG:
+		case IDC_CB_EXT:
+			{
+			char TagImport=IsDlgButtonChecked(hWndDlg,IDC_CHK_IMPORTTAG);
+			char TagEnabled=IsDlgButtonChecked(hWndDlg,IDC_CHK_TAG);
+				ENABLE_TAG(TagEnabled && !TagImport);
+			char Enabled=SendMessage(GetDlgItem(hWndDlg, IDC_CB_EXT), CB_GETCURSEL, 0, 0)!=0;
+				ENABLE_AACTAGS(TagEnabled && !TagImport && Enabled);
+			}
+			break;
+#ifdef USE_IMPORT_TAG
+		case IDC_CHK_IMPORTTAG:
+			SendMessage(hWndDlg, WM_COMMAND, IDC_CHK_TAG, 0);
+			break;
+#endif
+		}
+		break; // End of WM_COMMAND
+	default: 
+		return FALSE;
+	}
+	
+	return TRUE;
+} // End of DIALOGSMsgProc                                      
--- /dev/null
+++ b/common/Cfaac/EncDialog.h
@@ -1,0 +1,2 @@
+extern BOOL DialogMsgProcAbout(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam);
+extern BOOL CALLBACK DIALOGMsgProcEnc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam);
--- /dev/null
+++ b/common/Cfaac/FAAC.rc
@@ -1,0 +1,343 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ENCODER DIALOGEX 0, 0, 338, 219
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | 
+    WS_SYSMENU
+CAPTION "MPEG4-AAC options"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+    DEFPUSHBUTTON   "&OK",IDOK,12,200,36,14
+    PUSHBUTTON      "&Cancel",IDCANCEL,48,200,36,14
+    PUSHBUTTON      "&About",IDC_BTN_ABOUT,84,200,36,14
+    PUSHBUTTON      "&License",IDC_BTN_LICENSE,120,200,36,14
+    CONTROL         "Automatic configuration",IDC_CHK_AUTOCFG,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,4,4,90,10
+    CONTROL         "Main",IDC_RADIO_MAIN,"Button",BS_AUTORADIOBUTTON | 
+                    WS_GROUP,9,28,31,10
+    CONTROL         "LC",IDC_RADIO_LOW,"Button",BS_AUTORADIOBUTTON,9,40,25,
+                    10
+    CONTROL         "LTP",IDC_RADIO_LTP,"Button",BS_AUTORADIOBUTTON,9,52,29,
+                    10
+    CONTROL         "SSR",IDC_RADIO_SSR,"Button",BS_AUTORADIOBUTTON | NOT 
+                    WS_VISIBLE | WS_DISABLED,9,63,31,10
+    CONTROL         "MPEG4",IDC_RADIO_MPEG4,"Button",BS_AUTORADIOBUTTON | 
+                    WS_GROUP,62,27,40,10
+    CONTROL         "MPEG2",IDC_RADIO_MPEG2,"Button",BS_AUTORADIOBUTTON,62,
+                    40,40,9
+    CONTROL         "Raw",IDC_RADIO_RAW,"Button",BS_AUTORADIOBUTTON | 
+                    WS_GROUP,112,27,42,10
+    CONTROL         "ADTS",IDC_RADIO_ADTS,"Button",BS_AUTORADIOBUTTON,112,40,
+                    41,9
+    CONTROL         "Quality",IDC_RADIO_QUALITY,"Button",BS_AUTORADIOBUTTON | 
+                    WS_GROUP,9,84,37,10
+    COMBOBOX        IDC_CB_QUALITY,102,81,48,97,CBS_DROPDOWN | WS_VSCROLL | 
+                    WS_GROUP | WS_TABSTOP
+    CONTROL         "Bitrate",IDC_RADIO_BITRATE,"Button",BS_AUTORADIOBUTTON,
+                    9,100,36,10
+    COMBOBOX        IDC_CB_BITRATE,102,97,48,86,CBS_DROPDOWN | WS_VSCROLL | 
+                    WS_TABSTOP
+    LTEXT           "Cutoff",IDC_STATIC,21,121,20,8
+    COMBOBOX        IDC_CB_BANDWIDTH,102,118,48,81,CBS_DROPDOWN | WS_VSCROLL | 
+                    WS_TABSTOP
+    LTEXT           "Write",IDC_STATIC,22,138,18,8
+    COMBOBOX        IDC_CB_EXT,102,135,48,81,CBS_DROPDOWNLIST | WS_VSCROLL | 
+                    WS_TABSTOP
+    CONTROL         "Allow Mid/Side",IDC_CHK_ALLOWMIDSIDE,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,9,152,63,10
+    CONTROL         "Use TNS",IDC_CHK_USETNS,"Button",BS_AUTOCHECKBOX | NOT 
+                    WS_VISIBLE | WS_DISABLED | WS_TABSTOP,9,162,45,10
+    CONTROL         "Use LFE channel",IDC_CHK_USELFE,"Button",
+                    BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | 
+                    WS_TABSTOP,88,152,67,10
+    EDITTEXT        IDC_E_BROWSE,50,172,83,14,ES_AUTOHSCROLL
+    PUSHBUTTON      "Browse",IDC_BTN_BROWSE,137,172,18,14,BS_BITMAP | 
+                    BS_FLAT
+    GROUPBOX        "",IDC_GRP_TAG,160,4,174,210
+    CONTROL         "Tag",IDC_CHK_TAG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+                    165,3,29,10
+    CONTROL         "Import",IDC_CHK_IMPORTTAG,"Button",BS_AUTOCHECKBOX | 
+                    NOT WS_VISIBLE | WS_TABSTOP,165,15,35,10
+    EDITTEXT        IDC_E_SOURCEPATH,207,11,63,14,ES_AUTOHSCROLL | NOT 
+                    WS_VISIBLE
+    PUSHBUTTON      "Browse",IDC_BTN_BROWSEIMPORT,273,11,18,14,BS_BITMAP | 
+                    BS_FLAT | NOT WS_VISIBLE
+    EDITTEXT        IDC_E_SOURCEEXT,294,11,34,14,ES_AUTOHSCROLL | NOT 
+                    WS_VISIBLE
+    EDITTEXT        IDC_E_ARTIST,207,27,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_TITLE,207,42,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_ALBUM,207,57,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_YEAR,207,72,121,14,ES_AUTOHSCROLL
+    COMBOBOX        IDC_CB_GENRE,207,87,121,161,CBS_DROPDOWN | WS_VSCROLL | 
+                    WS_TABSTOP
+    EDITTEXT        IDC_E_WRITER,207,101,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_COMMENT,207,116,121,29,ES_MULTILINE | 
+                    ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_COMPILATION,207,146,121,14,ES_AUTOHSCROLL | NOT 
+                    WS_VISIBLE
+    CONTROL         "Part of a compilation",IDC_CHK_COMPILATION,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,165,148,80,10
+    EDITTEXT        IDC_E_TRACK,233,162,40,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_NTRACKS,288,162,40,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_DISK,233,177,40,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_NDISKS,288,177,40,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_ARTFILE,207,192,98,14,ES_AUTOHSCROLL
+    PUSHBUTTON      "&...",IDC_BTN_ARTFILE,311,192,17,14,BS_BITMAP | BS_FLAT
+    GROUPBOX        "AAC type",IDC_STATIC,56,16,48,52
+    GROUPBOX        "Profile",IDC_STATIC,4,16,48,52
+    GROUPBOX        "Header",IDC_STATIC,108,16,48,52
+    GROUPBOX        "Encoding mode",IDC_STATIC,4,73,152,42
+    LTEXT           "Artist",IDC_STATIC,165,29,16,8
+    LTEXT           "Title",IDC_STATIC,165,44,14,8
+    LTEXT           "Album",IDC_STATIC,165,59,20,8
+    LTEXT           "Year",IDC_STATIC,165,74,16,8
+    LTEXT           "Genre",IDC_STATIC,165,89,20,8
+    LTEXT           "Writer",IDC_STATIC,165,103,20,8
+    LTEXT           "Comment\n(ctrl-Enter\nto go down)",IDC_STATIC,165,118,
+                    37,26
+    LTEXT           "Track",IDC_STATIC,165,166,20,8
+    LTEXT           "/",IDC_STATIC,277,166,8,8
+    LTEXT           "Disk",IDC_STATIC,165,180,15,8
+    LTEXT           "/",IDC_STATIC,277,180,8,8
+    LTEXT           "Cover art file",IDC_STATIC,165,195,40,8
+    LTEXT           "Output folder",IDC_L_BROWSE,4,175,42,8
+END
+
+IDD_DECODER DIALOGEX 0, 0, 162, 153
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | 
+    WS_SYSMENU
+CAPTION "Raw .AAC options"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "&OK",IDOK,47,132,36,14
+    PUSHBUTTON      "&Cancel",IDCANCEL,83,132,36,14
+    PUSHBUTTON      "&About",IDC_BTN_ABOUT,119,132,36,14
+    CONTROL         "Main",IDC_RADIO_MAIN,"Button",BS_AUTORADIOBUTTON | 
+                    WS_GROUP,19,33,31,10
+    CONTROL         "Low",IDC_RADIO_LOW,"Button",BS_AUTORADIOBUTTON,19,44,29,
+                    10
+    CONTROL         "SSR",IDC_RADIO_SSR,"Button",BS_AUTORADIOBUTTON | 
+                    WS_DISABLED,19,56,31,10
+    CONTROL         "LTP",IDC_RADIO_LTP,"Button",BS_AUTORADIOBUTTON,19,68,29,
+                    10
+    GROUPBOX        "Profile",IDC_STATIC,13,23,48,70
+    COMBOBOX        IDC_CB_SAMPLERATE,72,74,69,87,CBS_DROPDOWN | WS_DISABLED | 
+                    WS_VSCROLL | WS_TABSTOP
+    CONTROL         "Default settings",IDC_CHK_DEFAULTCFG,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,13,7,64,10
+    GROUPBOX        "Sample rate",IDC_STATIC,66,61,81,32
+    CONTROL         "HE",IDC_RADIO_HE,"Button",BS_AUTORADIOBUTTON | 
+                    WS_DISABLED,19,80,26,10
+    CONTROL         "Down matrix 5.1 to 2 channels",IDC_CHK_DOWNMATRIX,
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,98,111,10
+    CONTROL         "Assume old ADTS format",IDC_CHK_OLDADTS,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,13,110,95,10
+    COMBOBOX        IDC_CB_BITSPERSAMPLE,72,35,69,87,CBS_DROPDOWNLIST | 
+                    WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+    GROUPBOX        "Output bits per sample",IDC_STATIC,66,23,81,32
+    GROUPBOX        "",IDC_GRP_DEFAULT,7,8,147,118
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_ENCODER, DIALOG
+    BEGIN
+        LEFTMARGIN, 4
+        RIGHTMARGIN, 334
+        TOPMARGIN, 4
+        BOTTOMMARGIN, 214
+    END
+
+    IDD_DECODER, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 154
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 146
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Italian (Italy) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA)
+#ifdef _WIN32
+LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUT DIALOGEX 0, 0, 191, 230
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
+CAPTION "About"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "&OK",IDOK,145,208,39,14
+    CONTROL         104,IDC_AUDIOCODING,"Static",SS_BITMAP | SS_NOTIFY | 
+                    SS_SUNKEN,7,7,178,69
+    CONTROL         107,IDC_MPEG4IP,"Static",SS_BITMAP | SS_NOTIFY | 
+                    SS_SUNKEN,7,202,59,20
+    CONTROL         106,IDC_EMAIL,"Static",SS_BITMAP | SS_NOTIFY,96,204,43,
+                    18
+    LTEXT           "Text",IDC_L_ABOUT,7,55,177,142
+    ICON            IDI_ID3,IDC_ID3,70,202,20,20,SS_NOTIFY | SS_SUNKEN
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_ABOUT, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 184
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 222
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_AUDIOCODING         BITMAP                  "AudioCoding.bmp"
+IDB_EMAIL               BITMAP                  "Email.bmp"
+IDB_MPEG4IP             BITMAP                  "mpeg4ip-v.bmp"
+IDB_BROWSE              BITMAP                  "Open.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ID3                 ICON                    "id3v2.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "041004b0"
+        BEGIN
+            VALUE "FileDescription", "FAAC plugin"
+            VALUE "FileVersion", "1, 0, 0, 0"
+            VALUE "InternalName", "FAAC"
+            VALUE "LegalCopyright", "Copyright (C) 2004"
+            VALUE "OriginalFilename", "FAAC.dll"
+            VALUE "ProductName", " FAAC Dynamic Link Library"
+            VALUE "ProductVersion", "1, 0, 0, 0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x410, 1200
+    END
+END
+
+#endif    // Italian (Italy) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
binary files /dev/null b/common/Cfaac/Open.bmp differ
--- /dev/null
+++ b/common/Cfaac/ReadMe.txt
@@ -1,0 +1,20 @@
++----------------------------------------------------------------+
+|                                                                |
+|                           Cfaac Readme                         |
+|                           ------------                         |
+|                                                                |
++----------------------------------------------------------------+
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY.
+
+----------------------------------------------------------------------------
+
+Cfaac is a set of classes to develop plugins (to import/export .aac/.mp4 files) with ease.
+
+----------------------------------------------------------------------------
+
+For suggestions, bugs report, etc., you can contact me at
[email protected]
--- /dev/null
+++ b/common/Cfaac/TypeDef.h
@@ -1,0 +1,45 @@
+/*
+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:
[email protected]
+*/
+
+//---------------------------------------------------------------------------
+#ifndef TypeDefH
+#define TypeDefH
+//---------------------------------------------------------------------------
+
+/* typedef.h */
+
+#ifndef BYTE
+typedef unsigned char    BYTE;
+#endif
+#ifndef WORD
+typedef unsigned short   WORD;
+#endif
+#ifndef DWORD
+typedef unsigned long    DWORD;
+#endif
+#ifndef QWORD
+typedef unsigned __int64 QWORD;
+#endif
+
+//---------------------------------------------------------------------------
+#endif
+//---------------------------------------------------------------------------
+
binary files /dev/null b/common/Cfaac/id3v2.ico differ
binary files /dev/null b/common/Cfaac/mpeg4ip-v.bmp differ
--- /dev/null
+++ b/common/Cfaac/resource.h
@@ -1,0 +1,81 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by FAAC.rc
+//
+#define IDD_ENCODER                     101
+#define IDD_DECODER                     102
+#define IDD_ABOUT                       103
+#define IDB_AUDIOCODING                 104
+#define IDB_EMAIL                       106
+#define IDB_MPEG4IP                     107
+#define IDB_BROWSE                      108
+#define IDI_ID3                         110
+#define IDC_CHK_DEFAULTCFG              1000
+#define IDC_CHK_DOWNMATRIX              1001
+#define IDC_CHK_OLDADTS                 1002
+#define IDC_CB_SAMPLERATE               1003
+#define IDC_AUDIOCODING                 1004
+#define IDC_CB_BITSPERSAMPLE            1004
+#define IDC_EMAIL                       1005
+#define IDC_MPEG4IP                     1006
+#define IDC_E_BROWSE                    1007
+#define IDC_BTN_BROWSE                  1008
+#define IDC_RADIO_MPEG4                 1009
+#define IDC_RADIO_MPEG2                 1010
+#define IDC_RADIO_LOW                   1011
+#define IDC_RADIO_MAIN                  1012
+#define IDC_RADIO_SSR                   1013
+#define IDC_RADIO_LTP                   1014
+#define IDC_RADIO_RAW                   1015
+#define IDC_RADIO_HE                    1016
+#define IDC_BTN_BROWSE2                 1016
+#define IDC_BTN_BROWSEIMPORT            1016
+#define IDC_RADIO_ADTS                  1017
+#define IDC_CB_BANDWIDTH                1018
+#define IDC_CB_BITRATE                  1019
+#define IDC_CHK_ALLOWMIDSIDE            1020
+#define IDC_CHK_USETNS                  1021
+#define IDC_CHK_USELFE                  1022
+#define IDC_CHK_AUTOCFG                 1023
+#define IDC_BTN_ABOUT                   1024
+#define IDC_L_ABOUT                     1025
+#define IDC_BTN_ARTFILE                 1026
+#define IDC_CHK_USETNS2                 1027
+#define IDC_CB_EXT                      1028
+#define IDC_RADIO_BITRATE               1030
+#define IDC_RADIO_QUALITY               1031
+#define IDC_CB_QUALITY                  1032
+#define IDC_E_ARTIST                    1034
+#define IDC_CHK_TAG                     1035
+#define IDC_E_TITLE                     1036
+#define IDC_E_ALBUM                     1037
+#define IDC_E_YEAR                      1038
+#define IDC_CB_GENRE                    1039
+#define IDC_E_WRITER                    1040
+#define IDC_E_COMMENT                   1041
+#define IDC_E_TRACK                     1042
+#define IDC_E_NTRACKS                   1043
+#define IDC_E_DISK                      1044
+#define IDC_E_NDISKS                    1045
+#define IDC_GRP_TAG                     1046
+#define IDC_E_COMPILATION               1047
+#define IDC_E_ARTFILE                   1048
+#define IDC_BTN_LICENSE                 1049
+#define IDC_CHK_COMPILATION             1050
+#define IDC_GRP_DEFAULT                 1051
+#define IDC_ID3                         1052
+#define IDC_L_BROWSE                    1054
+#define IDC_CHK_IMPORTTAG               1055
+#define IDC_E_SOURCEEXT                 1056
+#define IDC_E_SOURCEPATH                1057
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        111
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1057
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif