Citra: Implement Looped Buffers

Created on 19 Sep 2016  路  7Comments  路  Source: citra-emu/citra

Many games seem to use looped audio buffers and produce the following log message.

Audio.DSP <Error> audio_core/hle/source.cpp:DequeueBuffer:249: Looped buffers are unimplemented at the moment

We should implement them.

This is an issue to track the progress of the implementation.

A-audio dsp-hle T-unimplemented has-games-wiki-entry

Most helpful comment

Chiming in here after doing a bunch of fiddling based on @MerryMage 's test suite on my o3ds and a few games that use loops in the emulator...

  • Simple loops are the only thing I've seen in a commercial game. Pretty much, having a buffer in the queue flagged as looping the entire, usually for a reverb effect (found this in Zelda OOT's background music, Mario Kart's button noises, and Mario 3D Land's "?" blocks). A patch to support this would be trivial, and I can clean it up and toss one out sometime tomorrow.
  • I haven't been able to get loop_related to do anything on my hardware. The play_position register affects the start of the first playback of the embedded buffer. All following loops start from the beginning of the buffer regardless of the value of loop_related. Commercial games seem to be fond of setting the dirty bit for play_position=0 when looping, though that register does not seem to be updated to any other value by either the game or the DSP engine. Further testing is definitely necessary.
  • Complex loops don't seem to work with queued buffers, only the embedded ones. This might just be a timing or caching issue though (Mario Kart 7 always invalidates the cache to the DSP command buffer when playing loops, so there might be some errata).

I'd be happy to make a PR for any of this, and any additional information can help speed the latter 2 bullet points.

All 7 comments

The work would likely require either writing a few tests to confirm how looped buffers work or reverse engineering the DSP binary blob.

A buffer is a looped buffer if Buffer::is_looped is set. SourceConfiguration::loop_related indicates where the first sample position of the loop is. There is a second loop boolean SourceConfiguration::looping.

My own work on this is waiting on some DSP RE I'm doing; but I don't mind someone jumping in in the meantime.

Chiming in here after doing a bunch of fiddling based on @MerryMage 's test suite on my o3ds and a few games that use loops in the emulator...

  • Simple loops are the only thing I've seen in a commercial game. Pretty much, having a buffer in the queue flagged as looping the entire, usually for a reverb effect (found this in Zelda OOT's background music, Mario Kart's button noises, and Mario 3D Land's "?" blocks). A patch to support this would be trivial, and I can clean it up and toss one out sometime tomorrow.
  • I haven't been able to get loop_related to do anything on my hardware. The play_position register affects the start of the first playback of the embedded buffer. All following loops start from the beginning of the buffer regardless of the value of loop_related. Commercial games seem to be fond of setting the dirty bit for play_position=0 when looping, though that register does not seem to be updated to any other value by either the game or the DSP engine. Further testing is definitely necessary.
  • Complex loops don't seem to work with queued buffers, only the embedded ones. This might just be a timing or caching issue though (Mario Kart 7 always invalidates the cache to the DSP command buffer when playing loops, so there might be some errata).

I'd be happy to make a PR for any of this, and any additional information can help speed the latter 2 bullet points.

It's been a while since I've taken a look at audio. The above statements were based on what I remembered of my previous work before I started writing everything down; apologies for what appears to be my poor memory and sending you on what seems to be a wild goose chase.

Feel free to submit a PR for what you do have; I'm currently (very slowly) reverse engineering the binary blob.

Mostly implemented afaik in #2422.

I implemented everything mentioned here in that PR. The only thing left is the FIFO like behavior in 3ds sound, as noted in the other pr.

Is this issue solved?

Closing as there's no value in keeping this open; everything mentioned has been implemented.

Was this page helpful?
0 / 5 - 0 ratings