shithub: aacenc

Download patch

ref: 7caf982e9711c30024db3149fca39c6ae5fbee6f
parent: 668ec4a6c0b23d65270c609ec748879b3075c6ee
author: menno <menno>
date: Thu May 13 04:58:51 EDT 2004

New plugins for FAAC:
- tagging

--- a/plugins/cooledit/CRegistry.cpp
+++ b/plugins/cooledit/CRegistry.cpp
@@ -1,5 +1,5 @@
 /*
-FAAC - codec plugin for Cooledit
+CRegistry class
 Copyright (C) 2002-2004 Antonio Foranna
 
 This program is free software; you can redistribute it and/or modify
@@ -19,47 +19,56 @@
 ntnfrn_email-temp@yahoo.it
 */
 
-//#include "stdafx.h"
-#include <windows.h>
-#include <stdlib.h>		// malloc, free
-#include <string.h>
 #include "CRegistry.h"
 
+//************************************************************************************************
 
-
-// *****************************************************************************
-
-
-
 CRegistry::CRegistry()
 {
 	regKey=NULL;
 	path=NULL;
 }
+//------------------------------------------------------------------------------------------------
 
 CRegistry::~CRegistry()
 {
-	closeReg();
+	if(regKey)
+		RegCloseKey(regKey);
+	if(path)
+		free(path);
 }
+//************************************************************************************************
+/*
+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::openReg(HKEY hKey, char *SubKey)
+BOOL CRegistry::Open(HKEY hKey, char *SubKey)
 {
 	if(regKey)
 		RegCloseKey(regKey);
-	if(RegOpenKeyEx(hKey, SubKey, NULL , KEY_ALL_ACCESS , &regKey)==ERROR_SUCCESS)
+	if(RegOpenKeyEx(hKey, SubKey, 0, KEY_ALL_ACCESS, &regKey)==ERROR_SUCCESS)
 	{
 		setPath(SubKey);
 		return TRUE;
@@ -71,13 +80,13 @@
 		return FALSE;
 	}
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-BOOL CRegistry::openCreateReg(HKEY hKey, char *SubKey)
+BOOL CRegistry::OpenCreate(HKEY hKey, char *SubKey)
 {
 	if(regKey)
 		RegCloseKey(regKey);
-	if(RegOpenKeyEx(hKey, SubKey, NULL , KEY_ALL_ACCESS , &regKey)==ERROR_SUCCESS)
+	if(RegOpenKeyEx(hKey, SubKey, 0, KEY_ALL_ACCESS, &regKey)==ERROR_SUCCESS)
 	{
 		setPath(SubKey);
 		return TRUE;
@@ -85,7 +94,7 @@
 	else // open failed -> create the key
 	{
 	DWORD disp;
-		RegCreateKeyEx(hKey , SubKey, NULL , NULL, REG_OPTION_NON_VOLATILE , KEY_ALL_ACCESS , NULL , &regKey , &disp );
+		RegCreateKeyEx(hKey, SubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &regKey, &disp);
 		if(disp==REG_CREATED_NEW_KEY) 
 		{
 			setPath(SubKey);
@@ -99,9 +108,9 @@
 		}
 	}
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::closeReg()
+void CRegistry::Close()
 {
 	if(regKey)
 		RegCloseKey(regKey);
@@ -110,93 +119,78 @@
 		delete path; 
 	path=NULL;
 }
+//************************************************************************************************
+//************************************************************************************************
+//************************************************************************************************
 
-
-
-// *****************************************************************************
-
-
-
-void CRegistry::DeleteRegVal(char *SubKey)
+void CRegistry::DeleteVal(char *SubKey)
 {
 	RegDeleteValue(regKey,SubKey);
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::DeleteRegKey(char *SubKey)
+void CRegistry::DeleteKey(char *SubKey)
 {
 	RegDeleteKey(regKey,SubKey);
 }
 
+//************************************************************************************************
+//************************************************************************************************
+//************************************************************************************************
 
-
-// *****************************************************************************
-
-
-
-void CRegistry::setRegBool(char *keyStr , BOOL val)
+void CRegistry::SetBool(char *keyStr, BOOL val)
 {
 BOOL tempVal;
 DWORD len;
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
 		tempVal!=val)
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(BOOL));
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, (BYTE *)&val, sizeof(BOOL));
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::setRegBool(char *keyStr , bool val)
+void CRegistry::SetByte(char *keyStr, BYTE val)
 {
-bool tempVal;
-DWORD len;
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS ||
-		tempVal!=val)
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(bool));
-}
-// -----------------------------------------------------------------------------------------------
-
-void CRegistry::setRegByte(char *keyStr , BYTE val)
-{
 DWORD	t=val;
 DWORD	tempVal;
 DWORD	len;
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
 		tempVal!=val)
-		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&t , sizeof(DWORD));
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&t, sizeof(DWORD));
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::setRegWord(char *keyStr , WORD val)
+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 ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
 		tempVal!=val)
-		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&t , sizeof(DWORD));
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&t, sizeof(DWORD));
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::setRegDword(char *keyStr , DWORD val)
+void CRegistry::SetDword(char *keyStr, DWORD val)
 {
 DWORD tempVal;
 DWORD len;
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
 		tempVal!=val)
-		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&val , sizeof(DWORD));
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&val, sizeof(DWORD));
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::setRegFloat(char *keyStr , float val)
+void CRegistry::SetFloat(char *keyStr, float val)
 {
 float tempVal;
 DWORD len;
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
 		tempVal!=val)
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(float));
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, (BYTE *)&val, sizeof(float));
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::setRegStr(char *keyStr , char *valStr)
+void CRegistry::SetStr(char *keyStr, char *valStr)
 {
 DWORD len;
 DWORD slen=strlen(valStr)+1;
@@ -204,35 +198,35 @@
 	if(!valStr || !*valStr)
 		return;
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, NULL , &len )!=ERROR_SUCCESS ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, NULL, &len )!=ERROR_SUCCESS ||
 		len!=slen)
-		RegSetValueEx(regKey , keyStr , NULL , REG_SZ , (BYTE *)valStr , 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 ||
+		if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)tempVal, &len )!=ERROR_SUCCESS ||
 			strcmpi(tempVal,valStr))
-			RegSetValueEx(regKey , keyStr , NULL , REG_SZ , (BYTE *)valStr , slen);
+			RegSetValueEx(regKey, keyStr, 0, REG_SZ, (BYTE *)valStr, slen);
 		delete tempVal;
 	}
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::setRegValN(char *keyStr , BYTE *addr,  DWORD size)
+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 ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, NULL, &len )!=ERROR_SUCCESS ||
 		len!=size)
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , addr , 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 ||
+		if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)tempVal, &len )!=ERROR_SUCCESS ||
 			memcmp(tempVal,addr,len))
-			RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , addr , size);
+			RegSetValueEx(regKey, keyStr, 0, REG_BINARY, addr, size);
 		delete tempVal;
 	}
 }
@@ -239,128 +233,130 @@
 
 
 
-// *****************************************************************************
+//************************************************************************************************
+//************************************************************************************************
+//************************************************************************************************
 
 
 
-BOOL CRegistry::getSetRegBool(char *keyStr, BOOL val)
+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 , NULL , REG_BINARY , (BYTE *)&val , sizeof(BOOL));
-		return val;
-	}
-	return tempVal;
-}
-// -----------------------------------------------------------------------------------------------
-
-bool CRegistry::getSetRegBool(char *keyStr, bool val)
-{
 bool tempVal;
 DWORD len=sizeof(bool);
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS)
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
 	{
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(bool));
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, (BYTE *)&val, sizeof(bool));
 		return val;
 	}
 	return tempVal;
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-BYTE CRegistry::getSetRegByte(char *keyStr, BYTE val)
+BYTE CRegistry::GetSetByte(char *keyStr, BYTE val)
 {
 DWORD tempVal;
 DWORD len=sizeof(DWORD);
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS)
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
 	{
 		tempVal=val;
-		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&tempVal , sizeof(DWORD));
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&tempVal, sizeof(DWORD));
 		return val;
 	}
 	return (BYTE)tempVal;
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-WORD CRegistry::getSetRegWord(char *keyStr, WORD val)
+WORD CRegistry::GetSetWord(char *keyStr, WORD val)
 {
 DWORD tempVal;
 DWORD len=sizeof(DWORD);
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS)
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
 	{
 		tempVal=val;
-		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&tempVal , sizeof(DWORD));
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&tempVal, sizeof(DWORD));
 		return val;
 	}
 	return (WORD)tempVal;
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-DWORD CRegistry::getSetRegDword(char *keyStr, DWORD val)
+DWORD CRegistry::GetSetDword(char *keyStr, DWORD val)
 {
 DWORD tempVal;
 DWORD len=sizeof(DWORD);
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS)
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
 	{
-		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&val , sizeof(DWORD));
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&val, sizeof(DWORD));
 		return val;
 	}
 	return (DWORD)tempVal;
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-float CRegistry::getSetRegFloat(char *keyStr, float val)
+float CRegistry::GetSetFloat(char *keyStr, float val)
 {
 float tempVal;
 DWORD len=sizeof(float);
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS)
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
 	{
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(float));
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, (BYTE *)&val, sizeof(float));
 		return val;
 	}
 	return tempVal;
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-int CRegistry::getSetRegStr(char *keyStr, char *tempString, char *dest, int maxLen)
+char *CRegistry::GetSetStr(char *keyStr, char *String)
 {
-DWORD tempLen=maxLen;
+long	retVal;
+DWORD	Len;
+char	*dest=NULL;
 	
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *) dest , &tempLen )!=ERROR_SUCCESS)
+	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(!tempString)
-		{
-			*dest=0;
-			return 0;
-		}
-		strcpy(dest,tempString);
-		tempLen=strlen(tempString)+1;
-		RegSetValueEx(regKey , keyStr , NULL , REG_SZ , (BYTE *)tempString , tempLen);
+		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 tempLen;
+	return dest;
 }
 // -----------------------------------------------------------------------------------------------
 
-int CRegistry::getSetRegValN(char *keyStr, BYTE *tempAddr, BYTE *addr, DWORD size)
+int CRegistry::GetSetValN(char *keyStr, BYTE *defData, DWORD defSize, BYTE **dest)
 {
-DWORD tempLen=size;
+long	retVal;
+DWORD	size;
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)addr , &tempLen )!=ERROR_SUCCESS)
+	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(!tempAddr)
-		{
-			*addr=0;
+		if(dest)
+			free(dest);
+		if(!defData)
 			return 0;
-		}
-		memcpy(addr,tempAddr,size);
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)addr , size);
+
+		size=defSize;
+		if(!(*dest=(BYTE *)malloc(size)))
+			return 0;
+		memcpy(*dest,defData,size);
+		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)*dest , size);
 	}
-	return tempLen;
+	return size;
 }
--- a/plugins/cooledit/CRegistry.h
+++ b/plugins/cooledit/CRegistry.h
@@ -1,5 +1,5 @@
 /*
-FAAC - codec plugin for Cooledit
+CRegistry class
 Copyright (C) 2002-2004 Antonio Foranna
 
 This program is free software; you can redistribute it and/or modify
@@ -19,9 +19,16 @@
 ntnfrn_email-temp@yahoo.it
 */
 
-#ifndef registry_h
-#define registry_h
+//---------------------------------------------------------------------------
+#ifndef CRegistryH
+#define CRegistryH
+//---------------------------------------------------------------------------
 
+#include <windows.h>
+#include <stdlib.h>
+#include <string.h>
+//#include <memory.h>
+
 class CRegistry 
 {
 public:
@@ -28,31 +35,30 @@
 			CRegistry();
 			~CRegistry();
 
-	BOOL	openReg(HKEY hKey, char *SubKey);
-	BOOL	openCreateReg(HKEY hKey, char *SubKey);
-	void	closeReg();
-	void	DeleteRegVal(char *SubKey);
-	void	DeleteRegKey(char *SubKey);
+	BOOL	Open(HKEY hKey, char *SubKey);
+	BOOL	OpenCreate(HKEY hKey, char *SubKey);
+	void	Close();
+	void	DeleteVal(char *SubKey);
+	void	DeleteKey(char *SubKey);
 
-	void	setRegBool(char *keyStr , BOOL val);
-	void	setRegBool(char *keyStr , bool val);
-	void	setRegByte(char *keyStr , BYTE val);
-	void	setRegWord(char *keyStr , WORD val);
-	void	setRegDword(char *keyStr , DWORD val);
-	void	setRegFloat(char *keyStr , float val);
-	void	setRegStr(char *keyStr , char *valStr);
-	void	setRegValN(char *keyStr , BYTE *addr,  DWORD size);
+	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	getSetRegBool(char *keyStr, BOOL var);
-	bool	getSetRegBool(char *keyStr, bool var);
-	BYTE	getSetRegByte(char *keyStr, BYTE var);
-	WORD	getSetRegWord(char *keyStr, WORD var);
-	DWORD	getSetRegDword(char *keyStr, DWORD var);
-	float	getSetRegFloat(char *keyStr, float var);
-	int		getSetRegStr(char *keyStr, char *tempString, char *dest, int maxLen);
-	int		getSetRegValN(char *keyStr, BYTE *tempAddr, 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
\ No newline at end of file
+
+#endif
--- a/plugins/cooledit/Cfaac.cpp
+++ b/plugins/cooledit/Cfaac.cpp
@@ -27,15 +27,6 @@
 
 
 
-#define FREE_ARRAY(ptr) \
-{ \
-	if(ptr) \
-		free(ptr); \
-	ptr=0; \
-}
-
-// *********************************************************************************************
-
 Cfaac::Cfaac(HANDLE hOut)
 {
 	if(hOut)
@@ -45,14 +36,10 @@
 	}
 
     if(!(hOutput=GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE|GMEM_ZEROINIT,sizeof(MYOUTPUT))))
+	{
 		MessageBox(0, "Memory allocation error: hOutput", APP_NAME " plugin", MB_OK|MB_ICONSTOP); \
-/*
-MYOUTPUT *mo;
-
-	if(!(mo=(MYOUTPUT *)GlobalLock(hOutput)))
-		MessageBox(0, "GlobalLock(hOutput)", APP_NAME " plugin", MB_OK|MB_ICONSTOP); \
-
-	GlobalUnlock(hOutput);*/
+		return;
+	}
 }
 // -----------------------------------------------------------------------------------------------
 
@@ -82,6 +69,15 @@
 	{
 		fclose(mo->aacFile);
 		mo->aacFile=0;
+
+	MY_ENC_CFG	cfg;
+		getFaacCfg(&cfg);
+		if(cfg.Tag.On && mo->Filename)
+		{
+			WriteAacTag(mo->Filename,&cfg.Tag);
+			FREE_ARRAY(mo->Filename);
+		}
+		FreeTag(&cfg.Tag);
 	}
 	else
 	{
@@ -213,7 +209,144 @@
 			break;
 	}
 }
+// *********************************************************************************************
 
+int Cfaac::check_image_header(const char *buf)
+{
+  if (!strncmp(buf, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8))
+    return 1; /* PNG */
+  else if (!strncmp(buf, "\xFF\xD8\xFF\xE0", 4) &&
+	   !strncmp(buf + 6, "JFIF\0", 5))
+    return 1; /* JPEG */
+  else if (!strncmp(buf, "GIF87a", 6) || !strncmp(buf, "GIF89a", 6))
+    return 1; /* GIF */
+  else
+    return 0;
+}
+// -----------------------------------------------------------------------------------------------
+
+int Cfaac::ReadCoverArtFile(char *pCoverArtFile, char **artData)
+{
+FILE *artFile;
+
+	if(!pCoverArtFile || !*pCoverArtFile)
+		return 0;
+
+	if(!(artFile=fopen(pCoverArtFile, "rb")))
+	{
+		MessageBox(NULL,"ReadCoverArtFile: fopen",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;
+}
+
+void Cfaac::WriteMP4Tag(MP4FileHandle MP4File, MP4TAG *Tag)
+{
+char	*art=NULL;
+DWORD	artSize;
+
+char	buf[512], *faac_id_string, *faac_copyright_string;
+	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(Tag->artist) MP4SetMetadataArtist(MP4File, Tag->artist);
+	if(Tag->writer) MP4SetMetadataWriter(MP4File, Tag->writer);
+	if(Tag->title) MP4SetMetadataName(MP4File, Tag->title);
+	if(Tag->album) MP4SetMetadataAlbum(MP4File, Tag->album);
+	if(Tag->trackno>0) MP4SetMetadataTrack(MP4File, Tag->trackno, Tag->ntracks);
+	if(Tag->discno>0) MP4SetMetadataDisk(MP4File, Tag->discno, Tag->ndiscs);
+	if(Tag->compilation) MP4SetMetadataCompilation(MP4File, Tag->compilation);
+	if(Tag->year) MP4SetMetadataYear(MP4File, Tag->year);
+	if(Tag->genre) MP4SetMetadataGenre(MP4File, Tag->genre);
+	if(Tag->comment) MP4SetMetadataComment(MP4File, Tag->comment);
+	artSize=ReadCoverArtFile(Tag->artFileName,&art);
+	if(artSize)
+	{
+		MP4SetMetadataCoverArt(MP4File, (BYTE *)art, artSize);
+		free(art);
+	}
+}
+
+#define ADD_FIELD(id3Tag,NewFrame,ID3FID,ID3FN,data) \
+{ \
+	ID3_Frame *NewFrame=new ID3_Frame(ID3FID); \
+		NewFrame->Field(ID3FN)=data; \
+		id3Tag.AttachFrame(NewFrame); \
+}
+
+void Cfaac::WriteAacTag(char *Filename, MP4TAG *Tag)
+{
+char	buf[512], *faac_id_string, *faac_copyright_string;
+char	*art=NULL;
+DWORD	artSize;
+ID3_Tag id3Tag;
+ID3_Frame *Frame;
+
+	id3Tag.Link(Filename);
+//	Frame=id3Tag.Find(ID3FID_ALBUM);
+//	if(Frame!=NULL)
+//		myTag.RemoveFrame(Frame);
+
+	sprintf(buf, "FAAC v%s", (faacEncGetVersion(&faac_id_string, &faac_copyright_string)==FAAC_CFG_VERSION) ? faac_id_string : " wrong libfaac version");
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_ENCODEDBY,ID3FN_TEXT,buf);
+
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_LEADARTIST,ID3FN_TEXT,Tag->artist);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_COMPOSER,ID3FN_TEXT,Tag->writer);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_TITLE,ID3FN_TEXT,Tag->title);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_ALBUM,ID3FN_TEXT,Tag->album);
+	sprintf(buf,"%d",Tag->trackno);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_TRACKNUM,ID3FN_TEXT,buf);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_YEAR,ID3FN_TEXT,Tag->year);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_CONTENTTYPE,ID3FN_TEXT,Tag->genre);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_COMMENT,ID3FN_TEXT,Tag->comment);
+	artSize=ReadCoverArtFile(Tag->artFileName,&art);
+	if(artSize)
+	{
+		ADD_FIELD(id3Tag,NewFrame,ID3FID_PICTURE,ID3FN_PICTURETYPE,Tag->artFileName);
+		id3Tag.Update();
+		free(art);
+	}
+	else
+		id3Tag.Update();
+}
+
 // *********************************************************************************************
 //									Main functions
 // *********************************************************************************************
@@ -238,24 +371,53 @@
 }
 // *********************************************************************************************
 
+void Cfaac::FreeTag(MP4TAG *Tag)
+{
+	FREE_ARRAY(Tag->artist);
+	FREE_ARRAY(Tag->title);
+	FREE_ARRAY(Tag->album);
+	FREE_ARRAY(Tag->year);
+	FREE_ARRAY(Tag->genre);
+	FREE_ARRAY(Tag->writer);
+	FREE_ARRAY(Tag->comment);
+	FREE_ARRAY(Tag->artFileName);
+}
+// -----------------------------------------------------------------------------------------------
+
 void Cfaac::getFaacCfg(MY_ENC_CFG *cfg)
 { 
 CRegistry reg;
 
-	if(reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME "\\FAAC"))
+	if(reg.OpenCreate(HKEY_CURRENT_USER, REGISTRY_PROGRAM_NAME "\\FAAC"))
 	{
-		cfg->AutoCfg=reg.getSetRegBool("Auto",true);
-		cfg->SaveMP4=reg.getSetRegBool("Write MP4",false);
-		cfg->EncCfg.mpegVersion=reg.getSetRegDword("MPEG version",MPEG4); 
-		cfg->EncCfg.aacObjectType=reg.getSetRegDword("Profile",LOW); 
-		cfg->EncCfg.allowMidside=reg.getSetRegDword("MidSide",true); 
-		cfg->EncCfg.useTns=reg.getSetRegDword("TNS",true); 
-		cfg->EncCfg.useLfe=reg.getSetRegDword("LFE",false);
-		cfg->UseQuality=reg.getSetRegBool("Use quality",false);
-		cfg->EncCfg.quantqual=reg.getSetRegDword("Quality",100); 
-		cfg->EncCfg.bitRate=reg.getSetRegDword("BitRate",0); 
-		cfg->EncCfg.bandWidth=reg.getSetRegDword("BandWidth",0); 
-		cfg->EncCfg.outputFormat=reg.getSetRegDword("Header",ADTS); 
+		cfg->AutoCfg=reg.GetSetBool(REG_AUTO,DEF_AUTO);
+		cfg->SaveMP4=reg.GetSetBool(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); 
+		cfg->OutDir=NULL;
+
+		cfg->Tag.On=reg.GetSetByte(REG_TAGON,0);
+		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.GetSetDword(REG_TRACK,0);
+		cfg->Tag.ntracks=reg.GetSetDword(REG_NTRACKS,0);
+		cfg->Tag.discno=reg.GetSetDword(REG_DISK,0);
+		cfg->Tag.ndiscs=reg.GetSetDword(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);
@@ -266,20 +428,35 @@
 { 
 CRegistry reg;
 
-	if(reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME "\\FAAC"))
+	if(reg.OpenCreate(HKEY_CURRENT_USER, REGISTRY_PROGRAM_NAME "\\FAAC"))
 	{
-		reg.setRegBool("Auto",cfg->AutoCfg); 
-		reg.setRegBool("Write MP4",cfg->SaveMP4); 
-		reg.setRegDword("MPEG version",cfg->EncCfg.mpegVersion); 
-		reg.setRegDword("Profile",cfg->EncCfg.aacObjectType); 
-		reg.setRegDword("MidSide",cfg->EncCfg.allowMidside); 
-		reg.setRegDword("TNS",cfg->EncCfg.useTns); 
-		reg.setRegDword("LFE",cfg->EncCfg.useLfe); 
-		reg.setRegBool("Use quality",cfg->UseQuality); 
-		reg.setRegDword("Quality",cfg->EncCfg.quantqual); 
-		reg.setRegDword("BitRate",cfg->EncCfg.bitRate); 
-		reg.setRegDword("BandWidth",cfg->EncCfg.bandWidth); 
-		reg.setRegDword("Header",cfg->EncCfg.outputFormat); 
+		reg.SetBool(REG_AUTO,cfg->AutoCfg); 
+		reg.SetBool(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.SetByte(REG_TAGON,cfg->Tag.On);
+		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.SetDword(REG_TRACK,cfg->Tag.trackno); 
+		reg.SetDword(REG_NTRACKS,cfg->Tag.ntracks); 
+		reg.SetDword(REG_DISK,cfg->Tag.discno); 
+		reg.SetDword(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);
@@ -313,36 +490,53 @@
 	if(!(mo->buf32bit=(int32_t *)malloc(samplesInput*sizeof(int32_t))))
 		return ERROR_Init("Memory allocation error: 32 bit buffer");
 
-
 	getFaacCfg(&cfg);
 
-	if(cfg.SaveMP4)
+	if(cfg.SaveMP4)// || cfg.Tag.On)
 		if(!strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".aac"))
+		{
 			strcpy(lpstrFilename+lstrlen(lpstrFilename)-4,".mp4");
+		FILE *f=fopen(lpstrFilename,"rb");
+			if(f)
+			{
+			char buf[MAX_PATH+20];
+				sprintf(buf,"Overwrite \"%s\" ?",lpstrFilename);
+				fclose(f);
+				if(MessageBox(NULL,buf,"File already exists!",MB_YESNO|MB_ICONQUESTION)==IDNO)
+					return ERROR_Init(0);//"User abort");
+			}
+		}
 		else
 			if(strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".mp4"))
 				strcat(lpstrFilename,".mp4");
-	mo->WriteMP4=!strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".mp4");
+	mo->WriteMP4=	!strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".mp4") ||
+					!strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".m4a");
 
-	if(cfg.AutoCfg)
+faacEncConfigurationPtr CurFormat=faacEncGetCurrentConfiguration(mo->hEncoder);
+	CurFormat->inputFormat=FAAC_INPUT_32BIT;
+/*	switch(wBitsPerSample)
 	{
-	faacEncConfigurationPtr myFormat=&cfg.EncCfg;
-	faacEncConfigurationPtr CurFormat=faacEncGetCurrentConfiguration(mo->hEncoder);
-		if(mo->WriteMP4)
-			CurFormat->outputFormat=RAW;
-		CurFormat->useLfe=wChannels>=6 ? 1 : 0;
-		if(!faacEncSetConfiguration(mo->hEncoder, CurFormat))
-			return ERROR_Init("Unsupported parameters!");
-	}
-	else
+	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;
-	faacEncConfigurationPtr CurFormat=faacEncGetCurrentConfiguration(mo->hEncoder);
 
 		if(cfg.UseQuality)
 		{
 			CurFormat->quantqual=myFormat->quantqual;
-			CurFormat->bitRate=myFormat->bitRate;
+			CurFormat->bitRate=0;//myFormat->bitRate;
 		}
 		else
 			if(!CurFormat->bitRate)
@@ -361,34 +555,30 @@
 			CurFormat->bandWidth=myFormat->bandWidth;
 			break;
 		}
-/*
-		switch(wBitsPerSample)
-		{
-		case 16:
-			CurFormat->inputFormat=FAAC_INPUT_16BIT;
-			break;
-		case 24:
-			CurFormat->inputFormat=FAAC_INPUT_24BIT;
-			break;
-		case 32:
-			CurFormat->inputFormat=FAAC_INPUT_32BIT;
-			break;
-		default:
-			CurFormat->inputFormat=FAAC_INPUT_NULL;
-			break;
-		}
-*/
 		CurFormat->mpegVersion=myFormat->mpegVersion;
-		CurFormat->outputFormat=mo->WriteMP4 ? 0 : myFormat->outputFormat;
+		CurFormat->outputFormat=myFormat->outputFormat;
 		CurFormat->mpegVersion=myFormat->mpegVersion;
 		CurFormat->aacObjectType=myFormat->aacObjectType;
 		CurFormat->allowMidside=myFormat->allowMidside;
 		CurFormat->useTns=myFormat->useTns;
-		CurFormat->useLfe=wChannels>=6 ? 1 : 0;
-
-		if(!faacEncSetConfiguration(mo->hEncoder, CurFormat))
-			return ERROR_Init("Unsupported parameters!");
 	}
+	else
+	{
+		CurFormat->mpegVersion=DEF_MPEGVER;
+		CurFormat->aacObjectType=DEF_PROFILE;
+		CurFormat->allowMidside=DEF_MIDSIDE;
+		CurFormat->useTns=DEF_TNS;
+		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(lpstrFilename);
@@ -414,7 +604,10 @@
         MP4SetTrackESConfiguration(mo->MP4File, mo->MP4track, (unsigned __int8 *)ASC, ASCLength);
 		mo->frameSize=samplesInput/wChannels;
 		mo->ofs=mo->frameSize;
-    }
+
+		if(cfg.Tag.On)
+			WriteMP4Tag(mo->MP4File,&cfg.Tag);
+	}
 	else // Create AAC file -----------------------------------------------------------------------------
 	{
 		// open the aac output file 
@@ -423,10 +616,13 @@
 
 		// use bufferized stream
 		setvbuf(mo->aacFile,NULL,_IOFBF,32767);
+
+		mo->Filename=strdup(lpstrFilename);
 	}
 
 	showInfo(mo);
 
+	FreeTag(&cfg.Tag);
 	GlobalUnlock(hOutput);
     return hOutput;
 }
@@ -450,7 +646,8 @@
 		mo->samplesInput=(len<<3)/mo->BitsPerSample;
 		mo->samplesInputSize=mo->samplesInput*(mo->BitsPerSample>>3);
 	}
-	To32bit(buf,bufIn,mo->samplesInput,mo->BitsPerSample>>3,false);
+//	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)
--- a/plugins/cooledit/Cfaac.h
+++ b/plugins/cooledit/Cfaac.h
@@ -37,6 +37,7 @@
 #endif
 #include <faac.h>
 #include <win32_ver.h>	// mpeg4ip version
+#include <id3/tag.h>	// id3 tag
 #include "CRegistry.h"
 #include "Defines.h"	// my defines
 
@@ -49,12 +50,66 @@
 
 // *********************************************************************************************
 
+#define REG_AUTO "Auto"
+#define DEF_AUTO true
+#define REG_WRITEMP4 "Write MP4"
+#define DEF_WRITEMP4 false
+#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 false
+#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_TAGON "Tag On"
+#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
+{
+BYTE	On;
+char	*artist, *title, *album, *year, *genre, *writer, *comment;
+int		trackno,ntracks, discno,ndiscs;
+BYTE	compilation;
+char	*artFileName;
+} MP4TAG;
+// -----------------------------------------------------------------------------------------------
+
 typedef struct mec
 {
 bool					AutoCfg,
 						UseQuality,
 						SaveMP4;
+char					*OutDir;
 faacEncConfiguration	EncCfg;
+MP4TAG					Tag;
 } MY_ENC_CFG;
 // -----------------------------------------------------------------------------------------------
 
@@ -71,6 +126,7 @@
 
 // AAC
 FILE			*aacFile;
+char			*Filename;
 
 // GLOBAL
 long			Samprate;
@@ -104,14 +160,19 @@
 	virtual int ERROR_processData(char *str) { DisplayError("processData", str); return -1; }
 	virtual void showInfo(MYOUTPUT *mi) {}
 	virtual void showProgress(MYOUTPUT *mi) {}
-	virtual void To32bit(int32_t *buf, BYTE *bufi, int size, BYTE samplebytes, BYTE bigendian);
+	void To32bit(int32_t *buf, BYTE *bufi, int size, BYTE samplebytes, BYTE bigendian);
+	int check_image_header(const char *buf);
+	int ReadCoverArtFile(char *pCoverArtFile, char **artBuf);
 
 public:
     Cfaac(HANDLE hOutput=NULL);
     virtual ~Cfaac();
 
+	static void FreeTag(MP4TAG *Tag);
 	static void getFaacCfg(MY_ENC_CFG *cfg);
 	static void setFaacCfg(MY_ENC_CFG *cfg);
+	virtual void WriteMP4Tag(MP4FileHandle MP4File, MP4TAG *Tag);
+	virtual void WriteAacTag(char *Filename, MP4TAG *Tag);
     virtual HANDLE Init(LPSTR lpstrFilename,long lSamprate,WORD wBitsPerSample,WORD wChannels,long FileSize);
     virtual int processData(HANDLE hOutput, BYTE *bufIn, DWORD len);
 	virtual int processDataBufferized(HANDLE hOutput, BYTE *bufIn, long lBytes);
--- a/plugins/cooledit/Cfaad.cpp
+++ b/plugins/cooledit/Cfaad.cpp
@@ -314,16 +314,16 @@
 { 
 CRegistry reg;
 
-	if(reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME  "\\FAAD"))
+if(reg.OpenCreate(HKEY_LOCAL_MACHINE, REGISTRY_PROGRAM_NAME "\\FAAD"))
 	{
-		cfg->DefaultCfg=reg.getSetRegBool("Default",true);
-		cfg->DecCfg.defObjectType=reg.getSetRegByte("Profile",LC);
-		cfg->DecCfg.defSampleRate=reg.getSetRegDword("SampleRate",44100);
-		cfg->DecCfg.outputFormat=reg.getSetRegByte("Bps",FAAD_FMT_16BIT);
-		cfg->DecCfg.downMatrix=reg.getSetRegByte("Downmatrix",0);
-		cfg->DecCfg.useOldADTSFormat=reg.getSetRegByte("Old ADTS",0);
-		cfg->DecCfg.dontUpSampleImplicitSBR=reg.getSetRegByte("Don\'t upsample implicit SBR",1);
-//		cfg->Channels=reg.getSetRegByte("Channels",2);
+		cfg->DefaultCfg=reg.GetSetBool("Default",true);
+		cfg->DecCfg.defObjectType=reg.GetSetByte("Profile",LC);
+		cfg->DecCfg.defSampleRate=reg.GetSetDword("SampleRate",44100);
+		cfg->DecCfg.outputFormat=reg.GetSetByte("Bps",FAAD_FMT_16BIT);
+		cfg->DecCfg.downMatrix=reg.GetSetByte("Downmatrix",0);
+		cfg->DecCfg.useOldADTSFormat=reg.GetSetByte("Old ADTS",0);
+		cfg->DecCfg.dontUpSampleImplicitSBR=reg.GetSetByte("Don\'t upsample implicit SBR",1);
+//		cfg->Channels=reg.GetSetByte("Channels",2);
 	}
 	else
 		MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
@@ -334,16 +334,16 @@
 { 
 CRegistry reg;
 
-	if(reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME  "\\FAAD"))
+	if(reg.OpenCreate(HKEY_LOCAL_MACHINE, REGISTRY_PROGRAM_NAME "\\FAAD"))
 	{
-		reg.setRegBool("Default",cfg->DefaultCfg);
-		reg.setRegByte("Profile",cfg->DecCfg.defObjectType);
-		reg.setRegDword("SampleRate",cfg->DecCfg.defSampleRate);
-		reg.setRegByte("Bps",cfg->DecCfg.outputFormat);
-		reg.setRegByte("Downmatrix",cfg->DecCfg.downMatrix);
-		reg.setRegByte("Old ADTS",cfg->DecCfg.useOldADTSFormat);
-		reg.setRegByte("Don\'t upsample implicit SBR",cfg->DecCfg.dontUpSampleImplicitSBR);
-//		reg.setRegByte("Channels",cfg->Channels);
+		reg.SetBool("Default",cfg->DefaultCfg);
+		reg.SetByte("Profile",cfg->DecCfg.defObjectType);
+		reg.SetDword("SampleRate",cfg->DecCfg.defSampleRate);
+		reg.SetByte("Bps",cfg->DecCfg.outputFormat);
+		reg.SetByte("Downmatrix",cfg->DecCfg.downMatrix);
+		reg.SetByte("Old ADTS",cfg->DecCfg.useOldADTSFormat);
+		reg.SetByte("Don\'t upsample implicit SBR",cfg->DecCfg.dontUpSampleImplicitSBR);
+//		reg.SetByte("Channels",cfg->Channels);
 	}
 	else
 		MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
--- a/plugins/cooledit/FAAC.rc
+++ b/plugins/cooledit/FAAC.rc
@@ -1,4 +1,4 @@
-//Microsoft Developer Studio generated resource script.
+// Microsoft Visual C++ generated resource script.
 //
 #include "resource.h"
 
@@ -26,60 +26,96 @@
 // Dialog
 //
 
-IDD_ENCODER DIALOG DISCARDABLE  0, 0, 197, 147
-STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+IDD_ENCODER DIALOGEX 0, 0, 338, 209
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | 
+    WS_SYSMENU
 CAPTION "MPEG4-AAC options"
-FONT 8, "MS Sans Serif"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
 BEGIN
-    DEFPUSHBUTTON   "&OK",IDOK,85,128,36,14
-    PUSHBUTTON      "&Cancel",IDCANCEL,121,128,36,14
-    PUSHBUTTON      "&About",IDC_BTN_ABOUT,157,128,36,14
+    DEFPUSHBUTTON   "&OK",IDOK,12,190,36,14
+    PUSHBUTTON      "&Cancel",IDCANCEL,48,190,36,14
+    PUSHBUTTON      "&About",IDC_BTN_ABOUT,84,190,36,14
+    PUSHBUTTON      "&License",IDC_BTN_LICENSE,120,190,36,14
     CONTROL         "Automatic configuration",IDC_CHK_AUTOCFG,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,4,4,90,10
