Blame us428control/Cus428Midi.cc

Packit 427e91
/* -*- mode:C++; indent-tabs-mode:t; tab-width:8; c-basic-offset: 8 -*- */
Packit 427e91
/*
Packit 427e91
 *
Packit 427e91
 * Copyright (c) 2003 by Karsten Wiese <annabellesgarden@yahoo.de>
Packit 427e91
 * Copyright (c) 2004-2007 by Rui Nuno Capela <rncbc@rncbc.org>
Packit 427e91
 *
Packit 427e91
 *   This program is free software; you can redistribute it and/or modify
Packit 427e91
 *   it under the terms of the GNU General Public License as published by
Packit 427e91
 *   the Free Software Foundation; either version 2 of the License, or
Packit 427e91
 *   (at your option) any later version.
Packit 427e91
 *
Packit 427e91
 *   This program is distributed in the hope that it will be useful,
Packit 427e91
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 427e91
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 427e91
 *   GNU General Public License for more details.
Packit 427e91
 *
Packit 427e91
 *   You should have received a copy of the GNU General Public License
Packit 427e91
 *   along with this program; if not, write to the Free Software
Packit 427e91
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit 427e91
 */
Packit 427e91
Packit 427e91
#include <alsa/asoundlib.h>
Packit 427e91
#include "Cus428Midi.h"
Packit 427e91
Packit 427e91
Packit 427e91
char Cus428Midi::KnobParam[] = {
Packit 427e91
	0x17,
Packit 427e91
	0x16,
Packit 427e91
	0x15,
Packit 427e91
	0x14,
Packit 427e91
	0x13,
Packit 427e91
	0x2A,
Packit 427e91
	0x29,
Packit 427e91
	0x28,
Packit 427e91
	(char)-1,
Packit 427e91
	0x10,
Packit 427e91
	0x11,
Packit 427e91
	0x18,
Packit 427e91
	0x19,
Packit 427e91
	0x1A,
Packit 427e91
	(char)-1,
Packit 427e91
	(char)-1,
Packit 427e91
	(char)-1,
Packit 427e91
	(char)-1,
Packit 427e91
	0x2C,
Packit 427e91
	0x2D,
Packit 427e91
	0x2E,
Packit 427e91
	0x2F,
Packit 427e91
	(char)-1,
Packit 427e91
	(char)-1,
Packit 427e91
	0x20,
Packit 427e91
	0x21,
Packit 427e91
	0x22,
Packit 427e91
	0x23,
Packit 427e91
	0x24,
Packit 427e91
	0x25,
Packit 427e91
	0x26,
Packit 427e91
	0x27,
Packit 427e91
	0,
Packit 427e91
	1,
Packit 427e91
	2,
Packit 427e91
	3,
Packit 427e91
	4,
Packit 427e91
	5,
Packit 427e91
	6,
Packit 427e91
	7,
Packit 427e91
	(char)-1,
Packit 427e91
	(char)-1,
Packit 427e91
	(char)-1,
Packit 427e91
	(char)-1,
Packit 427e91
	(char)-1,
Packit 427e91
	(char)-1,
Packit 427e91
	(char)-1,
Packit 427e91
	(char)-1,
Packit 427e91
	0x30,
Packit 427e91
	0x31,
Packit 427e91
	0x32,
Packit 427e91
	0x33,
Packit 427e91
	0x34,
Packit 427e91
	0x35,
Packit 427e91
	0x36,
Packit 427e91
	0x37,
Packit 427e91
};
Packit 427e91
Packit 427e91
extern int verbose;
Packit 427e91
Packit 427e91
Packit 427e91
// Parse and dispatch input MIDI events.
Packit 427e91
void Cus428Midi::ProcessMidiEvents()
Packit 427e91
{
Packit 427e91
	snd_seq_event_t *ev;
Packit 427e91
	unsigned char *data;
Packit 427e91
Packit 427e91
	do {
Packit 427e91
		ev = NULL;
Packit 427e91
		snd_seq_event_input(Seq, &ev;;
Packit 427e91
		if (ev == NULL)
Packit 427e91
			break;
Packit 427e91
		switch (ev->type) {
Packit 427e91
		case SND_SEQ_EVENT_SYSEX:
Packit 427e91
			data = (unsigned char *) ev->data.ext.ptr;
Packit 427e91
			if (data[1] == 0x7f && data[3] == 0x06) {
Packit 427e91
				// MMC Command code is in data[4]...
Packit 427e91
				if (verbose > 1)
Packit 427e91
					fprintf(stderr, "MMC Command 0x%02x: ", data[4]);
Packit 427e91
				switch (data[4]) {
Packit 427e91
				case MMC_CMD_STOP:
Packit 427e91
					if (verbose > 1)
Packit 427e91
						fprintf(stderr, "STOP.\n");
Packit 427e91
					OneState->TransportSet(T_STOP, true);
Packit 427e91
					break;
Packit 427e91
				case MMC_CMD_PLAY:
Packit 427e91
				case MMC_CMD_DEFERRED_PLAY:
Packit 427e91
					if (verbose > 1)
Packit 427e91
						fprintf(stderr, "PLAY.\n");
Packit 427e91
					OneState->TransportSet(T_PLAY, true);
Packit 427e91
					break;
Packit 427e91
				case MMC_CMD_FAST_FORWARD:
Packit 427e91
					if (verbose > 1)
Packit 427e91
						fprintf(stderr, "FFWD.\n");
Packit 427e91
					OneState->TransportSet(T_F_FWD, true);
Packit 427e91
					break;
Packit 427e91
				case MMC_CMD_REWIND:
Packit 427e91
					if (verbose > 1)
Packit 427e91
						fprintf(stderr, "REW.\n");
Packit 427e91
					OneState->TransportSet(T_REW, true);
Packit 427e91
					break;
Packit 427e91
				case MMC_CMD_RECORD_STROBE:
Packit 427e91
				case MMC_CMD_RECORD_PAUSE:
Packit 427e91
					if (verbose > 1)
Packit 427e91
						fprintf(stderr, "RECORD ON.\n");
Packit 427e91
					OneState->TransportSet(T_RECORD, true);
Packit 427e91
					break;
Packit 427e91
				case MMC_CMD_RECORD_EXIT:
Packit 427e91
					if (verbose > 1)
Packit 427e91
						fprintf(stderr, "RECORD OFF.\n");
Packit 427e91
					OneState->TransportSet(T_RECORD, false);
Packit 427e91
					break;
Packit 427e91
				case MMC_CMD_LOCATE:
Packit 427e91
					if (verbose > 1)
Packit 427e91
						fprintf(stderr, "LOCATE.\n");
Packit 427e91
					OneState->LocateWheel(&data[7]);
Packit 427e91
					break;
Packit 427e91
				case MMC_CMD_MASKED_WRITE:
Packit 427e91
					if (verbose > 1)
Packit 427e91
						fprintf(stderr, "MASKED WRITE.\n");
Packit 427e91
					OneState->MaskedWrite(&data[6]);
Packit 427e91
					break;
Packit 427e91
				case MMC_CMD_MMC_RESET:
Packit 427e91
					if (verbose > 1)
Packit 427e91
						fprintf(stderr, "MMC RESET.\n");
Packit 427e91
					OneState->MmcReset();
Packit 427e91
					break;
Packit 427e91
				default:
Packit 427e91
					if (verbose > 1)
Packit 427e91
						fprintf(stderr, "Not implemented.\n");
Packit 427e91
					break;
Packit 427e91
				}
Packit 427e91
			}	// Look for Tascam US-224/US-428(?) specific LED codes.
Packit 427e91
			else if (data[1] == 0x4e && data[3] == 0x12) {
Packit 427e91
				if (verbose > 1)
Packit 427e91
					fprintf(stderr, "TASCAM Command 0x%02x.\n", data[4]);
Packit 427e91
				// Transport LEDs.
Packit 427e91
				switch (data[4]) {
Packit 427e91
				case 0x01:		// Transport LEDs...
Packit 427e91
					switch(data[5]) {
Packit 427e91
					case 0x13:	// REWIND.
Packit 427e91
						OneState->LightSet(Cus428State::eL_Rew,  data[6]);
Packit 427e91
						OneState->LightSend();
Packit 427e91
						break;
Packit 427e91
					case 0x14:	// FFWD.
Packit 427e91
						OneState->LightSet(Cus428State::eL_FFwd, data[6]);
Packit 427e91
						OneState->LightSend();
Packit 427e91
						break;
Packit 427e91
					case 0x16:	// PLAY.
Packit 427e91
						OneState->LightSet(Cus428State::eL_Play, data[6]);
Packit 427e91
						OneState->LightSend();
Packit 427e91
						break;
Packit 427e91
					case 0x17:	// REC.
Packit 427e91
						OneState->LightSet(Cus428State::eL_Record, data[6]);
Packit 427e91
						OneState->LightSend();
Packit 427e91
						break;
Packit 427e91
					default:
Packit 427e91
						break;
Packit 427e91
					}
Packit 427e91
					break;
Packit 427e91
				case 0x02:		// Mute LEDs
Packit 427e91
					OneState->LightSet(Cus428State::eL_Mute0 + data[5], data[6]);
Packit 427e91
					OneState->LightSend();
Packit 427e91
					break;
Packit 427e91
				case 0x03:		// Select LEDs
Packit 427e91
					OneState->LightSet(Cus428State::eL_Select0 + data[5], data[6]);
Packit 427e91
					OneState->LightSend();
Packit 427e91
					break;
Packit 427e91
				case 0x04:		// Record LEDs
Packit 427e91
					OneState->LightSet(Cus428State::eL_Rec0 + data[5], data[6]);
Packit 427e91
					OneState->LightSend();
Packit 427e91
					break;
Packit 427e91
				case 0x05:		// Null LED
Packit 427e91
					OneState->LightSet(Cus428State::eL_Null, data[5]);
Packit 427e91
					OneState->LightSend();
Packit 427e91
					break;
Packit 427e91
				case 0x06:		// Solo LED
Packit 427e91
					OneState->LightSet(Cus428State::eL_Solo, data[5]);
Packit 427e91
					OneState->LightSend();
Packit 427e91
					break;
Packit 427e91
				case 0x07:		// Bank L LED
Packit 427e91
					OneState->LightSet(Cus428State::eL_BankL, data[5]);
Packit 427e91
					OneState->LightSend();
Packit 427e91
					break;
Packit 427e91
				case 0x08:		// Bank R LED
Packit 427e91
					OneState->LightSet(Cus428State::eL_BankR, data[5]);
Packit 427e91
					OneState->LightSend();
Packit 427e91
					break;
Packit 427e91
				case 0x10:		// Dump fader position.
Packit 427e91
					OneState->SliderSend(data[5]);
Packit 427e91
					break;
Packit 427e91
				}
Packit 427e91
			}
Packit 427e91
			break;
Packit 427e91
		default:
Packit 427e91
			break;
Packit 427e91
		}
Packit 427e91
		snd_seq_free_event(ev);
Packit 427e91
	}
Packit 427e91
	while (snd_seq_event_input_pending(Seq, 0) > 0);
Packit 427e91
}
Packit 427e91
Packit 427e91
Packit 427e91
// Send MMC command.
Packit 427e91
void Cus428Midi::SendMmcCommand(unsigned char MmcCmd, unsigned char *MmcData, unsigned char MmcLen)
Packit 427e91
{
Packit 427e91
	unsigned char  SysexSize;
Packit 427e91
	unsigned char  SysexLen;
Packit 427e91
	unsigned char *SysexData;
Packit 427e91
Packit 427e91
	SysexSize = 6;
Packit 427e91
	if (MmcLen > 0)
Packit 427e91
		SysexSize += 1 + MmcLen;
Packit 427e91
	SysexData = (unsigned char *) alloca(SysexSize);
Packit 427e91
	SysexLen  = 0;
Packit 427e91
Packit 427e91
	SysexData[SysexLen++] = 0xf0;	// Sysex header.
Packit 427e91
	SysexData[SysexLen++] = 0x7f;	// Realtime sysex.
Packit 427e91
	SysexData[SysexLen++] = 0x7f;	// All-caller-id.
Packit 427e91
	SysexData[SysexLen++] = 0x06;	// MMC command mode.
Packit 427e91
	SysexData[SysexLen++] = MmcCmd;	// MMC command code.
Packit 427e91
	if (MmcData && MmcLen > 0) {
Packit 427e91
		SysexData[SysexLen++] = MmcLen;
Packit 427e91
		memcpy(&SysexData[SysexLen], MmcData, MmcLen);
Packit 427e91
		SysexLen += MmcLen;
Packit 427e91
	}
Packit 427e91
	SysexData[SysexLen++] = 0xf7;	// Sysex trailer.
Packit 427e91
Packit 427e91
	snd_seq_ev_set_sysex(&Ev, SysexLen, SysexData);
Packit 427e91
Packit 427e91
	SubMitEvent();
Packit 427e91
}