Skip to content

Commit

Permalink
passing port to Csound engine from MIDI output\n
Browse files Browse the repository at this point in the history
  • Loading branch information
vlazzarini committed Dec 15, 2017
1 parent f1a5790 commit 85735ad
Show file tree
Hide file tree
Showing 14 changed files with 136 additions and 124 deletions.
33 changes: 11 additions & 22 deletions InOut/cmidi.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,47 +175,36 @@ static int MidiOutDeviceOpen(CSOUND *csound, void **userData, const char *dev)
}

/* used to distinguish between 1 and 2-byte messages */
static const int datbyts[8] = { 2, 2, 2, 2, 1, 1, 2, 0 };
//static const int datbyts[8] = { 2, 2, 2, 2, 1, 1, 2, 0 };

/* csound MIDI read callback, called every k-cycle */
static int MidiDataRead(CSOUND *csound, void *userData,
unsigned char *mbuf, int nbytes)
MIDIMESSAGE *mbuf, int nbytes)
{
cdata *data = (cdata *)userData;
MIDIdata *mdata = data->mdata;
int *q = &data->q, st, d1, d2, n = 0;
int *q = &data->q, n = 0;
unsigned char st;
MIDIMESSAGE mmsg;

/* check if there is new data in circular queue */
while (mdata[*q].flag) {
st = (int) mdata[*q].status;
d1 = (int) mdata[*q].data1;
d2 = (int) mdata[*q].data2;
st = mmsg.bData[0] = mdata[*q].status;
mmsg.bData[1] = mdata[*q].data1;
mmsg.bData[2] = mdata[*q].data2;

if (st < 0x80) goto next;

if (st >= 0xF0 &&
!(st == 0xF8 || st == 0xFA || st == 0xFB ||
st == 0xFC || st == 0xFF)) goto next;

nbytes -= (datbyts[(st - 0x80) >> 4] + 1);
nbytes--;
if (nbytes < 0) break;

/* write to csound midi buffer */
n += (datbyts[(st - 0x80) >> 4] + 1);
switch (datbyts[(st - 0x80) >> 4]) {
case 0:
*mbuf++ = (unsigned char) st;
break;
case 1:
*mbuf++ = (unsigned char) st;
*mbuf++ = (unsigned char) d1;
break;
case 2:
*mbuf++ = (unsigned char) st;
*mbuf++ = (unsigned char) d1;
*mbuf++ = (unsigned char) d2;
break;
}
n++;
memcpy(mbuf++, &mmsg, sizeof(MIDIMESSAGE));
/* mark as read */
next:
mdata[*q].flag = 0;
Expand Down
20 changes: 10 additions & 10 deletions InOut/ipmidi.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ static int OpenMidiInDevice_(CSOUND *csound, void **userData, const char *dev)
}

static int ReadMidiData_(CSOUND *csound, void *userData,
unsigned char *mbuf, int nbytes)
{
MIDIMESSAGE *mbuf, int nbytes)
{
int n;
int sock = *((int *) userData);
fd_set rset;
Expand All @@ -126,14 +126,14 @@ static int ReadMidiData_(CSOUND *csound, void *userData,
timeout.tv_usec = 0;

rc = select(sock + 1, &rset, NULL, NULL, &timeout);
if (rc > 0) {
#ifdef WIN32
n = recv(sock, mbuf, nbytes, 0);
#else
n = read(sock, mbuf, nbytes);
#endif
printf("ReadMidiData__ n = %d\n", n);
}
/* if (rc > 0) { */
/* #ifdef WIN32 */
/* n = recv(sock, mbuf, nbytes, 0); */
/* #else */
/* n = read(sock, mbuf, nbytes); */
/* #endif */
/* printf("ReadMidiData__ n = %d\n", n); */
/* } */

/* return the number of bytes read */
return n;
Expand Down
72 changes: 37 additions & 35 deletions InOut/midirecv.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
and a non-zero error code if an error occured.
int (*MidiReadCallback)(CSOUND *csound,
void *userData, unsigned char *buf, int nbytes);
void *userData, MIDIMESSAGE *buf, int items);
Read at most 'nbytes' bytes of MIDI data from input stream
Read at most 'items' MIDI data messages from input stream
'userData', and store in 'buf'. Returns the actual number of
bytes read, which may be zero if there were no events, and
negative in case of an error. Note: incomplete messages (such
Expand Down Expand Up @@ -113,7 +113,7 @@ static const MYFLT dsctl_map[12] = {
FL(1.0), FL(0.0), FL(1.0), FL(0.0), FL(1.0), FL(0.0)
};

static const int16 datbyts[8] = { 2, 2, 2, 2, 1, 1, 2, 0 };
//static const int16 datbyts[8] = { 2, 2, 2, 2, 1, 1, 2, 0 };

/* open a Midi event stream for reading, alloc bufs */
/* callable once from main.c */
Expand Down Expand Up @@ -479,10 +479,11 @@ int sensMidi(CSOUND *csound)
MGLOBAL *p = csound->midiGlobals;
MEVENT *mep = p->Midevtblk;
OPARMS *O = csound->oparms;
MIDIMESSAGE *mmsg;
int n;
int16 c, type;

nxtchr:
do {
if (p->bufp >= p->endatp) {
p->bufp = &(p->mbuf[0]);
p->endatp = p->bufp;
Expand All @@ -494,18 +495,23 @@ int sensMidi(CSOUND *csound)
else
p->endatp += (int) n;
}
if (O->FMidiin) { /* read MIDI file */

/* read MIDI file */
/*
if (O->FMidiin) {
n = csoundMIDIFileRead(csound, p->endatp,
MBUFSIZ - (int) (p->endatp - p->bufp));
if (n > 0)
p->endatp += (int) n;
}
} */
if (p->endatp <= p->bufp)
return 0; /* no events were received */
}

if ((c = *(p->bufp++)) & 0x80) { /* STATUS byte: */
mmsg = p->bufp++;
c = mmsg->bData[0];
if (c & 0x80) { /* STATUS byte: */
type = c & 0xF0;
p->sexp = 0;
if (type == SYSTEM_TYPE) {
int16 lo3 = (c & 0x07);
if (c & 0x08) /* sys_realtime: */
Expand All @@ -516,72 +522,68 @@ int sensMidi(CSOUND *csound)
case 4: /* stop */
case 6: /* active sensing */
case 7: /* system reset */
goto nxtchr;
continue;
default:
csound->Message(csound, Str("undefined sys-realtime msg %x\n"), c);
goto nxtchr;
continue;
}
else { /* sys_non-realtime status: */
p->sexp = 0; /* implies sys_exclus end */
switch (lo3) { /* dispatch on lo3: */
case 7: goto nxtchr; /* EOX: already done */
case 7: continue; /* EOX: already done */
case 0: p->sexp = 1; /* sys_ex begin: */
goto nxtchr; /* goto copy data */
continue; /* goto copy data */
/* sys_common: need some data, so build evt */
case 1: /* MTC quarter frame */
case 3: p->datreq = 1; /* song select */
break;
case 2: p->datreq = 2; /* song position */
break;
case 6: /* tune request */
goto nxtchr;
continue;
default:
csound->Message(csound, Str("undefined sys_common msg %x\n"), c);
p->datreq = 32767; /* waste any data following */
p->datcnt = 0;
goto nxtchr;
continue;
}
}
mep->type = type; /* begin sys_com event */
mep->chan = lo3; /* holding code in chan */
p->datcnt = 0;
goto nxtchr;
continue;
}
else { /* other status types: */
int16 chan;
p->sexp = 0; /* also implies sys_exclus end */
chan = c & 0xF;
mep->type = type; /* & begin new event */
mep->chan = chan;
p->datreq = datbyts[(type>>4) & 0x7];
p->datcnt = 0;
goto nxtchr;
}
}
} else continue;

if (p->sexp != 0) { /* NON-STATUS byte: */
goto nxtchr;
continue;
}
if (p->datcnt == 0)
mep->dat1 = c; /* else normal data */
else mep->dat2 = c;
if (++p->datcnt < p->datreq) /* if msg incomplete */
goto nxtchr; /* get next char */
mep->dat1 = mmsg->bData[1];
mep->dat2 = mmsg->bData[2];
mep->dev = mmsg->bData[3];
printf("Dev=%lld \n", mep->dev);
/* Enter the input event into a buffer used by 'midiin'. */
if (mep->type != SYSTEM_TYPE) {
unsigned char *pMessage =
&(p->MIDIINbuffer2[p->MIDIINbufIndex++].bData[0]);
MIDIMESSAGE *pMessage =
&(p->MIDIINbuffer2[p->MIDIINbufIndex++]);
p->MIDIINbufIndex &= MIDIINBUFMSK;
*pMessage++ = mep->type | mep->chan;
*pMessage++ = (unsigned char) mep->dat1;
*pMessage = (p->datreq < 2 ? (unsigned char) 0 : mep->dat2);
memcpy(pMessage, mmsg, sizeof(MIDIMESSAGE));

}
p->datcnt = 0; /* else allow a repeat */
/* NB: this allows repeat in syscom 1,2,3 too */
if (mep->type > NOTEON_TYPE) { /* if control or syscom */
m_chanmsg(csound, mep); /* handle from here */
goto nxtchr; /* & go look for more */
}
return 2; /* else it's note_on/off */
m_chanmsg(csound, mep); /* handle from here */
continue;
}
return 2; /* else it's note_on/off */
} while(1);
}

extern void csoundCloseMidiOutFile(CSOUND *);
Expand Down
49 changes: 22 additions & 27 deletions InOut/pmidi.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void _wassert(wchar_t *condition)

typedef struct _pmall_data {
PortMidiStream *midistream;
int dev_offset;
int devnum;
struct _pmall_data *next;
} pmall_data;

Expand Down Expand Up @@ -234,7 +234,7 @@ static int OpenMidiInDevice_(CSOUND *csound, void **userData, const char *dev)
if (dev == NULL || dev[0] == '\0')
devnum =
portMidi_getPackedDeviceID((int)Pm_GetDefaultInputDeviceID(), 0);
else if (UNLIKELY((dev[0] < '0' || dev[0] > '9') && dev[0] != 'a')) {
else if (UNLIKELY((dev[0] < '0' || dev[0] > '9') && dev[0] != 'a' && dev[0] != 'x')) {
portMidiErrMsg(csound,
Str("error: must specify a device number (>=0) or"
" 'a' for all, 'x' for extended, not a name"));
Expand All @@ -251,13 +251,13 @@ static int OpenMidiInDevice_(CSOUND *csound, void **userData, const char *dev)
// allow to proceed if 'a'/'x' is given even if there are no MIDI devices
devnum = -1;
}

if (UNLIKELY(cntdev < 1 && (dev==NULL || dev[0] != 'a' || dev[0] != 'x'))) {
return portMidiErrMsg(csound, Str("no input devices are available"));
}
opendevs = 0;
for (i = 0; i < cntdev; i++) {
if (devnum == i || devnum == -1) {
if (devnum == i || dev[0] == 'a' || dev[0] == 'x' || devnum == -1) {
if (opendevs == 0) {
data = (pmall_data *) csound->Malloc(csound, sizeof(pmall_data));
next = data;
Expand All @@ -282,7 +282,9 @@ static int OpenMidiInDevice_(CSOUND *csound, void **userData, const char *dev)
retval = Pm_OpenInput(&next->midistream,
(PmDeviceID) portMidi_getRealDeviceID(i, 0),
NULL, 512L, (PmTimeProcPtr) NULL, NULL);
next->dev_offset = dev[0] == 'a' ? 0 : i;
// record device number so we can potentially send
// streams to different internal ports
next->devnum = dev[0] == 'a' ? 0 : i;
if (UNLIKELY(retval != pmNoError)) {
// Prevent leaking memory from "data"
if (data) {
Expand Down Expand Up @@ -358,9 +360,11 @@ static int OpenMidiOutDevice_(CSOUND *csound, void **userData, const char *dev)
}

static int ReadMidiData_(CSOUND *csound, void *userData,
unsigned char *mbuf, int nbytes)
MIDIMESSAGE *mbuf, int nitems)
{
int n, retval, st, d1, d2;
int n, retval;
unsigned char st;
MIDIMESSAGE mmsg;
PmEvent mev;
pmall_data *data;
/*
Expand All @@ -374,9 +378,11 @@ static int ReadMidiData_(CSOUND *csound, void *userData,
if (UNLIKELY(retval < 0))
return portMidiErrMsg(csound, Str("error polling input device"));
while ((retval = Pm_Read(data->midistream, &mev, 1L)) > 0) {
st = (int)Pm_MessageStatus(mev.message);
d1 = (int)Pm_MessageData1(mev.message);
d2 = (int)Pm_MessageData2(mev.message);
st = mmsg.bData[0] = Pm_MessageStatus(mev.message);
mmsg.bData[1] = Pm_MessageData1(mev.message);
mmsg.bData[2] = Pm_MessageData2(mev.message);
mmsg.bData[3] = data->devnum;

/* unknown message or sysex data: ignore */
if (UNLIKELY(st < 0x80))
continue;
Expand All @@ -385,27 +391,15 @@ static int ReadMidiData_(CSOUND *csound, void *userData,
!(st == 0xF8 || st == 0xFA || st == 0xFB ||
st == 0xFC || st == 0xFF)))
continue;
nbytes -= (datbyts[(st - 0x80) >> 4] + 1);
if (UNLIKELY(nbytes < 0)) {
nitems--;
if (UNLIKELY(nitems < 0)) {
portMidiErrMsg(csound, Str("buffer overflow in MIDI input"));
break;
}
/* channel messages */
n += (datbyts[(st - 0x80) >> 4] + 1);
switch (datbyts[(st - 0x80) >> 4]) {
case 0:
*mbuf++ = (unsigned char) st;
break;
case 1:
*mbuf++ = (unsigned char) st;
*mbuf++ = (unsigned char) d1;
break;
case 2:
*mbuf++ = (unsigned char) st;
*mbuf++ = (unsigned char) d1;
*mbuf++ = (unsigned char) d2;
break;
}
n++;
memcpy(mbuf++, &mmsg, sizeof(MIDIMESSAGE));

}
if (UNLIKELY(retval < 0)) {
portMidiErrMsg(csound, Str("read error %d"), retval);
Expand All @@ -414,6 +408,7 @@ static int ReadMidiData_(CSOUND *csound, void *userData,
}
}
data = data->next;

}
/* return the number of bytes read */
return n;
Expand Down

0 comments on commit 85735ad

Please sign in to comment.