aboutsummaryrefslogtreecommitdiff
path: root/src/midiio/src/Sequencer_alsa05.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/midiio/src/Sequencer_alsa05.cpp')
-rw-r--r--src/midiio/src/Sequencer_alsa05.cpp518
1 files changed, 518 insertions, 0 deletions
diff --git a/src/midiio/src/Sequencer_alsa05.cpp b/src/midiio/src/Sequencer_alsa05.cpp
new file mode 100644
index 0000000..ad4ef2d
--- /dev/null
+++ b/src/midiio/src/Sequencer_alsa05.cpp
@@ -0,0 +1,518 @@
+//
+// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
+// Creation Date: Thu May 11 21:10:02 PDT 2000
+// Last Modified: Wed Oct 3 22:18:27 PDT 2001 (frozen to ALSA 0.5)
+// Filename: ...sig/maint/code/control/Sequencer_alsa05.cpp
+// Web Address: http://sig.sapp.org/src/sig/Sequencer_alsa05.cpp
+// Syntax: C++
+//
+// Description: Basic MIDI input/output functionality for the
+// Linux ALSA raw midi devices. This class
+// is inherited by the classes MidiInPort_alsa05 and
+// MidiOutPort_alsa05.
+//
+
+#if defined(LINUX) && defined(ALSA05)
+
+#include "Collection.h"
+#include <sys/asoundlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <string.h>
+#include <iostream.h>
+#include <stdio.h>
+#include "Sequencer_alsa05.h"
+
+typedef unsigned char uchar;
+
+// define static variables:
+int Sequencer_alsa05::class_count = 0;
+int Sequencer_alsa05::initialized = 0;
+
+// static variables for MIDI I/O information database
+int Sequencer_alsa05::indevcount = 0;
+int Sequencer_alsa05::outdevcount = 0;
+
+Collection<snd_rawmidi_t*> Sequencer_alsa05::rawmidi_in;
+Collection<snd_rawmidi_t*> Sequencer_alsa05::rawmidi_out;
+Collection<int> Sequencer_alsa05::midiincard;
+Collection<int> Sequencer_alsa05::midioutcard;
+Collection<int> Sequencer_alsa05::midiindevice;
+Collection<int> Sequencer_alsa05::midioutdevice;
+Collection<char*> Sequencer_alsa05::midiinname;
+Collection<char*> Sequencer_alsa05::midioutname;
+
+
+
+///////////////////////////////
+//
+// Sequencer_alsa05::Sequencer_alsa05 --
+// default value: autoOpen = 1;
+//
+
+Sequencer_alsa05::Sequencer_alsa05(int autoOpen) {
+ if (class_count < 0) {
+ cerr << "Unusual class instatiation count: " << class_count << endl;
+ exit(1);
+ } else if (class_count == 0) {
+ buildInfoDatabase();
+ }
+
+ if (autoOpen) {
+ open();
+ }
+
+ class_count++;
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::~Sequencer_alsa05 --
+//
+
+Sequencer_alsa05::~Sequencer_alsa05() {
+
+ if (class_count == 1) {
+ close();
+ removeInfoDatabase();
+ } else if (class_count <= 0) {
+ cerr << "Unusual class instatiation count: " << class_count << endl;
+ exit(1);
+ }
+
+ class_count--;
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::close -- close the sequencer device. The device
+// automatically closes once the program ends.
+//
+
+void Sequencer_alsa05::close(void) {
+ int i;
+
+ for (i=0; i<getNumInputs(); i++) {
+ if (rawmidi_in[i] != NULL) {
+ snd_rawmidi_close(rawmidi_in[i]);
+ rawmidi_in[i] = NULL;
+ }
+ }
+
+ for (i=0; i<getNumOutputs(); i++) {
+ if (rawmidi_out[i] != NULL) {
+ snd_rawmidi_close(rawmidi_out[i]);
+ rawmidi_out[i] = NULL;
+ }
+ }
+
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::displayInputs -- display a list of the
+// available MIDI input devices.
+// default values: out = cout, initial = "\t"
+//
+
+void Sequencer_alsa05::displayInputs(ostream& out, char* initial) {
+ for (int i=0; i<getNumInputs(); i++) {
+ out << initial << i << ": " << getInputName(i) << '\n';
+ }
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::displayOutputs -- display a list of the
+// available MIDI output devices.
+// default values: out = cout, initial = "\t"
+//
+
+void Sequencer_alsa05::displayOutputs(ostream& out, char* initial) {
+ for (int i=0; i<getNumOutputs(); i++) {
+ out << initial << i << ": " << getOutputName(i) << '\n';
+ }
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::getInputName -- returns a string to the name of
+// the specified input device. The string will remain valid as
+// long as there are any sequencer devices in existence.
+//
+
+const char* Sequencer_alsa05::getInputName(int aDevice) {
+ if (initialized == 0) {
+ buildInfoDatabase();
+ }
+ return midiinname[aDevice];
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::getNumInputs -- returns the total number of
+// MIDI inputs that can be used.
+//
+
+int Sequencer_alsa05::getNumInputs(void) {
+ if (initialized == 0) {
+ buildInfoDatabase();
+ }
+ return indevcount;
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::getNumOutputs -- returns the total number of
+// MIDI inputs that can be used.
+//
+
+int Sequencer_alsa05::getNumOutputs(void) {
+ if (initialized == 0) {
+ buildInfoDatabase();
+ }
+ return outdevcount;
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::getOutputName -- returns a string to the name of
+// the specified output device. The string will remain valid as
+// long as there are any sequencer devices in existence.
+//
+
+const char* Sequencer_alsa05::getOutputName(int aDevice) {
+ if (initialized == 0) {
+ buildInfoDatabase();
+ }
+ return midioutname[aDevice];
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::is_open -- returns true if the
+// sequencer device is open, false otherwise.
+//
+
+int Sequencer_alsa05::is_open(int mode, int index) {
+ if (mode == 0) {
+ // midi output
+ if (rawmidi_out[index] != NULL) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ if (rawmidi_in[index] != NULL) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
+
+
+int Sequencer_alsa05::is_open_in(int index) {
+ return is_open(1, index);
+}
+
+
+int Sequencer_alsa05::is_open_out(int index) {
+ return is_open(0, index);
+}
+
+
+
+/////////////////////////////
+//
+// Sequencer_alsa05::open -- returns true if the device
+// was successfully opended (or already opened)
+//
+
+int Sequencer_alsa05::open(void) {
+ if (rawmidi_out.getSize() != 0 || rawmidi_in.getSize() != 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::read -- reads MIDI bytes and also stores the
+// device from which the byte was read from. Timing is not
+// saved from the device. If needed, then it would have to
+// be saved in this function, or just return the raw packet
+// data (use rawread function).
+//
+
+void Sequencer_alsa05::read(int dev, uchar* buf, int count) {
+ snd_rawmidi_read(rawmidi_in[dev], buf, count);
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::rebuildInfoDatabase -- rebuild the internal
+// database that keeps track of the MIDI input and output devices.
+//
+
+void Sequencer_alsa05::rebuildInfoDatabase(void) {
+ removeInfoDatabase();
+ buildInfoDatabase();
+}
+
+
+
+///////////////////////////////
+//
+// Sequencer_alsa05::write -- Send a byte out the specified MIDI
+// port which can be either an internal or an external synthesizer.
+//
+
+int Sequencer_alsa05::write(int aDevice, int aByte) {
+ uchar byte[1];
+ byte[0] = (uchar)aByte;
+ return write(aDevice, byte, 1);
+}
+
+
+int Sequencer_alsa05::write(int aDevice, uchar* bytes, int count) {
+ int status = snd_rawmidi_write(rawmidi_out[aDevice], bytes, count);
+ return status == count ? 1 : 0;
+}
+
+
+int Sequencer_alsa05::write(int aDevice, char* bytes, int count) {
+ return write(aDevice, (uchar*)bytes, count);
+}
+
+
+int Sequencer_alsa05::write(int aDevice, int* bytes, int count) {
+ uchar *newBytes;
+ newBytes = new uchar[count];
+ for (int i=0; i<count; i++) {
+ newBytes[i] = (uchar)bytes[i];
+ }
+ int status = write(aDevice, newBytes, count);
+ delete [] newBytes;
+ return status;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// private functions
+//
+
+//////////////////////////////
+//
+// Sequencer_alsa05::buildInfoDatabase -- determines the number
+// of MIDI input and output devices available from
+// /dev/snd/midiXX, and determines their names.
+//
+
+void Sequencer_alsa05::buildInfoDatabase(void) {
+ if (initialized) {
+ return;
+ }
+
+ initialized = 1;
+
+ if (indevcount != 0 || outdevcount != 0) {
+ cout << "Error: Sequencer_alsa05 is already running" << endl;
+ cout << "Indevcout = " << indevcount << " and "
+ << " outdevcount = " << outdevcount << endl;
+ exit(1);
+ }
+
+ indevcount = 0;
+ outdevcount = 0;
+
+ midiincard.setSize(0);
+ midiincard.allowGrowth();
+ midioutcard.setSize(0);
+ midioutcard.allowGrowth();
+
+ midiindevice.setSize(0);
+ midiindevice.allowGrowth();
+ midioutdevice.setSize(0);
+ midioutdevice.allowGrowth();
+
+ midiinname.setSize(0);
+ midiinname.allowGrowth();
+ midioutname.setSize(0);
+ midioutname.allowGrowth();
+
+ rawmidi_in.setSize(256);
+ rawmidi_out.setSize(256);
+
+ // read number of MIDI inputs/output available
+ int card;
+ int device;
+
+ for (card=0; card<16; card++) {
+ for (device=0; device<16; device++) {
+ if (snd_rawmidi_open(&rawmidi_in[indevcount], card, device,
+ O_RDONLY | O_APPEND | O_NONBLOCK) == 0){
+ midiincard.append(card);
+ midiindevice.append(device);
+ indevcount++;
+ }
+ }
+ }
+ rawmidi_in.setSize(indevcount);
+
+ for (card=0; card<16; card++) {
+ for (device=0; device<16; device++) {
+ if (snd_rawmidi_open(&rawmidi_out[outdevcount], card,
+ device, O_WRONLY | O_APPEND | O_NONBLOCK) == 0) {
+ midioutcard.append(card);
+ midioutdevice.append(device);
+ outdevcount++;
+ }
+ }
+ }
+ rawmidi_out.setSize(indevcount);
+
+ int i;
+ char buffer[256] = {0};
+ char* temp;
+ for (i=0; i<indevcount; i++) {
+ sprintf(buffer, "MIDI input %d", i);
+ temp = new char[strlen(buffer) + 1];
+ strcpy(temp, buffer);
+ midiinname.append(temp);
+ }
+
+ for (i=0; i<outdevcount; i++) {
+ sprintf(buffer, "MIDI output %d", i);
+ temp = new char[strlen(buffer) + 1];
+ strcpy(temp, buffer);
+ midioutname.append(temp);
+ }
+
+ midiincard.allowGrowth(0);
+ midioutcard.allowGrowth(0);
+ midiindevice.allowGrowth(0);
+ midioutdevice.allowGrowth(0);
+ midiinname.allowGrowth(0);
+ midioutname.allowGrowth(0);
+ rawmidi_in.allowGrowth(0);
+ rawmidi_out.allowGrowth(0);
+
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::getInDeviceValue --
+//
+
+int Sequencer_alsa05::getInDeviceValue(int aDevice) const {
+ return midiindevice[aDevice];
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::getInCardValue --
+//
+
+int Sequencer_alsa05::getInCardValue(int aDevice) const {
+ return midiincard[aDevice];
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::getOutDeviceValue --
+//
+
+int Sequencer_alsa05::getOutDeviceValue(int aDevice) const {
+ return midioutdevice[aDevice];
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::getOutCardValue --
+//
+
+int Sequencer_alsa05::getOutCardValue(int aDevice) const {
+ return midioutcard[aDevice];
+}
+
+
+
+//////////////////////////////
+//
+// Sequencer_alsa05::removeInfoDatabase --
+//
+
+void Sequencer_alsa05::removeInfoDatabase(void) {
+ if (rawmidi_in.getSize() != 0) {
+ close();
+ }
+
+ if (rawmidi_out.getSize() != 0) {
+ close();
+ }
+
+ rawmidi_in.setSize(0);
+ rawmidi_out.setSize(0);
+ midiincard.setSize(0);
+ midioutcard.setSize(0);
+ midiindevice.setSize(0);
+ midioutdevice.setSize(0);
+
+ int i;
+ for (i=0; i<midiinname.getSize(); i++) {
+ if (midiinname[i] != NULL) {
+ delete [] midiinname[i];
+ }
+ }
+
+ for (i=0; i<midioutname.getSize(); i++) {
+ if (midioutname[i] != NULL) {
+ delete [] midioutname[i];
+ }
+ }
+
+ indevcount = 0;
+ outdevcount = 0;
+ initialized = 0;
+}
+
+
+#endif /* LINUX and ALSA05 */
+
+
+// md5sum: b47021f0b71b2bc1555755584777c9a8 - Sequencer_alsa05.cpp =css= 20030102