This is winmidi.c in view mode; [Download] [Up]
/************************************************************************
winmidi.c - Midi DLL for Common Music
Copyright (c) 1993 Joseph Fosco
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The author may be reached (Email) at the address b38669@anl.gov,
or (US mail) at 15508 Brianne Lane, Oak Forest, IL 60452
*************************************************************************/
/*------------------------------------------------------------------
WINMIDI.C -- Dynamic Link Library module for Windows Multimedia
MIDI FUNCTIONS TO BE CALLED FROM COMMON MUSIC (LISP)
------------------------------------------------------------------*/
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#define MIDI_NOTE_ON 0x90
#define MIDI_NOTE_OFF 0x80
#define MIDI_ACTIVE_SENSING 0xFE
#define FF_MIDI_SUCCESS 0
#define MAX_TIMER_ACCURACY 0
#define MAX_WRITE_QUEUE_ITEMS 4000
#define MAX_READ_QUEUE_ITEMS 4000
#define MAX_SCHED_TIME 0xFFFFFFFF
typedef union {
DWORD dwMidiMsg;
BYTE byMidiByte[4];
} MIDI_DATA;
typedef struct read_queue_item{
MIDI_DATA MidiReadData; /* midi data received */
DWORD dwMidiTime; /* midi time this message was received */
WORD wLongMsg; /* indicates MIDI_DATA points to a buffer
containing a long midi message (sysex) */
/* currently tnis is not used */
} READ_QUEUE_ITEM;
typedef READ_QUEUE_ITEM FAR *LPREAD_QUEUE_ITEM;
typedef struct read_queue_hdr{
LPREAD_QUEUE_ITEM lpReadQueue; /* Start of Midi In Buffer */
LPREAD_QUEUE_ITEM lpReadQueueEnd; /* End of Buffer (Last Byte+1) */
LPREAD_QUEUE_ITEM lpFirstOpenReadItem; /* Next Item to fill */
LPREAD_QUEUE_ITEM lpFirstNewReadItem; /* Next Item to read */
int iReadCount; /* Number of Items in Buffer */
} READ_QUEUE_HDR;
typedef READ_QUEUE_HDR FAR *LPREAD_QUEUE_HDR;
#if 0
typedef struct write_queue_item{
MIDI_DATA MidiWriteData;
DWORD dwQuantaTime;
int iNextEvent;
int iPrevEvent;
int iNextOpenItem;
BYTE bFill1;
BYTE bFill2;
} WRITE_QUEUE_ITEM ;
typedef struct{
struct write_queue_item Item[];
} WRITE_QUEUE;
#endif
typedef struct{
MIDI_DATA MidiWriteData; /* midi data to send */
DWORD dwQuantaTime; /* quanta time this event should occur at */
int iNextEvent;
int iPrevEvent;
int iNextOpenItem;
BYTE bFill1; /* Filler to make this structure length */
BYTE bFill2; /* equal a power of 2 (for allocating > 64k) */
} WRITE_QUEUE_ITEM ;
typedef struct{
WRITE_QUEUE_ITEM Item[];
}WRITE_QUEUE;
typedef struct {
WORD total_midi_in;
WORD total_midi_out;
}TOTAL_MIDI_PORTS_STRUCT ;
WORD FAR PASCAL _export midiclose() ;
void FAR PASCAL _export timer_callback(UINT wID, UINT wMsg,
DWORD dwUser, DWORD dw1, DWORD dw2) ;
void FAR PASCAL _export midi_in_callback(HMIDIIN hMidiIn, WORD wMsg,
DWORD dwInstance,
MIDI_DATA MidiInMsg,
DWORD dwParam2);
void FAR PASCAL _export midi_out_callback(HMIDIOUT hMidiOut, WORD wMsg,
DWORD dwInstance, DWORD dwParam1,
DWORD dwParam2) ;
WORD FAR PASCAL _export midiflushreceive() ;
WORD FAR PASCAL _export midiflushtransmit() ;
WORD FAR PASCAL _export midiallnotesoff(DWORD qtime) ;
void PASCAL SetMidiOutOpenItems();
TIMECAPS tc;
WORD wTimerId = NULL;
HMIDIOUT hMidiOut = NULL;
HMIDIIN hMidiIn = NULL;
WORD wQuantaSize = 1000;
DWORD dwQuantaTime = 0; /* Current Quanta Time */
DWORD dwBaseTime = 0; /* Time (in milliseconds) when the Common
Music timer was started */
DWORD dwMidiBaseTime = 0; /* Time (in milliseconds) when MIDI input
was started. */
BOOL bTimerStarted = FALSE; /* TRUE when the timer is running */
BOOL bScheduling = FALSE; /* TRUE when pointers are being updated
to schedule another event. When TRUE,
MIDI output is disabled to avoid
loosing events */
WRITE_QUEUE FAR * lpWriteQueue = NULL;
int iFirstOpenWriteItem;
int iLastOpenWriteItem;
int iNextSchedEvent = -1;
DWORD dwNextSchedTime = MAX_SCHED_TIME;
int iLastSchedEvent = -1;
DWORD dwLastSchedTime = 0;
LPREAD_QUEUE_HDR lpFirstReadQueueHdr = NULL;
int FAR PASCAL LibMain (HANDLE hInstance, WORD wDataSeg, WORD wHeapSize,
LPSTR lpszCmdLine)
{
/* Do not unlock data segment ! */
if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) == TIMERR_NOCANDO)
return(0);
return(1);
}
int FAR PASCAL _export WEP (int nParam)
{
if (bTimerStarted)
{
timeKillEvent(wTimerId);
timeEndPeriod(tc.wPeriodMin);
}
if (hMidiOut != NULL)
midiclose();
return(1);
}
WORD FAR PASCAL _export midistarttimer()
{
if (1000000 / wQuantaSize > 1000 / tc.wPeriodMin)
return(1); /* Timer can't handle requested resolution */
if (bTimerStarted)
return(2); /* Timer already started */
if (timeBeginPeriod(tc.wPeriodMin) == TIMERR_NOCANDO)
return(3); /* Cannot set timer resolution */
wTimerId = timeSetEvent((wQuantaSize / 1000), MAX_TIMER_ACCURACY,
timer_callback, NULL, TIME_PERIODIC);
if (!wTimerId)
return(4);
dwBaseTime = timeGetTime();
bTimerStarted = TRUE;
return(FF_MIDI_SUCCESS);
}
WORD FAR PASCAL _export midistoptimer()
{
if (!bTimerStarted)
return(1); /* Timer is not running */
timeKillEvent(wTimerId);
wTimerId = NULL;
timeEndPeriod(wQuantaSize / 1000);
bTimerStarted = FALSE;
dwBaseTime = 0;
dwQuantaTime = 0;
return(FF_MIDI_SUCCESS);
}
DWORD FAR PASCAL _export midigettime()
{
if (bTimerStarted)
return (dwQuantaTime);
else
return (0);
}
WORD FAR PASCAL _export midisettime(DWORD new_time)
{
if (!bTimerStarted)
return(1); /* Timer must be running to set time */
dwBaseTime = timeGetTime() - (new_time * (wQuantaSize / 1000));
dwQuantaTime = new_time;
return(FF_MIDI_SUCCESS);
}
WORD FAR PASCAL _export midisetquantasize (DWORD new_quanta_size)
{
if (bTimerStarted)
return (1); /* can't change wQuantaSize while timer is running */
/* Check if new_quanta_size is within the capabilites of the */
/* computer. Compare interrupts per second with interrupts */
/* per second. */
if (1000000/ new_quanta_size > 1000/ tc.wPeriodMin)
return(2);
else
{
wQuantaSize = new_quanta_size;
return(FF_MIDI_SUCCESS);
}
}
WORD FAR PASCAL _export midiopen(WORD portnum)
{
HANDLE hQueue;
LPREAD_QUEUE_ITEM lpRdQ;
LPREAD_QUEUE_HDR lpRdQHdr;
WORD rtn;
/* Allocate storage for queue for outgoing midi data */
lpWriteQueue =
(WRITE_QUEUE FAR *) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE,
((DWORD)sizeof(WRITE_QUEUE_ITEM) *
MAX_WRITE_QUEUE_ITEMS));
if (!lpWriteQueue)
return(100);
/* Global storage accessed at interrupt time mest be Page locked */
if (GlobalPageLock(HIWORD(lpWriteQueue)) == 0)
return(110);
iFirstOpenWriteItem = 0;
iLastOpenWriteItem = MAX_WRITE_QUEUE_ITEMS - 1;
SetMidiOutOpenItems();
/* Allocate storage for incoming midi data */
/* First allocate storage for the header */
/* Then allocate storage for the incoming midi data queue */
hQueue = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
(DWORD)sizeof(READ_QUEUE_HDR));
if (hQueue == (HANDLE)NULL)
return(150);
lpRdQHdr = (LPREAD_QUEUE_HDR)GlobalLock(hQueue);
if (lpRdQHdr == (LPREAD_QUEUE_HDR)NULL)
{
GlobalFree(hQueue);
return(152);
}
/* Global storage accessed at interrupt time mest be Page locked */
if (GlobalPageLock(HIWORD(lpRdQHdr)) == 0)
{
GlobalFreePtr(lpRdQHdr);
return(154);
}
hQueue = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
(DWORD)(sizeof(READ_QUEUE_ITEM) *
MAX_READ_QUEUE_ITEMS));
if (hQueue == (HANDLE)NULL)
{
GlobalPageUnlock(HIWORD(lpRdQHdr));
GlobalFreePtr(lpRdQHdr);
return(156);
}
lpRdQ = (LPREAD_QUEUE_ITEM)GlobalLock(hQueue);
if (lpRdQ == (LPREAD_QUEUE_ITEM)NULL)
{
GlobalFree(hQueue);
GlobalPageUnlock(HIWORD(lpRdQHdr));
GlobalFreePtr(lpRdQHdr);
return(158);
}
/* Global storage accessed at interrupt time mest be Page locked */
if (GlobalPageLock(HIWORD(lpRdQ)) == 0)
{
GlobalFreePtr(lpRdQ);
GlobalPageUnlock(HIWORD(lpRdQHdr));
GlobalFreePtr(lpRdQHdr);
return(160);
}
/* Save pointer to first READ_QUEUE_HDR and */
/* initialize READ_QUEUE_HDR */
lpFirstReadQueueHdr = lpRdQHdr;
lpFirstReadQueueHdr->lpReadQueue = lpRdQ;
lpFirstReadQueueHdr->lpReadQueueEnd = lpRdQ + MAX_READ_QUEUE_ITEMS;
lpFirstReadQueueHdr->iReadCount = 0;
lpFirstReadQueueHdr->lpFirstOpenReadItem = lpRdQ;
lpFirstReadQueueHdr->lpFirstNewReadItem = lpRdQ;
/* Open Midi input and output ports and start midi input */
rtn = midiOutOpen((LPHMIDIOUT) &hMidiOut, portnum,
(DWORD)midi_out_callback, NULL, CALLBACK_FUNCTION);
if (rtn)
return(200 + rtn);
rtn = midiInOpen((LPHMIDIIN) &hMidiIn, portnum,
(DWORD)midi_in_callback, (DWORD)(LPVOID)lpRdQHdr,
CALLBACK_FUNCTION);
if (rtn)
return(300 + rtn);
dwMidiBaseTime = timeGetTime();
rtn = midiInStart(hMidiIn);
if (rtn)
return(400 + rtn);
rtn = midistarttimer();
if (rtn)
return(500+rtn);
rtn = midisettime((DWORD)0);
if (rtn)
return(600+rtn);
return(FF_MIDI_SUCCESS);
}
WORD FAR PASCAL _export midiclose()
{
WORD rtn;
iNextSchedEvent = -1;
dwNextSchedTime = MAX_SCHED_TIME;
iLastSchedEvent = -1;
dwLastSchedTime = 0;
/* if (bTimerStarted)
{
midisettime(0);
dwMidiBaseTime = 0;
wQuantaSize = 1000;
return(FF_MIDI_SUCCESS);
} */
midistoptimer();
if (!hMidiOut)
return(FF_MIDI_SUCCESS);
rtn = midiOutClose(hMidiOut);
if (rtn)
return(100 + rtn);
else
hMidiOut = NULL;
rtn = midiInClose(hMidiIn);
if (rtn)
return(200 + rtn);
else
hMidiIn = NULL;
/* Release storage for MIDI input and output queues */
GlobalPageUnlock(HIWORD(lpWriteQueue));
lpWriteQueue =
(WRITE_QUEUE FAR *)GlobalFreePtr(lpWriteQueue);
GlobalPageUnlock(HIWORD(lpFirstReadQueueHdr->lpReadQueue));
GlobalFreePtr(lpFirstReadQueueHdr->lpReadQueue);
GlobalPageUnlock(HIWORD(lpFirstReadQueueHdr));
lpFirstReadQueueHdr =
(LPREAD_QUEUE_HDR)GlobalFreePtr(lpFirstReadQueueHdr);
return(FF_MIDI_SUCCESS);
}
#if 0
WORD FAR PASCAL _export midireadmessages
(void (FAR * lisp_read_func)(DWORD))
{
unsigned int wNextItem;
MIDI_DATA CMMidiData; /* MidiMessage formatted for Common Music */
/* Check to be sure midi port has been opened and storage allocated */
if (!lpReadQueue)
return(100);
if (iLastOpenReadItem == MAX_READ_QUEUE_ITEMS - 1)
wNextItem = 0;
else
wNextItem = iLastOpenReadItem + 1;
while (wNextItem != iFirstOpenReadItem)
{
/* Format Midi Message for Common Music */
CMMidiData.byMidiByte[3] = 0;
CMMidiData.byMidiByte[2] =
lpReadQueue->Item[wNextItem].MidiReadData.byMidiByte[0];
CMMidiData.byMidiByte[1] =
lpReadQueue->Item[wNextItem].MidiReadData.byMidiByte[1];
CMMidiData.byMidiByte[0] =
lpReadQueue->Item[wNextItem].MidiReadData.byMidiByte[2];
if (iFirstOpenReadItem == -1)
iFirstOpenReadItem = wNextItem;
iLastOpenReadItem = wNextItem;
(*lisp_read_func)(CMMidiData.dwMidiMsg);
if (wNextItem == MAX_READ_QUEUE_ITEMS - 1)
wNextItem = 0;
else
wNextItem++;
}
return(FF_MIDI_SUCCESS);
}
#endif
#if 0
WORD FAR PASCAL _export midireadmessages
(void (FAR * lisp_read_func)(DWORD))
{
DWORD val = 1;
(*lisp_read_func)(val);
return(FF_MIDI_SUCCESS);
}
#endif
WORD FAR PASCAL _export midiwritemessage(MIDI_DATA CMMidiMsg, DWORD qtime)
{
WORD rtn;
MIDI_DATA WndwMidiData; /* MIDI data formatted for Windows */
int iCurItem, iChkItem;
/* Format MIDI data for Windows */
WndwMidiData.byMidiByte[3] = 0;
WndwMidiData.byMidiByte[2] = CMMidiMsg.byMidiByte[0];
WndwMidiData.byMidiByte[1] = CMMidiMsg.byMidiByte[1];
WndwMidiData.byMidiByte[0] = CMMidiMsg.byMidiByte[2];
if (qtime <= dwQuantaTime)
{
rtn = midiOutShortMsg(hMidiOut, WndwMidiData.dwMidiMsg);
return(rtn);
}
if (iFirstOpenWriteItem < 0) /* Return an error if there is no more */
return(101); /* space in the queue! */
bScheduling = TRUE; /* Disable MIDI Output while scheduling */
iCurItem = iFirstOpenWriteItem;
iFirstOpenWriteItem = lpWriteQueue->Item[iCurItem].iNextOpenItem;
if (iLastOpenWriteItem == iCurItem) /* if this was the only open item */
iLastOpenWriteItem = -1; /* indicate no more open items */
lpWriteQueue->Item[iCurItem].MidiWriteData.dwMidiMsg =
WndwMidiData.dwMidiMsg;
lpWriteQueue->Item[iCurItem].dwQuantaTime = qtime;
lpWriteQueue->Item[iCurItem].iNextOpenItem = -1;
if (dwNextSchedTime >= qtime) /* Add to Front of Queue */
{
lpWriteQueue->Item[iCurItem].iNextEvent = iNextSchedEvent;
lpWriteQueue->Item[iCurItem].iPrevEvent = -1;
if (iNextSchedEvent >= 0)
lpWriteQueue->Item[iNextSchedEvent].iPrevEvent = iCurItem;
iNextSchedEvent = iCurItem;
dwNextSchedTime = qtime;
if (iLastSchedEvent == -1)
{
iLastSchedEvent = iCurItem;
dwLastSchedTime = qtime;
}
}
else if (dwLastSchedTime <= qtime) /* Add to end of Queue */
{
lpWriteQueue->Item[iCurItem].iNextEvent = -1;
lpWriteQueue->Item[iCurItem].iPrevEvent = iLastSchedEvent;
if (iLastSchedEvent >= 0)
lpWriteQueue->Item[iLastSchedEvent].iNextEvent = iCurItem;
iLastSchedEvent = iCurItem;
dwLastSchedTime = qtime;
}
else /* Add to middle of Queue */
{
iChkItem = iNextSchedEvent;
while (lpWriteQueue->Item[iChkItem].dwQuantaTime < qtime)
iChkItem = lpWriteQueue->Item[iChkItem].iNextEvent;
lpWriteQueue->Item[iCurItem].iNextEvent = iChkItem;
lpWriteQueue->Item[iCurItem].iPrevEvent =
lpWriteQueue->Item[iChkItem].iPrevEvent;
lpWriteQueue->Item[iChkItem].iPrevEvent = iCurItem;
lpWriteQueue->
Item[lpWriteQueue->Item[iCurItem].iPrevEvent].iNextEvent
= iCurItem;
}
bScheduling = FALSE; /* Enable MIDI Output */
return(FF_MIDI_SUCCESS);
}
WORD FAR PASCAL _export midihush()
{
WORD rtn;
rtn = midiflushtransmit();
if (rtn)
return(rtn + 500);
rtn = midiallnotesoff((DWORD) 0);
if (rtn)
return(rtn + 600);
rtn = midiflushreceive();
if (rtn)
return(rtn + 700);
return(FF_MIDI_SUCCESS);
}
WORD FAR PASCAL _export midiflushtransmit()
{
if (!lpWriteQueue)
return(100);
bScheduling = TRUE; /* Disable MIDI Output while scheduling */
iNextSchedEvent = -1;
dwNextSchedTime = MAX_SCHED_TIME;
iLastSchedEvent = -1;
dwLastSchedTime = 0;
iFirstOpenWriteItem = 0;
iLastOpenWriteItem = MAX_WRITE_QUEUE_ITEMS - 1;
SetMidiOutOpenItems();
bScheduling = FALSE; /* Enable MIDI Output */
return(FF_MIDI_SUCCESS);
}
WORD FAR PASCAL _export midiflushreceive()
{
if (!lpFirstReadQueueHdr)
return(100);
#if 0
iFirstOpenReadItem = 0;
iLastOpenReadItem = MAX_READ_QUEUE_ITEMS - 1;
#endif
return(FF_MIDI_SUCCESS);
}
WORD FAR PASCAL _export midiallnotesoff(DWORD qtime)
{
int chnl, note;
MIDI_DATA CMMidiData;
WORD rtn;
/* Send a note off message for all notes on all channels */
for (chnl=0; chnl<16; chnl++)
for (note=0; note<128; note++)
{
CMMidiData.byMidiByte[3] = 0;
CMMidiData.byMidiByte[2] = MIDI_NOTE_OFF | chnl;
CMMidiData.byMidiByte[1] = note;
CMMidiData.byMidiByte[0] = 0x40;
rtn = midiwritemessage(CMMidiData, qtime);
if (rtn != FF_MIDI_SUCCESS)
return(rtn);
}
return(FF_MIDI_SUCCESS);
}
WORD FAR PASCAL _export miditotalports
(TOTAL_MIDI_PORTS_STRUCT * total_midi_ports)
{
total_midi_ports->total_midi_in = midiInGetNumDevs();
total_midi_ports->total_midi_out = midiOutGetNumDevs();
return(FF_MIDI_SUCCESS);
}
DWORD FAR PASCAL _export totalopen()
{
DWORD opncnt=0;
int chksub;
chksub = iFirstOpenWriteItem;
while (chksub != -1)
{
opncnt++;
chksub = lpWriteQueue->Item[chksub].iNextOpenItem;
}
return(opncnt);
}
DWORD FAR PASCAL _export checkread()
{
return((DWORD)lpFirstReadQueueHdr->lpFirstOpenReadItem);
}
void PASCAL SetMidiOutOpenItems()
{
int cnt;
for (cnt = 0; cnt < MAX_WRITE_QUEUE_ITEMS - 1; cnt++)
{
lpWriteQueue->Item[cnt].iNextOpenItem = cnt + 1;
}
lpWriteQueue->Item[MAX_WRITE_QUEUE_ITEMS - 1].iNextOpenItem = -1;
return;
}
void FAR PASCAL _export midi_out_callback(HMIDIOUT hMidiOut, WORD wMsg,
DWORD dwInstance, DWORD dwParam1,
DWORD dwParam2)
{
return ;
}
void FAR PASCAL _export midi_in_callback(HMIDIIN hMidiIn, WORD wMsg,
DWORD dwInstance,
MIDI_DATA MidiInMsg,
DWORD dwParam2)
{
/* static LPREAD_QUEUE_HDR lpRdQHdr = NULL; */
if (wMsg != MIM_DATA)
return;
/* Ignore Active Sensing messages */
if (MidiInMsg.byMidiByte[0] == MIDI_ACTIVE_SENSING)
return;
#if 0
lpRdQHdr = (LPREAD_QUEUE_HDR)dwInstance;
/* return if there is no space left in the read (input) queue */
if (lpRdQHdr->iReadCount >= MAX_READ_QUEUE_ITEMS)
return;
lpRdQHdr->lpFirstOpenReadItem->MidiReadData.dwMidiMsg =
MidiInMsg.dwMidiMsg;
lpRdQHdr->lpFirstOpenReadItem->dwMidiTime = dwParam2;
++lpRdQHdr->iReadCount;
++lpRdQHdr->lpFirstOpenReadItem;
if (lpRdQHdr->lpFirstOpenReadItem == lpRdQHdr->lpReadQueueEnd)
lpRdQHdr->lpFirstOpenReadItem = lpRdQHdr->lpReadQueue;
#endif
if (lpFirstReadQueueHdr->iReadCount >= MAX_READ_QUEUE_ITEMS)
return;
#if 0
lpFirstReadQueueHdr->lpFirstOpenReadItem->
MidiReadData.dwMidiMsg = MidiInMsg.dwMidiMsg;
#endif
lpFirstReadQueueHdr->lpFirstOpenReadItem->dwMidiTime = dwParam2;
++lpFirstReadQueueHdr->iReadCount;
++lpFirstReadQueueHdr->lpFirstOpenReadItem;
if (lpFirstReadQueueHdr->lpFirstOpenReadItem >=
lpFirstReadQueueHdr->lpReadQueueEnd)
lpFirstReadQueueHdr->lpFirstOpenReadItem =
lpFirstReadQueueHdr->lpReadQueue;
return;
}
void FAR PASCAL _export timer_callback(UINT wID, UINT wMsg,
DWORD dwUser, DWORD dw1, DWORD dw2)
{
dwQuantaTime += 1;
if (bScheduling) /* Don't send output while scheduling */
return;
while (dwNextSchedTime <= dwQuantaTime)
{
midiOutShortMsg (hMidiOut,
lpWriteQueue->Item[iNextSchedEvent].MidiWriteData.dwMidiMsg);
/* Make this write queue item the last open write queue item */
if (iLastOpenWriteItem != -1)
lpWriteQueue->Item[iLastOpenWriteItem].iNextOpenItem =
iNextSchedEvent;
iLastOpenWriteItem = iNextSchedEvent;
if (iFirstOpenWriteItem == -1)
iFirstOpenWriteItem = iNextSchedEvent;
/* Check for next event */
if (lpWriteQueue->Item[iNextSchedEvent].iNextEvent == -1)
{ /* no more events scheduled. */
iNextSchedEvent = -1;
dwNextSchedTime = MAX_SCHED_TIME;
iLastSchedEvent = -1;
dwLastSchedTime = 0;
}
else /* Schedule next event */
{
iNextSchedEvent =
lpWriteQueue->Item[iNextSchedEvent].iNextEvent;
dwNextSchedTime =
lpWriteQueue->Item[iNextSchedEvent].dwQuantaTime;
}
}
return ;
}
#if 0
extern "C"
{
WORD FAR PASCAL _export midistarttimer();
WORD FAR PASCAL _export midistarttimer();
WORD FAR PASCAL _export midistoptimer();
DWORD FAR PASCAL _export midigettime();
WORD FAR PASCAL _export midisettime(DWORD);
WORD FAR PASCAL _export midisetquantasize(DWORD);
WORD FAR PASCAL _export miditotalports(TOTAL_MIDI_PORTS_STRUCT FAR *);
WORD FAR PASCAL _export midiopen(WORD);
WORD FAR PASCAL _export midiclose();
WORD FAR PASCAL _export midireadmessages(void (FAR *)(DWORD));
WORD FAR PASCAL _export midiwritemessage(MIDI_DATA, DWORD);
WORD FAR PASCAL _export midihush();
WORD FAR PASCAL _export midiflushtransmit();
WORD FAR PASCAL _export midiflushreceive();
WORD FAR PASCAL _export midiallnotesoff(DWORD);
void FAR PASCAL _export midi_out_callback(HMIDIOUT, WORD, DWORD, DWORD, DWORD);
void FAR PASCAL _export midi_in_callback(HMIDIIN, WORD, DWORD, MIDI_DATA, DWORD);
void FAR PASCAL _export timer_callback(UINT, UINT, DWORD, DWORD, DWORD);
DWORD FAR PASCAL _export totalopen();
DWORD FAR PASCAL _export checkread();
}
#endif
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.