rust3ds / ctru-rs

Rust wrapper for libctru
https://rust3ds.github.io/ctru-rs/
Other
117 stars 17 forks source link

Addition of the NDSP module and related examples #83

Closed Meziu closed 1 year ago

Meziu commented 1 year ago

I've been working on this module for a while, being one of the most chaotic pieces of code I have ever had to read through. Even though this is actually libctru's second revision of an "audio" service, the system can barely stand on its feet, and making a safe wrapper depending solely on the assumptions (or lack thereof) libctru makes is not a simple task.

Even though it looks like it works as I wrote it, there are many more things I have to check and fix and other I simply have to add. Furthermore, I'm having problems tuning the audio-filters example to behave exactly the same way as the one in 3ds-examples.

This is why I made this PR draft: I need feedback on the overall structure of the wrapper (before venturing into audio streaming), and I need help to get the example to actually work.

~Even though the examples "procedure" seems to be working, the sound produced has 2 issues: it's not continuous and it makes a weird pop in the background. The 3ds-example's code generates a clean continuous wave.~ Edit: found the main issue. I finally understood the inner workings of the samples, and why 3ds-examples made all that conversion efforts. It works better, but I still find a small issue in this version: it seems the audio doesn't finish properly or something, since it's possible to hear some overlap the longer the app runs. I'd investigate more but my 3DS' battery ran out. To tomorrow :smile:.

It's hacky, it's unfinished, but that's why I want to hear your thoughts :smiley:

Meziu commented 1 year ago

The example works fine now though I had to turn up the buffer length. My guess to why it didn't work is that due to chunks_exact_mut and the other wrapping operations my implementation of fill_buffer was actually slower when accessing memory, creating delays between the "ending" of a buffer and the start of the next one (which caused popping). I could make an unsafe version to see the results (basically copying 1:1 the one in 3ds_examples) but the use of too much unsafe code in an example seems against its purpose.

Meziu commented 1 year ago

@ian-h-chamberlain Since you made the GitHub Actions and test implementation, could you take a look at why the checks fail? They seem to fail in the test implementation, which isn't related to our commits...

Techie-Pi commented 1 year ago

Looks like the test fails with the latest nightly because TestOpts recently added fail_fast. And the 2022-07-18 nightly test fails because cast_mut was added on 1.65 (and nightly-2022-07-18 is near 1.62). So maybe we should update the nightly used in the nightly-2022-07-18 test?

PS I'll review this code in a few weeks, but nothing stands out to me after the changes brought by @AzureMarker's review (though I just did a shallow pass over the code) :)

Meziu commented 1 year ago

Seems like ADPCM isn't worth the effort. I've seen some people around be able to reverse engineer it and use it, but it's overly complex and inaccessible. The only reason why someone would use that nowadays (in non-licensed software) is for modding, since many Nintendo games use that format for compressed audio.

Meziu commented 1 year ago

Seems like most of the work on the backend is done. This makes me very happy :smile:. I will soon start working on some decoding examples, so we can play some real :notes: tunes :notes: on the console.

Meziu commented 1 year ago

Edit: On second thought, adding weight to this PR is unneeded, and more complex examples should come once multi-threading enables optimizations. I just added some docs and put a new error case in, it should be fine now!