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