Takes a disc image file of Sly 2 or Sly 3 (including some of the demos), and lets you listen to (and download, raw or rendered to wav) all of its streamed music and ambient tracks.
No because you're not uploading anything anywhere. This page does all the work locally, in your browser (preferably Firefox), without relying on a server (except for loading this page and its scripts).
It's a bit like vgmstream's web player, but in pure javascript.
Because this page is made for a specific format used in Sly 2 and 3, and I had to manually find and classify each track. These games in particular have their entire file structure hidden, so searching for them is not as easy as opening a folder and reading a name.
Yes if you put this file in the same directory and rename it ".kpv.txth" (dots are important).
Read more about vgmstream's TXTH files on their github
discIdPromise
).knownIDs
at the end of slyDiscMusic_data.js),playTrack
)renderAdpcmToWav
).Yes (see slyDiscMusic_io.js, function loadFileDataPromise
)
interpretTrackHeader
in slyDiscMusic_play.js):
Offset | Format | Value | Notes |
---|---|---|---|
0x000 | ascii string | " KPV" (0x20 0x4B 0x50 0x56) | |
0x004 | Uint32 LE | length : number of used bytes per channel | each channel occupies an integer number of 0x800 sectors, so this value should be rounded up to get the actual file size |
0x008 | Uint32 LE | Unknown (sector size?), always 0x800 | |
0x00C | Uint32 LE | interleave*2 : double of channel interleave | Usually 0x2000, meaning that channels alternate every 0x1000 bytes. |
0x010 | Uint32 LE | sampleRate | |
0x014 | Uint32 LE | channels | |
0x018 | byte⁠[channels]⁠[4] | channel mapping | see below |
0x7FC | Uint32 LE | loop : byte offset of loop start point in each channel |
Byte 0 | Byte 1 | Uint16 LE |
---|---|---|
0x7F | Layer number | 0x0000 for Mono layers,0x005A and 0x010E to couple 2 channels into a Stereo layer |
psxApcmDecoder
in streamGen.js, based on vgmstream implementation)Byte 0 | Byte 1 | Bytes 2...15 |
---|---|---|
Low Nibble: shift High Nibble: coef | Flags (unused) | 28 signed nibbles (low before high): minisample snew sample = minisample <<(12-shift )+ prev[0]*coefTable[0][ coef ]+ prev[1]*coefTable[1][ coef ] |
where "coefTable" is the same as the one given in vgmstream, "prev[n]" are the previous output samples that you must keep track of when decoding. |
0xC0 00 00 00 ...
).