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

📄 spectral.c

📁 g729 coding ipaddressing
💻 C
📖 第 1 页 / 共 2 页
字号:
	DeleteObject(SelectObject(hdc, br));
	ReleaseDC(canvas, hdc);
}

//	PAINTCANVAS  --  Refresh a display frame from its backing bitmap

static void paintCanvas(HWND canvas, HBITMAP image)
{
	if (image != NULL) {
		HDC hdc = GetDC(canvas), hdca;
		HBITMAP oe;
		RECT r;
		int width, height;

		GetClientRect(canvas, &r);
		width = r.right - r.left;
		height = r.bottom - r.top;
		hdca = CreateCompatibleDC(hdc);
		oe = SelectObject(hdca, image);
		BitBlt(hdc, r.left + 1, r.top + 1, width - 2, height - 2, hdca, 1, 1, SRCCOPY);
		SelectObject(hdca, oe);
		DeleteDC(hdca);
		ReleaseDC(canvas, hdc);
	}
}

//	CLEARBITMAP  --  Clear a backing bitmap to a constant colour

static void clearBitmap(HWND canvas, HBITMAP image, COLORREF rgb)
{
	HDC hdc = GetDC(canvas), hdca;
	HBITMAP oe;
	HBRUSH br;
	HPEN pen;
	RECT r;

	hdca = CreateCompatibleDC(hdc);
	GetClientRect(canvas, &r);
	br = CreateSolidBrush(rgb);
	br = SelectObject(hdca, br);
	pen = CreatePen(PS_SOLID, 1, rgb);
	pen = SelectObject(hdca, pen);
	oe = SelectObject(hdca, image);
	Rectangle(hdca, r.left, r.top, r.right, r.bottom);
	DeleteObject(SelectObject(hdca, pen));
	DeleteObject(SelectObject(hdca, br));
	SelectObject(hdca, oe);
	DeleteDC(hdca);
	ReleaseDC(canvas, hdc);
}

//	SPECTRALDLGPROC  --  Spectral display dialogue procedure

