dsound: Add support for 32-bit IEEE float buffers.
This commit is contained in:
parent
7571fb5456
commit
d6f3ca9589
|
@ -1591,14 +1591,14 @@ HRESULT DirectSoundDevice_CreateSoundBuffer(
|
|||
|
||||
/* cbSize should be 22 bytes, with one possible exception */
|
||||
if (pwfxe->Format.cbSize > (sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)) &&
|
||||
!(IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) &&
|
||||
!((IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) || IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) &&
|
||||
pwfxe->Format.cbSize == sizeof(WAVEFORMATEXTENSIBLE)))
|
||||
{
|
||||
WARN("Too big a cbSize %u\n", pwfxe->Format.cbSize);
|
||||
return DSERR_CONTROLUNAVAIL;
|
||||
}
|
||||
|
||||
if (!IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))
|
||||
if ((!IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) && (!IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
|
||||
{
|
||||
if (!IsEqualGUID(&pwfxe->SubFormat, &GUID_NULL))
|
||||
FIXME("SubFormat %s not supported right now.\n", debugstr_guid(&pwfxe->SubFormat));
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* DirectSound format conversion and mixing routines
|
||||
*
|
||||
* Copyright 2007 Maarten Lankhorst
|
||||
* Copyright 2011 Owen Rudge for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -295,11 +296,121 @@ static void convert_32_to_32 (const void *src, void *dst, UINT src_stride,
|
|||
}
|
||||
}
|
||||
|
||||
const bitsconvertfunc convertbpp[4][4] = {
|
||||
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)
|
||||
|
|
|
@ -65,7 +65,7 @@ typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice;
|
|||
|
||||
/* dsound_convert.h */
|
||||
typedef void (*bitsconvertfunc)(const void *, void *, UINT, UINT, INT, UINT, UINT);
|
||||
extern const bitsconvertfunc convertbpp[4][4];
|
||||
extern const bitsconvertfunc convertbpp[5][4];
|
||||
typedef void (*mixfunc)(const void *, void *, unsigned);
|
||||
extern const mixfunc mixfunctions[4];
|
||||
typedef void (*normfunc)(const void *, void *, unsigned);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* Copyright 2000-2002 TransGaming Technologies, Inc.
|
||||
* Copyright 2007 Peter Dons Tychsen
|
||||
* Copyright 2007 Maarten Lankhorst
|
||||
* Copyright 2011 Owen Rudge for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -30,9 +31,13 @@
|
|||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "mmsystem.h"
|
||||
#include "wingdi.h"
|
||||
#include "mmreg.h"
|
||||
#include "winternl.h"
|
||||
#include "wine/debug.h"
|
||||
#include "dsound.h"
|
||||
#include "ks.h"
|
||||
#include "ksmedia.h"
|
||||
#include "dsdriver.h"
|
||||
#include "dsound_private.h"
|
||||
|
||||
|
@ -177,21 +182,32 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
|
|||
{
|
||||
BOOL needremix = TRUE, needresample = (dsb->freq != dsb->device->pwfx->nSamplesPerSec);
|
||||
DWORD bAlign = dsb->pwfx->nBlockAlign, pAlign = dsb->device->pwfx->nBlockAlign;
|
||||
WAVEFORMATEXTENSIBLE *pwfxe;
|
||||
BOOL ieee = FALSE;
|
||||
|
||||
TRACE("(%p)\n",dsb);
|
||||
|
||||
pwfxe = (WAVEFORMATEXTENSIBLE *) dsb->pwfx;
|
||||
|
||||
if ((pwfxe->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) || ((pwfxe->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE)
|
||||
&& (IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))))
|
||||
ieee = TRUE;
|
||||
|
||||
/* calculate the 10ms write lead */
|
||||
dsb->writelead = (dsb->freq / 100) * dsb->pwfx->nBlockAlign;
|
||||
|
||||
if ((dsb->pwfx->wBitsPerSample == dsb->device->pwfx->wBitsPerSample) &&
|
||||
(dsb->pwfx->nChannels == dsb->device->pwfx->nChannels) && !needresample)
|
||||
(dsb->pwfx->nChannels == dsb->device->pwfx->nChannels) && !needresample && !ieee)
|
||||
needremix = FALSE;
|
||||
HeapFree(GetProcessHeap(), 0, dsb->tmp_buffer);
|
||||
dsb->tmp_buffer = NULL;
|
||||
dsb->max_buffer_len = dsb->freqAcc = dsb->freqAccNext = 0;
|
||||
dsb->freqneeded = needresample;
|
||||
|
||||
dsb->convert = convertbpp[dsb->pwfx->wBitsPerSample/8 - 1][dsb->device->pwfx->wBitsPerSample/8 - 1];
|
||||
if (ieee)
|
||||
dsb->convert = convertbpp[4][dsb->device->pwfx->wBitsPerSample/8 - 1];
|
||||
else
|
||||
dsb->convert = convertbpp[dsb->pwfx->wBitsPerSample/8 - 1][dsb->device->pwfx->wBitsPerSample/8 - 1];
|
||||
|
||||
dsb->resampleinmixer = FALSE;
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ typedef struct _WAVEFORMATEX {
|
|||
/* WAVE form wFormatTag IDs */
|
||||
#define WAVE_FORMAT_UNKNOWN 0x0000 /* Microsoft Corporation */
|
||||
#define WAVE_FORMAT_ADPCM 0x0002 /* Microsoft Corporation */
|
||||
#define WAVE_FORMAT_IEEE_FLOAT 0x0003 /* Microsoft Corporation */
|
||||
#define WAVE_FORMAT_IBM_CVSD 0x0005 /* IBM Corporation */
|
||||
#define WAVE_FORMAT_ALAW 0x0006 /* Microsoft Corporation */
|
||||
#define WAVE_FORMAT_MULAW 0x0007 /* Microsoft Corporation */
|
||||
|
|
Loading…
Reference in New Issue