mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-17 19:19:16 +01:00
Allow TXTH codec strings in name_table
This commit is contained in:
parent
7400112fbe
commit
47132ece19
@ -449,7 +449,7 @@ Inside the table you define lines mapping a filename to a bunch of values, in th
|
||||
# put no name before the : to set default values
|
||||
: (value1), (...), (valueN)
|
||||
```
|
||||
Then I'll find your current file name, and you can then reference its numbers from the list as a `name_value` field, like `base_offset = name_value`, `start_offset = 0x1000 + name_value1`, `interleave = name_value5`, etc. `(filename)` can be with or without extension (like `bgm01.vag` or just `bgm01`), and if the file's name isn't found it'll use default values, and if those aren't defined you'll get 0 instead. Being "values" they can use math or offsets too (`bgm05: 5*0x010`).
|
||||
Then I'll find your current file name, and you can then reference its numbers from the list as a `name_value` field, like `base_offset = name_value`, `start_offset = 0x1000 + name_value1`, `interleave = name_value5`, etc. `(filename)` can be with or without extension (like `bgm01.vag` or just `bgm01`), and if the file's name isn't found it'll use default values, and if those aren't defined you'll get 0 instead. Being "values" they can use math or offsets too (`bgm05: 5*0x010`). You can also set a codec string too (`bgm01: PCM16LE`; `codec = name_value`).
|
||||
|
||||
You can use wildcards to match multiple names too (it stops on first name that matches), and UTF-8 names should work, case insensitive even.
|
||||
```
|
||||
|
153
src/meta/txth.c
153
src/meta/txth.c
@ -40,12 +40,14 @@ typedef enum {
|
||||
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;
|
||||
|
||||
UNKNOWN = 99,
|
||||
} txth_codec_t;
|
||||
|
||||
typedef enum { DEFAULT, NEGATIVE, POSITIVE, INVERTED } txth_loop_t;
|
||||
|
||||
typedef struct {
|
||||
txth_type codec;
|
||||
txth_codec_t codec;
|
||||
uint32_t codec_mode;
|
||||
|
||||
uint32_t value_mul;
|
||||
@ -196,6 +198,25 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) {
|
||||
}
|
||||
|
||||
|
||||
/* set common interleaves to simplify usage
|
||||
* (maybe should ignore if manually overwritten, possibly with 0 on purpose?) */
|
||||
if (txth.interleave == 0) {
|
||||
uint32_t interleave = 0;
|
||||
switch(txth.codec) {
|
||||
case PSX: interleave = 0x10; break;
|
||||
case PSX_bf: interleave = 0x10; break;
|
||||
case NGC_DSP: interleave = 0x08; break;
|
||||
case PCM16LE: interleave = 0x02; break;
|
||||
case PCM16BE: interleave = 0x02; break;
|
||||
case PCM8: interleave = 0x01; break;
|
||||
case PCM8_U: interleave = 0x01; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
txth.interleave = interleave;
|
||||
}
|
||||
|
||||
|
||||
/* type to coding conversion */
|
||||
switch (txth.codec) {
|
||||
case PSX: coding = coding_PSX; break;
|
||||
@ -881,63 +902,61 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static txth_codec_t parse_codec(txth_header* txth, const char* val) {
|
||||
if (is_string(val,"PSX")) return PSX;
|
||||
else if (is_string(val,"XBOX")) return XBOX;
|
||||
else if (is_string(val,"NGC_DTK")) return NGC_DTK;
|
||||
else if (is_string(val,"DTK")) return NGC_DTK;
|
||||
else if (is_string(val,"PCM16BE")) return PCM16BE;
|
||||
else if (is_string(val,"PCM16LE")) return PCM16LE;
|
||||
else if (is_string(val,"PCM8")) return PCM8;
|
||||
else if (is_string(val,"SDX2")) return SDX2;
|
||||
else if (is_string(val,"DVI_IMA")) return DVI_IMA;
|
||||
else if (is_string(val,"MPEG")) return MPEG;
|
||||
else if (is_string(val,"IMA")) return IMA;
|
||||
else if (is_string(val,"AICA")) return AICA;
|
||||
else if (is_string(val,"MSADPCM")) return MSADPCM;
|
||||
else if (is_string(val,"NGC_DSP")) return NGC_DSP;
|
||||
else if (is_string(val,"DSP")) return NGC_DSP;
|
||||
else if (is_string(val,"PCM8_U_int")) return PCM8_U_int;
|
||||
else if (is_string(val,"PSX_bf")) return PSX_bf;
|
||||
else if (is_string(val,"MS_IMA")) return MS_IMA;
|
||||
else if (is_string(val,"PCM8_U")) return PCM8_U;
|
||||
else if (is_string(val,"APPLE_IMA4")) return APPLE_IMA4;
|
||||
else if (is_string(val,"ATRAC3")) return ATRAC3;
|
||||
else if (is_string(val,"ATRAC3PLUS")) return ATRAC3PLUS;
|
||||
else if (is_string(val,"XMA1")) return XMA1;
|
||||
else if (is_string(val,"XMA2")) return XMA2;
|
||||
else if (is_string(val,"FFMPEG")) return FFMPEG;
|
||||
else if (is_string(val,"AC3")) return AC3;
|
||||
else if (is_string(val,"PCFX")) return PCFX;
|
||||
else if (is_string(val,"PCM4")) return PCM4;
|
||||
else if (is_string(val,"PCM4_U")) return PCM4_U;
|
||||
else if (is_string(val,"OKI16")) return OKI16;
|
||||
else if (is_string(val,"OKI4S")) return OKI4S;
|
||||
else if (is_string(val,"AAC")) return AAC;
|
||||
else if (is_string(val,"TGC")) return TGC;
|
||||
else if (is_string(val,"GCOM_ADPCM")) return TGC;
|
||||
else if (is_string(val,"ASF")) return ASF;
|
||||
else if (is_string(val,"EAXA")) return EAXA;
|
||||
/* special handling */
|
||||
else if (is_string(val,"name_value")) return txth->name_values[0];
|
||||
else if (is_string(val,"name_value1")) return txth->name_values[0];
|
||||
else if (is_string(val,"name_value2")) return txth->name_values[1];
|
||||
else if (is_string(val,"name_value3")) return txth->name_values[2];
|
||||
//todo rest (handle in function)
|
||||
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, char* val) {
|
||||
//;VGM_LOG("TXTH: key=%s, val=%s\n", key, val);
|
||||
|
||||
/* CODEC */
|
||||
if (is_string(key,"codec")) {
|
||||
if (is_string(val,"PSX")) txth->codec = PSX;
|
||||
else if (is_string(val,"XBOX")) txth->codec = XBOX;
|
||||
else if (is_string(val,"NGC_DTK")) txth->codec = NGC_DTK;
|
||||
else if (is_string(val,"DTK")) txth->codec = NGC_DTK;
|
||||
else if (is_string(val,"PCM16BE")) txth->codec = PCM16BE;
|
||||
else if (is_string(val,"PCM16LE")) txth->codec = PCM16LE;
|
||||
else if (is_string(val,"PCM8")) txth->codec = PCM8;
|
||||
else if (is_string(val,"SDX2")) txth->codec = SDX2;
|
||||
else if (is_string(val,"DVI_IMA")) txth->codec = DVI_IMA;
|
||||
else if (is_string(val,"MPEG")) txth->codec = MPEG;
|
||||
else if (is_string(val,"IMA")) txth->codec = IMA;
|
||||
else if (is_string(val,"AICA")) txth->codec = AICA;
|
||||
else if (is_string(val,"MSADPCM")) txth->codec = MSADPCM;
|
||||
else if (is_string(val,"NGC_DSP")) txth->codec = NGC_DSP;
|
||||
else if (is_string(val,"DSP")) txth->codec = NGC_DSP;
|
||||
else if (is_string(val,"PCM8_U_int")) txth->codec = PCM8_U_int;
|
||||
else if (is_string(val,"PSX_bf")) txth->codec = PSX_bf;
|
||||
else if (is_string(val,"MS_IMA")) txth->codec = MS_IMA;
|
||||
else if (is_string(val,"PCM8_U")) txth->codec = PCM8_U;
|
||||
else if (is_string(val,"APPLE_IMA4")) txth->codec = APPLE_IMA4;
|
||||
else if (is_string(val,"ATRAC3")) txth->codec = ATRAC3;
|
||||
else if (is_string(val,"ATRAC3PLUS")) txth->codec = ATRAC3PLUS;
|
||||
else if (is_string(val,"XMA1")) txth->codec = XMA1;
|
||||
else if (is_string(val,"XMA2")) txth->codec = XMA2;
|
||||
else if (is_string(val,"FFMPEG")) txth->codec = FFMPEG;
|
||||
else if (is_string(val,"AC3")) txth->codec = AC3;
|
||||
else if (is_string(val,"PCFX")) txth->codec = PCFX;
|
||||
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;
|
||||
else if (is_string(val,"ASF")) txth->codec = ASF;
|
||||
else if (is_string(val,"EAXA")) txth->codec = EAXA;
|
||||
else goto fail;
|
||||
|
||||
/* set common interleaves to simplify usage
|
||||
* (do it here to in case it's overwritten later, possibly with 0 on purpose) */
|
||||
if (txth->interleave == 0) {
|
||||
switch(txth->codec) {
|
||||
case PSX: txth->interleave = 0x10; break;
|
||||
case PSX_bf: txth->interleave = 0x10; break;
|
||||
case NGC_DSP: txth->interleave = 0x08; break;
|
||||
case PCM16LE: txth->interleave = 0x02; break;
|
||||
case PCM16BE: txth->interleave = 0x02; break;
|
||||
case PCM8: txth->interleave = 0x01; break;
|
||||
case PCM8_U: txth->interleave = 0x01; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
txth->codec = parse_codec(txth, val);
|
||||
if (txth->codec == UNKNOWN)
|
||||
goto fail;
|
||||
}
|
||||
else if (is_string(key,"codec_mode")) {
|
||||
if (!parse_num(txth->sf_head,txth,val, &txth->codec_mode)) goto fail;
|
||||
@ -1589,6 +1608,26 @@ static int read_name_table_keyval(txth_header* txth, const char* line, char* key
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_name_val(txth_header* txth, char* subval) {
|
||||
int ok;
|
||||
|
||||
ok = parse_num(txth->sf_head, txth, subval, &txth->name_values[txth->name_values_count]);
|
||||
if (!ok) {
|
||||
/* in rare cases may set codec */
|
||||
txth_codec_t codec = parse_codec(txth, subval);
|
||||
if (codec == UNKNOWN)
|
||||
goto fail;
|
||||
txth->name_values[txth->name_values_count] = codec;
|
||||
}
|
||||
txth->name_values_count++;
|
||||
if (txth->name_values_count >= 16) /* surely nobody needs that many */
|
||||
goto fail;
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_name_table(txth_header* txth, char* name_list) {
|
||||
STREAMFILE* sf_names = NULL;
|
||||
off_t txt_offset, file_size;
|
||||
@ -1666,9 +1705,7 @@ static int parse_name_table(txth_header* txth, char* name_list) {
|
||||
if (current[0] == ',')
|
||||
current++;
|
||||
|
||||
if (!parse_num(txth->sf_head,txth,subval, &txth->name_values[txth->name_values_count])) goto fail;
|
||||
txth->name_values_count++;
|
||||
if (txth->name_values_count >= 16) /* surely nobody needs that many */
|
||||
if (!parse_name_val(txth, subval))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -1920,7 +1957,7 @@ static int parse_num(STREAMFILE* sf, txth_header* txth, const char* val, uint32_
|
||||
//;VGM_LOG("TXTH: final result %u (0x%x)\n", result, result);
|
||||
return 1;
|
||||
fail:
|
||||
VGM_LOG("TXTH: error parsing num '%s'\n", val);
|
||||
//VGM_LOG("TXTH: error parsing num '%s'\n", val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user