mirror of
https://github.com/alsa-project/alsa-tools.git
synced 2026-03-22 05:33:54 -04:00
Added MMC support by Rui Nuno Capela <rncbc@rncbc.org>
MMC support has been improved and transport LEDs is getting almost functional. Tascam control protocol sysex decoding is also complete (LEDs control mainly).
This commit is contained in:
parent
9615f45528
commit
5313c94163
7 changed files with 541 additions and 35 deletions
|
|
@ -79,3 +79,173 @@ char Cus428Midi::KnobParam[] = {
|
|||
0x36,
|
||||
0x37,
|
||||
};
|
||||
|
||||
extern int verbose;
|
||||
|
||||
|
||||
// Parse and dispatch input MIDI events.
|
||||
void Cus428Midi::ProcessMidiEvents()
|
||||
{
|
||||
snd_seq_event_t *ev;
|
||||
unsigned char *data;
|
||||
|
||||
do {
|
||||
ev = NULL;
|
||||
snd_seq_event_input(Seq, &ev);
|
||||
if (ev == NULL)
|
||||
break;
|
||||
switch (ev->type) {
|
||||
case SND_SEQ_EVENT_SYSEX:
|
||||
data = (unsigned char *) ev->data.ext.ptr;
|
||||
if (data[1] == 0x7f && data[3] == 0x06) {
|
||||
// MMC Command code is in data[4]...
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "MMC Command 0x%02x: ", data[4]);
|
||||
switch (data[4]) {
|
||||
case MMC_CMD_STOP:
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "STOP.\n");
|
||||
OneState->TransportSet(T_STOP, true);
|
||||
break;
|
||||
case MMC_CMD_PLAY:
|
||||
case MMC_CMD_DEFERRED_PLAY:
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "PLAY.\n");
|
||||
OneState->TransportSet(T_PLAY, true);
|
||||
break;
|
||||
case MMC_CMD_FAST_FORWARD:
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "FFWD.\n");
|
||||
OneState->TransportSet(T_F_FWD, true);
|
||||
break;
|
||||
case MMC_CMD_REWIND:
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "REW.\n");
|
||||
OneState->TransportSet(T_REW, true);
|
||||
break;
|
||||
case MMC_CMD_RECORD_STROBE:
|
||||
case MMC_CMD_RECORD_PAUSE:
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "RECORD ON.\n");
|
||||
OneState->TransportSet(T_RECORD, true);
|
||||
break;
|
||||
case MMC_CMD_RECORD_EXIT:
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "RECORD OFF.\n");
|
||||
OneState->TransportSet(T_RECORD, false);
|
||||
break;
|
||||
case MMC_CMD_LOCATE:
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "LOCATE WHEEL.\n");
|
||||
OneState->LocateWheel(&data[7]);
|
||||
break;
|
||||
case MMC_CMD_MMC_RESET:
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "MMC RESET.\n");
|
||||
OneState->MmcReset();
|
||||
break;
|
||||
default:
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "Not implemented.\n");
|
||||
break;
|
||||
}
|
||||
} // Look for Tascam US-224/US-428(?) specific LED codes.
|
||||
else if (data[1] == 0x4e && data[3] == 0x12) {
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "TASCAM Command 0x%02x.\n", data[4]);
|
||||
// Transport LEDs.
|
||||
switch (data[4]) {
|
||||
case 0x01: // Transport LEDs...
|
||||
switch(data[5]) {
|
||||
case 0x13: // REWIND.
|
||||
OneState->LightSet(Cus428State::eL_Rew, data[6]);
|
||||
OneState->LightSend();
|
||||
break;
|
||||
case 0x14: // FFWD.
|
||||
OneState->LightSet(Cus428State::eL_FFwd, data[6]);
|
||||
OneState->LightSend();
|
||||
break;
|
||||
case 0x16: // PLAY.
|
||||
OneState->LightSet(Cus428State::eL_Play, data[6]);
|
||||
OneState->LightSend();
|
||||
break;
|
||||
case 0x17: // REC.
|
||||
OneState->LightSet(Cus428State::eL_Record, data[6]);
|
||||
OneState->LightSend();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x02: // Mute LEDs
|
||||
OneState->LightSet(Cus428State::eL_Mute0 + data[5], data[6]);
|
||||
OneState->LightSend();
|
||||
break;
|
||||
case 0x03: // Select LEDs
|
||||
OneState->LightSet(Cus428State::eL_Select0 + data[5], data[6]);
|
||||
OneState->LightSend();
|
||||
break;
|
||||
case 0x04: // Record LEDs
|
||||
OneState->LightSet(Cus428State::eL_Rec0 + data[5], data[6]);
|
||||
OneState->LightSend();
|
||||
break;
|
||||
case 0x05: // Null LED
|
||||
OneState->LightSet(Cus428State::eL_Null, data[5]);
|
||||
OneState->LightSend();
|
||||
break;
|
||||
case 0x06: // Solo LED
|
||||
OneState->LightSet(Cus428State::eL_Solo, data[5]);
|
||||
OneState->LightSend();
|
||||
break;
|
||||
case 0x07: // Bank L LED
|
||||
OneState->LightSet(Cus428State::eL_BankL, data[5]);
|
||||
OneState->LightSend();
|
||||
break;
|
||||
case 0x08: // Bank R LED
|
||||
OneState->LightSet(Cus428State::eL_BankR, data[5]);
|
||||
OneState->LightSend();
|
||||
break;
|
||||
case 0x10: // Dump fader position.
|
||||
OneState->SliderSend(data[5]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
snd_seq_free_event(ev);
|
||||
}
|
||||
while (snd_seq_event_input_pending(Seq, 0) > 0);
|
||||
}
|
||||
|
||||
|
||||
// Send MMC command.
|
||||
void Cus428Midi::SendMmcCommand(unsigned char MmcCmd, unsigned char *MmcData, unsigned char MmcLen)
|
||||
{
|
||||
unsigned char SysexSize;
|
||||
unsigned char SysexLen;
|
||||
unsigned char *SysexData;
|
||||
|
||||
SysexSize = 6;
|
||||
if (MmcLen > 0)
|
||||
SysexSize += 1 + MmcLen;
|
||||
SysexData = (unsigned char *) alloca(SysexSize);
|
||||
SysexLen = 0;
|
||||
|
||||
SysexData[SysexLen++] = 0xf0; // Sysex header.
|
||||
SysexData[SysexLen++] = 0x7f; // Realtime sysex.
|
||||
SysexData[SysexLen++] = 0x7f; // All-caller-id.
|
||||
SysexData[SysexLen++] = 0x06; // MMC command mode.
|
||||
SysexData[SysexLen++] = MmcCmd; // MMC command code.
|
||||
if (MmcData && MmcLen > 0) {
|
||||
SysexData[SysexLen++] = MmcLen;
|
||||
memcpy(&SysexData[SysexLen], MmcData, MmcLen);
|
||||
SysexLen += MmcLen;
|
||||
}
|
||||
SysexData[SysexLen++] = 0xf7; // Sysex trailer.
|
||||
|
||||
snd_seq_ev_set_sysex(&Ev, SysexLen, SysexData);
|
||||
|
||||
SubMitEvent();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue