mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[DSOUND]
* 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:
parent
a03f39b92f
commit
17cc5b0dab
16 changed files with 5961 additions and 5111 deletions
|
@ -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
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
@ -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
|
@ -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
366
reactos/include/dxsdk/dsdriver.h
Normal file
366
reactos/include/dxsdk/dsdriver.h
Normal 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 */
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue