## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
IIDX likes to call `CoCreateInstance` and `init` multiple times on ASIO
drivers, but some ASIO drivers like `Neva Uno` really don't like that
and ends up crashing. In our wrapper, cache the instances and try to
reuse them for better compatibility.
## Testing
Worked fine for FlexASIO / Xonar AE / Realtek ASIO though none of these
drivers repro the crashing behavior.
## Link to GitHub Issue or related Pull Request, if one exists
Building on #745
## Description of change
With `-wasapishared`, some users see `AUDCLNT_E_BUFFER_TOO_LARGE`
(`0x88890006`).
The existing one-device-period buffer clamp wasn't enough on endpoints
with a small shared buffer; the shared buffer is double-buffered, so a
full-buffer write often exceeds the free space.
### Fix
Added a FIFO bridge to `SharedRedirect` that decouples the game's
per-event writes from the shared engine's clock:
- **`GetBuffer`** hands the game a pointer into the FIFO tail to write
in place.
- **`ReleaseBuffer`** commits the write and drains `min(pending,
device_free)` frames to the device - so a write can never exceed what
the device accepts, structurally preventing the overflow on any
endpoint.
- **`GetCurrentPadding`** reports the FIFO fill level (capped to the
reported buffer size) so poll/timer-driven games pace correctly against
the virtual buffer.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
This new option, `-wasapishared`, detects when the game opens WASAPI
Exclusive stream and forcibly opens a shared mode stream instead on the
real device.
#### Benefits of this:
1. No need for `force wasapi shared` patches
2. No need to change sample rate of audio devices before starting up
games
3. Adds ability to boot in shared mode even for games that do not have
shared wasapi changes (old GITADORA, popn HC)
As a result, this option is strictly better than `shared wasapi` patches
available for many games.
#### Downsides:
1. OS resampling will add a small latency, but not big enough to be
noticeable.
2. Using shared mode instead of exclusive mode adds latency, of course.
(If you cared about latency, you would use the low latency option, or
use exclusive or asio)
Basically it's the "make things work" button for audio that should work
for almost all games that we support.
The option has no effect if the game opens in shared mode.
## Testing
SDVX7 - ok
GITADORA GW - ok
popn HC - ok
IIDX - ok
## Link to GitHub Issue or related Pull Request, if one exists
#730
## Description of change
Add an option that extracts channels from 7.1 ASIO and presents to 2-ch
ASIO. Same idea as the SDVX 2ch fix except for gitadora we are
duplicating the center channel to front.
## Testing
Tested SDVX and GFDM Arena.
## Link to GitHub Issue or related Pull Request, if one exists
#730
## Description of change
spicecfg is a 32-bit application. When it uses the ASIO SDK it only saw
the 32-bit drivers.
There are some ASIO drivers that have different names under 32-bit and
64-bit (Xonar AE is one of them)... so we have to manually scan the
registry and surface both the WOW32 and WOW64 nodes.
## Testing
<img width="329" height="309" alt="image"
src="https://github.com/user-attachments/assets/7abecf76-6835-4df5-8c2e-e7b425130f4c"
/>
Checked both 32-bit and 64-bit configurator, identical results.
## Link to GitHub Issue or related Pull Request, if one exists
#730
## Description of change
Flip the option - enable the Realtek hack by default, unless the user
chooses not to.
## Testing
Tested ASIO path and WASAPI path. WASAPI path should be unaffected as
the game just picks the default audio device.
## Link to GitHub Issue or related Pull Request, if one exists
#730, #718
## Description of change
Part 1)
When ASIO is in use, the game also looks for a Realtek device so that it
can open a WASAPI Exclusive mode stream for headphones.
Add an option to fake that, in case the user doesn't have a Realtek
device.
Part 2)
`-gdaasio` wasn't workign properly - fix the logic.
## Testing
Seems to work with FlexASIO, and Xonar with no real Realtek device.
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Create `WrappedAsio`, similar to how we wrap `IAudioEndpoint`
So far, the wrapper does these things:
1. logging (for diagnosis, since iidx and gfdm don't produce any logs
when asio succeeds)
2. iidx32+ hack to work around refcount mismatch issue
3. sdvx valk cab hack to force 2-channel audio ("downmixing" by taking
only the front channels)
4. honor volume boost
As a result of `#2` the mempatch was removed from `iidx.cpp` since we
can tackle it cleanly in the hook. `#3` also removes the need for manual
patches.
Real downmixing is hard & expensive on the CPU so it was not
implemented.
## Testing
Tested iidx/sdvx/gfdm with xonar and flexasio
## 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.
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#717, fixes#647
## Description of change
Adds an option to downmix surround sound (5.1, 7.1, etc) down to stereo
(2 speakers). This can be used in most WASAPI games, including Gitadora
and FTT.
How it works: when the game tries to open surround format (say, 7.1) we
create a fake buffer and tell the game that it is supported. In reality
we open a 2-channel stream with the real sound card. When the stream
begins, we downmix the channels down to two (using one of many
algorithms) and output to the sound card.
While we're here, implement an option to boost the game volume by some
decibel value, which is a feature often requested by SDVX players. This
was needed since downmixing can sometimes result in quieter audio.
## Testing
Tested GW Delta and FTT.
Downmix doesn't work on IIDX (32 bits) but volume boost works.
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#681
## Description of change
`Sleep` and `sleep_for()` can be very inaccurate and varies depending on
what the OS gives us...
### `timeBeginPeriod(1)`
On boot, we are now calling `timeBeginPeriod(1)`, which affects the
whole process but makes `Sleep` more accurate. There is some risk here
if any game was relying on doing things like `Sleep(1)` and expecting it
to run for 15.6ms. Most games already call `timeBeginPeriod(1)` in the
game engine, though not the whole time, so I'm hoping that this is not
too impactful.
### Opt out of Win11 power throttling
Ensure that timer resolution change above is respected even when the
window is occluded / minimized by opting out of throttling via
`PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION`.
### Use Win10 high resolution timer instead of Sleep
On Win10 1803 and above, there is a new OS-level API for high resolution
timers; if this is available, use it
(`CREATE_WAITABLE_TIMER_HIGH_RESOLUTION`). Worth noting that WINE
doesn't support this currently.
If not, fall back to `Sleep`, which is significantly better than
`sleep_for()` in my experiments.
Callers of Sleep / sleep_for were replaced with this new timer. Most of
them anyway; calls to Sleep() with more than 100ms+ was left alone.
### Add an option as a chicken bit
To opt out I'm adding a new option called `Use Legacy Timers` which will
revert to behavior before this PR. The code paths that switched from
`sleep_for` to `Sleep` will remain in place though, not affected by the
option.
## Expected changes
In some I/O emulation modules, poll threads may run more frequently,
resulting in lower latency.
It also means that spice overall may use more CPU resources and power.
If you don't like this, you can always enable the option to opt out;
e.g., if you're on old arcade cab PC.
## Testing
DDR p4io - ok
drs touch hook - ok
IIDX camera hook - ok
CCJ trackball - ok
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
On some Win11 systems,
`CoCreateInstance(CLSID_DirectSoundI3DL2ReverbDMO)` started to fail with
`ERROR_MOD_NOT_FOUND` instead of `REGDB_E_CLASSNOTREG` for some reason.
## Testing
User tested.
## Link to GitHub Issue or related Pull Request, if one exists
## Description of change
Deprecate backend conversion options and replace with one unified option
for enabling WASAPI exclusive conversion to ASIO.
The new option takes in a string (ASIO driver name) and when filled out,
it automatically enables the ASIO backend.
This is to avoid confusion that was caused by the previous option - the
fact that it was split into two (one to enable the conversion, another
to optionally pick which ASIO driver to use) and that user needed to
specify an integer as opposed to the driver name.
## Testing
Tested on IIDX33. Old options should continue to work.
## Link to GitHub Issue, if one exists
Fixes#509
## Description of change
Implement `WrappedIAudioClient3`.
For now, we have only seen SDVX use it (EG final) and only when the
shared mode patch is enabled. Exclusive still goes through version 1.
This means that for V3 we can forego implementing backend conversion
logic (for now).
Only significant addition is `InitializeSharedAudioStream` and this IS
called by SDVX when shared mode patch is enabled.
## Testing
Tested EG final, tested year 1 data, also IIDX shared/exclusive wasapi.
## Link to GitHub Issue, if one exists
#477
## Description of change
Arena cab has two sound cards and it uses `WrappedIMMDeviceCollection`
to set the volume to 100% on boot on both, instead of the typical
`GetDefaultAudioEndpoint`.
## Testing
Testing Delta, testing other games as well as they are affected.
## Link to GitHub Issue, if one exists
n/a
## Description of change
`acmFormatSuggest` is known to cause significant perf issues on Linux;
add a hook to return cached results.
The fix is only active in the Linux variant.
For discussion, see
* https://codeberg.org/nixac/spicetools/issues/2
* https://codeberg.org/nixac/spicetools/issues/4
## Testing
I've only tested this on Windows, checking if iidx and popn can boot,
play songs without audio issues.