| It may be than you should #ifdef for WIN32, not for MSVC. I'm not sure. I
will be testing this with MinGW.
Original Message:
-----------------
From: Victor Lazzarini Victor.Lazzarini@MAY.IE
Date: Mon, 06 Dec 2004 13:41:35 +0000
To: csound-dev@eartha.mills.edu
Subject: [CSOUND-DEV:5492] PortMidi implementation Fixed ?
Dear all,
The problem now seems to be fixed. Took less time than previously
thought.
Runs OK here on Windows under MSVC. I'll try Linux (redhat) later.
These were the changes in pmidi.c (I can't do CVS, so I'll ask someone
else to do them for me):
(1) line 38:
#ifdef MSVC /* VL MSVC fix */
# define u_char unsigned char
# define u_short unsigned short
# define u_int unsigned int
# define u_long unsigned long
#endif
u_char *mbuf, *bufp, *bufend, *endatp; /* VL dec 2004 changed back u_char
pointers */
static u_char *sexbuf, *sexp, *sexend;
(2) GetMidiData function:
long GetMIDIData(void)
{
int n,i,j;
extern int csoundIsExternalMidiEnabled(void*);
extern long csoundExternalMidiRead(void*, u_char *, int);
PmEvent event[MBUFSIZ];
/*
* Reads from user-defined MIDI input.
*/
if (csoundIsExternalMidiEnabled(&cenviron)) {
n = csoundExternalMidiRead(&cenviron, mbuf, MBUFSIZ);
if (n == 0) return 0;
bufp = mbuf;
endatp = mbuf + n;
return n;
}
else {
int retval = Pm_Poll(midistream);
if (retval<0) {
printf(Str(X_1185,"sensMIDI: retval errno %d\n"),errno);
}
else if (retval) { /* Pm_Poll return TRUE, FALSE of
error!! */
long n = Pm_Read(midistream, event, MBUFSIZ);
if (n<0) {
printf("**** read error %d\n", n);
return 0;
}
printf("**** %ld events read\n", n);
/* copies a PmEvent into the midi buffer VL dec 2004 */
for(i=0,j=0; i < n; i++){
mbuf[j++] = Pm_MessageStatus(event[i].message);
mbuf[j++] = Pm_MessageData1(event[i].message);
mbuf[j++] = Pm_MessageData2(event[i].message);
}
bufp = mbuf;
endatp = mbuf + j;
return n;
}
}
return 0;
}
(c) MidiOpen()
void MidiOpen(void) /* open a Midi event stream for reading, alloc bufs */
{ /* callable once from main.c */
/* First set up buffers. */
int i;
Midevtblk = (MEVENT *) mcalloc((long)sizeof(MEVENT));
mbuf = (u_char *) mcalloc((long)MBUFSIZ); /* mbuf is u_char array VL
dec 2004 */
bufend = mbuf + MBUFSIZ;
bufp = endatp = mbuf;
sexbuf = (u_char *) mcalloc((long)MBUFSIZ); /* sexbuf is u_char array
VL dec 2004 */
sexend = sexbuf + MBUFSIZ;
sexp = NULL;
for (i=0; i= endatp) {
if (!GetMIDIData())
return (0);
}
if ((c = *bufp++) & 0x80) { /* STATUS byte: */
type = c & 0xF0;
if (type == SYSTEM_TYPE) {
short lo3 = (c & 0x07);
if (c & 0x08) /* sys_realtime: */
switch (lo3) { /* dispatch now */
case 0: m_clktim++;
goto nxtchr;
case 2: m_start();
goto nxtchr;
case 3: m_contin();
goto nxtchr;
case 4: m_stop();
goto nxtchr;
case 6: m_sensing = 1;
goto nxtchr;
case 7: m_sysReset();
goto nxtchr;
default: printf(Str(X_1316,"undefined sys-realtime msg %x\n"),c);
goto nxtchr;
}
else { /* sys_non-realtime status: */
if (sexp != NULL) { /* implies */
m_sysex(sexbuf,sexp); /* sys_exclus end */
sexp = NULL;
}
switch (lo3) { /* dispatch on lo3: */
case 7: goto nxtchr; /* EOX: already done */
case 0: sexp = sexbuf; /* sys_ex begin: */
goto nxtchr; /* goto copy data */
case 1: /* sys_common: */
case 3: datreq = 1; /* need some data */
break;
case 2: datreq = 2; /* (so build evt) */
break;
case 6: m_tuneReq(); /* this do immed */
goto nxtchr;
default: printf(Str(X_1317,"undefined sys_common msg %x\n"), c);
datreq = 32767; /* waste any data following */
datcnt = 0;
goto nxtchr;
}
}
mep->type = type; /* begin sys_com event */
mep->chan = lo3; /* holding code in chan */
datcnt = 0;
goto nxtchr;
}
else { /* other status types: */
short chan;
if (sexp != NULL) { /* also implies */
m_sysex(sexbuf,sexp); /* sys_exclus end */
sexp = NULL;
}
chan = c & 0xF;
if (M_CHNBP[chan] == NULL) /* chk chnl exists */
m_chn_init(mep, chan);
mep->type = type; /* & begin new event */
mep->chan = chan;
datreq = datbyts[(type>>4) & 0x7];
datcnt = 0;
goto nxtchr;
}
}
if (sexp != NULL) { /* NON-STATUS byte: */
if (sexp < sexend) { /* if sys_excl */
*sexp = c; /* special data sav */
sexp++;
}
else printf(Str(X_1262,"system exclusive buffer overflow\n"));
goto nxtchr;
}
if (datcnt == 0)
mep->dat1 = c; /* else normal data */
else mep->dat2 = c;
if (++datcnt < datreq) /* if msg incomplete */
goto nxtchr; /* get next char */
/*
* Enter the input event into a buffer used by 'midiin'.
* This is a horrible hack that emulates what DirectCsound does,
* in an attempt to make 'midiin' work. It might be usable
* by other OSes than BeOS, but it should be cleaned up first.
*
* jjk 09262000
*/
/* IV - Nov 30 2002: should work on other systems too */
if (mep->type != SYSTEM_TYPE) {
unsigned char *pMessage =
&(MIDIINbuffer2[MIDIINbufIndex++].bData[0]);
MIDIINbufIndex &= MIDIINBUFMSK;
*pMessage++ = mep->type | mep->chan;
*pMessage++ = (unsigned char)mep->dat1;
*pMessage = (datreq < 2 ? (unsigned char) 0 : mep->dat2);
}
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(mep); /* handle from here */
goto nxtchr; /* & go look for more */
}
return(2); /* else it's note_on/off */
}
void MidiClose(void)
{
if (csoundIsExternalMidiEnabled(&cenviron)) {
csoundExternalMidiDeviceClose(&cenviron);
}
else {
Pm_Close(midistream);
}
}
Victor Lazzarini
Music Technology Laboratory
Music Department
National University of Ireland, Maynooth
--------------------------------------------------------------------
mail2web - Check your email from the web at
http://mail2web.com/ . |