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

📄 winsndds.cpp

📁 基于osip、eXosip、speex、ffmpeg的VoIP源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*mediastreamer2 library - modular sound and video processing and streamingCopyright (C) 2006  Simon MORLAT (simon.morlat@linphone.org)This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.*/#ifdef __DIRECTSOUND_ENABLED__#include "mediastreamer2/mssndcard.h"#include "mediastreamer2/msfilter.h"#include "mediastreamer2/msticker.h"#include <mmsystem.h>#ifdef _MSC_VER#include <mmreg.h>#endif#include <msacm.h>#include <dsound.h>#define WINSNDDS_NBUFS 10#define WINSNDDS_NSAMPLES 160#define WINSNDDS_MINIMUMBUFFER 5static MSFilter *ms_winsndds_read_new(MSSndCard *card);static MSFilter *ms_winsndds_write_new(MSSndCard *card);static HMODULE ms_lib_instance=NULL;static HRESULT (WINAPI *ms_DllGetClassObject)(REFCLSID , REFIID , LPVOID *); 	static HRESULT (WINAPI *ms_DirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);static HRESULT (WINAPI *ms_DirectSoundEnumerate)(LPDSENUMCALLBACKA, LPVOID); 	static HRESULT (WINAPI *ms_DirectSoundCaptureCreate)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN);static HRESULT (WINAPI *ms_DirectSoundCaptureEnumerate)(LPDSENUMCALLBACKA, LPVOID);typedef struct WinSndDsCard{	int in_devid;	int out_devid;	GUID in_guid;	GUID out_guid;}WinSndDsCard;static void winsnddscard_set_level(MSSndCard *card, MSSndCardMixerElem e, int percent){    MMRESULT mr = MMSYSERR_NOERROR;    DWORD dwVolume = 0xFFFF;    dwVolume = ((0xFFFF) * percent) / 100;	switch(e){		case MS_SND_CARD_MASTER:            /*mr = waveOutSetVolume(d->waveoutdev, dwVolume); */	        if (mr != MMSYSERR_NOERROR)	        {                ms_warning("Failed to set master volume. (waveOutSetVolume:0x%i)", mr);                return;	        }        break;        case MS_SND_CARD_CAPTURE:		break;		case MS_SND_CARD_PLAYBACK:		break;        default:			ms_warning("winsndds_card_set_level: unsupported command.");	}}static int winsnddscard_get_level(MSSndCard *card, MSSndCardMixerElem e){	switch(e){		case MS_SND_CARD_MASTER:            /*mr=waveOutGetVolume(d->waveoutdev, &dwVolume);*/            /* Transform to 0 to 100 scale*/            /*dwVolume = (dwVolume *100) / (0xFFFF);*/            return 60;        break;        case MS_SND_CARD_CAPTURE:		break;		case MS_SND_CARD_PLAYBACK:		break;		default:			ms_warning("winsndds_card_get_level: unsupported command.");			return -1;	}	return -1;}static void winsnddscard_set_source(MSSndCard *card, MSSndCardCapture source){	switch(source){		case MS_SND_CARD_MIC:		break;		case MS_SND_CARD_LINE:		break;	}	}static void winsnddscard_init(MSSndCard *card){	WinSndDsCard *c=(WinSndDsCard *)ms_new(WinSndDsCard,1);	card->data=c;}static void winsnddscard_uninit(MSSndCard *card){	ms_free(card->data);}static void winsnddscard_detect(MSSndCardManager *m);static  MSSndCard *winsnddscard_dup(MSSndCard *obj);MSSndCardDesc winsndds_card_desc={	"WINSNDDS",	winsnddscard_detect,	winsnddscard_init,	winsnddscard_set_level,	winsnddscard_get_level,	winsnddscard_set_source,	ms_winsndds_read_new,	ms_winsndds_write_new,	winsnddscard_uninit,	winsnddscard_dup};static  MSSndCard *winsnddscard_dup(MSSndCard *obj){	MSSndCard *card=ms_snd_card_new(&winsndds_card_desc);	card->name=ms_strdup(obj->name);	card->data=ms_new(WinSndDsCard,1);	memcpy(card->data,obj->data,sizeof(WinSndDsCard));	return card;}static MSSndCard *winsnddscard_new(const char *name, LPGUID lpguid, int in_dev, int out_dev, unsigned cap){	MSSndCard *card=ms_snd_card_new(&winsndds_card_desc);	WinSndDsCard *d=(WinSndDsCard*)card->data;	card->name=ms_strdup(name);	d->in_devid=in_dev;	d->out_devid=out_dev;	card->capabilities=cap;	if (out_dev!=-1)	{		if (lpguid!=NULL)			memcpy(&d->out_guid, lpguid, sizeof(GUID));		else			memset(&d->out_guid, 0, sizeof(GUID));	}	else	{		if (lpguid!=NULL)			memcpy(&d->in_guid, lpguid, sizeof(GUID));		else			memset(&d->in_guid, 0, sizeof(GUID));	}	return card;}static void add_or_update_card(MSSndCardManager *m, const char *name, LPGUID lpguid, int indev, int outdev, unsigned int capability){	MSSndCard *card;	const MSList *elem=ms_snd_card_manager_get_list(m);	for(;elem!=NULL;elem=elem->next){		card=(MSSndCard*)elem->data;		if (strcmp(card->name,name)==0){			/*update already entered card */			WinSndDsCard *d=(WinSndDsCard*)card->data;			card->capabilities|=capability;			if (indev!=-1) 				d->in_devid=indev;			if (outdev!=-1)				d->out_devid=outdev;			if (outdev!=-1)			{				if (lpguid!=NULL)					memcpy(&d->out_guid, lpguid, sizeof(GUID));				else					memset(&d->out_guid, 0, sizeof(GUID));			}			if (indev!=-1)			{				if (lpguid!=NULL)					memcpy(&d->in_guid, lpguid, sizeof(GUID));				else					memset(&d->in_guid, 0, sizeof(GUID));			}			return;		}	}	/* add this new card:*/	ms_snd_card_manager_add_card(m,winsnddscard_new(name,lpguid, indev,outdev,capability));}static BOOL CALLBACK enumerate_capture_devices_callback(LPGUID lpGUID, 	                                     LPCTSTR lpszDesc, 	                                     LPCTSTR lpszDrvName, 	                                     LPVOID lpContext ){	MSSndCardManager *m = (MSSndCardManager*)lpContext;	static int dev_index=0;	if ( lpGUID == NULL ) /* primary device */    {		char snd_card_name[256];		snprintf(snd_card_name, 256, "ds: %s", lpszDesc);		add_or_update_card(m,snd_card_name,lpGUID,dev_index,-1,MS_SND_CARD_CAP_CAPTURE);		dev_index++;    }    else    {		char snd_card_name[256];		snprintf(snd_card_name, 256, "ds: %s", lpszDesc);		add_or_update_card(m,snd_card_name,lpGUID,dev_index,-1,MS_SND_CARD_CAP_CAPTURE);		dev_index++;    }	return true;}static BOOL CALLBACK enumerate_playback_devices_callback(LPGUID lpGUID, 	                                     LPCTSTR lpszDesc, 	                                     LPCTSTR lpszDrvName, 	                                     LPVOID lpContext ){	MSSndCardManager *m = (MSSndCardManager*)lpContext;	static int dev_index=0;	if ( lpGUID == NULL ) /* primary device */    {		char snd_card_name[256];		snprintf(snd_card_name, 256, "ds: %s", lpszDesc);		add_or_update_card(m,snd_card_name,lpGUID,-1,dev_index,MS_SND_CARD_CAP_PLAYBACK);		dev_index++;    }    else    {		char snd_card_name[256];		snprintf(snd_card_name, 256, "ds: %s", lpszDesc);		add_or_update_card(m,snd_card_name,lpGUID,-1,dev_index,MS_SND_CARD_CAP_PLAYBACK);		dev_index++;    }	return true;}static void winsnddscard_detect(MSSndCardManager *m){    MMRESULT mr = NOERROR;	if (ms_lib_instance==NULL)	{		ms_lib_instance = LoadLibrary("dsound.dll");		if( ms_lib_instance == NULL )		{			/* error */			ms_debug("winsnddscard_init: no support for dsound (missing dsound.dll)\n");			return;		}		ms_DllGetClassObject =(HRESULT (WINAPI *)(REFCLSID, REFIID , LPVOID *))		GetProcAddress( ms_lib_instance, "DllGetClassObject" );		ms_DirectSoundCreate =(HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN))		GetProcAddress( ms_lib_instance, "DirectSoundCreate" );		ms_DirectSoundEnumerate =(HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID))		GetProcAddress( ms_lib_instance, "DirectSoundEnumerateA" );		ms_DirectSoundCaptureCreate =(HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN))		GetProcAddress( ms_lib_instance, "DirectSoundCaptureCreate" );		ms_DirectSoundCaptureEnumerate =(HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID))		GetProcAddress( ms_lib_instance, "DirectSoundCaptureEnumerateA" );		if( ms_DllGetClassObject == NULL ||			ms_DirectSoundCreate == NULL ||			ms_DirectSoundEnumerate == NULL ||			ms_DirectSoundCaptureEnumerate == NULL ||			ms_DirectSoundCaptureCreate == NULL )		{			/* error */			ms_debug("winsnddscard_init: no support for dsound\n");			return;		}	}	ms_DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)enumerate_capture_devices_callback, (void *)m );	ms_DirectSoundEnumerate( (LPDSENUMCALLBACK)enumerate_playback_devices_callback, (void *)m );}typedef struct WinSndDs{	int dev_id;	GUID in_guid;	GUID out_guid;	ms_thread_t thread;	ms_mutex_t thread_lock;	ms_cond_t thread_cond;	bool_t thread_running;	MSBufferizer output_buff;	LPDIRECTSOUND lpDirectSound;    LPDIRECTSOUNDBUFFER  lpDirectSoundOutputBuffer;    DWORD                outputBufferWriteOffsetBytes;     /* last write position */    double               dsw_framesWritten;	LPDIRECTSOUNDCAPTURE lpDirectSoundCapture;    LPDIRECTSOUNDCAPTUREBUFFER  lpDirectSoundInputBuffer;    UINT                 readOffset;      /* last read position */    UINT                 inputSize;	int              framesPerDSBuffer;	WAVEFORMATEX wfx;	queue_t rq;	ms_mutex_t mutex;	unsigned int bytes_read;	unsigned int nbufs_playing;	int32_t stat_input;	int32_t stat_output;	int32_t stat_notplayed;	int32_t stat_minimumbuffer;}WinSndDs;void *  winsndds_read_thread(void *arg){	WinSndDs *d=(WinSndDs*)arg;	ms_mutex_lock(&d->thread_lock);	ms_cond_signal(&d->thread_cond);	ms_mutex_unlock(&d->thread_lock);	while(d->thread_running)	{		HRESULT hr;		DWORD capturePos;		DWORD readPos;		long filled = 0;		long bytesFilled = 0;		LPBYTE            lpInBuf1 = NULL;		LPBYTE            lpInBuf2 = NULL;		DWORD             dwInSize1 = 0;		DWORD             dwInSize2 = 0;		hr = IDirectSoundCaptureBuffer_GetCurrentPosition( d->lpDirectSoundInputBuffer,			&capturePos, &readPos );		if( hr != DS_OK )		{			continue;		}		filled = readPos - d->readOffset;		if( filled < 0 ) filled += d->inputSize; // unwrap offset		bytesFilled = filled;		hr = IDirectSoundCaptureBuffer_Lock ( d->lpDirectSoundInputBuffer,			d->readOffset, bytesFilled,			(void **) &lpInBuf1, &dwInSize1,			(void **) &lpInBuf2, &dwInSize2, 0);		if (hr != DS_OK)		{			Sleep(10);			continue;		}		if (dwInSize1==0)		{			Sleep(10);		}		else if (dwInSize1>=bytesFilled)		{			mblk_t *m=allocb(bytesFilled,0);			memcpy(m->b_rptr, lpInBuf1, bytesFilled);			m->b_wptr+=bytesFilled;			ms_mutex_lock(&d->mutex);			putq(&d->rq,m);			ms_mutex_unlock(&d->mutex);			d->bytes_read+=bytesFilled;		}		else		{			mblk_t *m=allocb(bytesFilled,0);			memcpy(m->b_rptr, lpInBuf1, dwInSize1);			memcpy(m->b_rptr+dwInSize1, lpInBuf2, dwInSize2);			m->b_wptr+=bytesFilled;			ms_mutex_lock(&d->mutex);			putq(&d->rq,m);			ms_mutex_unlock(&d->mutex);			d->bytes_read+=bytesFilled;		}		d->readOffset = (d->readOffset + bytesFilled) % d->inputSize;		IDirectSoundCaptureBuffer_Unlock( d->lpDirectSoundInputBuffer,			lpInBuf1, dwInSize1, lpInBuf2, dwInSize2);	}	ms_mutex_lock(&d->thread_lock);	ms_cond_signal(&d->thread_cond);	ms_mutex_unlock(&d->thread_lock);	ms_thread_exit(NULL);	return NULL;}static void winsndds_apply_settings(WinSndDs *d){	d->wfx.nBlockAlign=d->wfx.nChannels*d->wfx.wBitsPerSample/8;	d->wfx.nAvgBytesPerSec=d->wfx.nSamplesPerSec*d->wfx.nBlockAlign;}static uint64_t winsndds_get_cur_time( void *data){

⌨️ 快捷键说明

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