resolve back reference distance in event stream in place

This commit is contained in:
wbcbz7 2024-06-07 16:25:25 +07:00
parent 3f3de1e08c
commit c6af5d02ac
2 changed files with 8 additions and 36 deletions

View file

@ -130,10 +130,12 @@ uint32_t opm_compress_channel(opm_convert_context_t* ctx, int ch, int min_backre
rec.flags |= OPM_CHAN_BACKREF;
rec.distance_frames = match.distance_frames;
rec.frames_to_play = match.logic_frames;
uint32_t backref_dist = rec.byte_stamp - src_ch[pos - rec.distance_frames].byte_stamp;
// fill dummy rawdata (will resolve this later!)
rec.rawdata.clear();
rec.rawdata.push_back(OPM_STREAM_BACKREF);
rec.rawdata.push_back(0);
rec.rawdata.push_back(OPM_STREAM_BACKREF | (backref_dist >> 8));
rec.rawdata.push_back(backref_dist & 0xFF);
rec.rawdata.push_back(rec.frames_to_play);
ctx->opmpacked[ch].push_back(rec);
pos += match.total_frames; // skip matched data
@ -181,26 +183,11 @@ void opm_compress(opm_convert_context_t* ctx) {
}
// recompress if current != best
if (sz - 1 != cur_backref_len.best) opm_compress_channel(ctx, ch, cur_backref_len.best);
// calculate byte offsets for each frame
std::vector<uint32_t> ch_bytepos;
uint32_t bytepos_cur = 0;
for (int f = 0; f < ctx->opmpacked[ch].size(); f++) {
ch_bytepos.push_back(bytepos_cur);
bytepos_cur += ctx->opmpacked[ch][f].rawdata.size();
}
// resolve back references
for (int f = 0; f < ctx->opmpacked[ch].size(); f++) {
// fixup back reference (if any)
if (ctx->opmpacked[ch][f].flags & OPM_CHAN_BACKREF) {
uint32_t backref_dist = ch_bytepos[f] - ch_bytepos[f - ctx->opmpacked[ch][f].distance_frames];
ctx->opmpacked[ch][f].rawdata[0] = OPM_STREAM_BACKREF | (backref_dist >> 8);
ctx->opmpacked[ch][f].rawdata[1] = (backref_dist & 0xFF);
}
}
ch++;
#ifndef ULTRA_DEBUG
printf("."); fflush(stdout);
#endif
if (ctx->flags.verbosity < 2) {
printf("."); fflush(stdout);
}
}
printf("done\n");
}

View file

@ -816,19 +816,6 @@ int main(int argc, char* argv[]) {
ctx->opmfile.filename = outfile_str;
ctx->logname = logfile_str;
#if 0
std::ifstream infile(infile_str, std::ios::in | std::ios::binary);
infile.unsetf(std::ios::skipws);
// get filesize
infile.seekg(0, std::ios::end);
uint64_t fsize = infile.tellg();
infile.seekg(0, std::ios::beg);
// read whole file
ctx->vgm.vgmfile.reserve(fsize);
ctx->vgm.vgmfile.insert(ctx->vgm.vgmfile.begin(), std::istream_iterator<uint8_t>(infile), std::istream_iterator<uint8_t>());
#else
// good old stdio :)
FILE* infile = fopen(infile_str.c_str(), "rb");
if (infile == nullptr) {
@ -848,8 +835,6 @@ int main(int argc, char* argv[]) {
// done
fclose(infile);
#endif
// get header
ctx->vgm.header = reinterpret_cast<VGMHeader*>(ctx->vgm.vgmfile.data());