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

📄 vis_spectrum.cpp

📁 mp3 频谱分析源码, mp3播放器开发必备源码,
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	LPBYTE lpByte = LPBYTE(Plugin.lpDIBits);
	// draw the background grid (this also serves to "erase" what was on the
	// bitmap before)

	// ok there's probably a more efficient and better way of doing this.
	for(int i=0;i<Plugin.Bit.bmWidth;i++) {
		for(int j=0;j<Plugin.Bit.bmHeight;j++) {
			if(((i-1)%Plugin.Settings.uchGridWidth <= (Plugin.Settings.uchGridWidth - (Plugin.Settings.uchGridHorzGap+1)))/*i%Plugin.Settings.uchGridWidth!=0*/ && j%(Plugin.Settings.uchGridVertGap+1)==0 && Plugin.Settings.bWantGrid && i!=0){
				lpByte[((Plugin.Bit.bmWidthBytes*j)+i*3)]  = unsigned char((g_ulGridColour >> 16) & 0xFF) /*0x42*/;
				lpByte[((Plugin.Bit.bmWidthBytes*j)+i*3)+1]= unsigned char((g_ulGridColour >> 8 ) & 0xFF)/*0x41*/;
				lpByte[((Plugin.Bit.bmWidthBytes*j)+i*3)+2]= unsigned char((g_ulGridColour >> 0 ) & 0xFF)/*0x00*/;
			}
			else { 
				lpByte[((Plugin.Bit.bmWidthBytes*j)+i*3)]  = unsigned char((g_ulBackColour >> 16) & 0xFF);
				lpByte[((Plugin.Bit.bmWidthBytes*j)+i*3)+1]= unsigned char((g_ulBackColour >> 8 ) & 0xFF);
				lpByte[((Plugin.Bit.bmWidthBytes*j)+i*3)+2]= unsigned char((g_ulBackColour >> 0 ) & 0xFF);
			}
		}
	}
	
	for(i=0;i<256 / Plugin.Settings.uchBarWidth;i++) {
		// first test if we want to remap the input levels and
		// do it accordingly.
		if(Plugin.Settings.bRemap) 
			g_achDisplayData[i] = g_achLevelMap[mod->spectrumData[0][i]];	
		else
			g_achDisplayData[i] = mod->spectrumData[0][i];
		
		// If the new data is greater than the current data....
		if(g_achDisplayData[i] > g_achScreenData[i]) {
				
				if(Plugin.Settings.bFilter) {
					// with level filter, this attempts to smooth
					// the level of the bars and prevent jumping
					int nIncrease = g_achDisplayData[i] - g_achScreenData[i];
					if(nIncrease > 0) nIncrease /= 2;
					if(nIncrease > Plugin.Settings.uchMaxIncrease) nIncrease = Plugin.Settings.uchMaxIncrease;
					// Add the increase to the bar
					if(g_achScreenData[i]+nIncrease<=255) 
						g_achScreenData[i]+=nIncrease;
					else
						g_achScreenData[i]=255;
				}
				else {
					// no level filter so we just use the max and min rise/fall to
					// control the actual speed of the bars.
					int nIncrease = g_achDisplayData[i] - g_achScreenData[i];

					if(nIncrease < Plugin.Settings.uchMaxIncrease) 
						g_achScreenData[i] +=nIncrease;//g_achDisplayData[i];
					else {
						if(g_achScreenData[i] + Plugin.Settings.uchMaxIncrease <= 255) 
							g_achScreenData[i] += Plugin.Settings.uchMaxIncrease;
						else
							g_achScreenData[i] = 255;
					}
				}
				// put the peak at the top of the bar if it is higher than
				// the peak currently is.
				if(g_achPeakData[0][i]<g_achScreenData[i]) {
					g_achPeakData[0][i] = g_achScreenData[i];
					// 1 in this case is used for the delay which
					// is why it is measured in frames.
					g_achPeakData[1][i] = Plugin.Settings.uchPeakDelay;
				}
			}
			else {
				// the value is less
				if(Plugin.Settings.bFilter) {
					// with the filter
					int nDecrease =  g_achScreenData[i] - g_achDisplayData[i];
					if(nDecrease>0) nDecrease/=16;
					// set to max decrease
					if (nDecrease > Plugin.Settings.uchMaxDecrease) nDecrease = Plugin.Settings.uchMaxDecrease;
					// because of division above, the level will never go below 16.
					// this means if the level is 16 or less, we manually set the 
					// decrease (tacky i know but it works :)
					// and we now have magic numbers
					if(g_achScreenData[i]<=16) {
						nDecrease = Plugin.Settings.uchDefaultDrop;
					}
					if(g_achScreenData[i] - nDecrease >= 0) {
						g_achScreenData[i] -=nDecrease;
					}
					else {
						g_achScreenData[i] = 0;
					}
				}
				else {
					// without filter
					int nDecrease = g_achScreenData[i] - g_achDisplayData[i];
					if(nDecrease < Plugin.Settings.uchMaxDecrease) 
						g_achScreenData[i] -= nDecrease;
					else {
						if(g_achScreenData[i] - Plugin.Settings.uchMaxDecrease >= 0) 
							g_achScreenData[i] -= Plugin.Settings.uchMaxDecrease;
						else
							g_achScreenData[i] = 0;
					}
				}
			}

			if(g_achPeakData[1][i]==0) {
				if(g_achPeakData[0][i]-Plugin.Settings.uchPeakDrop>=0) {
					if(g_achPeakData[0][i]-Plugin.Settings.uchPeakDrop>=g_achScreenData[i])
						g_achPeakData[0][i]-=Plugin.Settings.uchPeakDrop;
					else
						g_achPeakData[0][i] = g_achScreenData[i];
				}
				else {
					g_achPeakData[0][i]=0;
				}
			}
			else {
				g_achPeakData[1][i]--;
			}
	
	} 
	
	// draw the bars then the peaks
	for(i=0;i<(256 / Plugin.Settings.uchBarWidth );i++) {
		if(Plugin.Settings.bWantBars) {
			int nTo = g_achScreenData[i]/3;
			for(int j=nTo-1;j>=0;j--) {
				for(int k=0;k<Plugin.Settings.uchBarWidth - (Plugin.Settings.uchBarHorzGap);k++) {
					if(j%(Plugin.Settings.uchBarVertGap+1)==0) {
						
						switch(Plugin.Settings.uchBarStyle) {
						default:
						case 0:
							// Normal Style
							lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)] = unsigned char((g_ulColourMap[255-(j*3)] >> 16) & 0xFF);
							lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+1] = unsigned char((g_ulColourMap[255-(j*3)] >> 8) & 0xFF);
							lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+2] = unsigned char((g_ulColourMap[255-(j*3)] >> 0) & 0xFF);
							break;
						case 1:

							// Fire Style
							lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)] = unsigned char((g_ulColourMap[(nTo-j)*3]>>16) & 0xFF);
							lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+1] = unsigned char((g_ulColourMap[(nTo-j)*3]>>8) & 0xFF);
							lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+2] = unsigned char((g_ulColourMap[(nTo-j)*3]>>0) & 0xFF);
							break;
						case 2:
							// Line Style
							lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)] = unsigned char((g_ulColourMap[255-(nTo*3)]>>16) & 0xFF);
							lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+1] = unsigned char((g_ulColourMap[255-(nTo*3)]>>8) & 0xFF);
							lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+2] = unsigned char((g_ulColourMap[255-(nTo*3)]>>0) & 0xFF);
							break;
						}
					}
				}
			}
		}
		// draw the peaks
		if(Plugin.Settings.bWantPeaks) {
			int nPeak = g_achPeakData[0][i]/3;
			for(int k=0;k<Plugin.Settings.uchBarWidth - (Plugin.Settings.uchBarHorzGap);k++) {
				lpByte[((Plugin.Bit.bmWidthBytes * nPeak ) + (((i*Plugin.Settings.uchBarWidth)+k)+1)*3)] = unsigned char((g_ulPeakColour >> 16) & 0xFF);
				lpByte[((Plugin.Bit.bmWidthBytes * nPeak ) + (((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+1]= unsigned char((g_ulPeakColour >> 8) & 0xFF);
				lpByte[((Plugin.Bit.bmWidthBytes * nPeak ) + (((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+2] = unsigned char((g_ulPeakColour >> 0) & 0xFF);
			}
		}
	}
	
	// update the dc, i do it like this to make double size
	// easier to cope with.
	BitBlt(Plugin.hMemDC,Plugin.rcDrawingRect.left, Plugin.rcDrawingRect.top, Plugin.rcDrawingRect.right - Plugin.rcDrawingRect.left, Plugin.rcDrawingRect.bottom - Plugin.rcDrawingRect.top, Plugin.hBltDC,0,0,SRCCOPY);
	
	HDC hDC = GetDC(Plugin.hWndMain);
	
	if(!Plugin.Settings.bDoubleSize) {
		BitBlt(hDC,Plugin.rcDrawingRect.left,Plugin.rcDrawingRect.top,Plugin.rcDrawingRect.right - Plugin.rcDrawingRect.left,
			Plugin.rcDrawingRect.bottom - Plugin.rcDrawingRect.top ,Plugin.hMemDC,Plugin.rcDrawingRect.left,Plugin.rcDrawingRect.top,SRCCOPY);
	}
	else {
		StretchBlt(
			hDC,
			(Plugin.rcDrawingRect.left*2),(Plugin.rcDrawingRect.top*2),
			((Plugin.rcDrawingRect.right - Plugin.rcDrawingRect.left)*2),
			((Plugin.rcDrawingRect.bottom - Plugin.rcDrawingRect.top)*2),
			Plugin.hMemDC,Plugin.rcDrawingRect.left,Plugin.rcDrawingRect.top,
			(Plugin.rcDrawingRect.right - Plugin.rcDrawingRect.left),
			(Plugin.rcDrawingRect.bottom - Plugin.rcDrawingRect.top),SRCCOPY
		);
	
	}
	
	ReleaseDC(Plugin.hWndMain,hDC);
	return 0;
}

// the main window procedure.
LRESULT CALLBACK VisWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg) {
	case WM_CREATE:
		Plugin.bMouseDown = false;
		Plugin.hWndMain = hWnd;
		SetWindowLong(hWnd,GWL_STYLE,GetWindowLong(hWnd,GWL_STYLE)&~(WS_CAPTION));
		break;
	case WM_ACTIVATE:
		if(Plugin.Settings.bDimTitleBar) {
		switch(LOWORD(wParam)) {
				case WA_ACTIVE:
				case WA_CLICKACTIVE:{
					// set window active flag and draw active title bar
					//BitmapBlt(Plugin.hMemDC,Plugin.hBmpTitleActive,0,0);
					BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, 0, 0, 275, 14, 0, 116);
					Plugin.bWindowActive = true;
					UpdateRect(&Plugin.rcTitleBar,hWnd);
					break;
				}
				case WA_INACTIVE: 
					// set window active flag to false and draw the inactive
					// title bar
					Plugin.bWindowActive = false;
					BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, 0, 0, 275, 14, 0, 130);
					UpdateRect(&Plugin.rcTitleBar,hWnd);
					break;
			}	
		}
		break;
	case WM_USER:
	{
		// user functions
		switch(lParam) {
		case USR_REDRAWWINDOW: 
		{
			RECT rRect;
			GetWindowRect(hWnd,&rRect);
			HDC hDC = GetDC(hWnd);
			BitBlt(hDC,0,0,rRect.right-rRect.left,rRect.bottom-rRect.top,Plugin.hMemDC,0,0,SRCCOPY);
			ReleaseDC(hWnd,hDC);
			break;
		}
		case USR_HIDE:
			ShowWindow(hWnd,SW_HIDE);
			break;
		case USR_SHOW:
			ShowWindow(hWnd,SW_SHOW);
			break;
		case USR_DOUBLESIZE:
		{	
			switch(wParam) {
			case 0:
				// doublesize off
				Plugin.Settings.bDoubleSize = false;
				Plugin.Window.SetWindowPos(NULL,0,0,STD_WIDTH,STD_HEIGHT,SWP_NOMOVE|SWP_NOZORDER);
				break;
			default:
				// doublesize on
				Plugin.Window.SetWindowPos(NULL,0,0,STD_WIDTH*2,STD_HEIGHT*2,SWP_NOMOVE|SWP_NOZORDER);
				Plugin.Settings.bDoubleSize = true;
				break;
			}
			break;
		}
		case USR_CLOSETHREAD:
			KillUpdateThread();
			break;
		default:
			break;
		}
		break;
	}
	case WM_LBUTTONDOWN:
	{
		// get and set up the point structure
		POINT pt;
		pt.x = GET_X_LPARAM(lParam);
		pt.y = GET_Y_LPARAM(lParam);
		// start testing the coordinates, have to test the close
		// button before the title rect as it is inside it.
		if(PointInRect(&Plugin.rcQuitButton,pt)) {
			// if the mouse is on it make it look active
			BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, Plugin.rcQuitButton.left, Plugin.rcQuitButton.top, 9, 9, 9, 144);
			// and update the area to the screen
			UpdateRect(&Plugin.rcQuitButton,hWnd);
			SetCapture(hWnd);
			Plugin.bMouseDown = true;
		}
		else if(PointInRect(&Plugin.rcTitleBar,pt)) {
			// this fools the thing into believing that we
			// are actually clicking on the caption, and the
			// effect of this is that you get automatic window
			// moving which is smooth. It also enables the window
			// to have just the frame dragged when show window
			// contents is off.
			PostMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,(LPARAM)&pt);
		}
		else {
			// set mouse down to true
			Plugin.bMouseDown = true;
			// and capture the mouse
			SetCapture(hWnd);
		}
		break;
	}
	case WM_LBUTTONUP:
	{
		ReleaseCapture();
		// set mouse down flag to false
		Plugin.bMouseDown = false;
		// get x,y coords
		POINT pt;
		pt.x = GET_X_LPARAM(lParam);
		pt.y = GET_Y_LPARAM(lParam);
		// if over exit button, close
		if(PointInRect(&Plugin.rcQuitButton,pt)) SendMessage(hWnd,WM_CLOSE,0,0);
		// draw the quit button up or it may get stuck
		BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, Plugin.rcQuitButton.left, Plugin.rcQuitButton.top, 9, 9, 0, 144);
		UpdateRect(&Plugin.rcQuitButton,hWnd);
		break;
	}
	case WM_RBUTTONUP:
	{
		// if the mouse is in the drawing area, pop up our own menu,
		// otherwise, popup the winamp menu
		POINT pt;
		pt.x = GET_X_LPARAM(lParam);
		pt.y = GET_Y_LPARAM(lParam);
		// check that the mouse is in the rectangle of the drawing
		// area
		if(PointInRect(&Plugin.rcDrawingRect,pt)) {
			// show the popupmenu
			HMENU hMenu = LoadMenu((HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),MAKEINTRESOURCE(IDR_MAINMENU));
			HMENU hSub = GetSubMenu(hMenu,0);
			if(g_bAboutActive) EnableMenuItem(hSub,0,MF_BYPOSITION|MF_DISABLED|MF_GRAYED);
			GetCursorPos(&pt);
			TrackPopupMenu(hSub,0,pt.x,pt.y,0,hWnd,NULL);
			DestroyMenu(hMenu);
		}
		else {
			// ask winamp to display its own menu
			PostMessage(Plugin.hWndParent,uMsg,wParam,lParam);
		}
		break;
	}
	case WM_MOUSEMOVE:
	{
		if(Plugin.bMouseDown) {
			if(Plugin.bWindowActive) {
				POINT pts;
				pts.x = GET_X_LPARAM(lParam);
				pts.y = GET_Y_LPARAM(lParam);
				// handle the quit button
				if(PointInRect(&Plugin.rcQuitButton,pts)) {
					BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, Plugin.rcQuitButton.left, Plugin.rcQuitButton.top, 9, 9, 9, 144);	
					UpdateRect(&Plugin.rcQuitButton,hWnd);	
				}
				else {
					BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, Plugin.rcQuitButton.left, Plugin.rcQuitButton.top, 9, 9, 0, 144);				
					UpdateRect(&Plugin.rcQuitButton,hWnd);	
				}
			}
		}
		break;
	}
	case WM_WINDOWPOSCHANGING:
	{
		if(Plugin.Settings.bSnapWindow) {
			LPWINDOWPOS lpWndPos = (LPWINDOWPOS)lParam;
			// brand new docking code that works properly (yay)
			winamp_dock(hWnd,&lpWndPos->x,&lpWndPos->y,Plugin.Settings.ulWindowSnap);
			break;
		}
	}

⌨️ 快捷键说明

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