/* * 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;