Commit 9db49818 authored by aymeric's avatar aymeric
Browse files

Commit hopefully final version of direcsound support with capability to use...

Commit hopefully final version of direcsound support with capability to use the microsoft AEC if both the READ and WRITE filter from directsound are used in the same graph.

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@472 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
parent 35fc25ee
......@@ -23,6 +23,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/msticker.h"
extern void find_filters(MSList **filters, MSFilter *f );
#define UNICODE
#include <mmsystem.h>
#ifdef _MSC_VER
#include <mmreg.h>
......@@ -43,10 +47,10 @@ 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_DirectSoundEnumerate)(LPDSENUMCALLBACKW, LPVOID);
static HRESULT (WINAPI *ms_DirectSoundCaptureCreate)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN);
static HRESULT (WINAPI *ms_DirectSoundCaptureEnumerate)(LPDSENUMCALLBACKA, LPVOID);
static HRESULT (WINAPI *ms_DirectSoundCaptureEnumerate)(LPDSENUMCALLBACKW, LPVOID);
static HRESULT (WINAPI *ms_DirectSoundFullDuplexCreate)(LPCGUID , LPCGUID ,
LPCDSCBUFFERDESC , LPCDSBUFFERDESC , HWND ,
......@@ -60,7 +64,6 @@ typedef struct WinSndDsCard{
GUID out_guid;
}WinSndDsCard;
static void winsnddscard_set_level(MSSndCard *card, MSSndCardMixerElem e, int percent){
MMRESULT mr = MMSYSERR_NOERROR;
WinSndDsCard *d=(WinSndDsCard*)card->data;
......@@ -340,8 +343,8 @@ static void add_or_update_card(MSSndCardManager *m, const char *name, LPGUID lpg
}
static BOOL CALLBACK enumerate_capture_devices_callback(LPGUID lpGUID,
LPCTSTR lpszDesc,
LPCTSTR lpszDrvName,
LPCWSTR lpszDesc,
LPCWSTR lpszDrvName,
LPVOID lpContext )
{
MSSndCardManager *m = (MSSndCardManager*)lpContext;
......@@ -349,16 +352,22 @@ static BOOL CALLBACK enumerate_capture_devices_callback(LPGUID lpGUID,
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);
char szName[256];
wchar_t snd_card_name[256];
swprintf(snd_card_name, 256, L"DS: %s", lpszDesc);
WideCharToMultiByte(CP_UTF8,0,snd_card_name,-1,szName,256,0,0);
add_or_update_card(m,szName,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);
char szName[256];
wchar_t snd_card_name[256];
swprintf(snd_card_name, 256, L"DS: %s", lpszDesc);
WideCharToMultiByte(CP_UTF8,0,snd_card_name,-1,szName,256,0,0);
add_or_update_card(m,szName,lpGUID,dev_index,-1,MS_SND_CARD_CAP_CAPTURE);
dev_index++;
}
......@@ -366,8 +375,8 @@ static BOOL CALLBACK enumerate_capture_devices_callback(LPGUID lpGUID,
}
static BOOL CALLBACK enumerate_playback_devices_callback(LPGUID lpGUID,
LPCTSTR lpszDesc,
LPCTSTR lpszDrvName,
LPCWSTR lpszDesc,
LPCWSTR lpszDrvName,
LPVOID lpContext )
{
MSSndCardManager *m = (MSSndCardManager*)lpContext;
......@@ -375,18 +384,22 @@ static BOOL CALLBACK enumerate_playback_devices_callback(LPGUID lpGUID,
if ( lpGUID == NULL ) /* primary device */
{
char snd_card_name[256];
snprintf(snd_card_name, 256, "ds: %s", lpszDesc);
char szName[256];
wchar_t snd_card_name[256];
swprintf(snd_card_name, 256, L"DS: %s", lpszDesc);
WideCharToMultiByte(CP_UTF8,0,snd_card_name,-1,szName,256,0,0);
add_or_update_card(m,snd_card_name,lpGUID,-1,dev_index,MS_SND_CARD_CAP_PLAYBACK);
add_or_update_card(m,szName,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);
char szName[256];
wchar_t snd_card_name[256];
swprintf(snd_card_name, 256, L"DS: %s", lpszDesc);
WideCharToMultiByte(CP_UTF8,0,snd_card_name,-1,szName,256,0,0);
add_or_update_card(m,snd_card_name,lpGUID,-1,dev_index,MS_SND_CARD_CAP_PLAYBACK);
add_or_update_card(m,szName,lpGUID,-1,dev_index,MS_SND_CARD_CAP_PLAYBACK);
dev_index++;
}
......@@ -412,14 +425,14 @@ static void winsnddscard_detect(MSSndCardManager *m){
ms_DirectSoundCreate =(HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN))
GetProcAddress( ms_lib_instance, "DirectSoundCreate" );
ms_DirectSoundEnumerate =(HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID))
GetProcAddress( ms_lib_instance, "DirectSoundEnumerateA" );
ms_DirectSoundEnumerate =(HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID))
GetProcAddress( ms_lib_instance, "DirectSoundEnumerateW" );
ms_DirectSoundCaptureCreate =(HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN))
GetProcAddress( ms_lib_instance, "DirectSoundCaptureCreate" );
ms_DirectSoundCaptureEnumerate =(HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID))
GetProcAddress( ms_lib_instance, "DirectSoundCaptureEnumerateA" );
ms_DirectSoundCaptureEnumerate =(HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID))
GetProcAddress( ms_lib_instance, "DirectSoundCaptureEnumerateW" );
ms_DirectSoundFullDuplexCreate =(HRESULT (WINAPI *)(LPCGUID , LPCGUID ,
LPCDSCBUFFERDESC , LPCDSBUFFERDESC , HWND ,
......@@ -443,7 +456,6 @@ static void winsnddscard_detect(MSSndCardManager *m){
ms_DirectSoundEnumerate( (LPDSENUMCALLBACK)enumerate_playback_devices_callback, (void *)m );
}
typedef struct WinSndDs{
int dev_id;
GUID in_guid;
......@@ -707,6 +719,27 @@ static void winsndds_write_preprocess(MSFilter *f){
unsigned char* pDSBuffData;
DWORD outputBufferWriteOffsetBytes;
MSList *filters=NULL;
MSFilter *f_capture_filter=NULL;
WinSndDs *d_capture_filter=NULL;
find_filters(&filters, f);
if (filters!=NULL)
{
MSList *it;
/* search for another winsndds filter */
for(it=filters;it!=NULL;it=it->next)
{
MSFilter *f_tmp = (MSFilter*)it->data;
f_tmp->seen = FALSE;
if (f_tmp->desc->id == MS_WINSNDDS_READ_ID)
{
/* found */
f_capture_filter = f_tmp;
d_capture_filter=(WinSndDs*)f_capture_filter->data;
}
}
}
d->stat_input=0;
d->stat_output=0;
......@@ -715,13 +748,13 @@ static void winsndds_write_preprocess(MSFilter *f){
d->framesPerDSBuffer = d->wfx.nAvgBytesPerSec/4;
winsndds_apply_settings(d);
ms_message("full duplex and echo canceller! (%x)" ,d->lpDirectSoundCapture);
if (d->lpDirectSoundCapture!=NULL)
if (d_capture_filter!=NULL
&& d_capture_filter->lpDirectSoundCapture!=NULL
&& IsEqualIID(d_capture_filter->in_guid, d->in_guid))
{
DSCBUFFERDESC captureDesc;
ms_message("full duplex and echo canceller: activating!");
winsndds_read_postprocess(f);
winsndds_read_postprocess(f_capture_filter);
DSCEFFECTDESC dscfx[1];
ZeroMemory( &dscfx[0], sizeof( DSCEFFECTDESC ) );
......@@ -732,11 +765,14 @@ static void winsndds_write_preprocess(MSFilter *f){
dscfx[0].dwReserved1 = 0;
dscfx[0].dwReserved2 = 0;
d_capture_filter->framesPerDSBuffer = d_capture_filter->wfx.nAvgBytesPerSec/4;
winsndds_apply_settings(d_capture_filter);
ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC));
captureDesc.dwSize = sizeof(DSCBUFFERDESC);
captureDesc.dwFlags = DSCBCAPS_CTRLFX;
captureDesc.dwBufferBytes = d->framesPerDSBuffer;
captureDesc.lpwfxFormat = &d->wfx;
captureDesc.dwBufferBytes = d_capture_filter->framesPerDSBuffer;
captureDesc.lpwfxFormat = &d_capture_filter->wfx;
captureDesc.dwFXCount = 1;
captureDesc.lpDSCFXDesc = dscfx;
......@@ -744,20 +780,19 @@ static void winsndds_write_preprocess(MSFilter *f){
secondaryDesc.dwSize = sizeof(DSBUFFERDESC);
secondaryDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_LOCSOFTWARE;
//| DSBCAPS_CTRLFREQUENCY;
secondaryDesc.dwBufferBytes = d->framesPerDSBuffer;
secondaryDesc.lpwfxFormat = &d->wfx;
hWnd = GetDesktopWindow();
hr = ms_DirectSoundFullDuplexCreate(&d->in_guid,
hr = ms_DirectSoundFullDuplexCreate(&d_capture_filter->in_guid,
&d->out_guid,
&captureDesc,
&secondaryDesc,
hWnd,
DSSCL_NORMAL,
&d->lpDirectSoundFullDuplex,
(LPDIRECTSOUNDCAPTUREBUFFER8*)&d->lpDirectSoundInputBuffer,
(LPDIRECTSOUNDBUFFER8*)&d->lpDirectSound,
(LPDIRECTSOUNDCAPTUREBUFFER8*)&d_capture_filter->lpDirectSoundInputBuffer,
(LPDIRECTSOUNDBUFFER8*)&d->lpDirectSoundOutputBuffer,
NULL);
if (hr!=DS_OK)
......@@ -767,15 +802,15 @@ static void winsndds_write_preprocess(MSFilter *f){
captureDesc.dwFXCount = 0;
captureDesc.lpDSCFXDesc = NULL;
hr = ms_DirectSoundFullDuplexCreate(&d->in_guid,
hr = ms_DirectSoundFullDuplexCreate(&d_capture_filter->in_guid,
&d->out_guid,
&captureDesc,
&secondaryDesc,
hWnd,
DSSCL_NORMAL,
&d->lpDirectSoundFullDuplex,
(LPDIRECTSOUNDCAPTUREBUFFER8*)&d->lpDirectSoundInputBuffer,
(LPDIRECTSOUNDBUFFER8*)&d->lpDirectSound,
(LPDIRECTSOUNDCAPTUREBUFFER8*)&d_capture_filter->lpDirectSoundInputBuffer,
(LPDIRECTSOUNDBUFFER8*)&d->lpDirectSoundOutputBuffer,
NULL);
}
if (hr!=DS_OK)
......@@ -785,18 +820,17 @@ static void winsndds_write_preprocess(MSFilter *f){
}
ms_message("full duplex and echo canceller: activated!");
d->readOffset = 0;
d_capture_filter->readOffset = 0;
hr = IDirectSoundCaptureBuffer_Start( d->lpDirectSoundInputBuffer, DSCBSTART_LOOPING );
hr = IDirectSoundCaptureBuffer_Start( d_capture_filter->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);
ms_ticker_set_time_func(f_capture_filter->ticker,winsndds_get_cur_time,d_capture_filter);
d_capture_filter->thread_running=TRUE;
ms_thread_create(&d_capture_filter->thread,NULL,winsndds_read_thread,d_capture_filter);
ms_mutex_lock(&d_capture_filter->thread_lock);
ms_cond_wait(&d_capture_filter->thread_cond,&d_capture_filter->thread_lock);
ms_mutex_unlock(&d_capture_filter->thread_lock);
}
else
{
......@@ -866,6 +900,7 @@ static void winsndds_write_preprocess(MSFilter *f){
{
return ;
}
hr = IDirectSoundBuffer_Play( d->lpDirectSoundOutputBuffer, 0, 0, DSBPLAY_LOOPING);
if( hr != DS_OK )
{
......@@ -908,7 +943,7 @@ static void winsndds_write_process(MSFilter *f){
DWORD dwStatus;
HRESULT hr;
if (d->lpDirectSound==NULL) {
if (d->lpDirectSoundOutputBuffer==NULL) {
ms_queue_flush(f->inputs[0]);
return;
}
......@@ -945,8 +980,6 @@ static void winsndds_write_process(MSFilter *f){
//ms_message("DS information: last_writeOffset=%i current_playOffset=%i current_writeOffset=%i max_writable=%i",
// d->writeOffset, current_playOffset, currentWriteOffset, msize_max);
//d->writeOffset = outputBufferWriteOffsetBytes;
hr = IDirectSoundBuffer_GetStatus (d->lpDirectSoundOutputBuffer, &dwStatus);
if (dwStatus & DSBSTATUS_BUFFERLOST) {
hr = IDirectSoundBuffer_Restore (d->lpDirectSoundOutputBuffer);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment