MIDI input in Linux

Stephen Travis Pope stp at create.ucsb.edu
Tue Mar 9 21:22:18 UTC 1999


Luciano Notarfrancesco wrote:

> I want to use a MIDI keyboard with Squeak in Linux. Have anyone
> implemented the MIDI input primitives for Linux?

Not to my knowledge, but I know of some users who would *really* appreciate
it!

Here's the header file for the current Siren primitives (supported on Mac
and Windows, port to SGI under way). The Mac implementation of this can be
found at
ftp://ftp.create.ucsb.edu/pub/Smalltalk/Music/Siren/2.0/VM%20Src/sqMacMIDI.OMS.c

/***********************************************************************************

 *
 * Header File for the Squeak Interface to MIDI
 *              Stephen T. Pope -- stp at create.ucsb.edu -- 1998.05.05
 *
 * Version 2.00B -- Squeak MIDI Primitive Interface
 *
 * This file should be platform- and driver-independent.
 *
 * Note: Most of the primitives fail only under extreme conditions, and
return
 * negative results for "normal" failure.
 * A return value of 0 normally means "success" or "true."
 *
 *      The Smalltalk primitive bindings are:
 *              (610 primitiveOpenMIDI)
 *              (611 primitiveCloseMIDI)
 *              (612 primitiveGetMIDIDeviceName)
 *              (613 primitivePutMIDIOn)
 *              (614 primitiveReadMIDIPacket)
 *              (615 primitiveReadMIDIControl)
 *              (616 primitiveMIDIioctl)
 */


/***********************************************************************************

 * External MIDI interface function prototypes (Smalltalk primitives)
 */
                                // Open/start the MIDI interface. (Prim.
610)
                                // Answer the number of connected devices,
or 0 if the driver's
                                // already open.
                                // 'readSemaphore' is the index of the
semaphore to signal on MIDI
                                // input if it's non-zero and input
signalling is turned on (see the
                                // ioctl commands below).
                                // 'readSocket' is the socket to read from;
writeSocket will be
                                // readSocket + 1 (if readSocket's 0, don't
use sockets at all).
                                // (The socket is ignored in the default
driver.)
int sqOpenMIDI(int readSemaphore, int inputSocket);

                                // Close the MIDI interface and disconnect
from the driver (611)
int sqCloseMIDI(void);

                                // Get the name of a MIDI device. (612)
                                // 'index' is a table index (up to the
number of devices answered
                                // by the sqOpenMIDI call).
                                // 'name' is interpreted as (char *) and is
written into--the Smalltalk
                                // code must pre-allocate a ByteArray of
size 64 or greater.
                                // Answer the interface's direction  (see
sqMIDIioPort struct below).
int sqGetMIDIDeviceName(int tableIndex, int deviceName);

                                // Send data to the given device now. (613)
                                // 'message' is interpreted as (unsigned
char *);
                                // 'length' is the number of bytes of data
to send.
                                // 'interface' is the number of a device.
                                // Answer the number of bytes written.
int sqMIDIPlaySizeOn(int MIDImessage, int length, int device);

                                // Read input into a MIDI packet. (614)
                                // 'MIDIpacket' is interpreted as
(MIDIPacket *) and is written into
                                // with the time-stamp, flags, and length.
                                // 'dataBuffer' is interpreted as (unsigned
char *) and gets the MIDI
                                // message data.
                                // Answer the number of data bytes in the
packet.
int sqReadMIDIPacket(int MIDIpacket, int maxSize, int dataBuffer);

                                // Answer the last-read value of the
selected MIDI controller(s)
                                // (assuming controller value caching is
turned on). (615)
                                // Return 0 as a value for controllers for
which no data has come
                                // in (or should this be an error?).
                                // The function stores results values into
the array 'into', which
                                // is interpreted as (int *).
                                // Controller numbers of 0-127 are for the
normal MIDI controllers,
                                //              128-255 are for polyphonic
key pressures;
                                //              256-271 are for channel
pressures;
                                //              272-287 are used for