-    CONTROL         "MPEG4",IDC_RADIO_MPEG4,"Button",BS_AUTORADIOBUTTON | 
-                    WS_GROUP,9,29,40,10
-    CONTROL         "MPEG2",IDC_RADIO_MPEG2,"Button",BS_AUTORADIOBUTTON,9,42,
-                    40,9
     CONTROL         "Main",IDC_RADIO_MAIN,"Button",BS_AUTORADIOBUTTON | 
-                    WS_GROUP,9,73,31,10
-    CONTROL         "LC",IDC_RADIO_LOW,"Button",BS_AUTORADIOBUTTON,9,85,25,
+                    WS_GROUP,9,27,31,10
+    CONTROL         "LC",IDC_RADIO_LOW,"Button",BS_AUTORADIOBUTTON,9,39,25,
                     10
     CONTROL         "SSR",IDC_RADIO_SSR,"Button",BS_AUTORADIOBUTTON | 
-                    WS_DISABLED,9,97,31,10
-    CONTROL         "LTP",IDC_RADIO_LTP,"Button",BS_AUTORADIOBUTTON,9,109,29,
+                    WS_DISABLED,9,51,31,10
+    CONTROL         "LTP",IDC_RADIO_LTP,"Button",BS_AUTORADIOBUTTON,9,63,29,
                     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,59,29,42,10
-    CONTROL         "ADTS",IDC_RADIO_ADTS,"Button",BS_AUTORADIOBUTTON,59,42,
+                    WS_GROUP,112,27,42,10
+    CONTROL         "ADTS",IDC_RADIO_ADTS,"Button",BS_AUTORADIOBUTTON,112,40,
                     41,9
-    CONTROL         "Allow Mid/Side",IDC_CHK_ALLOWMIDSIDE,"Button",
-                    BS_AUTOCHECKBOX | WS_TABSTOP,109,29,63,10
-    CONTROL         "Use TNS",IDC_CHK_USETNS,"Button",BS_AUTOCHECKBOX | 
-                    WS_TABSTOP,109,41,45,10
-    CONTROL         "Use LFE channel",IDC_CHK_USELFE,"Button",
-                    BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | 
-                    WS_TABSTOP,4,122,67,10
     CONTROL         "Quality",IDC_RADIO_QUALITY,"Button",BS_AUTORADIOBUTTON | 
-                    WS_GROUP,61,73,37,10
-    COMBOBOX        IDC_CB_QUALITY,138,71,48,97,CBS_DROPDOWN | WS_VSCROLL | 
-                    WS_TABSTOP
+                    WS_GROUP,9,89,37,10
     CONTROL         "Bitrate per channel",IDC_RADIO_BITRATE,"Button",
-                    BS_AUTORADIOBUTTON,61,89,75,10
-    COMBOBOX        IDC_CB_BITRATE,138,87,48,86,CBS_DROPDOWN | WS_VSCROLL | 
+                    BS_AUTORADIOBUTTON,9,105,75,10
+    COMBOBOX        IDC_CB_QUALITY,102,86,48,97,CBS_DROPDOWN | WS_VSCROLL | 
                     WS_TABSTOP
-    COMBOBOX        IDC_CB_BANDWIDTH,138,108,48,81,CBS_DROPDOWN | WS_VSCROLL | 
+    COMBOBOX        IDC_CB_BITRATE,102,102,48,86,CBS_DROPDOWN | WS_VSCROLL | 
                     WS_TABSTOP
-    GROUPBOX        "AAC type",IDC_STATIC,4,18,48,38
-    GROUPBOX        "Profile",IDC_STATIC,4,62,48,59
-    LTEXT           "Bandwidth",IDC_STATIC,73,111,34,8
-    GROUPBOX        "Header",IDC_STATIC,55,18,48,38
-    GROUPBOX        "Encoding mode",IDC_STATIC,56,62,137,42
+    LTEXT           "Bandwidth",IDC_STATIC,21,126,34,8
+    COMBOBOX        IDC_CB_BANDWIDTH,102,123,48,81,CBS_DROPDOWN | WS_VSCROLL | 
+                    WS_TABSTOP
+    CONTROL         "Allow Mid/Side",IDC_CHK_ALLOWMIDSIDE,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,9,143,63,10
+    CONTROL         "Use TNS",IDC_CHK_USETNS,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,9,155,45,10
+    CONTROL         "Use LFE channel",IDC_CHK_USELFE,"Button",
+                    BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | 
+                    WS_TABSTOP,79,143,67,10
     CONTROL         "Write .mp4",IDC_CHK_WRITEMP4,"Button",BS_AUTOCHECKBOX | 
-                    NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,4,132,50,10
+                    WS_TABSTOP,9,168,50,10
+    GROUPBOX        "AAC type",IDC_STATIC,56,16,48,38
+    GROUPBOX        "Profile",IDC_STATIC,4,16,48,59
+    GROUPBOX        "Header",IDC_STATIC,108,16,48,38
+    GROUPBOX        "Encoding mode",IDC_STATIC,4,78,152,42
+    GROUPBOX        "",IDC_GRP_TAG,160,4,174,200
+    CONTROL         "Tag",IDC_CHK_TAG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+                    165,4,29,10
+    EDITTEXT        IDC_E_ARTIST,207,22,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_TITLE,207,36,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_ALBUM,207,51,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_YEAR,207,66,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_WRITER,207,95,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_COMMENT,207,110,121,29,ES_MULTILINE | 
+                    ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_COMPILATION,207,140,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_TRACK,233,156,40,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_NTRACKS,288,156,40,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_DISK,233,171,40,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_NDISKS,288,171,40,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_ARTFILE,207,186,98,14,ES_AUTOHSCROLL
+    PUSHBUTTON      "&...",IDC_BTN_ARTFILE,311,186,17,14,BS_BITMAP | BS_FLAT
+    LTEXT           "Artist",IDC_STATIC,165,23,16,8
+    LTEXT           "Title",IDC_STATIC,165,38,14,8
+    LTEXT           "Album",IDC_STATIC,165,54,20,8
+    LTEXT           "Year",IDC_STATIC,165,68,16,8
+    LTEXT           "Genre",IDC_STATIC,165,83,20,8
+    LTEXT           "Writer",IDC_STATIC,165,98,20,8
+    LTEXT           "Comment\n(ctrl-Enter\nto go down)",IDC_STATIC,165,114,
+                    37,26
+    LTEXT           "Track",IDC_STATIC,165,160,20,8
+    LTEXT           "/",IDC_STATIC,277,160,8,8
+    LTEXT           "Disk",IDC_STATIC,165,174,15,8
+    LTEXT           "/",IDC_STATIC,277,174,8,8
+    LTEXT           "Compilation",IDC_STATIC,165,144,37,8
+    LTEXT           "Cover art file",IDC_STATIC,165,188,40,8
+    COMBOBOX        IDC_CB_GENRE,207,81,121,161,CBS_DROPDOWN | WS_VSCROLL | 
+                    WS_TABSTOP
 END
 
-IDD_DECODER DIALOG DISCARDABLE  0, 0, 141, 105
-STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+IDD_DECODER DIALOG  0, 0, 141, 105
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | 
+    WS_SYSMENU
 CAPTION "Raw .AAC options"
 FONT 8, "MS Sans Serif"
 BEGIN
@@ -115,18 +151,18 @@
 // TEXTINCLUDE
 //
 
-1 TEXTINCLUDE DISCARDABLE 
+1 TEXTINCLUDE 
 BEGIN
     "resource.h\0"
 END
 
-2 TEXTINCLUDE DISCARDABLE 
+2 TEXTINCLUDE 
 BEGIN
     "#include ""afxres.h""\r\n"
     "\0"
 END
 
-3 TEXTINCLUDE DISCARDABLE 
+3 TEXTINCLUDE 
 BEGIN
     "\r\n"
     "\0"
@@ -141,14 +177,14 @@
 //
 
 #ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO DISCARDABLE 
+GUIDELINES DESIGNINFO 
 BEGIN
     IDD_ENCODER, DIALOG
     BEGIN
         LEFTMARGIN, 4
-        RIGHTMARGIN, 193
+        RIGHTMARGIN, 334
         TOPMARGIN, 4
-        BOTTOMMARGIN, 142
+        BOTTOMMARGIN, 204
     END
 
     IDD_DECODER, DIALOG
@@ -179,8 +215,8 @@
 // Dialog
 //
 
-IDD_ABOUT DIALOG DISCARDABLE  0, 0, 191, 230
-STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
+IDD_ABOUT DIALOG  0, 0, 191, 230
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
 CAPTION "About"
 FONT 8, "MS Sans Serif"
 BEGIN
@@ -201,7 +237,7 @@
 //
 
 #ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO DISCARDABLE 
+GUIDELINES DESIGNINFO 
 BEGIN
     IDD_ABOUT, DIALOG
     BEGIN
@@ -219,9 +255,10 @@
 // Bitmap
 //
 
-IDB_AUDIOCODING         BITMAP  DISCARDABLE     "AudioCoding.bmp"
-IDB_EMAIL               BITMAP  DISCARDABLE     "Email.bmp"
-IDB_MPEG4IP             BITMAP  DISCARDABLE     "mpeg4ip-v.bmp"
+IDB_AUDIOCODING         BITMAP                  "AudioCoding.bmp"
+IDB_EMAIL               BITMAP                  "Email.bmp"
+IDB_MPEG4IP             BITMAP                  "mpeg4ip-v.bmp"
+IDB_BROWSE              BITMAP                  "Open.bmp"
 #endif    // Italian (Italy) resources
 /////////////////////////////////////////////////////////////////////////////
 
--- a/plugins/cooledit/FAAC.sln
+++ b/plugins/cooledit/FAAC.sln
@@ -1,46 +1,79 @@
 Microsoft Visual Studio Solution File, Format Version 7.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FAAC", "FAAC.vcproj", "{088ABC53-EDEB-47C6-BF78-9A633054EA09}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FAAC", "FAAC.vcproj", "{98D43204-EB3F-40C1-9B0D-2C33738C0788}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aacInfoLib", "aacInfoLib.vcproj", "{C9F1F5AE-902D-4B87-B149-8DDB40074227}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaac", "..\..\libfaac\libfaac.vcproj", "{D155A7E9-20BE-4480-B704-A7C74AE3DBB6}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaac", "..\..\libfaac\libfaac.vcproj", "{1BC93B83-B0D7-4A08-9461-0BCABB8A6E73}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaad", "..\..\..\faad2\libfaad\libfaad.vcproj", "{56FB973D-6363-4C20-A9EA-95759F34A8AB}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaad", "..\..\..\faad2\libfaad\libfaad.vcproj", "{F8F02EFC-27F1-4ED8-AD33-51BC1CB5EDAF}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmp4v2_st", "..\..\..\faad2\common\mp4v2\libmp4v2_st60.vcproj", "{2CF8D144-76E5-4F92-98C4-A572DF1CBD04}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmp4v2_st", "..\..\..\faad2\common\mp4v2\libmp4v2_st60.vcproj", "{95F5A44D-E9E4-4612-91D4-E9AF16542F62}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "id3lib", "..\..\..\faad2\common\id3lib\libprj\id3lib.vcproj", "{016F36CD-410C-4B47-A527-AF82B848E1EB}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\faad2\common\id3lib\zlib\prj\zlib.vcproj", "{873DE650-0D25-4EDA-846D-D36408A73E33}"
+EndProject
 Global
 	GlobalSection(SolutionConfiguration) = preSolution
 		ConfigName.0 = Debug
-		ConfigName.1 = Release
+		ConfigName.1 = NASM Debug
+		ConfigName.2 = NASM Release
+		ConfigName.3 = Release
 	EndGlobalSection
 	GlobalSection(ProjectDependencies) = postSolution
-		{088ABC53-EDEB-47C6-BF78-9A633054EA09}.0 = {C9F1F5AE-902D-4B87-B149-8DDB40074227}
-		{088ABC53-EDEB-47C6-BF78-9A633054EA09}.1 = {95F5A44D-E9E4-4612-91D4-E9AF16542F62}
-		{088ABC53-EDEB-47C6-BF78-9A633054EA09}.2 = {F8F02EFC-27F1-4ED8-AD33-51BC1CB5EDAF}
-		{088ABC53-EDEB-47C6-BF78-9A633054EA09}.3 = {1BC93B83-B0D7-4A08-9461-0BCABB8A6E73}
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.0 = {56FB973D-6363-4C20-A9EA-95759F34A8AB}
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.1 = {873DE650-0D25-4EDA-846D-D36408A73E33}
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.2 = {D155A7E9-20BE-4480-B704-A7C74AE3DBB6}
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.3 = {016F36CD-410C-4B47-A527-AF82B848E1EB}
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.4 = {2CF8D144-76E5-4F92-98C4-A572DF1CBD04}
 	EndGlobalSection
 	GlobalSection(ProjectConfiguration) = postSolution
-		{088ABC53-EDEB-47C6-BF78-9A633054EA09}.Debug.ActiveCfg = Debug|Win32
-		{088ABC53-EDEB-47C6-BF78-9A633054EA09}.Debug.Build.0 = Debug|Win32
-		{088ABC53-EDEB-47C6-BF78-9A633054EA09}.Release.ActiveCfg = Release|Win32
-		{088ABC53-EDEB-47C6-BF78-9A633054EA09}.Release.Build.0 = Release|Win32
-		{C9F1F5AE-902D-4B87-B149-8DDB40074227}.Debug.ActiveCfg = Debug|Win32
-		{C9F1F5AE-902D-4B87-B149-8DDB40074227}.Debug.Build.0 = Debug|Win32
-		{C9F1F5AE-902D-4B87-B149-8DDB40074227}.Release.ActiveCfg = Release|Win32
-		{C9F1F5AE-902D-4B87-B149-8DDB40074227}.Release.Build.0 = Release|Win32
-		{1BC93B83-B0D7-4A08-9461-0BCABB8A6E73}.Debug.ActiveCfg = Debug|Win32
-		{1BC93B83-B0D7-4A08-9461-0BCABB8A6E73}.Debug.Build.0 = Debug|Win32
-		{1BC93B83-B0D7-4A08-9461-0BCABB8A6E73}.Release.ActiveCfg = Release|Win32
-		{1BC93B83-B0D7-4A08-9461-0BCABB8A6E73}.Release.Build.0 = Release|Win32
-		{F8F02EFC-27F1-4ED8-AD33-51BC1CB5EDAF}.Debug.ActiveCfg = Debug|Win32
-		{F8F02EFC-27F1-4ED8-AD33-51BC1CB5EDAF}.Debug.Build.0 = Debug|Win32
-		{F8F02EFC-27F1-4ED8-AD33-51BC1CB5EDAF}.Release.ActiveCfg = Release|Win32
-		{F8F02EFC-27F1-4ED8-AD33-51BC1CB5EDAF}.Release.Build.0 = Release|Win32
-		{95F5A44D-E9E4-4612-91D4-E9AF16542F62}.Debug.ActiveCfg = Debug|Win32
-		{95F5A44D-E9E4-4612-91D4-E9AF16542F62}.Debug.Build.0 = Debug|Win32
-		{95F5A44D-E9E4-4612-91D4-E9AF16542F62}.Release.ActiveCfg = Release|Win32
-		{95F5A44D-E9E4-4612-91D4-E9AF16542F62}.Release.Build.0 = Release|Win32
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.Debug.ActiveCfg = Debug|Win32
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.Debug.Build.0 = Debug|Win32
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.NASM Debug.ActiveCfg = Debug|Win32
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.NASM Debug.Build.0 = Debug|Win32
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.NASM Release.ActiveCfg = Release|Win32
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.NASM Release.Build.0 = Release|Win32
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.Release.ActiveCfg = Release|Win32
+		{98D43204-EB3F-40C1-9B0D-2C33738C0788}.Release.Build.0 = Release|Win32
+		{D155A7E9-20BE-4480-B704-A7C74AE3DBB6}.Debug.ActiveCfg = Debug|Win32
+		{D155A7E9-20BE-4480-B704-A7C74AE3DBB6}.Debug.Build.0 = Debug|Win32
+		{D155A7E9-20BE-4480-B704-A7C74AE3DBB6}.NASM Debug.ActiveCfg = Debug|Win32
+		{D155A7E9-20BE-4480-B704-A7C74AE3DBB6}.NASM Debug.Build.0 = Debug|Win32
+		{D155A7E9-20BE-4480-B704-A7C74AE3DBB6}.NASM Release.ActiveCfg = Release|Win32
+		{D155A7E9-20BE-4480-B704-A7C74AE3DBB6}.NASM Release.Build.0 = Release|Win32
+		{D155A7E9-20BE-4480-B704-A7C74AE3DBB6}.Release.ActiveCfg = Release|Win32
+		{D155A7E9-20BE-4480-B704-A7C74AE3DBB6}.Release.Build.0 = Release|Win32
+		{56FB973D-6363-4C20-A9EA-95759F34A8AB}.Debug.ActiveCfg = Debug|Win32
+		{56FB973D-6363-4C20-A9EA-95759F34A8AB}.Debug.Build.0 = Debug|Win32
+		{56FB973D-6363-4C20-A9EA-95759F34A8AB}.NASM Debug.ActiveCfg = Debug|Win32
+		{56FB973D-6363-4C20-A9EA-95759F34A8AB}.NASM Debug.Build.0 = Debug|Win32
+		{56FB973D-6363-4C20-A9EA-95759F34A8AB}.NASM Release.ActiveCfg = Release|Win32
+		{56FB973D-6363-4C20-A9EA-95759F34A8AB}.NASM Release.Build.0 = Release|Win32
+		{56FB973D-6363-4C20-A9EA-95759F34A8AB}.Release.ActiveCfg = Release|Win32
+		{56FB973D-6363-4C20-A9EA-95759F34A8AB}.Release.Build.0 = Release|Win32
+		{2CF8D144-76E5-4F92-98C4-A572DF1CBD04}.Debug.ActiveCfg = Debug|Win32
+		{2CF8D144-76E5-4F92-98C4-A572DF1CBD04}.Debug.Build.0 = Debug|Win32
+		{2CF8D144-76E5-4F92-98C4-A572DF1CBD04}.NASM Debug.ActiveCfg = Debug|Win32
+		{2CF8D144-76E5-4F92-98C4-A572DF1CBD04}.NASM Debug.Build.0 = Debug|Win32
+		{2CF8D144-76E5-4F92-98C4-A572DF1CBD04}.NASM Release.ActiveCfg = Release|Win32
+		{2CF8D144-76E5-4F92-98C4-A572DF1CBD04}.NASM Release.Build.0 = Release|Win32
+		{2CF8D144-76E5-4F92-98C4-A572DF1CBD04}.Release.ActiveCfg = Release|Win32
+		{2CF8D144-76E5-4F92-98C4-A572DF1CBD04}.Release.Build.0 = Release|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.Debug.ActiveCfg = Debug|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.Debug.Build.0 = Debug|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.NASM Debug.ActiveCfg = Debug|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.NASM Debug.Build.0 = Debug|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.NASM Release.ActiveCfg = Release|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.NASM Release.Build.0 = Release|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.Release.ActiveCfg = Release|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.Release.Build.0 = Release|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.Debug.ActiveCfg = Debug|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.Debug.Build.0 = Debug|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.NASM Debug.ActiveCfg = NASM Debug|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.NASM Debug.Build.0 = NASM Debug|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.NASM Release.ActiveCfg = NASM Release|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.NASM Release.Build.0 = NASM Release|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.Release.ActiveCfg = Release|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.Release.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 	EndGlobalSection
--- a/plugins/cooledit/FAAC.vcproj
+++ b/plugins/cooledit/FAAC.vcproj
@@ -16,15 +16,15 @@
 			IntermediateDirectory=".\Debug"
 			ConfigurationType="2"
 			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
 			<Tool
 				Name="VCCLCompilerTool"
+				AdditionalOptions=""
 				Optimization="0"
-				AdditionalIncludeDirectories="../../../faad2/common/faad,../../include,../../../faad2/include,../../../faad2/common/mp4v2"
-				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FAAC_EXPORTS"
+				AdditionalIncludeDirectories="../../include,../../../faad2/include,../../../faad2/common/faad,../../../faad2/common/mp4v2,../../../faad2/common/id3lib/include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN"
 				BasicRuntimeChecks="3"
-				RuntimeLibrary="5"
+				RuntimeLibrary="3"
 				UsePrecompiledHeader="2"
 				PrecompiledHeaderFile=".\Debug/FAAC.pch"
 				AssemblerListingLocation=".\Debug/"
@@ -40,9 +40,11 @@
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
 				AdditionalDependencies="ws2_32.lib odbc32.lib odbccp32.lib"
-				OutputFile="Debug/FAAC.flt"
+				OutputFile="C:\Programmi\Adobe\Audition 1.0\FAAC.flt"
 				LinkIncremental="2"
 				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="C:\Programmi\Intel\Compiler70\IA32\Lib"
+				IgnoreDefaultLibraryNames=""
 				ModuleDefinitionFile=".\FAAC.def"
 				GenerateDebugInformation="TRUE"
 				ProgramDatabaseFile=".\Debug/FAAC.pdb"
@@ -75,15 +77,15 @@
 			IntermediateDirectory=".\Release"
 			ConfigurationType="2"
 			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
+			ATLMinimizesCRunTimeLibraryUsage="FALSE">
 			<Tool
 				Name="VCCLCompilerTool"
+				AdditionalOptions=""
 				InlineFunctionExpansion="1"
 				AdditionalIncludeDirectories="../../../faad2/common/faad,../../include,../../../faad2/include,../../../faad2/common/mp4v2"
-				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FAAC_EXPORTS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN"
 				StringPooling="TRUE"
-				RuntimeLibrary="0"
+				RuntimeLibrary="2"
 				EnableFunctionLevelLinking="TRUE"
 				UsePrecompiledHeader="2"
 				PrecompiledHeaderFile=".\Release/FAAC.pch"
@@ -136,6 +138,12 @@
 				RelativePath=".\CRegistry.cpp">
 			</File>
 			<File
+				RelativePath=".\Cfaac.cpp">
+			</File>
+			<File
+				RelativePath=".\Cfaad.cpp">
+			</File>
+			<File
 				RelativePath=".\FAAC.def">
 			</File>
 			<File
@@ -158,15 +166,18 @@
 				RelativePath=".\CRegistry.h">
 			</File>
 			<File
-				RelativePath=".\Defines.h">
+				RelativePath=".\Cfaac.h">
 			</File>
 			<File
-				RelativePath=".\Filters.h">
+				RelativePath=".\Cfaad.h">
 			</File>
 			<File
-				RelativePath=".\Structs.h">
+				RelativePath=".\Defines.h">
 			</File>
 			<File
+				RelativePath=".\Filters.h">
+			</File>
+			<File
 				RelativePath="..\..\include\faac.h">
 			</File>
 			<File
@@ -187,6 +198,9 @@
 			</File>
 			<File
 				RelativePath=".\Mail.bmp">
+			</File>
+			<File
+				RelativePath="Open.bmp">
 			</File>
 			<File
 				RelativePath=".\mpeg4ip-v.bmp">
--- a/plugins/cooledit/Faac.cpp
+++ b/plugins/cooledit/Faac.cpp
@@ -21,6 +21,8 @@
 
 #include <windows.h>
 #include <shellapi.h>	// ShellExecute
+#include <Commdlg.h>
+//#include <shlobj.h>		// Browse
 //#include <stdio.h>		// FILE *
 //#include <stdlib.h>		// malloc, free
 #include "resource.h"
@@ -27,9 +29,14 @@
 #include "filters.h"	// CoolEdit
 #include "Cfaac.h"
 
+#include <commctrl.h>
+//#include <id3.h>
+#include <id3v2tag.h>
+
 // *********************************************************************************************
 
 extern HINSTANCE hInst;
+extern HBITMAP hBmBrowse;
 
 // *********************************************************************************************
 
@@ -83,6 +90,14 @@
 }
 // -----------------------------------------------------------------------------------------------
 
+#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) && \
@@ -122,6 +137,34 @@
 }
 // -----------------------------------------------------------------------------------------------
 
+#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_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_E_NTRACKS), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_DISK), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_NDISKS), Enabled); \
+}
+// -----------------------------------------------------------------------------------------------
+
 BOOL DialogMsgProcAbout(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
 {
 	switch(Message)
@@ -128,15 +171,10 @@
 	{
 	case WM_INITDIALOG:
 		{
-		  char buf[512];
-		  unsigned long samplesInput, maxBytesOutput;
+		char buf[512];
+		char *faac_id_string, *faac_copyright_string;
 
-		  faacEncHandle hEncoder =
-		    faacEncOpen(44100, 2, &samplesInput, &maxBytesOutput);
-		  faacEncConfigurationPtr myFormat =
-		    faacEncGetCurrentConfiguration(hEncoder);
-
-			sprintf(buf,
+		sprintf(buf,
 					APP_NAME " plugin " APP_VER " by Antonio Foranna\n\n"
 					"Engines used:\n"
 					"\tlibfaac v%s\n"
@@ -146,11 +184,10 @@
 					"This program is free software and can be distributed/modifyed under the terms of the GNU General Public License.\n"
 					"This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.\n\n"
 					"Compiled on %s\n",
-				(myFormat->version == FAAC_CFG_VERSION) ? myFormat->name : " bad version",
+				(faacEncGetVersion(&faac_id_string, &faac_copyright_string)==FAAC_CFG_VERSION) ? faac_id_string : " wrong libfaac version",
 					__DATE__
 					);
 			SetDlgItemText(hWndDlg, IDC_L_ABOUT, buf);
-			faacEncClose(hEncoder);
 		}
 		break;
 	case WM_COMMAND:
@@ -180,9 +217,141 @@
 
 	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 DIALOGMsgProc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
 {
 	switch(Message)
@@ -192,9 +361,11 @@
 		char buf[50];
 		char *Quality[]={"Default","10","20","30","40","50","60","70","80","90","100","110","120","130","140","150","200","300","400","500",0};
 		char *BitRate[]={"Auto","8","18","20","24","32","40","48","56","64","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 *BandWidth[]={"Auto","Full","4000","8000","11025","16000","22050","24000","32000","44100","48000","64000","88200","96000",0};
 		MY_ENC_CFG cfg;
 
+			SetWindowPos(GetDlgItem(hWndDlg,IDC_CHK_TAG),GetDlgItem(hWndDlg,IDC_GRP_TAG),0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
+
 			Cfaac::getFaacCfg(&cfg);
 
 			INIT_CB(hWndDlg,IDC_CB_QUALITY,Quality,0);
@@ -201,6 +372,9 @@
 			INIT_CB(hWndDlg,IDC_CB_BITRATE,BitRate,0);
 			INIT_CB(hWndDlg,IDC_CB_BANDWIDTH,BandWidth,0);
 
+			INIT_CB_GENRES(hWndDlg,IDC_CB_GENRE,ID3Genres,0);
+
+			SendMessage(GetDlgItem(hWndDlg, IDC_BTN_ARTFILE), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBmBrowse);
 			if(cfg.EncCfg.mpegVersion==MPEG4)
 				CheckDlgButton(hWndDlg,IDC_RADIO_MPEG4,TRUE);
 			else
@@ -284,6 +458,24 @@
 
 			CheckDlgButton(hWndDlg,IDC_CHK_AUTOCFG, cfg.AutoCfg);
 			DISABLE_CTRL(!cfg.AutoCfg);
+
+			CheckDlgButton(hWndDlg,IDC_CHK_TAG, cfg.Tag.On);
+			ENABLE_TAG(cfg.Tag.On);
+			ENABLE_AACTAGS(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);
+			Cfaac::FreeTag(&cfg.Tag);
 		}
 		break; // End of WM_INITDIALOG                                 
 
@@ -295,13 +487,6 @@
 	case WM_COMMAND:
 		switch(LOWORD(wParam))
 		{
-		case IDC_CHK_AUTOCFG:
-			{
-			char Enabled=!IsDlgButtonChecked(hWndDlg,IDC_CHK_AUTOCFG);
-				DISABLE_CTRL(Enabled);
-			}
-			break;
-
 		case IDOK:
 			{
 			char buf[50];
@@ -356,9 +541,34 @@
 
 				cfg.SaveMP4=IsDlgButtonChecked(hWndDlg, IDC_CHK_WRITEMP4) ? TRUE : FALSE;
 
+				cfg.Tag.On=IsDlgButtonChecked(hWndDlg,IDC_CHK_TAG) ? 1 : 0;
+			char buffer[MAX_PATH];
+				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);
+
 				Cfaac::setFaacCfg(&cfg);
+				Cfaac::FreeTag(&cfg.Tag);
 
-				EndDialog(hWndDlg, 1);
+				EndDialog(hWndDlg, TRUE);
 			}
 			break;
 
@@ -371,7 +581,97 @@
 		case IDC_BTN_ABOUT:
 			DialogBox((HINSTANCE)hInst,(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;
+
+		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			= hInst;
+
+				if(GetOpenFileName(&ofn))
+					SetDlgItemText(hWndDlg, IDC_E_ARTFILE, ArtFilename);
+			}
+			break;
+
 		case IDC_RADIO_MPEG4:
 			EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LTP), !IsDlgButtonChecked(hWndDlg,IDC_CHK_AUTOCFG));
 			break;
@@ -380,6 +680,26 @@
 			EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LTP), FALSE);
 			DISABLE_LTP
 			break;
+
+		case IDC_CHK_AUTOCFG:
+			{
+			char Enabled=!IsDlgButtonChecked(hWndDlg,IDC_CHK_AUTOCFG);
+				DISABLE_CTRL(Enabled);
+			}
+			break;
+
+		case IDC_CHK_TAG:
+			{
+			char Enabled=IsDlgButtonChecked(hWndDlg,IDC_CHK_TAG);
+				ENABLE_TAG(Enabled);
+			}
+//			break;
+		case IDC_CHK_WRITEMP4:
+			{
+			char Enabled=IsDlgButtonChecked(hWndDlg,IDC_CHK_WRITEMP4) && IsDlgButtonChecked(hWndDlg,IDC_CHK_TAG);
+				ENABLE_AACTAGS(Enabled);
+			}
+			break;
 		}
 		break; // End of WM_COMMAND
 	default: 
@@ -393,63 +713,26 @@
 // *********************************************************************************************
 // *********************************************************************************************
 
-#define ERROR_FGO(msg) \
-{ \
-	if(msg) \
-	{ \
-	char buf[100]; \
-		sprintf(buf,"FilterGetOptions: %s", msg); \
-		MessageBox(0, buf, APP_NAME " plugin", MB_OK|MB_ICONSTOP); \
-	} \
-	return 0; \
+inline DWORD ERROR_FGO(char *msg)
+{
+	if(msg)
+	{
+	char buf[100];
+		sprintf(buf,"FilterGetOptions: %s", msg);
+		MessageBox(0, buf, APP_NAME " plugin", MB_OK|MB_ICONSTOP);
+	}
+	return 0;
 }
 // -----------------------------------------------------------------------------------------------
 
 DWORD FAR PASCAL FilterGetOptions(HWND hWnd, HINSTANCE hInst, long lSamprate, WORD wChannels, WORD wBitsPerSample, DWORD dwOptions)
 {
-long		retVal;
-/*CRegistry	reg;
-BOOL		OpenDialog=FALSE;
+long retVal=DialogBoxParam((HINSTANCE)hInst,(LPCSTR)MAKEINTRESOURCE(IDD_ENCODER), (HWND)hWnd, (DLGPROC)DIALOGMsgProc, dwOptions);
 
-	if(!reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME  "\\FAAD"))
-		ERROR_FGO("Can't open registry!")
-	else
-		if(OpenDialog=reg.getSetRegBool("OpenDialog",FALSE))
-			reg.setRegBool("OpenDialog",FALSE);
-
-	if(OpenDialog)
-	{
-	MY_DEC_CFG	*Cfg;
-		if(!(Cfg=(MY_DEC_CFG *)malloc(sizeof(MY_DEC_CFG))))
-			ERROR_FGO("Memory allocation error");
-		ReadCfgDec(Cfg);
-		Cfg->DecCfg.defSampleRate=lSamprate;
-		switch(wBitsPerSample)
-		{
-		case 16:
-			Cfg->DecCfg.outputFormat=FAAD_FMT_16BIT;
-			break;
-		case 24:
-			Cfg->DecCfg.outputFormat=FAAD_FMT_24BIT;
-			break;
-		case 32:
-			Cfg->DecCfg.outputFormat=FAAD_FMT_32BIT;
-			break;
-		default:
-			ERROR_FGO("Invalid Bps");
-		}
-		Cfg->Channels=(BYTE)wChannels;
-		retVal=DialogBoxParam((HINSTANCE)hInst,(LPCSTR)MAKEINTRESOURCE(IDD_DECODER), (HWND)hWnd, (DLGPROC)DialogMsgProcDecoder, (DWORD)Cfg);
-		WriteCfgDec(Cfg);
-		FREE(Cfg);
-	}
-	else*/
-		retVal=DialogBoxParam((HINSTANCE)hInst,(LPCSTR)MAKEINTRESOURCE(IDD_ENCODER), (HWND)hWnd, (DLGPROC)DIALOGMsgProc, dwOptions);
-
 	if(retVal==-1)
-		ERROR_FGO("DialogBoxParam");
+		/*return */ERROR_FGO("DialogBoxParam");
 
-	return retVal;
+	return !retVal ? dwOptions : retVal;
 }
 // *********************************************************************************************
 
--- a/plugins/cooledit/Main.cpp
+++ b/plugins/cooledit/Main.cpp
@@ -20,6 +20,7 @@
 */
 
 #include <windows.h>
+#include "resource.h"
 #include "filters.h"	//CoolEdit
 //#include "faac.h"
 #include "Defines.h"	// my defines
@@ -27,7 +28,9 @@
 // Plugins of CoolEdit can be unloaded between each call of its exported funcs,
 // that's why no global variables can be used
 
-HINSTANCE hInst;
+HINSTANCE hInst=NULL;
+HBITMAP hBmBrowse=NULL;
+
 BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
 {
 	switch (fdwReason)
@@ -34,6 +37,8 @@
 	{
 	case DLL_PROCESS_ATTACH:
 		hInst=(HINSTANCE)hModule;
+		if(!hBmBrowse)
+			hBmBrowse=(HBITMAP)LoadImage(hInst,MAKEINTRESOURCE(IDB_BROWSE),IMAGE_BITMAP,0,0,/*LR_CREATEDIBSECTION|*/LR_LOADTRANSPARENT|LR_LOADMAP3DCOLORS);
         /*	Code from LibMain inserted here.  Return TRUE to keep the
 			DLL loaded or return FALSE to fail loading the DLL.
 
@@ -75,6 +80,12 @@
 			LibMain) not be necessary.  Check to make certain that the
 			operating system is not doing it for you.
 			*/
+		hInst=NULL;
+		if(hBmBrowse)
+		{
+            DeleteObject(hBmBrowse);
+            hBmBrowse=NULL;
+		}
 		break;
 	}
  
binary files /dev/null b/plugins/cooledit/Open.bmp differ
--- a/plugins/cooledit/Readme.txt
+++ b/plugins/cooledit/Readme.txt
@@ -14,8 +14,8 @@
 
 FAAC is a codec plugin for Cooledit/Audition to import and export .aac/.mp4 files.
 
-To compile it:
---------------
+To use it:
+----------
 
 1) put FAAC and FAAD2 packages into the same folder;
 2) open the project, set "Active Configuration = FAAC - win32 Release" and compile;
@@ -24,7 +24,8 @@
 To write .mp4 files:
 --------------------
 
-Append .mp4 extension to the name of file in the "Save waveform as" dialog.
+Check "Write .mp4" in the config dialog or
+append .mp4 extension to the name of file in the "Save waveform as" dialog.
 
 ----------------------------------------------------------------------------
 
--- a/plugins/cooledit/defines.h
+++ b/plugins/cooledit/defines.h
@@ -20,10 +20,10 @@
 */
 
 #define APP_NAME "MPEG4-AAC"
-#define APP_VER "v2.2"
+#define APP_VER "v2.3"
 #define REGISTRY_PROGRAM_NAME "SOFTWARE\\4N\\CoolEdit\\AAC-MPEG4"
 
-// -----------------------------------------------------------------------------------------------
+// *********************************************************************************************
 
 #define FREE_ARRAY(ptr) \
 { \
--- a/plugins/cooledit/resource.h
+++ b/plugins/cooledit/resource.h
@@ -1,5 +1,5 @@
 //{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
+// Microsoft Visual C++ generated include file.
 // Used by FAAC.rc
 //
 #define IDD_ENCODER                     101
@@ -8,6 +8,7 @@
 #define IDB_AUDIOCODING                 104
 #define IDB_EMAIL                       106
 #define IDB_MPEG4IP                     107
+#define IDB_BROWSE                      108
 #define IDC_RADIO_MPEG4                 1000
 #define IDC_RADIO_MPEG2                 1001
 #define IDC_RADIO_LOW                   1002
@@ -25,8 +26,13 @@
 #define IDC_CHK_AUTOCFG                 1013
 #define IDC_BTN_ABOUT                   1014
 #define IDC_L_ABOUT                     1015
+#define IDC_BTN_ARTFILE                 1015
 #define IDC_AUDIOCODING                 1016
+#define IDC_CHK_USETNS2                 1016
+#define IDC_CHK_MP4                     1016
+#define WRITEMP4                        1016
 #define IDC_EMAIL                       1017
+#define IDC_E_BROWSE                    1017
 #define IDC_MPEG4IP                     1018
 #define IDC_CHK_DEFAULTCFG              1019
 #define IDC_CB_SAMPLERATE               1020
@@ -36,14 +42,30 @@
 #define IDC_CHK_DOWNMATRIX              1025
 #define IDC_CHK_OLDADTS                 1026
 #define IDC_CHK_WRITEMP4                1027
+#define IDC_E_ARTIST                    1028
+#define IDC_CHK_TAG                     1029
+#define IDC_E_TITLE                     1030
+#define IDC_E_ALBUM                     1031
+#define IDC_E_YEAR                      1032
+#define IDC_CB_GENRE                    1033
+#define IDC_E_WRITER                    1034
+#define IDC_E_COMMENT                   1035
+#define IDC_E_TRACK                     1036
+#define IDC_E_NTRACKS                   1037
+#define IDC_E_DISK                      1038
+#define IDC_E_NDISKS                    1039
+#define IDC_GRP_TAG                     1040
+#define IDC_E_COMPILATION               1041
+#define IDC_E_ARTFILE                   1042
+#define IDC_BTN_LICENSE                 1043
 
 // Next default values for new objects
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        108
+#define _APS_NEXT_RESOURCE_VALUE        109
 #define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1028
+#define _APS_NEXT_CONTROL_VALUE         1044
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
--- a/plugins/winamp/CRegistry.cpp
+++ b/plugins/winamp/CRegistry.cpp
@@ -1,5 +1,5 @@
 /*
-FAAC - codec plugin for Cooledit
+CRegistry class
 Copyright (C) 2002-2004 Antonio Foranna
 
 This program is free software; you can redistribute it and/or modify
@@ -19,47 +19,56 @@
 ntnfrn_email-temp@yahoo.it
 */
 
-//#include "stdafx.h"
-#include <windows.h>
-#include <stdlib.h>		// malloc, free
-#include <string.h>
 #include "CRegistry.h"
 
+//************************************************************************************************
 
-
-// *****************************************************************************
-
-
-
 CRegistry::CRegistry()
 {
 	regKey=NULL;
 	path=NULL;
 }
+//------------------------------------------------------------------------------------------------
 
 CRegistry::~CRegistry()
 {
-	closeReg();
+	if(regKey)
+		RegCloseKey(regKey);
+	if(path)
+		free(path);
 }
+//************************************************************************************************
+/*
+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::openReg(HKEY hKey, char *SubKey)
+BOOL CRegistry::Open(HKEY hKey, char *SubKey)
 {
 	if(regKey)
 		RegCloseKey(regKey);
-	if(RegOpenKeyEx(hKey, SubKey, NULL , KEY_ALL_ACCESS , &regKey)==ERROR_SUCCESS)
+	if(RegOpenKeyEx(hKey, SubKey, 0, KEY_ALL_ACCESS, &regKey)==ERROR_SUCCESS)
 	{
 		setPath(SubKey);
 		return TRUE;
@@ -71,13 +80,13 @@
 		return FALSE;
 	}
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-BOOL CRegistry::openCreateReg(HKEY hKey, char *SubKey)
+BOOL CRegistry::OpenCreate(HKEY hKey, char *SubKey)
 {
 	if(regKey)
 		RegCloseKey(regKey);
-	if(RegOpenKeyEx(hKey, SubKey, NULL , KEY_ALL_ACCESS , &regKey)==ERROR_SUCCESS)
+	if(RegOpenKeyEx(hKey, SubKey, 0, KEY_ALL_ACCESS, &regKey)==ERROR_SUCCESS)
 	{
 		setPath(SubKey);
 		return TRUE;
@@ -85,7 +94,7 @@
 	else // open failed -> create the key
 	{
 	DWORD disp;
-		RegCreateKeyEx(hKey , SubKey, NULL , NULL, REG_OPTION_NON_VOLATILE , KEY_ALL_ACCESS , NULL , &regKey , &disp );
+		RegCreateKeyEx(hKey, SubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &regKey, &disp);
 		if(disp==REG_CREATED_NEW_KEY) 
 		{
 			setPath(SubKey);
@@ -99,9 +108,9 @@
 		}
 	}
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::closeReg()
+void CRegistry::Close()
 {
 	if(regKey)
 		RegCloseKey(regKey);
@@ -110,93 +119,78 @@
 		delete path; 
 	path=NULL;
 }
+//************************************************************************************************
+//************************************************************************************************
+//************************************************************************************************
 
-
-
-// *****************************************************************************
-
-
-
-void CRegistry::DeleteRegVal(char *SubKey)
+void CRegistry::DeleteVal(char *SubKey)
 {
 	RegDeleteValue(regKey,SubKey);
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::DeleteRegKey(char *SubKey)
+void CRegistry::DeleteKey(char *SubKey)
 {
 	RegDeleteKey(regKey,SubKey);
 }
 
+//************************************************************************************************
+//************************************************************************************************
+//************************************************************************************************
 
-
-// *****************************************************************************
-
-
-
-void CRegistry::setRegBool(char *keyStr , BOOL val)
+void CRegistry::SetBool(char *keyStr, BOOL val)
 {
 BOOL tempVal;
 DWORD len;
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
 		tempVal!=val)
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(BOOL));
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, (BYTE *)&val, sizeof(BOOL));
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::setRegBool(char *keyStr , bool val)
+void CRegistry::SetByte(char *keyStr, BYTE val)
 {
-bool tempVal;
-DWORD len;
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS ||
-		tempVal!=val)
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(bool));
-}
-// -----------------------------------------------------------------------------------------------
-
-void CRegistry::setRegByte(char *keyStr , BYTE val)
-{
 DWORD	t=val;
 DWORD	tempVal;
 DWORD	len;
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
 		tempVal!=val)
-		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&t , sizeof(DWORD));
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&t, sizeof(DWORD));
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::setRegWord(char *keyStr , WORD val)
+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 ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
 		tempVal!=val)
-		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&t , sizeof(DWORD));
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&t, sizeof(DWORD));
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::setRegDword(char *keyStr , DWORD val)
+void CRegistry::SetDword(char *keyStr, DWORD val)
 {
 DWORD tempVal;
 DWORD len;
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
 		tempVal!=val)
-		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&val , sizeof(DWORD));
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&val, sizeof(DWORD));
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::setRegFloat(char *keyStr , float val)
+void CRegistry::SetFloat(char *keyStr, float val)
 {
 float tempVal;
 DWORD len;
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS ||
 		tempVal!=val)
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(float));
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, (BYTE *)&val, sizeof(float));
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::setRegStr(char *keyStr , char *valStr)
+void CRegistry::SetStr(char *keyStr, char *valStr)
 {
 DWORD len;
 DWORD slen=strlen(valStr)+1;
@@ -204,35 +198,35 @@
 	if(!valStr || !*valStr)
 		return;
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, NULL , &len )!=ERROR_SUCCESS ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, NULL, &len )!=ERROR_SUCCESS ||
 		len!=slen)
-		RegSetValueEx(regKey , keyStr , NULL , REG_SZ , (BYTE *)valStr , 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 ||
+		if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)tempVal, &len )!=ERROR_SUCCESS ||
 			strcmpi(tempVal,valStr))
-			RegSetValueEx(regKey , keyStr , NULL , REG_SZ , (BYTE *)valStr , slen);
+			RegSetValueEx(regKey, keyStr, 0, REG_SZ, (BYTE *)valStr, slen);
 		delete tempVal;
 	}
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-void CRegistry::setRegValN(char *keyStr , BYTE *addr,  DWORD size)
+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 ||
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, NULL, &len )!=ERROR_SUCCESS ||
 		len!=size)
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , addr , 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 ||
+		if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)tempVal, &len )!=ERROR_SUCCESS ||
 			memcmp(tempVal,addr,len))
-			RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , addr , size);
+			RegSetValueEx(regKey, keyStr, 0, REG_BINARY, addr, size);
 		delete tempVal;
 	}
 }
@@ -239,128 +233,130 @@
 
 
 
-// *****************************************************************************
+//************************************************************************************************
+//************************************************************************************************
+//************************************************************************************************
 
 
 
-BOOL CRegistry::getSetRegBool(char *keyStr, BOOL val)
+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 , NULL , REG_BINARY , (BYTE *)&val , sizeof(BOOL));
-		return val;
-	}
-	return tempVal;
-}
-// -----------------------------------------------------------------------------------------------
-
-bool CRegistry::getSetRegBool(char *keyStr, bool val)
-{
 bool tempVal;
 DWORD len=sizeof(bool);
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS)
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
 	{
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(bool));
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, (BYTE *)&val, sizeof(bool));
 		return val;
 	}
 	return tempVal;
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-BYTE CRegistry::getSetRegByte(char *keyStr, BYTE val)
+BYTE CRegistry::GetSetByte(char *keyStr, BYTE val)
 {
 DWORD tempVal;
 DWORD len=sizeof(DWORD);
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS)
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
 	{
 		tempVal=val;
-		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&tempVal , sizeof(DWORD));
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&tempVal, sizeof(DWORD));
 		return val;
 	}
 	return (BYTE)tempVal;
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-WORD CRegistry::getSetRegWord(char *keyStr, WORD val)
+WORD CRegistry::GetSetWord(char *keyStr, WORD val)
 {
 DWORD tempVal;
 DWORD len=sizeof(DWORD);
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS)
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
 	{
 		tempVal=val;
-		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&tempVal , sizeof(DWORD));
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&tempVal, sizeof(DWORD));
 		return val;
 	}
 	return (WORD)tempVal;
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-DWORD CRegistry::getSetRegDword(char *keyStr, DWORD val)
+DWORD CRegistry::GetSetDword(char *keyStr, DWORD val)
 {
 DWORD tempVal;
 DWORD len=sizeof(DWORD);
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS)
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
 	{
-		RegSetValueEx(regKey , keyStr , NULL , REG_DWORD , (BYTE *)&val , sizeof(DWORD));
+		RegSetValueEx(regKey, keyStr, 0, REG_DWORD, (BYTE *)&val, sizeof(DWORD));
 		return val;
 	}
 	return (DWORD)tempVal;
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-float CRegistry::getSetRegFloat(char *keyStr, float val)
+float CRegistry::GetSetFloat(char *keyStr, float val)
 {
 float tempVal;
 DWORD len=sizeof(float);
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)&tempVal , &len )!=ERROR_SUCCESS)
+	if(RegQueryValueEx(regKey, keyStr, NULL, NULL, (BYTE *)&tempVal, &len )!=ERROR_SUCCESS)
 	{
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)&val , sizeof(float));
+		RegSetValueEx(regKey, keyStr, 0, REG_BINARY, (BYTE *)&val, sizeof(float));
 		return val;
 	}
 	return tempVal;
 }
-// -----------------------------------------------------------------------------------------------
+//************************************************************************************************
 
-int CRegistry::getSetRegStr(char *keyStr, char *tempString, char *dest, int maxLen)
+char *CRegistry::GetSetStr(char *keyStr, char *String)
 {
-DWORD tempLen=maxLen;
+long	retVal;
+DWORD	Len;
+char	*dest=NULL;
 	
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *) dest , &tempLen )!=ERROR_SUCCESS)
+	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(!tempString)
-		{
-			*dest=0;
-			return 0;
-		}
-		strcpy(dest,tempString);
-		tempLen=strlen(tempString)+1;
-		RegSetValueEx(regKey , keyStr , NULL , REG_SZ , (BYTE *)tempString , tempLen);
+		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 tempLen;
+	return dest;
 }
 // -----------------------------------------------------------------------------------------------
 
-int CRegistry::getSetRegValN(char *keyStr, BYTE *tempAddr, BYTE *addr, DWORD size)
+int CRegistry::GetSetValN(char *keyStr, BYTE *defData, DWORD defSize, BYTE **dest)
 {
-DWORD tempLen=size;
+long	retVal;
+DWORD	size;
 
-	if(RegQueryValueEx(regKey , keyStr , NULL , NULL, (BYTE *)addr , &tempLen )!=ERROR_SUCCESS)
+	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(!tempAddr)
-		{
-			*addr=0;
+		if(dest)
+			free(dest);
+		if(!defData)
 			return 0;
-		}
-		memcpy(addr,tempAddr,size);
-		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)addr , size);
+
+		size=defSize;
+		if(!(*dest=(BYTE *)malloc(size)))
+			return 0;
+		memcpy(*dest,defData,size);
+		RegSetValueEx(regKey , keyStr , NULL , REG_BINARY , (BYTE *)*dest , size);
 	}
-	return tempLen;
+	return size;
 }
--- a/plugins/winamp/CRegistry.h
+++ b/plugins/winamp/CRegistry.h
@@ -1,5 +1,5 @@
 /*
-FAAC - codec plugin for Cooledit
+CRegistry class
 Copyright (C) 2002-2004 Antonio Foranna
 
 This program is free software; you can redistribute it and/or modify
@@ -19,9 +19,16 @@
 ntnfrn_email-temp@yahoo.it
 */
 
-#ifndef registry_h
-#define registry_h
+//---------------------------------------------------------------------------
+#ifndef CRegistryH
+#define CRegistryH
+//---------------------------------------------------------------------------
 
+#include <windows.h>
+#include <stdlib.h>
+#include <string.h>
+//#include <memory.h>
+
 class CRegistry 
 {
 public:
@@ -28,31 +35,30 @@
 			CRegistry();
 			~CRegistry();
 
-	BOOL	openReg(HKEY hKey, char *SubKey);
-	BOOL	openCreateReg(HKEY hKey, char *SubKey);
-	void	closeReg();
-	void	DeleteRegVal(char *SubKey);
-	void	DeleteRegKey(char *SubKey);
+	BOOL	Open(HKEY hKey, char *SubKey);
+	BOOL	OpenCreate(HKEY hKey, char *SubKey);
+	void	Close();
+	void	DeleteVal(char *SubKey);
+	void	DeleteKey(char *SubKey);
 
-	void	setRegBool(char *keyStr , BOOL val);
-	void	setRegBool(char *keyStr , bool val);
-	void	setRegByte(char *keyStr , BYTE val);
-	void	setRegWord(char *keyStr , WORD val);
-	void	setRegDword(char *keyStr , DWORD val);
-	void	setRegFloat(char *keyStr , float val);
-	void	setRegStr(char *keyStr , char *valStr);
-	void	setRegValN(char *keyStr , BYTE *addr,  DWORD size);
+	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	getSetRegBool(char *keyStr, BOOL var);
-	bool	getSetRegBool(char *keyStr, bool var);
-	BYTE	getSetRegByte(char *keyStr, BYTE var);
-	WORD	getSetRegWord(char *keyStr, WORD var);
-	DWORD	getSetRegDword(char *keyStr, DWORD var);
-	float	getSetRegFloat(char *keyStr, float var);
-	int		getSetRegStr(char *keyStr, char *tempString, char *dest, int maxLen);
-	int		getSetRegValN(char *keyStr, BYTE *tempAddr, 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
\ No newline at end of file
+
+#endif
--- a/plugins/winamp/Cfaac.cpp
+++ b/plugins/winamp/Cfaac.cpp
@@ -27,15 +27,6 @@
 
 
 
-#define FREE_ARRAY(ptr) \
-{ \
-	if(ptr) \
-		free(ptr); \
-	ptr=0; \
-}
-
-// *********************************************************************************************
-
 Cfaac::Cfaac(HANDLE hOut)
 {
 	if(hOut)
@@ -45,14 +36,10 @@
 	}
 
     if(!(hOutput=GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE|GMEM_ZEROINIT,sizeof(MYOUTPUT))))
+	{
 		MessageBox(0, "Memory allocation error: hOutput", APP_NAME " plugin", MB_OK|MB_ICONSTOP); \
-/*
-MYOUTPUT *mo;
-
-	if(!(mo=(MYOUTPUT *)GlobalLock(hOutput)))
-		MessageBox(0, "GlobalLock(hOutput)", APP_NAME " plugin", MB_OK|MB_ICONSTOP); \
-
-	GlobalUnlock(hOutput);*/
+		return;
+	}
 }
 // -----------------------------------------------------------------------------------------------
 
@@ -82,6 +69,15 @@
 	{
 		fclose(mo->aacFile);
 		mo->aacFile=0;
+
+	MY_ENC_CFG	cfg;
+		getFaacCfg(&cfg);
+		if(cfg.Tag.On && mo->Filename)
+		{
+			WriteAacTag(mo->Filename,&cfg.Tag);
+			FREE_ARRAY(mo->Filename);
+		}
+		FreeTag(&cfg.Tag);
 	}
 	else
 	{
@@ -213,7 +209,144 @@
 			break;
 	}
 }
+// *********************************************************************************************
 
+int Cfaac::check_image_header(const char *buf)
+{
+  if (!strncmp(buf, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8))
+    return 1; /* PNG */
+  else if (!strncmp(buf, "\xFF\xD8\xFF\xE0", 4) &&
+	   !strncmp(buf + 6, "JFIF\0", 5))
+    return 1; /* JPEG */
+  else if (!strncmp(buf, "GIF87a", 6) || !strncmp(buf, "GIF89a", 6))
+    return 1; /* GIF */
+  else
+    return 0;
+}
+// -----------------------------------------------------------------------------------------------
+
+int Cfaac::ReadCoverArtFile(char *pCoverArtFile, char **artData)
+{
+FILE *artFile;
+
+	if(!pCoverArtFile || !*pCoverArtFile)
+		return 0;
+
+	if(!(artFile=fopen(pCoverArtFile, "rb")))
+	{
+		MessageBox(NULL,"ReadCoverArtFile: fopen",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;
+}
+
+void Cfaac::WriteMP4Tag(MP4FileHandle MP4File, MP4TAG *Tag)
+{
+char	*art=NULL;
+DWORD	artSize;
+
+char	buf[512], *faac_id_string, *faac_copyright_string;
+	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(Tag->artist) MP4SetMetadataArtist(MP4File, Tag->artist);
+	if(Tag->writer) MP4SetMetadataWriter(MP4File, Tag->writer);
+	if(Tag->title) MP4SetMetadataName(MP4File, Tag->title);
+	if(Tag->album) MP4SetMetadataAlbum(MP4File, Tag->album);
+	if(Tag->trackno>0) MP4SetMetadataTrack(MP4File, Tag->trackno, Tag->ntracks);
+	if(Tag->discno>0) MP4SetMetadataDisk(MP4File, Tag->discno, Tag->ndiscs);
+	if(Tag->compilation) MP4SetMetadataCompilation(MP4File, Tag->compilation);
+	if(Tag->year) MP4SetMetadataYear(MP4File, Tag->year);
+	if(Tag->genre) MP4SetMetadataGenre(MP4File, Tag->genre);
+	if(Tag->comment) MP4SetMetadataComment(MP4File, Tag->comment);
+	artSize=ReadCoverArtFile(Tag->artFileName,&art);
+	if(artSize)
+	{
+		MP4SetMetadataCoverArt(MP4File, (BYTE *)art, artSize);
+		free(art);
+	}
+}
+
+#define ADD_FIELD(id3Tag,NewFrame,ID3FID,ID3FN,data) \
+{ \
+	ID3_Frame *NewFrame=new ID3_Frame(ID3FID); \
+		NewFrame->Field(ID3FN)=data; \
+		id3Tag.AttachFrame(NewFrame); \
+}
+
+void Cfaac::WriteAacTag(char *Filename, MP4TAG *Tag)
+{
+char	buf[512], *faac_id_string, *faac_copyright_string;
+char	*art=NULL;
+DWORD	artSize;
+ID3_Tag id3Tag;
+ID3_Frame *Frame;
+
+	id3Tag.Link(Filename);
+//	Frame=id3Tag.Find(ID3FID_ALBUM);
+//	if(Frame!=NULL)
+//		myTag.RemoveFrame(Frame);
+
+	sprintf(buf, "FAAC v%s", (faacEncGetVersion(&faac_id_string, &faac_copyright_string)==FAAC_CFG_VERSION) ? faac_id_string : " wrong libfaac version");
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_ENCODEDBY,ID3FN_TEXT,buf);
+
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_LEADARTIST,ID3FN_TEXT,Tag->artist);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_COMPOSER,ID3FN_TEXT,Tag->writer);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_TITLE,ID3FN_TEXT,Tag->title);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_ALBUM,ID3FN_TEXT,Tag->album);
+	sprintf(buf,"%d",Tag->trackno);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_TRACKNUM,ID3FN_TEXT,buf);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_YEAR,ID3FN_TEXT,Tag->year);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_CONTENTTYPE,ID3FN_TEXT,Tag->genre);
+	ADD_FIELD(id3Tag,NewFrame,ID3FID_COMMENT,ID3FN_TEXT,Tag->comment);
+	artSize=ReadCoverArtFile(Tag->artFileName,&art);
+	if(artSize)
+	{
+		ADD_FIELD(id3Tag,NewFrame,ID3FID_PICTURE,ID3FN_PICTURETYPE,Tag->artFileName);
+		id3Tag.Update();
+		free(art);
+	}
+	else
+		id3Tag.Update();
+}
+
 // *********************************************************************************************
 //									Main functions
 // *********************************************************************************************
@@ -238,24 +371,53 @@
 }
 // *********************************************************************************************
 
+void Cfaac::FreeTag(MP4TAG *Tag)
+{
+	FREE_ARRAY(Tag->artist);
+	FREE_ARRAY(Tag->title);
+	FREE_ARRAY(Tag->album);
+	FREE_ARRAY(Tag->year);
+	FREE_ARRAY(Tag->genre);
+	FREE_ARRAY(Tag->writer);
+	FREE_ARRAY(Tag->comment);
+	FREE_ARRAY(Tag->artFileName);
+}
+// -----------------------------------------------------------------------------------------------
+
 void Cfaac::getFaacCfg(MY_ENC_CFG *cfg)
 { 
 CRegistry reg;
 
-	if(reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME "\\FAAC"))
+	if(reg.OpenCreate(HKEY_CURRENT_USER, REGISTRY_PROGRAM_NAME "\\FAAC"))
 	{
-		cfg->AutoCfg=reg.getSetRegBool("Auto",true);
-		cfg->SaveMP4=reg.getSetRegBool("Write MP4",false);
-		cfg->EncCfg.mpegVersion=reg.getSetRegDword("MPEG version",MPEG4); 
-		cfg->EncCfg.aacObjectType=reg.getSetRegDword("Profile",LOW); 
-		cfg->EncCfg.allowMidside=reg.getSetRegDword("MidSide",true); 
-		cfg->EncCfg.useTns=reg.getSetRegDword("TNS",true); 
-		cfg->EncCfg.useLfe=reg.getSetRegDword("LFE",false);
-		cfg->UseQuality=reg.getSetRegBool("Use quality",false);
-		cfg->EncCfg.quantqual=reg.getSetRegDword("Quality",100); 
-		cfg->EncCfg.bitRate=reg.getSetRegDword("BitRate",0); 
-		cfg->EncCfg.bandWidth=reg.getSetRegDword("BandWidth",0); 
-		cfg->EncCfg.outputFormat=reg.getSetRegDword("Header",ADTS); 
+		cfg->AutoCfg=reg.GetSetBool(REG_AUTO,DEF_AUTO);
+		cfg->SaveMP4=reg.GetSetBool(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); 
+		cfg->OutDir=NULL;
+
+		cfg->Tag.On=reg.GetSetByte(REG_TAGON,0);
+		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.GetSetDword(REG_TRACK,0);
+		cfg->Tag.ntracks=reg.GetSetDword(REG_NTRACKS,0);
+		cfg->Tag.discno=reg.GetSetDword(REG_DISK,0);
+		cfg->Tag.ndiscs=reg.GetSetDword(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);
@@ -266,20 +428,35 @@
 { 
 CRegistry reg;
 
-	if(reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME "\\FAAC"))
+	if(reg.OpenCreate(HKEY_CURRENT_USER, REGISTRY_PROGRAM_NAME "\\FAAC"))
 	{
-		reg.setRegBool("Auto",cfg->AutoCfg); 
-		reg.setRegBool("Write MP4",cfg->SaveMP4); 
-		reg.setRegDword("MPEG version",cfg->EncCfg.mpegVersion); 
-		reg.setRegDword("Profile",cfg->EncCfg.aacObjectType); 
-		reg.setRegDword("MidSide",cfg->EncCfg.allowMidside); 
-		reg.setRegDword("TNS",cfg->EncCfg.useTns); 
-		reg.setRegDword("LFE",cfg->EncCfg.useLfe); 
-		reg.setRegBool("Use quality",cfg->UseQuality); 
-		reg.setRegDword("Quality",cfg->EncCfg.quantqual); 
-		reg.setRegDword("BitRate",cfg->EncCfg.bitRate); 
-		reg.setRegDword("BandWidth",cfg->EncCfg.bandWidth); 
-		reg.setRegDword("Header",cfg->EncCfg.outputFormat); 
+		reg.SetBool(REG_AUTO,cfg->AutoCfg); 
+		reg.SetBool(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.SetByte(REG_TAGON,cfg->Tag.On);
+		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.SetDword(REG_TRACK,cfg->Tag.trackno); 
+		reg.SetDword(REG_NTRACKS,cfg->Tag.ntracks); 
+		reg.SetDword(REG_DISK,cfg->Tag.discno); 
+		reg.SetDword(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);
@@ -313,36 +490,53 @@
 	if(!(mo->buf32bit=(int32_t *)malloc(samplesInput*sizeof(int32_t))))
 		return ERROR_Init("Memory allocation error: 32 bit buffer");
 
-
 	getFaacCfg(&cfg);
 
-	if(cfg.SaveMP4)
+	if(cfg.SaveMP4)// || cfg.Tag.On)
 		if(!strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".aac"))
+		{
 			strcpy(lpstrFilename+lstrlen(lpstrFilename)-4,".mp4");
+		FILE *f=fopen(lpstrFilename,"rb");
+			if(f)
+			{
+			char buf[MAX_PATH+20];
+				sprintf(buf,"Overwrite \"%s\" ?",lpstrFilename);
+				fclose(f);
+				if(MessageBox(NULL,buf,"File already exists!",MB_YESNO|MB_ICONQUESTION)==IDNO)
+					return ERROR_Init(0);//"User abort");
+			}
+		}
 		else
 			if(strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".mp4"))
 				strcat(lpstrFilename,".mp4");
-	mo->WriteMP4=!strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".mp4");
+	mo->WriteMP4=	!strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".mp4") ||
+					!strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".m4a");
 
-	if(cfg.AutoCfg)
+faacEncConfigurationPtr CurFormat=faacEncGetCurrentConfiguration(mo->hEncoder);
+	CurFormat->inputFormat=FAAC_INPUT_32BIT;
+/*	switch(wBitsPerSample)
 	{
-	faacEncConfigurationPtr myFormat=&cfg.EncCfg;
-	faacEncConfigurationPtr CurFormat=faacEncGetCurrentConfiguration(mo->hEncoder);
-		if(mo->WriteMP4)
-			CurFormat->outputFormat=RAW;
-		CurFormat->useLfe=wChannels>=6 ? 1 : 0;
-		if(!faacEncSetConfiguration(mo->hEncoder, CurFormat))
-			return ERROR_Init("Unsupported parameters!");
-	}
-	else
+	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;
-	faacEncConfigurationPtr CurFormat=faacEncGetCurrentConfiguration(mo->hEncoder);
 
 		if(cfg.UseQuality)
 		{
 			CurFormat->quantqual=myFormat->quantqual;
-			CurFormat->bitRate=myFormat->bitRate;
+			CurFormat->bitRate=0;//myFormat->bitRate;
 		}
 		else
 			if(!CurFormat->bitRate)
@@ -361,34 +555,30 @@
 			CurFormat->bandWidth=myFormat->bandWidth;
 			break;
 		}
-/*
-		switch(wBitsPerSample)
-		{
-		case 16:
-			CurFormat->inputFormat=FAAC_INPUT_16BIT;
-			break;
-		case 24:
-			CurFormat->inputFormat=FAAC_INPUT_24BIT;
-			break;
-		case 32:
-			CurFormat->inputFormat=FAAC_INPUT_32BIT;
-			break;
-		default:
-			CurFormat->inputFormat=FAAC_INPUT_NULL;
-			break;
-		}
-*/
 		CurFormat->mpegVersion=myFormat->mpegVersion;
-		CurFormat->outputFormat=mo->WriteMP4 ? 0 : myFormat->outputFormat;
+		CurFormat->outputFormat=myFormat->outputFormat;
 		CurFormat->mpegVersion=myFormat->mpegVersion;
 		CurFormat->aacObjectType=myFormat->aacObjectType;
 		CurFormat->allowMidside=myFormat->allowMidside;
 		CurFormat->useTns=myFormat->useTns;
-		CurFormat->useLfe=wChannels>=6 ? 1 : 0;
-
-		if(!faacEncSetConfiguration(mo->hEncoder, CurFormat))
-			return ERROR_Init("Unsupported parameters!");
 	}
+	else
+	{
+		CurFormat->mpegVersion=DEF_MPEGVER;
+		CurFormat->aacObjectType=DEF_PROFILE;
+		CurFormat->allowMidside=DEF_MIDSIDE;
+		CurFormat->useTns=DEF_TNS;
+		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(lpstrFilename);
@@ -414,7 +604,10 @@
         MP4SetTrackESConfiguration(mo->MP4File, mo->MP4track, (unsigned __int8 *)ASC, ASCLength);
 		mo->frameSize=samplesInput/wChannels;
 		mo->ofs=mo->frameSize;
-    }
+
+		if(cfg.Tag.On)
+			WriteMP4Tag(mo->MP4File,&cfg.Tag);
+	}
 	else // Create AAC file -----------------------------------------------------------------------------
 	{
 		// open the aac output file 
@@ -423,10 +616,13 @@
 
 		// use bufferized stream
 		setvbuf(mo->aacFile,NULL,_IOFBF,32767);
+
+		mo->Filename=strdup(lpstrFilename);
 	}
 
 	showInfo(mo);
 
+	FreeTag(&cfg.Tag);
 	GlobalUnlock(hOutput);
     return hOutput;
 }
@@ -450,7 +646,8 @@
 		mo->samplesInput=(len<<3)/mo->BitsPerSample;
 		mo->samplesInputSize=mo->samplesInput*(mo->BitsPerSample>>3);
 	}
-	To32bit(buf,bufIn,mo->samplesInput,mo->BitsPerSample>>3,false);
+//	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)
--- a/plugins/winamp/Cfaac.h
+++ b/plugins/winamp/Cfaac.h
@@ -37,6 +37,7 @@
 #endif
 #include <faac.h>
 #include <win32_ver.h>	// mpeg4ip version
+#include <id3/tag.h>	// id3 tag
 #include "CRegistry.h"
 #include "Defines.h"	// my defines
 
@@ -49,12 +50,66 @@
 
 // *********************************************************************************************
 
+#define REG_AUTO "Auto"
+#define DEF_AUTO true
+#define REG_WRITEMP4 "Write MP4"
+#define DEF_WRITEMP4 false
+#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 false
+#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_TAGON "Tag On"
+#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
+{
+BYTE	On;
+char	*artist, *title, *album, *year, *genre, *writer, *comment;
+int		trackno,ntracks, discno,ndiscs;
+BYTE	compilation;
+char	*artFileName;
+} MP4TAG;
+// -----------------------------------------------------------------------------------------------
+
 typedef struct mec
 {
 bool					AutoCfg,
 						UseQuality,
 						SaveMP4;
+char					*OutDir;
 faacEncConfiguration	EncCfg;
+MP4TAG					Tag;
 } MY_ENC_CFG;
 // -----------------------------------------------------------------------------------------------
 
@@ -71,6 +126,7 @@
 
 // AAC
 FILE			*aacFile;
+char			*Filename;
 
 // GLOBAL
 long			Samprate;
@@ -104,14 +160,19 @@
 	virtual int ERROR_processData(char *str) { DisplayError("processData", str); return -1; }
 	virtual void showInfo(MYOUTPUT *mi) {}
 	virtual void showProgress(MYOUTPUT *mi) {}
-	virtual void To32bit(int32_t *buf, BYTE *bufi, int size, BYTE samplebytes, BYTE bigendian);
+	void To32bit(int32_t *buf, BYTE *bufi, int size, BYTE samplebytes, BYTE bigendian);
+	int check_image_header(const char *buf);
+	int ReadCoverArtFile(char *pCoverArtFile, char **artBuf);
 
 public:
     Cfaac(HANDLE hOutput=NULL);
     virtual ~Cfaac();
 
+	static void FreeTag(MP4TAG *Tag);
 	static void getFaacCfg(MY_ENC_CFG *cfg);
 	static void setFaacCfg(MY_ENC_CFG *cfg);
+	virtual void WriteMP4Tag(MP4FileHandle MP4File, MP4TAG *Tag);
+	virtual void WriteAacTag(char *Filename, MP4TAG *Tag);
     virtual HANDLE Init(LPSTR lpstrFilename,long lSamprate,WORD wBitsPerSample,WORD wChannels,long FileSize);
     virtual int processData(HANDLE hOutput, BYTE *bufIn, DWORD len);
 	virtual int processDataBufferized(HANDLE hOutput, BYTE *bufIn, long lBytes);
--- a/plugins/winamp/FAAC.rc
+++ b/plugins/winamp/FAAC.rc
@@ -1,4 +1,4 @@
-//Microsoft Developer Studio generated resource script.
+// Microsoft Visual C++ generated resource script.
 //
 #include "resource.h"
 
@@ -26,58 +26,126 @@
 // Dialog
 //
 
-IDD_ENCODER DIALOG DISCARDABLE  0, 0, 195, 167
-STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
-CAPTION "AAC-MPEG4 options"
-FONT 8, "MS Sans Serif"
+IDD_ENCODER DIALOGEX 0, 0, 338, 209
+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,119,148,36,14
-    PUSHBUTTON      "Cancel",IDCANCEL,155,148,36,14
+    DEFPUSHBUTTON   "&OK",IDOK,12,190,36,14
+    PUSHBUTTON      "&Cancel",IDCANCEL,48,190,36,14
+    PUSHBUTTON      "&About",IDC_BTN_ABOUT,84,190,36,14
+    PUSHBUTTON      "&License",IDC_BTN_LICENSE,120,190,36,14
     CONTROL         "Automatic configuration",IDC_CHK_AUTOCFG,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,4,4,90,10
-    CONTROL         "MPEG4",IDC_RADIO_MPEG4,"Button",BS_AUTORADIOBUTTON | 
-                    WS_GROUP,8,29,42,10
-    CONTROL         "MPEG2",IDC_RADIO_MPEG2,"Button",BS_AUTORADIOBUTTON,8,42,
-                    41,9
     CONTROL         "Main",IDC_RADIO_MAIN,"Button",BS_AUTORADIOBUTTON | 
-                    WS_GROUP,12,73,31,10
-    CONTROL         "LC",IDC_RADIO_LOW,"Button",BS_AUTORADIOBUTTON,12,85,25,
+                    WS_GROUP,9,27,31,10
+    CONTROL         "LC",IDC_RADIO_LOW,"Button",BS_AUTORADIOBUTTON,9,39,25,
                     10
     CONTROL         "SSR",IDC_RADIO_SSR,"Button",BS_AUTORADIOBUTTON | 
-                    WS_DISABLED,12,97,31,10
-    CONTROL         "LTP",IDC_RADIO_LTP,"Button",BS_AUTORADIOBUTTON,12,109,
-                    29,10
+                    WS_DISABLED,9,51,31,10
+    CONTROL         "LTP",IDC_RADIO_LTP,"Button",BS_AUTORADIOBUTTON,9,63,29,
+                    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,59,30,42,10
-    CONTROL         "ADTS",IDC_RADIO_ADTS,"Button",BS_AUTORADIOBUTTON,59,42,
+                    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,89,37,10
+    CONTROL         "Bitrate per channel",IDC_RADIO_BITRATE,"Button",
+                    BS_AUTORADIOBUTTON,9,105,75,10
+    COMBOBOX        IDC_CB_QUALITY,102,86,48,97,CBS_DROPDOWN | WS_VSCROLL | 
+                    WS_TABSTOP
+    COMBOBOX        IDC_CB_BITRATE,102,102,48,86,CBS_DROPDOWN | WS_VSCROLL | 
+                    WS_TABSTOP
+    LTEXT           "Bandwidth",IDC_STATIC,21,126,34,8
+    COMBOBOX        IDC_CB_BANDWIDTH,102,123,48,81,CBS_DROPDOWN | WS_VSCROLL | 
+                    WS_TABSTOP
     CONTROL         "Allow Mid/Side",IDC_CHK_ALLOWMIDSIDE,"Button",
-                    BS_AUTOCHECKBOX | WS_TABSTOP,107,21,63,10
+                    BS_AUTOCHECKBOX | WS_TABSTOP,9,140,63,10
     CONTROL         "Use TNS",IDC_CHK_USETNS,"Button",BS_AUTOCHECKBOX | 
-                    WS_TABSTOP,107,34,45,10
-    CONTROL         "Write .mp4",IDC_CHK_WRITEMP4,"Button",BS_AUTOCHECKBOX | 
-                    WS_TABSTOP,107,46,50,10
+                    WS_TABSTOP,9,153,45,10
     CONTROL         "Use LFE channel",IDC_CHK_USELFE,"Button",
                     BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | 
-                    WS_TABSTOP,4,152,67,10
-    CONTROL         "Quality",IDC_RADIO_QUALITY,"Button",BS_AUTORADIOBUTTON | 
-                    WS_GROUP,62,74,37,10
-    COMBOBOX        IDC_CB_QUALITY,138,72,48,97,CBS_DROPDOWN | WS_VSCROLL | 
+                    WS_TABSTOP,71,59,67,10
+    CONTROL         "Write .mp4",IDC_CHK_WRITEMP4,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,102,153,50,10
+    EDITTEXT        IDC_E_BROWSE,50,167,83,14,ES_AUTOHSCROLL
+    PUSHBUTTON      "Browse",IDC_BTN_BROWSE,137,167,18,14,BS_BITMAP | 
+                    BS_FLAT
+    GROUPBOX        "",IDC_GRP_TAG,160,4,174,200
+    CONTROL         "Tag (write .mp4)",IDC_CHK_TAG,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,165,3,67,10
+    EDITTEXT        IDC_E_ARTIST,207,20,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_TITLE,207,35,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_ALBUM,207,50,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_YEAR,207,65,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_WRITER,207,94,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_COMMENT,207,109,121,29,ES_MULTILINE | 
+                    ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_COMPILATION,207,139,121,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_TRACK,233,155,40,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_NTRACKS,288,155,40,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_DISK,233,170,40,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_NDISKS,288,170,40,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_E_ARTFILE,207,185,98,14,ES_AUTOHSCROLL
+    PUSHBUTTON      "&...",IDC_BTN_ARTFILE,311,185,17,14,BS_BITMAP | BS_FLAT
+    GROUPBOX        "AAC type",IDC_STATIC,56,16,48,38
+    GROUPBOX        "Profile",IDC_STATIC,4,16,48,59
+    GROUPBOX        "Header",IDC_STATIC,108,16,48,38
+    GROUPBOX        "Encoding mode",IDC_STATIC,4,78,152,42
+    LTEXT           "Artist",IDC_STATIC,165,22,16,8
+    LTEXT           "Title",IDC_STATIC,165,37,14,8
+    LTEXT           "Album",IDC_STATIC,165,52,20,8
+    LTEXT           "Year",IDC_STATIC,165,67,16,8
+    LTEXT           "Genre",IDC_STATIC,165,82,20,8
+    LTEXT           "Writer",IDC_STATIC,165,97,20,8
+    LTEXT           "Comment\n(ctrl-Enter\nto go down)",IDC_STATIC,165,113,
+                    37,26
+    LTEXT           "Track",IDC_STATIC,165,159,20,8
+    LTEXT           "/",IDC_STATIC,277,159,8,8
+    LTEXT           "Disk",IDC_STATIC,165,173,15,8
+    LTEXT           "/",IDC_STATIC,277,173,8,8
+    LTEXT           "Compilation",IDC_STATIC,165,143,37,8
+    LTEXT           "Cover art file",IDC_STATIC,165,188,40,8
+    LTEXT           "Output folder",IDC_STATIC,4,169,42,8
+    COMBOBOX        IDC_CB_GENRE,207,80,121,161,CBS_DROPDOWN | WS_VSCROLL | 
                     WS_TABSTOP
-    CONTROL         "Bitrate per channel",IDC_RADIO_BITRATE,"Button",
-                    BS_AUTORADIOBUTTON,62,90,75,10
-    COMBOBOX        IDC_CB_BITRATE,138,88,48,86,CBS_DROPDOWN | WS_VSCROLL | 
+END
+
+IDD_DECODER DIALOG  0, 0, 141, 105
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | 
+    WS_SYSMENU
+CAPTION "Raw .AAC options"
+FONT 8, "MS Sans Serif"
+BEGIN
+    DEFPUSHBUTTON   "&OK",IDOK,24,84,36,14
+    PUSHBUTTON      "&Cancel",IDCANCEL,61,84,36,14
+    PUSHBUTTON      "&About",IDC_BTN_ABOUT,97,84,36,14
+    CONTROL         "Main",IDC_RADIO_MAIN,"Button",BS_AUTORADIOBUTTON | 
+                    WS_GROUP,93,17,31,10
+    CONTROL         "Low",IDC_RADIO_LOW,"Button",BS_AUTORADIOBUTTON,93,28,29,
+                    10
+    CONTROL         "SSR",IDC_RADIO_SSR,"Button",BS_AUTORADIOBUTTON | 
+                    WS_DISABLED,93,40,31,10
+    CONTROL         "LTP",IDC_RADIO_LTP,"Button",BS_AUTORADIOBUTTON,93,52,29,
+                    10
+    GROUPBOX        "Profile",IDC_STATIC,85,7,48,70
+    COMBOBOX        IDC_CB_SAMPLERATE,13,57,62,87,CBS_DROPDOWN | WS_VSCROLL | 
                     WS_TABSTOP
-    COMBOBOX        IDC_CB_BANDWIDTH,138,109,48,81,CBS_DROPDOWN | WS_VSCROLL | 
-                    WS_TABSTOP
-    EDITTEXT        IDC_E_BROWSE,4,128,163,14,ES_AUTOHSCROLL
-    PUSHBUTTON      "Browse",IDC_BTN_BROWSE,173,128,18,14,BS_BITMAP | 
-                    BS_FLAT
-    GROUPBOX        "AAC type",IDC_STATIC,4,18,48,38
-    GROUPBOX        "Profile",IDC_STATIC,4,63,48,59
-    GROUPBOX        "Header",IDC_STATIC,55,18,48,38
-    LTEXT           "Bandwidth",IDC_STATIC,74,112,34,8
-    GROUPBOX        "Encoding mode",IDC_STATIC,56,63,135,42
+    CONTROL         "Default settings",IDC_CHK_DEFAULTCFG,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,11,64,10
+    GROUPBOX        "Sample rate",IDC_STATIC,7,46,73,31
+    CONTROL         "HE",IDC_RADIO_HE,"Button",BS_AUTORADIOBUTTON,93,64,26,
+                    10
+    CONTROL         "Downmatrix",IDC_CHK_DOWNMATRIX,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,7,24,53,10
+    CONTROL         "Old ADTS",IDC_CHK_OLDADTS,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,7,36,48,10
 END
 
 
@@ -87,18 +155,18 @@
 // TEXTINCLUDE
 //
 
-1 TEXTINCLUDE DISCARDABLE 
+1 TEXTINCLUDE 
 BEGIN
     "resource.h\0"
 END
 
-2 TEXTINCLUDE DISCARDABLE 
+2 TEXTINCLUDE 
 BEGIN
     "#include ""afxres.h""\r\n"
     "\0"
 END
 
-3 TEXTINCLUDE DISCARDABLE 
+3 TEXTINCLUDE 
 BEGIN
     "\r\n"
     "\0"
@@ -113,15 +181,23 @@
 //
 
 #ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO DISCARDABLE 
+GUIDELINES DESIGNINFO 
 BEGIN
     IDD_ENCODER, DIALOG
     BEGIN
         LEFTMARGIN, 4
-        RIGHTMARGIN, 191
+        RIGHTMARGIN, 334
         TOPMARGIN, 4
-        BOTTOMMARGIN, 162
+        BOTTOMMARGIN, 204
     END
+
+    IDD_DECODER, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 133
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 98
+    END
 END
 #endif    // APSTUDIO_INVOKED
 
@@ -143,17 +219,17 @@
 // Dialog
 //
 
-IDD_ABOUT DIALOG DISCARDABLE  0, 0, 192, 230
-STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
+IDD_ABOUT DIALOG  0, 0, 191, 230
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
 CAPTION "About"
 FONT 8, "MS Sans Serif"
 BEGIN
-    DEFPUSHBUTTON   "&OK",IDOK,135,209,50,14
-    CONTROL         107,IDC_AUDIOCODING,"Static",SS_BITMAP | SS_NOTIFY | 
+    DEFPUSHBUTTON   "&OK",IDOK,134,208,50,14
+    CONTROL         104,IDC_AUDIOCODING,"Static",SS_BITMAP | SS_NOTIFY | 
                     SS_SUNKEN,7,7,178,69
-    CONTROL         110,IDC_MPEG4IP,"Static",SS_BITMAP | SS_NOTIFY | 
-                    SS_SUNKEN,7,204,59,19
-    CONTROL         109,IDC_EMAIL,"Static",SS_BITMAP | SS_NOTIFY,77,205,43,
+    CONTROL         107,IDC_MPEG4IP,"Static",SS_BITMAP | SS_NOTIFY | 
+                    SS_SUNKEN,7,203,59,19
+    CONTROL         106,IDC_EMAIL,"Static",SS_BITMAP | SS_NOTIFY,77,204,43,
                     18
     LTEXT           "Text",IDC_L_ABOUT,7,55,177,142
 END
@@ -165,14 +241,14 @@
 //
 
 #ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO DISCARDABLE 
+GUIDELINES DESIGNINFO 
 BEGIN
     IDD_ABOUT, DIALOG
     BEGIN
         LEFTMARGIN, 7
-        RIGHTMARGIN, 185
+        RIGHTMARGIN, 184
         TOPMARGIN, 7
-        BOTTOMMARGIN, 223
+        BOTTOMMARGIN, 222
     END
 END
 #endif    // APSTUDIO_INVOKED
@@ -183,10 +259,10 @@
 // Bitmap
 //
 
-IDB_BROWSE              BITMAP  DISCARDABLE     "Open.bmp"
-IDB_AUDIOCODING         BITMAP  DISCARDABLE     "AudioCoding.bmp"
-IDB_EMAIL               BITMAP  DISCARDABLE     "Email.bmp"
-IDB_MPEG4IP             BITMAP  DISCARDABLE     "mpeg4ip-v.bmp"
+IDB_AUDIOCODING         BITMAP                  "AudioCoding.bmp"
+IDB_EMAIL               BITMAP                  "Email.bmp"
+IDB_MPEG4IP             BITMAP                  "mpeg4ip-v.bmp"
+IDB_BROWSE              BITMAP                  "Open.bmp"
 #endif    // Italian (Italy) resources
 /////////////////////////////////////////////////////////////////////////////
 
binary files a/plugins/winamp/Open.bmp b/plugins/winamp/Open.bmp differ
--- a/plugins/winamp/Out_faac.cpp
+++ b/plugins/winamp/Out_faac.cpp
@@ -23,6 +23,7 @@
 #include <shlobj.h>
 #include <stdio.h>		// FILE *
 #include <shellapi.h>	// ShellExecute
+#include <Commdlg.h>
 #include "resource.h"
 #include "out.h"
 /*#include <mp4.h>
@@ -33,8 +34,12 @@
 #include "defines.h"
 #include "Cfaac.h"
 
+#include <commctrl.h>
+//#include <id3.h>
+#include <id3v2tag.h>
 
 
+
 void Config(HWND);
 void About(HWND);
 void Init();
@@ -178,29 +183,23 @@
 	{
 	case WM_INITDIALOG:
 		{
-		  char buf[512];
-		  unsigned long samplesInput, maxBytesOutput;
+		char buf[512];
+		char *faac_id_string, *faac_copyright_string;
 
-		  faacEncHandle hEncoder =
-		    faacEncOpen(44100, 2, &samplesInput, &maxBytesOutput);
-		  faacEncConfigurationPtr myFormat =
-		    faacEncGetCurrentConfiguration(hEncoder);
-
-			sprintf(buf,
+		sprintf(buf,
 					APP_NAME " plugin " APP_VER " by Antonio Foranna\n\n"
 					"Engines used:\n"
 					"\tlibfaac v%s\n"
-//					"\tFAAD2 v" FAAD2_VERSION "\n"
+					"\tFAAD2 v" FAAD2_VERSION "\n"
 					"\t" PACKAGE " v" VERSION "\n\n"
 					"This code is given with FAAC package and does not contain executables.\n"
 					"This program is free software and can be distributed/modifyed under the terms of the GNU General Public License.\n"
 					"This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.\n\n"
 					"Compiled on %s\n",
-					(myFormat->version == FAAC_CFG_VERSION) ? myFormat->name : " bad version",
+				(faacEncGetVersion(&faac_id_string, &faac_copyright_string)==FAAC_CFG_VERSION) ? faac_id_string : " wrong libfaac version",
 					__DATE__
 					);
 			SetDlgItemText(hWndDlg, IDC_L_ABOUT, buf);
-			faacEncClose(hEncoder);
 		}
 		break;
 	case WM_COMMAND:
@@ -256,7 +255,7 @@
 }
 // *********************************************************************************************
 
-static int CALLBACK WINAPI BrowseCallbackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
+static int CALLBACK BrowseCallbackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
 {
 	if (uMsg == BFFM_INITIALIZED)
 	{
@@ -271,8 +270,12 @@
 { 
 CRegistry reg;
 
-	if(reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME))
-		reg.getSetRegStr("OutDir","",OutDir,MAX_PATH); 
+	if(reg.OpenCreate(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME))
+	{
+	char *tmp=reg.GetSetStr("OutDir","");
+		memcpy(OutDir,tmp,strlen(tmp));
+		free(tmp);
+	}
 	else
 		MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
 }
@@ -282,8 +285,8 @@
 { 
 CRegistry reg;
 
-	if(reg.openCreateReg(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME))
-		reg.setRegStr("OutDir",OutDir); 
+	if(reg.OpenCreate(HKEY_LOCAL_MACHINE,REGISTRY_PROGRAM_NAME))
+		reg.SetStr("OutDir",OutDir); 
 	else
 		MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
 }
@@ -295,7 +298,16 @@
 		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) && \
@@ -333,6 +345,167 @@
 }
 // -----------------------------------------------------------------------------------------------
 
+#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_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_E_NTRACKS), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_DISK), Enabled); \
+	EnableWindow(GetDlgItem(hWndDlg, IDC_E_NDISKS), Enabled); \
+}
+// -----------------------------------------------------------------------------------------------
+
+// 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"
+};
+
 static BOOL CALLBACK DIALOGMsgProc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
 {
 	switch(Message)
@@ -345,6 +518,8 @@
 		char *BandWidth[]={"Auto","Full","4000","8000","11025","16000","22050","24000","32000","44100","48000",0};
 		MY_ENC_CFG cfg;
 			
+			SetWindowPos(GetDlgItem(hWndDlg,IDC_CHK_TAG),GetDlgItem(hWndDlg,IDC_GRP_TAG),0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
+
 			ReadCfgEnc();
 			Cfaac::getFaacCfg(&cfg);
 			
@@ -351,8 +526,11 @@
 			INIT_CB(hWndDlg,IDC_CB_QUALITY,Quality,0);
 			INIT_CB(hWndDlg,IDC_CB_BITRATE,BitRate,0);
 			INIT_CB(hWndDlg,IDC_CB_BANDWIDTH,BandWidth,0);
+
+			INIT_CB_GENRES(hWndDlg,IDC_CB_GENRE,ID3Genres,0);
 			
 			SendMessage(GetDlgItem(hWndDlg, IDC_BTN_BROWSE), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBmBrowse);
+			SendMessage(GetDlgItem(hWndDlg, IDC_BTN_ARTFILE), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBmBrowse);
 			if(!*OutDir)
 				GetCurrentDirectory(MAX_PATH,OutDir);
 			SetDlgItemText(hWndDlg, IDC_E_BROWSE, OutDir);
@@ -439,8 +617,25 @@
 			CheckDlgButton(hWndDlg, IDC_CHK_WRITEMP4, cfg.SaveMP4);
 
 			CheckDlgButton(hWndDlg,IDC_CHK_AUTOCFG, cfg.AutoCfg);
-			
 			DISABLE_CTRL(!cfg.AutoCfg);
+
+			CheckDlgButton(hWndDlg,IDC_CHK_TAG, cfg.Tag.On);
+			ENABLE_TAG(cfg.Tag.On);
+			ENABLE_AACTAGS(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);
+			Cfaac::FreeTag(&cfg.Tag);
 		}
 		break; // End of WM_INITDIALOG                                 
 		
@@ -452,13 +647,6 @@
 	case WM_COMMAND:
 		switch(LOWORD(wParam))
 		{
-		case IDC_CHK_AUTOCFG:
-			{
-			char Enabled=!IsDlgButtonChecked(hWndDlg,IDC_CHK_AUTOCFG);
-				DISABLE_CTRL(Enabled);
-			}
-			break;
-			
 		case IDOK:
 			{
 			HANDLE hCfg=(HANDLE)lParam;
@@ -515,8 +703,34 @@
 				
 				cfg.SaveMP4=IsDlgButtonChecked(hWndDlg, IDC_CHK_WRITEMP4) ? TRUE : FALSE;
 
+				cfg.Tag.On=IsDlgButtonChecked(hWndDlg,IDC_CHK_TAG) ? 1 : 0;
+			char buffer[MAX_PATH];
+				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);
+
 				WriteCfgEnc();
 				Cfaac::setFaacCfg(&cfg);
+				Cfaac::FreeTag(&cfg.Tag);
+
 				EndDialog(hWndDlg, (DWORD)hCfg);
 			}
 			break;
@@ -526,6 +740,73 @@
 			// 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;
 			
 		case IDC_BTN_BROWSE:
 			{
@@ -550,6 +831,33 @@
 			}
 			break;
 			
+		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;
+				ofn.hInstance			= hInstance;
+
+				if(GetOpenFileName(&ofn))
+					SetDlgItemText(hWndDlg, IDC_E_ARTFILE, ArtFilename);
+			}
+			break;
+
 		case IDC_RADIO_MPEG4:
 			EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LTP), !IsDlgButtonChecked(hWndDlg,IDC_CHK_AUTOCFG));
 			break;
@@ -557,7 +865,27 @@
 		case IDC_RADIO_MPEG2:
 			EnableWindow(GetDlgItem(hWndDlg, IDC_RADIO_LTP), FALSE);
 			DISABLE_LTP
-				break;
+			break;
+
+		case IDC_CHK_AUTOCFG:
+			{
+			char Enabled=!IsDlgButtonChecked(hWndDlg,IDC_CHK_AUTOCFG);
+				DISABLE_CTRL(Enabled);
+			}
+			break;
+
+		case IDC_CHK_TAG:
+			{
+			char Enabled=IsDlgButtonChecked(hWndDlg,IDC_CHK_TAG);
+				ENABLE_TAG(Enabled);
+			}
+//			break;
+		case IDC_CHK_WRITEMP4:
+			{
+			char Enabled=IsDlgButtonChecked(hWndDlg,IDC_CHK_WRITEMP4) && IsDlgButtonChecked(hWndDlg,IDC_CHK_TAG);
+				ENABLE_AACTAGS(Enabled);
+			}
+			break;
 		}
 		break; // End of WM_COMMAND
 	default: 
--- a/plugins/winamp/RESOURCE.H
+++ b/plugins/winamp/RESOURCE.H
@@ -1,16 +1,15 @@
 //{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
+// Microsoft Visual C++ generated include file.
 // Used by FAAC.rc
 //
-#define IDOK2                           3
-#define IDD_COMPRESSION                 101
 #define IDD_ENCODER                     101
-#define IDD_ABOUT                       102
-#define IDB_LOGO                        104
-#define IDB_BROWSE                      105
-#define IDB_AUDIOCODING                 107
-#define IDB_EMAIL                       109
-#define IDB_MPEG4IP                     110
+#define IDD_DECODER                     102
+#define IDD_ABOUT                       103
+#define IDB_AUDIOCODING                 104
+#define IDB_EMAIL                       106
+#define IDB_MPEG4IP                     107
+#define IDB_BITMAP1                     108
+#define IDB_BROWSE                      108
 #define IDC_RADIO_MPEG4                 1000
 #define IDC_RADIO_MPEG2                 1001
 #define IDC_RADIO_LOW                   1002
@@ -17,37 +16,58 @@
 #define IDC_RADIO_MAIN                  1003
 #define IDC_RADIO_SSR                   1004
 #define IDC_RADIO_LTP                   1005
-#define IDC_ALLOWMIDSIDE                1006
-#define IDC_CHK_ALLOWMIDSIDE            1006
-#define IDC_USETNS                      1007
-#define IDC_CHK_USETNS                  1007
-#define IDC_USELFE                      1008
-#define IDC_CHK_USELFE                  1008
-#define IDC_CB_BANDWIDTH                1009
-#define IDC_CB_BITRATE                  1010
-#define IDC_CHK_AUTOCFG                 1011
-#define IDC_E_BROWSE                    1012
-#define IDC_BTN_BROWSE                  1013
-#define IDC_IMG_LOGO                    1014
-#define IDC_RADIO_RAW                   1014
-#define IDC_BTN_ABOUT                   1015
+#define IDC_RADIO_RAW                   1006
+#define IDC_RADIO_HE                    1006
+#define IDC_RADIO_ADTS                  1007
+#define IDC_CB_BANDWIDTH                1008
+#define IDC_CB_BITRATE                  1009
+#define IDC_CHK_ALLOWMIDSIDE            1010
+#define IDC_CHK_USETNS                  1011
+#define IDC_CHK_USELFE                  1012
+#define IDC_CHK_AUTOCFG                 1013
+#define IDC_BTN_ABOUT                   1014
 #define IDC_L_ABOUT                     1015
-#define IDC_RADIO_ADTS                  1015
+#define IDC_BTN_ARTFILE                 1015
 #define IDC_AUDIOCODING                 1016
-#define IDC_CHK_WRITEMP4                1016
+#define IDC_CHK_USETNS2                 1016
+#define IDC_CHK_MP4                     1016
+#define WRITEMP4                        1016
 #define IDC_EMAIL                       1017
+#define IDC_E_BROWSE                    1017
 #define IDC_MPEG4IP                     1018
+#define IDC_BTN_BROWSE                  1018
+#define IDC_CHK_DEFAULTCFG              1019
+#define IDC_CB_SAMPLERATE               1020
 #define IDC_RADIO_BITRATE               1022
 #define IDC_RADIO_QUALITY               1023
 #define IDC_CB_QUALITY                  1024
+#define IDC_CHK_DOWNMATRIX              1025
+#define IDC_CHK_OLDADTS                 1026
+#define IDC_CHK_WRITEMP4                1027
+#define IDC_E_ARTIST                    1028
+#define IDC_CHK_TAG                     1029
+#define IDC_E_TITLE                     1030
+#define IDC_E_ALBUM                     1031
+#define IDC_E_YEAR                      1032
+#define IDC_CB_GENRE                    1033
+#define IDC_E_WRITER                    1034
+#define IDC_E_COMMENT                   1035
+#define IDC_E_TRACK                     1036
+#define IDC_E_NTRACKS                   1037
+#define IDC_E_DISK                      1038
+#define IDC_E_NDISKS                    1039
+#define IDC_GRP_TAG                     1040
+#define IDC_E_COMPILATION               1041
+#define IDC_E_ARTFILE                   1042
+#define IDC_BTN_LICENSE                 1043
 
 // Next default values for new objects
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        112
+#define _APS_NEXT_RESOURCE_VALUE        109
 #define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1017
+#define _APS_NEXT_CONTROL_VALUE         1044
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
--- a/plugins/winamp/ReadMe.txt
+++ b/plugins/winamp/ReadMe.txt
@@ -12,13 +12,14 @@
 
 ----------------------------------------------------------------------------
 
-out_AAC is an encoder plugin for Winamp 2 and 5.
+out_AAC is an encoder plugin for Winamp 2 and 5 to export .aac/.mp4 files.
 
 To use it:
 ----------
 
-In visual studio set "Active Configuration = out_FAAC - win32 Release" and compile then
-copy out_AAC.dll into Winamp\plugins folder.
+1) put FAAC and FAAD2 packages into the same folder;
+2) open the project, set "Active Configuration = FAAC - win32 Release" and compile;
+3) copy out_AAC.dll into Winamp\plugins folder.
 
 ----------------------------------------------------------------------------
 
--- a/plugins/winamp/defines.h
+++ b/plugins/winamp/defines.h
@@ -20,7 +20,7 @@
 */
 
 #define APP_NAME "MPEG4-AAC encoder"
-#define APP_VER "v1.3"
+#define APP_VER "v1.4"
 #define REGISTRY_PROGRAM_NAME "SOFTWARE\\4N\\Winamp\\Out_AAC"
 
 // -----------------------------------------------------------------------------------------------
--- a/plugins/winamp/out_FAAC.sln
+++ b/plugins/winamp/out_FAAC.sln
@@ -3,23 +3,66 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaac", "..\..\libfaac\libfaac.vcproj", "{27812E8E-D771-4C78-8675-FB67C3FF26FD}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmp4v2_st", "..\..\..\faad2\common\mp4v2\libmp4v2_st60.vcproj", "{76B4120C-00C0-4EAE-B2BA-BC930178A391}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\faad2\common\id3lib\zlib\prj\zlib.vcproj", "{873DE650-0D25-4EDA-846D-D36408A73E33}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "id3lib", "..\..\..\faad2\common\id3lib\libprj\id3lib.vcproj", "{016F36CD-410C-4B47-A527-AF82B848E1EB}"
+EndProject
 Global
 	GlobalSection(SolutionConfiguration) = preSolution
 		ConfigName.0 = Debug
-		ConfigName.1 = Release
+		ConfigName.1 = NASM Debug
+		ConfigName.2 = NASM Release
+		ConfigName.3 = Release
 	EndGlobalSection
 	GlobalSection(ProjectDependencies) = postSolution
-		{D5E38472-E616-414F-AE28-2138AAB73DA7}.0 = {27812E8E-D771-4C78-8675-FB67C3FF26FD}
+		{D5E38472-E616-414F-AE28-2138AAB73DA7}.0 = {76B4120C-00C0-4EAE-B2BA-BC930178A391}
+		{D5E38472-E616-414F-AE28-2138AAB73DA7}.1 = {27812E8E-D771-4C78-8675-FB67C3FF26FD}
+		{D5E38472-E616-414F-AE28-2138AAB73DA7}.2 = {873DE650-0D25-4EDA-846D-D36408A73E33}
+		{D5E38472-E616-414F-AE28-2138AAB73DA7}.3 = {016F36CD-410C-4B47-A527-AF82B848E1EB}
 	EndGlobalSection
 	GlobalSection(ProjectConfiguration) = postSolution
 		{D5E38472-E616-414F-AE28-2138AAB73DA7}.Debug.ActiveCfg = Debug|Win32
 		{D5E38472-E616-414F-AE28-2138AAB73DA7}.Debug.Build.0 = Debug|Win32
+		{D5E38472-E616-414F-AE28-2138AAB73DA7}.NASM Debug.ActiveCfg = Debug|Win32
+		{D5E38472-E616-414F-AE28-2138AAB73DA7}.NASM Debug.Build.0 = Debug|Win32
+		{D5E38472-E616-414F-AE28-2138AAB73DA7}.NASM Release.ActiveCfg = Release|Win32
+		{D5E38472-E616-414F-AE28-2138AAB73DA7}.NASM Release.Build.0 = Release|Win32
 		{D5E38472-E616-414F-AE28-2138AAB73DA7}.Release.ActiveCfg = Release|Win32
 		{D5E38472-E616-414F-AE28-2138AAB73DA7}.Release.Build.0 = Release|Win32
 		{27812E8E-D771-4C78-8675-FB67C3FF26FD}.Debug.ActiveCfg = Debug|Win32
 		{27812E8E-D771-4C78-8675-FB67C3FF26FD}.Debug.Build.0 = Debug|Win32
+		{27812E8E-D771-4C78-8675-FB67C3FF26FD}.NASM Debug.ActiveCfg = Debug|Win32
+		{27812E8E-D771-4C78-8675-FB67C3FF26FD}.NASM Debug.Build.0 = Debug|Win32
+		{27812E8E-D771-4C78-8675-FB67C3FF26FD}.NASM Release.ActiveCfg = Release|Win32
+		{27812E8E-D771-4C78-8675-FB67C3FF26FD}.NASM Release.Build.0 = Release|Win32
 		{27812E8E-D771-4C78-8675-FB67C3FF26FD}.Release.ActiveCfg = Release|Win32
 		{27812E8E-D771-4C78-8675-FB67C3FF26FD}.Release.Build.0 = Release|Win32
+		{76B4120C-00C0-4EAE-B2BA-BC930178A391}.Debug.ActiveCfg = Debug|Win32
+		{76B4120C-00C0-4EAE-B2BA-BC930178A391}.Debug.Build.0 = Debug|Win32
+		{76B4120C-00C0-4EAE-B2BA-BC930178A391}.NASM Debug.ActiveCfg = Debug|Win32
+		{76B4120C-00C0-4EAE-B2BA-BC930178A391}.NASM Debug.Build.0 = Debug|Win32
+		{76B4120C-00C0-4EAE-B2BA-BC930178A391}.NASM Release.ActiveCfg = Release|Win32
+		{76B4120C-00C0-4EAE-B2BA-BC930178A391}.NASM Release.Build.0 = Release|Win32
+		{76B4120C-00C0-4EAE-B2BA-BC930178A391}.Release.ActiveCfg = Release|Win32
+		{76B4120C-00C0-4EAE-B2BA-BC930178A391}.Release.Build.0 = Release|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.Debug.ActiveCfg = Debug|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.Debug.Build.0 = Debug|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.NASM Debug.ActiveCfg = NASM Debug|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.NASM Debug.Build.0 = NASM Debug|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.NASM Release.ActiveCfg = NASM Release|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.NASM Release.Build.0 = NASM Release|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.Release.ActiveCfg = Release|Win32
+		{873DE650-0D25-4EDA-846D-D36408A73E33}.Release.Build.0 = Release|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.Debug.ActiveCfg = Debug|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.Debug.Build.0 = Debug|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.NASM Debug.ActiveCfg = Debug|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.NASM Debug.Build.0 = Debug|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.NASM Release.ActiveCfg = Release|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.NASM Release.Build.0 = Release|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.Release.ActiveCfg = Release|Win32
+		{016F36CD-410C-4B47-A527-AF82B848E1EB}.Release.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 	EndGlobalSection
--- a/plugins/winamp/out_FAAC.vcproj
+++ b/plugins/winamp/out_FAAC.vcproj
@@ -20,11 +20,12 @@
 			CharacterSet="2">
 			<Tool
 				Name="VCCLCompilerTool"
+				AdditionalOptions=""
 				InlineFunctionExpansion="1"
 				AdditionalIncludeDirectories="..\..\include"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;OUT_FAAC_EXPORTS"
 				StringPooling="TRUE"
-				RuntimeLibrary="4"
+				RuntimeLibrary="2"
 				EnableFunctionLevelLinking="TRUE"
 				UsePrecompiledHeader="2"
 				PrecompiledHeaderFile=".\Release/Out_FAAC.pch"
@@ -75,14 +76,15 @@
 			ConfigurationType="2"
 			UseOfMFC="0"
 			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
+			CharacterSet="0">
 			<Tool
 				Name="VCCLCompilerTool"
+				AdditionalOptions=""
 				Optimization="0"
-				AdditionalIncludeDirectories="..\..\include"
-				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;OUT_FAAC_EXPORTS"
+				AdditionalIncludeDirectories="../../include,../../../faad2/include,../../../faad2/common/faad,../../../faad2/common/mp4v2,../../../faad2/common/id3lib/include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN"
 				BasicRuntimeChecks="3"
-				RuntimeLibrary="5"
+				RuntimeLibrary="3"
 				UsePrecompiledHeader="2"
 				PrecompiledHeaderFile=".\Debug/Out_FAAC.pch"
 				AssemblerListingLocation=".\Debug/"
@@ -96,9 +98,9 @@
 				Name="VCCustomBuildTool"/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib"
-				OutputFile="Debug/Out_AAC.dll"
+				AdditionalOptions="/MACHINE:I386 &quot;c:\CPP\faad2-2.0\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib&quot; &quot;c:\CPP\faad2-2.0\faac\libfaac\Debug\libfaac.lib&quot;"
+				AdditionalDependencies="ws2_32.lib odbc32.lib odbccp32.lib"
+				OutputFile="C:\Program Files\Audio\Gen\Winamp\Plugins\Out_AAC.dll"
 				LinkIncremental="2"
 				SuppressStartupBanner="TRUE"
 				ModuleDefinitionFile=".\Out_FAAC.def"
@@ -136,6 +138,9 @@
 				RelativePath=".\CRegistry.cpp">
 			</File>
 			<File
+				RelativePath="Cfaac.cpp">
+			</File>
+			<File
 				RelativePath=".\FAAC.rc">
 			</File>
 			<File
@@ -152,6 +157,9 @@
 				RelativePath=".\CRegistry.h">
 			</File>
 			<File
+				RelativePath="Cfaac.h">
+			</File>
+			<File
 				RelativePath=".\FILTERS.H">
 			</File>
 			<File
@@ -168,7 +176,16 @@
 			Name="Resource Files"
 			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
 			<File
+				RelativePath="AudioCoding.bmp">
+			</File>
+			<File
+				RelativePath="Email.bmp">
+			</File>
+			<File
 				RelativePath=".\Open.bmp">
+			</File>
+			<File
+				RelativePath="mpeg4ip-v.bmp">
 			</File>
 		</Filter>
 	</Files>