summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse/muse/driver/coremidi.cpp706
-rw-r--r--muse/muse/driver/coremidi.h62
-rw-r--r--muse/muse/driver/coretimer.cpp146
-rw-r--r--muse/muse/driver/coretimer.h42
-rw-r--r--muse/muse/driver/mididev.h20
5 files changed, 976 insertions, 0 deletions
diff --git a/muse/muse/driver/coremidi.cpp b/muse/muse/driver/coremidi.cpp
new file mode 100644
index 00000000..6abfe43c
--- /dev/null
+++ b/muse/muse/driver/coremidi.cpp
@@ -0,0 +1,706 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: alsamidi.cpp,v 1.35 2006/04/20 10:07:34 wschweer Exp $
+// (C) Copyright 2000-2001 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#include "coremidi.h"
+#include "globals.h"
+#include "midi.h"
+#include "../midiseq.h"
+#include "../song.h"
+#include "al/pos.h"
+
+//static const unsigned int inCap = SND_SEQ_PORT_CAP_SUBS_READ;
+//static const unsigned int outCap = SND_SEQ_PORT_CAP_SUBS_WRITE;
+
+CoreMidi coreMidi;
+CoreMidi* midiDriver;
+
+//---------------------------------------------------------
+// CoreMidi
+//---------------------------------------------------------
+
+CoreMidi::CoreMidi()
+ {
+ //alsaSeq = 0;
+ }
+
+//---------------------------------------------------------
+// init
+// return true on error
+//---------------------------------------------------------
+
+bool CoreMidi::init()
+ {
+ if (debugMsg)
+ printf("init CoreMidi\n");
+/* int error = snd_seq_open(&alsaSeq, "hw", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK);
+ if (error < 0) {
+ fprintf(stderr, "open ALSA sequencer failed: %s\n",
+ snd_strerror(error));
+ return true;
+ }
+
+ snd_seq_set_client_name(alsaSeq, "MusE Sequencer");
+
+ //-----------------------------------------
+ // subscribe to "Announce"
+ // this enables callbacks for any
+ // alsa port changes
+ //-----------------------------------------
+
+ snd_seq_addr_t src, dst;
+ int rv = snd_seq_create_simple_port(alsaSeq, "MusE Port 0",
+ inCap | outCap | SND_SEQ_PORT_CAP_READ
+ | SND_SEQ_PORT_CAP_WRITE
+ | SND_SEQ_PORT_CAP_NO_EXPORT,
+ SND_SEQ_PORT_TYPE_APPLICATION);
+ if (rv < 0) {
+ fprintf(stderr, "Alsa: create MusE port failed: %s\n", snd_strerror(error));
+ exit(1);
+ }
+ dst.port = rv;
+ dst.client = snd_seq_client_id(alsaSeq);
+ src.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE;
+ src.client = SND_SEQ_CLIENT_SYSTEM;
+
+ snd_seq_port_subscribe_t* subs;
+ snd_seq_port_subscribe_alloca(&subs);
+ snd_seq_port_subscribe_set_dest(subs, &dst);
+ snd_seq_port_subscribe_set_sender(subs, &src);
+ error = snd_seq_subscribe_port(alsaSeq, subs);
+ if (error < 0) {
+ fprintf(stderr, "Alsa: Subscribe System failed: %s\n", snd_strerror(error));
+ return true;
+ }
+
+ return false;*/
+ return false;
+ }
+
+//---------------------------------------------------------
+// outputPorts
+//---------------------------------------------------------
+
+std::list<PortName>* CoreMidi::outputPorts()
+ {
+ std::list<PortName>* clientList = new std::list<PortName>;
+/* snd_seq_client_info_t* cinfo;
+ snd_seq_client_info_alloca(&cinfo);
+ snd_seq_client_info_set_client(cinfo, 0);
+
+ while (snd_seq_query_next_client(alsaSeq, cinfo) >= 0) {
+ snd_seq_port_info_t *pinfo;
+ snd_seq_port_info_alloca(&pinfo);
+ snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
+ snd_seq_port_info_set_port(pinfo, -1);
+ while (snd_seq_query_next_port(alsaSeq, pinfo) >= 0) {
+ unsigned int capability = snd_seq_port_info_get_capability(pinfo);
+ if (((capability & outCap) == outCap)
+ && !(capability & SND_SEQ_PORT_CAP_NO_EXPORT)) {
+ int client = snd_seq_port_info_get_client(pinfo);
+ if (client != snd_seq_client_id(alsaSeq)) {
+ PortName pn;
+ pn.name = QString(snd_seq_port_info_get_name(pinfo));
+ snd_seq_addr_t* adr = new snd_seq_addr_t;
+ adr->port = snd_seq_port_info_get_port(pinfo);
+ adr->client = client;
+ pn.port = adr;
+ clientList->push_back(pn);
+ }
+ }
+ }
+ }*/
+ return clientList;
+ }
+
+//---------------------------------------------------------
+// inputPorts
+//---------------------------------------------------------
+
+std::list<PortName>* CoreMidi::inputPorts()
+ {
+ std::list<PortName>* clientList = new std::list<PortName>;
+
+ /* snd_seq_client_info_t* cinfo;
+ snd_seq_client_info_alloca(&cinfo);
+ snd_seq_client_info_set_client(cinfo, 0);
+
+ while (snd_seq_query_next_client(alsaSeq, cinfo) >= 0) {
+ snd_seq_port_info_t *pinfo;
+ snd_seq_port_info_alloca(&pinfo);
+ snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
+ snd_seq_port_info_set_port(pinfo, -1);
+ while (snd_seq_query_next_port(alsaSeq, pinfo) >= 0) {
+ unsigned int capability = snd_seq_port_info_get_capability(pinfo);
+ if (((capability & inCap) == inCap)
+ && !(capability & SND_SEQ_PORT_CAP_NO_EXPORT)) {
+ int client = snd_seq_port_info_get_client(pinfo);
+ if (client != snd_seq_client_id(alsaSeq)) {
+ PortName pn;
+ pn.name = QString(snd_seq_port_info_get_name(pinfo));
+ snd_seq_addr_t* adr = new snd_seq_addr_t;
+ adr->port = snd_seq_port_info_get_port(pinfo);
+ adr->client = client;
+ pn.port = adr;
+ clientList->push_back(pn);
+ }
+ }
+ }
+ }*/
+ return clientList;
+ }
+
+//---------------------------------------------------------
+// registerOutPort
+//---------------------------------------------------------
+
+Port CoreMidi::registerOutPort(const QString& name)
+ {
+// int port = snd_seq_create_simple_port(alsaSeq, name.toLatin1().data(),
+// outCap | SND_SEQ_PORT_CAP_WRITE, SND_SEQ_PORT_TYPE_APPLICATION);
+// if (port < 0) {
+// perror("create port");
+// exit(1);
+// }
+// snd_seq_addr_t* adr = new snd_seq_addr_t;
+// adr->port = port;
+// adr->client = snd_seq_client_id(alsaSeq);
+// return adr;
+ return 0;
+ }
+
+//---------------------------------------------------------
+// equal
+//---------------------------------------------------------
+
+bool CoreMidi::equal(Port p1, Port p2)
+ {
+/* snd_seq_addr_t* a1 = (snd_seq_addr_t*)(p1);
+ snd_seq_addr_t* a2 = (snd_seq_addr_t*)(p2);
+ return (a1->port == a2->port) && (a1->client == a2->client);*/
+ return false;
+ }
+
+//---------------------------------------------------------
+// registerInPort
+//---------------------------------------------------------
+
+Port CoreMidi::registerInPort(const QString& name)
+ {
+/* int port = snd_seq_create_simple_port(alsaSeq, name.toLatin1().data(),
+ inCap | SND_SEQ_PORT_CAP_READ, SND_SEQ_PORT_TYPE_APPLICATION);
+ if (port < 0) {
+ perror("create port");
+ exit(1);
+ }
+ snd_seq_addr_t* adr = new snd_seq_addr_t;
+ adr->port = port;
+ adr->client = snd_seq_client_id(alsaSeq);
+ return adr;*/
+ return 0;
+ }
+
+//---------------------------------------------------------
+// unregisterPort
+//---------------------------------------------------------
+
+void CoreMidi::unregisterPort(Port port)
+ {
+/* snd_seq_delete_simple_port(alsaSeq, AlsaPort(port)->port);
+ delete (snd_seq_addr_t*)port;*/
+ }
+
+//---------------------------------------------------------
+// setPortName
+//---------------------------------------------------------
+
+void CoreMidi::setPortName(Port, const QString& name)
+ {
+ printf("CoreMidi::setPortName(%s): not impl.\n", name.toLatin1().data());
+ }
+
+//---------------------------------------------------------
+// portName
+//---------------------------------------------------------
+
+QString CoreMidi::portName(Port p)
+ {
+/* snd_seq_port_info_t* pinfo;
+ snd_seq_port_info_alloca(&pinfo);
+ snd_seq_get_any_port_info(alsaSeq, AlsaPort(p)->client, AlsaPort(p)->port, pinfo);
+ return QString(snd_seq_port_info_get_name(pinfo));*/
+ return "port";
+ }
+
+//---------------------------------------------------------
+// findPort
+//---------------------------------------------------------
+
+Port CoreMidi::findPort(const QString& name)
+ {
+/* snd_seq_addr_t* adr = new snd_seq_addr_t;
+ adr->port = 0;
+ adr->client = 0;
+
+ snd_seq_client_info_t* cinfo;
+ snd_seq_client_info_alloca(&cinfo);
+ snd_seq_client_info_set_client(cinfo, 0);
+
+ while (snd_seq_query_next_client(alsaSeq, cinfo) >= 0) {
+ snd_seq_port_info_t *pinfo;
+ snd_seq_port_info_alloca(&pinfo);
+ snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
+ snd_seq_port_info_set_port(pinfo, -1);
+ while (snd_seq_query_next_port(alsaSeq, pinfo) >= 0) {
+ const char* pn = snd_seq_port_info_get_name(pinfo);
+ if (name == pn) {
+ snd_seq_addr_t* adr = new snd_seq_addr_t;
+ *adr = *snd_seq_port_info_get_addr(pinfo);
+ return adr;
+ }
+ }
+ }
+ printf("CoreMidi: port <%s> not found\n", name.toLatin1().data());*/
+ return 0;
+ }
+
+//---------------------------------------------------------
+// connect
+// return false if connect fails
+//---------------------------------------------------------
+
+bool CoreMidi::connect(Port src, Port dst)
+ {
+/* if (((AlsaPort)dst) == 0) {
+ printf("CoreMidi::connect failed: invalid alsa port\n");
+ return false;
+ }
+ snd_seq_port_subscribe_t* sub;
+ snd_seq_port_subscribe_alloca(&sub);
+
+ snd_seq_port_subscribe_set_sender(sub, (AlsaPort)src);
+ snd_seq_port_subscribe_set_dest(sub, (AlsaPort)dst);
+ int rv = snd_seq_subscribe_port(alsaSeq, sub);
+ if (rv < 0) {
+ printf("CoreMidi::connect(%d:%d, %d:%d) failed: %s\n",
+ ((AlsaPort)src)->client, ((AlsaPort)src)->port,
+ ((AlsaPort)dst)->client, ((AlsaPort)dst)->port,
+ snd_strerror(rv));
+ return false;
+ }*/
+ return true;
+ }
+
+//---------------------------------------------------------
+// disconnect
+// return false if disconnect fails
+//---------------------------------------------------------
+
+bool CoreMidi::disconnect(Port src, Port dst)
+ {
+/* snd_seq_port_subscribe_t* sub;
+ snd_seq_port_subscribe_alloca(&sub);
+ snd_seq_port_subscribe_set_sender(sub, (AlsaPort)src);
+ snd_seq_port_subscribe_set_dest(sub, (AlsaPort)dst);
+ int rv = snd_seq_unsubscribe_port(alsaSeq, sub);
+ if (rv < 0)
+ printf("CoreMidi::disconnect() failed: %s\n",
+ snd_strerror(rv));
+ return rv >= 0;*/
+ return true;
+ }
+
+//---------------------------------------------------------
+// getInputPollFd
+//---------------------------------------------------------
+
+void CoreMidi::getInputPollFd(struct pollfd** p, int* n)
+ {
+/* int npfdi = snd_seq_poll_descriptors_count(alsaSeq, POLLIN);
+ struct pollfd* pfdi = new struct pollfd[npfdi];
+ snd_seq_poll_descriptors(alsaSeq, pfdi, npfdi, POLLIN);
+ *p = pfdi;
+ *n = npfdi;*/
+ *n=0;
+ }
+
+//---------------------------------------------------------
+// getOutputPollFd
+//---------------------------------------------------------
+
+void CoreMidi::getOutputPollFd(struct pollfd** p, int* n)
+ {
+/* int npfdo = snd_seq_poll_descriptors_count(alsaSeq, POLLOUT);
+ struct pollfd* pfdo = new struct pollfd[npfdo];
+ snd_seq_poll_descriptors(alsaSeq, pfdo, npfdo, POLLOUT);
+ *p = pfdo;
+ *n = npfdo;*/
+ n=0;
+ }
+
+//---------------------------------------------------------
+// addConnection
+// a new connection was added
+//---------------------------------------------------------
+
+/*void CoreMidi::addConnection(snd_seq_connect_t* ev)
+ {
+ Port rs = Port(&ev->sender);
+ Port rd = Port(&ev->dest);
+
+ MidiOutPortList* opl = song->midiOutPorts();
+ for (iMidiOutPort i = opl->begin(); i != opl->end(); ++i) {
+ MidiOutPort* oport = *i;
+ Port src = oport->port();
+
+ if (equal(src, rs)) {
+ RouteList* orl = oport->outRoutes();
+ iRoute ir;
+ for (ir = orl->begin(); ir != orl->end(); ++ir) {
+ Port dst = ir->port;
+ if (equal(dst, rd))
+ break;
+ }
+ if (ir == orl->end()) {
+ snd_seq_addr_t* adr = new snd_seq_addr_t(ev->dest);
+ orl->push_back(Route(Port(adr), Route::MIDIPORT));
+ }
+ break;
+ }
+ }
+
+ MidiInPortList* ipl = song->midiInPorts();
+ for (iMidiInPort i = ipl->begin(); i != ipl->end(); ++i) {
+ MidiInPort* iport = *i;
+ Port dst = iport->port();
+
+ if (equal(dst, rd)) {
+ RouteList* irl = iport->inRoutes();
+ iRoute ir;
+ for (ir = irl->begin(); ir != irl->end(); ++ir) {
+ Port src = ir->port;
+ if (equal(src, rs))
+ break;
+ }
+ if (ir == irl->end()) {
+ snd_seq_addr_t* adr = new snd_seq_addr_t(ev->sender);
+ irl->push_back(Route(Port(adr), Route::MIDIPORT));
+ }
+ break;
+ }
+ }
+ }
+*/
+//---------------------------------------------------------
+// removeConnection
+// a connection was removed
+//---------------------------------------------------------
+/*
+void CoreMidi::removeConnection(snd_seq_connect_t* ev)
+ {
+ Port rs = Port(&ev->sender);
+ Port rd = Port(&ev->dest);
+
+ MidiInPortList* ipl = song->midiInPorts();
+ for (iMidiInPort i = ipl->begin(); i != ipl->end(); ++i) {
+ MidiInPort* iport = *i;
+ Port dst = iport->port();
+
+ if (equal(dst, rd)) {
+ RouteList* irl = iport->inRoutes();
+ for (iRoute ir = irl->begin(); ir != irl->end(); ++ir) {
+ Port src = ir->port;
+
+ if (equal(src, rs)) {
+ irl->erase(ir);
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ MidiOutPortList* opl = song->midiOutPorts();
+ for (iMidiOutPort i = opl->begin(); i != opl->end(); ++i) {
+ MidiOutPort* oport = *i;
+ Port src = oport->port();
+
+ if (equal(src, rs)) {
+ RouteList* orl = oport->outRoutes();
+ for (iRoute r = orl->begin(); r != orl->end(); ++r) {
+ Port dst = r->port;
+
+ if (equal(dst, rd)) {
+ orl->erase(r);
+printf("REMOVE OUT connection\n");
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+*/
+//---------------------------------------------------------
+// read
+// read ALSA midi events
+// This is called by the high priority RT MidiSeq
+// thread.
+//---------------------------------------------------------
+
+void CoreMidi::read(MidiSeq* seq)
+ {
+/* snd_seq_event_t* ev;
+ for (int i = 0;; ++i) {
+ int rv = snd_seq_event_input(alsaSeq, &ev);
+ if (rv <= 0) {
+ if (rv < 0 && rv != -11) // Resource temporarily unavailable
+ printf("CoreMidi: read error 0x%x %s\n", rv, snd_strerror(rv));
+ break;
+ }
+// printf("Alsa midi event %d %d\n", rv, ev->type);
+
+ switch(ev->type) {
+ case SND_SEQ_EVENT_PORT_SUBSCRIBED:
+ // printf("subscribe\n");
+ addConnection((snd_seq_connect_t*)(&ev->data));
+ break;
+ case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
+ // printf("unsubscribe\n");
+ removeConnection((snd_seq_connect_t*)(&ev->data));
+ break;
+ case SND_SEQ_EVENT_CLIENT_START:
+ // printf("client start\n");
+ break;
+ case SND_SEQ_EVENT_CLIENT_EXIT:
+ // printf("client exit\n");
+ break;
+ case SND_SEQ_EVENT_PORT_START:
+ // printf("port start\n");
+ break;
+ case SND_SEQ_EVENT_PORT_EXIT:
+ // printf("port exit\n");
+ break;
+ case SND_SEQ_EVENT_SYSEX:
+ {
+ //
+ // look for Midi Machine Control events (MMC)
+ //
+ unsigned char* data = ((unsigned char*)ev->data.ext.ptr) + 1;
+ int len = ev->data.ext.len - 2;
+ if ((len == 4) && (data[0] == 0x7f) && (data[2] == 0x06)) {
+ seq->mmcInput(data[1], data[3], 0);
+ break;
+ }
+ if ((len == 11) && (data[0] == 0x7f)
+ && (data[2] == 0x06)
+ && (data[3] == 0x44) && (data[4] == 0x06)
+ && (data[5] == 0x1)) {
+ int h = data[6];
+ int m = data[7];
+ int s = data[8];
+ int f = data[9];
+ int sf = data[10];
+ AL::Pos pos(h * 60 + m, s, f, sf);
+ seq->mmcInput(data[1], data[3], pos);
+ break;
+ }
+ }
+
+ case SND_SEQ_EVENT_KEYPRESS:
+ case SND_SEQ_EVENT_CHANPRESS:
+ case SND_SEQ_EVENT_NOTEON:
+ case SND_SEQ_EVENT_NOTEOFF:
+ case SND_SEQ_EVENT_PGMCHANGE:
+ case SND_SEQ_EVENT_PITCHBEND:
+ case SND_SEQ_EVENT_CONTROLLER:
+ {
+ Port port = &ev->dest;
+ MidiInPortList* mpl = song->midiInPorts();
+ for (iMidiInPort i = mpl->begin(); i != mpl->end(); ++i) {
+ MidiInPort* inPort = *i;
+ if (equal(port, inPort->port())) {
+ inPort->eventReceived(ev);
+ }
+ }
+ }
+ break;
+
+ case SND_SEQ_EVENT_CLOCK:
+ seq->realtimeSystemInput(0, 0xf8);
+ break;
+ case SND_SEQ_EVENT_START:
+ seq->realtimeSystemInput(0, 0xfa);
+ break;
+ case SND_SEQ_EVENT_CONTINUE:
+ seq->realtimeSystemInput(0, 0xfb);
+ break;
+ case SND_SEQ_EVENT_STOP:
+ seq->realtimeSystemInput(0, 0xfc);
+ break;
+ case SND_SEQ_EVENT_TICK:
+ seq->realtimeSystemInput(0, 0xf9);
+ break;
+ case SND_SEQ_EVENT_SONGPOS:
+ seq->setSongPosition(0, ev->data.control.value);
+ break;
+ case SND_SEQ_EVENT_SENSING:
+ break;
+ case SND_SEQ_EVENT_QFRAME:
+ seq->mtcInputQuarter(0, ev->data.control.value);
+ break;
+ // case SND_SEQ_EVENT_CLIENT_START:
+ // case SND_SEQ_EVENT_CLIENT_EXIT:
+ // case SND_SEQ_EVENT_CLIENT_CHANGE:
+ // case SND_SEQ_EVENT_PORT_CHANGE:
+ // case SND_SEQ_EVENT_SONGSEL:
+ // case SND_SEQ_EVENT_TIMESIGN:
+ // case SND_SEQ_EVENT_KEYSIGN:
+ // case SND_SEQ_EVENT_SETPOS_TICK:
+ // case SND_SEQ_EVENT_SETPOS_TIME:
+ // case SND_SEQ_EVENT_TEMPO:
+ // case SND_SEQ_EVENT_TUNE_REQUEST:
+ // case SND_SEQ_EVENT_RESET:
+ // case SND_SEQ_EVENT_NOTE:
+ // case SND_SEQ_EVENT_CONTROL14:
+ // case SND_SEQ_EVENT_NONREGPARAM:
+ // case SND_SEQ_EVENT_REGPARAM:
+ default:
+ printf("ALSA Midi input: type %d not handled\n", ev->type);
+ break;
+ }
+ snd_seq_free_event(ev);
+ }*/
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void CoreMidi::write()
+ {
+ }
+
+//---------------------------------------------------------
+// putEvent
+//---------------------------------------------------------
+
+void CoreMidi::putEvent(Port p, const MidiEvent& e)
+ {
+/* if (midiOutputTrace) {
+ printf("MidiOut<%s>: midiAlsa: ", portName(p).toLatin1().data());
+ e.dump();
+ }
+ int chn = e.channel();
+ int a = e.dataA();
+ int b = e.dataB();
+
+ snd_seq_event_t event;
+ memset(&event, 0, sizeof(event));
+ snd_seq_ev_set_direct(&event);
+ snd_seq_ev_set_source(&event, ((snd_seq_addr_t*)p)->port);
+ snd_seq_ev_set_dest(&event, SND_SEQ_ADDRESS_SUBSCRIBERS, 0);
+
+ switch(e.type()) {
+ case ME_NOTEON:
+ snd_seq_ev_set_noteon(&event, chn, a, b);
+ break;
+ case ME_NOTEOFF:
+ snd_seq_ev_set_noteoff(&event, chn, a, 0);
+ break;
+ case ME_PROGRAM:
+ snd_seq_ev_set_pgmchange(&event, chn, a);
+ break;
+ case ME_CONTROLLER:
+ snd_seq_ev_set_controller(&event, chn, a, b);
+ break;
+ case ME_PITCHBEND:
+ snd_seq_ev_set_pitchbend(&event, chn, a);
+ break;
+ case ME_POLYAFTER:
+ // chnEvent2(chn, 0xa0, a, b);
+ break;
+ case ME_AFTERTOUCH:
+ snd_seq_ev_set_chanpress(&event, chn, a);
+ break;
+ case ME_SYSEX:
+ {
+ const unsigned char* p = e.data();
+ int n = e.len();
+ int len = n + sizeof(event) + 2;
+ char buf[len];
+ event.type = SND_SEQ_EVENT_SYSEX;
+ event.flags = SND_SEQ_EVENT_LENGTH_VARIABLE;
+ event.data.ext.len = n + 2;
+ event.data.ext.ptr = (void*)(buf + sizeof(event));
+ memcpy(buf, &event, sizeof(event));
+ char* pp = buf + sizeof(event);
+ *pp++ = 0xf0;
+ memcpy(pp, p, n);
+ pp += n;
+ *pp = 0xf7;
+ putEvent(&event);
+ return;
+ }
+ case ME_SONGPOS:
+ event.data.control.value = a;
+ event.type = SND_SEQ_EVENT_SONGPOS;
+ break;
+ case ME_CLOCK:
+ event.type = SND_SEQ_EVENT_CLOCK;
+ break;
+ case ME_START:
+ event.type = SND_SEQ_EVENT_START;
+ break;
+ case ME_CONTINUE:
+ event.type = SND_SEQ_EVENT_CONTINUE;
+ break;
+ case ME_STOP:
+ event.type = SND_SEQ_EVENT_STOP;
+ break;
+ default:
+ printf("MidiAlsaDevice::putEvent(): event type %d not implemented\n",
+ e.type());
+ return;
+ }
+ putEvent(&event);*/
+ }
+
+//---------------------------------------------------------
+// putEvent
+// return false if event is delivered
+//---------------------------------------------------------
+
+// bool CoreMidi::putEvent(snd_seq_event_t* event)
+// {
+// int error;
+//
+// do {
+// error = snd_seq_event_output_direct(alsaSeq, event);
+// int len = snd_seq_event_length(event);
+// if (error == len) {
+// // printf(".");fflush(stdout);
+// return false;
+// }
+// if (error < 0) {
+// if (error == -12) {
+// // printf("?");fflush(stdout);
+// return true;
+// }
+// else {
+// fprintf(stderr, "MidiAlsaDevice::%p putEvent(): midi write error: %s\n",
+// this, snd_strerror(error));
+// //exit(-1);
+// }
+// }
+// else
+// fprintf(stderr, "MidiAlsaDevice::putEvent(): midi write returns %d, expected %d: %s\n",
+// error, len, snd_strerror(error));
+// } while (error == -12);
+// return true;
+// }
+
+
diff --git a/muse/muse/driver/coremidi.h b/muse/muse/driver/coremidi.h
new file mode 100644
index 00000000..cca3ddf2
--- /dev/null
+++ b/muse/muse/driver/coremidi.h
@@ -0,0 +1,62 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: alsamidi.h,v 1.10 2005/12/19 16:16:27 wschweer Exp $
+// (C) Copyright 2001 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#ifndef __COREMIDI_H__
+#define __COREMIDI_H__
+
+// #include <config.h>
+//#include <alsa/asoundlib.h>
+
+#include "driver.h"
+
+class MidiSeq;
+class MidiEvent;
+
+//typedef snd_seq_addr_t* AlsaPort;
+
+//---------------------------------------------------------
+// CoreMidi
+//---------------------------------------------------------
+
+class CoreMidi : public Driver {
+ //snd_seq_t* alsaSeq;
+
+// void removeConnection(snd_seq_connect_t* ev);
+// void addConnection(snd_seq_connect_t* ev);
+
+ public:
+ CoreMidi();
+ virtual bool init();
+
+ virtual std::list<PortName>* outputPorts();
+ virtual std::list<PortName>* inputPorts();
+
+ virtual Port registerOutPort(const QString& name);
+ virtual Port registerInPort(const QString& name);
+ virtual void unregisterPort(Port);
+ virtual void setPortName(Port p, const QString& n);
+ virtual QString portName(Port);
+ virtual Port findPort(const QString& name);
+ virtual bool equal(Port, Port);
+
+ virtual bool connect(Port, Port);
+ virtual bool disconnect(Port, Port);
+
+ void getInputPollFd(struct pollfd**, int* n);
+ void getOutputPollFd(struct pollfd**, int* n);
+
+ void read(MidiSeq*); // process events
+ void write();
+
+ void putEvent(Port, const MidiEvent&);
+ //bool putEvent(snd_seq_event_t* event);
+ };
+
+extern CoreMidi coreMidi;
+extern CoreMidi* midiDriver;
+#endif
+
diff --git a/muse/muse/driver/coretimer.cpp b/muse/muse/driver/coretimer.cpp
new file mode 100644
index 00000000..2c2da475
--- /dev/null
+++ b/muse/muse/driver/coretimer.cpp
@@ -0,0 +1,146 @@
+ //=========================================================
+ // MusE
+ // Linux Music Editor
+ // $Id: rtctimer.cpp,v 1.1.2.8 2006/01/13 18:10:55 wschweer Exp $
+ //
+ // Most code moved from midiseq.cpp by Werner Schweer.
+ //
+ // (C) Copyright 2004 Robert Jonsson (rj@spamatica.se)
+ // (C) Copyright -2004 Werner Schweer (werner@seh.de)
+ //=========================================================
+
+#include "coretimer.h"
+#include "globals.h"
+#include "gconfig.h"
+
+
+CoreTimer::CoreTimer()
+ {
+ timerFd = -1;
+ }
+
+CoreTimer::~CoreTimer()
+ {
+ if (timerFd != -1)
+ close(timerFd);
+ }
+
+bool CoreTimer::initTimer()
+ {
+ if(TIMER_DEBUG)
+ printf("CoreTimer::initTimer()\n");
+/* if (timerFd != -1) {
+ fprintf(stderr,"CoreTimer::initTimer(): called on initialised timer!\n");
+ return -1;
+ }
+ doSetuid();
+
+ timerFd = ::open("/dev/rtc", O_RDONLY);
+ if (timerFd == -1) {
+ fprintf(stderr, "fatal error: open /dev/rtc failed: %s\n", strerror(errno));
+ undoSetuid();
+ return timerFd;
+ }
+ if (!setTimerFreq(config.rtcTicks)) {
+ // unable to set timer frequency
+ return -1;
+ }
+ // check if timer really works, start and stop it once.
+ if (!startTimer()) {
+ return -1;
+ }
+ if (!stopTimer()) {
+ return -1;
+ }
+*/
+ return true;
+ }
+
+unsigned int CoreTimer::setTimerResolution(unsigned int resolution)
+ {
+ if(TIMER_DEBUG)
+ printf("CoreTimer::setTimerResolution(%d)\n",resolution);
+ /* The RTC can take power-of-two frequencies from 2 to 8196 Hz.
+ * It doesn't really have a resolution as such.
+ */
+ return 0;
+ }
+
+bool CoreTimer::setTimerFreq(unsigned int freq)
+ {
+/* int rc = ioctl(timerFd, RTC_IRQP_SET, freq);
+ if (rc == -1) {
+ fprintf(stderr, "CoreTimer::setTimerFreq(): cannot set tick on /dev/rtc: %s\n",
+ strerror(errno));
+ fprintf(stderr, " precise timer not available\n");
+ return 0;
+ }
+*/
+ return true ;
+ }
+
+int CoreTimer::getTimerResolution()
+ {
+ /* The RTC doesn't really work with a set resolution as such.
+ * Not sure how this fits into things yet.
+ */
+ return 0;
+ }
+
+unsigned int CoreTimer::getTimerFreq()
+ {
+ unsigned int freq;
+/* int rv = ioctl(timerFd, RTC_IRQP_READ, &freq);
+ if (rv < 1)
+ return 0;
+*/
+ return freq;
+ }
+
+bool CoreTimer::startTimer()
+ {
+ if(TIMER_DEBUG)
+ printf("CoreTimer::startTimer()\n");
+/* if (timerFd == -1) {
+ fprintf(stderr, "CoreTimer::startTimer(): no timer open to start!\n");
+ return false;
+ }
+ if (ioctl(timerFd, RTC_PIE_ON, 0) == -1) {
+ perror("MidiThread: start: RTC_PIE_ON failed");
+ undoSetuid();
+ return false;
+ }
+*/ return true;
+ }
+
+bool CoreTimer::stopTimer()
+ {
+/* if(TIMER_DEBUG)
+ printf("CoreTimer::stopTimer\n");
+ if (timerFd != -1) {
+ ioctl(timerFd, RTC_PIE_OFF, 0);
+ }
+ else {
+ fprintf(stderr,"CoreTimer::stopTimer(): no RTC to stop!\n");
+ return false;
+ }
+*/ return true;
+ }
+
+unsigned long CoreTimer::getTimerTicks()
+ {
+ if(TIMER_DEBUG)
+ printf("getTimerTicks()\n");
+ unsigned long int nn;
+/* if (timerFd==-1) {
+ fprintf(stderr,"CoreTimer::getTimerTicks(): no RTC open to read!\n");
+ return 0;
+ }
+ if (read(timerFd, &nn, sizeof(unsigned long)) != sizeof(unsigned long)) {
+ fprintf(stderr,"CoreTimer::getTimerTicks(): error reading RTC\n");
+ return 0;
+ }
+*/
+ return nn;
+ }
+
diff --git a/muse/muse/driver/coretimer.h b/muse/muse/driver/coretimer.h
new file mode 100644
index 00000000..6096101f
--- /dev/null
+++ b/muse/muse/driver/coretimer.h
@@ -0,0 +1,42 @@
+ //=========================================================
+ // MusE
+ // Linux Music Editor
+ // $Id: rtctimer.h,v 1.1.2.3 2005/08/21 18:11:28 spamatica Exp $
+ //
+ // (C) Copyright 2004-2006 Robert Jonsson (rj@spamatica.se)
+ // (C) Copyright -2004 Werner Schweer (werner@seh.de)
+ //=========================================================
+
+#ifndef __CORETIMER_H__
+#define __CORETIMER_H__
+
+#include "timerdev.h"
+
+
+//---------------------------------------------------------
+// AlsaTimer
+//---------------------------------------------------------
+
+class CoreTimer : public Timer {
+
+
+ public:
+ CoreTimer();
+ virtual ~CoreTimer();
+
+ virtual bool initTimer();
+ virtual unsigned int setTimerResolution(unsigned int resolution);
+ virtual int getTimerResolution();
+ virtual bool setTimerFreq(unsigned int tick);
+ virtual unsigned int getTimerFreq();
+
+ virtual bool startTimer();
+ virtual bool stopTimer();
+ virtual unsigned long getTimerTicks();
+
+ private:
+ int timerFd;
+
+};
+
+#endif //__CORETIMER_H__
diff --git a/muse/muse/driver/mididev.h b/muse/muse/driver/mididev.h
new file mode 100644
index 00000000..10f4bcd6
--- /dev/null
+++ b/muse/muse/driver/mididev.h
@@ -0,0 +1,20 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: audiodev.h,v 1.10 2006/01/17 17:18:07 wschweer Exp $
+//
+// (C) Copyright 2006 Robert Jonsson rj at spamatica.se
+//=========================================================
+
+#ifndef __MIDIDEV_H__
+#define __MIDIDEV_H__
+
+#ifdef __APPLE__
+#include "driver/coremidi.h"
+#else
+#include "driver/alsamidi.h"
+#endif
+
+
+#endif
+