void midiInfo() { cout << "MIDI INFO port = " << portopt << endl; std::vector<unsigned char> message; double stamp; int nBytes; int i; #ifdef MARSYAS_MIDIIO RtMidiIn *midiin = NULL; try { midiin = new RtMidiIn(); } catch (RtError3 &error) { error.printMessage(); exit(1); } try { midiin->openPort(portopt); } catch (RtError3 &error) { error.printMessage(); exit(1); } // Don't ignore sysex, timing, or active sensing messages. midiin->ignoreTypes( false, false, false ); while(1) { stamp = midiin->getMessage( &message ); nBytes = message.size(); if (nBytes >0) { for ( i=0; i<nBytes; i++ ) std::cout << "Byte " << i << " = " << (int)message[i] << ", "; if ( nBytes > 0 ) std::cout << "stamp = " << stamp << '\n'; } usleep(10); } #endif }
value rtmidi_in_getmessage(value obj) { RtMidiIn *midiin = (RtMidiIn *)(intptr_t)val_float(obj); std::vector<unsigned char> message; double stamp = midiin->getMessage(&message); // ignore stamp for now value ret = alloc_array(message.size()); for (int i = 0; i < message.size(); ++i) { val_array_set_i(ret, i, alloc_int(message[i])); } return ret; }
void *MIDIReadThread(FREContext ctx) { printf("MIDI Start read thread\n"); std::vector<unsigned char> message; int nBytes; double stamp; while(!exitRunThread) { //printf("Check thread, %i devices\n",openMidiIn.size()); for(unsigned int di=0;di<openMidiIn.size();di++) { RtMidiIn * in = openMidiIn[di]; while(true) { stamp = in->getMessage(&message ); nBytes = message.size(); if(nBytes == 3) //complete midi message { midiMessage m; m.device = in; m.stamp = stamp; m.status = message[0]; //printf("Status %i from %i\n",m.status,in); m.data1 = message[1]; m.data2 = message[2]; messageQueue.push_back(m); FREDispatchStatusEventAsync(ctx,(const uint8_t *)"data",(const uint8_t *)"none"); }else if(nBytes == 0) break; } } // Sleep for 10 milliseconds ... platform-dependent. Sleep( 1 ); //FREDispatchStatusEventAsync(ctx,(const uint8_t *)"data",(const uint8_t *)"myo"); } printf("Exit Run Thread !\n"); return 0; }
double rtmidi_in_get_message (RtMidiInPtr device, unsigned char *message, size_t *size) { #if defined(__NO_EXCEPTIONS__) // FIXME: use allocator to achieve efficient buffering std::vector<unsigned char> v; RtMidiIn* rtm = (RtMidiIn*) device->ptr; rtm->resetError(); double ret = rtm->getMessage (&v); if (rtm->isError()) { device->ok = false; device->msg = rtm->getError().what (); return -1; } if (v.size () > 0 && v.size() <= *size) { memcpy (message, v.data (), (int) v.size ()); } *size = v.size(); return ret; #else try { // FIXME: use allocator to achieve efficient buffering std::vector<unsigned char> v; double ret = ((RtMidiIn*) device->ptr)->getMessage (&v); if (v.size () > 0 && v.size() <= *size) { memcpy (message, v.data (), (int) v.size ()); } *size = v.size(); return ret; } catch (const RtMidiError & err) { device->ok = false; device->msg = err.what (); return -1; } catch (...) { device->ok = false; device->msg = "Unknown error"; return -1; } #endif }
/* returns 0 if no new messages, otherwise populates message */ int get_midi_message(MidiMsg *message) { std::vector<unsigned char> rtmsg; while(true) { midi.getMessage(&rtmsg); if(rtmsg.size() == 0) return 0; int type = (rtmsg[0] & 0xf0) >> 4; message->control = 0; message->pitch_bend = 0; if(type == MIDI_NOTE_OFF || (type == MIDI_NOTE_ON && rtmsg[2] == 0)) { message->velocity = 0; } else if(type == MIDI_NOTE_ON) { message->velocity = rtmsg[2] / 127.0; } else if(type == MIDI_KEY_PRESSURE) { message->velocity = rtmsg[2] / 127.0; } else if(type == MIDI_CONTROL) { message->control = 1; message->velocity = rtmsg[2] / 127.0; } else if(type == MIDI_PITCH_BEND) { message->pitch_bend = 1; message->velocity = rtmsg[2] / 127.0; } else { printf("unknown: %d size %ld [%d %d %d]\n", type, rtmsg.size(), rtmsg[0], rtmsg[1], rtmsg[2]); continue; // unrecognized } message->channel = rtmsg[0] & 0x0f; message->note = rtmsg[1]; return 1; } }
static VALUE rtMidiIn_getData(VALUE self) { RtMidiIn *device; Data_Get_Struct(self, RtMidiIn, device); std::vector<unsigned char> message; VALUE messages = rb_ary_new(); try { double stamp = device->getMessage(&message); for(int x = 0; x < message.size(); x++) { rb_ary_push(messages, INT2FIX((int)message[x])); } } catch(RtError &error) { rb_warn("getData failed"); } return messages; }
void MidiListener::run() { vector<unsigned char> message; int nBytes; double stamp; RtMidiIn *midiIn = tmidi_data->midiIn; int this_patch_num; if ( tmidi_data->verboseMode ) cout << "MidiListener thread running\n"; // Install an interrupt handler function //(void) signal(SIGINT, finish); while ( true ) { stamp = midiIn->getMessage( &message ); nBytes = message.size(); if ( nBytes > 0 ) { if ( message[0] == MIDI_SYSEX_HEADER ) { // if ( tmidi_data->verboseMode ) cout << "MidiListener: SysEx response received " << nBytes << " bytes\n"; switch (message[4]) { case MIDI_PRESET_DUMP: if ( tmidi_data->verboseMode ) cout << "MidiListener: SysEx Preset Dump response received " << nBytes << " bytes\n"; patch_t this_patch; if (nBytes != EWI_SYSEX_PRESET_DUMP_LEN) { cout << "Invalid Preset Dump received from EWI (" << nBytes << " bytes)\n"; break; } for ( int i = 0; i < EWI_PATCH_LENGTH; i++ ) this_patch.whole_patch[i] = message[i]; if ( this_patch.parameters.header[3] == MIDI_SYSEX_ALLCHANNELS ) { this_patch_num = ( int ) this_patch.parameters.patch_num++; if (this_patch_num < 0 || this_patch_num >= EWI_NUM_PATCHES) { cout << "Illegal patch number recieved from EWI - " << this_patch_num << "\n"; break; } for ( int i = 0; i < EWI_PATCH_LENGTH; i++ ) tmidi_data->patches[this_patch_num].whole_patch[i] = message[i]; tmidi_data->last_patch_loaded = this_patch_num; if ( tmidi_data->verboseMode ) cout << "MidiListener: Received " << this_patch_num + 1 << " - " << this_patch.parameters.name << "\n"; } break; case MIDI_QUICKPC_DUMP: if ( tmidi_data->verboseMode ) cout << "MidiListener: SysEx QuickPC Dump response received " << nBytes << " bytes\n"; if (nBytes != EWI_SYSEX_QUICKPC_DUMP_LEN) { cout << "Invalid QuickPC Dump received from EWI (" << nBytes << " bytes)\n"; break; } for (int i = 0; i < EWI_NUM_QUICKPCS; i++) { tmidi_data->quickPCs[i] = message[i+6]; } break; default: cerr << "MidiListener: Unrecognised SysEx type received (type " << message[4] <<")\n"; break; } tmidi_data->mymutex.lock(); tmidi_data->sysexDone.wakeAll(); tmidi_data->mymutex.unlock(); } // All non-SysEx messages are ignored } SLEEP( 10 ); } }
int main( int argc, char *argv[] ) { RtMidiIn *midiin = 0; std::vector<unsigned char> message; int nBytes, i; double stamp; // Minimal command-line check. if ( argc > 2 ) usage(); // RtMidiIn constructor try { midiin = new RtMidiIn(); } catch ( RtError &error ) { error.printMessage(); exit( EXIT_FAILURE ); } // Check available ports vs. specified. unsigned int port = 0; unsigned int nPorts = midiin->getPortCount(); if ( argc == 2 ) port = (unsigned int) atoi( argv[1] ); if ( port >= nPorts ) { delete midiin; std::cout << "Invalid port specifier!\n"; usage(); } try { midiin->openPort( port ); } catch ( RtError &error ) { error.printMessage(); goto cleanup; } // Don't ignore sysex, timing, or active sensing messages. midiin->ignoreTypes( false, false, false ); // Install an interrupt handler function. done = false; (void) signal(SIGINT, finish); // Periodically check input queue. std::cout << "Reading MIDI from port ... quit with Ctrl-C.\n"; while ( !done ) { stamp = midiin->getMessage( &message ); nBytes = message.size(); for ( i=0; i<nBytes; i++ ) std::cout << "Byte " << i << " = " << (int)message[i] << ", "; if ( nBytes > 0 ) std::cout << "stamp = " << stamp << std::endl; // Sleep for 10 milliseconds. SLEEP( 10 ); } // Clean up cleanup: delete midiin; return 0; }
//Pluck Karplus Strong Model Plucked.cpp outputs to DAC void PluckLive(string deviceopt, mrs_real pos, mrs_real fre, mrs_real loz, mrs_real stret) { #ifdef MARSYAS_MIDIIO RtMidiIn *midiin = 0; std::vector<unsigned char> message; double stamp; int nBytes; int i; // initialize RtMidi try { midiin = new RtMidiIn(); } catch (RtError3 &error) { error.printMessage(); exit(1); } // find input midi port try { midiin->openPort(portopt); } catch (RtError3 &error) { error.printMessage(); exit(1); } MarSystemManager mng; MarSystem* series = mng.create("Series", "series"); // create 16 plucked Karplus-Strong strings MarSystem* mix = mng.create("Fanout", "mix"); for (mrs_natural i = 0; i < 16; i++) { ostringstream oss; oss << "src" << i; mix->addMarSystem(mng.create("Plucked", oss.str())); } series->addMarSystem(mix); series->addMarSystem(mng.create("Sum", "sum")); series->addMarSystem(mng.create("Gain", "gain")); series->addMarSystem(mng.create("AudioSink", "dest")); series->update(); series->updctrl("Gain/gain/mrs_real/gain", 0.10); series->updctrl("AudioSink/dest/mrs_real/israte", series->getctrl("Fanout/mix/Plucked/src0/mrs_real/osrate")); series->updctrl("AudioSink/dest/mrs_natural/bufferSize", 128); series->updctrl("Fanout/mix/Plucked/src0/mrs_real/frequency",fre); series->updctrl("Fanout/mix/Plucked/src0/mrs_real/pluckpos",pos); series->updctrl("Fanout/mix/Plucked/src0/mrs_real/loss",loz); series->updctrl("mrs_natural/inSamples", 64); series->update(); // initially only play one string for (int i=1; i < 16; i++) { ostringstream oss1; oss1 << "Fanout/mix/Plucked/src" << i << "/mrs_real/nton"; series->updctrl(oss1.str(), 0.0); } mrs_natural t=0; int channel, type, byte2, byte3; int mes_count = 0; mrs_real freq; int p0byte3, p1byte3, p2byte3; // used to keep track of polyphony vector<int> voices; for (int i=0; i < 16; i++) { voices.push_back(0); } while(1) { // for (int i=0; i < 4; i++) // { stamp = midiin->getMessage( &message ); // } nBytes = message.size(); if (nBytes > 0) { byte3 = message[2]; byte2 = message[1]; type = message[0]; if (deviceopt == "Keyboard") { if (type == 144) { // allocate voice for (int i=0; i < 16; i++) { if (voices[i] == 0) { voices[i] = byte2; break; } } // free voice if velocity is 0 (implicit noteoff) for (int i=0; i < 16; i++) { if ((byte3 == 0)&&(voices[i] == byte2)) { voices[i] = 0; break; } } for (int i=0; i < 16; i++) { ostringstream oss, oss1; oss << "Fanout/mix/Plucked/src" << i << "/mrs_real/frequency"; oss1 << "Fanout/mix/Plucked/src" << i << "/mrs_real/nton"; if (voices[i] != 0) { freq = 220.0 * pow( 2.0,(voices[i] - 57.0) / 12.0 ); series->updctrl(oss1.str(), 1.0); series->updctrl(oss.str(),freq); // series->update(); } } } if (type == 128) { // free voice if noteoff for (int i=0; i < 16; i++) { if (voices[i] == byte2) { ostringstream oss, oss1; oss1 << "Fanout/mix/Plucked/src" << i << "/mrs_real/nton"; series->updctrl(oss1.str(), 0.0); voices[i] = 0; break; } } } } if (deviceopt == "KiomB") { if (byte2 == 0) { freq = 220.0 * pow( 2.0, (byte3 - 57.0) / 12.0 ); if ((byte3 > 25)&&(abs(byte3 - p0byte3) > 2)) { series->updctrl("Fanout/mix/Plucked/src0/mrs_real/frequency",freq); } } p0byte3 = byte3; } if (byte2 == 1) { freq = 220.0 * pow( 2.0, (byte3 - 60.0) / 12.0 ); if ((byte3 > 25)&&(abs(byte3 - p1byte3) > 2)) series->updctrl("Fanout/mix/Plucked/src1/mrs_real/frequency",freq); p1byte3 = byte3; } if (byte2 == 2) { freq = 220.0 * pow( 2.0, (byte3 - 62.0) / 12.0 ); if ((byte3 > 25)&&(abs(byte3 - p2byte3) > 2)) series->updctrl("Fanout/mix/Plucked/src2/mrs_real/frequency",freq); p2byte3 = byte3; } } series->tick(); t++; } #endif }