pitchBend.
                                // The return value the number of values
actually read.
int sqReadMIDIControl(int fromController, int toController, int into);

                                // General-purpose MIDI driver feature
query/set call (like UNIX
                                // device driver ioctl() calls). (616)
                                // 'which' selects the operation (see the
flags defined below);
                                // 'onOff' is a flag for choosing
query/set/clear operations
                                // Answer the result (true/false, or a
number)
int sqMIDIioctl(int whichIoctl, int onOff);


/***********************************************************************************

 * MIDI Driver ioctl flags
 */
////////// ioctl selectors //////////
                                // Is a MIDI driver installed? True iff the
VM includes the MIDI
                                // prims and can successfully open the
OS-level MIDI driver.
#define sqMIDIInstalled         1

                                // What driver version is this? (May be
platform-specific.)
#define sqMIDIVersion           2

                                // Is there a time-stamped output buffer? If
yes, you may use an
                                // extended version of the sqMIDIPlaySizeOn
primitive that includes
                                // an offset time so you can schedule events
in the future
                                // (e.g., sqMIDIPlaySizeOnAt).
#define sqMIDIHasBuffer         3

                                // Is there a 1-call note command? If yes,
you may use an extended
                                // version of the sqMIDIPlaySizeOn primitive
that includes the note
                                // duration and schedules note-off messages
in the driver.
                                // (e.g., sqMIDIPlaySizeOnAtDur).
#define sqMIDIHasDurs           4

                                // Does the driver have its own clock? If
yes, there may be special
                                // primitives to get/set its value.
#define sqMIDIHasClock          5

                                // Should the driver signal a semaphore in
input? If yes, the semaphore
                                // passed down in the sqOpenMIDI call will
be signalled on all event
                                // input, and also on controller input of
controller caching is turned off.
#define sqMIDIUseSemaphore      6

                                // Should we echo in-coming events from the
driver? If yes, all incoming
                                // packets are echo'ed immediately.
#define sqMIDIEcho                      7

                                // Should we cache controller values for
polling? If yes, controller messages
                                // do not trigger the read semaphore, but
the controller values are stored in
                                // tables in the driver. If on, it is
assumed that applications will poll for
                                // controller values using
sqReadMIDIControl.
#define sqMIDIControllerCache   8

                                // How many events are in the input Q?
Answers the number of available packets.
#define sqMIDIEventsAvailable   9

                                // Special flag to flush the driver's I/O
buffers.
#define sqMIDIFlushDriver               10

////////// ioctl arguments //////////
#define sqMIDIQuery             0               // Query about the state of
a feature or flag
#define sqMIDITurnOn    1               // Turn it on
#define sqMIDITurnOff   2               // Turn it off


/***********************************************************************************

 * MIDI Command Codes
 */

#define NoteOnCmd               0x90
#define NoteOffCmd              0x80
#define PgmChngCmd              0xC0
#define ControlCmd              0xB0
#define PolyPressCmd    0xA0
#define ChanPressCmd    0xD0
#define PchWheelCmd             0xE0
#define SysExCmd                0xF0


/***********************************************************************************

 * Event queue entry struct
 */

#define PKT_LEN         255

typedef struct sqMIDIEvent {
        long                    startTime;              // start time in
clock ticks
        long                    timeStamp;              // timestamp in
arbitrary units
        unsigned char   flags;                  // continutation,
timestamped, etc.
        unsigned char   len;                    // number of MIDI bytes
        unsigned char   data[PKT_LEN];          // MIDI data buffer
} sqMIDIEvent;


/***********************************************************************************

 * I/O Port struct
 */
typedef struct sqMIDIioPort {
        char    name[64];                               // port name
        int             direction;                              // port
direction 1=in, 2=out, 3=both
} sqMIDIioPort;


/***********************************************************************************

 *    E N D
 */


--
stp

Stephen Travis Pope | stp at create.ucsb.edu | http://www.create.ucsb.edu/~stp





More information about the Squeak-dev mailing list