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

📄 vis_spectrum.cpp

📁 mp3 频谱分析源码, mp3播放器开发必备源码,
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "stdafx.h"
#include "vis_spectrum.h"
#include "optionsdlg.h"
#include "resource.h"
#include "frontend.h"

void* WndProcOld;
HANDLE hThread;
bool g_bAboutActive=false;
void GetColourMap();

// Window Procedure Prototype
LRESULT CALLBACK VisWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK SubWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL    CALLBACK AboutDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);

bool SetCurrentSkin(const char* lpszBitmap);
void GetConfigFileName(struct winampVisModule* mod, char* lpBuffer, DWORD dwSize);
void OnConfigRead(struct winampVisModule* mod);
void OnConfigWrite(struct winampVisModule* mod);
void OnPluginConfig(struct winampVisModule* mod);
void OnPluginQuit(struct winampVisModule* mod);
int  OnPluginInit(struct winampVisModule* mod);
int  OnPluginRender(struct winampVisModule* mod);
void UpdateRect(LPRECT lpRect, HWND hWnd);
void KillUpdateThread();
void InitUpdateThread(int nFunc = 0);
void LoadSkin();
void SaveSkin(char* szName);

DWORD kill_update_thread=0;
DWORD APIENTRY UpdateThread(LPVOID lpParam);

// obtain the address of the module
winampVisModule* OnGetModule(int nModule);

// global variables
VS_PLUGINVARS Plugin;

// a level mapper, (these were generated using another program, i did not
// write them out by hand - I am not that stupid :)
unsigned char g_achLevelMap[256] = {
0,35,85,112,129,141,150,158,164,169,174,178,182,186,189,191,194,197,199,201,203,205,207,
209,210,211,213,214,215,216,218,219,220,221,222,223,223,224,225,226,227,228,228,229,230,
230,231,231,232,232,233,233,234,234,235,235,236,236,237,237,237,238,238,239,239,239,240,
240,240,241,241,241,241,242,242,242,242,243,243,243,243,244,244,244,244,244,245,245,245,
245,245,246,246,246,246,246,246,247,247,247,247,247,247,247,247,248,248,248,248,248,248,
248,248,249,249,249,249,249,249,249,249,249,249,250,250,250,250,250,250,250,250,250,250,
250,250,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,
252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,
253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
253,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255
};

// global variables used for adjusting the data and colour mapping. g_achPeakData
// stores the level of the peaks in element 0 and how much delay
// is left (in frames) in element 1.
unsigned char g_achDisplayData[576];
unsigned char g_achScreenData[576];
unsigned char g_achPeakData[2][576]; // 0 = height, 1 = delay time
// A colour mapper
unsigned long g_ulColourMap[256];
unsigned long g_ulPeakColour = 0xFFFFFF;
unsigned long g_ulGridColour = 0x424100;
unsigned long g_ulBackColour = 0x000000;

// (with initialisation)
winampVisHeader waHeader = { 
	VIS_HDRVER, 
	PLUGIN_DESC, 
	OnGetModule 
};

// The global module variable
winampVisModule waModule = {
	PLUGIN_DESC,
	NULL,				// hWndParent
	NULL,				// hDllInstance
	0,					// sRate
	0,					// nCh
	DEFAULT_LATENCY,	// latencyMS
	DEFAULT_DELAY,		// delayMS
	1,					// spectrumNch
	0,					// waveformNch
	{ 0, },				// spectrumData
	{ 0, },				// waveformData
	OnPluginConfig,		// config function
	OnPluginInit,		// init function
	OnPluginRender,		// render function
	OnPluginQuit		// quit function
};

// exported function (also see vis_spectrum.def). Returns
// the vis header to winamp.
__declspec(dllexport) winampVisHeader* winampVisGetHeader()
{
	return &waHeader;
}

// return the selected module (this dll only contains one
// module of course)
winampVisModule* OnGetModule(int nModule)
{
	switch(nModule) {
		case 0: 
			return &waModule;
		default:
			return NULL;
	}
}

// Gets a file name for the plugin to use. 
void GetConfigFileName(struct winampVisModule* mod, char* lpBuffer, DWORD dwSize)
{
	char* lpPtr;
	GetModuleFileName(mod->hDllInstance,lpBuffer,dwSize);
	lpPtr=lpBuffer+strlen(lpBuffer);
	while(lpPtr>=lpBuffer && *lpPtr !='\\') lpPtr--;
	if(++lpPtr>=lpBuffer) *lpPtr = 0;
	strcat(lpBuffer,CONFIG_FILE);
}

// Called when the configuration is to be read
void OnConfigRead(struct winampVisModule* mod)
{
	
	char szFileName[256];
	GetConfigFileName(mod,szFileName,256);

	VS_SAVEDATA Settings = {
		GetPrivateProfileInt(PLUGIN_KEY,"ulLeft",0,szFileName),    // left window pos
		GetPrivateProfileInt(PLUGIN_KEY,"ulTop",0,szFileName),    // top window pos
		GetPrivateProfileInt(PLUGIN_KEY,"ulWidth",STD_WIDTH,szFileName),  // width of window
		GetPrivateProfileInt(PLUGIN_KEY,"ulHeight",STD_HEIGHT,szFileName),  // height of window
		GetPrivateProfileInt(PLUGIN_KEY,"ulWindowSnap",10,szFileName),   // window snap threshold
		(GetPrivateProfileInt(PLUGIN_KEY,"bSnapWindow",1,szFileName)!=0), // snap windows
		(GetPrivateProfileInt(PLUGIN_KEY,"bDoubleSize",0,szFileName)!=0),// double size
		(GetPrivateProfileInt(PLUGIN_KEY,"bDimTitleBar",1,szFileName)!=0), // dim title bar on inactive
		(GetPrivateProfileInt(PLUGIN_KEY,"bSaveWndPos",1,szFileName)!=0), // save window pos
		(GetPrivateProfileInt(PLUGIN_KEY,"bWinampCursor",1,szFileName)!=0), // use default cursor
		(GetPrivateProfileInt(PLUGIN_KEY,"bWantPeaks",1,szFileName)!=0), // show peaks
		(GetPrivateProfileInt(PLUGIN_KEY,"bWantBars",1,szFileName)!=0), // show bars
		(GetPrivateProfileInt(PLUGIN_KEY,"bWantGrid",1,szFileName)!=0),// show grid
		(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchBarWidth",4,szFileName),    // bar width
		(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchBarHorzGap",1,szFileName),    // bar horizontal gap (shrinks width of bar)
		(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchBarVertGap",0,szFileName),    // vertical bar gaps
		(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchPeakDelay",20,szFileName),   // delay (in frames of 25 ms) of peaks to drop
		(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchPeakDrop",4,szFileName),    // peak drop speed (per frame)
		(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchDefaultDrop",2,szFileName),    // default drop speed (when bars are below 16)
		(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchMaxIncrease",19,szFileName),   // maximum increase at one time
		(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchMaxDecrease",6,szFileName),   // maximum decrease at one time
		(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchGridWidth",4,szFileName),	  // horizontal grid width
		(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchGridVertGap",1,szFileName),    // vertical grid gap
		(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchGridHorzGap",0,szFileName),
		(GetPrivateProfileInt(PLUGIN_KEY,"bFilter",0,szFileName)!=0), // filter
		(GetPrivateProfileInt(PLUGIN_KEY,"bRemap",1,szFileName)!=0), // level remap
		0,
		0,
		(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchBarStyle",1,szFileName)
	};

	
	Plugin.Settings.nDelayMS = (int)GetPrivateProfileInt(PLUGIN_KEY,"nDelayMS",25,szFileName);
	Plugin.Settings.nLatency = (int)GetPrivateProfileInt(PLUGIN_KEY,"nLatency",25,szFileName);

	if(Plugin.Settings.nLatency < 10) Plugin.Settings.nLatency = 25;
	if(Plugin.Settings.nDelayMS < 10) Plugin.Settings.nDelayMS = 25;

	mod->delayMs = Plugin.Settings.nDelayMS;
	mod->latencyMs = Plugin.Settings.nLatency;

	Plugin.Settings = Settings;

}

// called when the configuration is to be written
void OnConfigWrite(struct winampVisModule* mod)
{
	char szFileName[256];
	GetConfigFileName(mod,szFileName,256);
	WritePrivateProfileInt(PLUGIN_KEY,"ulLeft",Plugin.Settings.ulLeft,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"ulTop",Plugin.Settings.ulTop,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"ulWidth",Plugin.Settings.ulWidth,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"ulHeight",Plugin.Settings.ulHeight,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"ulWindowSnap",Plugin.Settings.ulWindowSnap,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"bSnapWindow",(int)Plugin.Settings.bSnapWindow,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"bDoubleSize",(int)Plugin.Settings.bDoubleSize,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"bDimTitleBar",(int)Plugin.Settings.bDimTitleBar,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"bSaveWndPos",(int)Plugin.Settings.bSaveWndPos,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"bWinampCursor",(int)Plugin.Settings.bWinampCursor,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"bWantPeaks",(int)Plugin.Settings.bWantPeaks,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"bWantBars",(int)Plugin.Settings.bWantBars,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"bWantGrid",(int)Plugin.Settings.bWantGrid,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"uchBarWidth",(int)Plugin.Settings.uchBarWidth,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"uchBarHorzGap",(int)Plugin.Settings.uchBarHorzGap,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"uchBarVertGap",(int)Plugin.Settings.uchBarVertGap,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"uchPeakDelay",(int)Plugin.Settings.uchPeakDelay,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"uchPeakDrop",(int)Plugin.Settings.uchPeakDrop,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"uchDefaultDrop",(int)Plugin.Settings.uchDefaultDrop,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"uchMaxIncrease",(int)Plugin.Settings.uchMaxIncrease,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"uchMaxDecrease",(int)Plugin.Settings.uchMaxDecrease,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"uchGridWidth",(int)Plugin.Settings.uchGridWidth,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"uchGridVertGap",(int)Plugin.Settings.uchGridVertGap,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"uchGridHorzGap",(int)Plugin.Settings.uchGridHorzGap,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"bFilter",(int)Plugin.Settings.bFilter,szFileName );
	WritePrivateProfileInt(PLUGIN_KEY,"bRemap",(int)Plugin.Settings.bRemap,szFileName );
	WritePrivateProfileInt(PLUGIN_KEY,"nLatency",(int)mod->latencyMs,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"nDelayMS",(int)mod->delayMs,szFileName);
	WritePrivateProfileInt(PLUGIN_KEY,"uchBarStyle",(int)Plugin.Settings.uchBarStyle,szFileName);
}

// Configure the plugin - See optionsdlg.cpp and optionsdlg.h for
// the actual code to this.
void OnPluginConfig(struct winampVisModule* mod)
{
	DoOptionsDialogThingy(mod);
}

int OnPluginInit(struct winampVisModule* mod)
{
	// set global struct data
	Plugin.hWndParent = mod->hwndParent;
	// drawing area
	Plugin.rcDrawingRect.left = 7;
	Plugin.rcDrawingRect.top = 15;
	Plugin.rcDrawingRect.right = 268;
	Plugin.rcDrawingRect.bottom = 109;
	// title bar
	Plugin.rcTitleBar.top = 0;
	Plugin.rcTitleBar.left = 0;
	Plugin.rcTitleBar.right = STD_WIDTH;
	Plugin.rcTitleBar.bottom = 14;
	// close button
	Plugin.rcQuitButton.left = 264;
	Plugin.rcQuitButton.top  = 3;
	Plugin.rcQuitButton.right = 273;
	Plugin.rcQuitButton.bottom = 12;
	
	Plugin.hCurDlg = NULL;
	// read in config
	OnConfigRead(mod);
	// do window thing
	Plugin.Window.GetClassInfo()->lpfnWndProc = VisWndProc;
	Plugin.Window.GetClassInfo()->style = CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW;
	Plugin.Window.GetClassInfo()->hInstance = mod->hDllInstance;
	Plugin.Window.GetClassInfo()->hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	
	if(Plugin.Settings.bWinampCursor) 
		Plugin.Window.GetClassInfo()->hCursor = LoadCursor((HINSTANCE)GetWindowLong(mod->hwndParent,GWL_HINSTANCE),MAKEINTRESOURCE(IDR_MAINCURSOR));
	else
		Plugin.Window.GetClassInfo()->hCursor = LoadCursor(NULL,IDC_ARROW);

	Plugin.Window.GetClassInfo()->lpszClassName = g_lpszClassName;
	
	// register the window class
	if(!Plugin.Window.DoRegisterClass()) {
		MessageBox(mod->hwndParent,"Couldn't register window class for "PLUGIN_DESC" plugin.","Error - "PLUGIN_DESC,MB_ICONERROR);
		return INIT_FAIL;

	}
	// create the window
	if(!Plugin.Window.Create(PLUGIN_DESC,Plugin.Settings.ulLeft,Plugin.Settings.ulTop,Plugin.Settings.ulWidth,Plugin.Settings.ulHeight,WS_POPUP,WS_EX_TOOLWINDOW,mod->hwndParent)) {
		MessageBox(mod->hwndParent,"Couldn't create window for "PLUGIN_DESC" plugin.","Error - "PLUGIN_DESC,MB_ICONERROR);
		// unregister the class again
		Plugin.Window.DoUnregisterClass();
		return INIT_FAIL;
	}
	// chuck the address of the module in the user data
	SetWindowLong(Plugin.Window.GetSafeHandle(),GWL_USERDATA,(long)mod);
	// create the rest of the stuff
	HDC hDC = GetDC(mod->hwndParent);
	Plugin.hMemDC = CreateCompatibleDC(hDC);
	Plugin.hBltDC = CreateCompatibleDC(hDC);
	
	Plugin.hBmpSkin = LoadBitmap(mod->hDllInstance,MAKEINTRESOURCE(IDB_BMPSKIN));
	Plugin.hMemBmp  = MakeScreenCompatibleBitmap(Plugin.hBmpSkin, STD_WIDTH, STD_HEIGHT);
	
	ReleaseDC(mod->hwndParent,hDC);
	// select the new bitmap into the dc
	Plugin.hOldBmp = (HBITMAP)SelectObject(Plugin.hMemDC,Plugin.hMemBmp);
	
	// draw on the main window
	BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin,0,0,STD_WIDTH,STD_HEIGHT,0,0);

	LPBITMAPINFO bmi = new BITMAPINFO;
	
	bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmi->bmiHeader.biBitCount = 24;
	bmi->bmiHeader.biCompression = BI_RGB;
	bmi->bmiHeader.biHeight = Plugin.rcDrawingRect.bottom - Plugin.rcDrawingRect.top;
	bmi->bmiHeader.biPlanes = 1;
	bmi->bmiHeader.biWidth = Plugin.rcDrawingRect.right - Plugin.rcDrawingRect.left;

	Plugin.hBmpDIBSection = CreateDIBSection(Plugin.hMemDC,bmi,DIB_RGB_COLORS,&Plugin.lpDIBits,NULL,0);

	delete bmi;

	if(!Plugin.hBmpDIBSection) {
		MessageBox(mod->hwndParent,"Couldn't create DIB Section for "PLUGIN_DESC" plugin.","Error - "PLUGIN_DESC,MB_ICONERROR);
		SelectObject(Plugin.hMemDC,Plugin.hOldBmp);
		DeleteObject(Plugin.hMemBmp);
		DeleteDC(Plugin.hMemDC);
		DeleteDC(Plugin.hBltDC);
		Plugin.Window.Destroy();
		UnregisterClass(g_lpszClassName,mod->hDllInstance);
		return INIT_FAIL;
	}
	
	Plugin.hOldBltBmp = (HBITMAP)SelectObject(Plugin.hBltDC,Plugin.hBmpDIBSection);

	for(int i=0;i<576;i++) {
		g_achPeakData[0][i]=0;
		g_achPeakData[1][i]=0;
		g_achDisplayData[i]=0;
		g_achScreenData[i]=0;
	}
	
	GetColourMap();

	GetObject(Plugin.hBmpDIBSection,sizeof(BITMAP),&Plugin.Bit);
	
	
	SetDoubleSize(Plugin.Window.GetSafeHandle(),(int)Plugin.Settings.bDoubleSize);

	// subclass
	WndProcOld = (void *) GetWindowLong(mod->hwndParent,GWL_WNDPROC);
	SetWindowLong(mod->hwndParent,GWL_WNDPROC,(long)SubWndProc);

	// load skin
	LoadSkin();

	// render for the first time
	OnPluginRender(mod);
	
	// show the window
	Plugin.Window.Show();
	Plugin.Window.Refresh();
	
	return INIT_SUCCESS;
}

// Called when the plugin is about to be closed.
void OnPluginQuit(struct winampVisModule* mod)
{
	// kill the effect thread if it exists
	KillUpdateThread();

	MessageBeep(MB_ICONEXCLAMATION);

	// Restore all original data and delete objects etc.
	SelectObject(Plugin.hMemDC,Plugin.hOldBmp);
	SelectObject(Plugin.hBltDC,Plugin.hOldBltBmp);
	DeleteObject(Plugin.hBmpSkin);
	DeleteObject(Plugin.hMemBmp);
	DeleteObject(Plugin.hBmpDIBSection);
	
	DeleteDC(Plugin.hMemDC);
	DeleteDC(Plugin.hBltDC);
	
	Plugin.Window.Destroy();
	Plugin.Window.DoUnregisterClass();
}

int OnPluginRender(struct winampVisModule* mod)
{

⌨️ 快捷键说明

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