* Sync to Wine 1.3.29 in an attempt to get it working again.
* Dedicated to Daniel Reimer.
* Thanks to Sylvain for pinpointing this version.

svn path=/trunk/; revision=64379
This commit is contained in:
Amine Khaldi 2014-09-28 20:12:26 +00:00
parent a03f39b92f
commit 17cc5b0dab
16 changed files with 5961 additions and 5111 deletions

View file

@ -30,5 +30,5 @@ if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
target_link_libraries(dsound mingwex)
endif()
add_importlibs(dsound winmm ole32 advapi32 user32 msvcrt kernel32 ntdll)
add_importlibs(dsound winmm advapi32 msvcrt kernel32 ntdll)
add_cd_file(TARGET dsound DESTINATION reactos/system32 FOR all)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -44,214 +44,488 @@
#define le32(x) (x)
#endif
/* This is an inlined version of lrintf. */
#if defined(_MSC_VER)
#if defined(_M_AMD64)
#include <xmmintrin.h>
#endif
FORCEINLINE
int
lrintf(float f)
static inline void src_advance(const void **src, UINT stride, INT *count, UINT *freqAcc, UINT adj)
{
#if defined(_M_IX86)
int result;
__asm
*freqAcc += adj;
if (*freqAcc >= (1 << DSOUND_FREQSHIFT))
{
fld f;
fistp result;
ULONG adv = (*freqAcc >> DSOUND_FREQSHIFT);
*freqAcc &= (1 << DSOUND_FREQSHIFT) - 1;
*(const char **)src += adv * stride;
*count -= adv;
}
return result;
#elif defined(_M_AMD64)
return _mm_cvtss_si32(_mm_load_ss(&f));
#endif
}
#endif
static float get8(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
static void convert_8_to_8 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
const BYTE* buf = dsb->buffer->memory;
buf += pos + channel;
return (buf[0] - 0x80) / (float)0x80;
while (count > 0)
{
*(BYTE *)dst = *(const BYTE *)src;
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static float get16(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
static void convert_8_to_16 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
const BYTE* buf = dsb->buffer->memory;
const SHORT *sbuf = (const SHORT*)(buf + pos + 2 * channel);
SHORT sample = (SHORT)le16(*sbuf);
return sample / (float)0x8000;
while (count > 0)
{
WORD dest = *(const BYTE *)src, *dest16 = dst;
*dest16 = le16(dest * 257 - 32768);
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static float get24(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
static void convert_8_to_24 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
LONG sample;
const BYTE* buf = dsb->buffer->memory;
buf += pos + 3 * channel;
/* The next expression deliberately has an overflow for buf[2] >= 0x80,
this is how negative values are made.
*/
sample = (buf[0] << 8) | (buf[1] << 16) | (buf[2] << 24);
return sample / (float)0x80000000U;
while (count > 0)
{
BYTE dest = *(const BYTE *)src;
BYTE *dest24 = dst;
dest24[0] = dest;
dest24[1] = dest;
dest24[2] = dest - 0x80;
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static float get32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
static void convert_8_to_32 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
const BYTE* buf = dsb->buffer->memory;
const LONG *sbuf = (const LONG*)(buf + pos + 4 * channel);
LONG sample = le32(*sbuf);
return sample / (float)0x80000000U;
while (count > 0)
{
DWORD dest = *(const BYTE *)src, *dest32 = dst;
*dest32 = le32(dest * 16843009 - 2147483648U);
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static float getieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
static void convert_16_to_8 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
const BYTE* buf = dsb->buffer->memory;
const float *sbuf = (const float*)(buf + pos + 4 * channel);
/* The value will be clipped later, when put into some non-float buffer */
return *sbuf;
while (count > 0)
{
BYTE *dst8 = dst;
*dst8 = (le16(*(const WORD *)src)) / 256;
*dst8 -= 0x80;
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
const bitsgetfunc getbpp[5] = {get8, get16, get24, get32, getieee32};
float get_mono(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
static void convert_16_to_16 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
DWORD channels = dsb->pwfx->nChannels;
DWORD c;
float val = 0;
/* XXX: does Windows include LFE into the mix? */
for (c = 0; c < channels; c++)
val += dsb->get_aux(dsb, pos, c);
val /= channels;
return val;
while (count > 0)
{
*(WORD *)dst = *(const WORD *)src;
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static inline unsigned char f_to_8(float value)
static void convert_16_to_24 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
if(value <= -1.f)
return 0;
if(value >= 1.f * 0x7f / 0x80)
return 0xFF;
return lrintf((value + 1.f) * 0x80);
while (count > 0)
{
WORD dest = le16(*(const WORD *)src);
BYTE *dest24 = dst;
dest24[0] = dest / 256;
dest24[1] = dest;
dest24[2] = dest / 256;
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static inline SHORT f_to_16(float value)
static void convert_16_to_32 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
if(value <= -1.f)
return 0x8000;
if(value >= 1.f * 0x7FFF / 0x8000)
return 0x7FFF;
return le16(lrintf(value * 0x8000));
while (count > 0)
{
DWORD dest = *(const WORD *)src, *dest32 = dst;
*dest32 = dest * 65537;
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static LONG f_to_24(float value)
static void convert_24_to_8 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
if(value <= -1.f)
return 0x80000000;
if(value >= 1.f * 0x7FFFFF / 0x800000)
return 0x7FFFFF00;
return lrintf(value * 0x80000000U);
while (count > 0)
{
BYTE *dst8 = dst;
*dst8 = ((const BYTE *)src)[2];
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static inline LONG f_to_32(float value)
static void convert_24_to_16 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
if(value <= -1.f)
return 0x80000000;
if(value >= 1.f * 0x7FFFFFFF / 0x80000000U) /* this rounds to 1.f */
return 0x7FFFFFFF;
return le32(lrintf(value * 0x80000000U));
while (count > 0)
{
WORD *dest16 = dst;
const BYTE *source = src;
*dest16 = le16(source[2] * 256 + source[1]);
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value)
static void convert_24_to_24 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
BYTE *buf = (BYTE *)dsb->device->tmp_buffer;
float *fbuf = (float*)(buf + pos + sizeof(float) * channel);
*fbuf = value;
while (count > 0)
{
BYTE *dest24 = dst;
const BYTE *src24 = src;
dest24[0] = src24[0];
dest24[1] = src24[1];
dest24[2] = src24[2];
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
void put_mono2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value)
static void convert_24_to_32 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
dsb->put_aux(dsb, pos, 0, value);
dsb->put_aux(dsb, pos, 1, value);
while (count > 0)
{
DWORD *dest32 = dst;
const BYTE *source = src;
*dest32 = le32(source[2] * 16777217 + source[1] * 65536 + source[0] * 256);
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
void mixieee32(float *src, float *dst, unsigned samples)
static void convert_32_to_8 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
TRACE("%p - %p %d\n", src, dst, samples);
while (samples--)
*(dst++) += *(src++);
while (count > 0)
{
BYTE *dst8 = dst;
*dst8 = (le32(*(const DWORD *)src) / 16777216);
*dst8 -= 0x80;
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static void norm8(float *src, unsigned char *dst, unsigned len)
static void convert_32_to_16 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
while (count > 0)
{
WORD *dest16 = dst;
*dest16 = le16(le32(*(const DWORD *)src) / 65536);
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static void convert_32_to_24 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
while (count > 0)
{
DWORD dest = le32(*(const DWORD *)src);
BYTE *dest24 = dst;
dest24[0] = dest / 256;
dest24[1] = dest / 65536;
dest24[2] = dest / 16777216;
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static void convert_32_to_32 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
while (count > 0)
{
DWORD *dest = dst;
*dest = *(const DWORD *)src;
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static void convert_ieee_32_to_8 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
while (count > 0)
{
DWORD src_le = le32(*(DWORD *) src);
float v = *((float *) &src_le);
INT8 d = 0;
if (v < -1.0f)
d = -128;
else if (v > 1.0f)
d = 127;
else
d = v * 127.5f - 0.5f;
*(BYTE *) dst = d ^ 0x80;
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static void convert_ieee_32_to_16 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
while (count > 0)
{
DWORD src_le = le32(*(DWORD *) src);
float v = *((float *) &src_le);
INT16 *d = (INT16 *) dst;
if (v < -1.0f)
*d = -32768;
else if (v > 1.0f)
*d = 32767;
else
*d = v * 32767.5f - 0.5f;
*d = le16(*d);
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static void convert_ieee_32_to_24 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
while (count > 0)
{
DWORD src_le = le32(*(DWORD *) src);
float v = *((float *) &src_le);
BYTE *dest24 = dst;
if (v < -1.0f)
{
dest24[0] = 0;
dest24[1] = 0;
dest24[2] = 0x80;
}
else if (v > 1.0f)
{
dest24[0] = 0xff;
dest24[1] = 0xff;
dest24[2] = 0x7f;
}
else if (v < 0.0f)
{
dest24[0] = v * 8388608.0f;
dest24[1] = v * 32768.0f;
dest24[2] = v * 128.0f;
}
else if (v >= 0.0f)
{
dest24[0] = v * 8388608.0f;
dest24[1] = v * 32768.0f;
dest24[2] = v * 127.0f;
}
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
static void convert_ieee_32_to_32 (const void *src, void *dst, UINT src_stride,
UINT dst_stride, INT count, UINT freqAcc, UINT adj)
{
while (count > 0)
{
DWORD src_le = le32(*(DWORD *) src);
float v = *((float *) &src_le);
INT32 *d = (INT32 *) dst;
if (v < -1.0f)
*d = -2147483647 - 1; /* silence warning */
else if (v > 1.0f)
*d = 2147483647;
else
*d = v * 2147483647.5f - 0.5f;
*d = le32(*d);
dst = (char *)dst + dst_stride;
src_advance(&src, src_stride, &count, &freqAcc, adj);
}
}
const bitsconvertfunc convertbpp[5][4] = {
{ convert_8_to_8, convert_8_to_16, convert_8_to_24, convert_8_to_32 },
{ convert_16_to_8, convert_16_to_16, convert_16_to_24, convert_16_to_32 },
{ convert_24_to_8, convert_24_to_16, convert_24_to_24, convert_24_to_32 },
{ convert_32_to_8, convert_32_to_16, convert_32_to_24, convert_32_to_32 },
{ convert_ieee_32_to_8, convert_ieee_32_to_16, convert_ieee_32_to_24, convert_ieee_32_to_32 },
};
static void mix8(signed char *src, INT *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
while (len--)
{
*dst = f_to_8(*src);
++dst;
++src;
}
/* 8-bit WAV is unsigned, it's here converted to signed, normalize function will convert it back again */
*(dst++) += (signed char)((BYTE)*(src++) - (BYTE)0x80);
}
static void norm16(float *src, SHORT *dst, unsigned len)
static void mix16(SHORT *src, INT *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
len /= 2;
while (len--)
{
*dst = f_to_16(*src);
++dst;
++src;
*dst += le16(*src);
++dst; ++src;
}
}
static void norm24(float *src, BYTE *dst, unsigned len)
static void mix24(BYTE *src, INT *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
len /= 3;
while (len--)
{
LONG t = f_to_24(*src);
dst[0] = (t >> 8) & 0xFF;
dst[1] = (t >> 16) & 0xFF;
dst[2] = t >> 24;
dst += 3;
DWORD field;
field = ((DWORD)src[2] << 16) + ((DWORD)src[1] << 8) + (DWORD)src[0];
if (src[2] & 0x80)
field |= 0xFF000000U;
*(dst++) += field;
++src;
}
}
static void norm32(float *src, INT *dst, unsigned len)
static void mix32(INT *src, LONGLONG *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
len /= 4;
while (len--)
*(dst++) += le32(*(src++));
}
const mixfunc mixfunctions[4] = {
(mixfunc)mix8,
(mixfunc)mix16,
(mixfunc)mix24,
(mixfunc)mix32
};
static void norm8(INT *src, signed char *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
while (len--)
{
*dst = f_to_32(*src);
*dst = (*src) + 0x80;
if (*src < -0x80)
*dst = 0;
else if (*src > 0x7f)
*dst = 0xff;
++dst;
++src;
}
}
static void normieee32(float *src, float *dst, unsigned len)
static void norm16(INT *src, SHORT *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
len /= 4;
len /= 2;
while (len--)
{
if(*src > 1)
*dst = 1;
else if(*src < -1)
*dst = -1;
*dst = le16(*src);
if (*src <= -0x8000)
*dst = le16(0x8000);
else if (*src > 0x7fff)
*dst = le16(0x7fff);
++dst;
++src;
}
}
static void norm24(INT *src, BYTE *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
len /= 3;
while (len--)
{
if (*src <= -0x800000)
{
dst[0] = 0;
dst[1] = 0;
dst[2] = 0x80;
}
else if (*src > 0x7fffff)
{
dst[0] = 0xff;
dst[1] = 0xff;
dst[2] = 0x7f;
}
else
*dst = *src;
{
dst[0] = *src;
dst[1] = *src >> 8;
dst[2] = *src >> 16;
}
++dst;
++src;
}
}
const normfunc normfunctions[5] = {
static void norm32(LONGLONG *src, INT *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
len /= 4;
while (len--)
{
*dst = le32(*src);
if (*src <= -(LONGLONG)0x80000000)
*dst = le32(0x80000000);
else if (*src > 0x7fffffff)
*dst = le32(0x7fffffff);
++dst;
++src;
}
}
const normfunc normfunctions[4] = {
(normfunc)norm8,
(normfunc)norm16,
(normfunc)norm24,
(normfunc)norm32,
(normfunc)normieee32
};

View file

@ -37,34 +37,48 @@
#include <winreg.h>
#include <rpcproxy.h>
struct list DSOUND_renderers = LIST_INIT(DSOUND_renderers);
CRITICAL_SECTION DSOUND_renderers_lock;
static CRITICAL_SECTION_DEBUG DSOUND_renderers_lock_debug =
{
0, 0, &DSOUND_renderers_lock,
{ &DSOUND_renderers_lock_debug.ProcessLocksList, &DSOUND_renderers_lock_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": DSOUND_renderers_lock") }
};
CRITICAL_SECTION DSOUND_renderers_lock = { &DSOUND_renderers_lock_debug, -1, 0, 0, 0, 0 };
struct list DSOUND_capturers = LIST_INIT(DSOUND_capturers);
CRITICAL_SECTION DSOUND_capturers_lock;
static CRITICAL_SECTION_DEBUG DSOUND_capturers_lock_debug =
{
0, 0, &DSOUND_capturers_lock,
{ &DSOUND_capturers_lock_debug.ProcessLocksList, &DSOUND_capturers_lock_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": DSOUND_capturers_lock") }
};
CRITICAL_SECTION DSOUND_capturers_lock = { &DSOUND_capturers_lock_debug, -1, 0, 0, 0, 0 };
DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS];
GUID DSOUND_renderer_guids[MAXWAVEDRIVERS];
GUID DSOUND_capture_guids[MAXWAVEDRIVERS];
WCHAR wine_vxd_drv[] = { 'w','i','n','e','m','m','.','v','x','d', 0 };
HRESULT mmErr(UINT err)
{
switch(err) {
case MMSYSERR_NOERROR:
return DS_OK;
case MMSYSERR_ALLOCATED:
return DSERR_ALLOCATED;
case MMSYSERR_ERROR:
case MMSYSERR_INVALHANDLE:
case WAVERR_STILLPLAYING:
return DSERR_GENERIC; /* FIXME */
case MMSYSERR_NODRIVER:
return DSERR_NODRIVER;
case MMSYSERR_NOMEM:
return DSERR_OUTOFMEMORY;
case MMSYSERR_INVALPARAM:
case WAVERR_BADFORMAT:
case WAVERR_UNPREPARED:
return DSERR_INVALIDPARAM;
case MMSYSERR_NOTSUPPORTED:
return DSERR_UNSUPPORTED;
default:
FIXME("Unknown MMSYS error %d\n",err);
return DSERR_GENERIC;
}
}
/* All default settings, you most likely don't want to touch these, see wiki on UsefulRegistryKeys */
int ds_emuldriver = 0;
int ds_hel_buflen = 32768 * 2;
int ds_snd_queue_max = 10;
int ds_snd_queue_min = 6;
int ds_snd_shadow_maxsize = 2;
int ds_hw_accel = DS_HW_ACCEL_FULL;
int ds_default_sample_rate = 44100;
int ds_default_bits_per_sample = 16;
static int ds_default_playback;
static int ds_default_capture;
static HINSTANCE instance;
/*
@ -114,18 +128,62 @@ void setup_dsound_options(void)
/* get options */
if (!get_config_key( hkey, appkey, "EmulDriver", buffer, MAX_PATH ))
ds_emuldriver = strcmp(buffer, "N");
if (!get_config_key( hkey, appkey, "HelBuflen", buffer, MAX_PATH ))
ds_hel_buflen = atoi(buffer);
if (!get_config_key( hkey, appkey, "SndQueueMax", buffer, MAX_PATH ))
ds_snd_queue_max = atoi(buffer);
if (!get_config_key( hkey, appkey, "SndQueueMin", buffer, MAX_PATH ))
ds_snd_queue_min = atoi(buffer);
if (!get_config_key( hkey, appkey, "HardwareAcceleration", buffer, MAX_PATH )) {
if (strcmp(buffer, "Full") == 0)
ds_hw_accel = DS_HW_ACCEL_FULL;
else if (strcmp(buffer, "Standard") == 0)
ds_hw_accel = DS_HW_ACCEL_STANDARD;
else if (strcmp(buffer, "Basic") == 0)
ds_hw_accel = DS_HW_ACCEL_BASIC;
else if (strcmp(buffer, "Emulation") == 0)
ds_hw_accel = DS_HW_ACCEL_EMULATION;
}
if (!get_config_key( hkey, appkey, "DefaultPlayback", buffer, MAX_PATH ))
ds_default_playback = atoi(buffer);
if (!get_config_key( hkey, appkey, "MaxShadowSize", buffer, MAX_PATH ))
ds_snd_shadow_maxsize = atoi(buffer);
if (!get_config_key( hkey, appkey, "DefaultCapture", buffer, MAX_PATH ))
ds_default_capture = atoi(buffer);
if (!get_config_key( hkey, appkey, "DefaultSampleRate", buffer, MAX_PATH ))
ds_default_sample_rate = atoi(buffer);
if (!get_config_key( hkey, appkey, "DefaultBitsPerSample", buffer, MAX_PATH ))
ds_default_bits_per_sample = atoi(buffer);
if (appkey) RegCloseKey( appkey );
if (hkey) RegCloseKey( hkey );
TRACE("ds_emuldriver = %d\n", ds_emuldriver);
TRACE("ds_hel_buflen = %d\n", ds_hel_buflen);
TRACE("ds_snd_queue_max = %d\n", ds_snd_queue_max);
TRACE("ds_snd_queue_min = %d\n", ds_snd_queue_min);
TRACE("ds_hw_accel = %s\n",
ds_hw_accel==DS_HW_ACCEL_FULL ? "Full" :
ds_hw_accel==DS_HW_ACCEL_STANDARD ? "Standard" :
ds_hw_accel==DS_HW_ACCEL_BASIC ? "Basic" :
ds_hw_accel==DS_HW_ACCEL_EMULATION ? "Emulation" :
"Unknown");
TRACE("ds_default_playback = %d\n", ds_default_playback);
TRACE("ds_default_capture = %d\n", ds_default_playback);
TRACE("ds_default_sample_rate = %d\n", ds_default_sample_rate);
TRACE("ds_default_bits_per_sample = %d\n", ds_default_bits_per_sample);
TRACE("ds_snd_shadow_maxsize = %d\n", ds_snd_shadow_maxsize);
}
static const char * get_device_id(LPCGUID pGuid)
@ -141,64 +199,6 @@ static const char * get_device_id(LPCGUID pGuid)
return debugstr_guid(pGuid);
}
static HRESULT get_mmdevenum(IMMDeviceEnumerator **devenum)
{
HRESULT hr, init_hr;
init_hr = CoInitialize(NULL);
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)devenum);
if(FAILED(hr)){
if(SUCCEEDED(init_hr))
CoUninitialize();
*devenum = NULL;
ERR("CoCreateInstance failed: %08x\n", hr);
return hr;
}
return init_hr;
}
static void release_mmdevenum(IMMDeviceEnumerator *devenum, HRESULT init_hr)
{
IMMDeviceEnumerator_Release(devenum);
if(SUCCEEDED(init_hr))
CoUninitialize();
}
static HRESULT get_mmdevice_guid(IMMDevice *device, IPropertyStore *ps,
GUID *guid)
{
PROPVARIANT pv;
HRESULT hr;
if(!ps){
hr = IMMDevice_OpenPropertyStore(device, STGM_READ, &ps);
if(FAILED(hr)){
WARN("OpenPropertyStore failed: %08x\n", hr);
return hr;
}
}else
IPropertyStore_AddRef(ps);
PropVariantInit(&pv);
hr = IPropertyStore_GetValue(ps, &PKEY_AudioEndpoint_GUID, &pv);
if(FAILED(hr)){
IPropertyStore_Release(ps);
WARN("GetValue(GUID) failed: %08x\n", hr);
return hr;
}
CLSIDFromString(pv.u.pwszVal, guid);
PropVariantClear(&pv);
IPropertyStore_Release(ps);
return S_OK;
}
/***************************************************************************
* GetDeviceID [DSOUND.9]
*
@ -221,56 +221,34 @@ static HRESULT get_mmdevice_guid(IMMDevice *device, IPropertyStore *ps,
*/
HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
{
IMMDeviceEnumerator *devenum;
EDataFlow flow = (EDataFlow)-1;
ERole role = (ERole)-1;
HRESULT hr, init_hr;
TRACE("(%s,%p)\n", get_device_id(pGuidSrc),pGuidDest);
if(!pGuidSrc || !pGuidDest)
return DSERR_INVALIDPARAM;
init_hr = get_mmdevenum(&devenum);
if(!devenum)
return init_hr;
if(IsEqualGUID(&DSDEVID_DefaultPlayback, pGuidSrc)){
role = eMultimedia;
flow = eRender;
}else if(IsEqualGUID(&DSDEVID_DefaultVoicePlayback, pGuidSrc)){
role = eCommunications;
flow = eRender;
}else if(IsEqualGUID(&DSDEVID_DefaultCapture, pGuidSrc)){
role = eMultimedia;
flow = eCapture;
}else if(IsEqualGUID(&DSDEVID_DefaultVoiceCapture, pGuidSrc)){
role = eCommunications;
flow = eCapture;
if ( pGuidSrc == NULL) {
WARN("invalid parameter: pGuidSrc == NULL\n");
return DSERR_INVALIDPARAM;
}
if(role != (ERole)-1 && flow != (EDataFlow)-1){
IMMDevice *device;
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum,
flow, role, &device);
if(FAILED(hr)){
WARN("GetDefaultAudioEndpoint failed: %08x\n", hr);
release_mmdevenum(devenum, init_hr);
return DSERR_NODRIVER;
}
hr = get_mmdevice_guid(device, NULL, pGuidDest);
IMMDevice_Release(device);
release_mmdevenum(devenum, init_hr);
return (hr == S_OK) ? DS_OK : hr;
if ( pGuidDest == NULL ) {
WARN("invalid parameter: pGuidDest == NULL\n");
return DSERR_INVALIDPARAM;
}
release_mmdevenum(devenum, init_hr);
if ( IsEqualGUID( &DSDEVID_DefaultPlayback, pGuidSrc ) ||
IsEqualGUID( &DSDEVID_DefaultVoicePlayback, pGuidSrc ) ) {
*pGuidDest = DSOUND_renderer_guids[ds_default_playback];
TRACE("returns %s\n", get_device_id(pGuidDest));
return DS_OK;
}
if ( IsEqualGUID( &DSDEVID_DefaultCapture, pGuidSrc ) ||
IsEqualGUID( &DSDEVID_DefaultVoiceCapture, pGuidSrc ) ) {
*pGuidDest = DSOUND_capture_guids[ds_default_capture];
TRACE("returns %s\n", get_device_id(pGuidDest));
return DS_OK;
}
*pGuidDest = *pGuidSrc;
TRACE("returns %s\n", get_device_id(pGuidDest));
return DS_OK;
}
@ -322,187 +300,6 @@ HRESULT WINAPI DirectSoundEnumerateA(
return DirectSoundEnumerateW(a_to_w_callback, &context);
}
HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device)
{
IMMDeviceEnumerator *devenum;
IMMDeviceCollection *coll;
UINT count, i;
HRESULT hr, init_hr;
init_hr = get_mmdevenum(&devenum);
if(!devenum)
return init_hr;
hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flow,
DEVICE_STATE_ACTIVE, &coll);
if(FAILED(hr)){
WARN("EnumAudioEndpoints failed: %08x\n", hr);
release_mmdevenum(devenum, init_hr);
return hr;
}
hr = IMMDeviceCollection_GetCount(coll, &count);
if(FAILED(hr)){
IMMDeviceCollection_Release(coll);
release_mmdevenum(devenum, init_hr);
WARN("GetCount failed: %08x\n", hr);
return hr;
}
for(i = 0; i < count; ++i){
GUID guid;
hr = IMMDeviceCollection_Item(coll, i, device);
if(FAILED(hr))
continue;
hr = get_mmdevice_guid(*device, NULL, &guid);
if(FAILED(hr)){
IMMDevice_Release(*device);
continue;
}
if(IsEqualGUID(&guid, tgt)){
IMMDeviceCollection_Release(coll);
release_mmdevenum(devenum, init_hr);
return DS_OK;
}
IMMDevice_Release(*device);
}
WARN("No device with GUID %s found!\n", wine_dbgstr_guid(tgt));
IMMDeviceCollection_Release(coll);
release_mmdevenum(devenum, init_hr);
return DSERR_INVALIDPARAM;
}
static BOOL send_device(IMMDevice *device, GUID *guid,
LPDSENUMCALLBACKW cb, void *user)
{
IPropertyStore *ps;
PROPVARIANT pv;
BOOL keep_going;
HRESULT hr;
PropVariantInit(&pv);
hr = IMMDevice_OpenPropertyStore(device, STGM_READ, &ps);
if(FAILED(hr)){
WARN("OpenPropertyStore failed: %08x\n", hr);
return TRUE;
}
hr = get_mmdevice_guid(device, ps, guid);
if(FAILED(hr)){
IPropertyStore_Release(ps);
return TRUE;
}
hr = IPropertyStore_GetValue(ps,
(const PROPERTYKEY *)&DEVPKEY_Device_FriendlyName, &pv);
if(FAILED(hr)){
IPropertyStore_Release(ps);
WARN("GetValue(FriendlyName) failed: %08x\n", hr);
return TRUE;
}
TRACE("Calling back with %s (%s)\n", wine_dbgstr_guid(guid),
wine_dbgstr_w(pv.u.pwszVal));
keep_going = cb(guid, pv.u.pwszVal, wine_vxd_drv, user);
PropVariantClear(&pv);
IPropertyStore_Release(ps);
return keep_going;
}
/* S_FALSE means the callback returned FALSE at some point
* S_OK means the callback always returned TRUE */
HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
LPDSENUMCALLBACKW cb, void *user)
{
IMMDeviceEnumerator *devenum;
IMMDeviceCollection *coll;
IMMDevice *defdev = NULL;
UINT count, i, n;
BOOL keep_going;
HRESULT hr, init_hr;
static const WCHAR primary_desc[] = {'P','r','i','m','a','r','y',' ',
'S','o','u','n','d',' ','D','r','i','v','e','r',0};
static const WCHAR empty_drv[] = {0};
init_hr = get_mmdevenum(&devenum);
if(!devenum)
return init_hr;
hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flow,
DEVICE_STATE_ACTIVE, &coll);
if(FAILED(hr)){
release_mmdevenum(devenum, init_hr);
WARN("EnumAudioEndpoints failed: %08x\n", hr);
return DS_OK;
}
hr = IMMDeviceCollection_GetCount(coll, &count);
if(FAILED(hr)){
IMMDeviceCollection_Release(coll);
release_mmdevenum(devenum, init_hr);
WARN("GetCount failed: %08x\n", hr);
return DS_OK;
}
if(count == 0){
release_mmdevenum(devenum, init_hr);
return DS_OK;
}
TRACE("Calling back with NULL (%s)\n", wine_dbgstr_w(primary_desc));
keep_going = cb(NULL, primary_desc, empty_drv, user);
/* always send the default device first */
if(keep_going){
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, flow,
eMultimedia, &defdev);
if(FAILED(hr)){
defdev = NULL;
n = 0;
}else{
keep_going = send_device(defdev, &guids[0], cb, user);
n = 1;
}
}
for(i = 0; keep_going && i < count; ++i){
IMMDevice *device;
hr = IMMDeviceCollection_Item(coll, i, &device);
if(FAILED(hr)){
WARN("Item failed: %08x\n", hr);
continue;
}
if(device != defdev){
send_device(device, &guids[n], cb, user);
++n;
}
IMMDevice_Release(device);
}
if(defdev)
IMMDevice_Release(defdev);
IMMDeviceCollection_Release(coll);
release_mmdevenum(devenum, init_hr);
return (keep_going == TRUE) ? S_OK : S_FALSE;
}
/***************************************************************************
* DirectSoundEnumerateW [DSOUND.3]
*
@ -520,20 +317,61 @@ HRESULT WINAPI DirectSoundEnumerateW(
LPDSENUMCALLBACKW lpDSEnumCallback,
LPVOID lpContext )
{
HRESULT hr;
unsigned devs, wod;
DSDRIVERDESC desc;
GUID guid;
int err;
WCHAR wDesc[MAXPNAMELEN];
WCHAR wName[MAXPNAMELEN];
TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext);
TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
lpDSEnumCallback, lpContext);
if (lpDSEnumCallback == NULL) {
WARN("invalid parameter: lpDSEnumCallback == NULL\n");
return DSERR_INVALIDPARAM;
WARN("invalid parameter: lpDSEnumCallback == NULL\n");
return DSERR_INVALIDPARAM;
}
setup_dsound_options();
hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
lpDSEnumCallback, lpContext);
return SUCCEEDED(hr) ? DS_OK : hr;
devs = waveOutGetNumDevs();
if (devs > 0) {
if (GetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) {
static const WCHAR empty[] = { 0 };
for (wod = 0; wod < devs; ++wod) {
if (IsEqualGUID( &guid, &DSOUND_renderer_guids[wod] ) ) {
err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
"Primary Sound Driver",desc.szDrvname,lpContext);
MultiByteToWideChar( CP_ACP, 0, "Primary Sound Driver", -1,
wDesc, sizeof(wDesc)/sizeof(WCHAR) );
if (lpDSEnumCallback(NULL, wDesc, empty, lpContext) == FALSE)
return DS_OK;
}
}
}
}
}
for (wod = 0; wod < devs; ++wod) {
err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&DSOUND_renderer_guids[wod]),desc.szDesc,desc.szDrvname,lpContext);
MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
wDesc, sizeof(wDesc)/sizeof(WCHAR) );
wDesc[(sizeof(wDesc)/sizeof(WCHAR)) - 1] = '\0';
MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
wName, sizeof(wName)/sizeof(WCHAR) );
wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0';
if (lpDSEnumCallback(&DSOUND_renderer_guids[wod], wDesc, wName, lpContext) == FALSE)
return DS_OK;
}
}
return DS_OK;
}
/***************************************************************************
@ -584,20 +422,64 @@ DirectSoundCaptureEnumerateW(
LPDSENUMCALLBACKW lpDSEnumCallback,
LPVOID lpContext)
{
HRESULT hr;
unsigned devs, wid;
DSDRIVERDESC desc;
GUID guid;
int err;
WCHAR wDesc[MAXPNAMELEN];
WCHAR wName[MAXPNAMELEN];
TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
if (lpDSEnumCallback == NULL) {
WARN("invalid parameter: lpDSEnumCallback == NULL\n");
WARN("invalid parameter: lpDSEnumCallback == NULL\n");
return DSERR_INVALIDPARAM;
}
setup_dsound_options();
hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
lpDSEnumCallback, lpContext);
return SUCCEEDED(hr) ? DS_OK : hr;
devs = waveInGetNumDevs();
if (devs > 0) {
if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) {
for (wid = 0; wid < devs; ++wid) {
if (IsEqualGUID( &guid, &DSOUND_capture_guids[wid] ) ) {
err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
"Primary Sound Capture Driver",desc.szDrvname,lpContext);
MultiByteToWideChar( CP_ACP, 0, "Primary Sound Capture Driver", -1,
wDesc, sizeof(wDesc)/sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
wName, sizeof(wName)/sizeof(WCHAR) );
wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0';
if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE)
return DS_OK;
}
}
}
}
}
for (wid = 0; wid < devs; ++wid) {
err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&DSOUND_capture_guids[wid]),desc.szDesc,desc.szDrvname,lpContext);
MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
wDesc, sizeof(wDesc)/sizeof(WCHAR) );
wDesc[(sizeof(wDesc)/sizeof(WCHAR)) - 1] = '\0';
MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
wName, sizeof(wName)/sizeof(WCHAR) );
wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0';
if (lpDSEnumCallback(&DSOUND_capture_guids[wid], wDesc, wName, lpContext) == FALSE)
return DS_OK;
}
}
return DS_OK;
}
/*******************************************************************************
@ -618,7 +500,7 @@ static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
}
static HRESULT WINAPI
DSCF_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppobj)
DSCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppobj)
{
IClassFactoryImpl *This = impl_from_IClassFactory(iface);
TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
@ -628,7 +510,7 @@ DSCF_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppobj)
IsEqualIID(riid, &IID_IClassFactory))
{
*ppobj = iface;
IClassFactory_AddRef(iface);
IUnknown_AddRef(iface);
return S_OK;
}
*ppobj = NULL;
@ -682,12 +564,12 @@ static const IClassFactoryVtbl DSCF_Vtbl = {
};
static IClassFactoryImpl DSOUND_CF[] = {
{ { &DSCF_Vtbl }, &CLSID_DirectSound, DSOUND_Create },
{ { &DSCF_Vtbl }, &CLSID_DirectSound8, DSOUND_Create8 },
{ { &DSCF_Vtbl }, &CLSID_DirectSoundCapture, DSOUND_CaptureCreate },
{ { &DSCF_Vtbl }, &CLSID_DirectSoundCapture8, DSOUND_CaptureCreate8 },
{ { &DSCF_Vtbl }, &CLSID_DirectSoundFullDuplex, DSOUND_FullDuplexCreate },
{ { &DSCF_Vtbl }, &CLSID_DirectSoundPrivate, IKsPrivatePropertySetImpl_Create },
{ { &DSCF_Vtbl }, &CLSID_DirectSound, (FnCreateInstance)DSOUND_Create },
{ { &DSCF_Vtbl }, &CLSID_DirectSound8, (FnCreateInstance)DSOUND_Create8 },
{ { &DSCF_Vtbl }, &CLSID_DirectSoundCapture, (FnCreateInstance)DSOUND_CaptureCreate },
{ { &DSCF_Vtbl }, &CLSID_DirectSoundCapture8, (FnCreateInstance)DSOUND_CaptureCreate8 },
{ { &DSCF_Vtbl }, &CLSID_DirectSoundFullDuplex, (FnCreateInstance)DSOUND_FullDuplexCreate },
{ { &DSCF_Vtbl }, &CLSID_DirectSoundPrivate, (FnCreateInstance)IKsPrivatePropertySetImpl_Create },
{ { NULL }, NULL, NULL }
};
@ -765,11 +647,18 @@ HRESULT WINAPI DllCanUnloadNow(void)
*/
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
int i;
TRACE("(%p %d %p)\n", hInstDLL, fdwReason, lpvReserved);
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
TRACE("DLL_PROCESS_ATTACH\n");
for (i = 0; i < MAXWAVEDRIVERS; i++) {
DSOUND_renderer[i] = NULL;
DSOUND_capture[i] = NULL;
INIT_GUID(DSOUND_renderer_guids[i], 0xbd6dd71a, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i);
INIT_GUID(DSOUND_capture_guids[i], 0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i);
}
instance = hInstDLL;
DisableThreadLibraryCalls(hInstDLL);
/* Increase refcount on dsound by 1 */
@ -777,8 +666,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
break;
case DLL_PROCESS_DETACH:
TRACE("DLL_PROCESS_DETACH\n");
DeleteCriticalSection(&DSOUND_renderers_lock);
DeleteCriticalSection(&DSOUND_capturers_lock);
break;
default:
TRACE("UNKNOWN REASON\n");

View file

@ -42,13 +42,12 @@
#include <wingdi.h>
#include <winternl.h>
#include <objbase.h>
#include <mmdeviceapi.h>
#include <audioclient.h>
#include <mmsystem.h>
#include <mmddk.h>
#include <dsound.h>
#include <dsconf.h>
#include <dsdriver.h>
#include <vfwmsgs.h>
#include <devpkey.h>
#include <wine/debug.h>
#include <wine/list.h>
@ -59,34 +58,48 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound);
#define DS_TIME_RES 2 /* Resolution of multimedia timer */
#define DS_TIME_DEL 10 /* Delay of multimedia timer callback, and duration of HEL fragment */
/* direct sound hardware acceleration levels */
#define DS_HW_ACCEL_FULL 0 /* default on Windows 98 */
#define DS_HW_ACCEL_STANDARD 1 /* default on Windows 2000 */
#define DS_HW_ACCEL_BASIC 2
#define DS_HW_ACCEL_EMULATION 3
extern int ds_emuldriver DECLSPEC_HIDDEN;
extern int ds_hel_buflen DECLSPEC_HIDDEN;
extern int ds_snd_queue_max DECLSPEC_HIDDEN;
extern int ds_snd_queue_min DECLSPEC_HIDDEN;
extern int ds_snd_shadow_maxsize DECLSPEC_HIDDEN;
extern int ds_hw_accel DECLSPEC_HIDDEN;
extern int ds_default_sample_rate DECLSPEC_HIDDEN;
extern int ds_default_bits_per_sample DECLSPEC_HIDDEN;
/*****************************************************************************
* Predeclare the interface implementation structures
*/
typedef struct IDirectSoundImpl IDirectSoundImpl;
typedef struct IDirectSound_IUnknown IDirectSound_IUnknown;
typedef struct IDirectSound_IDirectSound IDirectSound_IDirectSound;
typedef struct IDirectSound8_IUnknown IDirectSound8_IUnknown;
typedef struct IDirectSound8_IDirectSound IDirectSound8_IDirectSound;
typedef struct IDirectSound8_IDirectSound8 IDirectSound8_IDirectSound8;
typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
typedef struct IDirectSoundCaptureNotifyImpl IDirectSoundCaptureNotifyImpl;
typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
typedef struct IKsBufferPropertySetImpl IKsBufferPropertySetImpl;
typedef struct DirectSoundDevice DirectSoundDevice;
typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice;
/* dsound_convert.h */
typedef float (*bitsgetfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD);
typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD, float);
extern const bitsgetfunc getbpp[5] DECLSPEC_HIDDEN;
void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
void mixieee32(float *src, float *dst, unsigned samples) DECLSPEC_HIDDEN;
typedef void (*bitsconvertfunc)(const void *, void *, UINT, UINT, INT, UINT, UINT);
extern const bitsconvertfunc convertbpp[5][4] DECLSPEC_HIDDEN;
typedef void (*mixfunc)(const void *, void *, unsigned);
extern const mixfunc mixfunctions[4] DECLSPEC_HIDDEN;
typedef void (*normfunc)(const void *, void *, unsigned);
extern const normfunc normfunctions[5] DECLSPEC_HIDDEN;
typedef struct _DSVOLUMEPAN
{
DWORD dwTotalLeftAmpFactor;
DWORD dwTotalRightAmpFactor;
LONG lVolume;
DWORD dwVolAmpFactor;
LONG lPan;
DWORD dwPanLeftAmpFactor;
DWORD dwPanRightAmpFactor;
} DSVOLUMEPAN,*PDSVOLUMEPAN;
extern const normfunc normfunctions[4] DECLSPEC_HIDDEN;
/*****************************************************************************
* IDirectSoundDevice implementation structure
@ -96,11 +109,16 @@ struct DirectSoundDevice
LONG ref;
GUID guid;
DSCAPS drvcaps;
DWORD priolevel, sleeptime;
PWAVEFORMATEX pwfx, primary_pwfx;
UINT playing_offs_bytes, in_mmdev_bytes, prebuf;
PIDSDRIVER driver;
DSDRIVERDESC drvdesc;
DSDRIVERCAPS drvcaps;
DWORD priolevel;
PWAVEFORMATEX pwfx;
HWAVEOUT hwo;
LPWAVEHDR pwave;
UINT timerID, pwplay, pwqueue, prebuf, helfrags;
DWORD fraglen;
PIDSDRIVERBUFFER hwbuf;
LPBYTE buffer;
DWORD writelead, buflen, state, playpos, mixpos;
int nrofbuffers;
@ -109,25 +127,18 @@ struct DirectSoundDevice
CRITICAL_SECTION mixlock;
IDirectSoundBufferImpl *primary;
DWORD speaker_config;
float *mix_buffer, *tmp_buffer;
LPBYTE tmp_buffer, mix_buffer;
DWORD tmp_buffer_len, mix_buffer_len;
DSVOLUMEPAN volpan;
mixfunc mixfunction;
normfunc normfunction;
/* DirectSound3DListener fields */
IDirectSound3DListenerImpl* listener;
DS3DLISTENER ds3dl;
BOOL ds3dl_need_recalc;
IMMDevice *mmdevice;
IAudioClient *client;
IAudioClock *clock;
IAudioStreamVolume *volume;
IAudioRenderClient *render;
HANDLE sleepev, thread;
struct list entry;
};
/* reference counted buffer memory for duplicated buffer memory */
@ -145,7 +156,10 @@ HRESULT DirectSoundDevice_Initialize(
HRESULT DirectSoundDevice_AddBuffer(
DirectSoundDevice * device,
IDirectSoundBufferImpl * pDSB) DECLSPEC_HIDDEN;
void DirectSoundDevice_RemoveBuffer(DirectSoundDevice * device, IDirectSoundBufferImpl * pDSB) DECLSPEC_HIDDEN;
HRESULT DirectSoundDevice_RemoveBuffer(
DirectSoundDevice * device,
IDirectSoundBufferImpl * pDSB) DECLSPEC_HIDDEN;
HRESULT DirectSoundDevice_GetCaps(DirectSoundDevice * device, LPDSCAPS lpDSCaps) DECLSPEC_HIDDEN;
HRESULT DirectSoundDevice_CreateSoundBuffer(
DirectSoundDevice * device,
LPCDSBUFFERDESC dsbd,
@ -156,6 +170,19 @@ HRESULT DirectSoundDevice_DuplicateSoundBuffer(
DirectSoundDevice * device,
LPDIRECTSOUNDBUFFER psb,
LPLPDIRECTSOUNDBUFFER ppdsb) DECLSPEC_HIDDEN;
HRESULT DirectSoundDevice_SetCooperativeLevel(
DirectSoundDevice * devcie,
HWND hwnd,
DWORD level) DECLSPEC_HIDDEN;
HRESULT DirectSoundDevice_Compact(DirectSoundDevice * device) DECLSPEC_HIDDEN;
HRESULT DirectSoundDevice_GetSpeakerConfig(
DirectSoundDevice * device,
LPDWORD lpdwSpeakerConfig) DECLSPEC_HIDDEN;
HRESULT DirectSoundDevice_SetSpeakerConfig(
DirectSoundDevice * device,
DWORD config) DECLSPEC_HIDDEN;
HRESULT DirectSoundDevice_VerifyCertification(DirectSoundDevice * device,
LPDWORD pdwCertified) DECLSPEC_HIDDEN;
/*****************************************************************************
* IDirectSoundBuffer implementation structure
@ -163,74 +190,175 @@ HRESULT DirectSoundDevice_DuplicateSoundBuffer(
struct IDirectSoundBufferImpl
{
IDirectSoundBuffer8 IDirectSoundBuffer8_iface;
IDirectSoundNotify IDirectSoundNotify_iface;
IDirectSound3DListener IDirectSound3DListener_iface; /* only primary buffer */
IDirectSound3DBuffer IDirectSound3DBuffer_iface; /* only secondary buffer */
IKsPropertySet IKsPropertySet_iface;
LONG numIfaces; /* "in use interfaces" refcount */
LONG ref, refn, ref3D, refiks;
LONG ref;
/* IDirectSoundBufferImpl fields */
DirectSoundDevice* device;
RTL_RWLOCK lock;
PIDSDRIVERBUFFER hwbuf;
PWAVEFORMATEX pwfx;
BufferMemory* buffer;
LPBYTE tmp_buffer;
DWORD playflags,state,leadin;
DWORD writelead,buflen;
DWORD nAvgBytesPerSec;
DWORD freq;
DWORD freq, tmp_buffer_len, max_buffer_len;
DSVOLUMEPAN volpan;
DSBUFFERDESC dsbd;
/* used for frequency conversion (PerfectPitch) */
ULONG freqneeded;
DWORD firstep;
float freqAcc, freqAdjust, firgain;
ULONG freqneeded, freqAdjust, freqAcc, freqAccNext, resampleinmixer;
/* used for mixing */
DWORD sec_mixpos;
DWORD primary_mixpos, buf_mixpos, sec_mixpos;
/* IDirectSoundNotify fields */
/* IDirectSoundNotifyImpl fields */
IDirectSoundNotifyImpl* notify;
LPDSBPOSITIONNOTIFY notifies;
int nrofnotifies;
PIDSDRIVERNOTIFY hwnotify;
/* DirectSound3DBuffer fields */
IDirectSound3DBufferImpl* ds3db;
DS3DBUFFER ds3db_ds3db;
LONG ds3db_lVolume;
BOOL ds3db_need_recalc;
/* Used for bit depth conversion */
int mix_channels;
bitsgetfunc get, get_aux;
bitsputfunc put, put_aux;
/* IKsPropertySet fields */
IKsBufferPropertySetImpl* iks;
bitsconvertfunc convert;
struct list entry;
};
float get_mono(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel) DECLSPEC_HIDDEN;
void put_mono2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
HRESULT IDirectSoundBufferImpl_Create(
DirectSoundDevice *device,
IDirectSoundBufferImpl **ppdsb,
LPCDSBUFFERDESC dsbd) DECLSPEC_HIDDEN;
HRESULT IDirectSoundBufferImpl_Destroy(
IDirectSoundBufferImpl *pdsb) DECLSPEC_HIDDEN;
HRESULT IDirectSoundBufferImpl_Duplicate(
DirectSoundDevice *device,
IDirectSoundBufferImpl **ppdsb,
IDirectSoundBufferImpl *pdsb) DECLSPEC_HIDDEN;
void secondarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN;
const IDirectSound3DListenerVtbl ds3dlvt DECLSPEC_HIDDEN;
const IDirectSound3DBufferVtbl ds3dbvt DECLSPEC_HIDDEN;
const IKsPropertySetVtbl iksbvt DECLSPEC_HIDDEN;
HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
/*****************************************************************************
* DirectSoundCaptureDevice implementation structure
*/
struct DirectSoundCaptureDevice
{
/* IDirectSoundCaptureImpl fields */
GUID guid;
LONG ref;
/* DirectSound driver stuff */
PIDSCDRIVER driver;
DSDRIVERDESC drvdesc;
DSCDRIVERCAPS drvcaps;
PIDSCDRIVERBUFFER hwbuf;
/* wave driver info */
HWAVEIN hwi;
/* more stuff */
LPBYTE buffer;
DWORD buflen;
PWAVEFORMATEX pwfx;
IDirectSoundCaptureBufferImpl* capture_buffer;
DWORD state;
LPWAVEHDR pwave;
int nrofpwaves;
int index;
CRITICAL_SECTION lock;
};
/*****************************************************************************
* IDirectSoundCaptureBuffer implementation structure
*/
struct IDirectSoundCaptureBufferImpl
{
/* IUnknown fields */
const IDirectSoundCaptureBuffer8Vtbl *lpVtbl;
LONG ref;
/* IDirectSoundCaptureBufferImpl fields */
DirectSoundCaptureDevice* device;
/* FIXME: don't need this */
LPDSCBUFFERDESC pdscbd;
DWORD flags;
/* IDirectSoundCaptureNotifyImpl fields */
IDirectSoundCaptureNotifyImpl* notify;
LPDSBPOSITIONNOTIFY notifies;
int nrofnotifies;
PIDSDRIVERNOTIFY hwnotify;
};
/*****************************************************************************
* IDirectSound3DListener implementation structure
*/
struct IDirectSound3DListenerImpl
{
/* IUnknown fields */
const IDirectSound3DListenerVtbl *lpVtbl;
LONG ref;
/* IDirectSound3DListenerImpl fields */
DirectSoundDevice* device;
};
HRESULT IDirectSound3DListenerImpl_Create(
DirectSoundDevice *device,
IDirectSound3DListenerImpl **pdsl) DECLSPEC_HIDDEN;
/*****************************************************************************
* IKsBufferPropertySet implementation structure
*/
struct IKsBufferPropertySetImpl
{
/* IUnknown fields */
const IKsPropertySetVtbl *lpVtbl;
LONG ref;
/* IKsPropertySetImpl fields */
IDirectSoundBufferImpl* dsb;
};
HRESULT IKsBufferPropertySetImpl_Create(
IDirectSoundBufferImpl *dsb,
IKsBufferPropertySetImpl **piks) DECLSPEC_HIDDEN;
HRESULT IKsBufferPropertySetImpl_Destroy(
IKsBufferPropertySetImpl *piks) DECLSPEC_HIDDEN;
HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, IKsPropertySet **piks) DECLSPEC_HIDDEN;
/*****************************************************************************
* IDirectSound3DBuffer implementation structure
*/
struct IDirectSound3DBufferImpl
{
/* IUnknown fields */
const IDirectSound3DBufferVtbl *lpVtbl;
LONG ref;
/* IDirectSound3DBufferImpl fields */
IDirectSoundBufferImpl* dsb;
};
HRESULT IDirectSound3DBufferImpl_Create(
IDirectSoundBufferImpl *dsb,
IDirectSound3DBufferImpl **pds3db) DECLSPEC_HIDDEN;
HRESULT IDirectSound3DBufferImpl_Destroy(
IDirectSound3DBufferImpl *pds3db) DECLSPEC_HIDDEN;
/*******************************************************************************
*/
/* dsound.c */
HRESULT DSOUND_Create(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
HRESULT DSOUND_Create8(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
HRESULT IDirectSoundImpl_Create(IUnknown *outer_unk, REFIID riid, void **ppv, BOOL has_ds8) DECLSPEC_HIDDEN;
HRESULT DSOUND_Create(REFIID riid, LPDIRECTSOUND *ppDS) DECLSPEC_HIDDEN;
HRESULT DSOUND_Create8(REFIID riid, LPDIRECTSOUND8 *ppDS) DECLSPEC_HIDDEN;
/* primary.c */
DWORD DSOUND_fraglen(DWORD nSamplesPerSec, DWORD nBlockAlign) DECLSPEC_HIDDEN;
HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device) DECLSPEC_HIDDEN;
HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device) DECLSPEC_HIDDEN;
HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device) DECLSPEC_HIDDEN;
@ -238,25 +366,26 @@ HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device) DECLSPEC_HIDDEN;
HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos) DECLSPEC_HIDDEN;
LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN;
HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave) DECLSPEC_HIDDEN;
HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) DECLSPEC_HIDDEN;
HRESULT primarybuffer_create(DirectSoundDevice *device, IDirectSoundBufferImpl **ppdsb,
const DSBUFFERDESC *dsbd) DECLSPEC_HIDDEN;
void primarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN;
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN;
LONG capped_refcount_dec(LONG *ref) DECLSPEC_HIDDEN;
/* duplex.c */
HRESULT DSOUND_FullDuplexCreate(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
HRESULT DSOUND_FullDuplexCreate(REFIID riid, LPDIRECTSOUNDFULLDUPLEX* ppDSFD) DECLSPEC_HIDDEN;
/* mixer.c */
DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice* device, DWORD pos) DECLSPEC_HIDDEN;
void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len) DECLSPEC_HIDDEN;
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN;
DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, float *overshot) DECLSPEC_HIDDEN;
void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen, BOOL inmixer) DECLSPEC_HIDDEN;
DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, DWORD* overshot) DECLSPEC_HIDDEN;
DWORD CALLBACK DSOUND_mixthread(void *ptr) DECLSPEC_HIDDEN;
void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) DECLSPEC_HIDDEN;
void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) DECLSPEC_HIDDEN;
/* sound3d.c */
@ -264,9 +393,8 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN;
/* capture.c */
HRESULT DSOUND_CaptureCreate(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
HRESULT DSOUND_CaptureCreate8(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
HRESULT IDirectSoundCaptureImpl_Create(IUnknown *outer_unk, REFIID riid, void **ppv, BOOL has_dsc8) DECLSPEC_HIDDEN;
HRESULT DSOUND_CaptureCreate(REFIID riid, LPDIRECTSOUNDCAPTURE *ppDSC) DECLSPEC_HIDDEN;
HRESULT DSOUND_CaptureCreate8(REFIID riid, LPDIRECTSOUNDCAPTURE8 *ppDSC8) DECLSPEC_HIDDEN;
#define STATE_STOPPED 0
#define STATE_STARTING 1
@ -274,24 +402,16 @@ HRESULT IDirectSoundCaptureImpl_Create(IUnknown *outer_unk, REFIID riid, void **
#define STATE_CAPTURING 2
#define STATE_STOPPING 3
extern CRITICAL_SECTION DSOUND_renderers_lock DECLSPEC_HIDDEN;
extern CRITICAL_SECTION DSOUND_capturers_lock DECLSPEC_HIDDEN;
extern struct list DSOUND_capturers DECLSPEC_HIDDEN;
extern struct list DSOUND_renderers DECLSPEC_HIDDEN;
#define DSOUND_FREQSHIFT (20)
extern DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS] DECLSPEC_HIDDEN;
extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS] DECLSPEC_HIDDEN;
extern DirectSoundCaptureDevice * DSOUND_capture[MAXWAVEDRIVERS] DECLSPEC_HIDDEN;
extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS] DECLSPEC_HIDDEN;
extern WCHAR wine_vxd_drv[] DECLSPEC_HIDDEN;
HRESULT mmErr(UINT err) DECLSPEC_HIDDEN;
void setup_dsound_options(void) DECLSPEC_HIDDEN;
HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device) DECLSPEC_HIDDEN;
BOOL DSOUND_check_supported(IAudioClient *client, DWORD rate,
DWORD depth, WORD channels) DECLSPEC_HIDDEN;
UINT DSOUND_create_timer(LPTIMECALLBACK cb, DWORD_PTR user) DECLSPEC_HIDDEN;
HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
LPDSENUMCALLBACKW cb, void *user) DECLSPEC_HIDDEN;
const char * dumpCooperativeLevel(DWORD level) DECLSPEC_HIDDEN;
#endif /* _DSOUND_PRIVATE_H_ */

View file

@ -27,230 +27,567 @@
*/
typedef struct IDirectSoundFullDuplexImpl
{
IUnknown IUnknown_iface;
IDirectSoundFullDuplex IDirectSoundFullDuplex_iface;
LONG ref, refdsfd, numIfaces;
IUnknown *ds8_unk; /* Aggregated IDirectSound8 */
IUnknown *dsc8_unk; /* Aggregated IDirectSoundCapture8 */
/* IUnknown fields */
const IDirectSoundFullDuplexVtbl *lpVtbl;
LONG ref;
/* IDirectSoundFullDuplexImpl fields */
IDirectSound8 *renderer_device;
IDirectSoundCapture *capture_device;
LPUNKNOWN pUnknown;
LPDIRECTSOUND8 pDS8;
LPDIRECTSOUNDCAPTURE pDSC;
} IDirectSoundFullDuplexImpl;
static void fullduplex_destroy(IDirectSoundFullDuplexImpl *This)
{
IDirectSound8 *ds8;
IDirectSoundCapture8 *dsc8;
typedef struct IDirectSoundFullDuplex_IUnknown {
const IUnknownVtbl *lpVtbl;
LONG ref;
IDirectSoundFullDuplexImpl *pdsfd;
} IDirectSoundFullDuplex_IUnknown;
if (This->ds8_unk) {
IUnknown_QueryInterface(This->ds8_unk, &IID_IDirectSound8, (void**)&ds8);
while(IDirectSound8_Release(ds8) > 0);
IUnknown_Release(This->ds8_unk);
typedef struct IDirectSoundFullDuplex_IDirectSound8 {
const IDirectSound8Vtbl *lpVtbl;
LONG ref;
IDirectSoundFullDuplexImpl *pdsfd;
} IDirectSoundFullDuplex_IDirectSound8;
typedef struct IDirectSoundFullDuplex_IDirectSoundCapture {
const IDirectSoundCaptureVtbl *lpVtbl;
LONG ref;
IDirectSoundFullDuplexImpl *pdsfd;
} IDirectSoundFullDuplex_IDirectSoundCapture;
/*******************************************************************************
* IUnknown
*/
static HRESULT WINAPI IDirectSoundFullDuplex_IUnknown_QueryInterface(
LPUNKNOWN iface,
REFIID riid,
LPVOID * ppobj)
{
IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
}
static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_AddRef(
LPUNKNOWN iface)
{
IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
ULONG ref = InterlockedIncrement(&(This->ref));
TRACE("(%p) ref was %d\n", This, ref - 1);
return ref;
}
static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_Release(
LPUNKNOWN iface)
{
IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
ULONG ref = InterlockedDecrement(&(This->ref));
TRACE("(%p) ref was %d\n", This, ref + 1);
if (!ref) {
This->pdsfd->pUnknown = NULL;
HeapFree(GetProcessHeap(), 0, This);
TRACE("(%p) released\n", This);
}
if (This->dsc8_unk) {
IUnknown_QueryInterface(This->dsc8_unk, &IID_IDirectSoundCapture8, (void**)&dsc8);
while(IDirectSoundCapture_Release(dsc8) > 0);
IUnknown_Release(This->dsc8_unk);
return ref;
}
static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl =
{
IDirectSoundFullDuplex_IUnknown_QueryInterface,
IDirectSoundFullDuplex_IUnknown_AddRef,
IDirectSoundFullDuplex_IUnknown_Release
};
static HRESULT IDirectSoundFullDuplex_IUnknown_Create(
LPDIRECTSOUNDFULLDUPLEX pdsfd,
LPUNKNOWN * ppunk)
{
IDirectSoundFullDuplex_IUnknown * pdsfdunk;
TRACE("(%p,%p)\n",pdsfd,ppunk);
if (pdsfd == NULL) {
ERR("invalid parameter: pdsfd == NULL\n");
return DSERR_INVALIDPARAM;
}
HeapFree(GetProcessHeap(), 0, This);
TRACE("(%p) released\n", This);
if (ppunk == NULL) {
ERR("invalid parameter: ppunk == NULL\n");
return DSERR_INVALIDPARAM;
}
pdsfdunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdunk));
if (pdsfdunk == NULL) {
WARN("out of memory\n");
*ppunk = NULL;
return DSERR_OUTOFMEMORY;
}
pdsfdunk->lpVtbl = &DirectSoundFullDuplex_Unknown_Vtbl;
pdsfdunk->ref = 0;
pdsfdunk->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
*ppunk = (LPUNKNOWN)pdsfdunk;
return DS_OK;
}
/*******************************************************************************
* IUnknown implemetation for DirectSoundFullDuplex
* IDirectSoundFullDuplex_IDirectSound8
*/
static inline IDirectSoundFullDuplexImpl *impl_from_IUnknown(IUnknown *iface)
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
LPDIRECTSOUND8 iface,
REFIID riid,
LPVOID * ppobj)
{
return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IUnknown_iface);
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
}
static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_AddRef(
LPDIRECTSOUND8 iface)
{
IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface);
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
ULONG ref = InterlockedIncrement(&(This->ref));
TRACE("(%p) ref was %d\n", This, ref - 1);
return ref;
}
TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_Release(
LPDIRECTSOUND8 iface)
{
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
ULONG ref = InterlockedDecrement(&(This->ref));
TRACE("(%p) ref was %d\n", This, ref + 1);
if (!ref) {
This->pdsfd->pDS8 = NULL;
HeapFree(GetProcessHeap(), 0, This);
TRACE("(%p) released\n", This);
}
return ref;
}
if (!ppv) {
WARN("invalid parameter\n");
return E_INVALIDARG;
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
LPDIRECTSOUND8 iface,
LPCDSBUFFERDESC dsbd,
LPLPDIRECTSOUNDBUFFER ppdsb,
LPUNKNOWN lpunk)
{
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
return IDirectSound8_CreateSoundBuffer(This->pdsfd->renderer_device,dsbd,ppdsb,lpunk);
}
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetCaps(
LPDIRECTSOUND8 iface,
LPDSCAPS lpDSCaps)
{
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
TRACE("(%p,%p)\n",This,lpDSCaps);
return IDirectSound8_GetCaps(This->pdsfd->renderer_device, lpDSCaps);
}
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer(
LPDIRECTSOUND8 iface,
LPDIRECTSOUNDBUFFER psb,
LPLPDIRECTSOUNDBUFFER ppdsb)
{
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
return IDirectSound8_DuplicateSoundBuffer(This->pdsfd->renderer_device,psb,ppdsb);
}
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel(
LPDIRECTSOUND8 iface,
HWND hwnd,
DWORD level)
{
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
return IDirectSound8_SetCooperativeLevel(This->pdsfd->renderer_device,hwnd,level);
}
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Compact(
LPDIRECTSOUND8 iface)
{
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
TRACE("(%p)\n", This);
return IDirectSound8_Compact(This->pdsfd->renderer_device);
}
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig(
LPDIRECTSOUND8 iface,
LPDWORD lpdwSpeakerConfig)
{
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
return IDirectSound8_GetSpeakerConfig(This->pdsfd->renderer_device,lpdwSpeakerConfig);
}
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig(
LPDIRECTSOUND8 iface,
DWORD config)
{
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
TRACE("(%p,0x%08x)\n",This,config);
return IDirectSound8_SetSpeakerConfig(This->pdsfd->renderer_device,config);
}
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Initialize(
LPDIRECTSOUND8 iface,
LPCGUID lpcGuid)
{
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
return IDirectSound8_Initialize(This->pdsfd->renderer_device,lpcGuid);
}
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_VerifyCertification(
LPDIRECTSOUND8 iface,
DWORD *cert)
{
IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
TRACE("(%p, %p)\n", This, cert);
return IDirectSound8_VerifyCertification(This->pdsfd->renderer_device,cert);
}
static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_Vtbl =
{
IDirectSoundFullDuplex_IDirectSound8_QueryInterface,
IDirectSoundFullDuplex_IDirectSound8_AddRef,
IDirectSoundFullDuplex_IDirectSound8_Release,
IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer,
IDirectSoundFullDuplex_IDirectSound8_GetCaps,
IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer,
IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel,
IDirectSoundFullDuplex_IDirectSound8_Compact,
IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig,
IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig,
IDirectSoundFullDuplex_IDirectSound8_Initialize,
IDirectSoundFullDuplex_IDirectSound8_VerifyCertification
};
static HRESULT IDirectSoundFullDuplex_IDirectSound8_Create(
LPDIRECTSOUNDFULLDUPLEX pdsfd,
LPDIRECTSOUND8 * ppds8)
{
IDirectSoundFullDuplex_IDirectSound8 * pdsfdds8;
TRACE("(%p,%p)\n",pdsfd,ppds8);
if (pdsfd == NULL) {
ERR("invalid parameter: pdsfd == NULL\n");
return DSERR_INVALIDPARAM;
}
if (ppds8 == NULL) {
ERR("invalid parameter: ppds8 == NULL\n");
return DSERR_INVALIDPARAM;
}
if (((IDirectSoundFullDuplexImpl*)pdsfd)->renderer_device == NULL) {
WARN("not initialized\n");
*ppds8 = NULL;
return DSERR_UNINITIALIZED;
}
pdsfdds8 = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds8));
if (pdsfdds8 == NULL) {
WARN("out of memory\n");
*ppds8 = NULL;
return DSERR_OUTOFMEMORY;
}
pdsfdds8->lpVtbl = &DirectSoundFullDuplex_DirectSound8_Vtbl;
pdsfdds8->ref = 0;
pdsfdds8->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
*ppds8 = (LPDIRECTSOUND8)pdsfdds8;
return DS_OK;
}
/*******************************************************************************
* IDirectSoundFullDuplex_IDirectSoundCapture
*/
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
LPDIRECTSOUNDCAPTURE iface,
REFIID riid,
LPVOID * ppobj)
{
IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
}
static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(
LPDIRECTSOUNDCAPTURE iface)
{
IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
ULONG ref = InterlockedIncrement(&(This->ref));
TRACE("(%p) ref was %d\n", This, ref - 1);
return ref;
}
static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Release(
LPDIRECTSOUNDCAPTURE iface)
{
IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
ULONG ref = InterlockedDecrement(&(This->ref));
TRACE("(%p) ref was %d\n", This, ref + 1);
if (!ref) {
This->pdsfd->pDSC = NULL;
HeapFree(GetProcessHeap(), 0, This);
TRACE("(%p) released\n", This);
}
return ref;
}
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
LPDIRECTSOUNDCAPTURE iface,
LPCDSCBUFFERDESC lpcDSCBufferDesc,
LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
LPUNKNOWN pUnk)
{
IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
TRACE("(%p,%p,%p,%p)\n",This,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
return IDirectSoundCapture_CreateCaptureBuffer(This->pdsfd->capture_device,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
}
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps(
LPDIRECTSOUNDCAPTURE iface,
LPDSCCAPS lpDSCCaps)
{
IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
TRACE("(%p,%p)\n",This,lpDSCCaps);
return IDirectSoundCapture_GetCaps(This->pdsfd->capture_device, lpDSCCaps);
}
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Initialize(
LPDIRECTSOUNDCAPTURE iface,
LPCGUID lpcGUID)
{
IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
TRACE("(%p, %s)\n", This, debugstr_guid(lpcGUID));
return IDirectSoundCapture_Initialize(This->pdsfd->capture_device,lpcGUID);
}
static const IDirectSoundCaptureVtbl DirectSoundFullDuplex_DirectSoundCapture_Vtbl =
{
IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface,
IDirectSoundFullDuplex_IDirectSoundCapture_AddRef,
IDirectSoundFullDuplex_IDirectSoundCapture_Release,
IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer,
IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps,
IDirectSoundFullDuplex_IDirectSoundCapture_Initialize
};
static HRESULT IDirectSoundFullDuplex_IDirectSoundCapture_Create(
LPDIRECTSOUNDFULLDUPLEX pdsfd,
LPDIRECTSOUNDCAPTURE8 * ppdsc8)
{
IDirectSoundFullDuplex_IDirectSoundCapture * pdsfddsc;
TRACE("(%p,%p)\n",pdsfd,ppdsc8);
if (pdsfd == NULL) {
ERR("invalid parameter: pdsfd == NULL\n");
return DSERR_INVALIDPARAM;
}
if (ppdsc8 == NULL) {
ERR("invalid parameter: ppdsc8 == NULL\n");
return DSERR_INVALIDPARAM;
}
if (((IDirectSoundFullDuplexImpl*)pdsfd)->capture_device == NULL) {
WARN("not initialized\n");
*ppdsc8 = NULL;
return DSERR_UNINITIALIZED;
}
pdsfddsc = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfddsc));
if (pdsfddsc == NULL) {
WARN("out of memory\n");
*ppdsc8 = NULL;
return DSERR_OUTOFMEMORY;
}
pdsfddsc->lpVtbl = &DirectSoundFullDuplex_DirectSoundCapture_Vtbl;
pdsfddsc->ref = 0;
pdsfddsc->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
*ppdsc8 = (LPDIRECTSOUNDCAPTURE)pdsfddsc;
return DS_OK;
}
/***************************************************************************
* IDirectSoundFullDuplexImpl
*/
static ULONG WINAPI
IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface )
{
IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
ULONG ref = InterlockedIncrement(&(This->ref));
TRACE("(%p) ref was %d\n", This, ref - 1);
return ref;
}
static HRESULT WINAPI
IDirectSoundFullDuplexImpl_QueryInterface(
LPDIRECTSOUNDFULLDUPLEX iface,
REFIID riid,
LPVOID* ppobj )
{
IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
if (ppobj == NULL) {
WARN("invalid parameter\n");
return E_INVALIDARG;
}
*ppobj = NULL;
if (IsEqualIID(riid, &IID_IUnknown)) {
IUnknown_AddRef(&This->IUnknown_iface);
*ppv = &This->IUnknown_iface;
if (!This->pUnknown) {
IDirectSoundFullDuplex_IUnknown_Create(iface, &This->pUnknown);
if (!This->pUnknown) {
WARN("IDirectSoundFullDuplex_IUnknown_Create() failed\n");
*ppobj = NULL;
return E_NOINTERFACE;
}
}
IDirectSoundFullDuplex_IUnknown_AddRef(This->pUnknown);
*ppobj = This->pUnknown;
return S_OK;
} else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
IDirectSoundFullDuplex_AddRef(&This->IDirectSoundFullDuplex_iface);
*ppv = &This->IDirectSoundFullDuplex_iface;
IDirectSoundFullDuplexImpl_AddRef(iface);
*ppobj = This;
return S_OK;
} else if (This->ds8_unk && (IsEqualIID(riid, &IID_IDirectSound) ||
IsEqualIID(riid, &IID_IDirectSound8)))
return IUnknown_QueryInterface(This->ds8_unk, riid, ppv);
else if (This->dsc8_unk && IsEqualIID(riid, &IID_IDirectSoundCapture))
return IUnknown_QueryInterface(This->dsc8_unk, riid, ppv);
} else if (IsEqualIID(riid, &IID_IDirectSound)
|| IsEqualIID(riid, &IID_IDirectSound8)) {
if (!This->pDS8) {
IDirectSoundFullDuplex_IDirectSound8_Create(iface, &This->pDS8);
if (!This->pDS8) {
WARN("IDirectSoundFullDuplex_IDirectSound8_Create() failed\n");
*ppobj = NULL;
return E_NOINTERFACE;
}
}
IDirectSoundFullDuplex_IDirectSound8_AddRef(This->pDS8);
*ppobj = This->pDS8;
return S_OK;
} else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
if (!This->pDSC) {
IDirectSoundFullDuplex_IDirectSoundCapture_Create(iface, &This->pDSC);
if (!This->pDSC) {
WARN("IDirectSoundFullDuplex_IDirectSoundCapture_Create() failed\n");
*ppobj = NULL;
return E_NOINTERFACE;
}
}
IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(This->pDSC);
*ppobj = This->pDSC;
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI IUnknownImpl_AddRef(IUnknown *iface)
static ULONG WINAPI
IDirectSoundFullDuplexImpl_Release( LPDIRECTSOUNDFULLDUPLEX iface )
{
IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface);
ULONG ref = InterlockedIncrement(&This->ref);
IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
ULONG ref = InterlockedDecrement(&(This->ref));
TRACE("(%p) ref was %d\n", This, ref - 1);
TRACE("(%p) ref=%d\n", This, ref);
if(ref == 1)
InterlockedIncrement(&This->numIfaces);
if (!ref) {
if (This->capture_device)
IDirectSoundCapture_Release(This->capture_device);
if (This->renderer_device)
IDirectSound_Release(This->renderer_device);
HeapFree( GetProcessHeap(), 0, This );
TRACE("(%p) released\n", This);
}
return ref;
}
static ULONG WINAPI IUnknownImpl_Release(IUnknown *iface)
static HRESULT WINAPI
IDirectSoundFullDuplexImpl_Initialize(
LPDIRECTSOUNDFULLDUPLEX iface,
LPCGUID pCaptureGuid,
LPCGUID pRendererGuid,
LPCDSCBUFFERDESC lpDscBufferDesc,
LPCDSBUFFERDESC lpDsBufferDesc,
HWND hWnd,
DWORD dwLevel,
LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8,
LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8 )
{
IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if (!ref && !InterlockedDecrement(&This->numIfaces))
fullduplex_destroy(This);
return ref;
}
static const IUnknownVtbl unk_vtbl =
{
IUnknownImpl_QueryInterface,
IUnknownImpl_AddRef,
IUnknownImpl_Release
};
/***************************************************************************
* IDirectSoundFullDuplex implementation
*/
static inline IDirectSoundFullDuplexImpl *impl_from_IDirectSoundFullDuplex(IDirectSoundFullDuplex *iface)
{
return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IDirectSoundFullDuplex_iface);
}
static HRESULT WINAPI IDirectSoundFullDuplexImpl_QueryInterface(IDirectSoundFullDuplex *iface,
REFIID riid, void **ppv)
{
IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
return IUnknown_QueryInterface(&This->IUnknown_iface, riid, ppv);
}
static ULONG WINAPI IDirectSoundFullDuplexImpl_AddRef(IDirectSoundFullDuplex *iface)
{
IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
ULONG ref = InterlockedIncrement(&This->refdsfd);
TRACE("(%p) ref=%d\n", This, ref);
if(ref == 1)
InterlockedIncrement(&This->numIfaces);
return ref;
}
static ULONG WINAPI IDirectSoundFullDuplexImpl_Release(IDirectSoundFullDuplex *iface)
{
IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
ULONG ref = InterlockedDecrement(&This->refdsfd);
TRACE("(%p) ref=%d\n", This, ref);
if (!ref && !InterlockedDecrement(&This->numIfaces))
fullduplex_destroy(This);
return ref;
}
static HRESULT WINAPI IDirectSoundFullDuplexImpl_Initialize(IDirectSoundFullDuplex *iface,
const GUID *capture_dev, const GUID *render_dev, const DSCBUFFERDESC *cbufdesc,
const DSBUFFERDESC *bufdesc, HWND hwnd, DWORD level, IDirectSoundCaptureBuffer8 **dscb8,
IDirectSoundBuffer8 **dsb8)
{
IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
IDirectSound8 *ds8 = NULL;
IDirectSoundCapture8 *dsc8 = NULL;
HRESULT hr;
IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This, debugstr_guid(capture_dev),
debugstr_guid(render_dev), cbufdesc, bufdesc, hwnd, level, dscb8, dsb8);
TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This,
debugstr_guid(pCaptureGuid), debugstr_guid(pRendererGuid),
lpDscBufferDesc, lpDsBufferDesc, hWnd, dwLevel,
lplpDirectSoundCaptureBuffer8, lplpDirectSoundBuffer8);
if (!dscb8 || !dsb8)
return E_INVALIDARG;
*dscb8 = NULL;
*dsb8 = NULL;
if (This->ds8_unk || This->dsc8_unk) {
if (This->renderer_device != NULL || This->capture_device != NULL) {
WARN("already initialized\n");
*lplpDirectSoundCaptureBuffer8 = NULL;
*lplpDirectSoundBuffer8 = NULL;
return DSERR_ALREADYINITIALIZED;
}
hr = IDirectSoundImpl_Create(&This->IUnknown_iface, &IID_IUnknown, (void**)&This->ds8_unk,
TRUE);
if (SUCCEEDED(hr)) {
IUnknown_QueryInterface(This->ds8_unk, &IID_IDirectSound8, (void**)&ds8);
hr = IDirectSound_Initialize(ds8, render_dev);
}
hr = DSOUND_Create8(&IID_IDirectSound8, &This->renderer_device);
if (SUCCEEDED(hr))
hr = IDirectSound_Initialize(This->renderer_device, pRendererGuid);
if (hr != DS_OK) {
WARN("Creating/initializing IDirectSound8 failed\n");
goto error;
WARN("DirectSoundDevice_Initialize() failed\n");
*lplpDirectSoundCaptureBuffer8 = NULL;
*lplpDirectSoundBuffer8 = NULL;
return hr;
}
IDirectSound8_SetCooperativeLevel(ds8, hwnd, level);
IDirectSound8_SetCooperativeLevel(This->renderer_device, hWnd, dwLevel);
hr = IDirectSound8_CreateSoundBuffer(ds8, bufdesc, (IDirectSoundBuffer**)dsb8, NULL);
hr = IDirectSound8_CreateSoundBuffer(This->renderer_device, lpDsBufferDesc,
(IDirectSoundBuffer**)lplpDirectSoundBuffer8, NULL);
if (hr != DS_OK) {
WARN("IDirectSoundBuffer_Create() failed\n");
goto error;
WARN("IDirectSoundBufferImpl_Create() failed\n");
*lplpDirectSoundCaptureBuffer8 = NULL;
*lplpDirectSoundBuffer8 = NULL;
return hr;
}
hr = IDirectSoundCaptureImpl_Create(&This->IUnknown_iface, &IID_IUnknown,
(void**)&This->dsc8_unk, TRUE);
if (SUCCEEDED(hr)) {
IUnknown_QueryInterface(This->dsc8_unk, &IID_IDirectSoundCapture8, (void**)&dsc8);
hr = IDirectSoundCapture_Initialize(dsc8, capture_dev);
}
hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, &This->capture_device);
if (SUCCEEDED(hr))
hr = IDirectSoundCapture_Initialize(This->capture_device, pCaptureGuid);
if (hr != DS_OK) {
WARN("Creating/initializing IDirectSoundCapture8 failed\n");
goto error;
WARN("DirectSoundCaptureDevice_Initialize() failed\n");
*lplpDirectSoundCaptureBuffer8 = NULL;
*lplpDirectSoundBuffer8 = NULL;
return hr;
}
hr = IDirectSoundCapture_CreateCaptureBuffer(dsc8, cbufdesc,
(IDirectSoundCaptureBuffer**)dscb8, NULL);
hr = IDirectSoundCapture_CreateCaptureBuffer(This->capture_device,
lpDscBufferDesc,
(IDirectSoundCaptureBuffer**)lplpDirectSoundCaptureBuffer8,
NULL);
if (hr != DS_OK) {
WARN("IDirectSoundCapture_CreateCaptureBuffer() failed\n");
goto error;
WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
*lplpDirectSoundCaptureBuffer8 = NULL;
*lplpDirectSoundBuffer8 = NULL;
return hr;
}
IDirectSound8_Release(ds8);
IDirectSoundCapture_Release(dsc8);
return DS_OK;
error:
if (*dsb8) {
IDirectSoundBuffer8_Release(*dsb8);
*dsb8 = NULL;
}
if (ds8)
IDirectSound8_Release(ds8);
if (This->ds8_unk) {
IUnknown_Release(This->ds8_unk);
This->ds8_unk = NULL;
}
if (*dscb8) {
IDirectSoundCaptureBuffer8_Release(*dscb8);
*dscb8 = NULL;
}
if (dsc8)
IDirectSoundCapture_Release(dsc8);
if (This->dsc8_unk) {
IUnknown_Release(This->dsc8_unk);
This->dsc8_unk = NULL;
}
return hr;
}
static const IDirectSoundFullDuplexVtbl dsfd_vtbl =
static const IDirectSoundFullDuplexVtbl dsfdvt =
{
/* IUnknown methods */
IDirectSoundFullDuplexImpl_QueryInterface,
@ -261,32 +598,44 @@ static const IDirectSoundFullDuplexVtbl dsfd_vtbl =
IDirectSoundFullDuplexImpl_Initialize
};
HRESULT DSOUND_FullDuplexCreate(REFIID riid, void **ppv)
HRESULT DSOUND_FullDuplexCreate(
REFIID riid,
LPDIRECTSOUNDFULLDUPLEX* ppDSFD)
{
IDirectSoundFullDuplexImpl *obj;
HRESULT hr;
IDirectSoundFullDuplexImpl *This = NULL;
TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSFD);
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
if (ppDSFD == NULL) {
WARN("invalid parameter: ppDSFD == NULL\n");
return DSERR_INVALIDPARAM;
}
*ppv = NULL;
obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj));
if (!obj) {
if (!IsEqualIID(riid, &IID_IUnknown) &&
!IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
*ppDSFD = 0;
return E_NOINTERFACE;
}
/* Get dsound configuration */
setup_dsound_options();
This = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
if (This == NULL) {
WARN("out of memory\n");
*ppDSFD = NULL;
return DSERR_OUTOFMEMORY;
}
setup_dsound_options();
This->lpVtbl = &dsfdvt;
This->ref = 1;
This->capture_device = NULL;
This->renderer_device = NULL;
obj->IDirectSoundFullDuplex_iface.lpVtbl = &dsfd_vtbl;
obj->IUnknown_iface.lpVtbl = &unk_vtbl;
obj->ref = 1;
obj->refdsfd = 0;
obj->numIfaces = 1;
*ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
hr = IUnknown_QueryInterface(&obj->IUnknown_iface, riid, ppv);
IUnknown_Release(&obj->IUnknown_iface);
return hr;
return DS_OK;
}
/***************************************************************************
@ -295,50 +644,93 @@ HRESULT DSOUND_FullDuplexCreate(REFIID riid, void **ppv)
* Create and initialize a DirectSoundFullDuplex interface.
*
* PARAMS
* capture_dev [I] Address of sound capture device GUID.
* render_dev [I] Address of sound render device GUID.
* cbufdesc [I] Address of capture buffer description.
* bufdesc [I] Address of render buffer description.
* hwnd [I] Handle to application window.
* level [I] Cooperative level.
* dsfd [O] Address where full duplex interface returned.
* dscb8 [0] Address where capture buffer interface returned.
* dsb8 [0] Address where render buffer interface returned.
* outer_unk [I] Must be NULL.
* pcGuidCaptureDevice [I] Address of sound capture device GUID.
* pcGuidRenderDevice [I] Address of sound render device GUID.
* pcDSCBufferDesc [I] Address of capture buffer description.
* pcDSBufferDesc [I] Address of render buffer description.
* hWnd [I] Handle to application window.
* dwLevel [I] Cooperative level.
* ppDSFD [O] Address where full duplex interface returned.
* ppDSCBuffer8 [0] Address where capture buffer interface returned.
* ppDSBuffer8 [0] Address where render buffer interface returned.
* pUnkOuter [I] Must be NULL.
*
* RETURNS
* Success: DS_OK
* Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
* DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
*/
HRESULT WINAPI DirectSoundFullDuplexCreate(const GUID *capture_dev, const GUID *render_dev,
const DSCBUFFERDESC *cbufdesc, const DSBUFFERDESC *bufdesc, HWND hwnd, DWORD level,
IDirectSoundFullDuplex **dsfd, IDirectSoundCaptureBuffer8 **dscb8,
IDirectSoundBuffer8 **dsb8, IUnknown *outer_unk)
HRESULT WINAPI
DirectSoundFullDuplexCreate(
LPCGUID pcGuidCaptureDevice,
LPCGUID pcGuidRenderDevice,
LPCDSCBUFFERDESC pcDSCBufferDesc,
LPCDSBUFFERDESC pcDSBufferDesc,
HWND hWnd,
DWORD dwLevel,
LPDIRECTSOUNDFULLDUPLEX *ppDSFD,
LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8,
LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
LPUNKNOWN pUnkOuter)
{
HRESULT hr;
HRESULT hres;
IDirectSoundFullDuplexImpl *This = NULL;
TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n",
debugstr_guid(pcGuidCaptureDevice), debugstr_guid(pcGuidRenderDevice),
pcDSCBufferDesc, pcDSBufferDesc, hWnd, dwLevel, ppDSFD, ppDSCBuffer8,
ppDSBuffer8, pUnkOuter);
TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n", debugstr_guid(capture_dev),
debugstr_guid(render_dev), cbufdesc, bufdesc, hwnd, level, dsfd, dscb8, dsb8,
outer_unk);
if (!dsfd)
return DSERR_INVALIDPARAM;
if (outer_unk) {
*dsfd = NULL;
if (pUnkOuter) {
WARN("pUnkOuter != 0\n");
*ppDSFD = NULL;
return DSERR_NOAGGREGATION;
}
hr = DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex, (void**)dsfd);
if (hr == DS_OK) {
hr = IDirectSoundFullDuplex_Initialize(*dsfd, capture_dev, render_dev, cbufdesc, bufdesc,
hwnd, level, dscb8, dsb8);
if (hr != DS_OK) {
IDirectSoundFullDuplex_Release(*dsfd);
*dsfd = NULL;
WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
}
if (pcDSCBufferDesc == NULL) {
WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
*ppDSFD = NULL;
return DSERR_INVALIDPARAM;
}
return hr;
if (pcDSBufferDesc == NULL) {
WARN("invalid parameter: pcDSBufferDesc == NULL\n");
*ppDSFD = NULL;
return DSERR_INVALIDPARAM;
}
if (ppDSFD == NULL) {
WARN("invalid parameter: ppDSFD == NULL\n");
return DSERR_INVALIDPARAM;
}
if (ppDSCBuffer8 == NULL) {
WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
*ppDSFD = NULL;
return DSERR_INVALIDPARAM;
}
if (ppDSBuffer8 == NULL) {
WARN("invalid parameter: ppDSBuffer8 == NULL\n");
*ppDSFD = NULL;
return DSERR_INVALIDPARAM;
}
hres = DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex, (LPDIRECTSOUNDFULLDUPLEX*)&This);
if (FAILED(hres)) return hres;
hres = IDirectSoundFullDuplexImpl_Initialize((LPDIRECTSOUNDFULLDUPLEX)This,
pcGuidCaptureDevice,
pcGuidRenderDevice,
pcDSCBufferDesc,
pcDSBufferDesc,
hWnd, dwLevel, ppDSCBuffer8,
ppDSBuffer8);
if (hres != DS_OK) {
IUnknown_Release((LPDIRECTSOUNDFULLDUPLEX)This);
WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
*ppDSFD = NULL;
} else
*ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
return hres;
}

File diff suppressed because it is too large Load diff

View file

@ -1,18 +1,13 @@
/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */
#include <stdarg.h>
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
#include <objbase.h>
#include <mmddk.h>
#include <dsound.h>
#include <initguid.h>
#include <mmdeviceapi.h>
#include <audioclient.h>
#include <devpkey.h>
#include <dsdriver.h>
/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -21,8 +21,6 @@
#include "dsound_private.h"
static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 };
typedef struct IKsPrivatePropertySetImpl
{
IKsPropertySet IKsPropertySet_iface;
@ -40,7 +38,9 @@ static IKsPrivatePropertySetImpl *impl_from_IKsPropertySet(IKsPropertySet *iface
/* IUnknown methods */
static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
IKsPropertySet *iface, REFIID riid, void **ppobj)
LPKSPROPERTYSET iface,
REFIID riid,
LPVOID *ppobj )
{
IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
@ -48,7 +48,7 @@ static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IKsPropertySet)) {
*ppobj = iface;
IKsPropertySet_AddRef(iface);
IUnknown_AddRef(iface);
return S_OK;
}
*ppobj = NULL;
@ -76,61 +76,67 @@ static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface)
return ref;
}
struct search_data {
const WCHAR *tgt_name;
GUID *found_guid;
};
static BOOL CALLBACK search_callback(GUID *guid, const WCHAR *desc,
const WCHAR *module, void *user)
{
struct search_data *search = user;
if(!lstrcmpW(desc, search->tgt_name)){
*search->found_guid = *guid;
return FALSE;
}
return TRUE;
}
static HRESULT DSPROPERTY_WaveDeviceMappingW(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned )
{
HRESULT hr;
PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd = pPropData;
struct search_data search;
HRESULT hr = DSERR_INVALIDPARAM;
PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd;
TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
pPropData,cbPropData,pcbReturned);
pPropData,cbPropData,pcbReturned);
ppd = pPropData;
if (!ppd) {
WARN("invalid parameter: pPropData\n");
return DSERR_INVALIDPARAM;
WARN("invalid parameter: pPropData\n");
return DSERR_INVALIDPARAM;
}
search.tgt_name = ppd->DeviceName;
search.found_guid = &ppd->DeviceId;
if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER)
hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
search_callback, &search);
else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE)
hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
search_callback, &search);
else
return DSERR_INVALIDPARAM;
if(hr != S_FALSE)
/* device was not found */
return DSERR_INVALIDPARAM;
if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
ULONG wod;
unsigned int wodn;
TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
wodn = waveOutGetNumDevs();
for (wod = 0; wod < wodn; wod++) {
WAVEOUTCAPSW capsW;
MMRESULT res;
res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW));
if (res == MMSYSERR_NOERROR) {
if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
ppd->DeviceId = DSOUND_renderer_guids[wod];
hr = DS_OK;
TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
debugstr_w(ppd->DeviceName));
break;
}
}
}
} else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
ULONG wid;
unsigned int widn;
TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
widn = waveInGetNumDevs();
for (wid = 0; wid < widn; wid++) {
WAVEINCAPSW capsW;
MMRESULT res;
res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW));
if (res == MMSYSERR_NOERROR) {
if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
ppd->DeviceId = DSOUND_capture_guids[wid];
hr = DS_OK;
TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
debugstr_w(ppd->DeviceName));
break;
}
}
}
}
if (pcbReturned)
*pcbReturned = cbPropData;
return DS_OK;
return hr;
}
static HRESULT DSPROPERTY_WaveDeviceMappingA(
@ -174,12 +180,10 @@ static HRESULT DSPROPERTY_DescriptionW(
PULONG pcbReturned )
{
PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData;
HRESULT err;
GUID dev_guid;
IMMDevice *mmdevice;
IPropertyStore *ps;
PROPVARIANT pv;
DWORD desclen;
HRESULT hr;
ULONG wod, wid, wodn, widn;
DSDRIVERDESC desc;
TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
pPropData,cbPropData,pcbReturned);
@ -203,41 +207,63 @@ static HRESULT DSPROPERTY_DescriptionW(
GetDeviceID(&ppd->DeviceId, &dev_guid);
hr = get_mmdevice(eRender, &dev_guid, &mmdevice);
if(FAILED(hr)){
hr = get_mmdevice(eCapture, &dev_guid, &mmdevice);
if(FAILED(hr))
return hr;
wodn = waveOutGetNumDevs();
widn = waveInGetNumDevs();
wid = wod = dev_guid.Data4[7];
if (!memcmp(&dev_guid, &DSOUND_renderer_guids[0], sizeof(GUID)-1)
&& wod < wodn)
{
ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
ppd->WaveDeviceId = wod;
}
else if (!memcmp(&dev_guid, &DSOUND_capture_guids[0], sizeof(GUID)-1)
&& wid < widn)
{
ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
ppd->WaveDeviceId = wid;
}
else
{
WARN("Device not found\n");
return E_PROP_ID_UNSUPPORTED;
}
hr = IMMDevice_OpenPropertyStore(mmdevice, STGM_READ, &ps);
if(FAILED(hr)){
IMMDevice_Release(mmdevice);
WARN("OpenPropertyStore failed: %08x\n", hr);
return hr;
if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER)
err = waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel);
else
err = waveInMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel);
if (err != MMSYSERR_NOERROR)
{
WARN("waveMessage(DRV_QUERYDSOUNDDESC) failed!\n");
return E_PROP_ID_UNSUPPORTED;
}
else
{
/* FIXME: Still a memory leak.. */
int desclen, modlen;
static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 };
modlen = MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, NULL, 0 );
desclen = MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, NULL, 0 );
ppd->Module = HeapAlloc(GetProcessHeap(),0,modlen*sizeof(WCHAR));
ppd->Description = HeapAlloc(GetProcessHeap(),0,desclen*sizeof(WCHAR));
ppd->Interface = wInterface;
if (!ppd->Description || !ppd->Module)
{
WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, ppd->Description);
HeapFree(GetProcessHeap(), 0, ppd->Module);
ppd->Description = ppd->Module = NULL;
return E_OUTOFMEMORY;
}
MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->Module, modlen );
MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->Description, desclen );
}
hr = IPropertyStore_GetValue(ps,
(const PROPERTYKEY *)&DEVPKEY_Device_FriendlyName, &pv);
if(FAILED(hr)){
IPropertyStore_Release(ps);
IMMDevice_Release(mmdevice);
WARN("GetValue(FriendlyName) failed: %08x\n", hr);
return hr;
}
desclen = lstrlenW(pv.u.pwszVal) + 1;
/* FIXME: Still a memory leak.. */
ppd->Description = HeapAlloc(GetProcessHeap(), 0, desclen * sizeof(WCHAR));
memcpy(ppd->Description, pv.u.pwszVal, desclen * sizeof(WCHAR));
ppd->Module = wine_vxd_drv;
ppd->Interface = wInterface;
ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
PropVariantClear(&pv);
IPropertyStore_Release(ps);
IMMDevice_Release(mmdevice);
if (pcbReturned) {
*pcbReturned = sizeof(*ppd);
TRACE("*pcbReturned=%d\n", *pcbReturned);
@ -246,49 +272,15 @@ static HRESULT DSPROPERTY_DescriptionW(
return S_OK;
}
static
BOOL CALLBACK enum_callback(GUID *guid, const WCHAR *desc, const WCHAR *module,
void *user)
{
PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = user;
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
DWORD len;
BOOL ret;
TRACE("%s %s %s %p\n", wine_dbgstr_guid(guid), wine_dbgstr_w(desc),
wine_dbgstr_w(module), user);
if(!guid)
return TRUE;
data.DeviceId = *guid;
len = lstrlenW(module) + 1;
data.Module = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
memcpy(data.Module, module, len * sizeof(WCHAR));
len = lstrlenW(desc) + 1;
data.Description = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
memcpy(data.Description, desc, len * sizeof(WCHAR));
data.Interface = wInterface;
ret = ppd->Callback(&data, ppd->Context);
HeapFree(GetProcessHeap(), 0, data.Module);
HeapFree(GetProcessHeap(), 0, data.Description);
return ret;
}
static HRESULT DSPROPERTY_EnumerateW(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned )
{
PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData;
HRESULT hr;
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
BOOL ret;
int widn, wodn, i;
TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
pPropData,cbPropData,pcbReturned);
@ -301,14 +293,45 @@ static HRESULT DSPROPERTY_EnumerateW(
return E_PROP_ID_UNSUPPORTED;
}
hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
enum_callback, ppd);
wodn = waveOutGetNumDevs();
widn = waveInGetNumDevs();
if(hr == S_OK)
hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
enum_callback, ppd);
data.DeviceId = DSOUND_renderer_guids[0];
for (i = 0; i < wodn; ++i)
{
HRESULT hr;
data.DeviceId.Data4[7] = i;
hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
if (FAILED(hr))
{
ERR("DescriptionW failed!\n");
return S_OK;
}
ret = ppd->Callback(&data, ppd->Context);
HeapFree(GetProcessHeap(), 0, data.Module);
HeapFree(GetProcessHeap(), 0, data.Description);
if (!ret)
return S_OK;
}
return SUCCEEDED(hr) ? DS_OK : hr;
data.DeviceId = DSOUND_capture_guids[0];
for (i = 0; i < widn; ++i)
{
HRESULT hr;
data.DeviceId.Data4[7] = i;
hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
if (FAILED(hr))
{
ERR("DescriptionW failed!\n");
return S_OK;
}
ret = ppd->Callback(&data, ppd->Context);
HeapFree(GetProcessHeap(), 0, data.Module);
HeapFree(GetProcessHeap(), 0, data.Description);
if (!ret)
return S_OK;
}
return S_OK;
}
static BOOL DSPROPERTY_descWtoA(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
@ -589,24 +612,23 @@ static const IKsPropertySetVtbl ikspvt = {
IKsPrivatePropertySetImpl_QuerySupport
};
HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, void **ppv)
HRESULT IKsPrivatePropertySetImpl_Create(
REFIID riid,
IKsPropertySet **piks)
{
IKsPrivatePropertySetImpl *iks;
HRESULT hr;
TRACE("(%s, %p)\n", debugstr_guid(riid), piks);
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
iks = HeapAlloc(GetProcessHeap(), 0, sizeof(*iks));
if (!iks) {
WARN("out of memory\n");
return DSERR_OUTOFMEMORY;
if (!IsEqualIID(riid, &IID_IUnknown) &&
!IsEqualIID(riid, &IID_IKsPropertySet)) {
*piks = 0;
return E_NOINTERFACE;
}
iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
iks->ref = 1;
iks->IKsPropertySet_iface.lpVtbl = &ikspvt;
hr = IKsPropertySet_QueryInterface(&iks->IKsPropertySet_iface, riid, ppv);
IKsPropertySet_Release(&iks->IKsPropertySet_iface);
return hr;
*piks = &iks->IKsPropertySet_iface;
return S_OK;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,366 @@
/*
* DirectSound driver
* (DirectX 5 version)
*
* Copyright (C) 2000 Ove Kaaven
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_DSDRIVER_H
#define __WINE_DSDRIVER_H
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************
* Predeclare the interfaces
*/
DEFINE_GUID(IID_IDsDriver, 0x8C4233C0l, 0xB4CC, 0x11CE, 0x92, 0x94, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);
typedef struct IDsDriver *PIDSDRIVER;
DEFINE_GUID(IID_IDsDriverBuffer, 0x8C4233C1l, 0xB4CC, 0x11CE, 0x92, 0x94, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);
typedef struct IDsDriverBuffer *PIDSDRIVERBUFFER;
DEFINE_GUID(IID_IDsDriverPropertySet, 0x0F6F2E8E0, 0xD842, 0x11D0, 0x8F, 0x75, 0x00, 0xC0, 0x4F, 0xC2, 0x8A, 0xCA);
typedef struct IDsDriverPropertySet *PIDSDRIVERPROPERTYSET;
DEFINE_GUID(IID_IDsDriverNotify, 0x00363EF44, 0x3B57, 0x11D3, 0xAC, 0x79, 0x00, 0x10, 0x5A, 0x01, 0x7f, 0xe1);
typedef struct IDsDriverNotify *PIDSDRIVERNOTIFY;
DEFINE_GUID(IID_IDsCaptureDriver, 0x03DD10C47, 0x74FB, 0x11D3, 0x90, 0x49, 0xCB, 0xB4, 0xB3, 0x2E, 0xAA, 0x08);
typedef struct IDsCaptureDriver *PIDSCDRIVER;
DEFINE_GUID(IID_IDsCaptureDriverBuffer, 0x03DD10C48, 0x74FB, 0x11D3, 0x90, 0x49, 0xCB, 0xB4, 0xB3, 0x2E, 0xAA, 0x08);
typedef struct IDsCaptureDriverBuffer *PIDSCDRIVERBUFFER;
#define DSDDESC_DOMMSYSTEMOPEN 0x00000001
#define DSDDESC_DOMMSYSTEMSETFORMAT 0x00000002
#define DSDDESC_USESYSTEMMEMORY 0x00000004
#define DSDDESC_DONTNEEDPRIMARYLOCK 0x00000008
#define DSDDESC_DONTNEEDSECONDARYLOCK 0x00000010
#define DSDDESC_DONTNEEDWRITELEAD 0x00000020
#define DSDHEAP_NOHEAP 0
#define DSDHEAP_CREATEHEAP 1
#define DSDHEAP_USEDIRECTDRAWHEAP 2
#define DSDHEAP_PRIVATEHEAP 3
typedef struct _DSDRIVERDESC
{
DWORD dwFlags;
CHAR szDesc[256];
CHAR szDrvname[256];
DWORD dnDevNode;
WORD wVxdId;
WORD wReserved;
ULONG ulDeviceNum;
DWORD dwHeapType;
LPVOID pvDirectDrawHeap;
DWORD dwMemStartAddress;
DWORD dwMemEndAddress;
DWORD dwMemAllocExtra;
LPVOID pvReserved1;
LPVOID pvReserved2;
} DSDRIVERDESC,*PDSDRIVERDESC;
typedef struct _DSDRIVERCAPS
{
DWORD dwFlags;
DWORD dwMinSecondarySampleRate;
DWORD dwMaxSecondarySampleRate;
DWORD dwPrimaryBuffers;
DWORD dwMaxHwMixingAllBuffers;
DWORD dwMaxHwMixingStaticBuffers;
DWORD dwMaxHwMixingStreamingBuffers;
DWORD dwFreeHwMixingAllBuffers;
DWORD dwFreeHwMixingStaticBuffers;
DWORD dwFreeHwMixingStreamingBuffers;
DWORD dwMaxHw3DAllBuffers;
DWORD dwMaxHw3DStaticBuffers;
DWORD dwMaxHw3DStreamingBuffers;
DWORD dwFreeHw3DAllBuffers;
DWORD dwFreeHw3DStaticBuffers;
DWORD dwFreeHw3DStreamingBuffers;
DWORD dwTotalHwMemBytes;
DWORD dwFreeHwMemBytes;
DWORD dwMaxContigFreeHwMemBytes;
} DSDRIVERCAPS,*PDSDRIVERCAPS;
typedef struct _DSVOLUMEPAN
{
DWORD dwTotalLeftAmpFactor;
DWORD dwTotalRightAmpFactor;
LONG lVolume;
DWORD dwVolAmpFactor;
LONG lPan;
DWORD dwPanLeftAmpFactor;
DWORD dwPanRightAmpFactor;
} DSVOLUMEPAN,*PDSVOLUMEPAN;
typedef union _DSPROPERTY
{
struct {
GUID Set;
ULONG Id;
ULONG Flags;
ULONG InstanceId;
} DUMMYSTRUCTNAME;
ULONGLONG Alignment;
} DSPROPERTY,*PDSPROPERTY;
typedef struct _DSCDRIVERCAPS
{
DWORD dwSize;
DWORD dwFlags;
DWORD dwFormats;
DWORD dwChannels;
} DSCDRIVERCAPS,*PDSCDRIVERCAPS;
/*****************************************************************************
* IDsDriver interface
*/
#define INTERFACE IDsDriver
DECLARE_INTERFACE_(IDsDriver,IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
/*** IDsDriver methods ***/
STDMETHOD(GetDriverDesc)(THIS_ PDSDRIVERDESC pDsDriverDesc) PURE;
STDMETHOD(Open)(THIS) PURE;
STDMETHOD(Close)(THIS) PURE;
STDMETHOD(GetCaps)(THIS_ PDSDRIVERCAPS pDsDrvCaps) PURE;
STDMETHOD(CreateSoundBuffer)(THIS_ LPWAVEFORMATEX pwfx,DWORD dwFlags,DWORD dwCardAddress,LPDWORD pdwcbBufferSize,LPBYTE *ppbBuffer,LPVOID *ppvObj) PURE;
STDMETHOD(DuplicateSoundBuffer)(THIS_ PIDSDRIVERBUFFER pIDsDriverBuffer,LPVOID *ppvObj) PURE;
};
#undef INTERFACE
#if !defined (__cplusplus) || defined(CINTERFACE)
/*** IUnknown methods ***/
#define IDsDriver_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IDsDriver_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IDsDriver_Release(p) (p)->lpVtbl->Release(p)
/*** IDsDriver methods ***/
#define IDsDriver_GetDriverDesc(p,a) (p)->lpVtbl->GetDriverDesc(p,a)
#define IDsDriver_Open(p) (p)->lpVtbl->Open(p)
#define IDsDriver_Close(p) (p)->lpVtbl->Close(p)
#define IDsDriver_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a)
#define IDsDriver_CreateSoundBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateSoundBuffer(p,a,b,c,d,e,f)
#define IDsDriver_DuplicateSoundBuffer(p,a,b) (p)->lpVtbl->DuplicateSoundBuffer(p,a,b)
#endif
/*****************************************************************************
* IDsDriverBuffer interface
*/
#define INTERFACE IDsDriverBuffer
DECLARE_INTERFACE_(IDsDriverBuffer,IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
/*** IDsDriverBuffer methods ***/
STDMETHOD(Lock)(THIS_ LPVOID *ppvAudio1,LPDWORD pdwLen1,LPVOID *pdwAudio2,LPDWORD pdwLen2,DWORD dwWritePosition,DWORD dwWriteLen,DWORD dwFlags) PURE;
STDMETHOD(Unlock)(THIS_ LPVOID pvAudio1,DWORD dwLen1,LPVOID pvAudio2,DWORD dwLen2) PURE;
STDMETHOD(SetFormat)(THIS_ LPWAVEFORMATEX pwfxToSet) PURE;
STDMETHOD(SetFrequency)(THIS_ DWORD dwFrequency) PURE;
STDMETHOD(SetVolumePan)(THIS_ PDSVOLUMEPAN pDsVolumePan) PURE;
STDMETHOD(SetPosition)(THIS_ DWORD dwNewPosition) PURE;
STDMETHOD(GetPosition)(THIS_ LPDWORD lpdwCurrentPlayCursor,LPDWORD lpdwCurrentWriteCursor) PURE;
STDMETHOD(Play)(THIS_ DWORD dwReserved1,DWORD dwReserved2,DWORD dwFlags) PURE;
STDMETHOD(Stop)(THIS) PURE;
};
#undef INTERFACE
#if !defined (__cplusplus) || defined(CINTERFACE)
/*** IUnknown methods ***/
#define IDsDriverBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IDsDriverBuffer_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IDsDriverBuffer_Release(p) (p)->lpVtbl->Release(p)
/*** IDsDriverBuffer methods ***/
#define IDsDriverBuffer_Lock(p,a,b,c,d,e,f,g) (p)->lpVtbl->Lock(p,a,b,c,d,e,f,g)
#define IDsDriverBuffer_Unlock(p,a,b,c,d) (p)->lpVtbl->Unlock(p,a,b,c,d)
#define IDsDriverBuffer_SetFormat(p,a) (p)->lpVtbl->SetFormat(p,a)
#define IDsDriverBuffer_SetFrequency(p,a) (p)->lpVtbl->SetFrequency(p,a)
#define IDsDriverBuffer_SetVolumePan(p,a) (p)->lpVtbl->SetVolumePan(p,a)
#define IDsDriverBuffer_SetPosition(p,a) (p)->lpVtbl->SetPosition(p,a)
#define IDsDriverBuffer_GetPosition(p,a,b) (p)->lpVtbl->GetPosition(p,a,b)
#define IDsDriverBuffer_Play(p,a,b,c) (p)->lpVtbl->Play(p,a,b,c)
#define IDsDriverBuffer_Stop(p) (p)->lpVtbl->Stop(p)
#endif
/*****************************************************************************
* IDsDriverPropertySet interface
*/
#define INTERFACE IDsDriverPropertySet
DECLARE_INTERFACE_(IDsDriverPropertySet,IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
/*** IDsDriverPropertySet methods ***/
STDMETHOD(Get)(THIS_ PDSPROPERTY pDsProperty,LPVOID pPropertyParams,ULONG cbPropertyParams,LPVOID pPropertyData,ULONG cbPropertyData,PULONG pcbReturnedData) PURE;
STDMETHOD(Set)(THIS_ PDSPROPERTY pDsProperty,LPVOID pPropertyParams,ULONG cbPropertyParams,LPVOID pPropertyData,ULONG cbPropertyData) PURE;
STDMETHOD(QuerySupport)(THIS_ REFGUID PropertySetId,ULONG PropertyId,PULONG pSupport) PURE;
};
#undef INTERFACE
#if !defined (__cplusplus) || defined(CINTERFACE)
/*** IUnknown methods ***/
#define IDsDriverPropertySet_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IDsDriverPropertySet_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IDsDriverPropertySet_Release(p) (p)->lpVtbl->Release(p)
/*** IDsDriverPropertySet methods ***/
#define IDsDriverPropertySet_Get(p,a,b,c,d,e,f) (p)->lpVtbl->Get(p,a,b,c,d,e,f)
#define IDsDriverPropertySet_Set(p,a,b,c,d,e) (p)->lpVtbl->Set(p,a,b,c,d,e)
#define IDsDriverPropertySet_QuerySupport(p,a,b,c) (p)->lpVtbl->QuerySupport(p,a,b,c)
#endif
/* Defined property sets */
DEFINE_GUID(DSPROPSETID_DirectSound3DListener, 0x6D047B40, 0x7AF9, 0x11D0, 0x92, 0x94, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0);
typedef enum
{
DSPROPERTY_DIRECTSOUND3DLISTENER_ALL,
DSPROPERTY_DIRECTSOUND3DLISTENER_POSITION,
DSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY,
DSPROPERTY_DIRECTSOUND3DLISTENER_ORIENTATION,
DSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR,
DSPROPERTY_DIRECTSOUND3DLISTENER_ROLLOFFFACTOR,
DSPROPERTY_DIRECTSOUND3DLISTENER_DOPPLERFACTOR,
DSPROPERTY_DIRECTSOUND3DLISTENER_BATCH,
DSPROPERTY_DIRECTSOUND3DLISTENER_ALLOCATION
} DSPROPERTY_DIRECTSOUND3DLISTENER;
DEFINE_GUID(DSPROPSETID_DirectSound3DBuffer, 0x6D047B41, 0x7AF9, 0x11D0, 0x92, 0x94, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0);
typedef enum
{
DSPROPERTY_DIRECTSOUND3DBUFFER_ALL,
DSPROPERTY_DIRECTSOUND3DBUFFER_POSITION,
DSPROPERTY_DIRECTSOUND3DBUFFER_VELOCITY,
DSPROPERTY_DIRECTSOUND3DBUFFER_CONEANGLES,
DSPROPERTY_DIRECTSOUND3DBUFFER_CONEORIENTATION,
DSPROPERTY_DIRECTSOUND3DBUFFER_CONEOUTSIDEVOLUME,
DSPROPERTY_DIRECTSOUND3DBUFFER_MINDISTANCE,
DSPROPERTY_DIRECTSOUND3DBUFFER_MAXDISTANCE,
DSPROPERTY_DIRECTSOUND3DBUFFER_MODE
} DSPROPERTY_DIRECTSOUND3DBUFFER;
DEFINE_GUID(DSPROPSETID_DirectSoundSpeakerConfig, 0x6D047B42, 0x7AF9, 0x11D0, 0x92, 0x94, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0);
typedef enum
{
DSPROPERTY_DIRECTSOUNDSPEAKERCONFIG_SPEAKERCONFIG
} DSPROPERTY_DIRECTSOUNDSPEAKERCONFIG;
/*****************************************************************************
* IDsDriverNotify interface
*/
#define INTERFACE IDsDriverNotify
DECLARE_INTERFACE_(IDsDriverNotify,IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
/*** IDsDriverNotify methods ***/
STDMETHOD(SetNotificationPositions)(THIS_ DWORD dwPositionNotifies,LPCDSBPOSITIONNOTIFY pcPositionNotifies) PURE;
};
#undef INTERFACE
#if !defined (__cplusplus) || defined(CINTERFACE)
/*** IUnknown methods ***/
#define IDsDriverNotify_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IDsDriverNotify_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IDsDriverNotify_Release(p) (p)->lpVtbl->Release(p)
/*** IDsDriverNotify methods ***/
#define IDsDriverNotify_SetNotificationPositions(p,a,b) (p)->lpVtbl->SetNotificationPositions(p,a,b)
#endif
/*****************************************************************************
* IDsCaptureDriver interface
*/
#define INTERFACE IDsCaptureDriver
DECLARE_INTERFACE_(IDsCaptureDriver,IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
/*** IDsCaptureDriver methods ***/
STDMETHOD(GetDriverDesc)(THIS_ PDSDRIVERDESC pDsDriverDesc) PURE;
STDMETHOD(Open)(THIS) PURE;
STDMETHOD(Close)(THIS) PURE;
STDMETHOD(GetCaps)(THIS_ PDSCDRIVERCAPS pDsDrvCaps) PURE;
STDMETHOD(CreateCaptureBuffer)(THIS_ LPWAVEFORMATEX pwfx,DWORD dwFlags,DWORD dwCardAddress,LPDWORD pdwcbBufferSize,LPBYTE *ppbBuffer,LPVOID *ppvObj) PURE;
};
#undef INTERFACE
#if !defined (__cplusplus) || defined(CINTERFACE)
/*** IUnknown methods ***/
#define IDsCaptureDriver_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IDsCaptureDriver_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IDsCaptureDriver_Release(p) (p)->lpVtbl->Release(p)
/*** IDsCaptureDriver methods ***/
#define IDsCaptureDriver_GetDriverDesc(p,a) (p)->lpVtbl->GetDriverDesc(p,a)
#define IDsCaptureDriver_Open(p) (p)->lpVtbl->Open(p)
#define IDsCaptureDriver_Close(p) (p)->lpVtbl->Close(p)
#define IDsCaptureDriver_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a)
#define IDsCaptureDriver_CreateCaptureBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateCaptureBuffer(p,a,b,c,d,e,f)
#endif
/*****************************************************************************
* IDsCaptureDriverBuffer interface
*/
#define INTERFACE IDsCaptureDriverBuffer
DECLARE_INTERFACE_(IDsCaptureDriverBuffer,IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
/*** IDsCaptureDriverBuffer methods ***/
STDMETHOD(Lock)(THIS_ LPVOID *ppvAudio1,LPDWORD pdwLen1,LPVOID *ppvAudio2,LPDWORD pdwLen2,DWORD dwWritePosition,DWORD dwWriteLen,DWORD dwFlags) PURE;
STDMETHOD(Unlock)(THIS_ LPVOID pvAudio1,DWORD dwLen1,LPVOID pvAudio2,DWORD dwLen2) PURE;
STDMETHOD(SetFormat)(THIS_ LPWAVEFORMATEX pwfxToSet) PURE;
STDMETHOD(GetPosition)(THIS_ LPDWORD lpdwCurrentPlayCursor,LPDWORD lpdwCurrentWriteCursor) PURE;
STDMETHOD(GetStatus)(THIS_ LPDWORD lpdwStatus) PURE;
STDMETHOD(Start)(THIS_ DWORD dwFlags) PURE;
STDMETHOD(Stop)(THIS) PURE;
};
#undef INTERFACE
#if !defined (__cplusplus) || defined(CINTERFACE)
/*** IUnknown methods ***/
#define IDsCaptureDriverBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IDsCaptureDriverBuffer_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IDsCaptureDriverBuffer_Release(p) (p)->lpVtbl->Release(p)
/*** IDsCaptureDriverBuffer methods ***/
#define IDsCaptureDriverBuffer_Lock(p,a,b,c,d,e,f,g) (p)->lpVtbl->Lock(p,a,b,c,d,e,f,g)
#define IDsCaptureDriverBuffer_Unlock(p,a,b,c,d) (p)->lpVtbl->Unlock(p,a,b,c,d)
#define IDsCaptureDriverBuffer_SetFormat(p,a) (p)->lpVtbl->SetFormat(p,a)
#define IDsCaptureDriverBuffer_GetPosition(p,a,b) (p)->lpVtbl->GetPosition(p,a,b)
#define IDsCaptureDriverBuffer_GetStatus(p,a) (p)->lpVtbl->GetStatus(p,a)
#define IDsCaptureDriverBuffer_Start(p,a) (p)->lpVtbl->Start(p,a)
#define IDsCaptureDriverBuffer_Stop(p) (p)->lpVtbl->Stop(p)
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __WINE_DSDRIVER_H */

View file

@ -40,7 +40,7 @@ reactos/dll/directx/wine/dinput8 # Synced to Wine-1.7.27
reactos/dll/directx/wine/dmusic # Synced to Wine-1.7.27
reactos/dll/directx/wine/dplay # Synced to Wine-1.7.27
reactos/dll/directx/wine/dplayx # Synced to Wine-1.7.27
reactos/dll/directx/wine/dsound # Synced to Wine-1.5.26
reactos/dll/directx/wine/dsound # Synced to Wine-1.3.29
reactos/dll/directx/wine/dxdiagn # Synced to Wine-1.7.27
reactos/dll/directx/wine/dxgi # Synced to Wine-1.7.27
reactos/dll/directx/wine/msdmo # Synced to Wine-1.7.27