⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qcdfaad.c

📁 BHE的解码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
** 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;		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -