Gamecube .HPS music by nifanatic at 7:55 PM EDT on September 5, 2009
Been trying to do some GCN/Smash Bros. Melee music editing, but I can't seem to nail .hps format. Would anyone happen to know how it's possible to convert, say, WAV files into working HPS files that can run in-game?
by TRG at 10:47 PM EDT on September 5, 2009
Oh, and a GC iso program that allows larger files to replace smaller files would be nice, like with Wii Scrubber. Otherwise the music possibilities are very limited.
by hcs at 11:33 PM EDT on September 5, 2009
I don't know of any existing tools for creating HPS, but it shouldn't be hard to make one. It'd require DSP format input, though, as with dkdsp or revb.
This does not mean that I'm working on such a thing.
by god at 7:18 PM EDT on September 7, 2009
Do you have written documentation on the HALPST format, hcs? I was able to get a cached version of the DSP information from a "wiki" off of the sourceforge page, but now everything with a url pointing to this wiki sends me to the sourceforge mainpage. Do you have the original documentation? I'm interested in trying to make a WAV -> HPS converter.
HPS (HALPST) format info by hcs at 9:11 PM EDT on September 7, 2009
I've still got a dump of the wiki, looks like I never put up anything interesting about HALPST.
vgmstream itself is probably the best documentation around, here's a rundown of what I see now:

(integers are big endian)
0x00-0x07: " HALPST\0" // magic
0x08-0x0B: sample rate
0x0C-0x0F: channel count

channel info (left channel 0x10-0x47, right channel 0x48-0x7F):
0x00-0x03: maximum block size (all channels)
0x04-0x07: 2? loop start? channel count?
0x08-0x0b: nibble count
0x0c-0x0f: 2? start nibble? channel count?
0x10-0x2f: DSP decode coefficients
0x30-0x31: 0? gain?
0x32-0x33: initial P/S
0x34-0x35: 0? initial hist1?
0x36-0x37: 0? initial hist2?

block structure (blocks start at 0x80):
0x00-0x03: block size (all channels)
0x04-0x07: last nibble in block to play?
0x08-0x0b: next block offset (looping implemented this way!)
0x0C-0x13: left channel decode state
0x14-0x1B: right channel decode state
0x1C-0x1F: 0? padding?
Then the left channel starts, and the right channel starts halfway through the block.

per block per channel initial decode state:
0x00-0x01: initial P/S
0x02-0x03: initial hist1?
0x04-0x05: initial hist2?
0x06-0x07: 0? gain? padding?

Oh, and I should note that nonlooping tracks are indicated by a 0xFFFFFFFF for the last "next block". Also mono HPSes are possible (and if you don't have a way of inserting larger files you might try this to save space), but I don't recall what game had them to check against this info.

edited 9:25 PM EDT September 7, 2009

edited 9:41 PM EDT September 7, 2009

So after looking at it for a little I've decided to go ahead and make a revb-type utility for this format. I'll post when it's done.

edited 10:03 PM EDT September 7, 2009
by god at 11:05 PM EDT on September 7, 2009
Thanks for all that info. It's pretty much what I gathered by looking through vgmstream. My issue is understanding the bitwise operations when decoding the blocks. :/
A revb, halpst style, would be absolutely great. I'd be very impressed..and grateful. Keep it up.
by bxaimc at 8:48 AM EDT on September 9, 2009
I still don't understand the hps spec.....it's a bit weird thanks to HAL...
anyway, here's my attempt at hps making by hand:
hpstest4.hps
edit: fixed nibble count

edited 9:09 AM EDT September 9, 2009
by nifanatic at 9:46 PM EDT on September 9, 2009
Good show, bxaimc... But the only unfortunate thing is, won't be able to test than in Melee due to how massive the size is. I can only replace themes that are of equal to less KB size as the song I'm wanting to replace. Nothing comes close to 10MB, last I checked. If you could find a way of shrinking... that'd be great.
by hcs at 10:02 PM EDT on September 9, 2009
Wouldn't work anyway, I'm almost certain the block size would make their driver throw a fit.
by bxaimc at 5:23 PM EDT on September 10, 2009
Yea, my file was only a test of the format. If you wanted it to work on melee, the block spliting is key.
by nifanatic at 7:43 PM EDT on September 12, 2009
In any case, with voice replacements being worked on as well, having something to work with HPS files would be a godsend... Appreciate you taking up making something for it, hcs. :)

edited 10:31 PM EDT September 12, 2009
by god at 11:21 PM EDT on October 11, 2009
Under the "block info" section from an earlier post by hcs, there's this:
0x0C-0x13: left channel decode state
0x14-0x1B: right channel decode state

How are the decode states determined for HPS files given the DSP that it's playing for each block? Not changing them when inserting custom DSPs doesn't seem to affect the performance of the new HPS, but I'd like to be as accurate as possible.
by hcs at 2:21 AM EDT on October 12, 2009
I don't know if those states are actually used by the decoder, but the test program I wrote confirms that those are the accurate values at the start of each block.
The state breaks down as follows:
0-1: initial p/s (this is simply the first byte of the channel)
2-3: initial history 1
4-5: initial history 2
6-7: 0?

The histories are computed by decoding the previous block and seeing what the last two samples were.

Note: I can post what code I have now if you're interested, but note that it's only in the "check existing .hps" stage.

edited 10:44 AM EDT October 12, 2009
by god at 1:17 PM EDT on October 12, 2009
Cool, I was just wondering how it affected the HPS while decoding. I understand the histories, etc.

I wrote a program that runs dspadpcm and inserts the DSPs created into a temp.hps file. I found out at first that I had made an error with those decoder states (I just didn't include them in the block headers), so I wondered what use they had.

I'd be interested in the code. I think I could learn a few things.
by hcs at 3:09 PM EDT on October 12, 2009
Here ya go, heed the readme.
[edit]
Bah, miswrite in said readme, it should say that the history tests should only be skipped on the loop check pass.

edited 3:20 PM EDT October 12, 2009
Updated as a result.

edited 3:22 PM EDT October 12, 2009
by god at 12:34 AM EST on November 17, 2009
Bumping this up.

hcs says:
"The histories are computed by decoding the previous block and seeing what the last two samples were."

Can you clear up how this is done?
I'd like to perfect this HPS substitution program I have, which currently skips over the decoder states without changing them. The audio works, but there are pops and cracks at some points in the music when it's played ingame.

When I read this, I thought you meant that the last 8 bytes from each block were repeated as the decoder states (histories), but when I checked some of the original HPS files from the game, I couldn't find any evidence of that. There seems to be some calculation done to figure these values out.
by hcs at 3:42 AM EST on November 17, 2009
Take a look at the loop at line 459, that's what does the decoding. Then the final values at info[c].state.hist1 and hist2 should be in the header of the next block (though this does not hold for the loop, apparently).

edited 3:44 AM EST November 17, 2009
by god at 10:09 AM EST on November 17, 2009
Thanks.
So the decode_dsp_nowhere() will crank out the hist1 and hist2 for the block. I didn't see that at first. Thank you.
May I use this code (with a few changes) in my program?
by hcs at 11:25 AM EST on November 17, 2009
You're welcome to it. I'd like to see source to the result, but I don't demand it.
by Decipio at 6:09 AM EDT on March 24, 2016
Hey hcs, I know this is an old topic but do you mind if I take hcshps and use it for pretty much the same exact reason that god was using it? If I get it to work I would of course give you credit for the parts that you did and can show you the source.
by hcs at 1:11 PM EDT on March 24, 2016
Go for it!
by Kurausukun at 4:10 AM EDT on March 25, 2016
This thread just reminded me, I need to bug soneek to release whatever he's using to convert between Nintendo dsp formats on SCM in some usable format. Unless he's already done that, and I'm just way behind (but I doubt it).
by Decipio at 8:45 PM EDT on March 29, 2016
Alright.. so originally, I was running into an issue with Nintendont's audio using custom HPS files and thought that the issue was due to incorrect decoder states in the block headers of my custom HPS files. I created an option in hcshps that fixed (or at least it seems to fix) those decoder states in block headers given an input HPS file, but files that I patched using this new option still didn't fix the audio issue that I was running into with Nintendont. I figured out that it had to do with block size. I made a post about it here:

http://smashboards.com/threads/fixing-hps-files-to-prevent-random-instances-of-silence-when-used-with-nintendont.434039/
by hcs at 9:06 PM EDT on March 29, 2016
Good to know about the block size, it's scary how tightly tuned these drivers can be.

Re: looping, iirc the original .HPS files use smaller blocks at the loop point so that they can loop more accurately, so you can probably get away with it like that if you want easier looping.


Go to Page 0

Search this thread

Show all threads

Reply to this thread:

User Name Tags:

bold: [b]bold[/b]
italics: [i]italics[/i]
emphasis: [em]emphasis[/em]
underline: [u]underline[/u]
small: [small]small[/small]
Link: [url=http://www.google.com]Link[/url]

[img=https://www.hcs64.com/images/mm1.png]
Password
Subject
Message

HCS Forum Index
Halley's Comet Software
forum source