Mercurial > hg > svcore
comparison data/midi/rtmidi/RtMidi.cpp @ 562:ecce042cc374
* Wire up MIDI input port (as far as printing a message when an event comes
in, anyway)
| author | Chris Cannam |
|---|---|
| date | Mon, 23 Feb 2009 17:50:17 +0000 |
| parents | 32d156c75df7 |
| children | a5e0d1068cae |
comparison
equal
deleted
inserted
replaced
| 561:863ad4b1f841 | 562:ecce042cc374 |
|---|---|
| 67 | 67 |
| 68 //*********************************************************************// | 68 //*********************************************************************// |
| 69 // Common RtMidiIn Definitions | 69 // Common RtMidiIn Definitions |
| 70 //*********************************************************************// | 70 //*********************************************************************// |
| 71 | 71 |
| 72 RtMidiIn :: RtMidiIn() : RtMidi() | 72 RtMidiIn :: RtMidiIn(std::string name) : RtMidi() |
| 73 { | 73 { |
| 74 this->initialize(); | 74 this->initialize(name); |
| 75 } | 75 } |
| 76 | 76 |
| 77 void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) | 77 void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) |
| 78 { | 78 { |
| 79 if ( inputData_.usingCallback ) { | 79 if ( inputData_.usingCallback ) { |
| 142 | 142 |
| 143 //*********************************************************************// | 143 //*********************************************************************// |
| 144 // Common RtMidiOut Definitions | 144 // Common RtMidiOut Definitions |
| 145 //*********************************************************************// | 145 //*********************************************************************// |
| 146 | 146 |
| 147 RtMidiOut :: RtMidiOut() : RtMidi() | 147 RtMidiOut :: RtMidiOut(std::string name) : RtMidi() |
| 148 { | 148 { |
| 149 this->initialize(); | 149 this->initialize(name); |
| 150 } | 150 } |
| 151 | 151 |
| 152 | 152 |
| 153 //*********************************************************************// | 153 //*********************************************************************// |
| 154 // API: Macintosh OS-X | 154 // API: Macintosh OS-X |
| 309 } | 309 } |
| 310 packet = MIDIPacketNext(packet); | 310 packet = MIDIPacketNext(packet); |
| 311 } | 311 } |
| 312 } | 312 } |
| 313 | 313 |
| 314 void RtMidiIn :: initialize( void ) | 314 void RtMidiIn :: initialize(std::string name) |
| 315 { | 315 { |
| 316 // Set up our client. | 316 // Set up our client. |
| 317 MIDIClientRef client; | 317 MIDIClientRef client; |
| 318 OSStatus result = MIDIClientCreate( CFSTR("RtMidi Input Client"), NULL, NULL, &client ); | 318 OSStatus result = MIDIClientCreate( CFSTR(name.c_str()), NULL, NULL, &client ); |
| 319 if ( result != noErr ) { | 319 if ( result != noErr ) { |
| 320 errorString_ = "RtMidiIn::initialize: error creating OS-X MIDI client object."; | 320 errorString_ = "RtMidiIn::initialize: error creating OS-X MIDI client object."; |
| 321 error( RtError::DRIVER_ERROR ); | 321 error( RtError::DRIVER_ERROR ); |
| 322 } | 322 } |
| 323 | 323 |
| 477 CFRelease( nameRef ); | 477 CFRelease( nameRef ); |
| 478 std::string stringName = name; | 478 std::string stringName = name; |
| 479 return stringName; | 479 return stringName; |
| 480 } | 480 } |
| 481 | 481 |
| 482 void RtMidiOut :: initialize( void ) | 482 void RtMidiOut :: initialize(std::string name) |
| 483 { | 483 { |
| 484 // Set up our client. | 484 // Set up our client. |
| 485 MIDIClientRef client; | 485 MIDIClientRef client; |
| 486 OSStatus result = MIDIClientCreate( CFSTR("RtMidi Output Client"), NULL, NULL, &client ); | 486 OSStatus result = MIDIClientCreate( CFSTR(name.c_str()), NULL, NULL, &client ); |
| 487 if ( result != noErr ) { | 487 if ( result != noErr ) { |
| 488 errorString_ = "RtMidiOut::initialize: error creating OS-X MIDI client object."; | 488 errorString_ = "RtMidiOut::initialize: error creating OS-X MIDI client object."; |
| 489 error( RtError::DRIVER_ERROR ); | 489 error( RtError::DRIVER_ERROR ); |
| 490 } | 490 } |
| 491 | 491 |
| 811 snd_midi_event_free( apiData->coder ); | 811 snd_midi_event_free( apiData->coder ); |
| 812 apiData->coder = 0; | 812 apiData->coder = 0; |
| 813 return 0; | 813 return 0; |
| 814 } | 814 } |
| 815 | 815 |
| 816 void RtMidiIn :: initialize( void ) | 816 void RtMidiIn :: initialize(std::string name) |
| 817 { | 817 { |
| 818 // Set up the ALSA sequencer client. | 818 // Set up the ALSA sequencer client. |
| 819 snd_seq_t *seq; | 819 snd_seq_t *seq; |
| 820 int result = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK); | 820 int result = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK); |
| 821 if ( result < 0 ) { | 821 if ( result < 0 ) { |
| 822 errorString_ = "RtMidiIn::initialize: error creating ALSA sequencer input client object."; | 822 errorString_ = "RtMidiIn::initialize: error creating ALSA sequencer input client object."; |
| 823 error( RtError::DRIVER_ERROR ); | 823 error( RtError::DRIVER_ERROR ); |
| 824 } | 824 } |
| 825 | 825 |
| 826 // Set client name. | 826 // Set client name. |
| 827 snd_seq_set_client_name(seq, "RtMidi Input Client"); | 827 snd_seq_set_client_name(seq, name.c_str()); |
| 828 | 828 |
| 829 // Save our api-specific connection information. | 829 // Save our api-specific connection information. |
| 830 AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; | 830 AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; |
| 831 data->seq = seq; | 831 data->seq = seq; |
| 832 data->vport = -1; | 832 data->vport = -1; |
| 883 if (nSrc < 1) { | 883 if (nSrc < 1) { |
| 884 errorString_ = "RtMidiIn::openPort: no MIDI input sources found!"; | 884 errorString_ = "RtMidiIn::openPort: no MIDI input sources found!"; |
| 885 error( RtError::NO_DEVICES_FOUND ); | 885 error( RtError::NO_DEVICES_FOUND ); |
| 886 } | 886 } |
| 887 | 887 |
| 888 snd_seq_port_info_t *pinfo; | 888 snd_seq_port_info_t *pinfo; |
| 889 snd_seq_port_info_alloca( &pinfo ); | 889 snd_seq_port_info_alloca( &pinfo ); |
| 890 std::ostringstream ost; | 890 std::ostringstream ost; |
| 891 AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_); | 891 AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_); |
| 892 if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, (int) portNumber ) == 0 ) { | 892 if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, (int) portNumber ) == 0 ) { |
| 893 ost << "RtMidiIn::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; | 893 ost << "RtMidiIn::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; |
| 894 errorString_ = ost.str(); | 894 errorString_ = ost.str(); |
| 895 error( RtError::INVALID_PARAMETER ); | 895 error( RtError::INVALID_PARAMETER ); |
| 896 } | 896 } |
| 897 | 897 |
| 898 char name[20]; | |
| 899 sprintf(name, "Input %d", portNumber + 1); | |
| 898 | 900 |
| 899 snd_seq_addr_t sender, receiver; | 901 snd_seq_addr_t sender, receiver; |
| 900 sender.client = snd_seq_port_info_get_client( pinfo ); | 902 sender.client = snd_seq_port_info_get_client( pinfo ); |
| 901 sender.port = snd_seq_port_info_get_port( pinfo ); | 903 sender.port = snd_seq_port_info_get_port( pinfo ); |
| 902 receiver.client = snd_seq_client_id( data->seq ); | 904 receiver.client = snd_seq_client_id( data->seq ); |
| 911 SND_SEQ_PORT_TYPE_APPLICATION ); | 913 SND_SEQ_PORT_TYPE_APPLICATION ); |
| 912 snd_seq_port_info_set_midi_channels(pinfo, 16); | 914 snd_seq_port_info_set_midi_channels(pinfo, 16); |
| 913 snd_seq_port_info_set_timestamping(pinfo, 1); | 915 snd_seq_port_info_set_timestamping(pinfo, 1); |
| 914 snd_seq_port_info_set_timestamp_real(pinfo, 1); | 916 snd_seq_port_info_set_timestamp_real(pinfo, 1); |
| 915 snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); | 917 snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); |
| 916 snd_seq_port_info_set_name(pinfo, "RtMidi Input"); | 918 snd_seq_port_info_set_name(pinfo, name); |
| 917 data->vport = snd_seq_create_port(data->seq, pinfo); | 919 data->vport = snd_seq_create_port(data->seq, pinfo); |
| 918 | 920 |
| 919 if ( data->vport < 0 ) { | 921 if ( data->vport < 0 ) { |
| 920 errorString_ = "RtMidiIn::openPort: ALSA error creating input port."; | 922 errorString_ = "RtMidiIn::openPort: ALSA error creating input port."; |
| 921 error( RtError::DRIVER_ERROR ); | 923 error( RtError::DRIVER_ERROR ); |
| 1093 errorString_ = "RtMidiOut::getPortName: error looking for port name!"; | 1095 errorString_ = "RtMidiOut::getPortName: error looking for port name!"; |
| 1094 error( RtError::INVALID_PARAMETER ); | 1096 error( RtError::INVALID_PARAMETER ); |
| 1095 return 0; | 1097 return 0; |
| 1096 } | 1098 } |
| 1097 | 1099 |
| 1098 void RtMidiOut :: initialize( void ) | 1100 void RtMidiOut :: initialize(std::string name) |
| 1099 { | 1101 { |
| 1100 // Set up the ALSA sequencer client. | 1102 // Set up the ALSA sequencer client. |
| 1101 snd_seq_t *seq; | 1103 snd_seq_t *seq; |
| 1102 int result = snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0); | 1104 int result = snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0); |
| 1103 if ( result < 0 ) { | 1105 if ( result < 0 ) { |
| 1104 errorString_ = "RtMidiOut::initialize: error creating ALSA sequencer client object."; | 1106 errorString_ = "RtMidiOut::initialize: error creating ALSA sequencer client object."; |
| 1105 error( RtError::DRIVER_ERROR ); | 1107 error( RtError::DRIVER_ERROR ); |
| 1106 } | 1108 } |
| 1107 | 1109 |
| 1108 // Set client name. | 1110 // Set client name. |
| 1109 snd_seq_set_client_name(seq, "RtMidi Output Client"); | 1111 snd_seq_set_client_name(seq, name.c_str()); |
| 1110 | 1112 |
| 1111 // Save our api-specific connection information. | 1113 // Save our api-specific connection information. |
| 1112 AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; | 1114 AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; |
| 1113 data->seq = seq; | 1115 data->seq = seq; |
| 1114 data->vport = -1; | 1116 data->vport = -1; |
| 1143 if (nSrc < 1) { | 1145 if (nSrc < 1) { |
| 1144 errorString_ = "RtMidiOut::openPort: no MIDI output sources found!"; | 1146 errorString_ = "RtMidiOut::openPort: no MIDI output sources found!"; |
| 1145 error( RtError::NO_DEVICES_FOUND ); | 1147 error( RtError::NO_DEVICES_FOUND ); |
| 1146 } | 1148 } |
| 1147 | 1149 |
| 1148 snd_seq_port_info_t *pinfo; | 1150 snd_seq_port_info_t *pinfo; |
| 1149 snd_seq_port_info_alloca( &pinfo ); | 1151 snd_seq_port_info_alloca( &pinfo ); |
| 1150 std::ostringstream ost; | 1152 std::ostringstream ost; |
| 1151 AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_); | 1153 AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_); |
| 1152 if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber ) == 0 ) { | 1154 if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber ) == 0 ) { |
| 1153 ost << "RtMidiOut::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; | 1155 ost << "RtMidiOut::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; |
| 1154 errorString_ = ost.str(); | 1156 errorString_ = ost.str(); |
| 1158 snd_seq_addr_t sender, receiver; | 1160 snd_seq_addr_t sender, receiver; |
| 1159 receiver.client = snd_seq_port_info_get_client( pinfo ); | 1161 receiver.client = snd_seq_port_info_get_client( pinfo ); |
| 1160 receiver.port = snd_seq_port_info_get_port( pinfo ); | 1162 receiver.port = snd_seq_port_info_get_port( pinfo ); |
| 1161 sender.client = snd_seq_client_id( data->seq ); | 1163 sender.client = snd_seq_client_id( data->seq ); |
| 1162 | 1164 |
| 1165 char name[20]; | |
| 1166 sprintf(name, "Output %d", portNumber + 1); | |
| 1167 | |
| 1163 if ( data->vport < 0 ) { | 1168 if ( data->vport < 0 ) { |
| 1164 data->vport = snd_seq_create_simple_port( data->seq, "RtMidi Output", | 1169 data->vport = snd_seq_create_simple_port( data->seq, name, |
| 1165 SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, | 1170 SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, |
| 1166 SND_SEQ_PORT_TYPE_MIDI_GENERIC ); | 1171 SND_SEQ_PORT_TYPE_MIDI_GENERIC ); |
| 1167 if ( data->vport < 0 ) { | 1172 if ( data->vport < 0 ) { |
| 1168 errorString_ = "RtMidiOut::openPort: ALSA error creating output port."; | 1173 errorString_ = "RtMidiOut::openPort: ALSA error creating output port."; |
| 1169 error( RtError::DRIVER_ERROR ); | 1174 error( RtError::DRIVER_ERROR ); |
| 1421 } | 1426 } |
| 1422 | 1427 |
| 1423 return 0; | 1428 return 0; |
| 1424 } | 1429 } |
| 1425 | 1430 |
| 1426 void RtMidiIn :: initialize( void ) | 1431 void RtMidiIn :: initialize(std::string name) |
| 1427 { | 1432 { |
| 1428 // Initialize the Irix MIDI system. At the moment, we will not | 1433 // Initialize the Irix MIDI system. At the moment, we will not |
| 1429 // worry about a return value of zero (ports) because there is a | 1434 // worry about a return value of zero (ports) because there is a |
| 1430 // chance the user could plug something in after instantiation. | 1435 // chance the user could plug something in after instantiation. |
| 1431 int nPorts = mdInit(); | 1436 int nPorts = mdInit(); |
| 1562 | 1567 |
| 1563 std::string stringName = std::string( mdGetName( portNumber ) ); | 1568 std::string stringName = std::string( mdGetName( portNumber ) ); |
| 1564 return stringName; | 1569 return stringName; |
| 1565 } | 1570 } |
| 1566 | 1571 |
| 1567 void RtMidiOut :: initialize( void ) | 1572 void RtMidiOut :: initialize(std::string name) |
| 1568 { | 1573 { |
| 1569 // Initialize the Irix MIDI system. At the moment, we will not | 1574 // Initialize the Irix MIDI system. At the moment, we will not |
| 1570 // worry about a return value of zero (ports) because there is a | 1575 // worry about a return value of zero (ports) because there is a |
| 1571 // chance the user could plug something in after instantiation. | 1576 // chance the user could plug something in after instantiation. |
| 1572 int nPorts = mdInit(); | 1577 int nPorts = mdInit(); |
| 1787 // this here allows our code to work for sysex messages which are | 1792 // this here allows our code to work for sysex messages which are |
| 1788 // segmented across multiple buffers. | 1793 // segmented across multiple buffers. |
| 1789 apiData->message.bytes.clear(); | 1794 apiData->message.bytes.clear(); |
| 1790 } | 1795 } |
| 1791 | 1796 |
| 1792 void RtMidiIn :: initialize( void ) | 1797 void RtMidiIn :: initialize(std::string name) |
| 1793 { | 1798 { |
| 1794 // We'll issue a warning here if no devices are available but not | 1799 // We'll issue a warning here if no devices are available but not |
| 1795 // throw an error since the user can plugin something later. | 1800 // throw an error since the user can plugin something later. |
| 1796 unsigned int nDevices = midiInGetNumDevs(); | 1801 unsigned int nDevices = midiInGetNumDevs(); |
| 1797 if ( nDevices == 0 ) { | 1802 if ( nDevices == 0 ) { |
| 1968 | 1973 |
| 1969 std::string stringName( nameString ); | 1974 std::string stringName( nameString ); |
| 1970 return stringName; | 1975 return stringName; |
| 1971 } | 1976 } |
| 1972 | 1977 |
| 1973 void RtMidiOut :: initialize( void ) | 1978 void RtMidiOut :: initialize(std::string name) |
| 1974 { | 1979 { |
| 1975 // We'll issue a warning here if no devices are available but not | 1980 // We'll issue a warning here if no devices are available but not |
| 1976 // throw an error since the user can plug something in later. | 1981 // throw an error since the user can plug something in later. |
| 1977 unsigned int nDevices = midiOutGetNumDevs(); | 1982 unsigned int nDevices = midiOutGetNumDevs(); |
| 1978 if ( nDevices == 0 ) { | 1983 if ( nDevices == 0 ) { |
