Ideas for compressing BRR samples further

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
psycopathicteen
Posts: 2936
Joined: Wed May 19, 2010 6:12 pm

Ideas for compressing BRR samples further

Post by psycopathicteen » Thu Jun 11, 2020 5:34 pm

In my SNES music program I'm making I just added an LZ4 compression feature, and these are the compression rates.

Synth patch with 4 detuned sawtooth oscillators:
BRR: 18432 bytes
LZ4: 12690 bytes

Synth patch with 4 detuned pulse waves
BRR: 18432 bytes
LZ4: 6139 bytes

The pulse waves look promising, but the sawtooth waves look like they can use a little more work. Any suggestions?

93143
Posts: 1192
Joined: Fri Jul 04, 2014 9:31 pm

Re: Ideas for compressing BRR samples further

Post by 93143 » Thu Jun 11, 2020 6:01 pm

Interesting. The conventional wisdom was that this doesn't work. I'm not surprised that it depends somewhat on the nature of the sample; sawtooth waves do have twice as many harmonics as square waves...

Those LZ4 numbers are for packed BRR, not packed PCM, right? Those numbers are comparable to what you'd see on graphics.

Is this for S-CPU decompression, or are you trying to pack more sample data into audio RAM?

psycopathicteen
Posts: 2936
Joined: Wed May 19, 2010 6:12 pm

Re: Ideas for compressing BRR samples further

Post by psycopathicteen » Thu Jun 11, 2020 6:20 pm

It's to pack more in the audio RAM.

93143
Posts: 1192
Joined: Fri Jul 04, 2014 9:31 pm

Re: Ideas for compressing BRR samples further

Post by 93143 » Thu Jun 11, 2020 6:34 pm

Found another post by the same guy saying that he's tried it and it doesn't work. I wonder if the disappointing saw results are indicative of what might happen if you try to generalize this to more information-dense waveforms...

Of course there are sounds that one might wish to play on a SNES that are not significantly/at all more complex than a supersaw but can't easily be single-cycle looped. I have my eye on that chorused square at 1/3 the size of the BRR...

How fast is the decompression on the SPC700? Is this a sample swapping technique or a sample streaming technique?

lidnariq
Posts: 9500
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Ideas for compressing BRR samples further

Post by lidnariq » Thu Jun 11, 2020 8:47 pm

... I really wonder what bregalad's test set was, because if you look at a histogram of BRR data it looks both extremely non-uniform
dx-10.png
dx-10.png (950 Bytes) Viewed 1565 times
and its spectrum has huge peaks indicating BRR's period of 9:
dx-10-spectrum.png
dx-10-spectrum.png (5.8 KiB) Viewed 1565 times
Specifically testing with the BRR (i.e. bytes 17673 through 65792) in "dx-10.spc" from the Dracula X soundtrack, naive compressors shave off 10% to 20%. (Gzip: 18.9%, bzip2: 14.8%, lzma: 20.7%, lz4: 9.6%)

nocash
Posts: 1211
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: Ideas for compressing BRR samples further

Post by nocash » Thu Jun 11, 2020 11:28 pm

Yes, that's interesting. Two basic questions:
- Is it lossless compression, allowing to restore the exact original BRR data?
- Did you already test different BRR files, including speech and other random sounds?
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

User avatar
Nikku4211
Posts: 66
Joined: Sun Dec 15, 2019 1:28 pm
Location: Bronx, New York
Contact:

Re: Ideas for compressing BRR samples further

Post by Nikku4211 » Fri Jun 12, 2020 5:22 pm

psycopathicteen wrote:
Thu Jun 11, 2020 6:20 pm
It's to pack more in the audio RAM.
The data has to be decompressed from LZ4 into BRR before being played by the SPC700. That's exactly what the general consensus that this method 'doesn't work' means: that it's not going to pack more in the audio RAM because the decompressed result will ultimately have to be stored in the audio RAM.
nocash wrote:
Thu Jun 11, 2020 11:28 pm
Yes, that's interesting. Two basic questions:
- Is it lossless compression, allowing to restore the exact original BRR data?
- Did you already test different BRR files, including speech and other random sounds?
LZ4 is lossless compression, yes.
I have an ASD, so empathy is not natural for me. If I hurt you, I apologise.

93143
Posts: 1192
Joined: Fri Jul 04, 2014 9:31 pm

Re: Ideas for compressing BRR samples further

Post by 93143 » Fri Jun 12, 2020 6:06 pm

Nikku4211 wrote:
Fri Jun 12, 2020 5:22 pm
The data has to be decompressed from LZ4 into BRR before being played by the SPC700. That's exactly what the general consensus that this method 'doesn't work' means: that it's not going to pack more in the audio RAM because the decompressed result will ultimately have to be stored in the audio RAM.
No, what "doesn't work" means is that your average BRR sample isn't going to get significantly smaller when compressed again, with the possible exception of the header bytes. This is pretty clear from Bregalad's posts, and lidnariq's results honestly aren't too far off that assertion.

The idea psycopathicteen is proposing seems to be that you could pack a bunch of compressed samples into ARAM and decompress each one with the SPC700 when required; they wouldn't ever have to all be uncompressed at the same time. This is likely why he picked LZ4; it's very fast on 8-bit processors. If the decompression is fast enough, it might not even be necessary to store the whole decompressed sample; it might be possible to use a small ring buffer.

This technique could replace or extend the effectiveness of I/O streaming from the CPU bus. On the flip side, it does mean that less sample space is available for simultaneous playback, so unless the SPC700 can keep several ring buffers fed at the same time, its applicability may be less universal.

Now, it is obvious that this technique could also be useful to save ROM, regardless of whether the SPC700 ends up saddled with the decompression or not. Depending on the material being compressed, it might not save much, and if you're computationally bound you may not want to bother, but it's good to know it isn't always just a pure loss.

User avatar
Nikku4211
Posts: 66
Joined: Sun Dec 15, 2019 1:28 pm
Location: Bronx, New York
Contact:

Re: Ideas for compressing BRR samples further

Post by Nikku4211 » Fri Jun 12, 2020 6:43 pm

93143 wrote:
Fri Jun 12, 2020 6:06 pm
The idea psycopathicteen is proposing seems to be that you could pack a bunch of compressed samples into ARAM and decompress each one with the SPC700 when required; they wouldn't ever have to all be uncompressed at the same time. This is likely why he picked LZ4; it's very fast on 8-bit processors. If the decompression is fast enough, it might not even be necessary to store the whole decompressed sample; it might be possible to use a small ring buffer.
I don't know. It still doesn't sound so good, especially when the LZ4 compressed samples, the sequencing data, the sound engine code, and whatever sample is being uncompressed are all in ARAM at the same time. I don't think the SPC700 can execute instructions directly from ROM without the S-CPU putting it into ARAM, right? If, for example, the song uses all 8 channels, each one playing a different sample, all playing a note simultaneously, than won't that mean you'll need to decompress 8 samples?

Boom.
I have an ASD, so empathy is not natural for me. If I hurt you, I apologise.

93143
Posts: 1192
Joined: Fri Jul 04, 2014 9:31 pm

Re: Ideas for compressing BRR samples further

Post by 93143 » Fri Jun 12, 2020 9:47 pm

Not necessarily. Why should every sample played have to be decompressed live? It could be that a number of the instruments are short or low-frequency samples that don't take up much space and therefore don't need compression. Maybe some samples are complex waveforms that don't compress well so there's no point. Perhaps it's only a few large samples that play at widely separated times that are compressed, so the SPC700 has plenty of time to completely decompress each one before it's needed, or if it can handle real-time decompression it can just feed a single ring buffer* while uncompressed BRR samples play on the rest of the channels. Or perhaps there are a lot of different relatively small instrument sets that can be swapped out between songs, or between sections of a song, without involving the S-CPU.

There's no need to assume an all-or-nothing approach. This scheme sounds like it scales pretty gracefully, unlike (say) blargg's PCM streaming technique which only works at all if there's nothing else happening...

Also, you've got 64 KB for everything, which is way more than you need for the engine code and song data. Most of the space is taken by samples and echo buffer. LZ4 is nowhere near complicated enough to take more than an insignificant fraction of the available memory.

*It should be noted that any ring buffer would have to be long enough so that the decompressor can still work, or rather the compressor would have to be designed for the desired ring buffer size - LZ4 works by copying duplicate data from earlier in the output stream.

calima
Posts: 1156
Joined: Tue Oct 06, 2015 10:16 am

Re: Ideas for compressing BRR samples further

Post by calima » Sat Jun 13, 2020 12:16 am

For the decompression speed, my NES lz4 unpacker does about 40kb/s. We could guesstimate spc700 at half a NES.

User avatar
Bregalad
Posts: 7889
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: Ideas for compressing BRR samples further

Post by Bregalad » Sat Jun 13, 2020 9:43 am

93143 wrote:
Fri Jun 12, 2020 6:06 pm
No, what "doesn't work" means is that your average BRR sample isn't going to get significantly smaller when compressed again, with the possible exception of the header bytes. This is pretty clear from Bregalad's posts, and lidnariq's results honestly aren't too far off that assertion.
Indeed that's what I was originally saying in the linked posts. But let's forget that and assume that it's feasible to compress BRR samples further in the ARAM.

For this to be any useful, you have to remember that all the following items will typically stand simultaneously in ARAM
  • Sound engine
  • Sound effect and sequence data
  • Echo buffer (optional)
  • BRR sample bank
  • Compressed sample bank
Note that a compressed sample which is currently playing back has to be stored twice in ARAM, once compressed and once in BRR format.

For this to make any sense, the compressed samples need to compress very well, and the compressed sample bank has to be much larger than the rest of the data present in the ARAM. I'm dubious...
Synth patch with 4 detuned sawtooth oscillators:
BRR: 18432 bytes
LZ4: 12690 bytes

Synth patch with 4 detuned pulse waves
BRR: 18432 bytes
LZ4: 6139 bytes
Just wondering, if those sounds like synth patches, could the BRR version possibly be generated algoritmically by software ? This would save the hassle to deal with compression in the first place.

User avatar
Nikku4211
Posts: 66
Joined: Sun Dec 15, 2019 1:28 pm
Location: Bronx, New York
Contact:

Re: Ideas for compressing BRR samples further

Post by Nikku4211 » Sat Jun 13, 2020 4:13 pm

Bregalad wrote:
Sat Jun 13, 2020 9:43 am
Just wondering, if those sounds like synth patches, could the BRR version possibly be generated algoritmically by software ? This would save the hassle to deal with compression in the first place.
Yeah, it'd be awesome to use the SPC700 itself to generate samples. I imagine it could be possible to even do software synth mixing on the SPC700 itself too, right?
I have an ASD, so empathy is not natural for me. If I hurt you, I apologise.

lidnariq
Posts: 9500
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Ideas for compressing BRR samples further

Post by lidnariq » Sat Jun 13, 2020 4:15 pm

I'm pretty certain I remember psycopathicteen having done that in the past. Some FM synth. He was trying to figure out how to pick which BRR filter.

Certainly the sizecoding approach is algorithmic generation for everything.

psycopathicteen
Posts: 2936
Joined: Wed May 19, 2010 6:12 pm

Re: Ideas for compressing BRR samples further

Post by psycopathicteen » Sat Jun 13, 2020 7:23 pm

I just tested this same algorithm with the BRR block header bytes rearranged at the front and here are the results:

12517 bytes for sawtooth patch
6013 bytes for pulse patch

With software generating, my main concern is the SPC700's Mhz speed. LZ4 decompressing is mostly just block moves.

I forgot to mentioned this in the OP but my LZ4 algorithm was slightly modified because my SNES music tool runs on the SNES itself. I'm using an 8-bit block match offset, instead of a 16-bit offset because comparing that many bytes took way too long. Of course, I'm not going to use this convoluted scheme for my game. My plan is to save all the sample data in save-RAM, and copy and paste the save-RAM file of the music program into my homebrew game ROM using tile molester.

Post Reply