Kitty Corp Meow Mix Forums

Super Smash Bros. Brawl Hacking => Programming => Topic started by: Exagone313 on June 19, 2016, 06:19:26 AM



Title: [Project] (B)RSTM web player
Post by: Exagone313 on June 19, 2016, 06:19:26 AM
Hi,

I'm creating a RSTM player in Javascript (web), I found two pages to decode the header (1 (http://wiibrew.org/wiki/BRSTM_file) 2 (http://wiki.tockdom.com/wiki/BRSTM_%28File_Format%29)), and I miss a specification for the HEAD, ADPC and DATA parts, I'm not sure of what they contain. I know HEAD contains the data I can see in BrawlBox. Apparently ADPCM, is a type of wav, so it should be playable in a browser using the Javascript Audio API, I tried to read the DATA part in my browser and it couldn't be recognized (EDIT: fail it was late, I didn't cut enough). I'm not familiarized with c-sharp so I can't read the BrawlLib source code (here (https://github.com/libertyernie/brawltools/tree/master/BrawlLib/Wii/Audio)).

My main project is to create a player for the Pokémon GSC musics (looped songs), and I'd prefer to load the .brstm files instead of having 2 audio files that have to be converted, because most of Pokémon songs are available in .brstm on Smash Custom Music. If I succeed, that website could also use this player (I will think to the proper open source license for that.)

I'm also wondering about the right of having such songs downloadable, I think it's a copyright violation, if you could tell me something about it I'd appreciate.

Thanks for your help.

EDIT: Apparently 4-bit IMA ADPCM is not supported in any browsers, have to look into on-the-fly conversion :(

EDIT 2: Found this (http://www.cs.columbia.edu/~hgs/audio/dvi/) (page 34) and this (https://wiki.multimedia.cx/index.php?title=IMA_ADPCM). Just need to know what do I have to convert.


Title: Re: [Project] (B)RSTM web player
Post by: Segtendo on June 19, 2016, 09:54:48 AM
Soneek has told me he's looking for programmers to improve Smash Custom Music. A new previewer sounds like a good idea. Maybe get in contact with him somehow once your plan has come to fruition?


Title: Re: [Project] (B)RSTM web player
Post by: Exagone313 on June 19, 2016, 11:05:48 AM
For now I'm just able to read the header, here is an example:

File Identifier: RSTM
Byte order: Big Endian
Version: 1.0
File size: 1286496
Header size: 64
Channels: 2
HEAD offset: 0x00 0x00 0x00 0x40 (64)
HEAD size: 256
ADPC offset: 0x00 0x00 0x01 0x40 (320)
ADPC size: 640
DATA offset: 0x00 0x00 0x03 0xc0 (960)
DATA size: 1285536
Other: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

I need to understand the three next blocks (HEAD, ADPC and DATA). The last two blocks are documented in one the link I provided above so I could get the sound. I have the algorithm that should (untested) permit to convert a sound into a playable format. I miss the HEAD part where I'll get the samples to cut the sound (?).


Title: Re: [Project] (B)RSTM web player
Post by: libertyernie on June 19, 2016, 02:43:25 PM
I don't entirely understand ADPCM myself, but I know both BrawlBox and vgmstream can play it (apparently vgmstream is a bit better, BrawlBox might have some slight clicks at block boundaries, though it's hard for me to tell.)
What language are you using on the server? If you can run C or C# code I bet you could have that convert BRSTM to WAV on request and send that to the browser.


Title: Re: [Project] (B)RSTM web player
Post by: Exagone313 on June 19, 2016, 05:14:34 PM
I decoded most of the HEAD part (by using the numbers displayed in BrawlBox), but I don't find if a song is looped or not (LoopStartSample can be zero for a looped song). Might have an idea but I'm not sure.
I don't understand the code of BrawlBox/BrawlLib so I can't use that, I would need your help for that.
I don't use any server, all is made in Javascript client-side. Normally it's possible, just have to get the algorithms. Web browsers can read 16-bit PCM and normally I can convert these 4-bit ADPCM into 16-bit PCM. I just don't know what to convert yet, and how channels are handled.

EDIT : Yeah, vgmstream really helps. I can read this code (https://github.com/kode54/vgmstream/blob/master/src/meta/brstm.c).


Title: Re: [Project] (B)RSTM web player
Post by: libertyernie on June 20, 2016, 08:12:12 PM
If this helps, here's what BrawlLib uses for StrmDataInfo, which is near the start of HEAD:
Code:
        public byte _encoding; // part of AudioFormatInfo
        public byte _looped; // part of AudioFormatInfo
        public byte _channels; // part of AudioFormatInfo
        public byte _sampleRate24; // part of AudioFormatInfo
        public bushort _sampleRate;
        public bushort _blockHeaderOffset;
        public bint _loopStartSample;
        public bint _numSamples;
        public bint _dataOffset;
        public bint _numBlocks;
        public bint _blockSize;
        public bint _samplesPerBlock; //0x3800
        public bint _lastBlockSize; //Without padding
        public bint _lastBlockSamples;
        public bint _lastBlockTotal; //Includes padding
        public bint _dataInterval; //0x3800
        public bint _bitsPerSample;



Title: Re: [Project] (B)RSTM web player
Post by: Exagone313 on June 21, 2016, 02:11:27 PM
It's hard to read the vgmstream code, but I feel it contains everything. I am just not sure yet I will be able to play songs.


Title: Re: [Project] (B)RSTM web player
Post by: Exagone313 on June 23, 2016, 03:13:15 PM
Ok I think I'm gonna give up with vgmstream and get back to brawllib/brawlbox. I need the decoding algorithms. If you can help me by sending me the file names (and the arguments the functions need), or I will check that in a few days. Thanks.


Title: Re: [Project] (B)RSTM web player
Post by: libertyernie on June 24, 2016, 10:33:30 AM
I'd start in ADPCMStream.GetStreams (line 27 of ADPCMStream.cs (https://github.com/libertyernie/brawltools/blob/master/BrawlLib/Wii/Audio/ADPCMStream.cs)). It takes a pointer to the RSTM header and returns an array of streams (usually there is just one, and it can be mono or stereo.) The ADPCMStream object you get back has methods like ReadSamples, SamplePosition, etc.

ADPCMState (https://github.com/libertyernie/brawltools/blob/master/BrawlLib/Wii/Audio/ADPCMState.cs) looks like it has the core ADPCM decoding logic.