1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
//*****************************************//
// cmidiin.cpp
// by Gary Scavone, 2003-2004.
//
// Simple program to test MIDI input and
// use of a user callback function.
//
//*****************************************//
#include <iostream>
#include <cstdlib>
#include "RtMidi.h"
void usage( void ) {
// Error function in case of incorrect command-line
// argument specifications.
std::cout << "\nuseage: cmidiin <port>\n";
std::cout << " where port = the device to use (first / default = 0).\n\n";
exit( 0 );
}
void mycallback( double deltatime, std::vector< unsigned char > *message, void */*userData*/ )
{
unsigned int nBytes = message->size();
for ( unsigned int i=0; i<nBytes; i++ )
std::cout << "Byte " << i << " = " << (int)message->at(i) << ", ";
if ( nBytes > 0 )
std::cout << "stamp = " << deltatime << std::endl;
}
// This function should be embedded in a try/catch block in case of
// an exception. It offers the user a choice of MIDI ports to open.
// It returns false if there are no ports available.
bool chooseMidiPort( RtMidiIn *rtmidi );
RtMidi::Api chooseMidiApi();
int main( int argc, char ** /*argv[]*/ )
{
RtMidiIn *midiin = 0;
// Minimal command-line check.
if ( argc > 2 ) usage();
try {
// RtMidiIn constructor
midiin = new RtMidiIn(chooseMidiApi());
// Call function to select port.
if ( chooseMidiPort( midiin ) == false ) goto cleanup;
// Set our callback function. This should be done immediately after
// opening the port to avoid having incoming messages written to the
// queue instead of sent to the callback function.
midiin->setCallback( &mycallback );
// Don't ignore sysex, timing, or active sensing messages.
midiin->ignoreTypes( false, false, false );
std::cout << "\nReading MIDI input ... press <enter> to quit.\n";
char input;
std::cin.get(input);
} catch ( RtMidiError &error ) {
error.printMessage();
}
cleanup:
delete midiin;
return 0;
}
bool chooseMidiPort( RtMidiIn *rtmidi )
{
std::cout << "\nWould you like to open a virtual input port? [y/N] ";
std::string keyHit;
std::getline( std::cin, keyHit );
if ( keyHit == "y" ) {
rtmidi->openVirtualPort();
return true;
}
std::string portName;
unsigned int i = 0, nPorts = rtmidi->getPortCount();
if ( nPorts == 0 ) {
std::cout << "No input ports available!" << std::endl;
return false;
}
if ( nPorts == 1 ) {
std::cout << "\nOpening " << rtmidi->getPortName() << std::endl;
}
else {
for ( i=0; i<nPorts; i++ ) {
portName = rtmidi->getPortName(i);
std::cout << " Input port #" << i << ": " << portName << '\n';
}
do {
std::cout << "\nChoose a port number: ";
std::cin >> i;
} while ( i >= nPorts );
std::getline( std::cin, keyHit ); // used to clear out stdin
}
rtmidi->openPort( i );
return true;
}
RtMidi::Api chooseMidiApi()
{
std::vector< RtMidi::Api > apis;
RtMidi::getCompiledApi( apis );
if (apis.size() <= 1)
return RtMidi::Api::UNSPECIFIED;
std::cout << "\nAPIs\n API #0: unspecified / default\n";
for (size_t n = 0; n < apis.size(); n++)
std::cout << " API #" << apis[n] << ": " << RtMidi::getApiDisplayName(apis[n]) << "\n";
std::cout << "\nChoose an API number: ";
unsigned int i;
std::cin >> i;
std::string dummy;
std::getline( std::cin, dummy ); // used to clear out stdin
return static_cast< RtMidi::Api >( i );
}
|