Files
spice2x-r3d/src/spice2x/hooks/audio/audio.h
T
bicarusandGitHub 48033816a8 audio: WASAPI exclusive resampling, buffer size increase options (#727)
## Link to GitHub Issue or related Pull Request, if one exists
n/a

## Description of change

Resampler:
Implement resampler for exclusive mode streams, as we are seeing more
and more devices - not just laptops but onboard audio devices - that
only support 48khz and not 44.1khz. Should work with volume boost (gain
calculated inside resample) and also downmixer (hands off intermediate
scratch buffers).

Buffer size increase:
By default many of these games request a tiny buffer when in shared mode
(TDJ uses 3ms). On some audio setup this results in crackling due to
underflow. Add an option to forcibly increase the buffer size.

## Testing
With resampler set to 48kHz and buffer set to 20ms I can reliably boot
and play IIDX on my display port monitor's speakers; previously this
wasn't possible. IIDX is event-driven.

Tested SDVX7 as well at 48kHz, which opens timer-driven streams.
2026-06-02 01:55:50 -07:00

61 lines
1.7 KiB
C++

#pragma once
#include <cstdint>
#include <optional>
#include <string>
#include <windows.h>
#include <mmreg.h>
#ifndef _MSC_VER
#include <ks.h>
#include <ksmedia.h>
#endif
namespace hooks::audio {
enum class Backend {
Asio,
WaveOut,
};
// surround-to-stereo downmix algorithm
enum class DownmixAlgorithm {
FrontOnly, // keep only the front channels
RearOnly, // keep only the rear/back channels
SideOnly, // keep only the side channels
AC4, // AC-4 stereo downmix coefficients (ETSI TS 103 190-1)
Normalize, // all channels equally loud, LFE dropped
};
extern bool ENABLED;
extern bool VOLUME_HOOK_ENABLED;
extern std::optional<DownmixAlgorithm> DOWNMIX_ALGORITHM;
extern float VOLUME_BOOST;
// target sample rate the hooked output is resampled to, if set
extern std::optional<uint32_t> RESAMPLE_RATE;
// minimum WASAPI exclusive buffer duration (milliseconds), if set. enlarges the device buffer
// to avoid underrun crackle on endpoints that cannot service a tiny buffer in time.
extern std::optional<uint32_t> EXCLUSIVE_BUFFER_MS;
extern bool USE_DUMMY;
extern WAVEFORMATEXTENSIBLE FORMAT;
extern std::optional<Backend> BACKEND;
extern std::optional<size_t> ASIO_DRIVER_ID;
extern std::string ASIO_DRIVER_NAME;
extern bool ASIO_FORCE_UNLOAD_ON_STOP;
extern bool LOW_LATENCY_SHARED_WASAPI;
void init();
void stop();
inline std::optional<Backend> name_to_backend(const char *value) {
if (_stricmp(value, "asio") == 0) {
return Backend::Asio;
} else if (_stricmp(value, "waveout") == 0) {
return Backend::WaveOut;
}
return std::nullopt;
}
}