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

📄 winsnd.c

📁 基于osip、eXosip、speex、ffmpeg的VoIP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	d->bytes_read=0;	d->pcmdev=NULL;	d->mixdev=NULL;    d->sound_err=-1; /* not opened */	d->read_started=FALSE;	d->write_started=FALSE;	d->bits=16;	d->rate=8000;	d->stereo=FALSE;	qinit(&d->rq);	d->bufferizer=ms_bufferizer_new();	ms_mutex_init(&d->mutex,NULL);	card->data=d;#ifndef DISABLE_SPEEX	d->pst=0;#endif	d->stat_input=0;	d->stat_output=0;	d->stat_notplayed=0;}static void winsnd_uninit(MSSndCard *card){	WinSndData *d=(WinSndData*)card->data;	if (d==NULL)		return;	if (d->pcmdev!=NULL) ms_free(d->pcmdev);	if (d->mixdev!=NULL) ms_free(d->mixdev);	ms_bufferizer_destroy(d->bufferizer);	flushq(&d->rq,0);	ms_mutex_destroy(&d->mutex);#ifndef DISABLE_SPEEX	if (d->pst!=NULL)	    speex_preprocess_state_destroy(d->pst);#endif	ms_free(d);}#define DSP_NAME "/dev/dsp"#define MIXER_NAME "/dev/mixer"static void winsnd_detect(MSSndCardManager *m);static  MSSndCard *winsnd_dup(MSSndCard *obj);MSSndCardDesc winsnd_card_desc={	"WINSND",	winsnd_detect,	winsnd_init,	winsnd_set_level,	winsnd_get_level,	winsnd_set_source,	ms_winsnd_read_new,	ms_winsnd_write_new,	winsnd_uninit,	winsnd_dup};static  MSSndCard *winsnd_dup(MSSndCard *obj){	MSSndCard *card=ms_snd_card_new(&winsnd_card_desc);	WinSndData *dcard=(WinSndData*)card->data;	WinSndData *dobj=(WinSndData*)obj->data;	dcard->pcmdev=ms_strdup(dobj->pcmdev);	dcard->mixdev=ms_strdup(dobj->mixdev);	dcard->devid=dobj->devid;	card->name=ms_strdup(obj->name);	return card;}static MSSndCard *winsnd_card_new(const char *pcmdev, const char *mixdev, int id){	MSSndCard *card=ms_snd_card_new(&winsnd_card_desc);	WinSndData *d=(WinSndData*)card->data;	d->pcmdev=ms_strdup(pcmdev);	d->mixdev=ms_strdup(mixdev);	card->name=ms_strdup(pcmdev);	d->devid=id;	return card;}static void winsnd_detect(MSSndCardManager *m){    MMRESULT mr = NOERROR;    unsigned int nInDevices = waveInGetNumDevs ();    unsigned int item;	char pcmdev[1024];	char mixdev[1024];    for (item = 0; item < nInDevices; item++)    {        WAVEINCAPS caps;        mr = waveInGetDevCaps (item, &caps, sizeof (WAVEINCAPS));        if (mr == MMSYSERR_NOERROR)        {            MSSndCard *card;	        snprintf(pcmdev,sizeof(pcmdev),"%s",caps.szPname);	        snprintf(mixdev,sizeof(mixdev),"%s",caps.szPname);            if (item == 0)            {		        card=winsnd_card_new(pcmdev,mixdev, item-1);		        ms_snd_card_manager_add_card(m,card);            }			card=winsnd_card_new(pcmdev,mixdev, item);			ms_snd_card_manager_add_card(m,card);        }    }#if 0	nInDevices = mixerGetNumDevs ();    for (item = 0; item < nInDevices; item++)    {        MIXERCAPS caps;        mr = mixerGetDevCaps (item, &caps, sizeof (MIXERCAPS));        if (mr == MMSYSERR_NOERROR)        {	        snprintf(pcmdev,sizeof(pcmdev),"%s",caps.szPname);	        snprintf(mixdev,sizeof(mixdev),"%s",caps.szPname);        }    }#endif}static void * winsnd_thread(void *p){	MSSndCard *card=(MSSndCard*)p;	WinSndData *d=(WinSndData*)card->data;	int bsize=d->rate/8000 * 320;	uint8_t *rtmpbuff=NULL;	uint8_t *wtmpbuff=NULL;	int err;	MMRESULT mr = NOERROR;    int pos_whdr=0;	d->stat_input=0;	d->stat_output=0;	d->stat_notplayed=0;	d->sound_err=winsnd_open(d, d->devid, d->bits,d->stereo,d->rate,&bsize);	if (d->sound_err==0){		rtmpbuff=(uint8_t*)alloca(bsize);		wtmpbuff=(uint8_t*)alloca(bsize);	}	while(d->read_started || d->write_started){		if (d->sound_err==0){			if (d->write_started){#if 0                if (d->stat_output>0 && d->buffer_playing==0)				{                    ms_error("No data currently playing in sound card" );				}				if (d->stat_output>0 && (d->stat_input-d->stat_output>10 || d->stat_input-d->stat_output<-10))                    ms_error("Not perfectly synchronized (input-output=%i)", d->stat_input-d->stat_output);#endif				while (d->buffer_playing<6 && d->buffer_playing<MAX_WAVEHDR)				{					ms_mutex_lock(&d->mutex);				    err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize);					ms_mutex_unlock(&d->mutex);				    if (err!=bsize)						break;					ms_mutex_lock(&d->mutex);                    /* write to sound devide! */                    memcpy (d->waveouthdr[pos_whdr].lpData, wtmpbuff, bsize);                    mr = waveOutWrite (d->waveoutdev,                        &(d->waveouthdr[pos_whdr]),                        sizeof (d->waveouthdr[pos_whdr]));                    if (mr != MMSYSERR_NOERROR)                    {                        if (mr == WAVERR_STILLPLAYING)                        {                            /* retry later */                            /* data should go back to queue */                            /* TODO */                            ms_warning("sound device write STILL_PLAYING (waveOutWrite:0x%i)", mr);                        }                        else                        {                            ms_warning("sound device write returned (waveOutWrite:0x%i)", mr);                        }                    }                    else                    {                        d->buffer_playing++;                        pos_whdr++;                        if (pos_whdr == MAX_WAVEHDR)                            pos_whdr = 0;   /* loop over the prepared blocks */                    }					ms_mutex_unlock(&d->mutex);				    if (err<0){#if !defined(_WIN32_WCE)					    ms_warning("Fail to write %i bytes from soundcard: %s",						    bsize,strerror(errno));#else					    ms_warning("Fail to write %i bytes from soundcard: %i",						    bsize,WSAGetLastError());#endif				    }				}                if (d->buffer_playing==6 || d->buffer_playing==MAX_WAVEHDR)                {					int discarded=0;					ms_mutex_lock(&d->mutex);					while (d->bufferizer->size>=bsize){						discarded++;						d->stat_notplayed++;					    err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize);					}					ms_mutex_unlock(&d->mutex);					if (discarded>0)						ms_error("Extra data for sound card removed (%ims), (playing: %i) (input-output: %i)", (discarded*20*320)/320, d->buffer_playing, d->stat_input - d->stat_output);				}#if !defined(_WIN32_WCE)				Sleep(5);#endif#if defined(_WIN32_WCE)				Sleep(10);#endif			}else {				int discarded=0;				/* don't think this is usefull, anyway... */				ms_mutex_lock(&d->mutex);				while (d->bufferizer->size>=bsize){					discarded++;				    err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize);				}				ms_mutex_unlock(&d->mutex);				if (discarded>0)					ms_error("Extra data for sound card removed (%ims), (playing: %i) (input-output: %i)", (discarded*20)/320, d->buffer_playing, d->stat_input - d->stat_output);			    Sleep(10);            }		}else Sleep(10);	}	if (d->sound_err==0) {        int i;        int count=0;        /* close sound card */		ms_error("Shutting down sound device (playing: %i) (input-output: %i) (notplayed: %i)", d->buffer_playing, d->stat_input - d->stat_output, d->stat_notplayed);        /* unprepare buffer */        for (i = 0; i < MAX_WAVEHDR; i++)        {            int counttry=0;            for (counttry=0;counttry<10;counttry++)            {                mr = waveInUnprepareHeader (d->waveindev,                                        &(d->waveinhdr[i]),                                        sizeof (d->waveinhdr[i]));                if (mr != MMSYSERR_NOERROR)                {                    ms_error("Failed to unprepared %i buffer from sound card (waveInUnprepareHeader:0x%i", count, mr);                    Sleep (20);                } else                {                    count++;        		    ms_message("successfully unprepared %i buffer from sound card.", count);                    break;                }            }        }		ms_warning("unprepared %i buffer from sound card.", count);        mr = waveInStop (d->waveindev);        if (mr != MMSYSERR_NOERROR)        {        	ms_error("failed to stop recording sound card (waveInStop:0x%i)", mr);        } else        {        	ms_message("successfully stopped recording sound card");        }        mr = waveInReset (d->waveindev);        if (mr != MMSYSERR_NOERROR)        {        	ms_warning("failed to reset recording sound card (waveInReset:0x%i)", mr);        } else        {        	ms_message("successful reset of recording sound card");        }        mr = waveInClose (d->waveindev);        if (mr != MMSYSERR_NOERROR)        {        	ms_warning("failed to close recording sound card (waveInClose:0x%i)", mr);        } else        {        	ms_message("successfully closed recording sound card");        }		d->sound_err=-1;	}	d->stat_input=0;	d->stat_output=0;	d->stat_notplayed=0;	return NULL;}static void winsnd_start_r(MSSndCard *card){	WinSndData *d=(WinSndData*)card->data;	if (d->read_started==FALSE && d->write_started==FALSE){		d->read_started=TRUE;		ms_thread_create(&d->thread,NULL,winsnd_thread,card);	}else d->read_started=TRUE;}static void winsnd_stop_r(MSSndCard *card){	WinSndData *d=(WinSndData*)card->data;	d->read_started=FALSE;	if (d->write_started==FALSE){		ms_thread_join(d->thread,NULL);	}}static void winsnd_start_w(MSSndCard *card){	WinSndData *d=(WinSndData*)card->data;	if (d->read_started==FALSE && d->write_started==FALSE){		d->write_started=TRUE;		ms_thread_create(&d->thread,NULL,winsnd_thread,card);	}else{		d->write_started=TRUE;	}}static void winsnd_stop_w(MSSndCard *card){	WinSndData *d=(WinSndData*)card->data;	d->write_started=FALSE;	if (d->read_started==FALSE){		ms_thread_join(d->thread,NULL);	}#ifdef CONTROLVOLUME	waveOutSetVolume(d->waveoutdev, d->dwOldVolume);#endif}static mblk_t *winsnd_get(MSSndCard *card){	WinSndData *d=(WinSndData*)card->data;	mblk_t *m;	ms_mutex_lock(&d->mutex);	m=getq(&d->rq);	ms_mutex_unlock(&d->mutex);	return m;}static void winsnd_put(MSSndCard *card, mblk_t *m){	WinSndData *d=(WinSndData*)card->data;	ms_mutex_lock(&d->mutex);	ms_bufferizer_put(d->bufferizer,m);	ms_mutex_unlock(&d->mutex);}static void winsnd_read_preprocess(MSFilter *f){	MSSndCard *card=(MSSndCard*)f->data;	winsnd_start_r(card);	ms_ticker_set_time_func(f->ticker,winsnd_get_cur_time,card->data);}static void winsnd_read_postprocess(MSFilter *f){	MSSndCard *card=(MSSndCard*)f->data;	ms_ticker_set_time_func(f->ticker,NULL,NULL);	winsnd_stop_r(card);}static void winsnd_read_process(MSFilter *f){	MSSndCard *card=(MSSndCard*)f->data;	mblk_t *m;	while((m=winsnd_get(card))!=NULL){		ms_queue_put(f->outputs[0],m);	}}static void winsnd_write_preprocess(MSFilter *f){	MSSndCard *card=(MSSndCard*)f->data;	winsnd_start_w(card);}static void winsnd_write_postprocess(MSFilter *f){	MSSndCard *card=(MSSndCard*)f->data;	winsnd_stop_w(card);}static void winsnd_write_process(MSFilter *f){	MSSndCard *card=(MSSndCard*)f->data;	mblk_t *m;	while((m=ms_queue_get(f->inputs[0]))!=NULL){		winsnd_put(card,m);	}}static int set_rate(MSFilter *f, void *arg){	MSSndCard *card=(MSSndCard*)f->data;	WinSndData *d=(WinSndData*)card->data;	d->rate=*((int*)arg);	return 0;}static int set_nchannels(MSFilter *f, void *arg){	MSSndCard *card=(MSSndCard*)f->data;	WinSndData *d=(WinSndData*)card->data;	d->stereo=(*((int*)arg)==2);	return 0;}static int winsnd_get_stat_input(MSFilter *f, void *arg){	MSSndCard *card=(MSSndCard*)f->data;	WinSndData *d=(WinSndData*)card->data;	return d->stat_input;}static int winsnd_get_stat_ouptut(MSFilter *f, void *arg){	MSSndCard *card=(MSSndCard*)f->data;	WinSndData *d=(WinSndData*)card->data;	return d->stat_output;}static int winsnd_get_stat_discarded(MSFilter *f, void *arg){	MSSndCard *card=(MSSndCard*)f->data;	WinSndData *d=(WinSndData*)card->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,	NULL,    winsnd_read_preprocess,	winsnd_read_process,	winsnd_read_postprocess,    NULL,	winsnd_methods};MSFilterDesc winsnd_write_desc={	MS_WINSND_WRITE_ID,	"MSWinSndWrite",	"Sound playback filter for Windows Sound drivers",	MS_FILTER_OTHER,	NULL,    1,	0,	NULL,    winsnd_write_preprocess,	winsnd_write_process,	winsnd_write_postprocess,	NULL,    winsnd_methods};MSFilter *ms_winsnd_read_new(MSSndCard *card){	MSFilter *f=ms_filter_new_from_desc(&winsnd_read_desc);	f->data=card;	return f;}MSFilter *ms_winsnd_write_new(MSSndCard *card){	MSFilter *f=ms_filter_new_from_desc(&winsnd_write_desc);	f->data=card;	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 + -