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

Add QEMU audio output to APU #25

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Add QEMU audio output to APU #25

wants to merge 5 commits into from

Conversation

JayFoxRox
Copy link
Owner

@JayFoxRox JayFoxRox commented Jan 22, 2019

This PR adds routing options for the GP audio output.

In Xbox, audio flows from VP (playback) → GP (effects) → EP (encoding) → ACI (actual output).

However, only the VP → GP transfer is hardwired. The other transfers are performed manually though programmable code. Hence, we can't easily sniff the audio data.

But: We can still make assumptions what Xbox DirectSound will do (HLE style). While the GP code is game specific, it always has a similar structure and it always seems to use the same memory layout.
The GP will DMA to scratch memory that is shared with the EP. So once the GP has ran, we just read the memory where we believe the GP must have written it.

This code will read this memory back and decode the samples.
We also make assumptions about the format: 5.1, 24 bit.

This assumption should hold true for all Xbox DirectSound versions.
- However, it doesn't hold true for the DirectSound variant used during the boot animation, because it runs a different GP-mainloop (as EP is disabled, GP must output to ACI directly; so this HLE hack doesn't see audio between GP / EP where expected).


The basic flow of the audio is (bold list items implemented in this PR), ordered chronologically:

Hardwired processing of VP

  • Processing of audio voices from RAM (buffer or stream) into 32 MIXBINs [follow-up PR, but using process_voice framework implemented here, which provides the MIXBINs, but nothing else]
  • XQEMU Debug: Injection of a 1500Hz sine-audio wave into MIXBINs (to get sound to test audio output, without voices being functional)
  • Non-programmable transfer of VP MIXBIN output to GP MIXBUF
  • XQEMU Debug: Additional routing of this 32 channel VP audio output
    • Dumping of individual channls to sample-accurate files, with masking to enable/disable each channel.
    • Playback of mono mix to QEMU audio output, with masking to enable/disable each channel.

Programmable processing of audio by GP (Game specific DSP Code for Xbox)

  • Responding to CPU command lists via DSP DMA from DSP scratch memory [already emulated in master]
  • Applying effects on 32 channel audio and downmixing to 5.1 [already emulated in master]
  • Programmable transfer of 5.1 audio via DSP DMA to DSP scratch memory, shared between GP / EP [already in master, but partially broken]
  • XQEMU Debug: Sniffing and additional routing of this 5.1 audio from DSP scratch memory (HLE heavy, to work-around EP, see note below)
    • Dumping of individual 5.1 channels to sample-accurate files.
    • Downmixed stereo audio playback to QEMU audio output.

Programmable processing of audio by EP (Common DSP Code for Xbox)

  • Programmable transfer of 5.1 audio via of DSP DMA from DSP scratch memory, shared between GP / EP [already in master, but partially broken]
  • Stereo downmixing, AC3 encoding etc. of 5.1 audio [already emulated in master, but broken]
  • Programmable transfer of 2.0 and 5.1 AC3 audio via DSP DMA to DSP FIFO memory, shared between EP / ACI [already in master but partially broken]

(As the EP code is crashing in XQEMU, it's disabled; however, because the task common to all games, we can temporarily HLE it by doing its job on our own)

ACI / AC97

  • Looped playback from RAM (which is shared with EP FIFO memory) [inherited from QEMU, but broken for various reasons]

(As the EP is broken / disabled, no audio ever reaches this component. It doesn't matter because we have our temporary HLE output from GP)


TODO:

  • Split GP debug via HLE into separate PR It's a commit already
  • Move GP debug output into a separate PR

@JayFoxRox JayFoxRox added the wip label Jan 22, 2019
hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
for(unsigned int frame = 0; frame < frames; frame++) {
se_frame(opaque);
}
}
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a hack... I'm not sure how it ended up in this branch? This was part of the DSP testing

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved into separate commit already.

hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
@@ -0,0 +1,35 @@
#!/usr/bin/python3
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

License?

@@ -0,0 +1,35 @@
#!/usr/bin/python3
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other repository or something? I asked on XQEMU IRC a couple of minutes ago

hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
@JayFoxRox JayFoxRox force-pushed the audio-card branch 5 times, most recently from 157c128 to 01bd642 Compare January 31, 2019 19:31
hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
@JayFoxRox
Copy link
Owner Author

Removing comment:

    /* FIXME: The following should not be necessary. It's a hack.
     *
     *        Normally, the GP mixes the MIXBINs, then DMAs the mixed result to
     *        the EP, which then encodes AC3 and DMAs to the ACI.
     *        So the final mixing of MIXBINs is typically done on GP.
     *
     *        As we don't have the working DSP / DMA / ACI, we need our own
     *        mixing and output for now.
     *        In the future, this code can be removed. */

hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
d->gp.dsp = dsp_init(d, gp_scratch_rw, gp_fifo_rw);
d->ep.dsp = dsp_init(d, ep_scratch_rw, ep_fifo_rw);


Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comment that only debug functionality is found beyond this point, or something?

hw/xbox/mcpx_apu.c Outdated Show resolved Hide resolved
@JayFoxRox JayFoxRox force-pushed the audio-card branch 3 times, most recently from dae54dc to 93ba86e Compare February 1, 2019 12:53
/* TODO: this should be on a thread so it waits on the voice lock */
static void se_frame(void *opaque)
#if (PLAYBACK_VP_BINS_MASK > 0) || (DUMP_VP_BINS_MASK > 0)
static void route_vs_bins(MCPXAPUState *d,
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*vp

d->gp.dsp = dsp_init(d, gp_scratch_rw, gp_fifo_rw);
d->ep.dsp = dsp_init(d, ep_scratch_rw, ep_fifo_rw);


#if PLAYBACK_VP_BINS_MASK || PLAYBACK_XBOX_DS_GP
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

> 0

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

Successfully merging this pull request may close these issues.

1 participant