fix AY envelope packing

This commit is contained in:
wbcbz7 2025-08-13 19:44:42 +07:00
parent ad6deb23d2
commit c41dca4325
2 changed files with 55 additions and 48 deletions

View file

@ -1046,7 +1046,7 @@ int opm_serialize_ssg_tone_stream(opm_channel_t* chctx) {
s.rawdata.push_back(OPM_STREAM_END_FRAME); s.rawdata.push_back(OPM_STREAM_END_FRAME);
} }
else { else {
if (ef & OPM_REC_AYTONE_PERIOD_HIGH) { if (ef & (OPM_REC_AYTONE_PERIOD_HIGH | OPM_REC_AYTONE_PERIOD_LOW)) {
// high period available, write it // high period available, write it
auto ef_cur = ef; auto ef_cur = ef;
ef &= ~(OPM_REC_AYTONE_PERIOD_HIGH | OPM_REC_AYTONE_PERIOD_LOW); // write both hi and lo if available ef &= ~(OPM_REC_AYTONE_PERIOD_HIGH | OPM_REC_AYTONE_PERIOD_LOW); // write both hi and lo if available
@ -1093,6 +1093,7 @@ int opm_serialize_ssg_tone_stream(opm_channel_t* chctx) {
int opm_serialize_ssg_env_stream(opm_channel_t* chctx) { int opm_serialize_ssg_env_stream(opm_channel_t* chctx) {
int old_delay = -1; int old_delay = -1;
bool delay_emitted = false;
for (int f = 0; f < chctx->records.size(); f++) { for (int f = 0; f < chctx->records.size(); f++) {
auto& s = chctx->records[f]; auto& s = chctx->records[f];
s.rawdata.clear(); s.rawdata.clear();
@ -1105,10 +1106,12 @@ int opm_serialize_ssg_env_stream(opm_channel_t* chctx) {
if (s.frame_dist != old_delay || (s.flags & OPM_CHAN_LOOP_POINT)) { if (s.frame_dist != old_delay || (s.flags & OPM_CHAN_LOOP_POINT)) {
old_delay = s.frame_dist; old_delay = s.frame_dist;
opm_set_delay(s.rawdata, s.frame_dist); opm_set_delay(s.rawdata, s.frame_dist);
delay_emitted = true;
} }
// process events // process events
if (s.records.size() > 0) for (int i = 0; i < s.records.size(); i++) { if (s.records.size() > 0) {
for (int i = 0; i < s.records.size(); i++) {
auto& e = s.records[i]; auto& e = s.records[i];
uint64_t ef = e.flags; uint64_t ef = e.flags;
@ -1116,7 +1119,7 @@ int opm_serialize_ssg_env_stream(opm_channel_t* chctx) {
s.rawdata.push_back(OPM_STREAM_END_FRAME); s.rawdata.push_back(OPM_STREAM_END_FRAME);
} }
else { else {
if (ef & OPM_REC_AYENV_PERIOD_HIGH) { if (ef & (OPM_REC_AYENV_PERIOD_HIGH | OPM_REC_AYENV_PERIOD_LOW)) {
// high period available, write it // high period available, write it
auto ef_cur = ef; auto ef_cur = ef;
ef &= ~(OPM_REC_AYENV_PERIOD_HIGH | OPM_REC_AYENV_PERIOD_LOW); // write both hi and lo if available ef &= ~(OPM_REC_AYENV_PERIOD_HIGH | OPM_REC_AYENV_PERIOD_LOW); // write both hi and lo if available
@ -1131,7 +1134,7 @@ int opm_serialize_ssg_env_stream(opm_channel_t* chctx) {
if (ef_cur & OPM_REC_AYENV_PERIOD_HIGH) s.rawdata.push_back(e.ayenv.period_hi); if (ef_cur & OPM_REC_AYENV_PERIOD_HIGH) s.rawdata.push_back(e.ayenv.period_hi);
} }
if (ef & OPM_REC_AYENV_NOISE) { if (ef & (OPM_REC_AYENV_NOISE | OPM_REC_AYENV_PERIOD_LOW)) {
// noise available, write it // noise available, write it
auto ef_cur = ef; auto ef_cur = ef;
ef &= ~(OPM_REC_AYENV_NOISE | OPM_REC_AYENV_PERIOD_LOW); // write both noise and period low if available ef &= ~(OPM_REC_AYENV_NOISE | OPM_REC_AYENV_PERIOD_LOW); // write both noise and period low if available
@ -1145,7 +1148,7 @@ int opm_serialize_ssg_env_stream(opm_channel_t* chctx) {
if (ef_cur & OPM_REC_AYENV_PERIOD_LOW) s.rawdata.push_back(e.ayenv.period_low); if (ef_cur & OPM_REC_AYENV_PERIOD_LOW) s.rawdata.push_back(e.ayenv.period_low);
} }
if (ef & OPM_REC_AYENV_ENVTYPE) { if (ef & (OPM_REC_AYENV_ENVTYPE | OPM_REC_AYENV_PERIOD_LOW)) {
// envelope type available, write it // envelope type available, write it
auto ef_cur = ef; auto ef_cur = ef;
ef &= ~(OPM_REC_AYENV_ENVTYPE | OPM_REC_AYENV_PERIOD_LOW); // write both envtype and period low if available ef &= ~(OPM_REC_AYENV_ENVTYPE | OPM_REC_AYENV_PERIOD_LOW); // write both envtype and period low if available
@ -1161,6 +1164,10 @@ int opm_serialize_ssg_env_stream(opm_channel_t* chctx) {
} }
} }
} }
else { // if (s.records.size() > 0)
if (delay_emitted) s.rawdata.push_back(OPM_STREAM_END_FRAME);
}
}
return 0; return 0;
} }

View file

@ -118,7 +118,7 @@ public:
} }
}; };
opna_interface_t opna_interface; opna_interface_t opna_interface[2];
ymfm::ym2203 *opnachip[2]; ymfm::ym2203 *opnachip[2];
opnx_register_queue_t opna_regqueue[2]; opnx_register_queue_t opna_regqueue[2];
ymfm::ym2203::output_data opna_out[MAX_FRAMES_PER_BUFFER][2]; ymfm::ym2203::output_data opna_out[MAX_FRAMES_PER_BUFFER][2];
@ -409,7 +409,7 @@ int main(int argc, char* argv[])
uint32_t sample_rate; uint32_t sample_rate;
for (int chip = 0; chip < 2; chip++) { for (int chip = 0; chip < 2; chip++) {
opnachip[chip] = new ymfm::ym2203(opna_interface); opnachip[chip] = new ymfm::ym2203(opna_interface[chip]);
if (opnachip[chip] == nullptr) { if (opnachip[chip] == nullptr) {
printf("error: unable to init ymfm!\n"); printf("error: unable to init ymfm!\n");
return 1; return 1;