BOOL CALLBACK spectralDlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
    switch (nMessage) {

    	case WM_INITDIALOG:
			hDlgSpectral = hwnd;
			samps_in_buffer = 0;
			epposx = sgposx = 0;
			easel = weasel = NULL;
			samples = (short *) malloc(fftsize * sizeof(short));
			if (samples != NULL) {
				pspectrum = (double *) malloc(nbands * sizeof(double));
				if (pspectrum == NULL) {
					free(samples);
					samples = NULL;
				} else {
					sourceSpectrum = malloc(fftsize);
					if (sourceSpectrum == NULL) {
						free(samples);
						samples = NULL;
						free(pspectrum);
						pspectrum = NULL;						
					}
				}
			}
			CheckDlgButton(hwnd, IDC_SPEC_REALTIME, spectrumBarGraph);
			CheckDlgButton(hwnd, IDC_SPEC_VOICEPRINT, spectrumVoicePrint);
			CheckDlgButton(hwnd, IDC_SPEC_DISABLE, !(spectrumBarGraph || spectrumVoicePrint));

			CheckDlgButton(hwnd, IDC_SPEC_TRANSMIT, spectrumTransmitOnly);
			CheckDlgButton(hwnd, IDC_SPEC_RECEIVE, spectrumReceiveOnly);
			CheckDlgButton(hwnd, IDC_SPEC_BOTH, !(spectrumTransmitOnly || spectrumReceiveOnly));

			CheckDlgButton(hwnd, IDC_SPEC_ENV_RMS, !spectrumMaxEnergy);
			CheckDlgButton(hwnd, IDC_SPEC_ENV_MAX, spectrumMaxEnergy);

			{
				HWND canvas = GetDlgItem(hwnd, IDC_SPEC_CHART);
				HDC hdc = GetDC(canvas);
				int width, height;
				RECT r;

				GetClientRect(canvas, &r);
				width = r.right - r.left;
				height = r.bottom - r.top;
				easel = CreateCompatibleBitmap(hdc, width, height);
				ReleaseDC(canvas, hdc);
				clearBitmap(canvas, easel, RGB(128, 128, 128));

				canvas = GetDlgItem(hwnd, IDC_SPEC_ENVELOPE);
				hdc = GetDC(canvas);
				GetClientRect(canvas, &r);
				width = r.right - r.left;
				height = r.bottom - r.top;
				weasel = CreateCompatibleBitmap(hdc, width, height);
				ReleaseDC(canvas, hdc);
				clearBitmap(canvas, weasel, RGB(0, 0, 0));
			}
			spectrumChanged = TRUE;
	    	return TRUE;
	    	
	    case WM_CLOSE:
	    	DestroyWindow(hwnd);
	    	return TRUE;
	    	
	    case WM_DESTROY:
			if (samples != NULL) {
				free(samples);
				samples = NULL;
			}
			if (sourceSpectrum != NULL) {
				free(sourceSpectrum);
				sourceSpectrum = NULL;
			}
			if (pspectrum != NULL) {
				free(pspectrum);
				pspectrum = NULL;
			}
			if (easel != NULL) {
				DeleteObject(easel);
				easel = NULL;
			}
			if (weasel != NULL) {
				DeleteObject(weasel);
				weasel = NULL;
			}
			spectrumEnd();
	    	hDlgSpectral = NULL;
	    	return 0;

		case WM_PAINT:
			InvalidateRect(GetDlgItem(hwnd, IDC_SPEC_CHART), NULL, FALSE);
			InvalidateRect(GetDlgItem(hwnd, IDC_SPEC_ENVELOPE), NULL, FALSE);
			paintCanvas(GetDlgItem(hwnd, IDC_SPEC_CHART), easel);
			paintCanvas(GetDlgItem(hwnd, IDC_SPEC_ENVELOPE), weasel);
			break;

		case WM_UPDATE_SPECTRUM:
#ifdef _DEBUG
			{	char s[20];

				sprintf(s, "P=%.2f  E=%d", escale, aEnergy);
				SetDlgItemText(hwnd, IDC_SPEC_SCALE, s);
			}
#endif
			paintEnergy(GetDlgItem(hwnd, IDC_SPEC_ENVELOPE));
			paintSpectrum(GetDlgItem(hwnd, IDC_SPEC_CHART));
			paintCanvas(GetDlgItem(hwnd, IDC_SPEC_CHART), easel);
			paintCanvas(GetDlgItem(hwnd, IDC_SPEC_ENVELOPE), weasel);
			break;

        case WM_COMMAND:
		    switch ((short) WM_COMMAND_ID(wParam)) {

		    	case IDOK:
		        	PostMessage(hwnd, WM_CLOSE, 0, 0L);
		        	break;
		        	
                case ID_HELP:
                	displayHelpTopic(IDS_HELP_SPECTRUM);
                	break;

				case IDC_SPEC_REALTIME:
				case IDC_SPEC_VOICEPRINT:
				case IDC_SPEC_DISABLE:
					spectrumBarGraph = IsDlgButtonChecked(hwnd, IDC_SPEC_REALTIME);
					spectrumVoicePrint = IsDlgButtonChecked(hwnd, IDC_SPEC_VOICEPRINT);
					spectrumChanged = TRUE;
					clearCanvas(GetDlgItem(hwnd, IDC_SPEC_CHART), RGB(128, 128, 128));
					sgposx = epposx;
					disableShown = FALSE;
					if (!(spectrumBarGraph || spectrumVoicePrint)) {
						paintSpectrum(GetDlgItem(hwnd, IDC_SPEC_CHART));
					}
					break;

				case IDC_SPEC_TRANSMIT:
				case IDC_SPEC_RECEIVE:
				case IDC_SPEC_BOTH:
					spectrumTransmitOnly = IsDlgButtonChecked(hwnd, IDC_SPEC_TRANSMIT);
					spectrumReceiveOnly = IsDlgButtonChecked(hwnd, IDC_SPEC_RECEIVE);
					break;

				case IDC_SPEC_ENV_RMS:
				case IDC_SPEC_ENV_MAX:
					spectrumMaxEnergy = IsDlgButtonChecked(hwnd, IDC_SPEC_ENV_MAX);
					break;
			}
    }
    return FALSE;
}

//	SPECTRALDIALOGUE  --  Spectral display dialogue

VOID spectralDialogue(HWND hwndParent)
{
	if (hDlgSpectral == NULL) {
		hDlgSpectral = CreateDialog(hInst, MAKEINTRESOURCE(IDD_SPECTRUM),
    					hwndParent, spectralDlgProc);
	}
}

