Merge pull request #1361 from bnnm/fsbopus-txth

- Add FSB Opus [LEGO 2K Drive (Switch)]
- Add TXTH experimental 'subsong_sum' feature
- Add .wvd extension [Donkey Kong Barrel Blast (Wii)]
This commit is contained in:
bnnm 2023-05-29 00:40:02 +02:00 committed by GitHub
commit 2ffc539ccf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 121 additions and 81 deletions

View File

@ -87,6 +87,7 @@ static void usage(const char* progname, int is_help) {
" -v: validate extensions (for extension testing)\n"
" -r: reset and output a second file (for reset testing)\n"
" -k N: kills (seeks) N samples before decoding (for seek testing)\n"
" -2 seeks to loop start, -3 seeks to loop end\n"
" -K N: kills (seeks) again to N samples before decoding (for seek testing)\n"
" -t: print !tags found in !tags.m3u (for tag testing)\n"
" -T: print title (for title testing)\n"
@ -736,15 +737,24 @@ static int convert_file(cli_config* cfg) {
/* get final play config */
len_samples = vgmstream_get_samples(vgmstream);
if (len_samples <= 0)
if (len_samples <= 0) {
fprintf(stderr, "wrong time config\n");
goto fail;
}
if (cfg->seek_samples1 < -1) /* ex value for loop testing */
/* special values for loop testing */
if (cfg->seek_samples1 == -2) { /* loop start...end */
cfg->seek_samples1 = vgmstream->loop_start_sample;
if (cfg->seek_samples1 >= len_samples)
cfg->seek_samples1 = -1;
if (cfg->seek_samples2 >= len_samples)
cfg->seek_samples2 = -1;
}
if (cfg->seek_samples1 == -3) { /* loop end..end */
cfg->seek_samples1 = vgmstream->loop_end_sample;
}
/* would be ignored by seek code though (allowed for seek_samples2 to test this) */
if (cfg->seek_samples1 < -1 || cfg->seek_samples1 >= len_samples) {
fprintf(stderr, "wrong seek config\n");
goto fail;
}
if (cfg->play_forever && !vgmstream_get_play_forever(vgmstream)) {
fprintf(stderr, "file can't be played forever");

View File

@ -246,74 +246,85 @@ This list is not complete and many other files are supported.
Quick list of most codecs vgmstream supports, including many obscure ones that
are used in few games.
- PCM 16-bit
- PCM 8-bit (signed, unsigned)
- PCM 4-bit (signed, unsigned)
- PCM 32-bit float
- u-Law/a-LAW
- CRI ADX (standard, fixed, exponential, encrypted)
- Nintendo DSP ADPCM a.k.a GC ADPCM
- Nintendo DTK ADPCM
- Nintendo AFC ADPCM
- ITU-T G.721
- CD-ROM XA ADPCM
- Sony PSX ADPCM a.k.a VAG (standard, badflags, configurable, extended)
- Sony HEVAG
- Electronic Arts EA-XA (stereo, mono, Maxis)
- Electronic Arts EA-XAS (v0, v1)
- DVI/IMA ADPCM (stereo/mono + high/low nibble, 3DS, Quantic Dream, SNDS, etc)
- Microsoft MS IMA ADPCM (standard, Xbox, NDS, Radical, Wwise, FSB, WV6, etc)
- Microsoft MS ADPCM (standard, Cricket Audio)
- Westwood VBR ADPCM
- Yamaha ADPCM (AICA, Aska)
- Procyon Studio ADPCM
- Level-5 0x555 ADPCM
- lsf ADPCM
- Konami MTAF ADPCM
- Konami MTA2 ADPCM
- Paradigm MC3 ADPCM
- FMOD FADPCM 4-bit ADPCM
- Konami XMD 4-bit ADPCM
- Platinum 4-bit ADPCM
- Argonaut ASF 4-bit ADPCM
- Tantalus 4-bit ADPCM
- Ocean DSA 4-bit ADPCM
- Circus XPCM ADPCM
- Circus XPCM VQ
- OKI 4-bit ADPCM (16-bit output, 4-shift, PC-FX)
- Ubisoft 4/6-bit ADPCM
- Tiger Game.com ADPCM
- LucasArts iMUSE VBR ADPCM
- CompressWave (CWav) Huffman ADPCM
- SDX2 2:1 Squareroot-Delta-Exact compression DPCM
- CBD2 2:1 Cuberoot-Delta-Exact compression DPCM
- Activision EXAKT SASSC DPCM
- Xilam DERF DPCM
- InterPlay ACM
- VisualArt's NWA
- Electronic Arts MicroTalk a.k.a. UTK or UMT
- Relic Codec
- CRI HCA
- tri-Ace PS2 Codec
- Xiph Vorbis (Ogg, FSB5, Wwise, OGL, Silicon Knights)
- MPEG MP1/2/3 (standard, AHX, XVAG, FSB, AWC, P3D, EA, etc)
- ITU-T G.722.1 annex C a.k.a. Polycom Siren 14 (Namco)
- ITU-T G.719 annex B a.k.a. Polycom Siren 22
- Electronic Arts EASpeex
- Electronic Arts EALayer3
- Electronic Arts EA-XMA
- Sony ATRAC3, ATRAC3plus
- Sony ATRAC9
- Microsoft XMA1/2
- Microsoft WMA v1, WMA v2, WMAPro
- AAC
- Bink
- AC3/SPDIF
- Xiph Opus (Ogg, Switch, EA, UE4, Exient)
- Xiph CELT (FSB)
- Musepack
- FLAC
- Inti Creates' Range / DCT codecs
- PCM
- PCM 16-bit (little endian, big endian)
- PCM 8-bit (signed, unsigned, sign bit)
- PCM 4-bit (signed, unsigned)
- PCM 24-bit (little endian, big endian)
- PCM 32-bit float
- u-Law/a-LAW
- ADPCM (BRR/XA-style)
- CD-ROM XA ADPCM
- Sony PSX ADPCM a.k.a VAG (standard, badflags, configurable, extended)
- CRI ADX (standard, fixed, exponential, encrypted)
- Silicon Graphics VADPCM
- Nintendo DSP ADPCM a.k.a GC ADPCM
- Nintendo DTK ADPCM
- Nintendo AFC ADPCM
- Microsoft MSADPCM (standard, mono, Cricket Audio)
- Electronic Arts EA-XA (stereo, mono, Maxis)
- Electronic Arts EA-XAS (v0, v1)
- Konami MTAF ADPCM
- Konami MTA2 ADPCM
- FMOD FADPCM ADPCM
- Procyon Studio ADPCM
- Level-5 0x555 ADPCM
- Konami XMD ADPCM
- Argonaut ASF ADPCM
- Tantalus ADPCM
- ADPCM (IMA-style)
- DVI/IMA ADPCM (stereo/mono + high/low nibble, 3DS, Quantic Dream, SNDS, etc)
- Microsoft MS-IMA ADPCM (standard, Xbox, NDS, Radical, Wwise, FSB, WV6, etc)
- Yamaha ADPCM (AICA, Aska)
- Westwood VBR ADPCM
- OKI ADPCM (16-bit output, 4-shift, PC-FX)
- LucasArts iMUSE VBR ADPCM
- Tiger Game.com ADPCM
- ADPCM (others)
- Sony HEVAG
- Ubisoft 4/6-bit ADPCM
- Platinum ADPCM
- Paradigm MC3 ADPCM
- Ocean DSA ADPCM
- lsf ADPCM
- ITU-T G.721
- CompressWave (CWav) Huffman ADPCM
- Perceptual/transform-based
- MPEG MP1/2/3 (standard, AHX, XVAG, FSB, AWC, P3D, EA, etc)
- Xiph Vorbis (Ogg, FSB, Wwise, OGL, Silicon Knights)
- CRI HCA
- ITU-T G.722.1 annex C a.k.a. Polycom Siren 14 (Namco)
- ITU-T G.719 annex B a.k.a. Polycom Siren 22
- Xiph Opus (Ogg, Switch, EA, UE4, Exient, FSB)
- Xiph CELT (FSB)
- Microsoft XMA1/2
- Microsoft WMA v1, WMA v2, WMAPro
- AAC
- Sony ATRAC3
- Sony ATRAC3plus
- Sony ATRAC9
- Relic Codec
- tri-Ace PS2 Codec
- Bink
- AC3/SPDIF
- Musepack
- Electronic Arts EASpeex
- Electronic Arts EALayer3
- Electronic Arts EA-XMA
- Electronic Arts MicroTalk a.k.a. UTK or UMT
- Inti Creates DCT codec
- Circus XPCM VQ
- Misc
- SDX2 2:1 Squareroot-Delta-Exact compression DPCM
- CBD2 2:1 Cuberoot-Delta-Exact compression DPCM
- Activision EXAKT SASSC DPCM
- Xilam DERF DPCM
- Circus XPCM DPCM
- VisualArt's NWA PCM/DPCM
- Marble WADY PCM/DPCM
- InterPlay ACM
- Inti Creates Range codec
- FLAC
- Others
Sometimes standard codecs come in non-standard layouts that aren't normally

View File

@ -53,8 +53,7 @@ The following can be used in place of `(value)` for `(key) = (value)` commands.
* `:LE|BE`: value is little/big endian (optional, defaults to LE)
* `$1|2|3|4`: value has size of 8/16/24/32 bit (optional, defaults to 4)
* Example: `@0x10:BE$2` means `get big endian 16b value at 0x10`
- `(field)`: uses current value of some fields. Accepted strings:
- `interleave, interleave_last, channels, sample_rate, start_offset, data_size, num_samples, loop_start_sample, loop_end_sample, subsong_count, subsong_spacing, subfile_offset, subfile_size, base_offset, name_valueX`
- `(field)`: uses current value of some fields (`interleave`, `channels`, `start_offset`, `data_size`, `num_samples`, `subsong_count`, `subfile_size`, `base_offset`, `name_valueX`, etc)
- `subsong` is a special field for current subsong
- `(other)`: other special values for certain keys, described per key
@ -419,12 +418,14 @@ Sets the number of subsongs in the file, adjusting reads per subsong N: `value =
Instead of `subsong_spacing` you can use `subsong_offset` (older alias).
Mainly for bigfiles with consecutive headers per subsong, set subsong_offset to 0 when done as it affects any reads. The current subsong number is handled externally by plugins or TXTP.
Mainly for bigfiles with consecutive headers per subsong, set `subsong_offset` to 0 when done as it affects any reads. The current subsong number is handled externally by plugins or TXTP.
```
subsong_count = (value)
subsong_spacing = (value)
```
A experimental field is `subsong_sum = (value)`, that sums all subsong values up to current subsong. Mainly meant when offsets are the sum of subsong sizes: if you have a table of sizes at 0x10 for 3 subsongs, each of size 0x1000, then `subsong_sum = @0x10` for first subsong sums 0x0000, 0x1000 for second, 0x2000 for third (can be used later as `start_offset = subsong_sum`).
#### NAMES
Sets the name of the stream, most useful when used with subsongs. TXTH will read a string at `name_offset`, with `name_size characters`.

View File

@ -639,6 +639,7 @@ static const char* extension_list[] = {
"wua",
"wv2",
"wv6",
"wvd", //txth/reserved [Donkey Kong Barrel Blast (Wii)]
"wve",
"wvs",
"wvx",

View File

@ -488,10 +488,9 @@ VGMSTREAM* init_vgmstream_fsb5(STREAMFILE* sf) {
vgmstream->interleave_block_size = 0x8c;
break;
#if 0 //disabled until some game is found, can be created in the GUI tool
#ifdef VGM_USE_FFMPEG
case 0x11: { /* FMOD_SOUND_FORMAT_OPUS */
int skip = 312; //fsb_opus_get_encoder_delay(fsb5.stream_offset, sb); /* returns 120 but this seems correct */
case 0x11: { /* FMOD_SOUND_FORMAT_OPUS [LEGO 2K Drive (Switch)] */
int skip = 312; //fsb_opus_get_encoder_delay(fsb5.stream_offset, sb); /* returns 120 but this seems correct in test files */
//vgmstream->num_samples -= skip;
vgmstream->codec_data = init_ffmpeg_fsb_opus(sb, fsb5.stream_offset, fsb5.stream_size, vgmstream->channels, skip, vgmstream->sample_rate);
@ -500,7 +499,6 @@ VGMSTREAM* init_vgmstream_fsb5(STREAMFILE* sf) {
vgmstream->layout_type = layout_none;
break;
}
#endif
#endif
default:
vgm_logi("FSB5: unknown codec 0x%x (report)\n", fsb5.codec);

View File

@ -116,6 +116,7 @@ typedef struct {
int target_subsong;
uint32_t subsong_count;
uint32_t subsong_spacing;
uint32_t subsong_sum;
uint32_t name_offset_set;
uint32_t name_offset;
@ -1300,6 +1301,23 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha
else if (is_string(key,"subsong_spacing") || is_string(key,"subsong_offset")) {
if (!parse_num(txth->sf_head,txth,val, &txth->subsong_spacing)) goto fail;
}
else if (is_string(key,"subsong_sum")) {
/* add all values up to current subsong (for example, to add all sizes to get current offset, so get start_offset)
* doesn't include current (that is, reading size from fist subsong doesn't add anything) */
int default_subsong = txth->target_subsong;
uint32_t subsong_sum = 0;
for (int i = 0; i < default_subsong - 1; i++) {
txth->target_subsong = i + 1;
if (!parse_num(txth->sf_head,txth,val, &subsong_sum)) goto fail;
txth->subsong_sum += subsong_sum;
}
txth->target_subsong = default_subsong;
}
else if (is_string(key,"name_offset")) {
if (!parse_num(txth->sf_head,txth,val, &txth->name_offset)) goto fail;
txth->name_offset_set = 1;
@ -2001,6 +2019,7 @@ static int parse_num(STREAMFILE* sf, txth_header* txth, const char* val, uint32_
else if ((n = is_string_field(val,"subsong_count"))) value = txth->subsong_count;
else if ((n = is_string_field(val,"subsong_spacing"))) value = txth->subsong_spacing;
else if ((n = is_string_field(val,"subsong_offset"))) value = txth->subsong_spacing;
else if ((n = is_string_field(val,"subsong_sum"))) value = txth->subsong_sum;
else if ((n = is_string_field(val,"subfile_offset"))) value = txth->subfile_offset;
else if ((n = is_string_field(val,"subfile_size"))) value = txth->subfile_size;
else if ((n = is_string_field(val,"base_offset"))) value = txth->base_offset;