BRR: is this doc accurate

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
BRR: is this doc accurate
by on (#3197)
just wanted to know how accurate this doc is:
http://www.snakeyes.org/docs/files/brr.txt

I read it through and made myself a simple brr->wav converter to
test if I understood the doc correctly...
but the brr didn't sound as it should (I tried converting it to wav with
some other program)
so I wanted to know if something in the doc is wrong
what I mostly was thinking could be wrong would be the filter part..
anyone that can read through the doc and tell me if every thing in it
is correct?

thanks. :)

edit:
I had a little look in the snes9x source and it seems like that's the way they are doing.. I think ;D
I'm actualy starting to think it's my code to generate a wav file that is wrong.. :oops:
I'm gonna have a look on it when I wake up tomorow.. I probably did something wrong

edit2:
After looking through my brr decoding code I discoverd that I had made the horrible mistake of nameing a variable in the for loop with same variable name as the for loop used... and that was the error ;D
now everything works!! yay!! :D
Re: BRR: is this doc accurate
by on (#3606)
dXtr wrote:
just wanted to know how accurate this doc is:
http://www.snakeyes.org/docs/files/brr.txt

It is, but there is something with clamping/rouding up that is needed to emulate "noise" samples, typically needed for the wind of Chrono Trigger, or also the juming noise in Megaman7 (and tons of others sound effects in various SNES games). I think that the last version of SNES 9x holds it pretty right, but not totally right (I noticed differences with the sound effects with CT between SNES9x and the real SNES).
Will the converter be available ? I already have one, but I'd be curious.

by on (#3617)
yeah.. if you want it..
for the moment it can only do brr->wav ;)

by on (#3619)
dXtr wrote:
yeah.. if you want it..
for the moment it can only do brr->wav ;)

Yeah, SNESSor is already able to do that, but I've no programm doing the opposite to my knowledge (exept SPCtool, that only compress a wav file in a exising SPC file, and I've no sound exept clicks and ticks under the Win2000's DOS version).

by on (#3622)
well.. later on it's going to support wav->brr.. but I have been working on some other projects lately so I haven't started that part yet.
Unfortantly I haven't come up with any good way of doing this that doesn't involve looping through every possible combination and then doing a brr->wav on every combination and pick the one that ressembles the original wav file. luckly I found the source for a brr encoder (brrenc.c) by someone named Chris Moeller, and I did even have more luck cus it's LGPL software. so I was thinking of baseing my wav->brr on his source code.

by on (#3626)
Contact anomie on the ZSNES forum for a detailed SPC-700 DSP doc that's currently a WIP and not posted anywhere (to my knowledge).

by on (#3627)
nice I will do that tomorrow. got to sleep some now :wink:

by on (#3634)
Super NES BRR and PlayStation VAG are forms of ADPCM (adaptive delta pulse code modulation). Here's the basic algorithm:
  1. For each filter, convolve the .wav with the filter to get a prediction residue for each sample.
  2. Select the filter that makes the smallest prediction residue.
  3. Select the scale (2^0 to 2^12) based on the range of this residue.
  4. Quantize the residue by dividing each element of the prediction residue by the scale.
  5. Write the scale, filter, and quantized prediction residue to a 9-byte block of the BRR sample.

by on (#3669)
thanks tepples. I couldn't really understand it before with all the filters and stuff :?
but hopefully whith your explanation I could write the code myself instead, and learn something. instead of just copying someones code and never really understand what it does ;)

by on (#3696)
tepples >
So I tried to write it myself....
I couldn't totally figure out this part
2. Select the filter that makes the smallest prediction residue.

especially this part "prediction residue" what is that o_O
I know what it means (some what) in swedish.. but I don't really understand what it means in this context. how do I calculate this "smallest prediction residue"?

---------

on another note.. b/c I can't get it to select the correct filter it's always defaults to filter 1 (except for first BRRblock that can only be 0).. but I did
try to convert a wav file to brr (that I had convert to wav from brr before ;) )
and I can hear something that a sounds similar (but not as good) as the original when converted back to wav. :D

by on (#3697)
Read all sections of Bores Introduction to DSP, especially the sections on FIR and IIR filters. Then do some reading on ADPCM codecs. Then you might understand what is going on inside BRR.

by on (#3698)
oooh. something to read in the bed ;)

by on (#3701)
dXtr wrote:
tepples >
So I tried to write it myself....
I couldn't totally figure out this part
2. Select the filter that makes the smallest prediction residue.

especially this part "prediction residue" what is that o_O
I know what it means (some what) in swedish.. but I don't really understand what it means in this context. how do I calculate this "smallest prediction residue"?


I think he means that you have to encode it by all the 4 different BRR compressions, then look at the 16th sample of all 4. Then, take the one who has the smallest difference with the original WAV sample. Scince the compression 2 and 3 are pretty much the same, I noticed that many licenced games does never uses the 3. So analyzing the 3 wouldn't be really needed.

by on (#3704)
My encoder works on the same brute force principle as the SoX MS ADPCM encoder I used as a base. No noise shaping, no smart crap, just pure brute force for the least mean square error, checking all scale factors and filter sets. (Or even no filter, in case that produces a better result.)

There are still some minor problems, especially if your sample peaks at or near the 16-bit signed integer limit. Try not to let that happen. :)

If you look at the source, you can also see that it has a feature for hinting the last block encoding so it will line up OK with the block you indicate as the loop start point. Notice that you'll have to make your loops a multiple of 16 samples in length, and you should probably pad the ends of your one-shot samples with at least 24 samples worth of silence.

The encoder in my foo_adpcm source code may be more up to date than the encoder in brrenc.c. It also includes my own PSX ADPCM / VAB encoder, almost identical in design, just different filters and block layout. Also XA ADPCM encoder, which produces full sectors with empty timestamps and ECC fields. (Heh, VAB is like a superset of XA ADPCM, one extra filter set, and of course it's not interleaved.)

Yadda, yadda. Maybe this information could go in a wiki somewhere...

by on (#3849)
thanks for the answers. sorry for not replying earilier. been busy with other stuff. hasn't happend to much on the code since my last message. I hope to do some more on it today. maybe I could have a release with full sourcecode of it in the end of the week if every thing goes as I want it to. will probably not be final version.. but always something. ;)