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

📄 winsnd2.c

📁 基于osip、eXosip、speex、ffmpeg的VoIP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (mr != MMSYSERR_NOERROR){		ms_error("waveInReset() error");		return ;	}	for(i=0;i<WINSND_NBUFS;++i){		WAVEHDR *hdr=&d->hdrs_read[i];		if (hdr->dwFlags & WHDR_PREPARED)		{			mr = waveInUnprepareHeader(d->indev,hdr,sizeof (*hdr));			if (mr != MMSYSERR_NOERROR){				ms_error("waveInUnPrepareHeader() error");			}		}	}	mr = waveInClose(d->indev);	if (mr != MMSYSERR_NOERROR){		ms_error("waveInClose() error");		return ;	}	ms_message("Shutting down sound device (playing: %i) (input-output: %i) (notplayed: %i)", d->nbufs_playing, d->stat_input - d->stat_output, d->stat_notplayed);	flushq(&d->rq,0);}static void winsnd_read_process(MSFilter *f){	WinSnd *d=(WinSnd*)f->data;	mblk_t *m;	int i;	ms_mutex_lock(&d->mutex);	while((m=getq(&d->rq))!=NULL){		ms_queue_put(f->outputs[0],m);	}	ms_mutex_unlock(&d->mutex);	for(i=0;i<WINSND_NBUFS;++i){		WAVEHDR *hdr=&d->hdrs_read[i];		if (hdr->dwUser==0) {			MMRESULT mr;			mr=waveInUnprepareHeader(d->indev,hdr,sizeof(*hdr));			if (mr!=MMSYSERR_NOERROR)				ms_warning("winsnd_read_process: Fail to unprepare header!");			add_input_buffer(d,hdr,hdr->dwBufferLength);		}	}}static void CALLBACKwrite_callback(HWAVEOUT outdev, UINT uMsg, DWORD dwInstance,                 DWORD dwParam1, DWORD dwParam2){	WAVEHDR *hdr=(WAVEHDR *) dwParam1;	WinSnd *d=(WinSnd*)dwInstance;		switch (uMsg){		case WOM_OPEN:			break;		case WOM_CLOSE:		case WOM_DONE:			if (hdr){				d->nbufs_playing--;			}			if (d->stat_output==0)			{				d->stat_input=1; /* reset */				d->stat_notplayed=0;			}			d->stat_output++;		break;	}}static void winsnd_write_preprocess(MSFilter *f){	WinSnd *d=(WinSnd*)f->data;	MMRESULT mr;	DWORD dwFlag;	int i;	d->stat_input=0;	d->stat_output=0;	d->stat_notplayed=0;	d->stat_minimumbuffer=WINSND_MINIMUMBUFFER;	winsnd_apply_settings(d);	/* Init Microphone device */	dwFlag = CALLBACK_FUNCTION;	if (d->dev_id != WAVE_MAPPER)		dwFlag = WAVE_MAPPED | CALLBACK_FUNCTION;	mr = waveOutOpen (&d->outdev, d->dev_id, &d->wfx,	            (DWORD) write_callback, (DWORD)d, dwFlag);	if (mr != MMSYSERR_NOERROR)	{		ms_error("Failed to open windows sound device %i. (waveOutOpen:0x%i)",d->dev_id, mr);		mr = waveOutOpen (&d->outdev, WAVE_MAPPER, &d->wfx,					(DWORD) write_callback, (DWORD)d, CALLBACK_FUNCTION);		if (mr != MMSYSERR_NOERROR)		{			ms_error("Failed to open windows sound device %i. (waveOutOpen:0x%i)",d->dev_id, mr);			d->outdev=NULL;			return ;		}	}	for(i=0;i<WINSND_OUT_NBUFS;++i){		WAVEHDR *hdr=&d->hdrs_write[i];		hdr->dwFlags=0;		hdr->dwUser=0;	}}static void winsnd_write_postprocess(MSFilter *f){	WinSnd *d=(WinSnd*)f->data;	MMRESULT mr;	int i;	if (d->outdev==NULL) return;	mr=waveOutReset(d->outdev);	if (mr != MMSYSERR_NOERROR){		ms_error("waveOutReset() error");		return ;	}	for(i=0;i<WINSND_OUT_NBUFS;++i){		WAVEHDR *hdr=&d->hdrs_write[i];		mblk_t *old;		if (hdr->dwFlags & WHDR_DONE){			mr=waveOutUnprepareHeader(d->outdev,hdr,sizeof(*hdr));			if (mr != MMSYSERR_NOERROR){				ms_error("waveOutUnprepareHeader error");			}			old=(mblk_t*)hdr->dwUser;			if (old) freemsg(old);			hdr->dwUser=0;		}	}	mr=waveOutClose(d->outdev);	if (mr != MMSYSERR_NOERROR){		ms_error("waveOutClose() error");		return ;	}	ms_message("Shutting down sound device (playing: %i) (d->write_rq.q_mcount=%i) (input-output: %i) (notplayed: %i)", d->nbufs_playing, d->write_rq.q_mcount, d->stat_input - d->stat_output, d->stat_notplayed);	flushq(&d->write_rq,0);	d->ready=0;	d->workaround=0;#ifndef DISABLE_SPEEX	if (d->pst!=NULL)	    speex_preprocess_state_destroy(d->pst);	d->pst=NULL;	d->pst_frame_size=0;#endif}static void winsnd_write_process(MSFilter *f){	WinSnd *d=(WinSnd*)f->data;	mblk_t *m,*old;	MMRESULT mr;	int i;	int discarded=0;	int possible_size=0;	if (d->outdev==NULL) {		ms_queue_flush(f->inputs[0]);		return;	}	while((m=ms_queue_get(f->inputs[0]))!=NULL){		possible_size = msgdsize(m);#ifndef DISABLE_SPEEX		if (d->pst_frame_size==0)		{			d->pst_frame_size=possible_size;			d->pst = speex_preprocess_state_init(d->pst_frame_size/2, d->wfx.nSamplesPerSec);			if (d->pst!=NULL) {				float f;				i=1;				speex_preprocess_ctl(d->pst, SPEEX_PREPROCESS_SET_VAD, &i);				i=0;				speex_preprocess_ctl(d->pst, SPEEX_PREPROCESS_SET_DENOISE, &i);				i=0;				speex_preprocess_ctl(d->pst, SPEEX_PREPROCESS_SET_AGC, &i);				f=8000;				speex_preprocess_ctl(d->pst, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f);				i=0;				speex_preprocess_ctl(d->pst, SPEEX_PREPROCESS_SET_DEREVERB, &i);			}		}#endif		putq(&d->write_rq,m);	}#ifdef AMD_HACK	/* too many sound card are crappy on windows... */	d->stat_minimumbuffer=15;  if (d->wfx.nSamplesPerSec>=32000) /* better results for high rates */  	d->stat_minimumbuffer=8;#endif  if (d->wfx.nSamplesPerSec>=32000) /* better results for high rates */  {	  if (d->nbufs_playing+d->write_rq.q_mcount<4)	  {		  d->ready=0;	  }  }  else  {	  if (d->nbufs_playing+d->write_rq.q_mcount<7)	  {		  d->ready=0;	  }  }#if defined(WCE_OPTICON_WORKAROUND)	if (d->workaround==0)	{		d->workaround=1;		Sleep(WCE_OPTICON_WORKAROUND);	}#endif	while((m=peekq(&d->write_rq))!=NULL){#ifndef DISABLE_SPEEX		int vad=1;		if (d->pst!=NULL && msgdsize(m)==d->pst_frame_size && d->pst_frame_size<=4096)		{			char tmp[4096];			memcpy(tmp, m->b_rptr, msgdsize(m));			vad = speex_preprocess(d->pst, (short*)tmp, NULL);			if (d->ready==0)			{				if (vad==0)				{					int missing;          missing = 10 - d->write_rq.q_mcount - d->nbufs_playing;          if (d->wfx.nSamplesPerSec>=32000) /* better results for high rates */            missing = 6 - d->write_rq.q_mcount - d->nbufs_playing;		      ms_message("WINSND trouble: inserting %i silence", missing);					while(missing>0)					{						old=dupb(m);						putq(&d->write_rq,old);						missing--;					}				}				d->ready=1;			}		}#else		if (d->ready==0)		{      int missing;			missing = 10 - d->write_rq.q_mcount - d->nbufs_playing;      if (d->wfx.nSamplesPerSec>=32000) /* better results for high rates */  			missing = 6 - d->write_rq.q_mcount - d->nbufs_playing;			ms_message("WINSND trouble: inserting %i silence", missing);			while(missing>0)			{				old=dupb(m);				putq(&d->write_rq,old);				missing--;			}			d->ready=1;		}#endif		for(i=0;i<d->stat_minimumbuffer;++i){			WAVEHDR *hdr=&d->hdrs_write[i];			if (hdr->dwFlags & WHDR_DONE){				old=(mblk_t*)hdr->dwUser;				mr=waveOutUnprepareHeader(d->outdev,hdr,sizeof(*hdr));				if (mr != MMSYSERR_NOERROR){					ms_error("waveOutUnprepareHeader error");				}				freemsg(old);				hdr->dwUser=0;			}			if (hdr->dwUser==0){				hdr->lpData=(LPSTR)m->b_rptr;				hdr->dwBufferLength=msgdsize(m);				hdr->dwFlags = 0;			    hdr->dwUser = (DWORD)m;			    mr = waveOutPrepareHeader(d->outdev,hdr,sizeof(*hdr));			    if (mr != MMSYSERR_NOERROR){					ms_error("waveOutPrepareHeader() error");					getq(&d->write_rq);					freemsg(m);					discarded++;					d->stat_notplayed++;					break;				}				mr=waveOutWrite(d->outdev,hdr,sizeof(*hdr));				if (mr != MMSYSERR_NOERROR){					ms_error("waveOutWrite() error");					getq(&d->write_rq);					freemsg(m);					discarded++;					d->stat_notplayed++;					break;				}else {					getq(&d->write_rq);					d->nbufs_playing++;					/* ms_debug("waveOutWrite() done"); */				}				break;			}		}		if (i==d->stat_minimumbuffer){			//ms_error("winsnd_write_process: All buffers are busy.");#ifndef DISABLE_SPEEX			if (d->pst==NULL)			{				/* initial behavior (detection in process?) */				getq(&d->write_rq);				freemsg(m);		    discarded++;		    d->stat_notplayed++;			}			else			{				if (vad==0)				{					getq(&d->write_rq);					freemsg(m);          ms_message("WINSND trouble: silence removed");			    discarded++;			    d->stat_notplayed++;				}			}#else			getq(&d->write_rq);			freemsg(m);			discarded++;			d->stat_notplayed++;#endif			break;		}	}}static int set_rate(MSFilter *f, void *arg){	WinSnd *d=(WinSnd*)f->data;	d->wfx.nSamplesPerSec=*((int*)arg);	return 0;}static int set_nchannels(MSFilter *f, void *arg){	WinSnd *d=(WinSnd*)f->data;	d->wfx.nChannels=*((int*)arg);	return 0;}static int winsnd_get_stat_input(MSFilter *f, void *arg){	WinSnd *d=(WinSnd*)f->data;	return d->stat_input;}static int winsnd_get_stat_ouptut(MSFilter *f, void *arg){	WinSnd *d=(WinSnd*)f->data;	return d->stat_output;}static int winsnd_get_stat_discarded(MSFilter *f, void *arg){	WinSnd *d=(WinSnd*)f->data;	return d->stat_notplayed;}static MSFilterMethod winsnd_methods[]={	{	MS_FILTER_SET_SAMPLE_RATE	, set_rate	},	{	MS_FILTER_SET_NCHANNELS		, set_nchannels	},	{	MS_FILTER_GET_STAT_INPUT, winsnd_get_stat_input },	{	MS_FILTER_GET_STAT_OUTPUT, winsnd_get_stat_ouptut },	{	MS_FILTER_GET_STAT_DISCARDED, winsnd_get_stat_discarded },	{	0				, NULL		}};MSFilterDesc winsnd_read_desc={	MS_WINSND_READ_ID,	"MSWinSndRead",	"Sound capture filter for Windows Sound drivers",	MS_FILTER_OTHER,	NULL,    0,	1,	winsnd_init,    winsnd_read_preprocess,	winsnd_read_process,	winsnd_read_postprocess,    winsnd_uninit,	winsnd_methods};MSFilterDesc winsnd_write_desc={	MS_WINSND_WRITE_ID,	"MSWinSndWrite",	"Sound playback filter for Windows Sound drivers",	MS_FILTER_OTHER,	NULL,    1,	0,	winsnd_init,    winsnd_write_preprocess,	winsnd_write_process,	winsnd_write_postprocess,	winsnd_uninit,    winsnd_methods};MSFilter *ms_winsnd_read_new(MSSndCard *card){	MSFilter *f=ms_filter_new_from_desc(&winsnd_read_desc);	WinSndCard *wc=(WinSndCard*)card->data;	WinSnd *d=(WinSnd*)f->data;	d->dev_id=wc->in_devid;	return f;}MSFilter *ms_winsnd_write_new(MSSndCard *card){	MSFilter *f=ms_filter_new_from_desc(&winsnd_write_desc);	WinSndCard *wc=(WinSndCard*)card->data;	WinSnd *d=(WinSnd*)f->data;	d->dev_id=wc->out_devid;	return f;}MS_FILTER_DESC_EXPORT(winsnd_read_desc)MS_FILTER_DESC_EXPORT(winsnd_write_desc)

⌨️ 快捷键说明

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