| I second the motion for platform-specific MIDI files. It could be done as
follows. This is a bit sketchy, but obviously something like this would (a)
work, and (b) be very much simpler than the existing code.
An abstract class (A C class, not a C++ class) for input and output drivers
with self-contained Csound input or output port function. The job of the
abstract driver is to encapsulate the business of reading a platform input
port and writing to a Csound input port, or reading a Csound output port and
writing to a platform output port.
typedef struct AbstractDriver
{
AbstractDriver *(*open)(void (*csoundPort)(void *csoundData));
int (*close)(struct AbstractDriver *this);
int(*sizeAvailable)(struct AbstractDriver *this)();
int (*read)(struct AbstractDriver *this);
int (*write)(struct AbstractDriver *this);
int(*control)(struct AbstractDriver *this, int command, void *data);
};
Then each platform would have a derived class (again a C class, not a C++
class), for example on Linux the MIDI input driver could be something like:
typedef struct LinuxMidiInputDriver
{
AbstractDriver baseDriver;
unsigned char buffer[4];
void (*midiInsert)(MIDIEVENT *event));
} ;
AbstractDriver *LinuxMidiInputOpen(void *buffer, int bufferSize, void
(*csoundPort)(MIDIEVENT *event))
{
LinuxMidiInputDriver *linuxDriver = (LinuxMidiInputDriver
*)malloc(sizeof(LinxMidiInputDriver), );
linuxDriver.baseDriver->buffer = buffer;
midiInsert = csoundPort;
(AbstractDriver *)linuxDriver;
Then in Csound itself would be tables of drivers,each terminated by a null
pointer:
AbstractDriver *inputDrivers[INPUT_DRIVER_COUNT + 1];
AbstractDriver *outputDrivers[OUTPUT_DRIVER_COUNT + 1];
AbstractDriver *audioInputDriver;
AbstractDriver *audioOutputDriver;
And on each platform there would be a driver.c file that fills in the
tables:
On Linux (note that the Csound midiInsert function gets plugged into the
driver):
inputDrivers[MIDI_INPUT_DRIVER] = LinuxMidiInputOpen(midiInsert);
inputDrivers[LINE_INPUT_DRIVER] = LinuxLineInDriverOpen(midiInsert);
On Windows:
inputDrivers[MIDI_INPUT_DRIVER] = WindowsMidiInputOpen(midiInsert);
inputDrivers[LINE_INPUT_DRIVER] = WindowsLineInDriverOpen(midiInsert);
Then kperf would look like this:
long kperf(long controlSampleCount)
{
extern struct AbstractDriver inputDrivers[];
extern struct AbstractDriver *outputDrivers[];
extern struct AbstractDriver *audioInputDrivers[];
extern struct AbstractDriver *audioOutputDriver[]s;
for(controlSampleIndex = 0; controlSampleIndex < controlSampleCount;
controlSampleIndex++)
{
// Read any pending control inputs.
int inputsRead = 0;
for(AbstractDriver *inputDriver = inputDrivers; inputDriver;
inputDrivers++)
{
if((*controlInput->available)(controlInput)
{
inputsRead = (*controlInput->read)(controlInput);
}
}
if(inputsRead)
{
return controlSampleIndex;
}
// Initialize the primary audio buffers.
controlSampleCounter++;
memset(inputBuffer, 0, inputBufferSize);
memset(outputBuffer, 0, outputBufferSize);
// Read any pending audio inputs.
for(AbstractDriver *audioInput = audioInputDrivers; audioInput;
audioInput++)
{
(*audioInput->read)(audioInput);
}
// For each active instrument...
for(ip = &actanchor; ip = ip->nxtact; )
{
// ...run each of its opcodes.
for(pds = (OPDS *)ip; pds = pds->nxtp; )
{
(*pds->opadr)(pds);
}
}
// Write any audio outputs.
for(AbstractDriver *audioOutput = audioOutputDrivers; audioOutput;
audioOutput++)
{
audioOutput = (*audioOutput->write)(audioOutput);
}
// Write any control outputs.
for(AbstractDriver *outputDriver = outputDrivers; outputDriver;
outputDriver++)
{
if(outputDriver->available(outputDriver))
{
(*outputDriver->write)(outputDriver);
}
}
}
return controlSampleIndex;
}
-----Original Message-----
From: Larry Troxler
To: Dave Phillips
Cc: Csound Mail ; Adam Zygmunt
; Jason ?
Date: Monday, August 09, 1999 3:33 PM
Subject: Re: compiling Linux Csound (official)
>On Mon, 9 Aug 1999, Dave Phillips wrote:
>>
>> However, I don't actually know where the problem lies in midirecv.c,
>> since the #ifdefs are rather numerous and somewhat confusing. If I had a
>> little more time I could narrow it down, but perhaps some other reader
>> can continue this exercise (Larry T, are you there ?). Perhaps it's time
>> to consider platform-specific files for the MIDI i/o ?
>>
>Actually, although midirecv.c definitely isn't correct, as it turns out, I
>have a MIDI driver problem now after a recent upgrade. So once I fix that,
>I'll go back and have a look.
>
>Actually, I do have the unnoficial version working, and the main reason
>I'm using the official one is because it seems to have more of the recent
>opcodes. Hmm, it probably would have been easier just to add the opcodes
>to the unnoficial one.
>
>Larry Troxler
> |