update for more compact event commands
This commit is contained in:
parent
6a6a43cac1
commit
a681a2c53b
|
@ -47,10 +47,8 @@ enum {
|
|||
OPM_STREAM_BACKREF = 0xE0, // E0..EF - word backrefpos (12 bit), byte frames
|
||||
|
||||
// setter commands
|
||||
OPM_SET_VOLUME = 0x00, // 00..7F - set volume (total level) for operator, end of frame
|
||||
OPM_SET_MULT_WAVE_TL = 0x80, // 80..9F - set mult/waveform/total level/ksr for operator
|
||||
OPM_SET_ADSR = 0xA0, // A0..AF - set attack/sustain/decay/release for operator
|
||||
OPM_SET_FREQ_FB = 0xB0, // B0..BF - set frequency + feedback
|
||||
OPM_SET_OPERATOR = 0x00, // 00..7F - set operator parameters
|
||||
OPM_SET_FREQ_FB_VOL = 0x80, // 80..BF - set frequency, feedback and total level
|
||||
|
||||
// control register set
|
||||
OPM_CTRL_KEY_PERC = 0x00, // 00..7F - set key on/off for percussion, end of frame
|
||||
|
@ -63,21 +61,20 @@ enum {
|
|||
|
||||
OPM_SET_VOLUME_END_OF_FRAME = (1 << 7),
|
||||
|
||||
OPM_CMD80_SET_MULT = (1 << 0),
|
||||
OPM_CMD80_SET_TL = (1 << 1),
|
||||
OPM_CMD80_SET_WAVEFORM = (1 << 2),
|
||||
OPM_CMD80_SELECT_OPERATOR = (1 << 3),
|
||||
OPM_CMD80_END_OF_FRAME = (1 << 4),
|
||||
OPM_CMD00_SET_MULT = (1 << 0),
|
||||
OPM_CMD00_SET_TL = (1 << 1),
|
||||
OPM_CMD00_SET_AD = (1 << 2),
|
||||
OPM_CMD00_SET_SR = (1 << 3),
|
||||
OPM_CMD00_SET_WAVEFORM = (1 << 4),
|
||||
OPM_CMD00_SELECT_OPERATOR = (1 << 5),
|
||||
OPM_CMD00_END_OF_FRAME = (1 << 6),
|
||||
|
||||
OPM_CMDA0_SET_AD = (1 << 0),
|
||||
OPM_CMDA0_SET_SR = (1 << 1),
|
||||
OPM_CMDA0_SELECT_OPERATOR = (1 << 2),
|
||||
OPM_CMDA0_END_OF_FRAME = (1 << 3),
|
||||
|
||||
OPM_CMDB0_SET_FEEDBACK = (1 << 0),
|
||||
OPM_CMDB0_SET_FREQ_LOW = (1 << 1),
|
||||
OPM_CMDB0_SET_FREQ_HIGH = (1 << 2),
|
||||
OPM_CMDB0_END_OF_FRAME = (1 << 3),
|
||||
OPM_CMD80_SET_KEYBLOCK = (1 << 0),
|
||||
OPM_CMD80_SET_FREQ = (1 << 1),
|
||||
OPM_CMD80_SET_FEEDBACK = (1 << 2),
|
||||
OPM_CMD80_SET_TL0 = (1 << 3),
|
||||
OPM_CMD80_SET_TL1 = (1 << 4),
|
||||
OPM_CMD80_END_OF_FRAME = (1 << 5),
|
||||
|
||||
OPM_CTRL_SET_REG01 = (1 << 0),
|
||||
OPM_CTRL_SET_REG08 = (1 << 1),
|
||||
|
|
|
@ -109,10 +109,24 @@ int opmplay_load_module(opmplay_context_t* ctx, opmplay_io_t* io) {
|
|||
return OPMPLAY_ERR_OK;
|
||||
}
|
||||
|
||||
void opmplay_pop_stack(opmplay_channel_context_t* chctx) {
|
||||
opmplay_channel_stack_t* st = chctx->stack + (--chctx->stack_pos);
|
||||
chctx->stream.ptr = st->ptr;
|
||||
chctx->stream.samples_to_play = st->frames_to_play;
|
||||
}
|
||||
|
||||
void opmplay_push_stack(opmplay_channel_context_t* chctx) {
|
||||
opmplay_channel_stack_t* st = chctx->stack + chctx->stack_pos;
|
||||
st->ptr = chctx->stream.ptr;
|
||||
st->frames_to_play = chctx->stream.samples_to_play;
|
||||
chctx->stack_pos++;
|
||||
}
|
||||
|
||||
int opmplay_loop(opmplay_context_t* ctx) {
|
||||
// channel streams
|
||||
for (int ch = 0; ch < OPMPLAY_MAX_CHANNLES; ch++) {
|
||||
// init stack
|
||||
ctx->channels[ch].stack_pos = 0;
|
||||
ctx->channels[ch].stream.samples_to_play = -1;
|
||||
ctx->channels[ch].stream.ptr = ctx->channels[ch].stream.loop;
|
||||
ctx->channels[ch].stream.delay = ctx->channels[ch].stream.reload = 1;
|
||||
|
@ -244,34 +258,29 @@ int opmplay_tick(opmplay_context_t* ctx, opl3_chip* opl3) {
|
|||
if (--chctx->stream.delay == 0) {
|
||||
while (isRun) {
|
||||
// get streams
|
||||
if ((*(data) & 0xE0) == OPM_SET_MULT_WAVE_TL) {
|
||||
if ((*(data) & 0x80) == OPM_SET_OPERATOR) {
|
||||
int mask = *data;
|
||||
int op = (mask & OPM_CMD80_SELECT_OPERATOR ? 3 : 0) + opmplay_opregs_channel_offset[ch];
|
||||
int op = (mask & OPM_CMD00_SELECT_OPERATOR ? 3 : 0) + opmplay_opregs_channel_offset[ch];
|
||||
data++;
|
||||
if (mask & OPM_CMD80_SET_MULT) OPL3_WriteRegBuffered(opl3, 0x20+op, *data++);
|
||||
if (mask & OPM_CMD80_SET_TL) OPL3_WriteRegBuffered(opl3, 0x40+op, *data++);
|
||||
if (mask & OPM_CMD80_SET_WAVEFORM) OPL3_WriteRegBuffered(opl3, 0xE0+op, *data++);
|
||||
if (mask & OPM_CMD00_SET_MULT) OPL3_WriteRegBuffered(opl3, 0x20 + op, *data++);
|
||||
if (mask & OPM_CMD00_SET_TL) OPL3_WriteRegBuffered(opl3, 0x40 + op, *data++);
|
||||
if (mask & OPM_CMD00_SET_AD) OPL3_WriteRegBuffered(opl3, 0x60 + op, *data++);
|
||||
if (mask & OPM_CMD00_SET_SR) OPL3_WriteRegBuffered(opl3, 0x80 + op, *data++);
|
||||
if (mask & OPM_CMD00_SET_WAVEFORM) OPL3_WriteRegBuffered(opl3, 0xE0 + op, *data++);
|
||||
if (mask & OPM_CMD00_END_OF_FRAME) isRun = false;
|
||||
continue;
|
||||
}
|
||||
if ((*(data) & 0xC0) == OPM_SET_FREQ_FB_VOL) {
|
||||
int mask = *data;
|
||||
data++;
|
||||
if (mask & OPM_CMD80_SET_KEYBLOCK) { chctx->block = *data; OPL3_WriteRegBuffered(opl3, 0xB0 + ch, *data++); };
|
||||
if (mask & OPM_CMD80_SET_FREQ) OPL3_WriteRegBuffered(opl3, 0xA0 + ch, *data++);
|
||||
if (mask & OPM_CMD80_SET_FEEDBACK) OPL3_WriteRegBuffered(opl3, 0xC0 + ch, *data++);
|
||||
if (mask & OPM_CMD80_SET_TL0) OPL3_WriteRegBuffered(opl3, 0x40 + opmplay_opregs_channel_offset[ch], *data++);
|
||||
if (mask & OPM_CMD80_SET_TL1) OPL3_WriteRegBuffered(opl3, 0x43 + opmplay_opregs_channel_offset[ch], *data++);
|
||||
if (mask & OPM_CMD80_END_OF_FRAME) isRun = false;
|
||||
continue;
|
||||
}
|
||||
if ((*(data) & 0xF0) == OPM_SET_ADSR) {
|
||||
int mask = *data;
|
||||
int op = (mask & OPM_CMDA0_SELECT_OPERATOR ? 3 : 0) + opmplay_opregs_channel_offset[ch];
|
||||
data++;
|
||||
if (mask & OPM_CMDA0_SET_AD) OPL3_WriteRegBuffered(opl3, 0x60 + op, *data++);
|
||||
if (mask & OPM_CMDA0_SET_SR) OPL3_WriteRegBuffered(opl3, 0x80 + op, *data++);
|
||||
if (mask & OPM_CMDA0_END_OF_FRAME) isRun = false;
|
||||
continue;
|
||||
}
|
||||
if ((*(data) & 0xF0) == OPM_SET_FREQ_FB) {
|
||||
int mask = *data;
|
||||
data++;
|
||||
if (mask & OPM_CMDB0_SET_FEEDBACK) OPL3_WriteRegBuffered(opl3, 0xC0 + ch, *data++);
|
||||
if (mask & OPM_CMDB0_SET_FREQ_LOW) OPL3_WriteRegBuffered(opl3, 0xA0 + ch, *data++);
|
||||
if (mask & OPM_CMDB0_SET_FREQ_HIGH) { chctx->block = *data; OPL3_WriteRegBuffered(opl3, 0xB0 + ch, *data++); };
|
||||
if (mask & OPM_CMDB0_END_OF_FRAME) isRun = false;
|
||||
continue;
|
||||
}
|
||||
if ((*data & 0xFC) == OPM_KEY_TRIGGER) {
|
||||
if (*data & OPM_KEY_ON) chctx->block |= (1 << 5); else chctx->block &= ~(1 << 5);
|
||||
OPL3_WriteRegBuffered(opl3, 0xB0 + ch, chctx->block);
|
||||
|
@ -279,6 +288,16 @@ int opmplay_tick(opmplay_context_t* ctx, opl3_chip* opl3) {
|
|||
data++;
|
||||
continue;
|
||||
}
|
||||
if ((*data & 0xF0) == OPM_STREAM_BACKREF) {
|
||||
// back reference, nested call :)
|
||||
int distance = ((*(data + 0) & 0x0F) << 8) | (*(data + 1));
|
||||
int frames_to_play = *(data + 2);
|
||||
chctx->stream.ptr = data + 3;
|
||||
opmplay_push_stack(chctx);
|
||||
data -= distance;
|
||||
chctx->stream.samples_to_play = frames_to_play;
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for common stuff
|
||||
switch (*data) {
|
||||
|
@ -317,10 +336,21 @@ int opmplay_tick(opmplay_context_t* ctx, opl3_chip* opl3) {
|
|||
}
|
||||
}
|
||||
chctx->stream.delay = chctx->stream.reload;
|
||||
chctx->stream.ptr = data;
|
||||
|
||||
// decrement samples to play counter
|
||||
if (--chctx->stream.samples_to_play == 0) {
|
||||
// pop context from the stack
|
||||
do opmplay_pop_stack(chctx); while (--chctx->stream.samples_to_play == 0);
|
||||
}
|
||||
else {
|
||||
// save data pointer
|
||||
chctx->stream.ptr = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx->pos.frame++;
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ extern "C" {
|
|||
// general enums
|
||||
enum {
|
||||
OPMPLAY_MAX_CHANNLES = 9+1,
|
||||
OPMPLAY_MAX_STACK_DEPTH = 4,
|
||||
};
|
||||
|
||||
// return error codes
|
||||
|
@ -68,9 +69,15 @@ struct opmplay_io_t {
|
|||
uint32_t(*seek)(opmplay_io_t* io, uint32_t offset); // returns 0 if success
|
||||
};
|
||||
|
||||
struct opmplay_channel_stack_t {
|
||||
uint8_t* ptr;
|
||||
uint32_t frames_to_play;
|
||||
};
|
||||
|
||||
struct opmplay_channel_context_t {
|
||||
// TODO: internal registers (skipped atm)
|
||||
uint8_t block; // used to track key on/off changes
|
||||
// stack
|
||||
opmplay_channel_stack_t stack[OPMPLAY_MAX_STACK_DEPTH];
|
||||
uint32_t stack_pos;
|
||||
|
||||
// stream data
|
||||
struct {
|
||||
|
@ -82,6 +89,9 @@ struct opmplay_channel_context_t {
|
|||
uint8_t* ptr;
|
||||
uint8_t* loop; // if active
|
||||
} stream;
|
||||
|
||||
// internal registers
|
||||
uint8_t block; // used to track key on/off changes
|
||||
};
|
||||
|
||||
struct opmplay_context_t {
|
||||
|
|
|
@ -31,15 +31,14 @@ struct opm_control_track_t {
|
|||
enum {
|
||||
OPM_MULT = (1 << 0),
|
||||
OPM_KSL_TL = (1 << 1),
|
||||
OPM_WAVEFORM = (1 << 2),
|
||||
OPM_AD = (1 << 3),
|
||||
OPM_SR = (1 << 4),
|
||||
OPM_AD = (1 << 2),
|
||||
OPM_SR = (1 << 3),
|
||||
OPM_WAVEFORM = (1 << 4),
|
||||
OPM_OP1_SHIFT = 5,
|
||||
|
||||
OPM_FEEDBACK = (1 << 10),
|
||||
OPM_BLOCK = (1 << 10),
|
||||
OPM_FNUM = (1 << 11),
|
||||
|
||||
OPM_BLOCK = (1 << 12),
|
||||
OPM_FEEDBACK = (1 << 12),
|
||||
OPM_KEY = (1 << 13),
|
||||
|
||||
OPM_KEYPERC = (1 << 14),
|
||||
|
@ -48,6 +47,10 @@ enum {
|
|||
OPM_REG_105 = (1 << 17),
|
||||
OPM_REG_104 = (1 << 18),
|
||||
OPM_REG_BD = (1 << 19),
|
||||
|
||||
// opm_serialize_channel_stream() tweaks
|
||||
OPM_TL0 = (1 << 13),
|
||||
OPM_TL1 = (1 << 14),
|
||||
};
|
||||
|
||||
struct opm_frame_record {
|
||||
|
|
|
@ -47,10 +47,8 @@ enum {
|
|||
OPM_STREAM_BACKREF = 0xE0, // E0..EF - word backrefpos (12 bit), byte frames
|
||||
|
||||
// setter commands
|
||||
OPM_SET_VOLUME = 0x00, // 00..7F - set volume (total level) for operator, end of frame
|
||||
OPM_SET_MULT_WAVE_TL = 0x80, // 80..9F - set mult/waveform/total level/ksr for operator
|
||||
OPM_SET_ADSR = 0xA0, // A0..AF - set attack/sustain/decay/release for operator
|
||||
OPM_SET_FREQ_FB = 0xB0, // B0..BF - set frequency + feedback
|
||||
OPM_SET_OPERATOR = 0x00, // 00..7F - set operator parameters
|
||||
OPM_SET_FREQ_FB_VOL = 0x80, // 80..BF - set frequency, feedback and total level
|
||||
|
||||
// control register set
|
||||
OPM_CTRL_KEY_PERC = 0x00, // 00..7F - set key on/off for percussion, end of frame
|
||||
|
@ -63,26 +61,25 @@ enum {
|
|||
|
||||
OPM_SET_VOLUME_END_OF_FRAME = (1 << 7),
|
||||
|
||||
OPM_CMD80_SET_MULT = (1 << 0),
|
||||
OPM_CMD80_SET_TL = (1 << 1),
|
||||
OPM_CMD80_SET_WAVEFORM = (1 << 2),
|
||||
OPM_CMD80_SELECT_OPERATOR = (1 << 3),
|
||||
OPM_CMD80_END_OF_FRAME = (1 << 4),
|
||||
OPM_CMD00_SET_MULT = (1 << 0),
|
||||
OPM_CMD00_SET_TL = (1 << 1),
|
||||
OPM_CMD00_SET_AD = (1 << 2),
|
||||
OPM_CMD00_SET_SR = (1 << 3),
|
||||
OPM_CMD00_SET_WAVEFORM = (1 << 4),
|
||||
OPM_CMD00_SELECT_OPERATOR = (1 << 5),
|
||||
OPM_CMD00_END_OF_FRAME = (1 << 6),
|
||||
|
||||
OPM_CMDA0_SET_AD = (1 << 0),
|
||||
OPM_CMDA0_SET_SR = (1 << 1),
|
||||
OPM_CMDA0_SELECT_OPERATOR = (1 << 2),
|
||||
OPM_CMDA0_END_OF_FRAME = (1 << 3),
|
||||
|
||||
OPM_CMDB0_SET_FEEDBACK = (1 << 0),
|
||||
OPM_CMDB0_SET_FREQ_LOW = (1 << 1),
|
||||
OPM_CMDB0_SET_FREQ_HIGH = (1 << 2),
|
||||
OPM_CMDB0_END_OF_FRAME = (1 << 3),
|
||||
OPM_CMD80_SET_KEYBLOCK = (1 << 0),
|
||||
OPM_CMD80_SET_FREQ = (1 << 1),
|
||||
OPM_CMD80_SET_FEEDBACK = (1 << 2),
|
||||
OPM_CMD80_SET_TL0 = (1 << 3),
|
||||
OPM_CMD80_SET_TL1 = (1 << 4),
|
||||
OPM_CMD80_END_OF_FRAME = (1 << 5),
|
||||
|
||||
OPM_CTRL_SET_REG01 = (1 << 0),
|
||||
OPM_CTRL_SET_REG08 = (1 << 1),
|
||||
OPM_CTRL_SET_REG105 = (1 << 2),
|
||||
OPM_CTRL_SET_RE104 = (1 << 3),
|
||||
OPM_CTRL_SET_REG104 = (1 << 3),
|
||||
OPM_CTRL_SET_REGBD = (1 << 4),
|
||||
};
|
||||
|
||||
|
|
|
@ -599,25 +599,29 @@ int opm_serialize_channel_stream(opm_convert_context_t* ctx, int ch) {
|
|||
auto& e = s.records[i];
|
||||
struct {
|
||||
int op[2];
|
||||
int adsr[2];
|
||||
int tl_relocated;
|
||||
int freq_fb;
|
||||
bool key;
|
||||
bool key_only;
|
||||
int last;
|
||||
} mask;
|
||||
|
||||
// generate masks
|
||||
mask.last = 0; int bit = 0;
|
||||
mask.last = 0; mask.tl_relocated = 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.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.op[op] = ((e.flags >> (OPM_OP1_SHIFT * op)) & (OPM_MULT | OPM_KSL_TL | OPM_AD | OPM_SR | OPM_WAVEFORM));
|
||||
// if only TL is updated, move it to the freq/feedback command
|
||||
if (mask.op[op] == OPM_KSL_TL) {
|
||||
mask.op[op] = 0;
|
||||
mask.tl_relocated |= (OPM_TL0 << op);
|
||||
}
|
||||
mask.last |= ((mask.op[op] ? 1 : 0) << op);
|
||||
}
|
||||
mask.freq_fb = (e.flags & (OPM_FNUM | OPM_BLOCK | OPM_FEEDBACK));
|
||||
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
|
||||
mask.freq_fb = (e.flags & (OPM_BLOCK | OPM_FNUM | OPM_FEEDBACK)) | mask.tl_relocated;
|
||||
mask.last |= ((mask.freq_fb ? 4 : 0) << 0);
|
||||
mask.key_only = ((e.flags & (OPM_BLOCK | OPM_FNUM | OPM_FEEDBACK | OPM_KEY)) | (mask.tl_relocated)) == (OPM_BLOCK | OPM_KEY);
|
||||
mask.last |= ((mask.key_only ? 8 : 0) << 0);
|
||||
if (i < s.records.size() - 1)
|
||||
mask.last |= (1 << 31); // prevent non-last events from emitting eof token
|
||||
|
||||
// TODO: do it less dirty :)
|
||||
if (mask.last == 0) {
|
||||
|
@ -626,41 +630,34 @@ int opm_serialize_channel_stream(opm_convert_context_t* ctx, int ch) {
|
|||
else {
|
||||
// output tokens
|
||||
for (int op = 0; op < 2; op++) {
|
||||
// mult/tl/waveform
|
||||
// per-operator params
|
||||
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)
|
||||
OPM_SET_OPERATOR | (mask.op[op] >> 0) | (OPM_CMD00_SELECT_OPERATOR * op) |
|
||||
(mask.last == 1 ? OPM_CMD00_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);
|
||||
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_AD) s.rawdata.push_back(e.op[op].ad);
|
||||
if (mask.op[op] & OPM_SR) s.rawdata.push_back(e.op[op].sr);
|
||||
if (mask.op[op] & OPM_WAVEFORM) s.rawdata.push_back(e.op[op].waveform);
|
||||
}
|
||||
mask.last >>= 1;
|
||||
}
|
||||
// freq/feedback
|
||||
if ((mask.last & 1) && !mask.key) {
|
||||
if ((mask.last & 1) && !mask.key_only) {
|
||||
s.rawdata.push_back(
|
||||
OPM_SET_FREQ_FB | (mask.freq_fb >> 10) |
|
||||
(mask.last == 1 ? OPM_CMDB0_END_OF_FRAME : 0)
|
||||
OPM_SET_FREQ_FB_VOL | (mask.freq_fb >> 10) |
|
||||
(mask.last == 1 ? OPM_CMD80_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);
|
||||
if (mask.freq_fb & OPM_BLOCK) s.rawdata.push_back(e.block);
|
||||
if (mask.freq_fb & OPM_FNUM) s.rawdata.push_back(e.fnum);
|
||||
if (mask.freq_fb & OPM_FEEDBACK) s.rawdata.push_back(e.feedback);
|
||||
if (mask.freq_fb & OPM_TL0) s.rawdata.push_back(e.op[0].ksl_tl);
|
||||
if (mask.freq_fb & OPM_TL1) s.rawdata.push_back(e.op[1].ksl_tl);
|
||||
}
|
||||
mask.last >>= 1;
|
||||
if (mask.key) {
|
||||
if (mask.key_only) {
|
||||
s.rawdata.push_back(
|
||||
OPM_KEY_TRIGGER |
|
||||
((e.block >> 5) & 1) |
|
||||
|
@ -669,7 +666,8 @@ int opm_serialize_channel_stream(opm_convert_context_t* ctx, int ch) {
|
|||
}
|
||||
mask.last >>= 1;
|
||||
}
|
||||
} else s.rawdata.push_back(OPM_STREAM_END_FRAME);
|
||||
} else
|
||||
s.rawdata.push_back(OPM_STREAM_END_FRAME);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -693,6 +691,7 @@ int opm_concat_streams(opm_convert_context_t* ctx) {
|
|||
// copy raw register data
|
||||
ctx->oplchan_out[ch].insert(ctx->oplchan_out[ch].end(), f.rawdata.begin(), f.rawdata.end());
|
||||
}
|
||||
ctx->oplchan_out[ch].push_back(OPM_STREAM_END);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue