Commit 98c653bc authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

dsound: Resample to float, not device format.

parent 20356f74
...@@ -125,13 +125,6 @@ static inline unsigned char f_to_8(float value) ...@@ -125,13 +125,6 @@ static inline unsigned char f_to_8(float value)
return lrintf((value + 1.f) * 0x80); return lrintf((value + 1.f) * 0x80);
} }
static void put8(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value)
{
BYTE* buf = dsb->device->tmp_buffer;
buf += pos + channel;
*buf = f_to_8(value);
}
static inline SHORT f_to_16(float value) static inline SHORT f_to_16(float value)
{ {
if(value <= -1.f) if(value <= -1.f)
...@@ -141,13 +134,6 @@ static inline SHORT f_to_16(float value) ...@@ -141,13 +134,6 @@ static inline SHORT f_to_16(float value)
return le16(lrintf(value * 0x8000)); return le16(lrintf(value * 0x8000));
} }
static void put16(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value)
{
BYTE* buf = dsb->device->tmp_buffer;
SHORT *sbuf = (SHORT*)(buf + pos + 2 * channel);
*sbuf = f_to_16(value);
}
static LONG f_to_24(float value) static LONG f_to_24(float value)
{ {
if(value <= -1.f) if(value <= -1.f)
...@@ -157,17 +143,6 @@ static LONG f_to_24(float value) ...@@ -157,17 +143,6 @@ static LONG f_to_24(float value)
return lrintf(value * 0x80000000U); return lrintf(value * 0x80000000U);
} }
static void put24(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value)
{
BYTE* buf = dsb->device->tmp_buffer;
LONG t;
buf += pos + 3 * channel;
t = f_to_24(value);
buf[0] = (t >> 8) & 0xFF;
buf[1] = (t >> 16) & 0xFF;
buf[2] = (t >> 24) & 0xFF;
}
static inline LONG f_to_32(float value) static inline LONG f_to_32(float value)
{ {
if(value <= -1.f) if(value <= -1.f)
...@@ -177,79 +152,26 @@ static inline LONG f_to_32(float value) ...@@ -177,79 +152,26 @@ static inline LONG f_to_32(float value)
return le32(lrintf(value * 0x80000000U)); return le32(lrintf(value * 0x80000000U));
} }
static void put32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value)
{ {
BYTE* buf = dsb->device->tmp_buffer; BYTE *buf = (BYTE *)dsb->device->tmp_buffer;
LONG *sbuf = (LONG*)(buf + pos + 4 * channel); float *fbuf = (float*)(buf + pos + sizeof(float) * channel);
*sbuf = f_to_32(value); *fbuf = value;
} }
const bitsputfunc putbpp[4] = {put8, put16, put24, put32};
void put_mono2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) void put_mono2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value)
{ {
dsb->put_aux(dsb, pos, 0, value); dsb->put_aux(dsb, pos, 0, value);
dsb->put_aux(dsb, pos, 1, value); dsb->put_aux(dsb, pos, 1, value);
} }
static void mix8(signed char *src, float *dst, unsigned len) void mixieee32(float *src, float *dst, unsigned samples)
{
TRACE("%p - %p %d\n", src, dst, len);
while (len--)
/* 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)) / (float)0x80;
}
static void mix16(SHORT *src, float *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
len /= 2;
while (len--)
{
*dst += le16(*src) / (float)0x8000U;
++dst; ++src;
}
}
static void mix24(BYTE *src, float *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
len /= 3;
while (len--)
{
DWORD field;
field = ((DWORD)src[2] << 16) + ((DWORD)src[1] << 8) + (DWORD)src[0];
if (src[2] & 0x80)
field |= 0xFF000000U;
*(dst++) += field / (float)0x800000U;
src += 3;
}
}
static void mix32(INT *src, float *dst, unsigned len)
{ {
TRACE("%p - %p %d\n", src, dst, len); TRACE("%p - %p %d\n", src, dst, samples);
len /= 4; while (samples--)
while (len--)
*(dst++) += le32(*(src++)) / (float)0x80000000U;
}
static void mixieee32(float *src, float *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
len /= 4;
while (len--)
*(dst++) += *(src++); *(dst++) += *(src++);
} }
const mixfunc mixfunctions[5] = {
(mixfunc)mix8,
(mixfunc)mix16,
(mixfunc)mix24,
(mixfunc)mix32,
(mixfunc)mixieee32
};
static void norm8(float *src, unsigned char *dst, unsigned len) static void norm8(float *src, unsigned char *dst, unsigned len)
{ {
TRACE("%p - %p %d\n", src, dst, len); TRACE("%p - %p %d\n", src, dst, len);
......
...@@ -55,9 +55,8 @@ typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice; ...@@ -55,9 +55,8 @@ typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice;
typedef float (*bitsgetfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD); typedef float (*bitsgetfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD);
typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD, float); typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD, float);
extern const bitsgetfunc getbpp[5] DECLSPEC_HIDDEN; extern const bitsgetfunc getbpp[5] DECLSPEC_HIDDEN;
extern const bitsputfunc putbpp[4] DECLSPEC_HIDDEN; void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
typedef void (*mixfunc)(const void *, void *, unsigned); void mixieee32(float *src, float *dst, unsigned samples) DECLSPEC_HIDDEN;
extern const mixfunc mixfunctions[5] DECLSPEC_HIDDEN;
typedef void (*normfunc)(const void *, void *, unsigned); typedef void (*normfunc)(const void *, void *, unsigned);
extern const normfunc normfunctions[5] DECLSPEC_HIDDEN; extern const normfunc normfunctions[5] DECLSPEC_HIDDEN;
...@@ -94,13 +93,11 @@ struct DirectSoundDevice ...@@ -94,13 +93,11 @@ struct DirectSoundDevice
CRITICAL_SECTION mixlock; CRITICAL_SECTION mixlock;
IDirectSoundBufferImpl *primary; IDirectSoundBufferImpl *primary;
DWORD speaker_config; DWORD speaker_config;
LPBYTE tmp_buffer; float *mix_buffer, *tmp_buffer;
float *mix_buffer;
DWORD tmp_buffer_len, mix_buffer_len; DWORD tmp_buffer_len, mix_buffer_len;
DSVOLUMEPAN volpan; DSVOLUMEPAN volpan;
mixfunc mixfunction;
normfunc normfunction; normfunc normfunction;
/* DirectSound3DListener fields */ /* DirectSound3DListener fields */
......
...@@ -141,7 +141,7 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) ...@@ -141,7 +141,7 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
dsb->freqAcc = 0; dsb->freqAcc = 0;
dsb->get_aux = ieee ? getbpp[4] : getbpp[dsb->pwfx->wBitsPerSample/8 - 1]; dsb->get_aux = ieee ? getbpp[4] : getbpp[dsb->pwfx->wBitsPerSample/8 - 1];
dsb->put_aux = putbpp[dsb->device->pwfx->wBitsPerSample/8 - 1]; dsb->put_aux = putieee32;
dsb->get = dsb->get_aux; dsb->get = dsb->get_aux;
dsb->put = dsb->put_aux; dsb->put = dsb->put_aux;
...@@ -234,10 +234,10 @@ static inline float get_current_sample(const IDirectSoundBufferImpl *dsb, ...@@ -234,10 +234,10 @@ static inline float get_current_sample(const IDirectSoundBufferImpl *dsb,
return dsb->get(dsb, mixpos % dsb->buflen, channel); return dsb->get(dsb, mixpos % dsb->buflen, channel);
} }
static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count)
UINT ostride, UINT count)
{ {
UINT istride = dsb->pwfx->nBlockAlign; UINT istride = dsb->pwfx->nBlockAlign;
UINT ostride = dsb->device->pwfx->nChannels * sizeof(float);
DWORD channel, i; DWORD channel, i;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
for (channel = 0; channel < dsb->mix_channels; channel++) for (channel = 0; channel < dsb->mix_channels; channel++)
...@@ -246,11 +246,11 @@ static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, ...@@ -246,11 +246,11 @@ static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb,
return count; return count;
} }
static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, float *freqAcc)
UINT ostride, UINT count, float *freqAcc)
{ {
UINT i, channel; UINT i, channel;
UINT istride = dsb->pwfx->nBlockAlign; UINT istride = dsb->pwfx->nBlockAlign;
UINT ostride = dsb->device->pwfx->nChannels * sizeof(float);
float freqAdjust = dsb->freqAdjust; float freqAdjust = dsb->freqAdjust;
float freqAcc_start = *freqAcc; float freqAcc_start = *freqAcc;
...@@ -314,15 +314,14 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, ...@@ -314,15 +314,14 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb,
return max_ipos; return max_ipos;
} }
static void cp_fields(IDirectSoundBufferImpl *dsb, static void cp_fields(IDirectSoundBufferImpl *dsb, UINT count, float *freqAcc)
UINT ostride, UINT count, float *freqAcc)
{ {
DWORD ipos, adv; DWORD ipos, adv;
if (dsb->freqAdjust == 1.0) if (dsb->freqAdjust == 1.0)
adv = cp_fields_noresample(dsb, ostride, count); /* *freqAcc is unmodified */ adv = cp_fields_noresample(dsb, count); /* *freqAcc is unmodified */
else else
adv = cp_fields_resample(dsb, ostride, count, freqAcc); adv = cp_fields_resample(dsb, count, freqAcc);
ipos = dsb->sec_mixpos + adv * dsb->pwfx->nBlockAlign; ipos = dsb->sec_mixpos + adv * dsb->pwfx->nBlockAlign;
if (ipos >= dsb->buflen) { if (ipos >= dsb->buflen) {
...@@ -365,89 +364,53 @@ static inline DWORD DSOUND_BufPtrDiff(DWORD buflen, DWORD ptr1, DWORD ptr2) ...@@ -365,89 +364,53 @@ static inline DWORD DSOUND_BufPtrDiff(DWORD buflen, DWORD ptr1, DWORD ptr2)
* *
* NOTE: writepos + len <= buflen. When called by mixer, MixOne makes sure of this. * NOTE: writepos + len <= buflen. When called by mixer, MixOne makes sure of this.
*/ */
static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD tmp_len) static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD frames)
{ {
INT oAdvance = dsb->device->pwfx->nBlockAlign; UINT size_bytes = frames * sizeof(float) * dsb->device->pwfx->nChannels;
INT size = tmp_len / oAdvance;
if (dsb->device->tmp_buffer_len < tmp_len || !dsb->device->tmp_buffer) if (dsb->device->tmp_buffer_len < size_bytes || !dsb->device->tmp_buffer)
{ {
dsb->device->tmp_buffer_len = tmp_len; dsb->device->tmp_buffer_len = size_bytes;
if (dsb->device->tmp_buffer) if (dsb->device->tmp_buffer)
dsb->device->tmp_buffer = HeapReAlloc(GetProcessHeap(), 0, dsb->device->tmp_buffer, tmp_len); dsb->device->tmp_buffer = HeapReAlloc(GetProcessHeap(), 0, dsb->device->tmp_buffer, size_bytes);
else else
dsb->device->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, tmp_len); dsb->device->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, size_bytes);
} }
cp_fields(dsb, oAdvance, size, &dsb->freqAcc); cp_fields(dsb, frames, &dsb->freqAcc);
} }
/** Apply volume to the given soundbuffer from (primary) position writepos and length len static void DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT frames)
* Returns: NULL if no volume needs to be applied
* or else a memory handle that holds 'len' volume adjusted buffer */
static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT len)
{ {
INT i; INT i;
BYTE *bpc; float vLeft, vRight;
INT16 *bps, *mems; UINT channels = dsb->device->pwfx->nChannels, chan;
DWORD vLeft, vRight;
INT nChannels = dsb->device->pwfx->nChannels;
LPBYTE mem = dsb->device->tmp_buffer;
TRACE("(%p,%d)\n",dsb,len); TRACE("(%p,%d)\n",dsb,frames);
TRACE("left = %x, right = %x\n", dsb->volpan.dwTotalLeftAmpFactor, TRACE("left = %x, right = %x\n", dsb->volpan.dwTotalLeftAmpFactor,
dsb->volpan.dwTotalRightAmpFactor); dsb->volpan.dwTotalRightAmpFactor);
if ((!(dsb->dsbd.dwFlags & DSBCAPS_CTRLPAN) || (dsb->volpan.lPan == 0)) && if ((!(dsb->dsbd.dwFlags & DSBCAPS_CTRLPAN) || (dsb->volpan.lPan == 0)) &&
(!(dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME) || (dsb->volpan.lVolume == 0)) && (!(dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME) || (dsb->volpan.lVolume == 0)) &&
!(dsb->dsbd.dwFlags & DSBCAPS_CTRL3D)) !(dsb->dsbd.dwFlags & DSBCAPS_CTRL3D))
return NULL; /* Nothing to do */ return; /* Nothing to do */
if (nChannels != 1 && nChannels != 2) if (channels != 1 && channels != 2)
{ {
FIXME("There is no support for %d channels\n", nChannels); FIXME("There is no support for %u channels\n", channels);
return NULL; return;
}
if (dsb->device->pwfx->wBitsPerSample != 8 && dsb->device->pwfx->wBitsPerSample != 16)
{
FIXME("There is no support for %d bpp\n", dsb->device->pwfx->wBitsPerSample);
return NULL;
} }
assert(dsb->device->tmp_buffer_len >= len && dsb->device->tmp_buffer); vLeft = dsb->volpan.dwTotalLeftAmpFactor / ((float)0xFFFF);
vRight = dsb->volpan.dwTotalRightAmpFactor / ((float)0xFFFF);
bpc = dsb->device->tmp_buffer; for(i = 0; i < frames; ++i){
bps = (INT16 *)bpc; for(chan = 0; chan < channels; ++chan){
mems = (INT16 *)mem; if(chan == 0)
vLeft = dsb->volpan.dwTotalLeftAmpFactor; dsb->device->tmp_buffer[i * channels + chan] *= vLeft;
if (nChannels > 1)
vRight = dsb->volpan.dwTotalRightAmpFactor;
else else
vRight = vLeft; dsb->device->tmp_buffer[i * channels + chan] *= vRight;
}
switch (dsb->device->pwfx->wBitsPerSample) { }
case 8:
/* 8-bit WAV is unsigned, but we need to operate */
/* on signed data for this to work properly */
for (i = 0; i < len-1; i+=2) {
*(bpc++) = (((*(mem++) - 128) * vLeft) >> 16) + 128;
*(bpc++) = (((*(mem++) - 128) * vRight) >> 16) + 128;
}
if (len % 2 == 1 && nChannels == 1)
*(bpc++) = (((*(mem++) - 128) * vLeft) >> 16) + 128;
break;
case 16:
/* 16-bit WAV is signed -- much better */
for (i = 0; i < len-3; i += 4) {
*(bps++) = (*(mems++) * vLeft) >> 16;
*(bps++) = (*(mems++) * vRight) >> 16;
}
if (len % 4 == 2 && nChannels == 1)
*(bps++) = ((INT)*(mems++) * vLeft) >> 16;
break;
}
return dsb->device->tmp_buffer;
} }
/** /**
...@@ -466,8 +429,9 @@ static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT len) ...@@ -466,8 +429,9 @@ static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT len)
static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD fraglen) static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD fraglen)
{ {
INT len = fraglen; INT len = fraglen;
BYTE *ibuf, *volbuf; float *ibuf;
DWORD oldpos; DWORD oldpos;
UINT frames = fraglen / dsb->device->pwfx->nBlockAlign;
TRACE("sec_mixpos=%d/%d\n", dsb->sec_mixpos, dsb->buflen); TRACE("sec_mixpos=%d/%d\n", dsb->sec_mixpos, dsb->buflen);
TRACE("(%p,%d,%d)\n",dsb,writepos,fraglen); TRACE("(%p,%d,%d)\n",dsb,writepos,fraglen);
...@@ -481,15 +445,13 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO ...@@ -481,15 +445,13 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
/* Resample buffer to temporary buffer specifically allocated for this purpose, if needed */ /* Resample buffer to temporary buffer specifically allocated for this purpose, if needed */
oldpos = dsb->sec_mixpos; oldpos = dsb->sec_mixpos;
DSOUND_MixToTemporary(dsb, len); DSOUND_MixToTemporary(dsb, frames);
ibuf = dsb->device->tmp_buffer; ibuf = dsb->device->tmp_buffer;
/* Apply volume if needed */ /* Apply volume if needed */
volbuf = DSOUND_MixerVol(dsb, len); DSOUND_MixerVol(dsb, frames);
if (volbuf)
ibuf = volbuf;
dsb->device->mixfunction(ibuf, dsb->device->mix_buffer, len); mixieee32(ibuf, dsb->device->mix_buffer, frames * dsb->device->pwfx->nChannels);
/* check for notification positions */ /* check for notification positions */
if (dsb->dsbd.dwFlags & DSBCAPS_CTRLPOSITIONNOTIFY && if (dsb->dsbd.dwFlags & DSBCAPS_CTRLPOSITIONNOTIFY &&
...@@ -694,6 +656,14 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force) ...@@ -694,6 +656,14 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
* Perform mixing for a Direct Sound device. That is, go through all the * Perform mixing for a Direct Sound device. That is, go through all the
* secondary buffers (the sound bites currently playing) and mix them in * secondary buffers (the sound bites currently playing) and mix them in
* to the primary buffer (the device buffer). * to the primary buffer (the device buffer).
*
* The mixing procedure goes:
*
* secondary->buffer (secondary format)
* =[Resample]=> device->tmp_buffer (float format)
* =[Volume]=> device->tmp_buffer (float format)
* =[Mix]=> device->mix_buffer (float format)
* =[Reformat]=> device->buffer (device format)
*/ */
static void DSOUND_PerformMix(DirectSoundDevice *device) static void DSOUND_PerformMix(DirectSoundDevice *device)
{ {
......
...@@ -189,13 +189,10 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) ...@@ -189,13 +189,10 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT || if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE && (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat, IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat,
&KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))){ &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
device->mixfunction = mixfunctions[4];
device->normfunction = normfunctions[4]; device->normfunction = normfunctions[4];
}else{ else
device->mixfunction = mixfunctions[device->pwfx->wBitsPerSample/8 - 1];
device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1]; device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
}
FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0); FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
FillMemory(device->mix_buffer, device->mix_buffer_len, 0); FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
...@@ -512,16 +509,14 @@ opened: ...@@ -512,16 +509,14 @@ opened:
WARN("DSOUND_PrimaryOpen(2) failed: %08x\n", err); WARN("DSOUND_PrimaryOpen(2) failed: %08x\n", err);
} }
if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT || if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE && (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat, IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat,
&KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))){ &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
device->mixfunction = mixfunctions[4];
device->normfunction = normfunctions[4]; device->normfunction = normfunctions[4];
}else{ else
device->mixfunction = mixfunctions[device->pwfx->wBitsPerSample/8 - 1];
device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1]; device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
}
if (old_fmt->nSamplesPerSec != device->pwfx->nSamplesPerSec || if (old_fmt->nSamplesPerSec != device->pwfx->nSamplesPerSec ||
old_fmt->wBitsPerSample != device->pwfx->wBitsPerSample || old_fmt->wBitsPerSample != device->pwfx->wBitsPerSample ||
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment