Mark Harmstone : dsound: Parse speaker config.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Jan 7 17:15:37 CST 2015
Module: wine
Branch: master
Commit: c4e3079766aed0b68f356ac571d449cc08d1321e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c4e3079766aed0b68f356ac571d449cc08d1321e
Author: Mark Harmstone <hellas at burntcomma.com>
Date: Tue Jan 6 19:26:47 2015 +0000
dsound: Parse speaker config.
---
dlls/dsound/dsound.c | 28 ++++++++++++++++++++++++++++
dlls/dsound/dsound_private.h | 5 +++++
dlls/dsound/primary.c | 27 ++++++++++++++++++++-------
3 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c
index 66c9d91..c5c6e8a 100644
--- a/dlls/dsound/dsound.c
+++ b/dlls/dsound/dsound.c
@@ -23,6 +23,7 @@
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
+#include <math.h>
#define COBJMACROS
#define NONAMELESSSTRUCT
@@ -585,6 +586,31 @@ HRESULT WINAPI DirectSoundCreate8(
return hr;
}
+void DSOUND_ParseSpeakerConfig(DirectSoundDevice *device)
+{
+ switch (DSSPEAKER_CONFIG(device->speaker_config)) {
+ case DSSPEAKER_MONO:
+ device->speaker_angles[0] = M_PI/180.0f * 0.0f;
+ device->speaker_num[0] = 0;
+ device->num_speakers = 1;
+ device->lfe_channel = -1;
+ break;
+
+ case DSSPEAKER_STEREO:
+ case DSSPEAKER_HEADPHONE:
+ device->speaker_angles[0] = M_PI/180.0f * -90.0f;
+ device->speaker_angles[1] = M_PI/180.0f * 90.0f;
+ device->speaker_num[0] = 0; /* Left */
+ device->speaker_num[1] = 1; /* Right */
+ device->num_speakers = 2;
+ device->lfe_channel = -1;
+ break;
+
+ default:
+ WARN("unknown speaker_config %u\n", device->speaker_config);
+ }
+}
+
/*******************************************************************************
* DirectSoundDevice
*/
@@ -605,6 +631,8 @@ static HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice)
device->state = STATE_STOPPED;
device->speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_WIDE);
+ DSOUND_ParseSpeakerConfig(device);
+
/* 3D listener initial parameters */
device->ds3dl.dwSize = sizeof(DS3DLISTENER);
device->ds3dl.vPosition.x = 0.0;
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
index 66af81a..5320d30 100644
--- a/dlls/dsound/dsound_private.h
+++ b/dlls/dsound/dsound_private.h
@@ -78,6 +78,10 @@ struct DirectSoundDevice
CRITICAL_SECTION mixlock;
IDirectSoundBufferImpl *primary;
DWORD speaker_config;
+ float speaker_angles[DS_MAX_CHANNELS];
+ int speaker_num[DS_MAX_CHANNELS];
+ int num_speakers;
+ int lfe_channel;
float *mix_buffer, *tmp_buffer;
DWORD tmp_buffer_len, mix_buffer_len;
@@ -199,6 +203,7 @@ HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, void **ppv) DECLSPEC_HIDDE
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;
+void DSOUND_ParseSpeakerConfig(DirectSoundDevice *device) DECLSPEC_HIDDEN;
/* primary.c */
diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c
index ea4559c..86ebba8 100644
--- a/dlls/dsound/primary.c
+++ b/dlls/dsound/primary.c
@@ -58,6 +58,21 @@ static DWORD DSOUND_fraglen(DirectSoundDevice *device)
return ret;
}
+static DWORD speaker_config_to_channel_mask(DWORD speaker_config)
+{
+ switch (DSSPEAKER_CONFIG(speaker_config)) {
+ case DSSPEAKER_MONO:
+ return SPEAKER_FRONT_LEFT;
+
+ case DSSPEAKER_STEREO:
+ case DSSPEAKER_HEADPHONE:
+ return SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
+ }
+
+ WARN("unknown speaker_config %u\n", speaker_config);
+ return SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
+}
+
static HRESULT DSOUND_WaveFormat(DirectSoundDevice *device, IAudioClient *client,
BOOL forcewave, WAVEFORMATEX **wfx)
{
@@ -72,15 +87,11 @@ static HRESULT DSOUND_WaveFormat(DirectSoundDevice *device, IAudioClient *client
if (FAILED(hr))
return hr;
- if (mixwfe->Format.nChannels > 2) {
- static int once;
- if (!once++)
- FIXME("Limiting channels to 2 due to lack of multichannel support\n");
-
- mixwfe->Format.nChannels = 2;
+ if (mixwfe->Format.nChannels > device->num_speakers) {
+ mixwfe->Format.nChannels = device->num_speakers;
mixwfe->Format.nBlockAlign = mixwfe->Format.nChannels * mixwfe->Format.wBitsPerSample / 8;
mixwfe->Format.nAvgBytesPerSec = mixwfe->Format.nSamplesPerSec * mixwfe->Format.nBlockAlign;
- mixwfe->dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
+ mixwfe->dwChannelMask = speaker_config_to_channel_mask(device->speaker_config);
}
if (!IsEqualGUID(&mixwfe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) {
@@ -226,6 +237,8 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
device->speaker_config = DSOUND_FindSpeakerConfig(device->mmdevice);
+ DSOUND_ParseSpeakerConfig(device);
+
hres = DSOUND_WaveFormat(device, device->client, forcewave, &wfx);
if (FAILED(hres)) {
IAudioClient_Release(device->client);
More information about the wine-cvs
mailing list