~ubuntu-branches/ubuntu/quantal/openal-soft/quantal

« back to all changes in this revision

Viewing changes to Alc/dsound.c

  • Committer: Package Import Robot
  • Author(s): Michael Terry
  • Date: 2012-05-22 10:14:53 UTC
  • mfrom: (7.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20120522101453-knsv1m1m8vl5ccfp
Tags: 1:1.14-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  - Add a symbols file for libopenal1
* debian/libopenal1.symbols:
  - Update for 1.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * OpenAL cross platform audio library
3
 
 * Copyright (C) 1999-2007 by authors.
4
 
 * This library is free software; you can redistribute it and/or
5
 
 *  modify it under the terms of the GNU Library General Public
6
 
 *  License as published by the Free Software Foundation; either
7
 
 *  version 2 of the License, or (at your option) any later version.
8
 
 *
9
 
 * This library is distributed in the hope that it will be useful,
10
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
 *  Library General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU Library General Public
15
 
 *  License along with this library; if not, write to the
16
 
 *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
 
 *  Boston, MA  02111-1307, USA.
18
 
 * Or go to http://www.gnu.org/copyleft/lgpl.html
19
 
 */
20
 
 
21
 
#include "config.h"
22
 
 
23
 
#define _WIN32_WINNT 0x0500
24
 
#define INITGUID
25
 
#include <stdlib.h>
26
 
#include <stdio.h>
27
 
#include <memory.h>
28
 
 
29
 
#include <dsound.h>
30
 
#include <cguid.h>
31
 
#include <mmreg.h>
32
 
#ifndef _WAVEFORMATEXTENSIBLE_
33
 
#include <ks.h>
34
 
#include <ksmedia.h>
35
 
#endif
36
 
 
37
 
#include "alMain.h"
38
 
#include "AL/al.h"
39
 
#include "AL/alc.h"
40
 
 
41
 
#ifndef DSSPEAKER_5POINT1
42
 
#define DSSPEAKER_5POINT1       6
43
 
#endif
44
 
#ifndef DSSPEAKER_7POINT1
45
 
#define DSSPEAKER_7POINT1       7
46
 
#endif
47
 
 
48
 
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
49
 
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
50
 
 
51
 
static void *ds_handle;
52
 
static HRESULT (WINAPI *pDirectSoundCreate)(LPCGUID pcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter);
53
 
static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext);
54
 
 
55
 
 
56
 
typedef struct {
57
 
    // DirectSound Playback Device
58
 
    LPDIRECTSOUND          lpDS;
59
 
    LPDIRECTSOUNDBUFFER    DSpbuffer;
60
 
    LPDIRECTSOUNDBUFFER    DSsbuffer;
61
 
 
62
 
    volatile int killNow;
63
 
    ALvoid *thread;
64
 
} DSoundData;
65
 
 
66
 
 
67
 
typedef struct {
68
 
    ALCchar *name;
69
 
    GUID guid;
70
 
} DevMap;
71
 
 
72
 
static const ALCchar dsDevice[] = "DirectSound Default";
73
 
static DevMap *DeviceList;
74
 
static ALuint NumDevices;
75
 
 
76
 
 
77
 
void *DSoundLoad(void)
78
 