/*	ENERGY  --  Calculate RMS and maximum energy of samples in this
				buffer for envelope display.  */

static void energy(short *samples, int nsamples, double *rms, double *emax)
{
	long i;
	double alevel = 0, mlevel = 0;

	for (i = 0; i < nsamples; i++) {
		int samp = samples[i];
		
		if (samp < 0) {
			if (samp == -32768) {
				samp = -32767;
			}
			samp = -samp;
		}
		alevel += ((double) samp) * samp;
		if (samp > mlevel) {
			mlevel = samp;
		}
	}
	alevel = sqrt(alevel / nsamples);

#ifdef _DEBUG
	aEnergy = (int) alevel;
#endif
	if (alevel < noiseFloor) {
		alevel = 0.0;
	} else {
		alevel -= noiseFloor;
	}
	if (logEnergy) {
		*rms = ((log(((double) alevel) + M_E) - 1) / (log(32767.0 + M_E) - 1));
		*emax = ((log(((double) mlevel) + M_E) - 1) / (log(32767.0 + M_E) - 1));
	} else {
		*rms = alevel / 32767.0;
		*emax = mlevel / 32767.0;
	}
}

/*	STORESAMPLE  --  Store next sample into buffer, updating spectrum
					 when it's full.  */

static void storeSample(short samp, BOOL isInput)
{
	sourceSpectrum[samps_in_buffer] = isInput;
	samples[samps_in_buffer++] = samp;
	if (samps_in_buffer >= fftsize) {
		DWORD tc = GetTickCount();

		//	Update average energy (0 to 1) of samples in buffer

		energy(samples, samps_in_buffer, &cEnergy, &mEnergy);
		ceColour = sourceSpectrum[samps_in_buffer -1] ? RGB(0, 0, 255) : RGB(0, 255, 0);

		//	Update power spectrum if it's being displayed

		if (spectrumBarGraph || spectrumVoicePrint) {
			pscale = spectrum(samples, samps_in_buffer, pspectrum, nbands, 0.0);
			if (pscale > escale) {
				//	New maximum power--set as top of scale
				escale = pscale;
			} else {
				/*	Otherwise exponentially smooth the scale factor
					for a smooth adaptive gain adjustment.  */
				escale = escale + PSMOOTH * (pscale - escale);
			}
		}

		samps_in_buffer = 0;
		if (!paintingSpectrum && ((nextSpectrumTime == 0) || (tc < nextSpectrumTime) ||
								   (tc > (nextSpectrumTime + SPECTRUM_INTERVAL)))) {
			nextSpectrumTime = tc;
			PostMessage(hDlgSpectral, WM_UPDATE_SPECTRUM, 0, 0);
		}
	}
}

/*	SPECTRUMUPDATE  --  Receive latest batch of audio samples and
						update the spectrum display, if necessary.
						If align == 0 and bytesec == 8000, the samples
						are assumed to already be in mu-law format.  */

void spectrumUpdate(LPSTR buffer, WORD buflen, DWORD channels,
					DWORD rate, DWORD bytesec, WORD align, BOOL isInput)
{

	//	Discard buffer if we're not monitoring this direction

	if ((isInput && spectrumTransmitOnly) ||
		((!isInput) && spectrumReceiveOnly)) {
			return;
	}

	/*	The job of the following code is to transform, if necessary,
		the received samples into 16 bit signed form and add them to
		the FFT array.  */

	if ((hDlgSpectral != NULL) && (samples != NULL)) {
		if (align == 2) {
			int i;
			
			for (i = 0; i < buflen / align; i++) {
				storeSample((short) (((WORD FAR *) buffer)[i]), isInput);
			} 
		} else {	// align == 1 or align == 0
			int i;
			
			for (i = 0; i < buflen; i++) {
				/*	This looks inefficient--it should just transform the 8 bit
					sample directly to 16 bit, but after all it's only two
					array accesses, which are trivial compared to the number
					of FFTs we're doing here.  */
				storeSample(audio_u2s((isInput || (align == 0)) ? (((BYTE FAR *) buffer)[i]) : audio_c2u((((BYTE FAR *) buffer)[i]))), isInput);
			} 
		}
	}
}											

⌨️ 快捷键说明

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