Skip to content

Commit

Permalink
Call AvSetMmThreadCharacteristicsW on the WASAPI mixing threads
Browse files Browse the repository at this point in the history
  • Loading branch information
kcat committed Aug 21, 2024
1 parent c68b793 commit c0e5532
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,11 @@ if(WIN32)
set(HAVE_WASAPI 1)
set(BACKENDS "${BACKENDS} WASAPI,")
set(ALC_OBJS ${ALC_OBJS} alc/backends/wasapi.cpp alc/backends/wasapi.h)

find_library(AVRT_LIBRARY NAMES avrt DOC "The AVRT library")
if(AVRT_LIBRARY)
set(EXTRA_LIBS ${AVRT_LIBRARY} ${EXTRA_LIBS})
endif()
endif()
endif()

Expand Down
23 changes: 23 additions & 0 deletions alc/backends/wasapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <cstdlib>
#include <memory.h>

#include <avrt.h>
#include <wtypes.h>
#include <mmdeviceapi.h>
#include <audiosessiontypes.h>
Expand Down Expand Up @@ -319,6 +320,13 @@ struct DeviceListLock : public std::unique_lock<DeviceList> {
DeviceList gDeviceList;


#ifdef AVRTAPI
struct AvrtHandleCloser {
void operator()(HANDLE handle) { AvRevertMmThreadCharacteristics(handle); }
};
using AvrtHandlePtr = std::unique_ptr<std::remove_pointer_t<HANDLE>,AvrtHandleCloser>;
#endif

#if defined(ALSOFT_UWP)
enum EDataFlow {
eRender = 0,
Expand Down Expand Up @@ -968,6 +976,7 @@ struct WasapiProxy {
static inline std::deque<Msg> mMsgQueue;
static inline std::mutex mMsgQueueLock;
static inline std::condition_variable mMsgQueueCond;
static inline DWORD sAvIndex{};

static inline std::optional<DeviceHelper> sDeviceHelper;

Expand Down Expand Up @@ -1169,6 +1178,15 @@ FORCE_ALIGN int WasapiPlayback::mixerProc()
const UINT32 buffer_len{mOrigBufferSize};
const void *resbufferptr{};

#ifdef AVRTAPI
/* TODO: "Audio" or "Pro Audio"? The suggestion is to use "Pro Audio" for
* device periods less than 10ms, and "Audio" for greater than or equal to
* 10ms.
*/
auto taskname = (update_size < mFormat.Format.nSamplesPerSec/100) ? L"Pro Audio" : L"Audio";
auto avhandle = AvrtHandlePtr{AvSetMmThreadCharacteristicsW(taskname, &sAvIndex)};
#endif

mBufferFilled = 0;
while(!mKillNow.load(std::memory_order_relaxed))
{
Expand Down Expand Up @@ -1257,6 +1275,11 @@ FORCE_ALIGN int WasapiPlayback::mixerSpatialProc()
std::vector<void*> resbuffers;
std::vector<const void*> tmpbuffers;

#ifdef AVRTAPI
auto taskname = (mOrigUpdateSize<mFormat.Format.nSamplesPerSec/100) ? L"Pro Audio" : L"Audio";
auto avhandle = AvrtHandlePtr{AvSetMmThreadCharacteristicsW(taskname, &sAvIndex)};
#endif

/* TODO: Set mPadding appropriately. There doesn't seem to be a way to
* update it dynamically based on the stream, so a fixed size may be the
* best we can do.
Expand Down

0 comments on commit c0e5532

Please sign in to comment.