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

📄 winsnd3.c

📁 基于osip、eXosip、speex、ffmpeg的VoIP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	            (DWORD) read_callback, (DWORD)f, dwFlag);	if (mr != MMSYSERR_NOERROR)	{	    ms_error("Failed to prepare windows sound device. (waveInOpen:0x%i)", mr);		mr = waveInOpen (&d->indev, WAVE_MAPPER, &d->wfx,					(DWORD) read_callback, (DWORD)d, CALLBACK_FUNCTION);		if (mr != MMSYSERR_NOERROR)		{			d->indev=NULL;			ms_error("Failed to prepare windows sound device. (waveInOpen:0x%i)", mr);		    return ;		}	}	bsize=WINSND_NSAMPLES*d->wfx.nAvgBytesPerSec/8000;	ms_debug("Using input buffers of %i bytes",bsize);	for(i=0;i<WINSND_NBUFS;++i){		WAVEHDR *hdr=&d->hdrs_read[i];		add_input_buffer(d,hdr,bsize);	}	d->running=TRUE;	mr=waveInStart(d->indev);	if (mr != MMSYSERR_NOERROR){		ms_error("waveInStart() error");		return ;	}#ifndef _TRUE_TIME	ms_ticker_set_time_func(f->ticker,winsnd_get_cur_time,d);#endif}static void winsnd_read_postprocess(MSFilter *f){	WinSnd *d=(WinSnd*)f->data;	MMRESULT mr;	int i;#ifndef _TRUE_TIME	ms_ticker_set_time_func(f->ticker,NULL,NULL);#endif	d->running=FALSE;	mr=waveInStop(d->indev);	if (mr != MMSYSERR_NOERROR){		ms_error("waveInStop() error");		return ;	}	mr=waveInReset(d->indev);	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;	}	d->outcurbuf=0;	d->overrun=FALSE;	d->nsamples=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 ;	}	d->ready=0;	d->workaround=0;}static void playout_buf(WinSnd *d, WAVEHDR *hdr, mblk_t *m){	MMRESULT mr;	hdr->dwUser=(DWORD)m;	hdr->lpData=(LPSTR)m->b_rptr;	hdr->dwBufferLength=msgdsize(m);	hdr->dwFlags = 0;	mr = waveOutPrepareHeader(d->outdev,hdr,sizeof(*hdr));	if (mr != MMSYSERR_NOERROR){		ms_error("waveOutPrepareHeader() error");		d->stat_notplayed++;	}	mr=waveOutWrite(d->outdev,hdr,sizeof(*hdr));	if (mr != MMSYSERR_NOERROR){		ms_error("waveOutWrite() error");		d->stat_notplayed++;	}else {		d->nbufs_playing++;	}}static void winsnd_write_process(MSFilter *f){	WinSnd *d=(WinSnd*)f->data;	mblk_t *m;	MMRESULT mr;	mblk_t *old;	if (d->outdev==NULL) {		ms_queue_flush(f->inputs[0]);		return;	}	if (d->overrun){		ms_warning("nbufs_playing=%i",d->nbufs_playing);		if (d->nbufs_playing>0){			ms_queue_flush(f->inputs[0]);			return;		}		else d->overrun=FALSE;	}	while(1){		int outcurbuf=d->outcurbuf % WINSND_OUT_NBUFS;		WAVEHDR *hdr=&d->hdrs_write[outcurbuf];		old=(mblk_t*)hdr->dwUser;		if (d->nsamples==0){			int tmpsize=WINSND_OUT_DELAY*d->wfx.nAvgBytesPerSec;			mblk_t *tmp=allocb(tmpsize,0);			memset(tmp->b_wptr,0,tmpsize);			tmp->b_wptr+=tmpsize;			playout_buf(d,hdr,tmp);			d->outcurbuf++;			d->nsamples+=WINSND_OUT_DELAY*d->wfx.nSamplesPerSec;			continue;		}		m=ms_queue_get(f->inputs[0]);		if (!m) break;		d->nsamples+=msgdsize(m)/d->wfx.nBlockAlign;		/*if the output buffer has finished to play, unprepare it*/		if (hdr->dwFlags & WHDR_DONE){			mr=waveOutUnprepareHeader(d->outdev,hdr,sizeof(*hdr));			if (mr != MMSYSERR_NOERROR){				ms_error("waveOutUnprepareHeader error");			}			freemsg(old);			old=NULL;			hdr->dwFlags=0;			hdr->dwUser=0;		}		if (old==NULL){			/* a free wavheader */			playout_buf(d,hdr,m);		}else{			/* no more free wavheader, overrun !*/			ms_warning("WINSND overrun, restarting");			d->overrun=TRUE;			d->nsamples=0;			waveOutReset(d->outdev);		}		d->outcurbuf++;	}}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 + -