Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

audio: Implement Xbox driver using OpenXDK XAudio #20

Merged
merged 2 commits into from
Apr 5, 2020

Conversation

JayFoxRox
Copy link
Member

@JayFoxRox JayFoxRox commented Jan 14, 2020

This implements audio.

Requires XboxDev/nxdk#286 for testing in XQEMU.

Code to test this can be found in JayFoxRox/nxdk#70 (you still have to manually fetch this submodule). There is also JayFoxRox/nxdk#68, but it is very broken (not sure if an issue with this PR or the SDL_mixer port).

During testing I occasionally had a bug in XQEMU where playback would randomly stop forever (no more callbacks either?). The problem still occurs but is much less frequent. I assume this is an independent bug in XAudio or QEMU.

This wasn't tested on hardware yet.

@sam-itt
Copy link

sam-itt commented Jan 31, 2020

Tested on real hardware. Works within a specific set of parameters, misbehave outside of that set:

  • Won't handle a spec with U8/1/441 Spec -> No sound
  • Play scrambled with S16/2/441
  • Only seems to work with a spec of S16/2/48 and will accept(play as expected) 48 or 441 feed

Some tests

@JayFoxRox
Copy link
Member Author

JayFoxRox commented Feb 3, 2020

I can confirm the issue reported by @sam-itt . I tracked it down to this:

while (SDL_TRUE) {
const double diff = SDL_pow(xdiv2, i * 2) / SDL_pow(f, 2);
if (diff < 1.0e-21f) {
break;
}
i0 += diff;
i++;
f *= (double) i;
}

The loop exit condition is never met (result of diff always too large).

I have added a commit to disable our nxdk-pdclib pow() function in SDL (which also provides its own). The nxdk-pdclib pow() function (added by @thrimbor) is based on exp() and log(). I assume it's simply not accurate enough or doesn't handle special values correctly.
We should have another issue about re-enabling more pdclib math.h functions in the future.

Ideally upstream SDL would not be able to get stuck in this loop though; the C specification is a bit convoluted so I might have missed something, but I believe there's no precision requirement on pow().

@sam-itt
Copy link

sam-itt commented Feb 4, 2020

I confirm that it works as expected when given U8/1channel/48k. Tested on real hardware.

@dracc
Copy link

dracc commented Feb 6, 2020

Tested as described in PR description. Works fine both in xqemu and on my 1.6.
Screenshot

@thrimbor
Copy link
Member

Finally got around to testing this on my 1.0 Xbox, and there seems to be a weird issue causing hangs/crashes (which doesn't happen with the XAudio sample). Sometimes it takes two loops, sometimes a dozen, but I always get a hang or a crash. I added a few debugPrints, and when it hangs, everything seems to work fine until SDL_AtomicGet(&_this->enabled). I don't know how that statement would cause this behavior, though.

@JayFoxRox
Copy link
Member Author

I had to rebase for JayFoxRox/hode#1 as I required the gamepad axis fix from the latest master.

I'm not sure what problem @thrimbor experiences or how to fix it.

I have had my Heart of Darkness port running in the background for a while and it seems to be mostly stable - I got a single hang after about 20 minutes; audio worked flawless until then (and then I'm not even sure if the crash was caused by audio).

I'd prefer if we merged this soon (with or without issues) because it's clearly better than master. We can always iterate later. We'll just create an issue about it being unstable / crashy.

@thrimbor
Copy link
Member

thrimbor commented Apr 5, 2020

Tested again, merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants