summaryrefslogtreecommitdiff
path: root/faad2/src/plugins/QCD
diff options
context:
space:
mode:
authorMichał Cichoń <michcic@gmail.com>2012-06-26 20:35:30 +0200
committerMichał Cichoń <michcic@gmail.com>2012-06-26 20:35:30 +0200
commitcc2160de5cc05dc3aa77f3a34358e66f6193c8c9 (patch)
treeb93dd2dbdf7ea5ca4d6647c58dbe504824ac419f /faad2/src/plugins/QCD
parenta9c5f408fdc10f9fd1da6e5cf6f6376f1f591e10 (diff)
downloadpianobar-windows-build-cc2160de5cc05dc3aa77f3a34358e66f6193c8c9.tar.gz
pianobar-windows-build-cc2160de5cc05dc3aa77f3a34358e66f6193c8c9.tar.bz2
pianobar-windows-build-cc2160de5cc05dc3aa77f3a34358e66f6193c8c9.zip
Add support for AAC.
Diffstat (limited to 'faad2/src/plugins/QCD')
-rw-r--r--faad2/src/plugins/QCD/QCDFAAD.c1030
-rw-r--r--faad2/src/plugins/QCD/QCDFAAD.sln29
-rw-r--r--faad2/src/plugins/QCD/QCDFAAD.vcproj348
-rw-r--r--faad2/src/plugins/QCD/QCDInputDLL.h50
-rw-r--r--faad2/src/plugins/QCD/QCDModDefs.h340
-rw-r--r--faad2/src/plugins/QCD/QCDModInput.h117
-rw-r--r--faad2/src/plugins/QCD/ReadMe.txt11
-rw-r--r--faad2/src/plugins/QCD/logo.bmpbin0 -> 87614 bytes
-rw-r--r--faad2/src/plugins/QCD/plugin_dlg.rc141
-rw-r--r--faad2/src/plugins/QCD/resource.h33
10 files changed, 2099 insertions, 0 deletions
diff --git a/faad2/src/plugins/QCD/QCDFAAD.c b/faad2/src/plugins/QCD/QCDFAAD.c
new file mode 100644
index 0000000..1d12295
--- /dev/null
+++ b/faad2/src/plugins/QCD/QCDFAAD.c
@@ -0,0 +1,1030 @@
+/*
+** 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.2 2003/04/28 19:04:35 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 <shellapi.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, hwndConfig, hwndAbout;
+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
+
+// 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, "5");
+ 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.0b";
+ /* 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;
+}
+
+//----------------------------------------------------------------------------
+
+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 Configure(int flags)
+{
+ if(!IsWindow(hwndConfig))
+ hwndConfig = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_CONFIG), hwndPlayer, config_dialog_proc);
+ ShowWindow(hwndConfig, SW_NORMAL);
+}
+
+//-----------------------------------------------------------------------------
+// proc of "About Dialog"
+INT_PTR CALLBACK about_dialog_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static RECT rcLOGO, rcMail1, rcMail2/*, rcMail3*/;
+ POINT ptMouse;
+ static char szPluginVer[] = "QCD FAAD Input Plug-in v1.0b\nCompiled on " __TIME__ ", " __DATE__;
+ static char szFLACVer[] = "Using: FAAD2 v "FAAD2_VERSION" by";
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ case WM_MOVE:
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_LOGO), &rcLOGO);
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_MAIL1), &rcMail1);
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_MAIL2), &rcMail2);
+// GetWindowRect(GetDlgItem(hwndDlg, IDC_MAIL2), &rcMail3);
+
+ SetDlgItemText(hwndDlg, IDC_PLUGINVER, szPluginVer);
+ SetDlgItemText(hwndDlg, IDC_FAADVER, szFLACVer);
+
+ return TRUE;
+ case WM_MOUSEMOVE:
+ ptMouse.x = LOWORD(lParam);
+ ptMouse.y = HIWORD(lParam);
+ ClientToScreen(hwndDlg, &ptMouse);
+ if( (ptMouse.x >= rcLOGO.left && ptMouse.x <= rcLOGO.right &&
+ ptMouse.y >= rcLOGO.top && ptMouse.y<= rcLOGO.bottom)
+ ||
+ (ptMouse.x >= rcMail1.left && ptMouse.x <= rcMail1.right &&
+ ptMouse.y >= rcMail1.top && ptMouse.y<= rcMail1.bottom)
+ ||
+ (ptMouse.x >= rcMail2.left && ptMouse.x <= rcMail2.right &&
+ ptMouse.y >= rcMail2.top && ptMouse.y<= rcMail2.bottom)
+/* ||
+ (ptMouse.x >= rcMail3.left && ptMouse.x <= rcMail3.right &&
+ ptMouse.y >= rcMail3.top && ptMouse.y<= rcMail3.bottom)*/ )
+ SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(32649)));
+ else
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+
+ return TRUE;
+ case WM_LBUTTONDOWN:
+ ptMouse.x = LOWORD(lParam);
+ ptMouse.y = HIWORD(lParam);
+ ClientToScreen(hwndDlg, &ptMouse);
+ if(ptMouse.x >= rcLOGO.left && ptMouse.x <= rcLOGO.right &&
+ ptMouse.y >= rcLOGO.top && ptMouse.y<= rcLOGO.bottom)
+ ShellExecute(0, NULL, "http://www.audiocoding.com", NULL,NULL, SW_NORMAL);
+ else if(ptMouse.x >= rcMail1.left && ptMouse.x <= rcMail1.right &&
+ ptMouse.y >= rcMail1.top && ptMouse.y<= rcMail1.bottom)
+ ShellExecute(0, NULL, "mailto:shaohao@elong.com", NULL,NULL, SW_NORMAL);
+ else if(ptMouse.x >= rcMail2.left && ptMouse.x <= rcMail2.right &&
+ ptMouse.y >= rcMail2.top && ptMouse.y<= rcMail2.bottom)
+ ShellExecute(0, NULL, "mailto:menno@audiocoding.com", NULL,NULL, SW_NORMAL);
+/* else if(ptMouse.x >= rcMail3.left && ptMouse.x <= rcMail3.right &&
+ ptMouse.y >= rcMail3.top && ptMouse.y<= rcMail3.bottom)
+ ShellExecute(0, NULL, "I don't know", NULL,NULL, SW_NORMAL);
+*/
+ return TRUE;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ default:
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void About(int flags)
+{
+ if(!IsWindow(hwndAbout))
+ hwndAbout = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_ABOUT), hwndPlayer, about_dialog_proc);
+ ShowWindow(hwndAbout, SW_SHOW);
+}
+
+//-----------------------------------------------------------------------------
+
+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.0b";
+ 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();
+
+ // 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);
+
+ seek_needed = playfrom > 0 ? playfrom : -1;
+ killPlayThread = 0;
+ strcpy(lastfn,medianame);
+
+ /*
+ 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;
+
+ 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(play_thread_handle != INVALID_HANDLE_VALUE)
+ {
+ if(WaitForSingleObject(play_thread_handle, INFINITE) == WAIT_TIMEOUT)
+ {
+// MessageBox(hwndPlayer, "FAAD thread kill timeout", "debug", 0);
+ TerminateThread(play_thread_handle,0);
+ }
+ CloseHandle(play_thread_handle);
+ play_thread_handle = INVALID_HANDLE_VALUE;
+ }
+
+ if (oldAPIs)
+ QCDCallbacks->toPlayer.PlayStopped(lastfn);
+
+ lastfn[0] = 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;
+
+ // Round off to a second
+ seconds = seek_needed - (seek_needed%1000);
+ QCDCallbacks->toPlayer.OutputFlush(decode_pos_ms);
+ aac_seek(seconds, seek_table);
+ decode_pos_ms = seconds;
+ decoded_frames = 0;
+ br_calc_frames = 0;
+ br_bytes_consumed = 0;
+
+ seek_needed = -1;
+ updatePos = 1;
+ }
+
+ /********************* QUIT *************************/
+ if (done)
+ {
+ if (QCDCallbacks->toPlayer.OutputDrain(0) && !(seek_needed >= 0))
+ {
+ play_thread_handle = INVALID_HANDLE_VALUE;
+ QCDCallbacks->toPlayer.OutputStop(STOPFLAG_PLAYDONE);
+ QCDCallbacks->toPlayer.PlayDone(lastfn);
+ }
+ else if (seek_needed >= 0)
+ {
+ done = FALSE;
+ continue;
+ }
+ break;
+ }
+
+ /******************* DECODE TO BUFFER ****************/
+ else
+ {
+ if (current_file_mode)
+ bytesconsumed = PlayThread_memmap();
+ else
+ bytesconsumed = PlayThread_file();
+
+ if(last_frame)
+ done = TRUE;
+ else
+ {
+
+ 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 = file_info.version;
+ 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;
+
+ l = frameInfo.samples * sizeof(short);
+
+ decode_pos_ms += (1024*1000)/file_info.sampling_rate;
+
+ wd.bytelen = l;
+ wd.data = sample_buffer;
+ wd.markerend = 0;
+ wd.markerstart = decode_pos_ms;
+ wd.bps = 16;
+ wd.nch = frameInfo.channels;
+ wd.numsamples =l/file_info.channels/(16/8);
+ wd.srate = file_info.sampling_rate;
+
+ if (!QCDCallbacks->toPlayer.OutputWrite(&wd))
+ done = TRUE;
+ }
+ }
+ }
+ }
+ Sleep(10);
+ }
+
+ // close up
+ play_thread_handle = INVALID_HANDLE_VALUE;
+
+ faacDecClose(hDecoder);
+ hDecoder = INVALID_HANDLE_VALUE;
+ close_filestream(infile);
+ infile = NULL;
+
+ if(seek_table)
+ {
+ free(seek_table);
+ seek_table = NULL;
+ seek_table_length = 0;
+ }
+
+ if(buffer)
+ {
+ LocalFree(buffer);
+ buffer = NULL;
+ }
+ if(memmap_buffer)
+ {
+ LocalFree(memmap_buffer);
+ memmap_buffer = NULL;
+ }
+
+ 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;
+}
+
+// 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
diff --git a/faad2/src/plugins/QCD/QCDFAAD.sln b/faad2/src/plugins/QCD/QCDFAAD.sln
new file mode 100644
index 0000000..5810dde
--- /dev/null
+++ b/faad2/src/plugins/QCD/QCDFAAD.sln
@@ -0,0 +1,29 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QCDFAAD", "QCDFAAD.vcproj", "{71955EB0-4F77-462B-A844-2BA56E74B87E}"
+ ProjectSection(ProjectDependencies) = postProject
+ {BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114} = {BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaad", "..\..\libfaad\libfaad.vcproj", "{BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {71955EB0-4F77-462B-A844-2BA56E74B87E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {71955EB0-4F77-462B-A844-2BA56E74B87E}.Debug|Win32.Build.0 = Debug|Win32
+ {71955EB0-4F77-462B-A844-2BA56E74B87E}.Release|Win32.ActiveCfg = Release|Win32
+ {71955EB0-4F77-462B-A844-2BA56E74B87E}.Release|Win32.Build.0 = Release|Win32
+ {BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}.Debug|Win32.ActiveCfg = Debug|Win32
+ {BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}.Debug|Win32.Build.0 = Debug|Win32
+ {BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}.Release|Win32.ActiveCfg = Release|Win32
+ {BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/faad2/src/plugins/QCD/QCDFAAD.vcproj b/faad2/src/plugins/QCD/QCDFAAD.vcproj
new file mode 100644
index 0000000..a57975e
--- /dev/null
+++ b/faad2/src/plugins/QCD/QCDFAAD.vcproj
@@ -0,0 +1,348 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="QCDFAAD"
+ ProjectGUID="{71955EB0-4F77-462B-A844-2BA56E74B87E}"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/QCDFAAD.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include,..\..\common\faad,..\..\plugins\winamp,..\..\common\id3lib\include"
+ PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;ID3LIB_COMPILATION"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ PrecompiledHeaderFile=".\Debug/QCDFAAD.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1043"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib odbc32.lib odbccp32.lib"
+ OutputFile=".\Debug/QCDFAAD.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug/QCDFAAD.pdb"
+ SubSystem="2"
+ ImportLibrary=".\Debug/QCDFAAD.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Debug/QCDFAAD.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/QCDFAAD.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\include,..\..\common\faad,..\..\plugins\winamp,..\..\common\id3lib\include"
+ PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;ID3LIB_COMPILATION"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release/QCDFAAD.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1043"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib odbc32.lib odbccp32.lib"
+ OutputFile=".\Release/QCDFAAD.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ ProgramDatabaseFile=".\Release/QCDFAAD.pdb"
+ SubSystem="2"
+ ImportLibrary=".\Release/QCDFAAD.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release/QCDFAAD.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="..\..\common\faad\aacinfo.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\common\faad\filestream.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="QCDFAAD.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath="..\..\common\faad\aacinfo.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\faad.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\faad\filestream.h"
+ >
+ </File>
+ <File
+ RelativePath="QCDInputDLL.h"
+ >
+ </File>
+ <File
+ RelativePath="QCDModDefs.h"
+ >
+ </File>
+ <File
+ RelativePath="QCDModInput.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ <File
+ RelativePath="hand.cur"
+ >
+ </File>
+ <File
+ RelativePath="logo.bmp"
+ >
+ </File>
+ <File
+ RelativePath="plugin_dlg.rc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/faad2/src/plugins/QCD/QCDInputDLL.h b/faad2/src/plugins/QCD/QCDInputDLL.h
new file mode 100644
index 0000000..a69023b
--- /dev/null
+++ b/faad2/src/plugins/QCD/QCDInputDLL.h
@@ -0,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
diff --git a/faad2/src/plugins/QCD/QCDModDefs.h b/faad2/src/plugins/QCD/QCDModDefs.h
new file mode 100644
index 0000000..1f68baf
--- /dev/null
+++ b/faad2/src/plugins/QCD/QCDModDefs.h
@@ -0,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
diff --git a/faad2/src/plugins/QCD/QCDModInput.h b/faad2/src/plugins/QCD/QCDModInput.h
new file mode 100644
index 0000000..40a7ae5
--- /dev/null
+++ b/faad2/src/plugins/QCD/QCDModInput.h
@@ -0,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
diff --git a/faad2/src/plugins/QCD/ReadMe.txt b/faad2/src/plugins/QCD/ReadMe.txt
new file mode 100644
index 0000000..2e89c09
--- /dev/null
+++ b/faad2/src/plugins/QCD/ReadMe.txt
@@ -0,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
diff --git a/faad2/src/plugins/QCD/logo.bmp b/faad2/src/plugins/QCD/logo.bmp
new file mode 100644
index 0000000..a01eb84
--- /dev/null
+++ b/faad2/src/plugins/QCD/logo.bmp
Binary files differ
diff --git a/faad2/src/plugins/QCD/plugin_dlg.rc b/faad2/src/plugins/QCD/plugin_dlg.rc
new file mode 100644
index 0000000..1316be9
--- /dev/null
+++ b/faad2/src/plugins/QCD/plugin_dlg.rc
@@ -0,0 +1,141 @@
+//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, 191, 168
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About FAAD Plug-in"
+FONT 8, "MS Sans Serif"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,70,147,50,14
+ CTEXT "",IDC_PLUGINVER,29,73,133,16
+ CTEXT "",IDC_FAADVER,40,123,111,8
+ LTEXT "QCD Input Plug-in by",IDC_STATIC,62,97,67,8
+ CONTROL 107,IDC_LOGO,"Static",SS_BITMAP | SS_CENTERIMAGE |
+ SS_REALSIZEIMAGE,7,0,177,68
+ LTEXT "Shao Hao",IDC_MAIL1,79,111,33,8
+ LTEXT "M. Bakker",IDC_MAIL3,59,134,34,8
+ LTEXT "menno",IDC_MAIL2,109,134,22,8
+ LTEXT "&&",IDC_STATIC,97,134,8,8
+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, 184
+ BOTTOMMARGIN, 161
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_LOGO BITMAP DISCARDABLE "logo.bmp"
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/faad2/src/plugins/QCD/resource.h b/faad2/src/plugins/QCD/resource.h
new file mode 100644
index 0000000..7837a2c
--- /dev/null
+++ b/faad2/src/plugins/QCD/resource.h
@@ -0,0 +1,33 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by plugin_dlg.rc
+//
+#define IDD_CONFIG 101
+#define IDD_ABOUT 106
+#define IDB_LOGO 107
+#define VARBITRATE_CHK 1004
+#define THREAD_PRIORITY_SLIDER 1007
+#define IDC_STATIC2 1034
+#define LOCAL_BUFFER_TXT 1035
+#define STREAM_BUFFER_TXT 1036
+#define IDC_MEMMAP 1037
+#define OK_BTN 1038
+#define CANCEL_BTN 1039
+#define RESET_BTN 1047
+#define IDC_LOGO 1048
+#define IDC_PLUGINVER 1050
+#define IDC_FAADVER 1051
+#define IDC_MAIL1 1052
+#define IDC_MAIL2 1053
+#define IDC_MAIL3 1054
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 109
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1055
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif