shithub: aacdec

Download patch

ref: 068acec8fe917fe572cbf11d0732bb0359be0321
parent: cdae0e79ef653b0166596891b9bb278cb5f1fdaa
author: menno <menno>
date: Sun Feb 9 13:55:19 EST 2003

Added plugin for Quintessential Player (QCD)

--- /dev/null
+++ b/plugins/QCD/QCDFAAD.c
@@ -1,0 +1,983 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**  
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+** 
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software 
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: QCDFAAD.c,v 1.1 2003/02/09 18:55:19 menno Exp $
+** based on menno's in_faad.dll plugin for Winamp
+**
+** The tag function has been removed because QCD supports ID3v1 & ID3v2 very well
+** About how to tagging: Please read the "ReadMe.txt" first
+**/
+
+#define WIN32_LEAN_AND_MEAN
+
+#include <windows.h>
+#include <mmreg.h>
+#include <commctrl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "QCDInputDLL.h"
+
+#include "resource.h"
+
+#include <faad.h>
+#include <aacinfo.h>
+#include <filestream.h>
+//#include <id3v2tag.h>
+
+static char app_name[] = "QCDFAAD";
+
+faadAACInfo file_info;
+
+faacDecHandle hDecoder;
+faacDecFrameInfo frameInfo;
+
+HINSTANCE		hInstance;
+HWND			hwndPlayer;
+QCDModInitIn	sQCDCallbacks, *QCDCallbacks;
+BOOL			oldAPIs = 0;
+static char	lastfn[MAX_PATH]; // currently playing file (used for getting info on the current file)
+int file_length; // file length, in bytes
+int paused; // are we paused?
+int seek_needed; // if != -1, it is the point that the decode thread should seek to, in ms.
+
+char *sample_buffer; // sample buffer
+unsigned char *buffer; // input buffer
+unsigned char *memmap_buffer; // input buffer for whole file
+long memmap_index;
+
+long buffercount, fileread, bytecount;
+
+// seek table for ADTS header files
+unsigned long *seek_table = NULL;
+int seek_table_length=0;
+
+int killPlayThread = 0; // the kill switch for the decode thread
+HANDLE play_thread_handle = INVALID_HANDLE_VALUE; // the handle to the decode thread
+FILE_STREAM *infile;
+
+/* Function definitions */
+int id3v2_tag(unsigned char *buffer);
+DWORD WINAPI PlayThread(void *b); // the decode thread procedure
+
+BOOL CALLBACK config_dialog_proc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK AboutProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);/* about dialogbox*/
+
+// general funcz
+static void show_error(const char *message,...)
+{
+	char foo[512];
+	va_list args;
+	va_start(args, message);
+	vsprintf(foo, message, args);
+	va_end(args);
+	MessageBox(hwndPlayer, foo, "FAAD Plug-in Error", MB_ICONSTOP);
+}
+
+
+// 1= use vbr display, 0 = use average bitrate. This value only controls what shows up in the
+// configuration form. Also- Streaming uses an on-the-fly bitrate display regardless of this value.
+long m_variable_bitrate_display=0;
+long m_priority = 5;
+long m_memmap_file = 0;
+static char INI_FILE[MAX_PATH];
+
+char *priority_text[] = {	"",
+							"Decode Thread Priority: Lowest",
+							"Decode Thread Priority: Lower",
+							"Decode Thread Priority: Normal",
+							"Decode Thread Priority: Higher",
+							"Decode Thread Priority: Highest (default)"
+						};
+
+long priority_table[] = {0, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST};
+
+long current_file_mode = 0;
+
+int PlayThread_memmap();
+int PlayThread_file();
+
+static void _r_s(char *name,char *data, int mlen)
+{
+	char buf[10];
+	strcpy(buf,data);
+	GetPrivateProfileString(app_name,name,buf,data,mlen,INI_FILE);
+}
+
+#define RS(x) (_r_s(#x,x,sizeof(x)))
+#define WS(x) (WritePrivateProfileString(app_name,#x,x,INI_FILE))
+
+void config_read()
+{
+    char variable_bitrate_display[10];
+    char priority[10];
+    char memmap_file[10];
+    char local_buffer_size[10];
+    char stream_buffer_size[10];
+
+    strcpy(variable_bitrate_display, "1");
+    strcpy(priority, "4");
+    strcpy(memmap_file, "0");
+    strcpy(local_buffer_size, "128");
+    strcpy(stream_buffer_size, "64");
+
+    RS(variable_bitrate_display);
+    RS(priority);
+    RS(memmap_file);
+    RS(local_buffer_size);
+    RS(stream_buffer_size);
+
+    m_priority = atoi(priority);
+    m_variable_bitrate_display = atoi(variable_bitrate_display);
+    m_memmap_file = atoi(memmap_file);
+    m_local_buffer_size = atoi(local_buffer_size);
+    m_stream_buffer_size = atoi(stream_buffer_size);
+}
+
+void config_write()
+{
+    char variable_bitrate_display[10];
+    char priority[10];
+    char memmap_file[10];
+    char local_buffer_size[10];
+    char stream_buffer_size[10];
+
+    itoa(m_priority, priority, 10);
+    itoa(m_variable_bitrate_display, variable_bitrate_display, 10);
+    itoa(m_memmap_file, memmap_file, 10);
+    itoa(m_local_buffer_size, local_buffer_size, 10);
+    itoa(m_stream_buffer_size, stream_buffer_size, 10);
+
+    WS(variable_bitrate_display);
+    WS(priority);
+    WS(memmap_file);
+    WS(local_buffer_size);
+    WS(stream_buffer_size);
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID pRes)
+{
+	if (fdwReason == DLL_PROCESS_ATTACH)
+		hInstance = hInst;
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+//old entrypoint api
+PLUGIN_API BOOL QInputModule(QCDModInitIn *ModInit, QCDModInfo *ModInfo)
+{
+	ModInit->version					= PLUGIN_API_VERSION;
+	ModInit->toModule.ShutDown			= ShutDown;
+	ModInit->toModule.GetTrackExtents	= GetTrackExtents;
+	ModInit->toModule.GetMediaSupported = GetMediaSupported;
+	ModInit->toModule.GetCurrentPosition= GetCurrentPosition;
+	ModInit->toModule.Play				= Play;
+	ModInit->toModule.Pause				= Pause;
+	ModInit->toModule.Stop				= Stop;
+	ModInit->toModule.SetVolume			= SetVolume;
+	ModInit->toModule.About				= About;
+	ModInit->toModule.Configure			= Configure;
+	QCDCallbacks = ModInit;
+
+	ModInfo->moduleString = "FAAD Plugin v1.0";
+	/* read config */
+	QCDCallbacks->Service(opGetPluginSettingsFile, INI_FILE, MAX_PATH, 0);
+
+	config_read();
+	ModInfo->moduleExtensions = "AAC";
+
+	hwndPlayer = (HWND)ModInit->Service(opGetParentWnd, 0, 0, 0);
+	lastfn[0] = 0;
+	play_thread_handle = INVALID_HANDLE_VALUE;
+
+	oldAPIs = 1;
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+
+PLUGIN_API QCDModInitIn* INPUTDLL_ENTRY_POINT()
+{
+	sQCDCallbacks.version						= PLUGIN_API_VERSION;
+	sQCDCallbacks.toModule.Initialize			= Initialize;
+	sQCDCallbacks.toModule.ShutDown				= ShutDown;
+	sQCDCallbacks.toModule.GetTrackExtents		= GetTrackExtents;
+	sQCDCallbacks.toModule.GetMediaSupported	= GetMediaSupported;
+	sQCDCallbacks.toModule.GetCurrentPosition	= GetCurrentPosition;
+	sQCDCallbacks.toModule.Play					= Play;
+	sQCDCallbacks.toModule.Pause				= Pause;
+	sQCDCallbacks.toModule.Stop					= Stop;
+	sQCDCallbacks.toModule.SetVolume			= SetVolume;
+	sQCDCallbacks.toModule.About				= About;
+	sQCDCallbacks.toModule.Configure			= Configure;
+
+	QCDCallbacks = &sQCDCallbacks;
+	return &sQCDCallbacks;
+}
+
+//----------------------------------------------------------------------------
+
+void Configure(int flags)
+{
+	HWND hwndConfig = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_CONFIG), hwndPlayer, config_dialog_proc);
+	if(hwndConfig)
+		ShowWindow(hwndConfig, SW_NORMAL);
+}
+
+BOOL CALLBACK config_dialog_proc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+	char tmp[10];
+
+    switch (message)
+	{
+    case WM_INITDIALOG:
+        /* Set priority slider range and previous position */
+		SendMessage(GetDlgItem(hwndDlg, THREAD_PRIORITY_SLIDER), TBM_SETRANGE, TRUE, MAKELONG(1, 5)); 
+		SendMessage(GetDlgItem(hwndDlg, THREAD_PRIORITY_SLIDER), TBM_SETPOS, TRUE, m_priority);
+		SetDlgItemText(hwndDlg, IDC_STATIC2, priority_text[m_priority]);
+		
+		/* Put a limit to the amount of characters allowed in the buffer boxes */
+		SendMessage(GetDlgItem(hwndDlg, LOCAL_BUFFER_TXT), EM_LIMITTEXT, 4, 0);
+		SendMessage(GetDlgItem(hwndDlg, STREAM_BUFFER_TXT), EM_LIMITTEXT, 4, 0);
+
+	    if(m_variable_bitrate_display)
+			SendMessage(GetDlgItem(hwndDlg, VARBITRATE_CHK), BM_SETCHECK, BST_CHECKED, 0);
+	    if(m_memmap_file)
+			SendMessage(GetDlgItem(hwndDlg, IDC_MEMMAP), BM_SETCHECK, BST_CHECKED, 0);
+
+		itoa(m_local_buffer_size, tmp, 10);
+		SetDlgItemText(hwndDlg, LOCAL_BUFFER_TXT, tmp);
+
+		itoa(m_stream_buffer_size, tmp, 10);
+		SetDlgItemText(hwndDlg, STREAM_BUFFER_TXT, tmp);
+
+		return TRUE;
+
+	case WM_HSCROLL:
+
+		/* Thread priority slider moved */
+		if(GetDlgItem(hwndDlg, THREAD_PRIORITY_SLIDER) == (HWND) lParam)
+		{
+			int tmp;
+			tmp = SendMessage(GetDlgItem(hwndDlg, THREAD_PRIORITY_SLIDER), TBM_GETPOS, 0, 0);
+
+			if(tmp > 0)
+			{
+				m_priority = tmp;
+
+                SetDlgItemText(hwndDlg, IDC_STATIC2, priority_text[m_priority]);
+
+				if(play_thread_handle)
+					SetThreadPriority(play_thread_handle, priority_table[m_priority]);
+			}
+		}
+
+		return TRUE;
+
+    case WM_COMMAND:
+
+		if(HIWORD(wParam) == BN_CLICKED)
+		{
+			if(GetDlgItem(hwndDlg, VARBITRATE_CHK) == (HWND) lParam)
+			{
+				/* Variable Bitrate checkbox hit */
+				m_variable_bitrate_display = SendMessage(GetDlgItem(hwndDlg, VARBITRATE_CHK), BM_GETCHECK, 0, 0); 
+			}
+			if(GetDlgItem(hwndDlg, IDC_MEMMAP) == (HWND) lParam)
+			{
+				/* Variable Bitrate checkbox hit */
+				m_memmap_file = SendMessage(GetDlgItem(hwndDlg, IDC_MEMMAP), BM_GETCHECK, 0, 0); 
+			}
+		}
+
+        switch (LOWORD(wParam))
+		{
+			case OK_BTN:
+				/* User hit OK, save buffer settings (all others are set on command) */
+				GetDlgItemText(hwndDlg, LOCAL_BUFFER_TXT, tmp, 5);
+				m_local_buffer_size = atol(tmp);
+
+				GetDlgItemText(hwndDlg, STREAM_BUFFER_TXT, tmp, 5);
+				m_stream_buffer_size = atol(tmp);
+
+                config_write();
+
+				EndDialog(hwndDlg, wParam);
+				return TRUE;
+			case RESET_BTN:
+				SendMessage(GetDlgItem(hwndDlg, VARBITRATE_CHK), BM_SETCHECK, BST_CHECKED, 0);
+				m_variable_bitrate_display = 1;
+				SendMessage(GetDlgItem(hwndDlg, IDC_MEMMAP), BM_SETCHECK, BST_UNCHECKED, 0);
+				m_memmap_file = 0;
+				SendMessage(GetDlgItem(hwndDlg, THREAD_PRIORITY_SLIDER), TBM_SETPOS, TRUE, 5);
+				m_priority = 5;
+				SetDlgItemText(hwndDlg, IDC_STATIC2, priority_text[5]);
+				SetDlgItemText(hwndDlg, LOCAL_BUFFER_TXT, "128");
+				m_local_buffer_size = 128;
+				SetDlgItemText(hwndDlg, STREAM_BUFFER_TXT, "64");
+				m_stream_buffer_size = 64;
+				return TRUE;
+			case IDCANCEL:
+			case CANCEL_BTN:
+				/* User hit Cancel or the X, just close without saving buffer settings */
+				DestroyWindow(hwndDlg);
+				return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+
+void About(int flags)
+{
+	HWND hwndAbout = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_ABOUT), hwndPlayer, AboutProc); 
+	if(hwndAbout)
+		ShowWindow(hwndAbout, SW_NORMAL);
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL Initialize(QCDModInfo *ModInfo, int flags)
+{
+	hwndPlayer = (HWND)QCDCallbacks->Service(opGetParentWnd, 0, 0, 0);
+
+	lastfn[0] = 0;
+	seek_needed = -1;
+	paused = 0;
+	play_thread_handle = INVALID_HANDLE_VALUE;
+
+	/* read config */
+	QCDCallbacks->Service(opGetPluginSettingsFile, INI_FILE, MAX_PATH, 0);
+    config_read();
+
+	ModInfo->moduleString = "FAAD Plugin v1.0";
+	ModInfo->moduleExtensions = "AAC";
+
+    /* Initialize winsock, necessary for streaming */
+    WinsockInit();
+
+	// insert menu item into plugin menu
+	QCDCallbacks->Service(opSetPluginMenuItem, hInstance, IDD_CONFIG, (long)"FAAD Plug-in");
+
+	return TRUE;
+}
+
+//----------------------------------------------------------------------------
+
+void ShutDown(int flags)
+{
+	Stop(lastfn, STOPFLAG_FORCESTOP);
+
+    if(buffer)
+		LocalFree(buffer);
+
+    /* Deallocate winsock */
+    WinsockDeInit();
+
+	if(seek_table)
+	{
+		free(seek_table);
+		seek_table = NULL;
+		seek_table_length = 0;
+	}
+
+	// delete the inserted plugin menu
+	QCDCallbacks->Service(opSetPluginMenuItem, hInstance, 0, 0);
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL GetMediaSupported(LPCSTR medianame, MediaInfo *mediaInfo)
+{
+	FILE_STREAM *in;
+	faadAACInfo tmp;
+	char *ch = strrchr(medianame, '.');
+
+	if (!medianame || !*medianame)
+		return FALSE;
+
+	if(!ch)
+		return (lstrlen(medianame) > 2); // no extension defaults to me (if not drive letter)
+
+   /* Finally fixed */
+    if(StringComp(ch, ".aac", 4) == 0)
+    {
+		in = open_filestream((char *)medianame);
+		
+		if(in != NULL && mediaInfo)
+		{
+			if(in->http)
+			{
+				/* No seeking in http streams */
+				mediaInfo->mediaType = DIGITAL_STREAM_MEDIA;
+				mediaInfo->op_canSeek = FALSE;
+			}
+			else
+			{
+				mediaInfo->mediaType = DIGITAL_FILE_MEDIA;
+			    get_AAC_format((char *)medianame, &tmp, NULL, NULL, 1);
+				if(tmp.headertype == 2) /* ADTS header - seekable */
+					mediaInfo->op_canSeek = TRUE;
+				else
+					mediaInfo->op_canSeek = FALSE; /* ADIF or Headerless - not seekable */
+			}
+			
+			close_filestream(in);
+			return TRUE;
+		}
+		else
+		{
+			close_filestream(in);
+			return FALSE;
+		}
+	}
+	else
+		return FALSE;		
+}
+
+unsigned long samplerate, channels;
+
+int play_memmap(char *fn)
+{
+    int tagsize = 0;
+
+    infile = open_filestream(fn);
+    
+	if (infile == NULL)
+        return 1;
+
+    fileread = filelength_filestream(infile);
+
+    memmap_buffer = (char*)LocalAlloc(LPTR, fileread);
+    read_buffer_filestream(infile, memmap_buffer, fileread);
+
+    /* skip id3v2 tag */
+    memmap_index = id3v2_tag(memmap_buffer);
+
+    hDecoder = faacDecOpen();
+
+	/* Copy the configuration dialog setting and use it as the default */
+	/* initialize the decoder, and get samplerate and channel info */
+
+    if( (buffercount = faacDecInit(hDecoder, memmap_buffer + memmap_index,
+        fileread - memmap_index - 1, &samplerate, &channels)) < 0 )
+    {
+		show_error("Error opening input file");
+		return 1;
+    }
+
+    memmap_index += buffercount;
+
+    PlayThread_memmap();
+
+    return 0;
+}
+
+int play_file(char *fn)
+{
+    int k;
+    int tagsize;
+
+    ZeroMemory(buffer, 768*2);
+
+     infile = open_filestream(fn);
+    
+	if (infile == NULL)
+        return 1;
+
+	fileread = filelength_filestream(infile);
+
+    buffercount = bytecount = 0;
+    read_buffer_filestream(infile, buffer, 768*2);
+
+    tagsize = id3v2_tag(buffer);
+
+	/* If we find a tag, run right over it */
+    if(tagsize)
+	{
+        if(infile->http)
+        {
+            int i;
+            /* Crude way of doing this, but I believe its fast enough to not make a big difference */
+            close_filestream(infile);
+            infile = open_filestream(fn);
+
+            for(i=0; i < tagsize; i++)
+                read_byte_filestream(infile);
+        }
+        else
+            seek_filestream(infile, tagsize, FILE_BEGIN);
+
+        bytecount = tagsize;
+        buffercount = 0;
+        read_buffer_filestream(infile, buffer, 768*2);
+    }
+
+    hDecoder = faacDecOpen();
+
+	/* Copy the configuration dialog setting and use it as the default */
+	/* initialize the decoder, and get samplerate and channel info */
+
+    if((buffercount = faacDecInit(hDecoder, buffer, 768*2, &samplerate, &channels)) < 0)
+    {
+		show_error("Error opening input file");
+		return 1;
+    }
+
+    if(buffercount > 0)
+	{
+		bytecount += buffercount;
+
+		for (k = 0; k < (768*2 - buffercount); k++)
+			buffer[k] = buffer[k + buffercount];
+
+		read_buffer_filestream(infile, buffer + (768*2) - buffercount, buffercount);
+		buffercount = 0;
+	}
+
+    PlayThread_file();
+
+    return 0;
+}
+
+
+//-----------------------------------------------------------------------------
+
+BOOL Play(LPCSTR medianame, int playfrom, int playto, int flags)
+{
+	if(stricmp(lastfn, medianame) != 0)
+	{
+		sQCDCallbacks.toPlayer.OutputStop(STOPFLAG_PLAYDONE);
+		Stop(lastfn, STOPFLAG_PLAYDONE);
+	}
+
+	if(paused)
+	{
+		// Update the player controls to reflect the new unpaused state
+		sQCDCallbacks.toPlayer.OutputPause(0);
+
+		Pause(medianame, PAUSE_DISABLED);
+
+		if (playfrom >= 0)
+			seek_needed = playfrom;
+	}
+	else if(play_thread_handle != INVALID_HANDLE_VALUE)
+	{
+		seek_needed = playfrom;
+		return TRUE;
+	}
+	else
+	{
+		int thread_id;
+
+		// alloc the input buffer
+		buffer = (unsigned char*)LocalAlloc(LPTR, 768*2);
+
+		current_file_mode = m_memmap_file;
+		
+		if(current_file_mode)
+		{
+			if(play_memmap((char *)medianame))
+				return FALSE;
+		}
+		else
+		{
+			if(play_file((char *)medianame))
+				return FALSE;
+		}
+		
+		if(seek_table)
+		{
+			free(seek_table);
+			seek_table = NULL;
+			seek_table_length = 0;
+		}
+		
+		get_AAC_format((char *)medianame, &file_info, &seek_table, &seek_table_length, 0);
+		
+		strcpy(lastfn,medianame);
+		paused = 0;
+		seek_needed = -1;
+		killPlayThread = 0;
+
+		/*
+		To RageAmp: This is really needed, because aacinfo isn't very accurate on ADIF files yet.
+		Can be fixed though :-)
+		*/
+		file_info.sampling_rate = samplerate;
+		file_info.channels = frameInfo.channels;
+
+		// show constant bitrate at first
+		{
+			AudioInfo cai;
+			cai.struct_size = sizeof(AudioInfo);
+			cai.frequency = file_info.sampling_rate;
+			cai.bitrate = file_info.bitrate;
+			cai.mode = (channels == 2) ? 0 : 3;
+			cai.layer = 0;
+			cai.level = 0;
+			QCDCallbacks->Service(opSetAudioInfo, &cai, sizeof(AudioInfo), 0);
+		}
+
+		play_thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) PlayThread, (void *) &killPlayThread, 0, &thread_id);
+		if(!play_thread_handle)
+			return FALSE;
+		
+		// Note: This line seriously slows down start up time
+		if(m_priority != 3) // if the priority in config window is set to normal, there is nothing to reset!
+			SetThreadPriority(play_thread_handle, priority_table[m_priority]);
+		
+    }
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL Pause(LPCSTR medianame, int flags)
+{
+	if(QCDCallbacks->toPlayer.OutputPause(flags))
+	{
+		// send back pause/unpause notification
+		QCDCallbacks->toPlayer.PlayPaused(medianame, flags);
+		paused = flags;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL Stop(LPCSTR medianame, int flags)
+{
+	if(medianame && *medianame && stricmp(lastfn, medianame) == 0)
+	{
+		sQCDCallbacks.toPlayer.OutputStop(flags);
+		
+		killPlayThread = 1;
+		if (WaitForSingleObject(play_thread_handle, INFINITE) == WAIT_TIMEOUT)
+            TerminateThread(play_thread_handle,0);
+        CloseHandle(play_thread_handle);
+        play_thread_handle = INVALID_HANDLE_VALUE;
+		
+		if (oldAPIs)
+			QCDCallbacks->toPlayer.PlayStopped(lastfn);
+		
+		lastfn[0] = 0;
+		faacDecClose(hDecoder);
+		close_filestream(infile);
+		
+		if (memmap_buffer)
+			LocalFree(memmap_buffer);
+		if(seek_table)
+		{
+			free(seek_table);
+			seek_table = NULL;
+			seek_table_length = 0;
+		}
+	}
+	return TRUE;
+}
+
+int aac_seek(int pos_ms, int *sktable)
+{
+    double offset_sec;
+
+    offset_sec = pos_ms / 1000.0;
+    if(!current_file_mode)
+    {
+        seek_filestream(infile, sktable[(int)(offset_sec+0.5)], FILE_BEGIN);
+
+        bytecount = sktable[(int)(offset_sec+0.5)];
+        buffercount = 0;
+        read_buffer_filestream(infile, buffer, 768*2);
+    }
+	else
+	{
+        memmap_index = sktable[(int)(offset_sec+0.5)];
+    }
+
+    return 0;
+}
+
+//-----------------------------------------------------------------------------
+
+void SetVolume(int levelleft, int levelright, int flags)
+{
+	QCDCallbacks->toPlayer.OutputSetVol(levelleft, levelright, flags);
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL GetCurrentPosition(LPCSTR medianame, long *track, long *offset)
+{
+	return QCDCallbacks->toPlayer.OutputGetCurrentPosition((UINT*)offset, 0);
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL GetTrackExtents(LPCSTR medianame, TrackExtents *ext, int flags)
+{
+    faadAACInfo tmp;
+
+    if(get_AAC_format((char*)medianame, &tmp, NULL, NULL, 1))
+		return FALSE;
+
+	ext->track = 1;
+	ext->start = 0;
+	ext->end = tmp.length;
+	ext->bytesize = tmp.bitrate * tmp.length;
+	ext->unitpersec = 1000;
+
+	return TRUE;
+}
+
+//--------------------------for play thread-------------------------------------
+
+int last_frame;
+
+DWORD WINAPI PlayThread(void *b)
+{
+    BOOL done = FALSE, updatePos = FALSE;
+	int decode_pos_ms = 0; // current decoding position, in milliseconds
+    int l;
+	int decoded_frames=0;
+	int br_calc_frames=0;
+	int br_bytes_consumed=0;
+    unsigned long bytesconsumed;
+
+    last_frame = 0;
+
+	if(!done)
+	{
+		// open outputdevice
+		WAVEFORMATEX wf;
+		wf.wFormatTag = WAVE_FORMAT_PCM;
+		wf.cbSize = 0;
+		wf.nChannels = file_info.channels;
+		wf.wBitsPerSample = 16;
+		wf.nSamplesPerSec = file_info.sampling_rate;
+		wf.nBlockAlign = wf.nChannels * wf.wBitsPerSample / 8;
+		wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;
+		if (!QCDCallbacks->toPlayer.OutputOpen(lastfn, &wf))
+		{
+			show_error("Error: Failed openning output plugin!");
+			done = TRUE; // cannot open sound device
+		}
+	}
+
+    while (! *((int *)b) )
+    {
+ 		/********************** SEEK ************************/
+       if (!done && seek_needed >= 0)
+        {
+            int seconds;
+
+			QCDCallbacks->toPlayer.OutputFlush(0);
+            // Round off to a second
+            seconds = seek_needed - (seek_needed%1000);
+            aac_seek(seconds, seek_table);
+            decode_pos_ms = seconds;
+			decoded_frames = 0;
+			br_calc_frames = 0;
+			br_bytes_consumed = 0;
+
+			seek_needed = -1;
+ 			done = FALSE;
+			updatePos = 1;
+       }
+
+		/********************* QUIT *************************/
+		if (done)
+		{
+			if (QCDCallbacks->toPlayer.OutputDrain(0) && !(seek_needed >= 0))
+			{
+				QCDCallbacks->toPlayer.OutputStop(STOPFLAG_PLAYDONE);
+				QCDCallbacks->toPlayer.PlayDone(lastfn);
+			}
+			else if (seek_needed >= 0)
+			{
+				done = FALSE;
+				continue;
+			}
+			break;
+		}
+
+        /******************* DECODE TO BUFFER ****************/
+		else
+        {
+            if(last_frame)
+            {
+                done=1;
+            }
+            else
+            {
+                if (current_file_mode)
+                    bytesconsumed = PlayThread_memmap();
+                else
+					bytesconsumed = PlayThread_file();
+
+				decoded_frames++;
+				br_calc_frames++;
+				br_bytes_consumed += bytesconsumed;
+
+				/* Update the variable bitrate about every second */
+				if(m_variable_bitrate_display && br_calc_frames == 43)
+				{
+					AudioInfo vai;
+					vai.struct_size = sizeof(AudioInfo);
+					vai.frequency = file_info.sampling_rate;
+					vai.bitrate = (int)((br_bytes_consumed * 8) / (decoded_frames / 43.07));
+					vai.mode = (channels == 2) ? 0 : 3;
+					vai.layer = 0;
+					vai.level = 0;
+					QCDCallbacks->Service(opSetAudioInfo, &vai, sizeof(AudioInfo), 0);
+
+					br_calc_frames = 0;
+				}
+
+                if (!killPlayThread && (frameInfo.samples > 0))
+                {
+                    //update the time display
+					if (updatePos)
+					{
+						QCDCallbacks->toPlayer.PositionUpdate(decode_pos_ms);
+						updatePos = 0;
+					}
+					
+					{
+						WriteDataStruct wd;
+
+						decode_pos_ms += (1024*1000)/file_info.sampling_rate;
+						
+						l = frameInfo.samples * sizeof(short);
+
+						wd.bytelen = l;
+						wd.data = sample_buffer;
+						wd.markerend = 0;
+						wd.markerstart = decode_pos_ms;
+						wd.bps = 16/*file_info.bitrate / frameInfo.samplerate*/;
+						wd.nch = frameInfo.channels;
+						wd.numsamples = frameInfo.samples/*wd.bytelen / (wd.bps / 8) / wd.nch*/;
+						wd.srate = file_info.sampling_rate;
+						
+						if (!QCDCallbacks->toPlayer.OutputWrite(&wd))
+							done = TRUE;
+					}
+                }
+            }
+        }
+        Sleep(10);
+    }
+	
+	if(seek_table)
+	{
+		free(seek_table);
+		seek_table = NULL;
+		seek_table_length = 0;
+	}
+    
+    return 0;
+}
+
+// thread play funcs
+int PlayThread_memmap()
+{
+    sample_buffer = (char*)faacDecDecode(hDecoder, &frameInfo,
+        memmap_buffer + memmap_index, fileread - memmap_index - 1);
+    if (frameInfo.error)
+    {
+        show_error(faacDecGetErrorMessage(frameInfo.error));
+        last_frame = 1;
+    }
+
+    memmap_index += frameInfo.bytesconsumed;
+    if (memmap_index >= fileread)
+        last_frame = 1;
+
+    return frameInfo.bytesconsumed;
+}
+
+int PlayThread_file()
+{
+    int k;
+
+    if (buffercount > 0) {
+        for (k = 0; k < (768*2 - buffercount); k++)
+            buffer[k] = buffer[k + buffercount];
+
+        read_buffer_filestream(infile, buffer + (768*2) - buffercount, buffercount);
+        buffercount = 0;
+    }
+
+    sample_buffer = (char*)faacDecDecode(hDecoder, &frameInfo, buffer, 768*2);
+    if (frameInfo.error)
+    {
+        show_error(faacDecGetErrorMessage(frameInfo.error));
+        last_frame = 1;
+    }
+
+    buffercount += frameInfo.bytesconsumed;
+
+    bytecount += frameInfo.bytesconsumed;
+    if (bytecount >= fileread)
+        last_frame = 1;
+
+    return frameInfo.bytesconsumed;
+}
+
+
+// proc of "About Dialog"
+INT_PTR CALLBACK AboutProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+	switch (uMsg)
+	{
+	case WM_COMMAND:
+		switch(LOWORD(wParam))
+		{
+		case IDOK:
+			DestroyWindow(hwndDlg);
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+// tag
+int id3v2_tag(unsigned char *buffer)
+{
+    if (StringComp(buffer, "ID3", 3) == 0)
+	{
+        unsigned long tagsize;
+
+        /* high bit is not used */
+        tagsize = (buffer[6] << 21) | (buffer[7] << 14) |
+            (buffer[8] <<  7) | (buffer[9] <<  0);
+
+        tagsize += 10;
+
+        return tagsize;
+    }
+	else
+	{
+        return 0;
+    }
+}
\ No newline at end of file
--- /dev/null
+++ b/plugins/QCD/QCDFAAD.dsp
@@ -1,0 +1,143 @@
+# Microsoft Developer Studio Project File - Name="QCDFAAD" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=QCDFAAD - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "QCDFAAD.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "QCDFAAD.mak" CFG="QCDFAAD - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "QCDFAAD - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "QCDFAAD - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "QCDFAAD - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /I "..\..\common\faad" /I "..\..\plugins\winamp" /I "..\..\common\id3lib\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ID3LIB_COMPILATION" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x413 /d "NDEBUG"
+# ADD RSC /l 0x413 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+
+!ELSEIF  "$(CFG)" == "QCDFAAD - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "..\..\common\faad" /I "..\..\plugins\winamp" /I "..\..\common\id3lib\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ID3LIB_COMPILATION" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x413 /d "_DEBUG"
+# ADD RSC /l 0x413 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "QCDFAAD - Win32 Release"
+# Name "QCDFAAD - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\common\faad\aacinfo.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\common\faad\filestream.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\QCDFAAD.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\common\faad\aacinfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\faad.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\common\faad\filestream.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\QCDInputDLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\QCDModDefs.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\QCDModInput.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\plugin_dlg.rc
+# End Source File
+# End Group
+# End Target
+# End Project
--- /dev/null
+++ b/plugins/QCD/QCDFAAD.dsw
@@ -1,0 +1,44 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "QCDFAAD"=".\QCDFAAD.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name libfaad
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "libfaad"="..\..\libfaad\libfaad.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null
+++ b/plugins/QCD/QCDInputDLL.h
@@ -1,0 +1,50 @@
+//-----------------------------------------------------------------------------
+// 
+// File:	QCDInputDLL.h
+//
+// About:	QCD Player Input module DLL interface.  For more documentation, see
+//			QCDModInput.h.
+//
+// Authors:	Written by Paul Quinn and Richard Carlson.
+//
+//	QCD multimedia player application Software Development Kit Release 1.0.
+//
+//	Copyright (C) 1997-2002 Quinnware
+//
+//	This code is free.  If you redistribute it in any form, leave this notice 
+//	here.
+//
+//	This program is distributed in the hope that it will be useful,
+//	but WITHOUT ANY WARRANTY; without even the implied warranty of
+//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef QCDInputDLL_H
+#define QCDInputDLL_H
+
+#include "QCDModInput.h"
+
+extern HINSTANCE		hInstance;
+extern HWND				hwndPlayer;
+extern QCDModInitIn		sQCDCallbacks, *QCDCallbacks;
+
+// Calls from the Player
+int  GetMediaSupported(const char* medianame, MediaInfo *mediaInfo);
+int  GetTrackExtents(const char* medianame, TrackExtents *ext, int flags);
+int  GetCurrentPosition(const char* medianame, long *track, long *offset);
+
+void SetEQ(EQInfo*);
+void SetVolume(int levelleft, int levelright, int flags);
+
+int  Play(const char* medianame, int framefrom, int frameto, int flags);
+int  Pause(const char* medianame, int flags);
+int  Stop(const char* medianame, int flags);
+int  Eject(const char* medianame, int flags);
+
+int  Initialize(QCDModInfo *ModInfo, int flags);
+void ShutDown(int flags);
+void Configure(int flags);
+void About(int flags);
+
+#endif //QCDInputDLL_H
\ No newline at end of file
--- /dev/null
+++ b/plugins/QCD/QCDModDefs.h
@@ -1,0 +1,340 @@
+//-----------------------------------------------------------------------------
+//
+// File:	QCDModDefs.h
+//
+// About:	Module definitions file.  Miscellanious definitions used by different
+//			module types.  This file is published with the plugin SDKs.
+//
+// Authors:	Written by Paul Quinn and Richard Carlson.
+//
+// Copyright:
+//
+//	QCD multimedia player application Software Development Kit Release 1.0.
+//
+//	Copyright (C) 1997-2002 Quinnware
+//
+//	This code is free.  If you redistribute it in any form, leave this notice 
+//	here.
+//
+//	This program is distributed in the hope that it will be useful,
+//	but WITHOUT ANY WARRANTY; without even the implied warranty of
+//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef QCDMODDEFS_H
+#define QCDMODDEFS_H
+
+#include <windows.h>
+
+#ifdef __cplusplus
+#define PLUGIN_API extern "C" __declspec(dllexport)
+#else
+#define PLUGIN_API __declspec(dllexport)
+#endif
+
+// Current plugin version
+#define PLUGIN_API_VERSION 250
+
+//-----------------------------------------------------------------------------
+
+typedef struct {
+	char				*moduleString;
+	char				*moduleExtensions;
+
+} QCDModInfo;
+
+//-----------------------------------------------------------------------------
+// Services (ops) provided by the Player
+//-----------------------------------------------------------------------------
+typedef enum 
+{									//*** below returns numeric info (*buffer not used)
+
+	opGetPlayerVersion = 0,			// high-order word = major version (eg 3.01 is 3), low-order word = minor (eg 3.01 = 1)
+	opGetParentWnd = 1,				// handle to player window
+	opGetPlayerInstance = 2,		// HINSTANCE to player executable
+
+	opGetPlayerState = 9,			// get current state of the player (returns: 1 = stopped, 2 = playing, 3 = paused, 0 = failed)
+	opGetNumTracks = 10,			// number of tracks in playlist
+	opGetCurrentIndex = 11,			// index of current track in playlist (0 based)
+	opGetNextIndex = 12,			// get index of next track to play (0 based), param1 = index start index. -1 for after current
+	opGetTrackNum = 13,				// get track number of index, param1 = index of track in playlist, -1 for current
+									//		- 'track number' is the number of the track in it's respective album, as opposed to playlist number
+									//		- the 'track number' for digital files will be 1, unless they are tagged with the CDDB identifier
+
+	opGetTrackLength = 14,			// get track length, param1 = index of track in playlist, -1 for current
+									//                   param2 = 0 for seconds, 1 for milliseconds
+	opGetTime = 15,					// get time on player, param1 = 0 for time displayed, 1 for track time, 2 for playlist time
+									//					   param2 = 0 for elapsed, 1 for remaining														   
+	opGetTrackState = 16,			// get whether track is marked, param1 = index of track, -1 for current
+	opGetPlaylistNum = 17,			// get playlist number of index, param1 = index of track in playlist, -1 for current
+	opGetMediaType = 18,			// get media type of track, param1 = index if track in playlist, -1 for current
+									//		- see MediaTypes below for return values
+
+	opGetAudioInfo = 19,			// get format info about currently playing track
+									//		- param1 = 0 for samplerate, 1 for bitrate, 2 for num channels
+
+	opGetOffline = 20,				// true if client is in Offline Mode
+	opGetVisTarget = 21,			// where is vis being drawn > 0 - internal to skin, 1 - external window, 2 - full screen
+	opGetAlwaysOnTop = 22,			// true if player is set to 'Always on Top'
+	opGetRepeatState = 23,			// returns: 0 - repeat off, 1 - repeat track, 2 - repeat all
+	opGetShuffleState = 27,			// returns: 0 - shuffle off, 1 - shuffle enabled
+
+	opGetTimerState = 24,			// low-order word: 0 - track ascend, 1 - playlist ascend, 2 - track descend, 3 - playlist descend
+									// hi-order word: 1 if 'show hours' is set, else 0
+
+	opGetVolume = 25,				// get master volume level (0 - 100), param1: 0 = combined, 1 = left, 2 = right
+	opSetVolume = 26,				// set master volume level, param1: vol level 0 - 100, param2: balance (-100 left, 0 center, 100 right)
+
+	opGetIndexFromPLNum = 28,		// get index from playlist number, param1 = playlist number
+
+	opGetChildWnd = 30,				// handle to the draggable window extension (only available on some skins) 
+	opGetExtVisWnd = 31,			// handle to the external visual window
+	opGetMusicBrowserWnd = 32,		// handle to the music browser window 
+	opGetSkinPreviewWnd = 33,		// handle to the skin preview window 
+	opGetPropertiesWnd = 34,		// handle to the player properties window 
+	opGetExtInfoWnd = 35,			// handle to the extended information window 
+	opGetAboutWnd = 36,				// handle to the about window 
+	opGetSegmentsWnd = 37,			// handle to the segments window 
+	opGetEQPresetsWnd = 38,			// handle to the EQ presets window 
+
+	opGetVisDimensions = 50,		// gets the width and height of visual window (param1 = -1 current vis window, 0 internal vis, 1 external vis, 2 full screen)
+									//		returns: HEIGHT in high word, WIDTH in low word 
+
+	opGetQueriesComplete = 60,		// get status on whether all tracks in playlist have been queryied for their info
+
+									// playlist manipulation
+	opDeleteIndex = 90,				// delete index from playlist (param1 = index)
+	opSelectIndex = 91,				// mark index as selected (param1 = index, param2 = 1 - set, 0 - unset)
+	opBlockIndex = 92,				// mark index as blocked (param1 = index, param2 = 1 - set, 0 - unset)
+
+	opGetMediaInfo = 99,			// get the CddbDisc object for the index specified, param1 = index of track, -1 for current
+									//		param2 = pointer to integer that receives track value
+									//		returns: pointer to CddbDisc object. Do not release or deallocate this pointer
+
+
+   									//*** below returns string info in buffer, param1 = size of buffer
+   									//*** returns 1 on success, 0 on failure
+
+	opGetTrackName = 100,			// get track name, param2 = index of track in playlist, -1 for current
+	opGetArtistName = 101,			// get artist name, param2 = index of track in playlist, -1 for current
+	opGetDiscName = 102,			// get disc name, param2 = index of track in playlist, -1 for current
+
+	opGetTrackFile = 103,			// file name of track in playlist, param2 = index of track in playlist, -1 for current
+	opGetSkinName = 104,			// get current skin name
+
+	opGetPluginFolder = 105,		// get current plugin folder
+	opGetPluginSettingsFile = 106,	// get settings file (plugins.ini) that plugin should save settings to
+	opGetPluginCacheFile = 107,		// get file that describes plugin validity, functions and names
+	opGetPlayerSettingsFile = 108,	// get settings file (qcd.ini) that player saves it settings to (should use for read-only)
+
+	opGetMusicFolder = 110,			// get current music folder
+	opGetPlaylistFolder = 111,		// get current playlist folder
+	opGetSkinFolder = 112,			// get current skin folder
+	opGetCDDBCacheFolder = 113,		// get current folder for CDDB cached info
+
+	opGetCurrentPlaylist = 114,		// get full pathname of playlist currently loaded 
+
+	opGetMediaID = 115,				// get media identifier, param2 = index of track in playlist, -1 for current
+									//		- for CD's it's the TOC - for anything else, right now it's 0      
+
+	opGetSupportedExtensions = 116,	// get file extensions supported by the player, param2 = 0 - get all extensions, 1 - get registered extensions
+									//		- returned extensions will be colon delimited
+
+
+   									//*** below buffer points to struct or other object
+   									//*** returns 1 on success, 0 on failure
+
+	opShowMainMenu = 120,			// Display Main QCD Menu (buffer = POINT* - location to display menu)
+	opGetMainMenu = 121,			// Returns copy of HMENU handle to QCD Menu (must use DestroyMenu on handle when complete)
+
+	opShowQuickTrack = 125,			// Display QuickTrack Menu (buffer = POINT* - location to display menu)
+
+	opGetEQVals = 200,				// get current EQ levels/on/off (buffer = EQInfo*)
+	opSetEQVals = 201,				// set EQ levels/on/off (buffer = EQInfo*)
+
+	opGetProxyInfo = 202,			// get proxy info (buffer = ProxyInfo*), returns 0 if proxy not in use
+
+
+									//*** below returns numeric info, buffer used
+
+	opGetIndexFromFilename = 210,	// get the index of a file that exists in current playlist (buffer = full path of file),
+									//		param1 = startindex (index to start searching on)
+                                    //		returns -1 if file not in playlist
+
+
+									//*** below send information to player
+									//*** returns 1 on success, 0 on failure
+
+	opSetStatusMessage = 1000,		// display message in status area (buffer = msg buffer (null term), param1 = text flags (see below))
+
+	opSetBrowserUrl = 1001,			// set music browser URL (buffer = url (null term))
+	                                //		null url buffer - closes browser
+	                                //		param1 = 0 - normal, 1 - force open
+
+	opSetAudioInfo = 1002,			// set the current music bitrate/khz (buffer = AudioInfo*, param1 = size of AudioInfo)
+
+	opSetTrackAlbum = 1003,			// update track ablum name (buffer = album (null term), param1 = (string ptr)file name), param2 = MediaTypes
+	opSetTrackTitle = 1004,			// update track title (buffer = title (null term), param1 = (string ptr)file name), param2 = MediaTypes
+	opSetTrackArtist = 1005,		// update track artist name (buffer = artist (null term), param1 = (string ptr)file name), param2 = MediaTypes
+
+	opSetPlaylist = 1006,			// add files to or reset playlist with new files (buffer = file list (null term), param1 = (string ptr)originating path (can be NULL), param2 = 1 - clear playlist flag, 2 - enqueue to top
+
+	opSetTrackExtents = 1007,		// update track TrackExtents info (buffer = &TrackExtents), param1 = (string ptr)file name)
+	opSetTrackSeekable = 1008,		// update track seekable flag (buffer = (string ptr)file name), param1 = TRUE/FALSE
+	opSetPlayNext = 1009,			// set the next index to be played (buffer = NULL, param1 = index, index = -1 unsets playnext)
+	opSetIndexFilename = 1010,		// updates the filename (or stream) that an index in the current playlist refers to, buffer = new filename, param1 = index
+
+	opSetSeekPosition = 1100,		// seek to position during playback (buffer = NULL, param1 = position, param2 = 0 - position is in seconds, 1 - position is in milliseconds, 2 - position is in percent (use (float)param1))
+
+
+									//*** below configures custom plugin menu items for the 'plugin menu'
+									//*** Player will call plugin's configure routine with menu value when menu item selected
+									//*** returns 1 on success, 0 on failure
+
+	opSetPluginMenuItem = 2000,		// buffer = HINSTANCE of plugin, param1 = item id, param2 = (string ptr)string to display
+									//		- set param2 = 0 to remove item id from menu
+									//		- set param1 = 0 and param2 = 0 to remove whole menu
+	opSetPluginMenuState = 2001,	// buffer = HINSTANCE of plugin, param1 = item id, param2 = menu flags (same as windows menu flags - eg: MF_CHECKED)
+
+
+									//*** other services
+
+	opSafeWait = 10000				// plugin's can use this to wait on an object without worrying about deadlocking the player.
+									// this should only be called by the thread that enters the plugin, not by any plugin-created threads
+
+} PluginServiceOp;
+
+//-----------------------------------------------------------------------------
+// Info services api provided by the Player, called by Plugin.
+//-----------------------------------------------------------------------------
+typedef long (*PluginServiceFunc)(PluginServiceOp op, void *buffer, long param1, long param2);
+
+
+//-----------------------------------------------------------------------------
+typedef struct				// for Output Plugin Write callback
+{
+	void	*data;			// pointer to valid data
+	int		bytelen;		// length of data pointed to by 'data' in bytes
+	UINT	numsamples;		// number of samples represented by 'data'
+	UINT	bps;			// bits per sample
+	UINT	nch;			// number of channels
+	UINT	srate;			// sample rate
+
+	UINT	markerstart;	// Marker position at start of data (marker is time value of data) 
+							// (set to WAVE_VIS_DATA_ONLY to not have data sent to output plugins)
+	UINT	markerend;		// Marker position at end of data (not currently used, set to 0)
+} WriteDataStruct;
+
+//-----------------------------------------------------------------------------
+typedef struct			// for GetTrackExtents Input Plugin callback
+{
+	UINT track;			// for CD's, set the track number. Otherwise set to 1.
+	UINT start;			// for CD's or media that doesn't start at the beginning 
+						// of the file, set to start position. Otherwise set to 0.
+	UINT end;			// set to end position of media.
+	UINT unitpersec;	// whatever units are being used for this media, how many
+						// of them per second. 
+						// (Note: ((end - start) / unitpersecond) = file length
+	UINT bytesize;		// size of file in bytes (if applicable, otherwise 0).
+} TrackExtents;
+
+//-----------------------------------------------------------------------------
+typedef struct			// for opSetAudioInfo service
+{		
+    long struct_size;	// sizeof(AudioInfo)
+    long level;			// MPEG level (1 for MPEG1, 2 for MPEG2, 3 for MPEG2.5, 7 for MPEGpro)
+    long layer;			// and layer (1, 2 or 3)
+    long bitrate;		// audio bitrate in bits per second
+    long frequency;		// audio freq in Hz
+    long mode;			// 0 for stereo, 1 for joint-stereo, 2 for dual-channel, 3 for mono, 4 for multi-channel
+} AudioInfo;
+
+//-----------------------------------------------------------------------------
+// Equalizer Info
+//-----------------------------------------------------------------------------
+typedef struct			// for coming QCD version
+{
+	long struct_size;	// sizeof(EQInfo)
+	char enabled;		
+	char preamp;		// -128 to 127, 0 is even
+	char bands[10];		// -128 to 127, 0 is even
+} EQInfo;
+
+//-----------------------------------------------------------------------------
+typedef struct
+{
+	long struct_size;	// sizeof(ProxyInfo)
+	char hostname[200];
+	long port;
+	char username[100];
+	char password[100];
+} ProxyInfo;
+
+//-----------------------------------------------------------------------------
+typedef enum			// for MediaInfo.mediaType
+{ 
+	UNKNOWN_MEDIA = 0,
+	CD_AUDIO_MEDIA = 1,
+	DIGITAL_FILE_MEDIA = 2,
+	DIGITAL_STREAM_MEDIA = 3
+} MediaTypes;
+
+//-----------------------------------------------------------------------------
+#define MAX_TOC_LEN				2048
+typedef struct
+{
+	// media descriptors
+	CHAR		mediaFile[MAX_PATH];
+	MediaTypes	mediaType;
+
+	// cd audio media info
+	CHAR		cd_mediaTOC[MAX_TOC_LEN];
+	int			cd_numTracks;
+	int			cd_hasAudio;
+
+	// operation info
+	int			op_canSeek;
+
+	// not used
+	int			reserved[4];
+
+} MediaInfo;
+
+
+//-----------------------------------------------------------------------------
+// When subclassing the parent window, a plugin can watch for these messages
+// to react to events going on between plugins and player
+// DO NOT SEND THESE MESSAGES - can only watch for them
+
+// Plugin to Player Notifiers
+#define WM_PN_POSITIONUPDATE	(WM_USER + 100)	// playback progress updated
+#define WM_PN_PLAYSTARTED		(WM_USER + 101)	// playback has started
+#define WM_PN_PLAYSTOPPED		(WM_USER + 102) // playback has stopped by user
+#define WM_PN_PLAYPAUSED		(WM_USER + 103) // playback has been paused
+#define WM_PN_PLAYDONE			(WM_USER + 104) // playback has finished (track completed)
+#define WM_PN_MEDIAEJECTED		(WM_USER + 105) // a CD was ejected (lParam = (LPCSTR)medianame)
+#define WM_PN_MEDIAINSERTED		(WM_USER + 106) // a CD was inserted (lParam = (LPCSTR)medianame)
+#define WM_PN_INFOCHANGED		(WM_USER + 107) // track information was updated (lParam = (LPCSTR)medianame)
+#define WM_PN_TRACKCHANGED		(WM_USER + 109)	// current track playing has changed (relevant from CD plugin) (lParam = (LPCSTR)medianame)
+
+// Player to Plugin Notifiers
+#define WM_PN_PLAYLISTCHANGED	(WM_USER + 200) // playlist has changed in some way (add, delete, sort, shuffle, drag-n-drop, etc...)
+
+// For intercepting main menu display
+// (so you can get handle, modify, and display your own)
+#define WM_SHOWMAINMENU			(WM_USER + 20)
+
+//-----------------------------------------------------------------------------
+// To shutdown player, send this command
+#define WM_SHUTDOWN				(WM_USER + 5)
+
+//-----------------------------------------------------------------------------
+// opSetStatusMessage textflags
+#define TEXT_DEFAULT		0x0		// message scrolls by in status window
+#define TEXT_TOOLTIP		0x1		// message acts as tooltip in status window
+#define TEXT_URGENT			0x2		// forces message to appear even if no status window (using msg box)
+#define TEXT_HOLD			0x4		// tooltip message stays up (no fade out)
+
+
+#endif //QCDMODDEFS_H
\ No newline at end of file
--- /dev/null
+++ b/plugins/QCD/QCDModInput.h
@@ -1,0 +1,117 @@
+//-----------------------------------------------------------------------------
+//
+// File:	QCDModInput.h
+//
+// About:	Input plugin module interface.  This file is published with the 
+//			Input plugin SDK.
+//
+// Authors:	Written by Paul Quinn and Richard Carlson.
+//
+// Copyright:
+//
+//	QCD multimedia player application Software Development Kit Release 1.0.
+//
+//	Copyright (C) 1997-2002 Quinnware
+//
+//	This code is free.  If you redistribute it in any form, leave this notice 
+//	here.
+//
+//	This program is distributed in the hope that it will be useful,
+//	but WITHOUT ANY WARRANTY; without even the implied warranty of
+//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef QCDMODINPUT_H
+#define QCDMODINPUT_H
+
+#include "QCDModDefs.h"
+
+// name of the DLL export for input plugins
+#define INPUTDLL_ENTRY_POINT		QInputModule2	// (updated plugin api version 240+)
+
+// media insert flags
+#define MEDIAINSERT_PLAY			0x1
+#define MEDIAINSERT_ADDTRACKS		0x2
+#define MEDIAINSERT_ADDSEGMENTS		0x4
+#define MEDIAINSERT_CLEARPLAYLIST	0x8
+
+// Stop will receive one of these flags (pass to output plugin's stop())
+#define STOPFLAG_FORCESTOP			0	// stop occuring due to user action or other event
+#define STOPFLAG_PLAYDONE			1	// stop occuring due to playlist completion
+
+// play flags
+#define PLAYFLAG_PLAYBACK			0x0
+#define PLAYFLAG_ENCODING			0x1
+#define PLAYFLAG_SEEKING			0x2
+
+// Wave Marker flags
+#define WAVE_VIS_DATA_ONLY			-1	// set to WaveDataStruct.markerstart in OutputWrite() call have data only go to vis 
+										// and not to output plugin
+// pause flags
+#define PAUSE_DISABLED				0	// Pause() call is to unpause playback
+#define PAUSE_ENABLED				1	// Pause() call is to pause playback
+
+//-----------------------------------------------------------------------------
+// Input Module
+//-----------------------------------------------------------------------------
+typedef struct 
+{
+	unsigned int		size;			// size of init structure
+	unsigned int		version;		// plugin structure version (set to PLUGIN_API_VERSION)
+	PluginServiceFunc	Service;		// player supplied services callback
+
+	struct
+	{
+		void (*PositionUpdate)(unsigned int position);
+		void (*PlayStopped)(const char* medianame);					// notify player of play stop
+		void (*PlayStarted)(const char* medianame);					// notify player of play start
+		void (*PlayPaused)(const char* medianame, int flags);		// notify player of play pause
+		void (*PlayDone)(const char* medianame);					// notify player when play done
+		void (*PlayTrackChanged)(const char* medianame);			// notify player when playing track changes (cd audio relevant only)
+		void (*MediaEjected)(const char* medianame);				// notify player of media eject (cd audio relevant)
+		void (*MediaInserted)(const char* medianame, int flags);	// notify player of media insert (cd audio relevant)
+
+																	// output plugin calls
+		int  (*OutputOpen)(const char* medianame, WAVEFORMATEX*);	// open output for wave data
+		int  (*OutputWrite)(WriteDataStruct*);						// send PCM audio data to output 
+																		// (blocks until write completes, thus if output is paused can 
+																		// block until unpaused)
+		int  (*OutputDrain)(int flags);								// wait for all output to complete (blocking)
+		int  (*OutputDrainCancel)(int flags);						// break a drain in progress
+		int  (*OutputFlush)(unsigned int marker);					// flush output upto marker
+		int  (*OutputStop)(int flags);								// stop output
+		int  (*OutputPause)(int flags);								// pause output
+
+		int  (*OutputSetVol)(int levelleft, int levelright, int flags);
+		int  (*OutputGetCurrentPosition)(unsigned int *position, int flags);
+
+		void *Reserved[10];
+	} toPlayer;
+
+	struct 
+	{
+		int  (*Initialize)(QCDModInfo *modInfo, int flags);			// initialize plugin
+		void (*ShutDown)(int flags);								// shutdown plugin
+
+		int  (*Play)(const char* medianame, int playfrom, int playto, int flags);	// start playing playfrom->playto
+		int  (*Stop)(const char* medianame, int flags);				// stop playing
+		int  (*Pause)(const char* medianame, int flags);			// pause playback
+		int  (*Eject)(const char* medianame, int flags);			// eject media
+		void (*SetEQ)(EQInfo*);										// update EQ settings
+
+		int  (*GetMediaSupported)(const char* medianame, MediaInfo *mediaInfo);			// does plugin support medianame (and provides info for media)
+		int  (*GetTrackExtents)(const char* medianame, TrackExtents *ext, int flags);	// get media start, end & units
+		int  (*GetCurrentPosition)(const char* medianame, long *track, long *offset);	// get playing media's position
+
+		void (*Configure)(int flags);									// launch configuration
+		void (*About)(int flags);										// launch about info
+
+		void (*SetVolume)(int levelleft, int levelright, int flags);	// level 0 - 100
+
+		void *Reserved[10];
+	} toModule;
+
+} QCDModInitIn;
+
+#endif //QCDMODINPUT_H
--- /dev/null
+++ b/plugins/QCD/ReadMe.txt
@@ -1,0 +1,11 @@
+QCDFAAD.dll input Plugin for Quintessential Player (QCD)
+Please goto http://www.quinnware.com to download the latest version of QCD.
+
+About Tagging music file:
+
+Because QCD support ID3v1 & ID3v2 functions. So you can add a string -- ":AAC" 
+in the configuration dialog box of QCDcddb.dll Libarary Plugin.
+(I think you will find it and will know how to do it,
+otherwise you can visite the message forum on the web site.)
+
+Have a good time:)
\ No newline at end of file
--- /dev/null
+++ b/plugins/QCD/plugin_dlg.rc
@@ -1,0 +1,133 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_CONFIG DIALOGEX 0, 0, 179, 133
+STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "FAAC Decoder Configuration"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+    CONTROL         "Enable variable bitrate display",VARBITRATE_CHK,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,7,140,10
+    EDITTEXT        STREAM_BUFFER_TXT,87,21,21,12,ES_AUTOHSCROLL | ES_NUMBER
+    EDITTEXT        LOCAL_BUFFER_TXT,87,38,21,12,ES_AUTOHSCROLL | ES_NUMBER
+    CONTROL         "Buffer entire files into memory",IDC_MEMMAP,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,60,140,10
+    CONTROL         "Slider1",THREAD_PRIORITY_SLIDER,"msctls_trackbar32",
+                    TBS_AUTOTICKS | WS_TABSTOP,7,89,165,11,WS_EX_TRANSPARENT
+    PUSHBUTTON      "OK",OK_BTN,64,112,50,14
+    PUSHBUTTON      "Cancel",CANCEL_BTN,121,112,50,14
+    LTEXT           "HTTP stream buffer:",IDC_STATIC,7,22,77,8
+    LTEXT           "Decode Thread Priority: Highest (default)",IDC_STATIC2,
+                    7,78,165,8
+    LTEXT           "Local file buffer: ",IDC_STATIC,7,40,77,8
+    PUSHBUTTON      "Reset",RESET_BTN,7,112,50,14
+END
+
+IDD_ABOUT DIALOG DISCARDABLE  0, 0, 187, 114
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About FAAD Plug-in"
+FONT 8, "MS Sans Serif"
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,68,93,50,14
+    CTEXT           "FAAD Input Plug-in for QCD v 1.0\nLast Modified Feb. 2003",
+                    IDC_STATIC,13,7,161,19
+    CTEXT           "Using: FAAD2 v1.2 beta by M. Bakker && menno",
+                    IDC_STATIC,7,33,173,8
+    LTEXT           "FAAD: http://www.audiocoding.com",IDC_STATIC,7,50,129,8
+    LTEXT           "Author: Shao Hao\nE-Mail: [email protected]",IDC_STATIC,
+                    9,67,140,20
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE 
+BEGIN
+    IDD_CONFIG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 172
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 126
+    END
+
+    IDD_ABOUT, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 180
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 107
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
--- /dev/null
+++ b/plugins/QCD/resource.h
@@ -1,0 +1,65 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by plugin_dlg.rc
+//
+#define PLUGIN_DLG                      101
+#define IDD_CONFIG                      101
+#define IDD_INFO                        102
+#define IDD_EDITTEXTFRAME               103
+#define IDD_ADDFRAME                    104
+#define IDD_ADDSTANDARD                 105
+#define IDD_ABOUT                       106
+#define VARBITRATE_CHK                  1004
+#define BUFFERING_SLIDER                1006
+#define THREAD_PRIORITY_SLIDER          1007
+#define IDC_ID3V2TAG                    1020
+#define IDC_CLOSE                       1021
+#define IDC_CANCEL                      1022
+#define IDC_HEADER                      1025
+#define IDC_PROFILE                     1026
+#define IDC_BITRATE                     1027
+#define IDC_SAMPLERATE                  1028
+#define IDC_CHANNELS                    1029
+#define IDC_VERSION                     1030
+#define IDC_ID3LIST                     1032
+#define IDC_STATIC2                     1034
+#define LOCAL_BUFFER_TXT                1035
+#define STREAM_BUFFER_TXT               1036
+#define IDC_CHECK1                      1037
+#define IDC_MEMMAP                      1037
+#define OK_BTN                          1038
+#define CANCEL_BTN                      1039
+#define IDC_EDITTEXTFRAME               1040
+#define IDC_FRAMETYPE                   1040
+#define IDC_TEXTFRAMENAME               1041
+#define IDC_COL0                        1041
+#define IDC_DELFRAME                    1042
+#define IDC_COL1                        1042
+#define IDC_EDITFRAME                   1043
+#define IDC_ADDFRAME                    1044
+#define IDC_TRACK                       1045
+#define IDC_ADDSTFRAMES                 1045
+#define IDC_TITLE                       1046
+#define IDC_FORMAT                      1046
+#define IDC_ARTIST                      1047
+#define RESET_BTN                       1047
+#define IDC_ALBUM                       1048
+#define IDC_YEAR                        1049
+#define IDC_COMMENT                     1050
+#define IDC_COMPOSER                    1051
+#define IDC_ORIGARTIST                  1052
+#define IDC_COPYRIGHT                   1053
+#define IDC_URL                         1054
+#define IDC_ENCBY                       1055
+#define IDC_GENRE                       1056
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        107
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1048
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif