From 4413d7b20f5e04cc74eda1bb5498ec566d4db725 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 14 Jun 2020 15:27:55 +0200 Subject: [PATCH 1/4] Cleanup --- src/meta/txth.c | 400 ++++++++++++++++++++++++------------------------ 1 file changed, 200 insertions(+), 200 deletions(-) diff --git a/src/meta/txth.c b/src/meta/txth.c index 0dbad5e1..5378a64a 100644 --- a/src/meta/txth.c +++ b/src/meta/txth.c @@ -120,61 +120,61 @@ typedef struct { int name_values_count; /* original STREAMFILE and its type (may be an unsupported "base" file or a .txth) */ - STREAMFILE *streamFile; + STREAMFILE* sf; int streamfile_is_txth; /* configurable STREAMFILEs and if we opened it (thus must close it later) */ - STREAMFILE *streamText; - STREAMFILE *streamHead; - STREAMFILE *streamBody; - int streamtext_opened; - int streamhead_opened; - int streambody_opened; + STREAMFILE* sf_text; + STREAMFILE* sf_head; + STREAMFILE* sf_body; + int sf_text_opened; + int sf_head_opened; + int sf_body_opened; } txth_header; -static VGMSTREAM *init_subfile(txth_header * txth); -static STREAMFILE * open_txth(STREAMFILE * streamFile); -static void clean_txth(txth_header * txth); -static int parse_txth(txth_header * txth); +static VGMSTREAM* init_subfile(txth_header* txth); +static STREAMFILE* open_txth(STREAMFILE* sf); +static void clean_txth(txth_header* txth); +static int parse_txth(txth_header* txth); /* TXTH - an artificial "generic" header for headerless streams. * Similar to GENH, but with a single separate .txth file in the dir and text-based. */ -VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; txth_header txth = {0}; coding_t coding; int i, j; /* accept .txth (should set body_file or will fail later) */ - if (check_extensions(streamFile, "txth")) { - txth.streamFile = streamFile; + if (check_extensions(sf, "txth")) { + txth.sf = sf; txth.streamfile_is_txth = 1; - txth.streamText = streamFile; - txth.streamHead = NULL; - txth.streamBody = NULL; - txth.streamtext_opened = 0; - txth.streamhead_opened = 0; - txth.streambody_opened = 0; + txth.sf_text = sf; + txth.sf_head = NULL; + txth.sf_body = NULL; + txth.sf_text_opened = 0; + txth.sf_head_opened = 0; + txth.sf_body_opened = 0; } else { /* accept base file (no need for ID or ext checks --if a companion .TXTH exists all is good). * player still needs to accept the streamfile's ext, so at worst rename to .vgmstream */ - STREAMFILE * streamText = open_txth(streamFile); - if (!streamText) goto fail; + STREAMFILE* sf_text = open_txth(sf); + if (!sf_text) goto fail; - txth.streamFile = streamFile; + txth.sf = sf; txth.streamfile_is_txth = 0; - txth.streamText = streamText; - txth.streamHead = streamFile; - txth.streamBody = streamFile; - txth.streamtext_opened = 1; - txth.streamhead_opened = 0; - txth.streambody_opened = 0; + txth.sf_text = sf_text; + txth.sf_head = sf; + txth.sf_body = sf; + txth.sf_text_opened = 1; + txth.sf_head_opened = 0; + txth.sf_body_opened = 0; } /* process the text file */ @@ -183,7 +183,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { /* special case of parsing subfiles */ if (txth.subfile_set) { - VGMSTREAM *subfile_vgmstream = init_subfile(&txth); + VGMSTREAM* subfile_vgmstream = init_subfile(&txth); clean_txth(&txth); return subfile_vgmstream; } @@ -234,7 +234,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { /* try to autodetect PS-ADPCM loop data */ if (txth.loop_flag_auto && coding == coding_PSX) { - txth.loop_flag = ps_find_loop_offsets(txth.streamBody, txth.start_offset, txth.data_size, txth.channels, txth.interleave, + txth.loop_flag = ps_find_loop_offsets(txth.sf_body, txth.start_offset, txth.data_size, txth.channels, txth.interleave, (int32_t*)&txth.loop_start_sample, (int32_t*)&txth.loop_end_sample); } @@ -251,7 +251,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { vgmstream->stream_size = txth.data_size; if (txth.name_offset_set) { size_t name_size = txth.name_size ? txth.name_size + 1 : STREAM_NAME_SIZE; - read_string(vgmstream->stream_name,name_size, txth.name_offset,txth.streamHead); + read_string(vgmstream->stream_name,name_size, txth.name_offset,txth.sf_head); } /* codec specific (taken from GENH with minimal changes) */ @@ -422,7 +422,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { if (txth.coef_table_set) coef = get_16bit(txth.coef_table + i*txth.coef_spacing + j*2); else - coef = read_16bit(txth.coef_offset + i*txth.coef_spacing + j*2, txth.streamHead); + coef = read_16bit(txth.coef_offset + i*txth.coef_spacing + j*2, txth.sf_head); vgmstream->ch[i].adpcm_coef[j] = coef; } } @@ -430,8 +430,8 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { goto fail; //IDK what is this /* for (j = 0; j < 8; j++) { - vgmstream->ch[i].adpcm_coef[j*2] = read_16bit(genh.coef_offset + i*genh.coef_spacing + j*2, txth.streamHead); - vgmstream->ch[i].adpcm_coef[j*2+1] = read_16bit(genh.coef_split_offset + i*genh.coef_split_spacing + j*2, txth.streamHead); + vgmstream->ch[i].adpcm_coef[j*2] = read_16bit(genh.coef_offset + i*genh.coef_spacing + j*2, txth.sf_head); + vgmstream->ch[i].adpcm_coef[j*2+1] = read_16bit(genh.coef_split_offset + i*genh.coef_split_spacing + j*2, txth.sf_head); } */ } @@ -444,8 +444,8 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { for (i = 0; i < vgmstream->channels; i++) { off_t offset = txth.hist_offset + i*txth.hist_spacing; - vgmstream->ch[i].adpcm_history1_16 = read_16bit(offset + 0x00, txth.streamHead); - vgmstream->ch[i].adpcm_history2_16 = read_16bit(offset + 0x02, txth.streamHead); + vgmstream->ch[i].adpcm_history1_16 = read_16bit(offset + 0x00, txth.sf_head); + vgmstream->ch[i].adpcm_history2_16 = read_16bit(offset + 0x02, txth.sf_head); } } @@ -454,7 +454,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { #ifdef VGM_USE_MPEG case coding_MPEG_layer3: vgmstream->layout_type = layout_none; - vgmstream->codec_data = init_mpeg(txth.streamBody, txth.start_offset, &coding, vgmstream->channels); + vgmstream->codec_data = init_mpeg(txth.sf_body, txth.start_offset, &coding, vgmstream->channels); if (!vgmstream->codec_data) goto fail; break; @@ -465,7 +465,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { if (txth.codec == FFMPEG || txth.codec == AC3 || txth.codec == AAC) { /* default FFmpeg */ - ffmpeg_data = init_ffmpeg_offset(txth.streamBody, txth.start_offset,txth.data_size); + ffmpeg_data = init_ffmpeg_offset(txth.sf_body, txth.start_offset,txth.data_size); if ( !ffmpeg_data ) goto fail; if (vgmstream->num_samples == 0) @@ -482,21 +482,21 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { block_align = txth.interleave; encoder_delay = txth.skip_samples; - ffmpeg_data = init_ffmpeg_atrac3_raw(txth.streamBody, txth.start_offset,txth.data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); + ffmpeg_data = init_ffmpeg_atrac3_raw(txth.sf_body, txth.start_offset,txth.data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); if (!ffmpeg_data) goto fail; } else if (txth.codec == ATRAC3PLUS) { int block_size = txth.interleave; bytes = ffmpeg_make_riff_atrac3plus(buf, sizeof(buf), vgmstream->num_samples, txth.data_size, vgmstream->channels, vgmstream->sample_rate, block_size, txth.skip_samples); - ffmpeg_data = init_ffmpeg_header_offset(txth.streamBody, buf,bytes, txth.start_offset,txth.data_size); + ffmpeg_data = init_ffmpeg_header_offset(txth.sf_body, buf,bytes, txth.start_offset,txth.data_size); if ( !ffmpeg_data ) goto fail; } else if (txth.codec == XMA1) { int xma_stream_mode = txth.codec_mode == 1 ? 1 : 0; bytes = ffmpeg_make_riff_xma1(buf, sizeof(buf), vgmstream->num_samples, txth.data_size, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode); - ffmpeg_data = init_ffmpeg_header_offset(txth.streamBody, buf,bytes, txth.start_offset,txth.data_size); + ffmpeg_data = init_ffmpeg_header_offset(txth.sf_body, buf,bytes, txth.start_offset,txth.data_size); if ( !ffmpeg_data ) goto fail; } else if (txth.codec == XMA2) { @@ -506,7 +506,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { block_count = txth.data_size / block_size; bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), vgmstream->num_samples, txth.data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - ffmpeg_data = init_ffmpeg_header_offset(txth.streamBody, buf,bytes, txth.start_offset,txth.data_size); + ffmpeg_data = init_ffmpeg_header_offset(txth.sf_body, buf,bytes, txth.start_offset,txth.data_size); if ( !ffmpeg_data ) goto fail; } else { @@ -518,7 +518,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { vgmstream->layout_type = layout_none; if (txth.codec == XMA1 || txth.codec == XMA2) { - xma_fix_raw_samples(vgmstream, txth.streamBody, txth.start_offset,txth.data_size, 0, 0,0); + xma_fix_raw_samples(vgmstream, txth.sf_body, txth.start_offset,txth.data_size, 0, 0,0); } else if (txth.skip_samples_set && txth.codec != ATRAC3) { /* force encoder delay */ ffmpeg_set_skip_samples(ffmpeg_data, txth.skip_samples); } @@ -547,7 +547,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { msd.loop_end_subframe = txth.loop_adjust >> 4; /* upper 4b: subframe where the loop ends, 0..3 */ } - xma_get_samples(&msd, txth.streamBody); + xma_get_samples(&msd, txth.sf_body); vgmstream->num_samples = msd.num_samples; if (txth.sample_type==1) { @@ -562,7 +562,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { vgmstream->allow_dual_stereo = 1; - if ( !vgmstream_open_stream(vgmstream,txth.streamBody,txth.start_offset) ) + if ( !vgmstream_open_stream(vgmstream,txth.sf_body,txth.start_offset) ) goto fail; clean_txth(&txth); @@ -574,10 +574,10 @@ fail: return NULL; } -static VGMSTREAM *init_subfile(txth_header * txth) { - VGMSTREAM *vgmstream = NULL; +static VGMSTREAM* init_subfile(txth_header* txth) { + VGMSTREAM* vgmstream = NULL; char extension[PATH_LIMIT]; - STREAMFILE * streamSubfile = NULL; + STREAMFILE* streamSubfile = NULL; if (txth->subfile_size == 0) { @@ -585,12 +585,12 @@ static VGMSTREAM *init_subfile(txth_header * txth) { txth->subfile_size = txth->data_size; else txth->subfile_size = txth->data_size - txth->subfile_offset; - if (txth->subfile_size + txth->subfile_offset > get_streamfile_size(txth->streamBody)) - txth->subfile_size = get_streamfile_size(txth->streamBody) - txth->subfile_offset; + if (txth->subfile_size + txth->subfile_offset > get_streamfile_size(txth->sf_body)) + txth->subfile_size = get_streamfile_size(txth->sf_body) - txth->subfile_offset; } if (txth->subfile_extension[0] == '\0') - get_streamfile_ext(txth->streamFile,txth->subfile_extension,sizeof(txth->subfile_extension)); + get_streamfile_ext(txth->sf,txth->subfile_extension,sizeof(txth->subfile_extension)); /* must detect a potential infinite loop: * - init_vgmstream enters TXTH and reads .txth @@ -602,7 +602,7 @@ static VGMSTREAM *init_subfile(txth_header * txth) { strcpy(extension, "subfile_txth."); strcat(extension, txth->subfile_extension); - streamSubfile = setup_subfile_streamfile(txth->streamBody, txth->subfile_offset, txth->subfile_size, extension); + streamSubfile = setup_subfile_streamfile(txth->sf_body, txth->subfile_offset, txth->subfile_size, extension); if (!streamSubfile) goto fail; vgmstream = init_vgmstream_from_STREAMFILE(streamSubfile); @@ -651,67 +651,67 @@ fail: } -static STREAMFILE * open_txth(STREAMFILE * streamFile) { +static STREAMFILE* open_txth(STREAMFILE* sf) { char basename[PATH_LIMIT]; char filename[PATH_LIMIT]; char fileext[PATH_LIMIT]; const char *subext; - STREAMFILE * streamText; + STREAMFILE* sf_text; /* try "(path/)(name.ext).txth" */ - get_streamfile_name(streamFile,filename,PATH_LIMIT); + get_streamfile_name(sf,filename,PATH_LIMIT); if (strstr(filename, "subfile_txth") != NULL) return NULL; /* detect special case of subfile-within-subfile */ strcat(filename, ".txth"); - streamText = open_streamfile(streamFile,filename); - if (streamText) return streamText; + sf_text = open_streamfile(sf,filename); + if (sf_text) return sf_text; /* try "(path/)(.sub.ext).txth" */ - get_streamfile_basename(streamFile,basename,PATH_LIMIT); + get_streamfile_basename(sf,basename,PATH_LIMIT); subext = filename_extension(basename); if (subext != NULL) { - get_streamfile_path(streamFile,filename,PATH_LIMIT); - get_streamfile_ext(streamFile,fileext,PATH_LIMIT); + get_streamfile_path(sf,filename,PATH_LIMIT); + get_streamfile_ext(sf,fileext,PATH_LIMIT); strcat(filename,"."); strcat(filename, subext); strcat(filename,"."); strcat(filename, fileext); strcat(filename, ".txth"); - streamText = open_streamfile(streamFile,filename); - if (streamText) return streamText; + sf_text = open_streamfile(sf,filename); + if (sf_text) return sf_text; } /* try "(path/)(.ext).txth" */ - get_streamfile_path(streamFile,filename,PATH_LIMIT); - get_streamfile_ext(streamFile,fileext,PATH_LIMIT); + get_streamfile_path(sf,filename,PATH_LIMIT); + get_streamfile_ext(sf,fileext,PATH_LIMIT); strcat(filename,"."); strcat(filename, fileext); strcat(filename, ".txth"); - streamText = open_streamfile(streamFile,filename); - if (streamText) return streamText; + sf_text = open_streamfile(sf,filename); + if (sf_text) return sf_text; /* try "(path/).txth" */ - get_streamfile_path(streamFile,filename,PATH_LIMIT); + get_streamfile_path(sf,filename,PATH_LIMIT); strcat(filename, ".txth"); - streamText = open_streamfile(streamFile,filename); - if (streamText) return streamText; + sf_text = open_streamfile(sf,filename); + if (sf_text) return sf_text; /* not found */ return NULL; } -static void clean_txth(txth_header * txth) { +static void clean_txth(txth_header* txth) { /* close stuff manually opened during parse */ - if (txth->streamtext_opened) close_streamfile(txth->streamText); - if (txth->streamhead_opened) close_streamfile(txth->streamHead); - if (txth->streambody_opened) close_streamfile(txth->streamBody); + if (txth->sf_text_opened) close_streamfile(txth->sf_text); + if (txth->sf_head_opened) close_streamfile(txth->sf_head); + if (txth->sf_body_opened) close_streamfile(txth->sf_body); } /* ****************************************************************** */ -static void set_body_chunk(txth_header * txth) { - STREAMFILE *temp_streamFile = NULL; +static void set_body_chunk(txth_header* txth) { + STREAMFILE* temp_sf = NULL; /* sets body "chunk" if all needed values are set * (done inline for padding/get_samples/etc calculators to work) */ @@ -720,7 +720,7 @@ static void set_body_chunk(txth_header * txth) { return; if (txth->chunk_size == 0 || txth->chunk_start > txth->data_size || txth->chunk_count == 0) return; - if (!txth->streamBody) + if (!txth->sf_body) return; /* treat chunks as subsongs */ @@ -741,20 +741,20 @@ static void set_body_chunk(txth_header * txth) { cfg.chunk_count = txth->chunk_count; cfg.chunk_number = txth->chunk_number - 1; /* 1-index to 0-index */ - temp_streamFile = setup_txth_streamfile(txth->streamBody, cfg, txth->streambody_opened); - if (!temp_streamFile) return; + temp_sf = setup_txth_streamfile(txth->sf_body, cfg, txth->sf_body_opened); + if (!temp_sf) return; } - /* closing is handled by temp_streamFile */ - //if (txth->streambody_opened) { - // close_streamfile(txth->streamBody); - // txth->streamBody = NULL; - // txth->streambody_opened = 0; + /* closing is handled by temp_sf */ + //if (txth->sf_body_opened) { + // close_streamfile(txth->sf_body); + // txth->sf_body = NULL; + // txth->sf_body_opened = 0; //} - txth->streamBody = temp_streamFile; - txth->streambody_opened = 1; + txth->sf_body = temp_sf; + txth->sf_body_opened = 1; /* cancel values once set, to avoid weirdness and possibly allow chunks-in-chunks? */ txth->chunk_start_set = 0; @@ -763,38 +763,38 @@ static void set_body_chunk(txth_header * txth) { /* re-apply */ if (!txth->data_size_set) { - txth->data_size = get_streamfile_size(txth->streamBody); + txth->data_size = get_streamfile_size(txth->sf_body); } } -static int parse_keyval(STREAMFILE * streamFile, txth_header * txth, const char * key, char * val); -static int parse_num(STREAMFILE * streamFile, txth_header * txth, const char * val, uint32_t * out_value); -static int parse_string(STREAMFILE * streamFile, txth_header * txth, const char * val, char * str); -static int parse_coef_table(STREAMFILE * streamFile, txth_header * txth, const char * val, uint8_t * out_value, size_t out_size); -static int parse_name_table(txth_header * txth, char * val); +static int parse_keyval(STREAMFILE* sf, txth_header* txth, const char * key, char * val); +static int parse_num(STREAMFILE* sf, txth_header* txth, const char * val, uint32_t * out_value); +static int parse_string(STREAMFILE* sf, txth_header* txth, const char * val, char * str); +static int parse_coef_table(STREAMFILE* sf, txth_header* txth, const char * val, uint8_t * out_value, size_t out_size); +static int parse_name_table(txth_header* txth, char * val); static int is_string(const char * val, const char * cmp); -static int get_bytes_to_samples(txth_header * txth, uint32_t bytes); -static int get_padding_size(txth_header * txth, int discard_empty); +static int get_bytes_to_samples(txth_header* txth, uint32_t bytes); +static int get_padding_size(txth_header* txth, int discard_empty); /* Simple text parser of "key = value" lines. * The code is meh and error handling not exactly the best. */ -static int parse_txth(txth_header * txth) { +static int parse_txth(txth_header* txth) { off_t txt_offset = 0x00; - off_t file_size = get_streamfile_size(txth->streamText); + off_t file_size = get_streamfile_size(txth->sf_text); /* setup txth defaults */ - if (txth->streamBody) - txth->data_size = get_streamfile_size(txth->streamBody); - txth->target_subsong = txth->streamFile->stream_index; + if (txth->sf_body) + txth->data_size = get_streamfile_size(txth->sf_body); + txth->target_subsong = txth->sf->stream_index; if (txth->target_subsong == 0) txth->target_subsong = 1; /* skip BOM if needed */ - if ((uint16_t)read_16bitLE(0x00, txth->streamText) == 0xFFFE || - (uint16_t)read_16bitLE(0x00, txth->streamText) == 0xFEFF) { + if ((uint16_t)read_16bitLE(0x00, txth->sf_text) == 0xFFFE || + (uint16_t)read_16bitLE(0x00, txth->sf_text) == 0xFEFF) { txt_offset = 0x02; } - else if (((uint32_t)read_32bitBE(0x00, txth->streamText) & 0xFFFFFF00) == 0xEFBBBF00) { + else if (((uint32_t)read_32bitBE(0x00, txth->sf_text) & 0xFFFFFF00) == 0xEFBBBF00) { txt_offset = 0x03; } @@ -804,36 +804,36 @@ static int parse_txth(txth_header * txth) { char key[TXT_LINE_MAX] = {0}, val[TXT_LINE_MAX] = {0}; /* at least as big as a line to avoid overflows (I hope) */ int ok, bytes_read, line_ok; - bytes_read = read_line(line, sizeof(line), txt_offset, txth->streamText, &line_ok); + bytes_read = read_line(line, sizeof(line), txt_offset, txth->sf_text, &line_ok); if (!line_ok) goto fail; //;VGM_LOG("TXTH: line=%s\n",line); txt_offset += bytes_read; - + /* get key/val (ignores lead spaces, stops at space/comment/separator) */ ok = sscanf(line, " %[^ \t#=] = %[^\t#\r\n] ", key,val); if (ok != 2) /* ignore line if no key=val (comment or garbage) */ continue; - if (!parse_keyval(txth->streamFile, txth, key, val)) /* read key/val */ + if (!parse_keyval(txth->sf, txth, key, val)) /* read key/val */ goto fail; } if (!txth->loop_flag_set) txth->loop_flag = txth->loop_end_sample && txth->loop_end_sample != 0xFFFFFFFF; - if (!txth->streamBody) + if (!txth->sf_body) goto fail; - if (txth->data_size > get_streamfile_size(txth->streamBody) - txth->start_offset || txth->data_size <= 0) - txth->data_size = get_streamfile_size(txth->streamBody) - txth->start_offset; + if (txth->data_size > get_streamfile_size(txth->sf_body) - txth->start_offset || txth->data_size <= 0) + txth->data_size = get_streamfile_size(txth->sf_body) - txth->start_offset; return 1; fail: return 0; } -static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char * key, char * val) { +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 */ @@ -891,29 +891,29 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char } } else if (is_string(key,"codec_mode")) { - if (!parse_num(txth->streamHead,txth,val, &txth->codec_mode)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->codec_mode)) goto fail; } /* VALUE MODIFIERS */ else if (is_string(key,"value_mul") || is_string(key,"value_*")) { - if (!parse_num(txth->streamHead,txth,val, &txth->value_mul)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->value_mul)) goto fail; } else if (is_string(key,"value_div") || is_string(key,"value_/")) { - if (!parse_num(txth->streamHead,txth,val, &txth->value_div)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->value_div)) goto fail; } else if (is_string(key,"value_add") || is_string(key,"value_+")) { - if (!parse_num(txth->streamHead,txth,val, &txth->value_add)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->value_add)) goto fail; } else if (is_string(key,"value_sub") || is_string(key,"value_-")) { - if (!parse_num(txth->streamHead,txth,val, &txth->value_sub)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->value_sub)) goto fail; } /* ID VALUES */ else if (is_string(key,"id_value")) { - if (!parse_num(txth->streamHead,txth,val, &txth->id_value)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->id_value)) goto fail; } else if (is_string(key,"id_offset")) { - if (!parse_num(txth->streamHead,txth,val, &txth->id_offset)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->id_offset)) goto fail; if (txth->id_value != txth->id_offset) /* evaluate current ID */ goto fail; } @@ -925,7 +925,7 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char txth->interleave = txth->data_size / txth->channels; } else { - if (!parse_num(txth->streamHead,txth,val, &txth->interleave)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->interleave)) goto fail; } } else if (is_string(key,"interleave_last")) { @@ -934,21 +934,21 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char txth->interleave_last = (txth->data_size % (txth->interleave * txth->channels)) / txth->channels; } else { - if (!parse_num(txth->streamHead,txth,val, &txth->interleave_last)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->interleave_last)) goto fail; } } /* BASE CONFIG */ else if (is_string(key,"channels")) { - if (!parse_num(txth->streamHead,txth,val, &txth->channels)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->channels)) goto fail; } else if (is_string(key,"sample_rate")) { - if (!parse_num(txth->streamHead,txth,val, &txth->sample_rate)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->sample_rate)) goto fail; } /* DATA CONFIG */ else if (is_string(key,"start_offset")) { - if (!parse_num(txth->streamHead,txth,val, &txth->start_offset)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->start_offset)) goto fail; /* apply */ @@ -959,7 +959,7 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char if (txth->subsong_count > 1 && txth->target_subsong < txth->subsong_count) { /* temp move to next start_offset and move back*/ txth->target_subsong++; - parse_num(txth->streamHead,txth,val, &txth->next_offset); + parse_num(txth->sf_head,txth,val, &txth->next_offset); txth->target_subsong--; if (txth->next_offset < txth->start_offset) txth->next_offset = 0; @@ -979,7 +979,7 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char txth->padding_size = get_padding_size(txth, 1); } else { - if (!parse_num(txth->streamHead,txth,val, &txth->padding_size)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->padding_size)) goto fail; } /* apply */ @@ -989,7 +989,7 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char } } else if (is_string(key,"data_size")) { - if (!parse_num(txth->streamHead,txth,val, &txth->data_size)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->data_size)) goto fail; txth->data_size_set = 1; } @@ -1006,7 +1006,7 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char txth->num_samples_data_size = 1; } else { - if (!parse_num(txth->streamHead,txth,val, &txth->num_samples)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->num_samples)) goto fail; if (txth->sample_type==1) txth->num_samples = get_bytes_to_samples(txth, txth->num_samples); if (txth->sample_type==2) @@ -1014,7 +1014,7 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char } } else if (is_string(key,"loop_start_sample")) { - if (!parse_num(txth->streamHead,txth,val, &txth->loop_start_sample)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->loop_start_sample)) goto fail; if (txth->sample_type==1) txth->loop_start_sample = get_bytes_to_samples(txth, txth->loop_start_sample); if (txth->sample_type==2) @@ -1027,7 +1027,7 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char txth->loop_end_sample = get_bytes_to_samples(txth, txth->data_size); } else { - if (!parse_num(txth->streamHead,txth,val, &txth->loop_end_sample)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->loop_end_sample)) goto fail; if (txth->sample_type==1) txth->loop_end_sample = get_bytes_to_samples(txth, txth->loop_end_sample); if (txth->sample_type==2) @@ -1037,7 +1037,7 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char txth->loop_end_sample += txth->loop_adjust; } else if (is_string(key,"skip_samples")) { - if (!parse_num(txth->streamHead,txth,val, &txth->skip_samples)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->skip_samples)) goto fail; txth->skip_samples_set = 1; if (txth->sample_type==1) txth->skip_samples = get_bytes_to_samples(txth, txth->skip_samples); @@ -1045,7 +1045,7 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char txth->skip_samples = get_bytes_to_samples(txth, txth->skip_samples * (txth->interleave*txth->channels)); } else if (is_string(key,"loop_adjust")) { - if (!parse_num(txth->streamHead,txth,val, &txth->loop_adjust)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->loop_adjust)) goto fail; if (txth->sample_type==1) txth->loop_adjust = get_bytes_to_samples(txth, txth->loop_adjust); if (txth->sample_type==2) @@ -1056,7 +1056,7 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char txth->loop_flag_auto = 1; } else { - if (!parse_num(txth->streamHead,txth,val, &txth->loop_flag)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->loop_flag)) goto fail; txth->loop_flag_set = 1; if (txth->loop_behavior == 0) { @@ -1087,33 +1087,33 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char /* COEFS */ else if (is_string(key,"coef_offset")) { - if (!parse_num(txth->streamHead,txth,val, &txth->coef_offset)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->coef_offset)) goto fail; /* special adjustments */ txth->coef_offset += txth->base_offset; if (txth->subsong_offset) txth->coef_offset += txth->subsong_offset * (txth->target_subsong - 1); } else if (is_string(key,"coef_spacing")) { - if (!parse_num(txth->streamHead,txth,val, &txth->coef_spacing)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->coef_spacing)) goto fail; } else if (is_string(key,"coef_endianness")) { if (is_string(val, "BE")) txth->coef_big_endian = 1; else if (is_string(val, "LE")) txth->coef_big_endian = 0; - else if (!parse_num(txth->streamHead,txth,val, &txth->coef_big_endian)) goto fail; + else if (!parse_num(txth->sf_head,txth,val, &txth->coef_big_endian)) goto fail; } else if (is_string(key,"coef_mode")) { - if (!parse_num(txth->streamHead,txth,val, &txth->coef_mode)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->coef_mode)) goto fail; } else if (is_string(key,"coef_table")) { - if (!parse_coef_table(txth->streamHead,txth,val, txth->coef_table, sizeof(txth->coef_table))) goto fail; + if (!parse_coef_table(txth->sf_head,txth,val, txth->coef_table, sizeof(txth->coef_table))) goto fail; txth->coef_table_set = 1; } /* HIST */ else if (is_string(key,"hist_offset")) { - if (!parse_num(txth->streamHead,txth,val, &txth->hist_offset)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->hist_offset)) goto fail; txth->hist_set = 1; /* special adjustment */ txth->hist_offset += txth->hist_offset; @@ -1121,25 +1121,25 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char txth->hist_offset += txth->subsong_offset * (txth->target_subsong - 1); } else if (is_string(key,"hist_spacing")) { - if (!parse_num(txth->streamHead,txth,val, &txth->hist_spacing)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->hist_spacing)) goto fail; } else if (is_string(key,"hist_endianness")) { if (is_string(val, "BE")) txth->hist_big_endian = 1; else if (is_string(val, "LE")) txth->hist_big_endian = 0; - else if (!parse_num(txth->streamHead,txth,val, &txth->hist_big_endian)) goto fail; + else if (!parse_num(txth->sf_head,txth,val, &txth->hist_big_endian)) goto fail; } /* SUBSONGS */ else if (is_string(key,"subsong_count")) { - if (!parse_num(txth->streamHead,txth,val, &txth->subsong_count)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->subsong_count)) goto fail; } else if (is_string(key,"subsong_offset")) { - if (!parse_num(txth->streamHead,txth,val, &txth->subsong_offset)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->subsong_offset)) goto fail; } else if (is_string(key,"name_offset")) { - if (!parse_num(txth->streamHead,txth,val, &txth->name_offset)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->name_offset)) goto fail; txth->name_offset_set = 1; /* special adjustment */ txth->name_offset += txth->base_offset; @@ -1147,82 +1147,82 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char txth->name_offset += txth->subsong_offset * (txth->target_subsong - 1); } else if (is_string(key,"name_size")) { - if (!parse_num(txth->streamHead,txth,val, &txth->name_size)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->name_size)) goto fail; } /* SUBFILES */ else if (is_string(key,"subfile_offset")) { - if (!parse_num(txth->streamHead,txth,val, &txth->subfile_offset)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->subfile_offset)) goto fail; txth->subfile_set = 1; } else if (is_string(key,"subfile_size")) { - if (!parse_num(txth->streamHead,txth,val, &txth->subfile_size)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->subfile_size)) goto fail; txth->subfile_set = 1; } else if (is_string(key,"subfile_extension")) { - if (!parse_string(txth->streamHead,txth,val, txth->subfile_extension)) goto fail; + if (!parse_string(txth->sf_head,txth,val, txth->subfile_extension)) goto fail; txth->subfile_set = 1; } /* HEADER/BODY CONFIG */ else if (is_string(key,"header_file")) { - if (txth->streamhead_opened) { - close_streamfile(txth->streamHead); - txth->streamHead = NULL; - txth->streamhead_opened = 0; + if (txth->sf_head_opened) { + close_streamfile(txth->sf_head); + txth->sf_head = NULL; + txth->sf_head_opened = 0; } if (is_string(val,"null")) { /* reset */ if (!txth->streamfile_is_txth) { - txth->streamHead = txth->streamFile; + txth->sf_head = txth->sf; } } else if (val[0]=='*' && val[1]=='.') { /* basename + extension */ - txth->streamHead = open_streamfile_by_ext(txth->streamFile, (val+2)); - if (!txth->streamHead) goto fail; - txth->streamhead_opened = 1; + txth->sf_head = open_streamfile_by_ext(txth->sf, (val+2)); + if (!txth->sf_head) goto fail; + txth->sf_head_opened = 1; } else { /* open file */ fix_dir_separators(val); /* clean paths */ - txth->streamHead = open_streamfile_by_filename(txth->streamFile, val); - if (!txth->streamHead) goto fail; - txth->streamhead_opened = 1; + txth->sf_head = open_streamfile_by_filename(txth->sf, val); + if (!txth->sf_head) goto fail; + txth->sf_head_opened = 1; } } else if (is_string(key,"body_file")) { - if (txth->streambody_opened) { - close_streamfile(txth->streamBody); - txth->streamBody = NULL; - txth->streambody_opened = 0; + if (txth->sf_body_opened) { + close_streamfile(txth->sf_body); + txth->sf_body = NULL; + txth->sf_body_opened = 0; } if (is_string(val,"null")) { /* reset */ if (!txth->streamfile_is_txth) { - txth->streamBody = txth->streamFile; + txth->sf_body = txth->sf; } } else if (val[0]=='*' && val[1]=='.') { /* basename + extension */ - txth->streamBody = open_streamfile_by_ext(txth->streamFile, (val+2)); - if (!txth->streamBody) goto fail; - txth->streambody_opened = 1; + txth->sf_body = open_streamfile_by_ext(txth->sf, (val+2)); + if (!txth->sf_body) goto fail; + txth->sf_body_opened = 1; } else { /* open file */ fix_dir_separators(val); /* clean paths */ - txth->streamBody = open_streamfile_by_filename(txth->streamFile, val); - if (!txth->streamBody) goto fail; - txth->streambody_opened = 1; + txth->sf_body = open_streamfile_by_filename(txth->sf, val); + if (!txth->sf_body) goto fail; + txth->sf_body_opened = 1; } /* use body as header when opening a .txth directly to simplify things */ - if (txth->streamfile_is_txth && !txth->streamhead_opened) { - txth->streamHead = txth->streamBody; + if (txth->streamfile_is_txth && !txth->sf_head_opened) { + txth->sf_head = txth->sf_body; } /* re-apply */ if (!txth->data_size_set) { - txth->data_size = get_streamfile_size(txth->streamBody); + txth->data_size = get_streamfile_size(txth->sf_body); /* maybe should be manually set again? */ if (txth->data_size && txth->data_size > txth->next_offset && txth->next_offset) @@ -1236,37 +1236,37 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char /* CHUNKS */ else if (is_string(key,"chunk_number")) { - if (!parse_num(txth->streamHead,txth,val, &txth->chunk_number)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->chunk_number)) goto fail; } else if (is_string(key,"chunk_start")) { - if (!parse_num(txth->streamHead,txth,val, &txth->chunk_start)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->chunk_start)) goto fail; txth->chunk_start_set = 1; set_body_chunk(txth); } else if (is_string(key,"chunk_header_size")) { - if (!parse_num(txth->streamHead,txth,val, &txth->chunk_header_size)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->chunk_header_size)) goto fail; //txth->chunk_header_size_set = 1; //set_body_chunk(txth); /* optional and should go before chunk_size */ } else if (is_string(key,"chunk_data_size")) { - if (!parse_num(txth->streamHead,txth,val, &txth->chunk_data_size)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->chunk_data_size)) goto fail; //txth->chunk_data_size_set = 1; //set_body_chunk(txth); /* optional and should go before chunk_size */ } else if (is_string(key,"chunk_size")) { - if (!parse_num(txth->streamHead,txth,val, &txth->chunk_size)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->chunk_size)) goto fail; txth->chunk_size_set = 1; set_body_chunk(txth); } else if (is_string(key,"chunk_count")) { - if (!parse_num(txth->streamHead,txth,val, &txth->chunk_count)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->chunk_count)) goto fail; txth->chunk_count_set = 1; set_body_chunk(txth); } /* BASE OFFSET */ else if (is_string(key,"base_offset")) { - if (!parse_num(txth->streamHead,txth,val, &txth->base_offset)) goto fail; + if (!parse_num(txth->sf_head,txth,val, &txth->base_offset)) goto fail; } /* NAME TABLE */ @@ -1398,7 +1398,7 @@ static int is_string_match(const char * text, const char * pattern) { /* either all chars consumed/matched and both pos point to null, or one didn't so string didn't match */ return text[t_pos] == '\0' && pattern[p_pos] == '\0'; } -static int parse_string(STREAMFILE * streamFile, txth_header * txth, const char * val, char * str) { +static int parse_string(STREAMFILE* sf, txth_header* txth, const char * val, char * str) { int n = 0; /* read string without trailing spaces */ @@ -1407,7 +1407,7 @@ static int parse_string(STREAMFILE * streamFile, txth_header * txth, const char return n; } -static int parse_coef_table(STREAMFILE * streamFile, txth_header * txth, const char * val, uint8_t * out_value, size_t out_size) { +static int parse_coef_table(STREAMFILE* sf, txth_header* txth, const char * val, uint8_t * out_value, size_t out_size) { uint32_t byte; int done = 0; @@ -1435,15 +1435,15 @@ fail: return 0; } -static int parse_name_table(txth_header * txth, char * name_list) { - STREAMFILE *nameFile = NULL; +static int parse_name_table(txth_header* txth, char * name_list) { + STREAMFILE* nameFile = NULL; off_t txt_offset, file_size; char fullname[PATH_LIMIT]; char filename[PATH_LIMIT]; char basename[PATH_LIMIT]; /* just in case */ - if (!txth->streamText || !txth->streamBody) + if (!txth->sf_text || !txth->sf_body) goto fail; /* trim name_list just in case */ @@ -1460,12 +1460,12 @@ static int parse_name_table(txth_header * txth, char * name_list) { //;VGM_LOG("TXTH: name_list='%s'\n", name_list); /* open companion file near .txth */ - nameFile = open_streamfile_by_filename(txth->streamText, name_list); + nameFile = open_streamfile_by_filename(txth->sf_text, name_list); if (!nameFile) goto fail; - get_streamfile_name(txth->streamBody, fullname, sizeof(filename)); - get_streamfile_filename(txth->streamBody, filename, sizeof(filename)); - get_streamfile_basename(txth->streamBody, basename, sizeof(basename)); + get_streamfile_name(txth->sf_body, fullname, sizeof(filename)); + get_streamfile_filename(txth->sf_body, filename, sizeof(filename)); + get_streamfile_basename(txth->sf_body, basename, sizeof(basename)); //;VGM_LOG("TXTH: names full=%s, file=%s, base=%s\n", fullname, filename, basename); txt_offset = 0x00; @@ -1526,7 +1526,7 @@ static int parse_name_table(txth_header * txth, char * name_list) { if (current[0] == ',') current++; - if (!parse_num(txth->streamHead,txth,subval, &txth->name_values[txth->name_values_count])) goto fail; + 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 */ goto fail; @@ -1547,7 +1547,7 @@ fail: } -static int parse_num(STREAMFILE * streamFile, txth_header * txth, const char * val, uint32_t * out_value) { +static int parse_num(STREAMFILE* sf, txth_header* txth, const char * val, uint32_t * out_value) { /* out_value can be these, save before modifying */ uint32_t value_mul = txth->value_mul; uint32_t value_div = txth->value_div; @@ -1593,7 +1593,7 @@ static int parse_num(STREAMFILE * streamFile, txth_header * txth, const char * v int hex = (val[1]=='0' && val[2]=='x'); /* can happen when loading .txth and not setting body/head */ - if (!streamFile) + if (!sf) goto fail; /* read exactly N fields in the expected format */ @@ -1610,7 +1610,7 @@ static int parse_num(STREAMFILE * streamFile, txth_header * txth, const char * v /* adjust offset */ offset += txth->base_offset; - if (/*offset < 0 ||*/ offset > get_streamfile_size(streamFile)) + if (/*offset < 0 ||*/ offset > get_streamfile_size(sf)) goto fail; if (ed1 == 'B' && ed2 == 'E') @@ -1622,10 +1622,10 @@ static int parse_num(STREAMFILE * streamFile, txth_header * txth, const char * v offset = offset + subsong_offset * (txth->target_subsong - 1); switch(size) { - case 1: value = (uint8_t)read_8bit(offset,streamFile); break; - case 2: value = big_endian ? (uint16_t)read_16bitBE(offset,streamFile) : (uint16_t)read_16bitLE(offset,streamFile); break; - case 3: value = (big_endian ? (uint32_t)read_32bitBE(offset,streamFile) : (uint32_t)read_32bitLE(offset,streamFile)) & 0x00FFFFFF; break; - case 4: value = big_endian ? (uint32_t)read_32bitBE(offset,streamFile) : (uint32_t)read_32bitLE(offset,streamFile); break; + case 1: value = (uint8_t)read_8bit(offset,sf); break; + case 2: value = big_endian ? (uint16_t)read_16bitBE(offset,sf) : (uint16_t)read_16bitLE(offset,sf); break; + case 3: value = (big_endian ? (uint32_t)read_32bitBE(offset,sf) : (uint32_t)read_32bitLE(offset,sf)) & 0x00FFFFFF; break; + case 4: value = big_endian ? (uint32_t)read_32bitBE(offset,sf) : (uint32_t)read_32bitLE(offset,sf); break; default: goto fail; } value_read = 1; @@ -1719,7 +1719,7 @@ fail: return 0; } -static int get_bytes_to_samples(txth_header * txth, uint32_t bytes) { +static int get_bytes_to_samples(txth_header* txth, uint32_t bytes) { switch(txth->codec) { case MS_IMA: return ms_ima_bytes_to_samples(bytes, txth->interleave, txth->channels); @@ -1748,10 +1748,10 @@ static int get_bytes_to_samples(txth_header * txth, uint32_t bytes) { case ATRAC3PLUS: return atrac3plus_bytes_to_samples(bytes, txth->interleave); case AAC: - return aac_get_samples(txth->streamBody, txth->start_offset, bytes); + return aac_get_samples(txth->sf_body, txth->start_offset, bytes); #ifdef VGM_USE_MPEG case MPEG: - return mpeg_get_samples(txth->streamBody, txth->start_offset, bytes); + return mpeg_get_samples(txth->sf_body, txth->start_offset, bytes); #endif case AC3: return ac3_bytes_to_samples(bytes, txth->interleave, txth->channels); @@ -1789,13 +1789,13 @@ static int get_bytes_to_samples(txth_header * txth, uint32_t bytes) { } } -static int get_padding_size(txth_header * txth, int discard_empty) { +static int get_padding_size(txth_header* txth, int discard_empty) { if (txth->data_size == 0 || txth->channels == 0) return 0; switch(txth->codec) { case PSX: - return ps_find_padding(txth->streamBody, txth->start_offset, txth->data_size, txth->channels, txth->interleave, discard_empty); + return ps_find_padding(txth->sf_body, txth->start_offset, txth->data_size, txth->channels, txth->interleave, discard_empty); default: return 0; } From fe1b76922a999261ab85f79f7e3b7625e983c3b9 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 14 Jun 2020 15:49:15 +0200 Subject: [PATCH 2/4] Fix some .ikm [Legend of Galactic Heroes (PC)] --- src/meta/ikm.c | 79 +++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/src/meta/ikm.c b/src/meta/ikm.c index d6044c9f..7c2456eb 100644 --- a/src/meta/ikm.c +++ b/src/meta/ikm.c @@ -3,24 +3,24 @@ /* IKM - MiCROViSiON PS2 container [Zwei (PS2)] */ -VGMSTREAM * init_vgmstream_ikm_ps2(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_ikm_ps2(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset; int loop_flag, channel_count; /* checks */ - if ( !check_extensions(streamFile,"ikm") ) + if ( !check_extensions(sf,"ikm") ) goto fail; - if (read_32bitBE(0x00,streamFile) != 0x494B4D00) /* "IKM\0" */ + if (read_u32be(0x00,sf) != 0x494B4D00) /* "IKM\0" */ goto fail; - if (read_32bitBE(0x40,streamFile) != 0x41535400) /* "AST\0" */ + if (read_u32be(0x40,sf) != 0x41535400) /* "AST\0" */ goto fail; /* 0x20: type 03? */ - loop_flag = (read_32bitLE(0x14, streamFile) > 0); - channel_count = read_32bitLE(0x50, streamFile); + loop_flag = (read_s32le(0x14, sf) > 0); + channel_count = read_s32le(0x50, sf); start_offset = 0x800; @@ -29,15 +29,15 @@ VGMSTREAM * init_vgmstream_ikm_ps2(STREAMFILE *streamFile) { if (!vgmstream) goto fail; vgmstream->meta_type = meta_IKM; - vgmstream->sample_rate = read_32bitLE(0x44, streamFile); - vgmstream->num_samples = ps_bytes_to_samples(read_32bitLE(0x4c, streamFile), channel_count); - vgmstream->loop_start_sample = read_32bitLE(0x14, streamFile); - vgmstream->loop_end_sample = read_32bitLE(0x18, streamFile); + vgmstream->sample_rate = read_s32le(0x44, sf); + vgmstream->num_samples = ps_bytes_to_samples(read_s32le(0x4c, sf), channel_count); + vgmstream->loop_start_sample = read_s32le(0x14, sf); + vgmstream->loop_end_sample = read_s32le(0x18, sf); vgmstream->coding_type = coding_PSX; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x10; /* @0x40 / channels */ - if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; @@ -46,34 +46,41 @@ fail: return NULL; } -/* IKM - MiCROViSiON PC container [Chaos Legion (PC)] */ -VGMSTREAM * init_vgmstream_ikm_pc(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +/* IKM - MiCROViSiON PC container [Chaos Legion (PC), Legend of Galactic Heroes (PC)] */ +VGMSTREAM* init_vgmstream_ikm_pc(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset; /* checks */ - if ( !check_extensions(streamFile,"ikm") ) + if ( !check_extensions(sf,"ikm") ) goto fail; - if (read_32bitBE(0x00,streamFile) != 0x494B4D00) /* "IKM\0" */ - goto fail; - if (read_32bitBE(0x30,streamFile) != 0x4F676753) /* "OggS" */ + if (read_u32be(0x00,sf) != 0x494B4D00) /* "IKM\0" */ goto fail; /* 0x20: type 01? */ - start_offset = 0x30; + /* find "OggS" start */ + if (read_u32be(0x30,sf) == 0x4F676753) { + start_offset = 0x30; /* Chaos Legion (PC) */ + } else if (read_u32be(0x800,sf) == 0x4F676753) { + start_offset = 0x800; /* Legend of Galactic Heroes (PC) */ + } else { + goto fail; + } + + #ifdef VGM_USE_VORBIS { ogg_vorbis_meta_info_t ovmi = {0}; ovmi.meta_type = meta_IKM; - ovmi.loop_start = read_32bitLE(0x14, streamFile); - ovmi.loop_end = read_32bitLE(0x18, streamFile); + ovmi.loop_start = read_s32le(0x14, sf); + ovmi.loop_end = read_s32le(0x18, sf); ovmi.loop_end_found = ovmi.loop_end; ovmi.loop_flag = ovmi.loop_end > 0; - ovmi.stream_size = read_32bitLE(0x24, streamFile); + ovmi.stream_size = read_s32le(0x24, sf); - vgmstream = init_vgmstream_ogg_vorbis_callbacks(streamFile, NULL, start_offset, &ovmi); + vgmstream = init_vgmstream_ogg_vorbis_callbacks(sf, NULL, start_offset, &ovmi); } #else goto fail; @@ -87,39 +94,39 @@ fail: } /* IKM - MiCROViSiON PSP container [The Legend of Heroes: A Tear of Vermillion (PSP)] */ -VGMSTREAM * init_vgmstream_ikm_psp(STREAMFILE *streamFile) { - VGMSTREAM *vgmstream = NULL; - STREAMFILE *temp_streamFile = NULL; +VGMSTREAM* init_vgmstream_ikm_psp(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + STREAMFILE* temp_sf = NULL; off_t start_offset; size_t data_size; /* checks */ - if ( !check_extensions(streamFile,"ikm") ) + if (!check_extensions(sf,"ikm")) goto fail; - if (read_32bitBE(0x00,streamFile) != 0x494B4D00) /* "IKM\0" */ + if (read_u32be(0x00,sf) != 0x494B4D00) /* "IKM\0" */ goto fail; - if (read_32bitBE(0x800,streamFile) != 0x52494646) /* "RIFF" */ + if (read_u32be(0x800,sf) != 0x52494646) /* "RIFF" */ goto fail; /* 0x20: type 00? */ /* loop values (pre-adjusted without encoder delay) at 0x14/18 are found in the RIFF too */ - data_size = read_32bitLE(0x24, streamFile); + data_size = read_s32le(0x24, sf); start_offset = 0x800; - temp_streamFile = setup_subfile_streamfile(streamFile, start_offset, data_size, "at3"); - if (!temp_streamFile) goto fail; + temp_sf = setup_subfile_streamfile(sf, start_offset, data_size, "at3"); + if (!temp_sf) goto fail; - vgmstream = init_vgmstream_riff(temp_streamFile); + vgmstream = init_vgmstream_riff(temp_sf); if (!vgmstream) goto fail; vgmstream->meta_type = meta_IKM; - close_streamfile(temp_streamFile); + close_streamfile(temp_sf); return vgmstream; fail: - close_streamfile(temp_streamFile); + close_streamfile(temp_sf); close_vgmstream(vgmstream); return NULL; } From 3164eaa2aee23fd11e4a415bf9893f7853caf330 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 14 Jun 2020 15:50:09 +0200 Subject: [PATCH 3/4] Add TXTH loop_behavior=inverted where 0 is loop [Bloody Roar 4] --- doc/TXTH.md | 21 +++++++++++---------- src/meta/txth.c | 22 ++++++++++++++-------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/doc/TXTH.md b/doc/TXTH.md index 5a65f8fd..9b172ec9 100644 --- a/doc/TXTH.md +++ b/doc/TXTH.md @@ -268,15 +268,16 @@ loop_end_sample = (value)|data_size Force loop on or off, as loop start/end may be defined but not used. If not set, by default it loops when loop_end_sample is defined and less than num_samples. Special values: -- auto: tries to autodetect loop points for PS-ADPCM data using data loop flags. +- `auto`: tries to autodetect loop points for PS-ADPCM data using data loop flags. Sometimes games give loop flags different meaning, so behavior can be tweaked by defining `loop_behavior` before `loop_flag`: - `default`: values 0 or 0xFFFF/0xFFFFFFFF (-1) disable looping, but not 0xFF (loop endlessly) - `negative`: values 0xFF/0xFFFF/0xFFFFFFFF (-1) enable looping - `positive`: values 0xFF/0xFFFF/0xFFFFFFFF (-1) disable looping +- `inverted`: values not 0 disable looping ``` -loop_negative = default|negative|positive +loop_behavior = default|negative|positive|inverted loop_flag = (value)|auto ``` @@ -414,12 +415,12 @@ Inside the table you define lines mapping a filename to a bunch of values, in th (filename1): (value) ... # may put multiple comma-separated values, spaces are ok -(filenameN) : (value1), (...) , (valueN) +(filenameN) : (value1), (...) , (valueN) # inline comments too # 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 be use math or offsets too. +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 use wildcards to match multiple names too (it stops on first name that matches), and UTF-8 names should work, case insensitive even. ``` @@ -428,11 +429,11 @@ bgm*_M: 1 # 1ch: some files end with _M for mono bgm*: 2 # 2ch: all other files, notice order matters ``` -While you can put anything in the values, this feature is meant to be used to store some number that points to the actual data inside a real multi-header, that could be set with `header_file`. If you need to store many constant values there is good chance it could be done in some better way. +While you can put anything in the values, this feature is meant to be used to store some number that points to the actual data inside a real multi-header, that could be set with `header_file`. If you feel the need to store many constant values per file, there is good chance it can be done in some better, simpler way. #### BASE OFFSET MODIFIER -You can set a default offset that affects next `@(offset)` reads making them `@(offset + base_offset)`, for cleaner parsing (particularly interesting when combined with the `name_list`). +You can set a default offset that affects next `@(offset)` reads making them `@(offset + base_offset)`, for cleaner parsing (particularly interesting when combined with the `name_table`). For example instead of `channels = @0x714` you could set `base_offset = 0x710, channels = @0x04`. Set to 0 when you want to disable it. ``` @@ -633,7 +634,7 @@ chunk_count = 26 # after setting chunks (sizes vary when 'dechunking') start_offset = 0x00 -padding_size = auto-empty +padding_size = auto-empty num_samples = data_size ``` @@ -675,9 +676,9 @@ Some formats read an offset to another part of the file, then another offset, th You can simulate this chaining multiple `base_offset` ``` -base_offset = @0x10 #sets at 0x1000 -channels = @0x04 #reads at 0x1004 -base_offset = base_offset + @0x10 #sets at 0x1000 + 0x200 = 0x1200 +base_offset = @0x10 #sets current at 0x1000 +channels = @0x04 #reads at 0x1004 (base_offset + 0x04) +base_offset = base_offset + @0x10 #sets current at 0x1000 + 0x200 = 0x1200 sample_rate = @0x04 #reads at 0x1204 ... ``` diff --git a/src/meta/txth.c b/src/meta/txth.c index 5378a64a..30f22178 100644 --- a/src/meta/txth.c +++ b/src/meta/txth.c @@ -41,6 +41,8 @@ typedef enum { EAXA = 31, /* Electronic Arts EA-XA 4-bit ADPCM v1 */ } txth_type; +typedef enum { DEFAULT, NEGATIVE, POSITIVE, INVERTED } txth_loop_t; + typedef struct { txth_type codec; uint32_t codec_mode; @@ -73,7 +75,7 @@ typedef struct { uint32_t skip_samples; uint32_t loop_flag; - uint32_t loop_behavior; + txth_loop_t loop_behavior; int loop_flag_set; int loop_flag_auto; @@ -1059,28 +1061,32 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char * key, ch if (!parse_num(txth->sf_head,txth,val, &txth->loop_flag)) goto fail; txth->loop_flag_set = 1; - if (txth->loop_behavior == 0) { + if (txth->loop_behavior == DEFAULT) { if ((txth->loop_flag == 0xFFFF || txth->loop_flag == 0xFFFFFFFF) ) txth->loop_flag = 0; - } - else if (txth->loop_behavior == 1) { + else if (txth->loop_behavior == NEGATIVE) { if (txth->loop_flag == 0xFF || txth->loop_flag == 0xFFFF || txth->loop_flag == 0xFFFFFFFF) txth->loop_flag = 1; } - else if (txth->loop_behavior == 2) { + else if (txth->loop_behavior == POSITIVE) { if (txth->loop_flag == 0xFF || txth->loop_flag == 0xFFFF || txth->loop_flag == 0xFFFFFFFF) txth->loop_flag = 0; } + else if (txth->loop_behavior == INVERTED) { + txth->loop_flag = (txth->loop_flag == 0); + } } } else if (is_string(key,"loop_behavior")) { if (is_string(val, "default")) - txth->loop_behavior = 0; + txth->loop_behavior = DEFAULT; else if (is_string(val, "negative")) - txth->loop_behavior = 1; + txth->loop_behavior = NEGATIVE; else if (is_string(val, "positive")) - txth->loop_behavior = 2; + txth->loop_behavior = POSITIVE; + else if (is_string(val, "inverted")) + txth->loop_behavior = INVERTED; else goto fail; } From 5aa09d45e01823d903a72da62ae9675c8ecc6b5a Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 14 Jun 2020 15:50:50 +0200 Subject: [PATCH 4/4] Doc --- doc/TXTP.md | 34 +++++++++++++++++++++------------- src/coding/coding_utils.c | 3 ++- src/meta/riff.c | 2 +- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/doc/TXTP.md b/doc/TXTP.md index e9e71d68..9a8b8532 100644 --- a/doc/TXTP.md +++ b/doc/TXTP.md @@ -91,7 +91,7 @@ BIK_E1_6A_DialEnd_00000000.audio.multi.bik#3 mode = layers ``` -Note that the number of channels is the sum of all layers, so three 2ch layers play as a 6ch file. If all layers share loop points they are automatically kept. +Note that the number of channels is the sum of all layers, so three 2ch layers play as a 6ch file (you can downmix to stereo using mixing commands, described later). If all layers share loop points they are automatically kept. ### Mixed groups You can set "groups" to 'fold' various files into one, as layers or segments, to allow complex cases: @@ -166,7 +166,7 @@ mainB_2ch.at3 group = 2L2 #@layer-v 2 # finally resulting layers are played as segments (2ch, 2ch) -# (could set a group = S and ommit S here, too) +# (could set a group = S and ommit mode here, too) mode = segments # if the last group joins all as segments you can use loop_start @@ -239,34 +239,42 @@ music_Home.ps3.scd#C3 4 ### Play settings **`#l(loops)`**, **`#f(fade)`**, **`#d(fade-delay)`**, **`#i(ignore loop)`**, **`#F(ignore fade)`**, **`#E(end-to-end loop)`** -Those setting should override player's defaults if set (except "loop forever"). They are equivalent to some test.exe options. +Those setting should override player's defaults if set. They are equivalent to some test.exe options. -**God Hand (PS2)**: *boss2_3ningumi_ver6.txtp* (each line is a separate TXTP) +**God Hand (PS2)**: *boss2_3ningumi_ver6.txtp* ``` # set number of loops boss2_3ningumi_ver6.adx#l3 - +``` +``` # set fade time (in seconds) boss2_3ningumi_ver6.adx#f10.5 - +``` +``` # set fade delay (in seconds) boss2_3ningumi_ver6.adx#d0.5 - +``` +``` # ignore and disable loops boss2_3ningumi_ver6.adx#i - +``` +``` # don't fade out and instead play the song ending after boss2_3ningumi_ver6.adx#F # this song has a nice stop - +``` +``` # force full loops from end-to-end boss2_3ningumi_ver6.adx#E - +``` +``` # settings can be combined boss2_3ningumi_ver6.adx#l2#F # 2 loops + ending - +``` +``` # settings can be combined boss2_3ningumi_ver6.adx#l1.5#d1#f5 - +``` +``` # boss2_3ningumi_ver6.adx#l1.0#F # this is equivalent to #i ``` @@ -284,7 +292,7 @@ main.fsb Similarly other games don't use loop points, but rather repeat/loops the song internally many times: ``` -intro.vag #t3:20 #i #l1.0 #trim + combine with forced loops for easy fades +bgm01.vag #t3:20 #i #l1.0 # trim + combine with forced loops for easy fades ``` Note that if you need to remove very few samples (like 1) to get smooth transitions it may be a bug in vgmstream, consider reporting. diff --git a/src/coding/coding_utils.c b/src/coding/coding_utils.c index 0b6b3bfa..4a28b718 100644 --- a/src/coding/coding_utils.c +++ b/src/coding/coding_utils.c @@ -155,7 +155,8 @@ int ffmpeg_make_riff_xma1(uint8_t * buf, size_t buf_size, size_t sample_count, s put_16bitLE(buf+off+0x12, speakers); } - /* xmaencode decoding rejects XMA1 without "seek" chunk, though it doesn't seem to use it */ + /* xmaencode decoding rejects XMA1 without "seek" chunk, though it doesn't seem to use it + * (needs to be have entries but can be bogus, also generates seek for even small sounds) */ memcpy(buf+riff_size-4-4, "data", 4); put_32bitLE(buf+riff_size-4, data_size); /* data size */ diff --git a/src/meta/riff.c b/src/meta/riff.c index 53eba94e..7e9785fe 100644 --- a/src/meta/riff.c +++ b/src/meta/riff.c @@ -936,7 +936,7 @@ static size_t get_ue4_msadpcm_interleave(STREAMFILE *sf, riff_fmt_chunk *fmt, of return v2_interleave; /* favor newer games */ } -/* same but big endian, seen in the spec and in Kitchenette (PC) */ +/* same but big endian, seen in the spec and in Kitchenette (PC) (possibly from Adobe Director) */ VGMSTREAM * init_vgmstream_rifx(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; riff_fmt_chunk fmt = {0};