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

📄 winsndds.cpp

📁 基于osip、eXosip、speex、ffmpeg的VoIP源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	WinSndDs *d=(WinSndDs*)data;	uint64_t curtime=((uint64_t)d->bytes_read*1000)/(uint64_t)d->wfx.nAvgBytesPerSec;	/* ms_debug("winsndds_get_cur_time: bytes_read=%u return %lu\n",d->bytes_read,(unsigned long)curtime); */	return curtime;}static void winsndds_init(MSFilter *f){	WinSndDs *d=(WinSndDs *)ms_new0(WinSndDs,1);	d->wfx.wFormatTag = WAVE_FORMAT_PCM;	d->wfx.cbSize = 0;	d->wfx.nAvgBytesPerSec = 16000;	d->wfx.nBlockAlign = 2;	d->wfx.nChannels = 1;	d->wfx.nSamplesPerSec = 8000;	d->wfx.wBitsPerSample = 16;	qinit(&d->rq);	ms_mutex_init(&d->mutex,NULL);	f->data=d;	d->stat_input=0;	d->stat_output=0;	d->stat_notplayed=0;	d->stat_minimumbuffer=WINSNDDS_MINIMUMBUFFER;	d->framesPerDSBuffer = 4096*3; //320 * (8000 / 1000);	d->thread = NULL;	ms_mutex_init(&d->thread_lock,NULL);	ms_cond_init(&d->thread_cond,NULL);	d->thread_running = FALSE;	ms_bufferizer_init(&d->output_buff);}static void winsndds_uninit(MSFilter *f){	WinSndDs *d=(WinSndDs*)f->data;	d->thread = NULL;	d->thread_running = FALSE;	ms_cond_destroy(&d->thread_cond);	ms_mutex_destroy(&d->thread_lock);	ms_bufferizer_uninit(&d->output_buff);	flushq(&d->rq,0);	ms_mutex_destroy(&d->mutex);	ms_free(f->data);}static void winsndds_read_preprocess(MSFilter *f){	WinSndDs *d=(WinSndDs*)f->data;    DSCBUFFERDESC  captureDesc;	HRESULT hr;	d->stat_input=0;	d->stat_output=0;	d->stat_notplayed=0;	d->stat_minimumbuffer=WINSNDDS_MINIMUMBUFFER;	winsndds_apply_settings(d);	ms_DirectSoundCaptureCreate( &d->in_guid, &d->lpDirectSoundCapture, NULL );	d->inputSize = d->framesPerDSBuffer * 1 * sizeof(short);	ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC));    captureDesc.dwSize = sizeof(DSCBUFFERDESC);    captureDesc.dwFlags =  0;    captureDesc.dwBufferBytes = d->framesPerDSBuffer * 1 * sizeof(short); //bytesPerBuffer;	captureDesc.lpwfxFormat = &d->wfx;    // Create the capture buffer	if ((hr = IDirectSoundCapture_CreateCaptureBuffer( d->lpDirectSoundCapture,		&captureDesc, &d->lpDirectSoundInputBuffer, NULL)) != DS_OK)	{		return; /* hr; */	}    d->readOffset = 0;  // reset last read position to start of buffer    hr = IDirectSoundCaptureBuffer_Start( d->lpDirectSoundInputBuffer, DSCBSTART_LOOPING );		ms_ticker_set_time_func(f->ticker,winsndds_get_cur_time,d);	d->thread_running=TRUE;	ms_thread_create(&d->thread,NULL,winsndds_read_thread,d);	ms_mutex_lock(&d->thread_lock);	ms_cond_wait(&d->thread_cond,&d->thread_lock);	ms_mutex_unlock(&d->thread_lock);	return; /* DS_OK; */}static void winsndds_read_postprocess(MSFilter *f){	WinSndDs *d=(WinSndDs*)f->data;	ms_mutex_lock(&d->thread_lock);	d->thread_running=FALSE;	ms_cond_wait(&d->thread_cond,&d->thread_lock);	ms_mutex_unlock(&d->thread_lock);	ms_thread_join(d->thread,NULL);	ms_ticker_set_time_func(f->ticker,NULL,NULL);    if( d->lpDirectSoundInputBuffer )    {        IDirectSoundCaptureBuffer_Stop( d->lpDirectSoundInputBuffer );        IDirectSoundCaptureBuffer_Release( d->lpDirectSoundInputBuffer );        d->lpDirectSoundInputBuffer = NULL;    }    if( d->lpDirectSoundCapture )    {        IDirectSoundCapture_Release( d->lpDirectSoundCapture );        d->lpDirectSoundCapture = NULL;    }	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 winsndds_read_process(MSFilter *f){	WinSndDs *d=(WinSndDs*)f->data;	mblk_t *m;		ms_mutex_lock(&d->mutex);	while((m=getq(&d->rq))!=NULL){		ms_queue_put(f->outputs[0],m);	}	ms_mutex_unlock(&d->mutex);}static void winsndds_write_preprocess(MSFilter *f){	WinSndDs *d=(WinSndDs*)f->data;    DWORD          dwDataLen;    DWORD          playCursor;    HWND           hWnd;    HRESULT        hr;	LPDIRECTSOUNDBUFFER pPrimaryBuffer;    DSBUFFERDESC   primaryDesc;    DSBUFFERDESC   secondaryDesc;    unsigned char* pDSBuffData;	d->stat_input=0;	d->stat_output=0;	d->stat_notplayed=0;	d->stat_minimumbuffer=WINSNDDS_MINIMUMBUFFER;	winsndds_apply_settings(d);	ms_DirectSoundCreate( &d->out_guid, &d->lpDirectSound, NULL );	hWnd = GetDesktopWindow();	if ((hr = IDirectSound_SetCooperativeLevel( d->lpDirectSound, 	              hWnd, DSSCL_EXCLUSIVE)) != DS_OK)	{ 	        return ;	}    ZeroMemory(&primaryDesc, sizeof(DSBUFFERDESC));    primaryDesc.dwSize        = sizeof(DSBUFFERDESC);    primaryDesc.dwFlags       = DSBCAPS_PRIMARYBUFFER; // all panning, mixing, etc done by synth    primaryDesc.dwBufferBytes = 0;    primaryDesc.lpwfxFormat   = NULL;    // Create the buffer    if ((hr = IDirectSound_CreateSoundBuffer( d->lpDirectSound,                  &primaryDesc, &pPrimaryBuffer, NULL)) != DS_OK)	{		return ;//hr;	}	if ((hr = IDirectSoundBuffer_SetFormat( pPrimaryBuffer, &d->wfx)) != DS_OK)	{		return ;//hr;	}    // Setup the secondary buffer description    ZeroMemory(&secondaryDesc, sizeof(DSBUFFERDESC));    secondaryDesc.dwSize = sizeof(DSBUFFERDESC);    secondaryDesc.dwFlags =  DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;    secondaryDesc.dwBufferBytes = d->framesPerDSBuffer * 1 * sizeof(short); //bytesPerBuffer;	secondaryDesc.lpwfxFormat = &d->wfx;    // Create the secondary buffer    if ((hr = IDirectSound_CreateSoundBuffer( d->lpDirectSound,                  &secondaryDesc, &d->lpDirectSoundOutputBuffer, NULL)) != DS_OK)	{		return ;//hr;	}    // Lock the DS buffer	if ((hr = IDirectSoundBuffer_Lock( d->lpDirectSoundOutputBuffer, 0,		d->framesPerDSBuffer * 1 * sizeof(short),		(LPVOID*)&pDSBuffData,		&dwDataLen, NULL, 0, 0)) != DS_OK)	{		return ;//hr;	}    // Zero the DS buffer    ZeroMemory(pDSBuffData, dwDataLen);    // Unlock the DS buffer	if ((hr = IDirectSoundBuffer_Unlock( d->lpDirectSoundOutputBuffer,		pDSBuffData, dwDataLen, NULL, 0)) != DS_OK)	{		return ;//hr;	}	// Let DSound set the starting write position because if we set it to zero, it looks like the    // buffer is full to begin with. This causes a long pause before sound starts when using large buffers.	hr = IDirectSoundBuffer_GetCurrentPosition( d->lpDirectSoundOutputBuffer,            &playCursor, &d->outputBufferWriteOffsetBytes );    if( hr != DS_OK )    {        return ;//hr;    }	    hr = IDirectSoundBuffer_SetCurrentPosition( d->lpDirectSoundOutputBuffer, 0 );    if( hr != DS_OK )    {        return ;//hr;    }    hr = IDirectSoundBuffer_Play( d->lpDirectSoundOutputBuffer, 0, 0, DSBPLAY_LOOPING);    if( hr != DS_OK )    {        return ;//hr;    }		return ;//hr;}static void winsndds_write_postprocess(MSFilter *f){	WinSndDs *d=(WinSndDs*)f->data;    if( d->lpDirectSoundOutputBuffer )    {        IDirectSoundBuffer_Stop( d->lpDirectSoundOutputBuffer );        IDirectSoundBuffer_Release( d->lpDirectSoundOutputBuffer );        d->lpDirectSoundOutputBuffer = NULL;    }    if( d->lpDirectSound )    {        IDirectSound_Release( d->lpDirectSound );        d->lpDirectSound = NULL;    }	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);}static void winsndds_write_process(MSFilter *f){	WinSndDs *d=(WinSndDs*)f->data;	int discarded=0;	static int fillme=0;	if (d->lpDirectSound==NULL) {		ms_queue_flush(f->inputs[0]);		return;	}	ms_bufferizer_put_from_queue(&d->output_buff,f->inputs[0]);	if (fillme==0)	{		if (ms_bufferizer_get_avail(&d->output_buff)>=4096*3)		{			fillme=1;			return;		}		return;	}	int msize = 4096;// 1280;	while (ms_bufferizer_get_avail(&d->output_buff)>=msize)	{		LPBYTE lpOutBuf1 = NULL;		LPBYTE lpOutBuf2 = NULL;		DWORD  dwOutSize1 = 0;		DWORD  dwOutSize2 = 0;		HRESULT hr;		char input[4096];		hr = IDirectSoundBuffer_Lock ( d->lpDirectSoundOutputBuffer,			d->outputBufferWriteOffsetBytes, msize, //bytesToXfer,			(void **) &lpOutBuf1, &dwOutSize1,			(void **) &lpOutBuf2, &dwOutSize2, DSBLOCK_FROMWRITECURSOR);		if (hr != DS_OK)		{			ms_error("DirectSound IDirectSoundBuffer_Lock failed, hresult = 0x%x\n", hr);			continue;		}		if (dwOutSize1==0)		{			ms_error("no free room to play sample\n");		}		else if (dwOutSize1+dwOutSize2!=msize)		{			ms_bufferizer_read(&d->output_buff,(uint8_t*)input,dwOutSize1+dwOutSize2);			memcpy(lpOutBuf1, input, dwOutSize1);			memcpy(lpOutBuf2, input+dwOutSize1, dwOutSize2);		}		else if (dwOutSize1>=msize)		{			ms_bufferizer_read(&d->output_buff,(uint8_t*)input,msize);			memcpy(lpOutBuf1, input, msize);		}		else		{			ms_bufferizer_read(&d->output_buff,(uint8_t*)input,msize);			memcpy(lpOutBuf1, input, dwOutSize1);			memcpy(lpOutBuf2, input+dwOutSize1, dwOutSize2);		}        IDirectSoundBuffer_Unlock( d->lpDirectSoundOutputBuffer,			lpOutBuf1, dwOutSize1, lpOutBuf2, dwOutSize2);		if (dwOutSize1==0)			break;		if (dwOutSize1+dwOutSize2!=msize)			break;	}	if (discarded>0)		ms_warning("Extra data for sound card removed (%i buf), (playing: %i) (input-output: %i)", discarded, d->nbufs_playing, d->stat_input - d->stat_output);}static int set_rate(MSFilter *f, void *arg){	WinSndDs *d=(WinSndDs*)f->data;	d->wfx.nSamplesPerSec=*((int*)arg);	return 0;}static int set_nchannels(MSFilter *f, void *arg){	WinSndDs *d=(WinSndDs*)f->data;	d->wfx.nChannels=*((int*)arg);	return 0;}static int winsndds_get_stat_input(MSFilter *f, void *arg){	WinSndDs *d=(WinSndDs*)f->data;	return d->stat_input;}static int winsndds_get_stat_ouptut(MSFilter *f, void *arg){	WinSndDs *d=(WinSndDs*)f->data;	return d->stat_output;}static int winsndds_get_stat_discarded(MSFilter *f, void *arg){	WinSndDs *d=(WinSndDs*)f->data;	return d->stat_notplayed;}static MSFilterMethod winsndds_methods[]={	{	MS_FILTER_SET_SAMPLE_RATE	, set_rate	},	{	MS_FILTER_SET_NCHANNELS		, set_nchannels	},	{	MS_FILTER_GET_STAT_INPUT, winsndds_get_stat_input },	{	MS_FILTER_GET_STAT_OUTPUT, winsndds_get_stat_ouptut },	{	MS_FILTER_GET_STAT_DISCARDED, winsndds_get_stat_discarded },	{	0				, NULL		}};MSFilterDesc winsndds_read_desc={	MS_WINSNDDS_READ_ID,	"MSWinSndRead",	"Sound capture filter for Windows Sound drivers",	MS_FILTER_OTHER,	NULL,    0,	1,	winsndds_init,    winsndds_read_preprocess,	winsndds_read_process,	winsndds_read_postprocess,    winsndds_uninit,	winsndds_methods};MSFilterDesc winsndds_write_desc={	MS_WINSNDDS_WRITE_ID,	"MSWinSndWrite",	"Sound playback filter for Windows Sound drivers",	MS_FILTER_OTHER,	NULL,    1,	0,	winsndds_init,    winsndds_write_preprocess,	winsndds_write_process,	winsndds_write_postprocess,	winsndds_uninit,    winsndds_methods};MSFilter *ms_winsndds_read_new(MSSndCard *card){	MSFilter *f=ms_filter_new_from_desc(&winsndds_read_desc);	WinSndDsCard *wc=(WinSndDsCard*)card->data;	WinSndDs *d=(WinSndDs*)f->data;	d->dev_id=wc->in_devid;	memcpy(&d->in_guid, &wc->in_guid, sizeof(GUID));	memcpy(&d->out_guid, &wc->out_guid, sizeof(GUID));	return f;}MSFilter *ms_winsndds_write_new(MSSndCard *card){	MSFilter *f=ms_filter_new_from_desc(&winsndds_write_desc);	WinSndDsCard *wc=(WinSndDsCard*)card->data;	WinSndDs *d=(WinSndDs*)f->data;	d->dev_id=wc->out_devid;	memcpy(&d->in_guid, &wc->in_guid, sizeof(GUID));	memcpy(&d->out_guid, &wc->out_guid, sizeof(GUID));	return f;}MS_FILTER_DESC_EXPORT(winsndds_read_desc)MS_FILTER_DESC_EXPORT(winsndds_write_desc)#endif

⌨️ 快捷键说明

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