diff --git a/doc/TXTH.md b/doc/TXTH.md index 77e83d78..98f4e8ff 100644 --- a/doc/TXTH.md +++ b/doc/TXTH.md @@ -140,6 +140,8 @@ as explained below, but often will use default values. Accepted codec strings: # * Variation with modified encoding # - OKI16 OKI ADPCM with 16-bit output (not VOX/Dialogic 12-bit) # * For rare PS2 games (Sweet Legacy, Hooligan) +# - OKI4S OKI ADPCM with 16-bit output and adjusted tables +# * For later Konami rhythm games # - AAC Advanced Audio Coding (raw without .mp4) # * For some 3DS games and many iOS games # * Should set skip_samples (around 1024 but varies) @@ -443,7 +445,7 @@ While you can put anything in the values, this feature is meant to be used to st You can set a default offset that affects next `@(offset)` reads making them `@(offset + base_offset)`, for cleaner parsing. This is particularly interesting when combined with offsets to some long value. For example instead of `channels = @0x714` you could set `base_offset = 0x710, channels = @0x04`. Or values from the `name_table`, like `base_offset = name_value, channels = @0x04`. - + It also allows parsing formats that set offsets to another offset, by "chaining" `base_offset`. With `base_offset = @0x10` (pointing to `0x40`) then `base_offset = @0x20`, it reads value at `0x60`. Set to 0 when you want to disable/reset the chain: `base_offset = @0x10` then `base_offset = 0` then `base_offset = @0x20` reads value at `0x20` diff --git a/src/coding/oki_decoder.c b/src/coding/oki_decoder.c index 35280681..10b64a9e 100644 --- a/src/coding/oki_decoder.c +++ b/src/coding/oki_decoder.c @@ -197,7 +197,7 @@ void decode_oki4s(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing stream->offset + i : /* stereo: one nibble per channel */ stream->offset + i/2; /* mono: consecutive nibbles (assumed) */ int nibble_shift = - is_stereo ? (!(channel&1) ? 0:4) : (!(i&1) ? 0:4); /* even = low, odd = high */ + is_stereo ? (!(channel&1) ? 0:4) : ((i&1) ? 0:4); /* even = low, odd = high */ oki4s_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index, &out_sample); outbuf[sample_count] = (out_sample); diff --git a/src/meta/txth.c b/src/meta/txth.c index 958db9e4..230b1ad1 100644 --- a/src/meta/txth.c +++ b/src/meta/txth.c @@ -39,6 +39,7 @@ typedef enum { TGC = 29, /* Tiger Game.com 4-bit ADPCM */ ASF = 30, /* Argonaut ASF 4-bit ADPCM */ EAXA = 31, /* Electronic Arts EA-XA 4-bit ADPCM v1 */ + OKI4S = 32, /* OKI ADPCM with 16-bit output (unlike OKI/VOX/Dialogic ADPCM's 12-bit) */ } txth_type; typedef enum { DEFAULT, NEGATIVE, POSITIVE, INVERTED } txth_loop_t; @@ -226,6 +227,7 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { case PCM4: coding = coding_PCM4; break; case PCM4_U: coding = coding_PCM4_U; break; case OKI16: coding = coding_OKI16; break; + case OKI4S: coding = coding_OKI4S; break; case TGC: coding = coding_TGC; break; case ASF: coding = coding_ASF; break; case EAXA: coding = coding_EA_XA; break; @@ -337,6 +339,7 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { break; case coding_OKI16: + case coding_OKI4S: vgmstream->layout_type = layout_none; break; @@ -872,6 +875,7 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char * key, ch else if (is_string(val,"PCM4")) txth->codec = PCM4; else if (is_string(val,"PCM4_U")) txth->codec = PCM4_U; else if (is_string(val,"OKI16")) txth->codec = OKI16; + else if (is_string(val,"OKI4S")) txth->codec = OKI4S; else if (is_string(val,"AAC")) txth->codec = AAC; else if (is_string(val,"TGC")) txth->codec = TGC; else if (is_string(val,"GCOM_ADPCM")) txth->codec = TGC; @@ -1524,8 +1528,8 @@ static int parse_name_table(txth_header* txth, char * name_list) { //;VGM_LOG("TXTH: compare name '%s'\n", key); /* parse values if key (name) matches default ("") or filename with/without extension */ - if (key[0]=='\0' - || is_string_match(filename, key) + if (key[0]=='\0' + || is_string_match(filename, key) || is_string_match(basename, key) || is_string_match(fullname, key)) { int n; @@ -1790,6 +1794,7 @@ static int get_bytes_to_samples(txth_header* txth, uint32_t bytes) { return yamaha_bytes_to_samples(bytes, txth->channels); case PCFX: case OKI16: + case OKI4S: return oki_bytes_to_samples(bytes, txth->channels); /* untested */