mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-05 22:30:15 +00:00
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 */
|
/* cbSize should be 22 bytes, with one possible exception */
|
||||||
if (pwfxe->Format.cbSize > (sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)) &&
|
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)))
|
pwfxe->Format.cbSize == sizeof(WAVEFORMATEXTENSIBLE)))
|
||||||
{
|
{
|
||||||
WARN("Too big a cbSize %u\n", pwfxe->Format.cbSize);
|
WARN("Too big a cbSize %u\n", pwfxe->Format.cbSize);
|
||||||
return DSERR_CONTROLUNAVAIL;
|
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))
|
if (!IsEqualGUID(&pwfxe->SubFormat, &GUID_NULL))
|
||||||
FIXME("SubFormat %s not supported right now.\n", debugstr_guid(&pwfxe->SubFormat));
|
FIXME("SubFormat %s not supported right now.\n", debugstr_guid(&pwfxe->SubFormat));
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* DirectSound format conversion and mixing routines
|
/* DirectSound format conversion and mixing routines
|
||||||
*
|
*
|
||||||
* Copyright 2007 Maarten Lankhorst
|
* Copyright 2007 Maarten Lankhorst
|
||||||
|
* Copyright 2011 Owen Rudge for CodeWeavers
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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_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_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_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_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)
|
static void mix8(signed char *src, INT *dst, unsigned len)
|
||||||
|
|
|
@ -65,7 +65,7 @@ typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice;
|
||||||
|
|
||||||
/* dsound_convert.h */
|
/* dsound_convert.h */
|
||||||
typedef void (*bitsconvertfunc)(const void *, void *, UINT, UINT, INT, UINT, UINT);
|
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);
|
typedef void (*mixfunc)(const void *, void *, unsigned);
|
||||||
extern const mixfunc mixfunctions[4];
|
extern const mixfunc mixfunctions[4];
|
||||||
typedef void (*normfunc)(const void *, void *, unsigned);
|
typedef void (*normfunc)(const void *, void *, unsigned);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* Copyright 2000-2002 TransGaming Technologies, Inc.
|
* Copyright 2000-2002 TransGaming Technologies, Inc.
|
||||||
* Copyright 2007 Peter Dons Tychsen
|
* Copyright 2007 Peter Dons Tychsen
|
||||||
* Copyright 2007 Maarten Lankhorst
|
* Copyright 2007 Maarten Lankhorst
|
||||||
|
* Copyright 2011 Owen Rudge for CodeWeavers
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -30,9 +31,13 @@
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "mmsystem.h"
|
#include "mmsystem.h"
|
||||||
|
#include "wingdi.h"
|
||||||
|
#include "mmreg.h"
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "dsound.h"
|
#include "dsound.h"
|
||||||
|
#include "ks.h"
|
||||||
|
#include "ksmedia.h"
|
||||||
#include "dsdriver.h"
|
#include "dsdriver.h"
|
||||||
#include "dsound_private.h"
|
#include "dsound_private.h"
|
||||||
|
|
||||||
|
@ -177,21 +182,32 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
|
||||||
{
|
{
|
||||||
BOOL needremix = TRUE, needresample = (dsb->freq != dsb->device->pwfx->nSamplesPerSec);
|
BOOL needremix = TRUE, needresample = (dsb->freq != dsb->device->pwfx->nSamplesPerSec);
|
||||||
DWORD bAlign = dsb->pwfx->nBlockAlign, pAlign = dsb->device->pwfx->nBlockAlign;
|
DWORD bAlign = dsb->pwfx->nBlockAlign, pAlign = dsb->device->pwfx->nBlockAlign;
|
||||||
|
WAVEFORMATEXTENSIBLE *pwfxe;
|
||||||
|
BOOL ieee = FALSE;
|
||||||
|
|
||||||
TRACE("(%p)\n",dsb);
|
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 */
|
/* calculate the 10ms write lead */
|
||||||
dsb->writelead = (dsb->freq / 100) * dsb->pwfx->nBlockAlign;
|
dsb->writelead = (dsb->freq / 100) * dsb->pwfx->nBlockAlign;
|
||||||
|
|
||||||
if ((dsb->pwfx->wBitsPerSample == dsb->device->pwfx->wBitsPerSample) &&
|
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;
|
needremix = FALSE;
|
||||||
HeapFree(GetProcessHeap(), 0, dsb->tmp_buffer);
|
HeapFree(GetProcessHeap(), 0, dsb->tmp_buffer);
|
||||||
dsb->tmp_buffer = NULL;
|
dsb->tmp_buffer = NULL;
|
||||||
dsb->max_buffer_len = dsb->freqAcc = dsb->freqAccNext = 0;
|
dsb->max_buffer_len = dsb->freqAcc = dsb->freqAccNext = 0;
|
||||||
dsb->freqneeded = needresample;
|
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;
|
dsb->resampleinmixer = FALSE;
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ typedef struct _WAVEFORMATEX {
|
||||||
/* WAVE form wFormatTag IDs */
|
/* WAVE form wFormatTag IDs */
|
||||||
#define WAVE_FORMAT_UNKNOWN 0x0000 /* Microsoft Corporation */
|
#define WAVE_FORMAT_UNKNOWN 0x0000 /* Microsoft Corporation */
|
||||||
#define WAVE_FORMAT_ADPCM 0x0002 /* 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_IBM_CVSD 0x0005 /* IBM Corporation */
|
||||||
#define WAVE_FORMAT_ALAW 0x0006 /* Microsoft Corporation */
|
#define WAVE_FORMAT_ALAW 0x0006 /* Microsoft Corporation */
|
||||||
#define WAVE_FORMAT_MULAW 0x0007 /* Microsoft Corporation */
|
#define WAVE_FORMAT_MULAW 0x0007 /* Microsoft Corporation */
|
||||||
|
|
Loading…
Reference in a new issue