Fixed coding style and IRQ handling per the spec.
Also made commands other than 0xFF ignored in UART mode, also per the spec.
This commit is contained in:
@@ -81,6 +81,7 @@ static void
|
||||
MPU401_ReCalcClock(mpu_t *mpu)
|
||||
{
|
||||
int32_t maxtempo = 240, mintempo = 16;
|
||||
int32_t freq;
|
||||
|
||||
if (mpu->clock.timebase >= 168)
|
||||
maxtempo = 179;
|
||||
@@ -94,12 +95,13 @@ MPU401_ReCalcClock(mpu_t *mpu)
|
||||
((mpu->clock.freq / 2) < maxtempo ? (mpu->clock.freq / 2) : maxtempo));
|
||||
|
||||
if (mpu->state.sync_in) {
|
||||
int32_t freq = (int32_t)((float)(mpu->clock.freq) * mpu->clock.freq_mod);
|
||||
freq = (int32_t)((float)(mpu->clock.freq) * mpu->clock.freq_mod);
|
||||
if ((freq > (mpu->clock.timebase * mintempo)) && (freq < (mpu->clock.timebase * maxtempo)))
|
||||
mpu->clock.freq = freq;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
MPU401_StartClock(mpu_t *mpu)
|
||||
{
|
||||
@@ -112,6 +114,7 @@ MPU401_StartClock(mpu_t *mpu)
|
||||
timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
MPU401_StopClock(mpu_t *mpu)
|
||||
{
|
||||
@@ -121,6 +124,7 @@ MPU401_StopClock(mpu_t *mpu)
|
||||
timer_disable(&mpu->mpu401_event_callback);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
MPU401_RunClock(mpu_t *mpu)
|
||||
{
|
||||
@@ -132,6 +136,7 @@ MPU401_RunClock(mpu_t *mpu)
|
||||
mpu401_log("Next event after %i us (time constant: %i)\n", (uint64_t) ((MPU401_TIMECONSTANT/mpu->clock.freq) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
MPU401_QueueByte(mpu_t *mpu, uint8_t data)
|
||||
{
|
||||
@@ -140,10 +145,11 @@ MPU401_QueueByte(mpu_t *mpu, uint8_t data)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((mpu->queue_used == 0) && (mpu->mode == M_INTELLIGENT)) {
|
||||
if (mpu->queue_used == 0) {
|
||||
mpu->state.irq_pending = 1;
|
||||
picint(1 << mpu->irq);
|
||||
}
|
||||
|
||||
if (mpu->queue_used < MPU401_QUEUE) {
|
||||
int pos = mpu->queue_used+mpu->queue_pos;
|
||||
|
||||
@@ -157,20 +163,22 @@ MPU401_QueueByte(mpu_t *mpu, uint8_t data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
MPU401_RecQueueBuffer(mpu_t *mpu, uint8_t *buf, uint32_t len, int block)
|
||||
{
|
||||
uint32_t cnt;
|
||||
uint32_t cnt = 0;
|
||||
int pos;
|
||||
|
||||
cnt = 0;
|
||||
while (cnt < len) {
|
||||
if (mpu->rec_queue_used < MPU401_INPUT_QUEUE) {
|
||||
int pos = mpu->rec_queue_used + mpu->rec_queue_pos;
|
||||
pos = mpu->rec_queue_used + mpu->rec_queue_pos;
|
||||
if (pos >= MPU401_INPUT_QUEUE)
|
||||
pos -= MPU401_INPUT_QUEUE;
|
||||
mpu->rec_queue[pos] = buf[cnt];
|
||||
mpu->rec_queue_used++;
|
||||
if ((!mpu->state.sysex_in_finished) && (buf[cnt] == MSG_EOX)) { /*finish sysex*/
|
||||
if ((!mpu->state.sysex_in_finished) && (buf[cnt] == MSG_EOX)) {
|
||||
/* finish sysex */
|
||||
mpu->state.sysex_in_finished = 1;
|
||||
break;
|
||||
}
|
||||
@@ -195,6 +203,7 @@ MPU401_RecQueueBuffer(mpu_t *mpu, uint8_t *buf, uint32_t len, int block)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
MPU401_ClrQueue(mpu_t *mpu)
|
||||
{
|
||||
@@ -255,7 +264,7 @@ MPU401_Reset(mpu_t *mpu)
|
||||
mpu->filter.midi_thru = 1;
|
||||
mpu->filter.commonmsgs_thru = 1;
|
||||
|
||||
/*reset channel reference and input tables*/
|
||||
/* Reset channel reference and input tables. */
|
||||
for (i = 0; i < 4; i++) {
|
||||
mpu->chanref[i].on = 1;
|
||||
mpu->chanref[i].chan = i;
|
||||
@@ -266,7 +275,7 @@ MPU401_Reset(mpu_t *mpu)
|
||||
mpu->inputref[i].on = 1;
|
||||
mpu->inputref[i].chan = i;
|
||||
if (i > 3)
|
||||
mpu->ch_toref[i] = 4;/*dummy reftable*/
|
||||
mpu->ch_toref[i] = 4; /* Dummy reftable. */
|
||||
}
|
||||
|
||||
MPU401_ClrQueue(mpu);
|
||||
@@ -276,12 +285,12 @@ MPU401_Reset(mpu_t *mpu)
|
||||
mpu->condbuf.counter = 0;
|
||||
mpu->condbuf.type = T_OVERFLOW;
|
||||
|
||||
for (i=0;i<8;i++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
mpu->playbuf[i].type = T_OVERFLOW;
|
||||
mpu->playbuf[i].counter = 0;
|
||||
}
|
||||
|
||||
/*clear MIDI buffers, terminate notes*/
|
||||
/* Clear MIDI buffers, terminate notes. */
|
||||
midi_clear_buffer();
|
||||
|
||||
for (i = 0xb0; i <= 0xbf; i++) {
|
||||
@@ -313,15 +322,20 @@ MPU401_ResetDone(void *priv)
|
||||
static void
|
||||
MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
|
||||
{
|
||||
uint8_t i, j, was_uart;
|
||||
uint8_t i, j, was_uart, recmsg[3];
|
||||
|
||||
if (mpu->state.reset)
|
||||
mpu->state.cmd_pending = val + 1;
|
||||
|
||||
/* The only command recognized in UART mode is 0xFF: Reset and return to Intelligent mode. */
|
||||
if ((val != 0xff) && (mpu->mode == M_UART))
|
||||
return;
|
||||
|
||||
/* In Intelligent mode, UART-only variants of the MPU-401 only support commands 0x3F and 0xFF. */
|
||||
if ((val != 0x3f) && (val != 0xff) && !mpu->intelligent)
|
||||
return;
|
||||
|
||||
/*hack:enable midi through after the first mpu401 command is written*/
|
||||
/* Hack: Enable midi through after the first mpu401 command is written. */
|
||||
mpu->midi_thru = 1;
|
||||
|
||||
if (val <= 0x2f) { /* Sequencer state */
|
||||
@@ -393,6 +407,7 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
|
||||
send_prchg = 1;
|
||||
MPU401_StartClock(mpu);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
MPU401_QueueByte(mpu, MSG_MPU_ACK);
|
||||
@@ -401,15 +416,20 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
|
||||
if (((val == 0x20) || (val == 0x26)) && (mpu->state.rec == M_RECON))
|
||||
MPU401_RecQueueBuffer(mpu, &rec_cnt, 1, 0);
|
||||
|
||||
if (send_prchg) for (i = 0; i < 16; i++)
|
||||
if (send_prchg) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (mpu->filter.prchg_mask & (1 << i)) {
|
||||
uint8_t recmsg[3] = {mpu->clock.rec_counter, 0xc0 | i, mpu->filter.prchg_buf[i]};
|
||||
recmsg[0] = mpu->clock.rec_counter;
|
||||
recmsg[1] = 0xc0 | i;
|
||||
recmsg[2] = mpu->filter.prchg_buf[i];
|
||||
MPU401_RecQueueBuffer(mpu, recmsg, 3, 0);
|
||||
mpu->filter.prchg_mask &= ~(1 << i);
|
||||
}
|
||||
} else if ((val >= 0xa0) && (val <= 0xa7)) { /* Request play counter */
|
||||
}
|
||||
}
|
||||
} else if ((val >= 0xa0) && (val <= 0xa7)) /* Request play counter */
|
||||
MPU401_QueueByte(mpu, mpu->playbuf[val & 7].counter);
|
||||
} else if ((val >= 0xd0) && (val <= 0xd7)) { /* Send data */
|
||||
else if ((val >= 0xd0) && (val <= 0xd7)) { /* Send data */
|
||||
mpu->state.old_track = mpu->state.track;
|
||||
mpu->state.track= val & 7;
|
||||
mpu->state.wsd = 1;
|
||||
@@ -459,7 +479,7 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
|
||||
mpu->filter.rt_in = 1;
|
||||
break;
|
||||
case 0x3f: /* UART mode */
|
||||
mpu401_log("MPU-401:Set UART mode %X\n",val);
|
||||
mpu401_log("MPU-401: Set UART mode %X\n",val);
|
||||
MPU401_QueueByte(mpu, MSG_MPU_ACK);
|
||||
mpu->mode = M_UART;
|
||||
return;
|
||||
@@ -581,7 +601,7 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
|
||||
mpu->state.command_byte = val;
|
||||
break;
|
||||
case 0xff: /* Reset MPU-401 */
|
||||
mpu401_log("MPU-401:Reset %X\n",val);
|
||||
mpu401_log("MPU-401: Reset %X\n", val);
|
||||
timer_set_delay_u64(&mpu->mpu401_reset_callback, MPU401_RESETBUSY * 33LL * TIMER_USEC);
|
||||
mpu->state.reset = 1;
|
||||
was_uart = (mpu->mode == M_UART);
|
||||
@@ -1028,6 +1048,21 @@ imf_write(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MPU401_ReadRaiseIRQ(mpu_t *mpu)
|
||||
{
|
||||
/* Clear IRQ. */
|
||||
picintc(1 << mpu->irq);
|
||||
mpu->state.irq_pending = 0;
|
||||
|
||||
if (mpu->queue_used) {
|
||||
/* Bytes remaining in queue, raise IRQ again. */
|
||||
mpu->state.irq_pending = 1;
|
||||
picint(1 << mpu->irq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
MPU401_ReadData(mpu_t *mpu)
|
||||
{
|
||||
@@ -1045,11 +1080,7 @@ MPU401_ReadData(mpu_t *mpu)
|
||||
|
||||
/* Shouldn't this check mpu->mode? */
|
||||
if (mpu->mode == M_UART) {
|
||||
if (mpu->state.irq_pending) {
|
||||
picintc(1 << mpu->irq);
|
||||
mpu->state.irq_pending = 0;
|
||||
}
|
||||
|
||||
MPU401_ReadRaiseIRQ(mpu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1059,7 +1090,7 @@ MPU401_ReadData(mpu_t *mpu)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*copy from recording buffer*/
|
||||
/* Copy from recording buffer. */
|
||||
if (!mpu->queue_used && mpu->rec_queue_used) {
|
||||
mpu->state.rec_copy = 1;
|
||||
if (mpu->rec_queue_pos >= MPU401_INPUT_QUEUE)
|
||||
@@ -1069,10 +1100,7 @@ MPU401_ReadData(mpu_t *mpu)
|
||||
mpu->rec_queue_used--;
|
||||
}
|
||||
|
||||
if (mpu->queue_used == 0) {
|
||||
picintc(1 << mpu->irq);
|
||||
mpu->state.irq_pending = 0;
|
||||
}
|
||||
MPU401_ReadRaiseIRQ(mpu);
|
||||
|
||||
if ((ret >= 0xf0) && (ret <= 0xf7)) {
|
||||
/* MIDI data request */
|
||||
@@ -1094,11 +1122,10 @@ MPU401_ReadData(mpu_t *mpu)
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret == MSG_MPU_END) || (ret == MSG_MPU_CLOCK) || (ret == MSG_MPU_ACK) || (ret == MSG_MPU_OVERFLOW)) {
|
||||
if ((ret == MSG_MPU_END) || (ret == MSG_MPU_CLOCK) || (ret == MSG_MPU_ACK) || (ret == MSG_MPU_OVERFLOW))
|
||||
MPU401_EOIHandlerDispatch(mpu);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1135,8 +1162,10 @@ mpu401_read(uint16_t addr, void *priv)
|
||||
break;
|
||||
|
||||
case 1: /* Read Status */
|
||||
if (mpu->state.cmd_pending) ret=STATUS_OUTPUT_NOT_READY;
|
||||
if (!mpu->queue_used) ret=STATUS_INPUT_NOT_READY;
|
||||
if (mpu->state.cmd_pending)
|
||||
ret = STATUS_OUTPUT_NOT_READY;
|
||||
if (!mpu->queue_used)
|
||||
ret = STATUS_INPUT_NOT_READY;
|
||||
ret |= 0x3f;
|
||||
|
||||
mpu401_log("Read Status (0x331) %x\n", ret);
|
||||
@@ -1153,6 +1182,7 @@ MPU401_Event(void *priv)
|
||||
{
|
||||
mpu_t *mpu = (mpu_t *)priv;
|
||||
uint8_t i;
|
||||
int max_meascnt;
|
||||
|
||||
mpu401_log("MPU-401 event callback\n");
|
||||
|
||||
@@ -1164,10 +1194,12 @@ MPU401_Event(void *priv)
|
||||
if (mpu->state.irq_pending) goto next_event;
|
||||
|
||||
if (mpu->state.playing) {
|
||||
for (i = 0; i < 8; i++) { /* Decrease counters */
|
||||
for (i = 0; i < 8; i++) {
|
||||
/* Decrease counters. */
|
||||
if (mpu->state.amask & (1 << i)) {
|
||||
mpu->playbuf[i].counter--;
|
||||
if (mpu->playbuf[i].counter <= 0) UpdateTrack(mpu, i);
|
||||
if (mpu->playbuf[i].counter <= 0)
|
||||
UpdateTrack(mpu, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1189,7 +1221,8 @@ MPU401_Event(void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
if (mpu->state.rec==M_RECON) { /* recording */
|
||||
if (mpu->state.rec == M_RECON) {
|
||||
/* Recording. */
|
||||
mpu->clock.rec_counter++;
|
||||
if (mpu->clock.rec_counter>=240) {
|
||||
mpu->clock.rec_counter=0;
|
||||
@@ -1198,8 +1231,9 @@ MPU401_Event(void *priv)
|
||||
}
|
||||
|
||||
if (mpu->state.playing || (mpu->state.rec == M_RECON)) {
|
||||
int max_meascnt = (mpu->clock.timebase * mpu->clock.midimetro * mpu->clock.metromeas) / 24;
|
||||
if (max_meascnt != 0) { /* measure end */
|
||||
max_meascnt = (mpu->clock.timebase * mpu->clock.midimetro * mpu->clock.metromeas) / 24;
|
||||
if (max_meascnt != 0) {
|
||||
/* Measure end. */
|
||||
if (++mpu->clock.measure_counter >= max_meascnt) {
|
||||
if (mpu->filter.rt_out)
|
||||
midi_raw_out_rt_byte(0xf8);
|
||||
@@ -1209,9 +1243,8 @@ MPU401_Event(void *priv)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!mpu->state.irq_pending && mpu->state.req_mask) {
|
||||
if (!mpu->state.irq_pending && mpu->state.req_mask)
|
||||
MPU401_EOIHandler(mpu);
|
||||
}
|
||||
|
||||
next_event:
|
||||
MPU401_RunClock(mpu);
|
||||
@@ -1219,6 +1252,7 @@ next_event:
|
||||
mpu->clock.ticks_in++;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
MPU401_NotesOff(mpu_t *mpu, int i)
|
||||
{
|
||||
@@ -1226,15 +1260,15 @@ MPU401_NotesOff(mpu_t *mpu, int i)
|
||||
uint8_t key;
|
||||
|
||||
if (mpu->filter.allnotesoff_out && !(mpu->inputref[i].on &&
|
||||
(mpu->inputref[i].key[0]|mpu->inputref[i].key[1]|
|
||||
mpu->inputref[i].key[2]|mpu->inputref[i].key[3]))) {
|
||||
(mpu->inputref[i].key[0] | mpu->inputref[i].key[1] |
|
||||
mpu->inputref[i].key[2] | mpu->inputref[i].key[3]))) {
|
||||
for (j=0;j<4;j++)
|
||||
mpu->chanref[mpu->ch_toref[i]].key[j]=0;
|
||||
midi_raw_out_byte(0xb0|i);
|
||||
midi_raw_out_byte(0xb0 | i);
|
||||
midi_raw_out_byte(123);
|
||||
midi_raw_out_byte(0);
|
||||
} else if (mpu->chanref[mpu->ch_toref[i]].on) {
|
||||
for (key=0;key<128;key++) {
|
||||
for (key = 0; key < 128; key++) {
|
||||
if ((mpu->chanref[mpu->ch_toref[i]].M_GETKEY) &&
|
||||
!(mpu->inputref[i].on && (mpu->inputref[i].M_GETKEY))) {
|
||||
midi_raw_out_byte(0x80|i);
|
||||
@@ -1246,16 +1280,17 @@ MPU401_NotesOff(mpu_t *mpu, int i)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*Input handler for SysEx */
|
||||
static int
|
||||
MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort)
|
||||
{
|
||||
mpu_t *mpu = (mpu_t *)p;
|
||||
int i;
|
||||
uint8_t val_ff = 0xff;
|
||||
|
||||
mpu401_log("MPU401 Input Sysex\n");
|
||||
|
||||
int i;
|
||||
|
||||
if (mpu->filter.sysex_in) {
|
||||
if (abort) {
|
||||
mpu->state.sysex_in_finished=1;
|
||||
@@ -1265,29 +1300,26 @@ MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort)
|
||||
if (mpu->state.sysex_in_finished) {
|
||||
if (mpu->rec_queue_used>=MPU401_INPUT_QUEUE)
|
||||
return len;
|
||||
uint8_t val_ff=0xff;
|
||||
MPU401_RecQueueBuffer(mpu,&val_ff,1,1);
|
||||
MPU401_RecQueueBuffer(mpu, &val_ff, 1, 1);
|
||||
mpu->state.sysex_in_finished=0;
|
||||
mpu->clock.rec_counter=0;
|
||||
}
|
||||
if (mpu->rec_queue_used>=MPU401_INPUT_QUEUE)
|
||||
return len;
|
||||
int available=MPU401_INPUT_QUEUE-mpu->rec_queue_used;
|
||||
int available = MPU401_INPUT_QUEUE - mpu->rec_queue_used;
|
||||
|
||||
if (available>=len) {
|
||||
MPU401_RecQueueBuffer(mpu,buffer,len,1);
|
||||
if (available >= len) {
|
||||
MPU401_RecQueueBuffer(mpu, buffer, len, 1);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
MPU401_RecQueueBuffer(mpu,buffer,available,1);
|
||||
} else {
|
||||
MPU401_RecQueueBuffer(mpu,buffer, available, 1);
|
||||
if (mpu->state.sysex_in_finished)
|
||||
return 0;
|
||||
return (len-available);
|
||||
return (len - available);
|
||||
}
|
||||
}
|
||||
else if (mpu->filter.sysex_thru && mpu->midi_thru) {
|
||||
} else if (mpu->filter.sysex_thru && mpu->midi_thru) {
|
||||
midi_raw_out_byte(0xf0);
|
||||
for (i=0;i<len;i++)
|
||||
for (i = 0; i < len; i++)
|
||||
midi_raw_out_byte(*(buffer+i));
|
||||
}
|
||||
return 0;
|
||||
@@ -1299,8 +1331,14 @@ static void
|
||||
MPU401_InputMsg(void *p, uint8_t *msg)
|
||||
{
|
||||
mpu_t *mpu = (mpu_t *)p;
|
||||
int i, tick;
|
||||
static uint8_t old_msg = 0;
|
||||
uint8_t len = msg[3], key;
|
||||
uint8_t recdata[2], recmsg[4];
|
||||
int send = 1, send_thru = 0;
|
||||
int retrigger_thru = 0, midistatus = 0, chan, chrefnum;
|
||||
|
||||
/*abort if sysex transfer is in progress*/
|
||||
/* Abort if sysex transfer is in progress. */
|
||||
if (!mpu->state.sysex_in_finished) {
|
||||
mpu401_log("SYSEX in progress\n");
|
||||
return;
|
||||
@@ -1308,58 +1346,56 @@ MPU401_InputMsg(void *p, uint8_t *msg)
|
||||
|
||||
mpu401_log("MPU401 Input Msg\n");
|
||||
|
||||
int i;
|
||||
static uint8_t old_msg=0;
|
||||
uint8_t len=msg[3];
|
||||
int send=1;
|
||||
int send_thru=0;
|
||||
int retrigger_thru=0;
|
||||
int midistatus=0;
|
||||
if (mpu->mode==M_INTELLIGENT) {
|
||||
if (msg[0]<0x80) { /* Expand running status */
|
||||
midistatus=1;
|
||||
msg[2]=msg[1];msg[1]=msg[0];msg[0]=old_msg;
|
||||
if (mpu->mode == M_INTELLIGENT) {
|
||||
if (msg[0] < 0x80) {
|
||||
/* Expand running status */
|
||||
midistatus = 1;
|
||||
msg[2] = msg[1];
|
||||
msg[1] = msg[0];
|
||||
msg[0] = old_msg;
|
||||
}
|
||||
old_msg=msg[0];
|
||||
int chan=msg[0]&0xf;
|
||||
int chrefnum=mpu->ch_toref[chan];
|
||||
uint8_t key=msg[1]&0x7f;
|
||||
if (msg[0]<0xf0) { //if non-system msg
|
||||
if (!(mpu->state.midi_mask&(1<<chan)) && mpu->filter.all_thru)
|
||||
send_thru=1;
|
||||
old_msg = msg[0];
|
||||
chan = msg[0] & 0xf;
|
||||
chrefnum = mpu->ch_toref[chan];
|
||||
key = msg[1] & 0x7f;
|
||||
if (msg[0] < 0xf0) {
|
||||
/* If non-system msg. */
|
||||
if (!(mpu->state.midi_mask & (1 << chan)) && mpu->filter.all_thru)
|
||||
send_thru = 1;
|
||||
else if (mpu->filter.midi_thru)
|
||||
send_thru=1;
|
||||
switch (msg[0]&0xf0) {
|
||||
case 0x80: /*note off*/
|
||||
send_thru = 1;
|
||||
switch (msg[0] & 0xf0) {
|
||||
case 0x80: /* Note off. */
|
||||
if (send_thru) {
|
||||
if (mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY))
|
||||
send_thru=0;
|
||||
send_thru = 0;
|
||||
if (!mpu->filter.midi_thru)
|
||||
break;
|
||||
if (!(mpu->inputref[chan].M_GETKEY))
|
||||
send_thru=0;
|
||||
send_thru = 0;
|
||||
mpu->inputref[chan].M_DELKEY;
|
||||
}
|
||||
break;
|
||||
case 0x90: /*note on*/
|
||||
case 0x90: /* Note on. */
|
||||
if (send_thru) {
|
||||
if (mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY))
|
||||
retrigger_thru=1;
|
||||
retrigger_thru = 1;
|
||||
if (!mpu->filter.midi_thru)
|
||||
break;
|
||||
if (mpu->inputref[chan].M_GETKEY)
|
||||
retrigger_thru=1;
|
||||
retrigger_thru = 1;
|
||||
mpu->inputref[chan].M_SETKEY;
|
||||
}
|
||||
break;
|
||||
case 0xb0:
|
||||
if (msg[1]>=120) {
|
||||
send_thru=0;
|
||||
if (msg[1]==123) { /* All notes off */
|
||||
for (key=0;key<128;key++) {
|
||||
if (msg[1] >= 120) {
|
||||
send_thru = 0;
|
||||
if (msg[1] == 123) {
|
||||
/* All notes off. */
|
||||
for (key = 0; key < 128; key++) {
|
||||
if (!(mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY)))
|
||||
if (mpu->inputref[chan].on && mpu->inputref[chan].M_GETKEY) {
|
||||
midi_raw_out_byte(0x80|chan);
|
||||
midi_raw_out_byte(0x80 | chan);
|
||||
midi_raw_out_byte(key);
|
||||
midi_raw_out_byte(0);
|
||||
}
|
||||
@@ -1370,128 +1406,143 @@ MPU401_InputMsg(void *p, uint8_t *msg)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (msg[0]>=0xf0 || (mpu->state.midi_mask&(1<<chan)))
|
||||
switch (msg[0]&0xf0) {
|
||||
case 0xa0: /*aftertouch*/
|
||||
}
|
||||
if ((msg[0] >= 0xf0) || (mpu->state.midi_mask & (1 << chan))) {
|
||||
switch (msg[0] & 0xf0) {
|
||||
case 0xa0: /* Aftertouch. */
|
||||
if (!mpu->filter.bender_in)
|
||||
send=0;
|
||||
send = 0;
|
||||
break;
|
||||
case 0xb0: /*control change*/
|
||||
if (!mpu->filter.bender_in && msg[1]<64)
|
||||
send=0;
|
||||
if (msg[1]>=120) {
|
||||
case 0xb0: /* Control change. */
|
||||
if (!mpu->filter.bender_in && (msg[1] < 64))
|
||||
send = 0;
|
||||
if (msg[1] >= 120) {
|
||||
if (mpu->filter.modemsgs_in)
|
||||
send=1;
|
||||
send = 1;
|
||||
}
|
||||
break;
|
||||
case 0xc0: /*program change*/
|
||||
if ((mpu->state.rec!=M_RECON) && !mpu->filter.data_in_stop) {
|
||||
mpu->filter.prchg_buf[chan]=msg[1];
|
||||
mpu->filter.prchg_mask|=1<<chan;
|
||||
case 0xc0: /* Program change. */
|
||||
if ((mpu->state.rec != M_RECON) && !mpu->filter.data_in_stop) {
|
||||
mpu->filter.prchg_buf[chan] = msg[1];
|
||||
mpu->filter.prchg_mask |= 1 << chan;
|
||||
}
|
||||
break;
|
||||
case 0xd0: /*ch pressure*/
|
||||
case 0xe0: /*pitch wheel*/
|
||||
case 0xd0: /* Ch pressure. */
|
||||
case 0xe0: /* Pitch wheel. */
|
||||
if (!mpu->filter.bender_in)
|
||||
send=0;
|
||||
send = 0;
|
||||
break;
|
||||
case 0xf0: //system message
|
||||
if (msg[0]==0xf8) {
|
||||
send=0;
|
||||
case 0xf0: /* System message. */
|
||||
if (msg[0] == 0xf8) {
|
||||
send = 0;
|
||||
if (mpu->clock.active && mpu->state.sync_in) {
|
||||
send = 0;/*don't pass to host in this mode?*/
|
||||
int tick=mpu->clock.timebase/24;
|
||||
if (mpu->clock.ticks_in!=tick) {
|
||||
if (!mpu->clock.ticks_in || (mpu->clock.ticks_in>tick*2))
|
||||
mpu->clock.freq_mod*=2.0;
|
||||
send = 0; /* Don't pass to host in this mode? */
|
||||
tick = mpu->clock.timebase / 24;
|
||||
if (mpu->clock.ticks_in != tick) {
|
||||
if (!mpu->clock.ticks_in || (mpu->clock.ticks_in > (tick * 2)))
|
||||
mpu->clock.freq_mod *= 2.0;
|
||||
else {
|
||||
if (ABS(mpu->clock.ticks_in-tick)==1)
|
||||
mpu->clock.freq_mod/=mpu->clock.ticks_in/(float)(tick*2);
|
||||
if (ABS(mpu->clock.ticks_in-tick) == 1)
|
||||
mpu->clock.freq_mod /= mpu->clock.ticks_in / (float) (tick * 2);
|
||||
else
|
||||
mpu->clock.freq_mod/=mpu->clock.ticks_in/(float)(tick);
|
||||
mpu->clock.freq_mod /= mpu->clock.ticks_in / (float) (tick);
|
||||
}
|
||||
MPU401_ReCalcClock(mpu);
|
||||
}
|
||||
mpu->clock.ticks_in=0;
|
||||
mpu->clock.ticks_in = 0;
|
||||
}
|
||||
} else if (msg[0] > 0xf8) { /* Realtime. */
|
||||
if (!(mpu->filter.rt_in && (msg[0] <= 0xfc) && (msg[0] >= 0xfa))) {
|
||||
recdata[0] = 0xff;
|
||||
recdata[1] = msg[0];
|
||||
MPU401_RecQueueBuffer(mpu, recdata, 2, 1);
|
||||
send = 0;
|
||||
}
|
||||
else if (msg[0]>0xf8) { /*realtime*/
|
||||
if (!(mpu->filter.rt_in && msg[0]<=0xfc && msg[0]>=0xfa)) {
|
||||
uint8_t recdata[2]={0xff,msg[0]};
|
||||
MPU401_RecQueueBuffer(mpu,recdata,2,1);
|
||||
send=0;
|
||||
}
|
||||
}
|
||||
else { /*common or system*/
|
||||
send=0;
|
||||
if (msg[0]==0xf2 || msg[0]==0xf3 || msg[0]==0xf6) {
|
||||
} else { /* Common or system. */
|
||||
send = 0;
|
||||
if ((msg[0] == 0xf2) || (msg[0] == 0xf3) || (msg[0] == 0xf6)) {
|
||||
if (mpu->filter.commonmsgs_in)
|
||||
send=1;
|
||||
send = 1;
|
||||
if (mpu->filter.commonmsgs_thru)
|
||||
for (i=0;i<len;i++)
|
||||
for (i = 0; i < len; i++)
|
||||
midi_raw_out_byte(msg[i]);
|
||||
}
|
||||
}
|
||||
if (send) {
|
||||
uint8_t recmsg[4]={0xff,msg[0],msg[1],msg[2]};
|
||||
MPU401_RecQueueBuffer(mpu,recmsg,len+1,1);
|
||||
recmsg[0] = 0xff;
|
||||
recmsg[1] = msg[0];
|
||||
recmsg[2] = msg[1];
|
||||
recmsg[3] = msg[2];
|
||||
MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1);
|
||||
}
|
||||
if (mpu->filter.rt_affection) switch(msg[0]) {
|
||||
case 0xf2:case 0xf3:
|
||||
mpu->state.block_ack=1;
|
||||
MPU401_WriteCommand(mpu,0xb8);/*clear play counters*/
|
||||
if (mpu->filter.rt_affection) {
|
||||
switch(msg[0]) {
|
||||
case 0xf2: case 0xf3:
|
||||
mpu->state.block_ack = 1;
|
||||
MPU401_WriteCommand(mpu, 0xb8); /* Clear play counters. */
|
||||
break;
|
||||
case 0xfa:
|
||||
mpu->state.block_ack=1;
|
||||
MPU401_WriteCommand(mpu,0xa);/*start,play*/
|
||||
mpu->state.block_ack = 1;
|
||||
MPU401_WriteCommand(mpu, 0xa); /* Start, play. */
|
||||
if (mpu->filter.rt_out)
|
||||
midi_raw_out_rt_byte(msg[0]);
|
||||
break;
|
||||
case 0xfb:
|
||||
mpu->state.block_ack=1;
|
||||
MPU401_WriteCommand(mpu,0xb);/*continue,play*/
|
||||
mpu->state.block_ack = 1;
|
||||
MPU401_WriteCommand(mpu, 0xb); /* Continue, play. */
|
||||
if (mpu->filter.rt_out)
|
||||
midi_raw_out_rt_byte(msg[0]);
|
||||
break;
|
||||
case 0xfc:
|
||||
mpu->state.block_ack=1;
|
||||
MPU401_WriteCommand(mpu,0xd);/*stop: play,rec,midi*/
|
||||
mpu->state.block_ack = 1;
|
||||
MPU401_WriteCommand(mpu, 0xd) ;/* Stop: Play, rec, midi */
|
||||
if (mpu->filter.rt_out)
|
||||
midi_raw_out_rt_byte(msg[0]);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (send_thru && mpu->midi_thru) {
|
||||
if (retrigger_thru) {
|
||||
midi_raw_out_byte(0x80|(msg[0]&0xf));
|
||||
midi_raw_out_byte(0x80 | (msg[0] & 0xf));
|
||||
midi_raw_out_byte(msg[1]);
|
||||
midi_raw_out_byte(msg[2]);
|
||||
}
|
||||
for (i=0/*((midistatus && !retrigger_thru)? 1:0)*/;i<len;i++)
|
||||
for (i = 0; i < len; i++)
|
||||
midi_raw_out_byte(msg[i]);
|
||||
}
|
||||
if (send) {
|
||||
if (mpu->state.rec==M_RECON) {
|
||||
uint8_t recmsg[4]={mpu->clock.rec_counter,msg[0],msg[1],msg[2]};
|
||||
MPU401_RecQueueBuffer(mpu,recmsg,len+1,1);
|
||||
mpu->clock.rec_counter=0;
|
||||
if (mpu->state.rec == M_RECON) {
|
||||
recmsg[0] = mpu->clock.rec_counter;
|
||||
recmsg[1] = msg[0];
|
||||
recmsg[2] = msg[1];
|
||||
recmsg[3] = msg[2];
|
||||
MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1);
|
||||
mpu->clock.rec_counter = 0;
|
||||
}
|
||||
else if (mpu->filter.data_in_stop) {
|
||||
if (mpu->filter.timing_in_stop) {
|
||||
uint8_t recmsg[4]={0,msg[0],msg[1],msg[2]};
|
||||
MPU401_RecQueueBuffer(mpu,recmsg,len+1,1);
|
||||
}
|
||||
else {
|
||||
uint8_t recmsg[4]={msg[0],msg[1],msg[2],0};
|
||||
MPU401_RecQueueBuffer(mpu,recmsg,len,1);
|
||||
recmsg[0] = 0;
|
||||
recmsg[1] = msg[0];
|
||||
recmsg[2] = msg[1];
|
||||
recmsg[3] = msg[2];
|
||||
MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1);
|
||||
} else {
|
||||
recmsg[0] = msg[0];
|
||||
recmsg[1] = msg[1];
|
||||
recmsg[2] = msg[2];
|
||||
recmsg[3] = 0;
|
||||
MPU401_RecQueueBuffer(mpu, recmsg, len, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
/*UART mode input*/
|
||||
for (i=0;i<len;i++) {
|
||||
|
||||
/* UART mode input. */
|
||||
for (i = 0; i < len; i++) {
|
||||
MPU401_QueueByte(mpu, msg[i]);
|
||||
picint(1 << mpu->irq);
|
||||
}
|
||||
@@ -1530,7 +1581,8 @@ mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode)
|
||||
void
|
||||
mpu401_device_add(void)
|
||||
{
|
||||
if (!mpu401_standalone_enable) return;
|
||||
if (!mpu401_standalone_enable)
|
||||
return;
|
||||
|
||||
if (machines[machine].flags & MACHINE_MCA)
|
||||
device_add(&mpu401_mca_device);
|
||||
|
Reference in New Issue
Block a user