Playing 2 high quality audio tracks with MSU1

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
Myself086
Posts: 158
Joined: Sat Nov 10, 2018 2:49 pm

Playing 2 high quality audio tracks with MSU1

Post by Myself086 »

I am thinking of porting a game to SNES but I need 2 high quality audio channels (music + 1 voice actor).

I know that MSU1 can only play 1 track at a time (1 channel). But can it read data at the same time?

What's the best approach for playing 8-bit audio on the SPC700?

I was thinking of playing 1 channel at a rate of 64000Hz after carefully placing the interpolation at a specific point in the table to play a pseudo 8-bit sample at 32000Hz. But I'm not sure I fully understand how the interpolation is done.
calima
Posts: 1745
Joined: Tue Oct 06, 2015 10:16 am

Re: Playing 2 high quality audio tracks with MSU1

Post by calima »

I believe streaming live audio (ie. not just midi-style) to the SPC uses way too much cpu. Combined with the fact that MSU1 does not exist as a standalone cart, I would recommend going custom, and having both hq audio channels played and mixed on-cart. Then the mixed audio stream is sent down the cart audio pins.
Myself086
Posts: 158
Joined: Sat Nov 10, 2018 2:49 pm

Re: Playing 2 high quality audio tracks with MSU1

Post by Myself086 »

I was thinking of using SA1+MSU1 since it's available on FXPak Pro. I wasn't planning on making physical copies. I know nothing about making custom hardware. Programming an FPGA core for this project could be interesting.

For transferring data to the SPC, I can use a 4-byte HDMA channel which is almost enough to play 2 8-bit 32000Hz tracks.
93143
Posts: 1715
Joined: Fri Jul 04, 2014 9:31 pm

Re: Playing 2 high quality audio tracks with MSU1

Post by 93143 »

Using HDMA for audio streaming is tricky because the oscillator ratio isn't reliable and is subject to thermal drift. You can't just dump 896 bytes on the SPC700 in one giant chunk and expect it to stay in sync, or even to be able to pick up the data without running out of stack space or index bits (depending on whether your method is more akin to d4s' method or mine).

More importantly, why the emphasis on 8-bit audio? BRR is much higher quality, and even with sync pauses, HDMA should be capable of close to 90 kHz if you don't need a high-frequency music engine. (A data rate that high would require the indexed direct transfer approach; the d4s-style stack indirect transfer approach is easier to sync but has too much overhead between data bursts.) One 32 kHz BRR channel should require a manageable amount of S-CPU power to transfer manually without HDMA, unless you want dialogue during intense action sequences...

If you really want uncompressed 8-bit audio, the echo buffer might be the best place for that. You can just write the sample to the upper byte of both channels, and leave the lower bytes zeroed. The issue with the echo buffer is it's a bit inflexible; if 32 kHz doesn't work, your next decent-sounding option is 16 kHz with sample-and-hold (write the byte four times instead of two). Also, obviously, you can't have hardware echo on anything else the SPC700 might happen to be doing...
Myself086
Posts: 158
Joined: Sat Nov 10, 2018 2:49 pm

Re: Playing 2 high quality audio tracks with MSU1

Post by Myself086 »

93143 wrote: Tue May 03, 2022 4:26 pm More importantly, why the emphasis on 8-bit audio? BRR is much higher quality, and even with sync pauses, HDMA should be capable of close to 90 kHz if you don't need a high-frequency music engine.
That's a very good question. I should try converting the voice actors to BRR and see how I feel about it. The original audio plays at a rate of 22050Hz so that would be a lot more convenient for space and bandwidth. Is there a tool that you recommend for converting audio to BRR and possibly test the converted audio directly on said tool?
93143 wrote: Tue May 03, 2022 4:26 pm (A data rate that high would require the indexed direct transfer approach; the d4s stack indirect transfer approach is easier to sync but has too much overhead between data bursts.)
I was thinking of using one loop per page and making sure the first byte always changes per scanline so it can be tested for synchronization. I haven't made this code yet so I don't know if the timing fits.
93143
Posts: 1715
Joined: Fri Jul 04, 2014 9:31 pm

Re: Playing 2 high quality audio tracks with MSU1

Post by 93143 »

Myself086 wrote: Tue May 03, 2022 6:34 pmIs there a tool that you recommend for converting audio to BRR and possibly test the converted audio directly on said tool?
Yeah, BRRTools. It converts both ways, with optional pre-emphasis filter when converting to BRR (to minimize the muffling effect of the Gaussian interpolator) and optional Gaussian interpolation when converting back. Unfortunately I think the back-conversion filter assumes a 32 kHz playback rate, which means it won't be perfectly accurate if your input is 22 kHz, but it should give you a very rough idea of what's going on. The pre-emphasis filter is also fairly approximate, presumably for speed and simplicity, but it does a decent job.

I came up with a much more precise convolution filter (the "16 kHz" one is the right one and should be used at the same sample rate as the input data) that should compensate for the Gaussian muffling nearly perfectly. But it could potentially reduce the perceived quality of the compressed sample by shifting the bandwidth balance upward too much (the gain near the Nyquist is something like 17 dB), and for speech at 22 kHz you probably won't need it...
I was thinking of using one loop per page and making sure the first byte always changes per scanline so it can be tested for synchronization. I haven't made this code yet so I don't know if the timing fits.
I wouldn't necessarily recommend trying to sync per scanline. There's not much room in the loop, although I suppose partially unrolling it could help. If you can make it work, go for it. It could be easier to deal with than the method I came up with, which requires an HDMA timing pulse every frame whether any streaming is happening or not...

Even if this works, it probably limits you to 3 bytes per scanline, since otherwise you'd have to massage the audio data to make sure every fourth byte is different. This is particularly true if you're using BRR, because messing with a header byte or a 4-bit subsample could have much more drastic effects than changing the lsb of an 8-bit sample... On the flip side, 3 data bytes per scanline would leave more time to try to sync on the non-data byte...

...

Also, yes, the MSU1 can read data while playing audio. If you're playing back Gangnam Style on the SNES, you'll want to both see and hear it. I believe the original idea was for two separate storage devices, one for data and one for audio, but the FXPak uses the same SD card for both, which is why you can't just slap any old bargain bin card into it and expect the MSU1 to work properly...
Post Reply