Merge remote-tracking branch 'sunshine/master'

This commit is contained in:
Yukino Song
2025-05-07 03:10:11 +08:00
30 changed files with 570 additions and 133 deletions

View File

@@ -117,15 +117,26 @@ namespace {
using virtual_sink_waveformats_t = std::vector<WAVEFORMATEXTENSIBLE>;
/**
* @brief List of supported waveformats for an N-channel virtual audio device
* @tparam channel_count Number of virtual audio channels
* @returns std::vector<WAVEFORMATEXTENSIBLE>
* @note The list of virtual formats returned are sorted in preference order and the first valid
* format will be used. All bits-per-sample options are listed because we try to match
* this to the default audio device. See also: set_format() below.
*/
template<WORD channel_count>
virtual_sink_waveformats_t create_virtual_sink_waveformats() {
if constexpr (channel_count == 2) {
auto channel_mask = waveformat_mask_stereo;
// only choose 24 or 16-bit formats to avoid clobbering existing Dolby/DTS spatial audio settings
// The 32-bit formats are a lower priority for stereo because using one will disable Dolby/DTS
// spatial audio mode if the user enabled it on the Steam speaker.
return {
create_waveformat(sample_format_e::s24in32, channel_count, channel_mask),
create_waveformat(sample_format_e::s24, channel_count, channel_mask),
create_waveformat(sample_format_e::s16, channel_count, channel_mask),
create_waveformat(sample_format_e::f32, channel_count, channel_mask),
create_waveformat(sample_format_e::s32, channel_count, channel_mask),
};
} else if (channel_count == 6) {
auto channel_mask1 = waveformat_mask_surround51_with_backspeakers;
@@ -298,6 +309,10 @@ namespace platf::audio {
auto waveformatext_pointer = reinterpret_cast<const WAVEFORMATEXTENSIBLE *>(mixer_waveformat.get());
capture_waveformat.dwChannelMask = waveformatext_pointer->dwChannelMask;
}
BOOST_LOG(info) << "Audio mixer format is "sv << mixer_waveformat->wBitsPerSample << "-bit, "sv
<< mixer_waveformat->nSamplesPerSec << " Hz, "sv
<< ((mixer_waveformat->nSamplesPerSec != 48000) ? "will be resampled to 48000 by Windows"sv : "no resampling needed"sv);
}
status = audio_client->Initialize(
@@ -315,7 +330,7 @@ namespace platf::audio {
return nullptr;
}
BOOST_LOG(info) << "Audio capture format is " << logging::bracket(waveformat_to_pretty_string(capture_waveformat));
BOOST_LOG(info) << "Audio capture format is "sv << logging::bracket(waveformat_to_pretty_string(capture_waveformat));
return audio_client;
}
@@ -795,6 +810,22 @@ namespace platf::audio {
}
}
// When switching to a Steam virtual speaker device, try to retain the bit depth of the
// default audio device. Switching from a 16-bit device to a 24-bit one has been known to
// cause glitches for some users.
int wanted_bits_per_sample = 32;
auto current_default_dev = default_device(device_enum);
if (current_default_dev) {
audio::prop_t prop;
prop_var_t current_device_format;
if (SUCCEEDED(current_default_dev->OpenPropertyStore(STGM_READ, &prop)) && SUCCEEDED(prop->GetValue(PKEY_AudioEngine_DeviceFormat, &current_device_format.prop))) {
auto *format = (WAVEFORMATEXTENSIBLE *) current_device_format.prop.blob.pBlobData;
wanted_bits_per_sample = format->Samples.wValidBitsPerSample;
BOOST_LOG(info) << "Virtual audio device will use "sv << wanted_bits_per_sample << "-bit to match default device"sv;
}
}
auto &device_id = virtual_sink_info->first;
auto &waveformats = virtual_sink_info->second.get().virtual_sink_waveformats;
for (const auto &waveformat : waveformats) {
@@ -804,6 +835,10 @@ namespace platf::audio {
auto waveformat_copy = waveformat;
auto waveformat_copy_pointer = reinterpret_cast<WAVEFORMATEX *>(&waveformat_copy);
if (wanted_bits_per_sample != waveformat.Samples.wValidBitsPerSample) {
continue;
}
WAVEFORMATEXTENSIBLE p {};
if (SUCCEEDED(policy->SetDeviceFormat(device_id_copy.c_str(), waveformat_copy_pointer, (WAVEFORMATEX *) &p))) {
BOOST_LOG(info) << "Changed virtual audio sink format to " << logging::bracket(waveformat_to_pretty_string(waveformat));

View File

@@ -219,7 +219,7 @@ namespace platf::dxgi {
{
util::buffer_t<std::uint8_t> cursor_img = img_data;
std::for_each((std::uint32_t *) std::begin(cursor_img), (std::uint32_t *) std::end(cursor_img), [](auto &pixel) {
auto alpha = (std::uint8_t)((pixel >> 24) & 0xFF);
auto alpha = (std::uint8_t) ((pixel >> 24) & 0xFF);
if (alpha == 0xFF) {
// Pixels with 0xFF alpha will be XOR-blended as is.
} else if (alpha == 0x00) {
@@ -286,7 +286,7 @@ namespace platf::dxgi {
{
util::buffer_t<std::uint8_t> cursor_img = img_data;
std::for_each((std::uint32_t *) std::begin(cursor_img), (std::uint32_t *) std::end(cursor_img), [](auto &pixel) {
auto alpha = (std::uint8_t)((pixel >> 24) & 0xFF);
auto alpha = (std::uint8_t) ((pixel >> 24) & 0xFF);
if (alpha == 0xFF) {
// Pixels with 0xFF alpha will be XOR-blended by make_cursor_xor_image().
// We make them transparent for the alpha-blended cursor image.

View File

@@ -92,10 +92,10 @@ namespace platf {
constexpr float EARTH_G = 9.80665f;
#define MPS2_TO_DS4_ACCEL(x) (int32_t)(((x) / EARTH_G) * 8192)
#define DPS_TO_DS4_GYRO(x) (int32_t)((x) * (1024 / 64))
#define MPS2_TO_DS4_ACCEL(x) (int32_t) (((x) / EARTH_G) * 8192)
#define DPS_TO_DS4_GYRO(x) (int32_t) ((x) * (1024 / 64))
#define APPLY_CALIBRATION(val, bias, scale) (int32_t)(((float) (val) + (bias)) / (scale))
#define APPLY_CALIBRATION(val, bias, scale) (int32_t) (((float) (val) + (bias)) / (scale))
constexpr DS4_TOUCH ds4_touch_unused = {
.bPacketCounter = 0,