blob: f28a0aec477c1eaa3f5b5b559872d3928674b5ec [file] [log] [blame]
/*
* 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 {
IXAudio2SourceVoice IXAudio2SourceVoice_iface;
#if XAUDIO2_VER == 0
IXAudio20SourceVoice IXAudio20SourceVoice_iface;
#elif XAUDIO2_VER <= 3
IXAudio23SourceVoice IXAudio23SourceVoice_iface;
#elif XAUDIO2_VER <= 7
IXAudio27SourceVoice IXAudio27SourceVoice_iface;
#endif
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 {
IXAudio2SubmixVoice IXAudio2SubmixVoice_iface;
#if XAUDIO2_VER == 0
IXAudio20SubmixVoice IXAudio20SubmixVoice_iface;
#elif XAUDIO2_VER <= 3
IXAudio23SubmixVoice IXAudio23SubmixVoice_iface;
#elif XAUDIO2_VER <= 7
IXAudio27SubmixVoice IXAudio27SubmixVoice_iface;
#endif
BOOL in_use;
XAUDIO2_VOICE_DETAILS details;
CRITICAL_SECTION lock;
struct list entry;
} XA2SubmixImpl;
struct _IXAudio2Impl {
IXAudio2 IXAudio2_iface;
IXAudio2MasteringVoice IXAudio2MasteringVoice_iface;
#if XAUDIO2_VER == 0
IXAudio20 IXAudio20_iface;
#elif XAUDIO2_VER <= 2
IXAudio22 IXAudio22_iface;
#elif XAUDIO2_VER <= 7
IXAudio27 IXAudio27_iface;
#endif
#if XAUDIO2_VER == 0
IXAudio20MasteringVoice IXAudio20MasteringVoice_iface;
#elif XAUDIO2_VER <= 3
IXAudio23MasteringVoice IXAudio23MasteringVoice_iface;
#elif XAUDIO2_VER <= 7
IXAudio27MasteringVoice IXAudio27MasteringVoice_iface;
#endif
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;
UINT32 last_query_glitches;
IAudioClient *aclient;
IAudioRenderClient *render;
UINT32 period_frames;
WAVEFORMATEXTENSIBLE fmt;
ALCdevice *al_device;
ALCcontext *al_ctx;
UINT32 ncbs;
IXAudio2EngineCallback **cbs;
BOOL running;
};
#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
extern const IXAudio23SourceVoiceVtbl XAudio23SourceVoice_Vtbl DECLSPEC_HIDDEN;
extern const IXAudio23SubmixVoiceVtbl XAudio23SubmixVoice_Vtbl DECLSPEC_HIDDEN;
extern const IXAudio23MasteringVoiceVtbl XAudio23MasteringVoice_Vtbl DECLSPEC_HIDDEN;
#elif XAUDIO2_VER <= 7
extern const IXAudio27SourceVoiceVtbl XAudio27SourceVoice_Vtbl DECLSPEC_HIDDEN;
extern const IXAudio27SubmixVoiceVtbl XAudio27SubmixVoice_Vtbl DECLSPEC_HIDDEN;
extern const IXAudio27MasteringVoiceVtbl XAudio27MasteringVoice_Vtbl DECLSPEC_HIDDEN;
#endif
#if XAUDIO2_VER == 0
extern const IXAudio20Vtbl XAudio20_Vtbl DECLSPEC_HIDDEN;
#elif XAUDIO2_VER <= 2
extern const IXAudio22Vtbl XAudio22_Vtbl DECLSPEC_HIDDEN;
#elif XAUDIO2_VER <= 7
extern const IXAudio27Vtbl XAudio27_Vtbl DECLSPEC_HIDDEN;
#endif
extern IClassFactory *make_xapo_factory(REFCLSID clsid) DECLSPEC_HIDDEN;
extern HRESULT xaudio2_initialize(IXAudio2Impl *This, UINT32 flags, XAUDIO2_PROCESSOR proc) DECLSPEC_HIDDEN;