fix implicit end of frame
This commit is contained in:
parent
4770e2cffd
commit
6a6a43cac1
|
@ -164,5 +164,7 @@ struct opm_convert_context_t {
|
|||
opm_header_t header;
|
||||
std::vector<opm_header_stream_desc_t> streamdesc;
|
||||
} opmfile;
|
||||
|
||||
std::string logname;
|
||||
};
|
||||
|
||||
|
|
|
@ -594,38 +594,7 @@ int opm_serialize_channel_stream(opm_convert_context_t* ctx, int ch) {
|
|||
opm_set_delay(s.rawdata, s.frame_dist);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// process events
|
||||
for (auto& e : s.records) {
|
||||
for (int op = 0; op < 2; op++) {
|
||||
// mult/tl/waveform
|
||||
int ff = ((e.flags >> (OPM_OP1_SHIFT * op)) & (OPM_MULT | OPM_KSL_TL | OPM_WAVEFORM));
|
||||
if (ff != 0) {
|
||||
s.rawdata.push_back(OPM_SET_MULT_WAVE_TL | (ff >> 0) | (OPM_CMD80_SELECT_OPERATOR * op));
|
||||
if (ff & OPM_MULT) s.rawdata.push_back(e.op[op].mult);
|
||||
if (ff & OPM_KSL_TL) s.rawdata.push_back(e.op[op].ksl_tl);
|
||||
if (ff & OPM_WAVEFORM) s.rawdata.push_back(e.op[op].waveform);
|
||||
}
|
||||
|
||||
// ad/sr
|
||||
ff = ((e.flags >> (OPM_OP1_SHIFT * op)) & (OPM_AD | OPM_SR));
|
||||
if (ff != 0) {
|
||||
s.rawdata.push_back(OPM_SET_ADSR | (ff >> 3) | (OPM_CMDA0_SELECT_OPERATOR * op));
|
||||
if (ff & OPM_AD) s.rawdata.push_back(e.op[op].ad);
|
||||
if (ff & OPM_SR) s.rawdata.push_back(e.op[op].sr);
|
||||
}
|
||||
}
|
||||
|
||||
int ff = (e.flags & (OPM_FNUM | OPM_BLOCK | OPM_FEEDBACK));
|
||||
if (ff != 0) {
|
||||
s.rawdata.push_back(OPM_SET_FREQ_FB | (ff >> 10));
|
||||
if (ff & OPM_FEEDBACK) s.rawdata.push_back(e.feedback);
|
||||
if (ff & OPM_FNUM) s.rawdata.push_back(e.fnum);
|
||||
if (ff & OPM_BLOCK) s.rawdata.push_back(e.block);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (int i = 0; i < s.records.size(); i++) {
|
||||
if (s.records.size() > 0) for (int i = 0; i < s.records.size(); i++) {
|
||||
// get masks for events
|
||||
auto& e = s.records[i];
|
||||
struct {
|
||||
|
@ -639,55 +608,68 @@ int opm_serialize_channel_stream(opm_convert_context_t* ctx, int ch) {
|
|||
// generate masks
|
||||
mask.last = 0; int bit = 0;
|
||||
for (int op = 0; op < 2; op++) {
|
||||
mask.op[op] = ((e.flags >> (OPM_OP1_SHIFT * op)) & (OPM_MULT | OPM_KSL_TL | OPM_WAVEFORM));
|
||||
mask.op[op] = ((e.flags >> (OPM_OP1_SHIFT * op)) & (OPM_MULT | OPM_KSL_TL | OPM_WAVEFORM));
|
||||
mask.last |= ((mask.op[op] ? 1 : 0) << bit++);
|
||||
mask.adsr[op] = ((e.flags >> (OPM_OP1_SHIFT * op)) & (OPM_AD | OPM_SR));
|
||||
mask.last |= ((mask.adsr[op] ? 1 : 0) << bit++);
|
||||
}
|
||||
mask.freq_fb = (e.flags & (OPM_FNUM | OPM_BLOCK | OPM_FEEDBACK));
|
||||
mask.last |= ((mask.freq_fb ? 1 : 0) << bit++);
|
||||
//mask.key = (e.flags & (OPM_FNUM | OPM_BLOCK | OPM_FEEDBACK | OPM_KEY)) == (OPM_BLOCK | OPM_KEY);
|
||||
//mask.last |= ((mask.key ? 1 : 0) << bit++);
|
||||
if (i < s.records.size() - 1) mask.last |= (1 << bit++); // prevent non-last events from emitting eof token
|
||||
mask.last |= ((mask.freq_fb ? 16 : 0) << 0);
|
||||
mask.key = (e.flags & (OPM_FNUM | OPM_BLOCK | OPM_FEEDBACK | OPM_KEY)) == (OPM_BLOCK | OPM_KEY);
|
||||
mask.last |= ((mask.key ? 32 : 0) << 0);
|
||||
if (i < s.records.size() - 1) mask.last |= 64; // prevent non-last events from emitting eof token
|
||||
|
||||
// output tokens
|
||||
for (int op = 0; op < 2; op++) {
|
||||
// mult/tl/waveform
|
||||
if (mask.last & 1) {
|
||||
// TODO: do it less dirty :)
|
||||
if (mask.last == 0) {
|
||||
s.rawdata.push_back(OPM_STREAM_END_FRAME);
|
||||
}
|
||||
else {
|
||||
// output tokens
|
||||
for (int op = 0; op < 2; op++) {
|
||||
// mult/tl/waveform
|
||||
if (mask.last & 1) {
|
||||
s.rawdata.push_back(
|
||||
OPM_SET_MULT_WAVE_TL | (mask.op[op] >> 0) | (OPM_CMD80_SELECT_OPERATOR * op) |
|
||||
(mask.last == 1 ? OPM_CMD80_END_OF_FRAME : 0)
|
||||
);
|
||||
if (mask.op[op] & OPM_MULT) s.rawdata.push_back(e.op[op].mult);
|
||||
if (mask.op[op] & OPM_KSL_TL) s.rawdata.push_back(e.op[op].ksl_tl);
|
||||
if (mask.op[op] & OPM_WAVEFORM) s.rawdata.push_back(e.op[op].waveform);
|
||||
}
|
||||
mask.last >>= 1;
|
||||
|
||||
// ad/sr
|
||||
if (mask.last & 1) {
|
||||
s.rawdata.push_back(
|
||||
OPM_SET_ADSR | (mask.adsr[op] >> 3) | (OPM_CMDA0_SELECT_OPERATOR * op) |
|
||||
(mask.last == 1 ? OPM_CMDA0_END_OF_FRAME : 0)
|
||||
);
|
||||
if (mask.adsr[op] & OPM_AD) s.rawdata.push_back(e.op[op].ad);
|
||||
if (mask.adsr[op] & OPM_SR) s.rawdata.push_back(e.op[op].sr);
|
||||
}
|
||||
mask.last >>= 1;
|
||||
}
|
||||
// freq/feedback
|
||||
if ((mask.last & 1) && !mask.key) {
|
||||
s.rawdata.push_back(
|
||||
OPM_SET_MULT_WAVE_TL | (mask.op[op] >> 0) | (OPM_CMD80_SELECT_OPERATOR * op) |
|
||||
(mask.last == 1 ? OPM_CMD80_END_OF_FRAME : 0)
|
||||
OPM_SET_FREQ_FB | (mask.freq_fb >> 10) |
|
||||
(mask.last == 1 ? OPM_CMDB0_END_OF_FRAME : 0)
|
||||
);
|
||||
if (mask.op[op] & OPM_MULT) s.rawdata.push_back(e.op[op].mult);
|
||||
if (mask.op[op] & OPM_KSL_TL) s.rawdata.push_back(e.op[op].ksl_tl);
|
||||
if (mask.op[op] & OPM_WAVEFORM) s.rawdata.push_back(e.op[op].waveform);
|
||||
if (mask.freq_fb & OPM_FEEDBACK) s.rawdata.push_back(e.feedback);
|
||||
if (mask.freq_fb & OPM_FNUM) s.rawdata.push_back(e.fnum);
|
||||
if (mask.freq_fb & OPM_BLOCK) s.rawdata.push_back(e.block);
|
||||
}
|
||||
mask.last >>= 1;
|
||||
|
||||
// ad/sr
|
||||
if (mask.last & 1) {
|
||||
if (mask.key) {
|
||||
s.rawdata.push_back(
|
||||
OPM_SET_ADSR | (mask.adsr[op] >> 3) | (OPM_CMDA0_SELECT_OPERATOR * op) |
|
||||
(mask.last == 1 ? OPM_CMDA0_END_OF_FRAME : 0)
|
||||
OPM_KEY_TRIGGER |
|
||||
((e.block >> 5) & 1) |
|
||||
(mask.last == 1 ? OPM_KEY_END_OF_FRAME : 0)
|
||||
);
|
||||
if (mask.adsr[op] & OPM_AD) s.rawdata.push_back(e.op[op].ad);
|
||||
if (mask.adsr[op] & OPM_SR) s.rawdata.push_back(e.op[op].sr);
|
||||
}
|
||||
mask.last >>= 1;
|
||||
}
|
||||
// freq/feedback
|
||||
if (mask.last & 1) {
|
||||
s.rawdata.push_back(
|
||||
OPM_SET_FREQ_FB | (mask.freq_fb >> 10) |
|
||||
(mask.last == 1 ? OPM_CMDB0_END_OF_FRAME : 0)
|
||||
);
|
||||
if (mask.freq_fb & OPM_FEEDBACK) s.rawdata.push_back(e.feedback);
|
||||
if (mask.freq_fb & OPM_FNUM) s.rawdata.push_back(e.fnum);
|
||||
if (mask.freq_fb & OPM_BLOCK) s.rawdata.push_back(e.block);
|
||||
}
|
||||
mask.last >>= 1;
|
||||
}
|
||||
#endif
|
||||
} else s.rawdata.push_back(OPM_STREAM_END_FRAME);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -717,6 +699,23 @@ int opm_concat_streams(opm_convert_context_t* ctx) {
|
|||
}
|
||||
|
||||
|
||||
// ---------------------------
|
||||
// dump events for each channel
|
||||
int opm_dump_events(opm_convert_context_t* ctx) {
|
||||
FILE* f = fopen(ctx->logname.c_str(), "w");
|
||||
fprintf(f, "total %d frames\n", ctx->total_frames);
|
||||
for (int ch = 0; ch < (1 + 9); ch++) {
|
||||
fprintf(f, "---channel %d\n", ch-1);
|
||||
for (auto& a : ctx->opmrecords[ch]) {
|
||||
fprintf(f, "frame %07d, dist %d: data ", a.frame, a.frame_dist, a.records.size());
|
||||
for (auto& d : a.rawdata) fprintf(f, "%02X ", d);
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
@ -742,7 +741,9 @@ int main(int argc, char* argv[]) {
|
|||
std::string infile_str = argv[1];
|
||||
std::string outfile_str = infile_str.substr(0, infile_str.find(".vgm")) + ".opm";
|
||||
std::string csvfile_str = infile_str.substr(0, infile_str.find(".vgm")) + ".csv";
|
||||
std::string logfile_str = infile_str.substr(0, infile_str.find(".vgm")) + ".log";
|
||||
ctx->opmfile.filename = outfile_str;
|
||||
ctx->logname = logfile_str;
|
||||
|
||||
std::ifstream infile(infile_str, std::ios::in | std::ios::binary);
|
||||
infile.unsetf(std::ios::skipws);
|
||||
|
@ -815,6 +816,9 @@ int main(int argc, char* argv[]) {
|
|||
opm_concat_streams(ctx);
|
||||
#endif
|
||||
|
||||
// dump raw data
|
||||
opm_dump_events(ctx);
|
||||
|
||||
// dump OPM file
|
||||
opm_write_file(ctx);
|
||||
|
||||
|
|
Loading…
Reference in a new issue