2015-10-02 15:49:29 +02:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2015 Andrew Eikum for CodeWeavers
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "winuser.h"
|
|
|
|
#include "wine/list.h"
|
|
|
|
|
|
|
|
#include "mmsystem.h"
|
|
|
|
#include "xaudio2.h"
|
|
|
|
#include "xaudio2fx.h"
|
|
|
|
#include "xapo.h"
|
|
|
|
#include "devpkey.h"
|
|
|
|
#include "mmdeviceapi.h"
|
|
|
|
#include "audioclient.h"
|
|
|
|
|
|
|
|
#include <AL/al.h>
|
|
|
|
#include <AL/alc.h>
|
|
|
|
#include <AL/alext.h>
|
|
|
|
|
|
|
|
typedef struct _XA2Buffer {
|
|
|
|
XAUDIO2_BUFFER xa2buffer;
|
|
|
|
DWORD offs_bytes;
|
|
|
|
UINT32 latest_al_buf, looped, loop_end_bytes, play_end_bytes, cur_end_bytes;
|
|
|
|
} XA2Buffer;
|
|
|
|
|
|
|
|
typedef struct _IXAudio2Impl IXAudio2Impl;
|
|
|
|
|
|
|
|
typedef struct _XA2SourceImpl {
|
2016-01-18 20:15:57 +01:00
|
|
|
IXAudio2SourceVoice IXAudio2SourceVoice_iface;
|
|
|
|
|
|
|
|
#if XAUDIO2_VER == 0
|
2015-10-07 18:19:35 +02:00
|
|
|
IXAudio20SourceVoice IXAudio20SourceVoice_iface;
|
2016-01-18 20:15:57 +01:00
|
|
|
#elif XAUDIO2_VER <= 3
|
2015-10-02 15:49:36 +02:00
|
|
|
IXAudio23SourceVoice IXAudio23SourceVoice_iface;
|
2016-01-18 20:15:57 +01:00
|
|
|
#elif XAUDIO2_VER <= 7
|
2015-10-02 15:49:29 +02:00
|
|
|
IXAudio27SourceVoice IXAudio27SourceVoice_iface;
|
2016-01-18 20:15:57 +01:00
|
|
|
#endif
|
2015-10-02 15:49:29 +02:00
|
|
|
|
|
|
|
IXAudio2Impl *xa2;
|
|
|
|
|
|
|
|
BOOL in_use;
|
|
|
|
|
|
|
|
CRITICAL_SECTION lock;
|
|
|
|
|
|
|
|
WAVEFORMATEX *fmt;
|
|
|
|
ALenum al_fmt;
|
|
|
|
UINT32 submit_blocksize;
|
|
|
|
|
|
|
|
IXAudio2VoiceCallback *cb;
|
|
|
|
|
|
|
|
DWORD nsends;
|
|
|
|
XAUDIO2_SEND_DESCRIPTOR *sends;
|
|
|
|
|
|
|
|
BOOL running;
|
|
|
|
|
|
|
|
UINT64 played_frames;
|
|
|
|
|
|
|
|
XA2Buffer buffers[XAUDIO2_MAX_QUEUED_BUFFERS];
|
|
|
|
UINT32 first_buf, cur_buf, nbufs, in_al_bytes;
|
|
|
|
|
|
|
|
UINT32 scratch_bytes, convert_bytes;
|
|
|
|
BYTE *scratch_buf, *convert_buf;
|
|
|
|
|
|
|
|
ALuint al_src;
|
|
|
|
/* most cases will only need about 4 AL buffers, but some corner cases
|
|
|
|
* could require up to MAX_QUEUED_BUFFERS */
|
|
|
|
ALuint al_bufs[XAUDIO2_MAX_QUEUED_BUFFERS];
|
|
|
|
DWORD first_al_buf, al_bufs_used;
|
|
|
|
|
|
|
|
struct list entry;
|
|
|
|
} XA2SourceImpl;
|
|
|
|
|
|
|
|
typedef struct _XA2SubmixImpl {
|
2016-01-18 20:15:57 +01:00
|
|
|
IXAudio2SubmixVoice IXAudio2SubmixVoice_iface;
|
|
|
|
|
|
|
|
#if XAUDIO2_VER == 0
|
2015-10-07 18:19:35 +02:00
|
|
|
IXAudio20SubmixVoice IXAudio20SubmixVoice_iface;
|
2016-01-18 20:15:57 +01:00
|
|
|
#elif XAUDIO2_VER <= 3
|
2015-10-02 15:49:36 +02:00
|
|
|
IXAudio23SubmixVoice IXAudio23SubmixVoice_iface;
|
2016-06-01 22:09:05 +02:00
|
|
|
#elif XAUDIO2_VER <= 7
|
|
|
|
IXAudio27SubmixVoice IXAudio27SubmixVoice_iface;
|
2016-01-18 20:15:57 +01:00
|
|
|
#endif
|
2015-10-02 15:49:29 +02:00
|
|
|
|
|
|
|
BOOL in_use;
|
|
|
|
|
2016-06-01 22:09:05 +02:00
|
|
|
XAUDIO2_VOICE_DETAILS details;
|
|
|
|
|
2015-10-02 15:49:29 +02:00
|
|
|
CRITICAL_SECTION lock;
|
|
|
|
|
|
|
|
struct list entry;
|
|
|
|
} XA2SubmixImpl;
|
|
|
|
|
|
|
|
struct _IXAudio2Impl {
|
2016-01-18 20:15:57 +01:00
|
|
|
IXAudio2 IXAudio2_iface;
|
|
|
|
IXAudio2MasteringVoice IXAudio2MasteringVoice_iface;
|
|
|
|
|
|
|
|
#if XAUDIO2_VER == 0
|
2015-10-07 18:19:35 +02:00
|
|
|
IXAudio20 IXAudio20_iface;
|
2016-01-18 20:15:57 +01:00
|
|
|
#elif XAUDIO2_VER <= 2
|
2015-10-05 18:33:03 +02:00
|
|
|
IXAudio22 IXAudio22_iface;
|
2016-01-18 20:15:57 +01:00
|
|
|
#elif XAUDIO2_VER <= 7
|
2015-10-02 15:49:29 +02:00
|
|
|
IXAudio27 IXAudio27_iface;
|
2016-01-18 20:15:57 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if XAUDIO2_VER == 0
|
2015-10-07 18:19:35 +02:00
|
|
|
IXAudio20MasteringVoice IXAudio20MasteringVoice_iface;
|
2016-01-18 20:15:57 +01:00
|
|
|
#elif XAUDIO2_VER <= 3
|
2015-10-02 15:49:36 +02:00
|
|
|
IXAudio23MasteringVoice IXAudio23MasteringVoice_iface;
|
2016-06-01 22:09:05 +02:00
|
|
|
#elif XAUDIO2_VER <= 7
|
|
|
|
IXAudio27MasteringVoice IXAudio27MasteringVoice_iface;
|
2016-01-18 20:15:57 +01:00
|
|
|
#endif
|
2015-10-02 15:49:29 +02:00
|
|
|
|
|
|
|
LONG ref;
|
|
|
|
|
|
|
|
CRITICAL_SECTION lock;
|
|
|
|
|
|
|
|
HANDLE engine, mmevt;
|
|
|
|
BOOL stop_engine;
|
|
|
|
|
|
|
|
struct list source_voices;
|
|
|
|
struct list submix_voices;
|
|
|
|
|
|
|
|
IMMDeviceEnumerator *devenum;
|
|
|
|
|
|
|
|
WCHAR **devids;
|
|
|
|
UINT32 ndevs;
|
|
|
|
|
2015-10-07 18:19:35 +02:00
|
|
|
UINT32 last_query_glitches;
|
|
|
|
|
2015-10-02 15:49:29 +02:00
|
|
|
IAudioClient *aclient;
|
|
|
|
IAudioRenderClient *render;
|
|
|
|
|
|
|
|
UINT32 period_frames;
|
|
|
|
|
|
|
|
WAVEFORMATEXTENSIBLE fmt;
|
|
|
|
|
|
|
|
ALCdevice *al_device;
|
|
|
|
ALCcontext *al_ctx;
|
|
|
|
|
|
|
|
UINT32 ncbs;
|
|
|
|
IXAudio2EngineCallback **cbs;
|
|
|
|
|
|
|
|
BOOL running;
|
|
|
|
};
|
|
|
|
|
2016-01-18 20:15:57 +01:00
|
|
|
#if XAUDIO2_VER == 0
|
|
|
|
extern const IXAudio20SourceVoiceVtbl XAudio20SourceVoice_Vtbl DECLSPEC_HIDDEN;
|
|
|
|
extern const IXAudio20SubmixVoiceVtbl XAudio20SubmixVoice_Vtbl DECLSPEC_HIDDEN;
|
|
|
|
extern const IXAudio20MasteringVoiceVtbl XAudio20MasteringVoice_Vtbl DECLSPEC_HIDDEN;
|
|
|
|
#elif XAUDIO2_VER <= 3
|
2015-10-02 15:49:36 +02:00
|
|
|
extern const IXAudio23SourceVoiceVtbl XAudio23SourceVoice_Vtbl DECLSPEC_HIDDEN;
|
|
|
|
extern const IXAudio23SubmixVoiceVtbl XAudio23SubmixVoice_Vtbl DECLSPEC_HIDDEN;
|
|
|
|
extern const IXAudio23MasteringVoiceVtbl XAudio23MasteringVoice_Vtbl DECLSPEC_HIDDEN;
|
2016-01-18 20:15:57 +01:00
|
|
|
#elif XAUDIO2_VER <= 7
|
|
|
|
extern const IXAudio27SourceVoiceVtbl XAudio27SourceVoice_Vtbl DECLSPEC_HIDDEN;
|
2016-06-01 22:09:05 +02:00
|
|
|
extern const IXAudio27SubmixVoiceVtbl XAudio27SubmixVoice_Vtbl DECLSPEC_HIDDEN;
|
|
|
|
extern const IXAudio27MasteringVoiceVtbl XAudio27MasteringVoice_Vtbl DECLSPEC_HIDDEN;
|
2016-01-18 20:15:57 +01:00
|
|
|
#endif
|
2015-10-05 18:33:03 +02:00
|
|
|
|
2016-01-18 20:15:57 +01:00
|
|
|
#if XAUDIO2_VER == 0
|
2015-10-07 18:19:35 +02:00
|
|
|
extern const IXAudio20Vtbl XAudio20_Vtbl DECLSPEC_HIDDEN;
|
2016-01-18 20:15:57 +01:00
|
|
|
#elif XAUDIO2_VER <= 2
|
|
|
|
extern const IXAudio22Vtbl XAudio22_Vtbl DECLSPEC_HIDDEN;
|
|
|
|
#elif XAUDIO2_VER <= 7
|
|
|
|
extern const IXAudio27Vtbl XAudio27_Vtbl DECLSPEC_HIDDEN;
|
|
|
|
#endif
|
2015-10-27 20:33:56 +01:00
|
|
|
|
2016-01-15 20:48:37 +01:00
|
|
|
extern IClassFactory *make_xapo_factory(REFCLSID clsid) DECLSPEC_HIDDEN;
|
2016-01-18 20:15:54 +01:00
|
|
|
extern HRESULT xaudio2_initialize(IXAudio2Impl *This, UINT32 flags, XAUDIO2_PROCESSOR proc) DECLSPEC_HIDDEN;
|