{
79
 
    if(!ds_handle)
80
 
    {
81
 
#ifdef _WIN32
82
 
        ds_handle = LoadLibraryA("dsound.dll");
83
 
        if(ds_handle == NULL)
84
 
        {
85
 
            AL_PRINT("Failed to load dsound.dll\n");
86
 
            return NULL;
87
 
        }
88
 
 
89
 
#define LOAD_FUNC(f) do { \
90
 
    p##f = (void*)GetProcAddress((HMODULE)ds_handle, #f); \
91
 
    if(p##f == NULL) \
92
 
    { \
93
 
        FreeLibrary(ds_handle); \
94
 
        ds_handle = NULL; \
95
 
        AL_PRINT("Could not load %s from dsound.dll\n", #f); \
96
 
        return NULL; \
97
 
    } \
98
 
} while(0)
99
 
#else
100
 
        ds_handle = (void*)0xDEADBEEF;
101
 
#define LOAD_FUNC(f) p##f = f
102
 
#endif
103
 
 
104
 
LOAD_FUNC(DirectSoundCreate);
105
 
LOAD_FUNC(DirectSoundEnumerateA);
106
 
#undef LOAD_FUNC
107
 
    }
108
 
    return ds_handle;
109
 
}
110
 
 
111
 
 
112
 
static BOOL CALLBACK DSoundEnumDevices(LPGUID guid, LPCSTR desc, LPCSTR drvname, LPVOID data)
113
 
{
114
 
    char str[1024];
115
 
    void *temp;
116
 
    int count;
117
 
    ALuint i;
118
 
 
119
 
    (void)data;
120
 
    (void)drvname;
121
 
 
122
 
    if(NumDevices == 0)
123
 
    {
124
 
        temp = realloc(DeviceList, sizeof(DevMap) * (NumDevices+1));
125
 
        if(temp)
126
 
        {
127
 
            DeviceList = temp;
128
 
            DeviceList[NumDevices].name = strdup(dsDevice);
129
 
            DeviceList[NumDevices].guid = GUID_NULL;
130
 
            NumDevices++;
131
 
        }
132
 
    }
133
 
 
134
 
    if(!guid)
135
 
        return TRUE;
136
 
 
137
 
    count = 0;
138
 
    do {
139
 
        if(count == 0)
140
 
            snprintf(str, sizeof(str), "%s via DirectSound", desc);
141
 
        else
142
 
            snprintf(str, sizeof(str), "%s #%d via DirectSound", desc, count+1);
143
 
        count++;
144
 
 
145
 
        for(i = 0;i < NumDevices;i++)
146
 
        {
147
 
            if(strcmp(str, DeviceList[i].name) == 0)
148
 
                break;
149
 
        }
150
 
    } while(i != NumDevices);
151
 
 
152
 
    temp = realloc(DeviceList, sizeof(DevMap) * (NumDevices+1));
153
 
    if(temp)
154
 
    {
155
 
        DeviceList = temp;
156
 
        DeviceList[NumDevices].name = strdup(str);
157
 
        DeviceList[NumDevices].guid = *guid;
158
 
        NumDevices++;
159
 
    }
160
 
 
161
 
    return TRUE;
162
 
}
163
 
 
164
 
 
165
 
static ALuint DSoundProc(ALvoid *ptr)
166
 
{
167
 
    ALCdevice *pDevice = (ALCdevice*)ptr;
168
 
    DSoundData *pData = (DSoundData*)pDevice->ExtraData;
169
 
    DSBCAPS DSBCaps;
170
 
    DWORD LastCursor = 0;
171
 
    DWORD PlayCursor;
172
 
    VOID *WritePtr1, *WritePtr2;
173
 
    DWORD WriteCnt1,  WriteCnt2;
174
 
    BOOL Playing = FALSE;
175
 
    DWORD FrameSize;
176
 
    DWORD FragSize;
177
 
    DWORD avail;
178
 
    HRESULT err;
179
 
 
180
 
    SetRTPriority();
181
 
 
182
 
    memset(&DSBCaps, 0, sizeof(DSBCaps));
183
 
    DSBCaps.dwSize = sizeof(DSBCaps);
184
 
    err = IDirectSoundBuffer_GetCaps(pData->DSsbuffer, &DSBCaps);
185
 
    if(FAILED(err))
186
 
    {
187
 
        AL_PRINT("Failed to get buffer caps: 0x%lx\n", err);
188
 
        aluHandleDisconnect(pDevice);
189
 
        return 1;
190
 
    }
191
 
 
192
 
    FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
193
 
    FragSize = pDevice->UpdateSize * FrameSize;
194
 
 
195
 
    IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &LastCursor, NULL);
196
 
    while(!pData->killNow)
197
 
    {
198
 
        // Get current play and write cursors
199
 
        IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &PlayCursor, NULL);
200
 
        avail = (PlayCursor-LastCursor+DSBCaps.dwBufferBytes) % DSBCaps.dwBufferBytes;
201
 
 
202
 
        if(avail < FragSize)
203
 
        {
204
 
            if(!Playing)
205
 
            {
206
 
                err = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING);
207
 
                if(FAILED(err))
208
 
                {
209
 
                    AL_PRINT("Failed to play buffer: 0x%lx\n", err);
210
 
                    aluHandleDisconnect(pDevice);
211
 
                    return 1;
212
 
                }
213
 
                Playing = TRUE;
214
 
            }
215
 
            Sleep(1);
216
 
            continue;
217
 
        }
