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

📄 sk.c

📁 用Labwindows/CVI开发的一个程序,可以对计算机的声卡进行数据采集,并将采集数据以波形方式在软件界面上实时显示,同时进行简单的频谱分析.
💻 C
字号:
#include <cvirte.h>		
#include <userint.h>
#include "sk.h"

#include "windows.h" 
#include <ansi_c.h>
#include <utility.h>
#include <analysis.h>
#include "windowsx.h"
#include "mmsystem.h"

#define SK_READLEN 192000
#define SK_SAMPSEC 192000

struct bufpoint
{
	WAVEHDR *header;
	struct bufpoint *next;
};

struct skbc
{
	int wavi;
	int pause;
	int restart,stop;
	int running;
	double time1,time2;        
	HWAVEIN devhandle;
	WAVEHDR  *waveheader,*waveheader2; 
	WAVEFORMATEX fx;  
};

static int panelHandle;
static short buf[SK_READLEN]; 
static struct skbc me;
static struct bufpoint *bp;
static double temdata[SK_READLEN],amp[SK_READLEN],phase[SK_READLEN],df; 

int main (int argc, char *argv[])
{
	if (InitCVIRTE (0, argv, 0) == 0)
		return -1;	/* out of memory */
	if ((panelHandle = LoadPanel (0, "sk.uir", PANEL)) < 0)
		return -1;
	me.pause=0;
	me.time1=me.time2=0;
	me.restart=me.stop=me.running=0;
	DisplayPanel (panelHandle);
	SetPanelAttribute(panelHandle,ATTR_WINDOW_ZOOM,VAL_MAXIMIZE);
	
	RunUserInterface ();
	DiscardPanel (panelHandle);
	return 0;
}

void restart(int flag) //0:close application,1:restart device
{
	me.restart=1;
	while(me.restart!=2)
		Delay(0.02);
	//free buf1
	waveInUnprepareHeader(me.devhandle, me.waveheader, sizeof(WAVEHDR));
	GlobalFreePtr(me.waveheader->lpData);
	//free buf2
	waveInUnprepareHeader(me.devhandle, me.waveheader2, sizeof(WAVEHDR));
	GlobalFreePtr(me.waveheader2->lpData);
	//stop the device
	waveInStop(me.devhandle);
	me.stop=1;
	waveInReset(me.devhandle);
	waveInClose(me.devhandle); 
	me.time1=me.time2=me.running=0;
	
	if(flag)
		startCallback ( panelHandle, PANEL_COMMANDBUTTON_2, EVENT_COMMIT,NULL, 0, 0);  
	
	me.stop=0;
	me.restart=0;
	me.pause=0;
	SetCtrlVal(panelHandle,PANEL_COMMANDBUTTON_3,0);
}

int CVICALLBACK quitCallback (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	switch (event)
	{
		case EVENT_COMMIT:
			if(me.running)
				restart(0);
			
			QuitUserInterface (0);
			break;
	}
	return 0;
}

void fftcallback(short *tem,int len,double interval) //
{
	int status,i,j=2;
	
	for(i=0;i<len;i++)
		temdata[i]=tem[i];
	status=AmpPhaseSpectrum(temdata,len,DISABLE_OPTION,interval/(double)len,amp,phase,&df); 
	for(i=2;i<(len/2);i++)
	{
		if(amp[i]>amp[j])
			j=i;
	}
	DeleteGraphPlot(panelHandle,PANEL_GRAPH_2,-1,VAL_DELAYED_DRAW);
	PlotWaveform (panelHandle, PANEL_GRAPH_2, amp+2, len/2-2, VAL_DOUBLE, 1, 0, 2, df, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID,
				 VAL_CONNECTED_POINTS, VAL_BLUE);
	SetCtrlVal(panelHandle,PANEL_NUMERIC,(double)j*df);
	return ;
}

void CALLBACK waveInProc( HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
{
	int len,i;
	//short buf[SK_READLEN];
	switch(uMsg)
	{
		case MM_WIM_OPEN: //
			
			break;
		case MM_WIM_DATA:
			if(me.stop)
				return;
			if(me.restart)
			{
				me.restart++;
				return;
			}
			
			len=bp->header->dwBytesRecorded/2;
			//memcpy(buf,me.waveheader2->lpData,len);
			for(i=0;i<len;i++)
			{
				buf[i]=*(short*)(&bp->header->lpData[i*2]);
			}    
			if(len>0 && !me.pause)
			{
				DeleteGraphPlot(panelHandle,PANEL_GRAPH,-1,VAL_DELAYED_DRAW);
				PlotWaveform (panelHandle, PANEL_GRAPH, buf, len, VAL_SHORT_INTEGER, 1, 0, 0, 1, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID,
					      VAL_CONNECTED_POINTS, VAL_RED);
				
				fftcallback(buf,len,me.time1);
				
			}
			
			bp->header->dwBytesRecorded=0;
			waveInAddBuffer(me.devhandle,bp->header, sizeof(WAVEHDR)); 
			//waveInAddBuffer(me.devhandle,bp->header, sizeof(WAVEHDR));
			//bp=bp->next;
			//me.time1=Timer();
			break;
	}
		
	
}

int CVICALLBACK startCallback (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	MMRESULT ret;
	struct bufpoint *p1,*p2;
	int frequence,interval;
	double readlen;
	switch (event)
	{
		case EVENT_COMMIT:
			GetCtrlVal(panel,PANEL_RING,&frequence);
			GetCtrlVal(panel,PANEL_RING_2,&interval);
			//初始化声音格式结构体      
			switch(frequence)
			{
				case 0:
					me.fx.nSamplesPerSec=11025; 
					break;
				case 1:
					me.fx.nSamplesPerSec=22050; 
					break;
				case 2:
					me.fx.nSamplesPerSec=44100; 
					break;
				case 3:
					me.fx.nSamplesPerSec=88200; 
					break;
				case 4:
					me.fx.nSamplesPerSec=192000; 
					break;
			}
			switch(interval)
			{
				case 0:
					readlen=me.fx.nSamplesPerSec; 
					me.time1=1.0;
					break;
				case 1:
					readlen=me.fx.nSamplesPerSec/2; 
					me.time1=0.5;   
					break;
				case 2:
					readlen=me.fx.nSamplesPerSec/4; 
					me.time1=0.25;   
					break;
				case 3:
					readlen=me.fx.nSamplesPerSec/10; 
					me.time1=0.1;   
					break;
				case 4:
					readlen=me.fx.nSamplesPerSec/20; 
					me.time1=0.05;   
					break;
				case 5:
					readlen=me.fx.nSamplesPerSec/50; 
					me.time1=0.02;   
					break;
				case 6:
					readlen=me.fx.nSamplesPerSec/100; 
					me.time1=0.01;   
					break;
			}
			me.fx.wFormatTag=WAVE_FORMAT_PCM;
			me.fx.nChannels=1;
			me.fx.wBitsPerSample=16;
			me.fx.nAvgBytesPerSec=me.fx.nSamplesPerSec*me.fx.wBitsPerSample/8;
			me.fx.nBlockAlign=2;
			me.fx.cbSize=0;
			//打开声音输入设备     
			ret=waveInOpen(&me.devhandle,WAVE_MAPPER,&me.fx,(DWORD)waveInProc,(DWORD)(&me),CALLBACK_FUNCTION);
			if(ret!=MMSYSERR_NOERROR)
			{
				MessagePopup("提示","打开设备有误,不成功.");
				return 0;
			}
			//定义第一个数据缓冲区    
			me.waveheader = GlobalAllocPtr(GHND|GMEM_SHARE, sizeof(WAVEHDR));
			me.waveheader->lpData=GlobalAllocPtr(GHND|GMEM_SHARE, 192000*me.fx.wBitsPerSample/8);
			me.waveheader->dwBufferLength=readlen*me.fx.wBitsPerSample/8;
			me.waveheader->dwBytesRecorded=0;
			me.waveheader->dwUser=0;
			me.waveheader->dwFlags=0;
			me.waveheader->dwLoops=1;
			me.waveheader->lpNext=NULL;
			me.waveheader->reserved=0;
			//预备声音缓冲区,使其不会被置换到硬盘上        
			waveInPrepareHeader(me.devhandle,me.waveheader,sizeof(WAVEHDR));
			
			//定义第二个数据缓冲区  
			me.waveheader2 = GlobalAllocPtr(GHND|GMEM_SHARE, sizeof(WAVEHDR));
			me.waveheader2->lpData=GlobalAllocPtr(GHND|GMEM_SHARE, 192000*me.fx.wBitsPerSample/8);
			me.waveheader2->dwBufferLength=readlen*me.fx.wBitsPerSample/8;
			me.waveheader2->dwBytesRecorded=0;
			me.waveheader2->dwUser=0;
			me.waveheader2->dwFlags=0;
			me.waveheader2->dwLoops=1;
			me.waveheader2->lpNext=NULL;
			me.waveheader2->reserved=0;
			//预备声音缓冲区,使其不会被置换到硬盘上    
			waveInPrepareHeader(me.devhandle,me.waveheader2,sizeof(WAVEHDR));
			
			p1=(struct bufpoint*)malloc(sizeof(struct bufpoint));
			p2=(struct bufpoint*)malloc(sizeof(struct bufpoint));
			p1->header=me.waveheader;
			p2->header=me.waveheader2;
			p1->next=p2;
			p2->next=p1;
			bp=p1;
			//向声音输入设备发送缓冲区   
			waveInAddBuffer(me.devhandle,me.waveheader, sizeof(WAVEHDR));
			waveInAddBuffer(me.devhandle,me.waveheader2, sizeof(WAVEHDR));
			//启动声音输入设备    
			ret=waveInStart(me.devhandle);
			me.running=1;
			break;
	}
	return 0;
}

int CVICALLBACK pauseCallback (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	int val;
	switch (event)
	{
		case EVENT_COMMIT:
			GetCtrlVal(panel,control,&val);
			me.pause=val;
			break;
	}
	return 0;
}

int CVICALLBACK qrequenceCallback (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	int frequence,val;
	switch (event)
	{
		case EVENT_COMMIT:
			//if(me.running)
			//	restart(1);
			me.fx.nSamplesPerSec=11025;
			break;
	}
	return 0;
}

int CVICALLBACK refreshCallback (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	int interval;
	double readlen;
	switch (event)
	{
		case EVENT_VAL_CHANGED:
			GetCtrlVal(panel,PANEL_RING_2,&interval);
			switch(interval)
			{
				case 0:
					readlen=me.fx.nSamplesPerSec; 
					me.time1=1.0;   
					break;
				case 1:
					readlen=me.fx.nSamplesPerSec/2; 
					me.time1=0.5;  
					break;
				case 2:
					readlen=me.fx.nSamplesPerSec/4; 
					me.time1=0.25; 
					break;
				case 3:
					readlen=me.fx.nSamplesPerSec/10; 
					me.time1=0.1;  
					break;
				case 4:
					readlen=me.fx.nSamplesPerSec/20; 
					me.time1=0.05; 
					break;
				case 5:
					readlen=me.fx.nSamplesPerSec/50; 
					me.time1=0.02; 
					break;
				case 6:
					readlen=me.fx.nSamplesPerSec/100; 
					me.time1=0.01; 
					break;
			}
			me.waveheader->dwBufferLength=readlen*me.fx.wBitsPerSample/8; 
			me.waveheader2->dwBufferLength=readlen*me.fx.wBitsPerSample/8; 
			break;
	}
	return 0;
}

⌨️ 快捷键说明

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