
Contents of /Public_Sound_Midi-1.0/Midi.cmod:
#include "global.h"
#include "svalue.h"
#include "interpret.h"
#include "backend.h"
#include "module_support.h"
#include "object.h"
#include "builtin_functions.h"
#include "mapping.h"
#include "threads.h"
#include "bignum.h"
/* All your includes here */
#include "portmidi/porttime.h"
#include "portmidi/portmidi.h"
/* Global variables
*/
#define TIME_PROC ((long (*)(void *)) Pt_Time)
#define TIME_INFO NULL
#define TIME_START Pt_Start(1, 0, 0)
DECLARATIONS
/*! @module Public
*/
/*! @module Sound
*/
/*! @module Midi
*/
/*! @class Device
*/
/* note
This MIDI module is a wrapper around portmidi (http://portmedia.sourceforge.net/) and consists of two classes:
The class Device is used for the actual communication, and the additional class Control is used to find out about the available MIDI devices.
*/
PIKECLASS Device {
CVAR const PmDeviceInfo * info;
CVAR PmStream * stream;
CVAR int ID;
CVAR PmEvent output_buffer[1];
CVAR PmEvent input_buffer[1];
CVAR int status;
CVAR int data1;
CVAR int data2;
/*! @decl void create(int ID)
*! Create a MIDI object for communication. You have to provide a device ID. ID numbers start from zero and go up until the maximum available. (Which can be checked with a control object, using the count_devices() function.)
*! @note
*! Each port is another device!
*/
PIKEFUN void create(int device_id) {
THIS->info = Pm_GetDeviceInfo(device_id);
THIS->ID = device_id;
pop_n_elems(args);
}
/*! @decl void set_ID(int ID)
*! Access another device with this object.
*/
PIKEFUN void set_ID(int device_id) {
// this does the same as the previous function, we should be able to merge them
THIS->info = Pm_GetDeviceInfo(device_id);
THIS->ID = device_id;
pop_n_elems(args);
}
/*! @decl int get_ID()
*! Retrieve the ID of the MIDI device this object addresses.
*/
PIKEFUN int get_ID() {
RETURN(THIS->ID);
}
/*! @decl int get_version()
*! Not really needed in most circumstanses. It gives you the version number of the PortMidi library.
*/
PIKEFUN int get_version() {
RETURN(THIS->info->structVersion);
}
/*! @decl string get_interface()
*! This gives you the type of interface that goes with the device, like ALSA or Jack.
*/
PIKEFUN string get_interface() {
struct pike_string *interface = make_shared_string(THIS->info->interf);
RETURN(interface);
}
/*! @decl string get_name()
*! This gives you the descriptive name of this interface.
*/
PIKEFUN string get_name() {
struct pike_string *name = make_shared_string(THIS->info->name);
RETURN(name);
}
/*! @decl int is_input()
*! See if this device is an input or output.
*/
PIKEFUN int is_input() {
RETURN(THIS->info->input);
}
/*! @decl int is_output()
*! See if this device is an input or output.
*/
PIKEFUN int is_output() {
RETURN(THIS->info->output);
}
/*! @decl int is_open()
*! See if this device is opened, which is needed before you can use it.
*/
PIKEFUN int is_open() {
RETURN(THIS->info->opened);
}
/*! @decl int open()
*! Open the device. The return value will be null or an error id.
*/
PIKEFUN int open() {
int err;
if (THIS->info->output) {
err = Pm_OpenOutput(&THIS->stream, THIS->ID, NULL, 0, NULL, NULL, 0);
} else {
// must be an input
err = Pm_OpenInput(&THIS->stream, THIS->ID, NULL, 0, NULL, NULL);
}
RETURN(err);
}
/*! @decl int message(int status, int data1, int data2)
*! Directly output a MIDI message.
*! @param status
*! The status byte, like 0x90 for a note-on event. Consult a MIDI manual for more information.
*! @param data1
*! @param data2
*! The two parts of the midi message
*/
PIKEFUN int message(int status, int data1, int data2) {
THIS->output_buffer[0].message = Pm_Message(status, data1, data2);
THIS->output_buffer[0].timestamp = TIME_PROC(TIME_INFO);
int err = Pm_Write(THIS->stream, THIS->output_buffer, 1);
RETURN(err);
}
/*! @decl int read()
*! Call this function to see if there is MIDI input waiting to be parsed. Returns 1 if a new message is waiting or 0 zero when the MIDI buffer was empty. A negative number signals an error.
*! @note
*! Use the functions get_status(), get_data1() and get_data2() to get the actual information contained in the message.
*/
PIKEFUN int read() {
int count = Pm_Read(THIS->stream, THIS->input_buffer, 1);
RETURN(count);
}
/*! @decl int get_status()
*! Retreive the status byte from the last read message.
*/
PIKEFUN int get_status() {
THIS->status = Pm_MessageStatus(THIS->input_buffer[0].message);
RETURN(THIS->status);
}
/*! @decl int is_data1()
*! Retreive the first data byte from the last read message.
*/
PIKEFUN int get_data1() {
THIS->data1 = Pm_MessageData1(THIS->input_buffer[0].message);
RETURN(THIS->data1);
}
/*! @decl int is_data2()
*! Retreive the second data byte from the last read message.
*/
PIKEFUN int get_data2() {
THIS->data2 = Pm_MessageData2(THIS->input_buffer[0].message);
RETURN(THIS->data2);
}
/*! @decl int is_data1()
*! Retreive the first data byte from the last read message.
*/
PIKEFUN int abort() {
int err = Pm_Abort(THIS->stream);
RETURN(err);
}
/*! @decl int close()
*! Close this device. Returns zero or an error code.
*/
PIKEFUN int close() {
int err = Pm_Close(THIS->stream);
RETURN(err);
}
INIT {
}
}
/*! @endclass
*/
/*! @class Control
*/
/* note
This MIDI module is a wrapper around portmidi (http://portmedia.sourceforge.net/) and consists of two classes:
The class Device is used for the actual communication, and the additional class Control is used to find out about the available MIDI devices.
*/
PIKECLASS Control {
PIKEFUN int create() {
int x = Pm_Initialize();
TIME_START;
RETURN(x);
}
/*! @decl int count_devices()
*! Query the number of available devices.
*/
PIKEFUN int count_devices() {
int x = Pm_CountDevices();
RETURN(x);
}
/*! @decl int get_default_input_device_id()
*! Get the ID of the default input device.
*/
PIKEFUN int get_default_input_device_id() {
int x = Pm_GetDefaultInputDeviceID();
RETURN(x);
}
/*! @decl int get_default_output_device_id()
*! Get the ID of the default output device.
*/
PIKEFUN int get_default_output_device_id() {
int x = Pm_GetDefaultOutputDeviceID();
RETURN(x);
}
/*! @decl string get_error_text(int error)
*! Convert an errorcode to a textual explanation.
*/
PIKEFUN string get_error_text(int error) {
struct pike_string *str;
str = make_shared_string(Pm_GetErrorText(error));
RETURN(str);
}
/*! @decl void terminate()
*! Close all MIDI connections. Call this when your program ends or when you want to initialize all over again.
*/
PIKEFUN void terminate() {
Pm_Terminate();
pop_n_elems(args);
}
INIT{
}
EXIT{
}
}
/*! @endclass
*/
/*! @endmodule
*/
/*! @endmodule
*/
/*! @endmodule
*/