218
 
        avail -= avail%FragSize;
219
 
 
220
 
        // Lock output buffer
221
 
        WriteCnt1 = 0;
222
 
        WriteCnt2 = 0;
223
 
        err = IDirectSoundBuffer_Lock(pData->DSsbuffer, LastCursor, avail, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
224
 
 
225
 
        // If the buffer is lost, restore it and lock
226
 
        if(err == DSERR_BUFFERLOST)
227
 
        {
228
 
            err = IDirectSoundBuffer_Restore(pData->DSsbuffer);
229
 
            if(SUCCEEDED(err))
230
 
            {
231
 
                Playing = FALSE;
232
 
                LastCursor = 0;
233
 
                err = IDirectSoundBuffer_Lock(pData->DSsbuffer, 0, DSBCaps.dwBufferBytes, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
234
 
            }
235
 
        }
236
 
 
237
 
        // Successfully locked the output buffer
238
 
        if(SUCCEEDED(err))
239
 
        {
240
 
            // If we have an active context, mix data directly into output buffer otherwise fill with silence
241
 
            aluMixData(pDevice, WritePtr1, WriteCnt1/FrameSize);
242
 
            aluMixData(pDevice, WritePtr2, WriteCnt2/FrameSize);
243
 
 
244
 
            // Unlock output buffer only when successfully locked
245
 
            IDirectSoundBuffer_Unlock(pData->DSsbuffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
246
 
        }
247
 
        else
248
 
        {
249
 
            AL_PRINT("Buffer lock error: %#lx\n", err);
250
 
            aluHandleDisconnect(pDevice);
251
 
            return 1;
252
 
        }
253
 
 
254
 
        // Update old write cursor location
255
 
        LastCursor += WriteCnt1+WriteCnt2;
256
 
        LastCursor %= DSBCaps.dwBufferBytes;
257
 
    }
258
 
 
259
 
    return 0;
260
 
}
261
 
 
262
 
static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
263
 
{
264
 
    DSoundData *pData = NULL;
265
 
    LPGUID guid = NULL;
266
 
    HRESULT hr;
267
 
 
268
 
    if(!DSoundLoad())
269
 
        return ALC_FALSE;
270
 
 
271
 
    if(!deviceName)
272
 
        deviceName = dsDevice;
273
 
    else if(strcmp(deviceName, dsDevice) != 0)
274
 
    {
275
 
        ALuint i;
276
 
 
277
 
        if(!DeviceList)
278
 
        {
279
 
            hr = pDirectSoundEnumerateA(DSoundEnumDevices, NULL);
280
 
            if(FAILED(hr))
281
 
                AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr);
282
 
        }
283
 
 
284
 
        for(i = 0;i < NumDevices;i++)
285
 
        {
286
 
            if(strcmp(deviceName, DeviceList[i].name) == 0)
287
 
            {
288
 
                if(i > 0)
289
 
                    guid = &DeviceList[i].guid;
290
 
                break;
291
 
            }
292
 
        }
293
 
        if(i == NumDevices)
294
 
            return ALC_FALSE;
295
 
    }
296
 
 
297
 
    //Initialise requested device
298
 
    pData = calloc(1, sizeof(DSoundData));
299
 
    if(!pData)
300
 
    {
301
 
        alcSetError(device, ALC_OUT_OF_MEMORY);
302
 
        return ALC_FALSE;
303
 
    }
304
 
 
305
 
    //DirectSound Init code
306
 
    hr = pDirectSoundCreate(guid, &pData->lpDS, NULL);
307
 
    if(SUCCEEDED(hr))
308
 
        hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY);
309
 
    if(FAILED(hr))
310
 
    {
311
 
        if(pData->lpDS)
312
 
            IDirectSound_Release(pData->lpDS);
313
 
        free(pData);
314
 
        AL_PRINT("Device init failed: 0x%08lx\n", hr);
315
 
        return ALC_FALSE;
316
 
    }
317
 
 
318
 
    device->szDeviceName = strdup(deviceName);
319
 
    device->ExtraData = pData;
320
 
    return ALC_TRUE;
321
 
}
322
 
 
323
 
static void DSoundClosePlayback(ALCdevice *device)
324
 
{
325
 
    DSoundData *pData = device->ExtraData;
326
 
 
327
 
    IDirectSound_Release(pData->lpDS);
328
 
    free(pData);
329
 
    device->ExtraData = NULL;
330
 
}
331
 
 
332
 
static ALCboolean DSoundResetPlayback(ALCdevice *device)
333
 
{
334
 
    DSoundData *pData = (DSoundData*)device->ExtraData;
335
 
    DSBUFFERDESC DSBDescription;
336
 
    WAVEFORMATEXTENSIBLE OutputType;
337
 
    DWORD speakers;
338
 
    HRESULT hr;
339
 
 
340
 
    memset(&OutputType, 0, sizeof(OutputType));
341
 
 
342
 
    switch(device->FmtType)
343
 
    {
344
 
        case DevFmtByte:
345
 
            device->FmtType = DevFmtUByte;
346
 
            break;
347
 
        case DevFmtUShort:
348
 
            device->FmtType = DevFmtShort;
349
 
            break;
350
 
        case DevFmtUByte:
351
 
        case DevFmtShort:
352
 
        case DevFmtFloat:
353
 
            break;
354
 
    }
355
 
 
356
 
    hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
357
 
    if(SUCCEEDED(hr) && ConfigValueExists(NULL, "format"))
358
 
    {
359
 
        switch(device->FmtChans)
360
 
        {
361
 
            case DevFmtMono:
362
 
                speakers = DSSPEAKER_COMBINED(DSSPEAKER_MONO, 0);
363
 
                break;
364
 
            case DevFmtStereo:
365
 
                speakers = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 0);
366
 
                break;
367
 
            case DevFmtQuad:
368
 
                speakers = DSSPEAKER_COMBINED(DSSPEAKER_QUAD, 0);
369
 
                break;
370
 
            case DevFmtX51:
371
 
                speakers = DSSPEAKER_COMBINED(DSSPEAKER_5POINT1, 0);
372
 
                break;
373
 
            case DevFmtX61:
374
 
                /* ??? */;
375
 
                break;
376
 
            case DevFmtX71:
377
 
                speakers = DSSPEAKER_COMBINED(DSSPEAKER_7POINT1, 0);
378
 
                break;
379
 
        }
380
 
    }
381
 
    if(SUCCEEDED(hr))
382
 
    {
383
 
        speakers = DSSPEAKER_CONFIG(speakers);
384
 
        if(speakers == DSSPEAKER_MONO)
385
 
        {
386
 
            device->FmtChans = DevFmtMono;
387
 
            OutputType.dwChannelMask = SPEAKER_FRONT_CENTER;
388
 
        }
389
 
        else if(speakers == DSSPEAKER_STEREO || speakers == DSSPEAKER_HEADPHONE)
390
 
        {
391
 
            device->FmtChans = DevFmtStereo;
392
 
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
393
 
                                       SPEAKER_FRONT_RIGHT;
394
 
        }
395
 
        else if(speakers == DSSPEAKER_QUAD)
396
 
        {
397
 
            device->FmtChans = DevFmtQuad;
398
 
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
399
 
                                       SPEAKER_FRONT_RIGHT |
400
 
                                       SPEAKER_BACK_LEFT |
401
 
                                       SPEAKER_BACK_RIGHT;
402
 
        }
403
 
        else if(speakers == DSSPEAKER_5POINT1)
404
 
        {
405
 
            device->FmtChans = DevFmtX51;
406
 
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
407
 
                                       SPEAKER_FRONT_RIGHT |
408
 
                                       SPEAKER_FRONT_CENTER |
409
 
                                       SPEAKER_LOW_FREQUENCY |
410
 
                                       SPEAKER_BACK_LEFT |
411
 
                                       SPEAKER_BACK_RIGHT;
412
 
        }
413
 
        else if(speakers == DSSPEAKER_7POINT1)
414
 
        {
415
 
            device->FmtChans = DevFmtX71;
416
 
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
417
 
                                       SPEAKER_FRONT_RIGHT |
418
 
                                       SPEAKER_FRONT_CENTER |
419
 
                                       SPEAKER_LOW_FREQUENCY |
420
 
                                       SPEAKER_BACK_LEFT |
421
 
                                       SPEAKER_BACK_RIGHT |
422
 
                                       SPEAKER_SIDE_LEFT |
423
 
                                       SPEAKER_SIDE_RIGHT;
424
 
        }
425
 
 
426
 
        OutputType.Format.wFormatTag = WAVE_FORMAT_PCM;
427
 
        OutputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans);
428
 
        OutputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 8;
429
 
        OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8;
430
 
        OutputType.Format.nSamplesPerSec = device->Frequency;
431
 
        OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec*OutputType.Format.nBlockAlign;
432
 
        OutputType.Format.cbSize = 0;
433
 
    }
434
 
 
435
 
    if(OutputType.Format.nChannels > 2 || OutputType.Format.wBitsPerSample > 16)
436
 
    {
437
 
        OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
438
 
        OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
439
 
        OutputType.Format.cbSize = 22;
440
 
        if(OutputType.Format.wBitsPerSample == 32)
441
 
            OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
442
 
        else
443
 
            OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
444
 
    }
445
 
    else
446
 
    {
447
 
        if(SUCCEEDED(hr))
448
 
        {
449
 
            memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
450
 
            DSBDescription.dwSize=sizeof(DSBUFFERDESC);
451
 
            DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
452
 
            hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL);
453
 
        }
454
 
        if(SUCCEEDED(hr))
455
 
            hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType.Format);
456
 
    }
457
 
 
458
 
    if(SUCCEEDED(hr))
459
 
    {
460
 
        memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
461
 
        DSBDescription.dwSize=sizeof(DSBUFFERDESC);
462
 
        DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2;
463
 
        DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates *
464
 
                                     OutputType.Format.nBlockAlign;
465
 
        DSBDescription.lpwfxFormat=&OutputType.Format;
466
 
        hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL);
467
 
    }
468
 
 
469
 
    if(SUCCEEDED(hr))
470
 
    {
471
 
        SetDefaultWFXChannelOrder(device);
472
 
        pData->thread = StartThread(DSoundProc, device);
473
 
        if(!pData->thread)
474
 
            hr = E_FAIL;
475
 
    }
476
 
 
477
 
    if(FAILED(hr))
478
 
    {
479
 
        if (pData->DSsbuffer)
480
 
            IDirectSoundBuffer_Release(pData->DSsbuffer);
481
 
        pData->DSsbuffer = NULL;
482
 
        if (pData->DSpbuffer)
483
 
            IDirectSoundBuffer_Release(pData->DSpbuffer);
484
 
        pData->DSpbuffer = NULL;
485
 
        return ALC_FALSE;
486
 
    }
487
 
 
488
 
    return ALC_TRUE;
489
 
}
490
 
 
491
 
static void DSoundStopPlayback(ALCdevice *device)
492
 
{
493
 
    DSoundData *pData = device->ExtraData;
494
 
 
495
 
    if(!pData->thread)
496
 
        return;
497
 
 
498
 
    pData->killNow = 1;
499
 
    StopThread(pData->thread);
500
 
    pData->thread = NULL;
501
 
 
502
 
    pData->killNow = 0;
503
 
 
504
 
    IDirectSoundBuffer_Release(pData->DSsbuffer);
505
 
    pData->DSsbuffer = NULL;
506
 
    if (pData->DSpbuffer)
507
 
        IDirectSoundBuffer_Release(pData->DSpbuffer);
508
 
    pData->DSpbuffer = NULL;
509
 
}
510
 
 
511
 
 
512
 
static ALCboolean DSoundOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
513
 
{
514
 
    (void)pDevice;
515
 
    (void)deviceName;
516
 
    return ALC_FALSE;
517
 
}
518
 
 
519
 
static void DSoundCloseCapture(ALCdevice *pDevice)
520
 
{
521
 
    (void)pDevice;
522
 
}
523
 
 
524
 
static void DSoundStartCapture(ALCdevice *pDevice)
525
 
{
526
 
    (void)pDevice;
527
 
}
528
 
 
529
 
static void DSoundStopCapture(ALCdevice *pDevice)
530
 
{
531
 
    (void)pDevice;
532
 
}
533
 
 
534
 
static void DSoundCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
535
 
{
536
 
    (void)pDevice;
537
 
    (void)pBuffer;
538
 
    (void)lSamples;
539
 
}
540
 
 
541
 
static ALCuint DSoundAvailableSamples(ALCdevice *pDevice)
542
 
{
543
 
    (void)pDevice;
544
 
    return 0;
545
 
}
546
 
 
547
 
 
548
 
BackendFuncs DSoundFuncs = {
549
 
    DSoundOpenPlayback,
550
 
    DSoundClosePlayback,
551
 
    DSoundResetPlayback,
552
 
    DSoundStopPlayback,
553
 
    DSoundOpenCapture,
554
 
    DSoundCloseCapture,
555
 
    DSoundStartCapture,
556
 
    DSoundStopCapture,
557
 
    DSoundCaptureSamples,
558
 
    DSoundAvailableSamples
559
 
};
560
 
 
561
 
 
562
 
void alcDSoundInit(BackendFuncs *FuncList)
563
 
{
564
 
    *FuncList = DSoundFuncs;
565
 
}
566
 
 
567
 
void alcDSoundDeinit(void)
568
 
{
569
 
    ALuint i;
570
 
 
571
 
    for(i = 0;i < NumDevices;++i)
572
 
        free(DeviceList[i].name);
573
 
    free(DeviceList);
574
 
    DeviceList = NULL;
575
 
    NumDevices = 0;
576
 
 
577
 
    if(ds_handle)
578
 
    {
579
 
#ifdef _WIN32
580
 
        FreeLibrary(ds_handle);
581
 
#endif
582
 
        ds_handle = NULL;
583
 
    }
584
 
}
585
 
 
586
 
void alcDSoundProbe(int type)
587
 
{
588
 
    if(!DSoundLoad()) return;
589
 
 
590
 
    if(type == DEVICE_PROBE)
591
 
        AppendDeviceList(dsDevice);
592
 
    else if(type == ALL_DEVICE_PROBE)
593
 
    {
594
 
        HRESULT hr;
595
 
        ALuint i;
596
 
 
597
 
        for(i = 0;i < NumDevices;++i)
598
 
            free(DeviceList[i].name);
599
 
        free(DeviceList);
600
 
        DeviceList = NULL;
601
 
        NumDevices = 0;
602
 
 
603
 
        hr = pDirectSoundEnumerateA(DSoundEnumDevices, NULL);
604
 
        if(FAILED(hr))
605
 
            AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr);
606
 
        else
607
 
        {
608
 
            for(i = 0;i < NumDevices;i++)
609
 
                AppendAllDeviceList(DeviceList[i].name);
610
 
        }
611
 
    }
612
 
}