void FugueSampler::update(unsigned long long tick) { for(unsigned track=0; track < nTracks; track++) { unsigned index = indices.at(track); if(file.getEventCount(track) > index) { if(file[track][index].isNoteOn()) { MidiEvent event = file.getEvent(track, index); float duration = file[track][index].getDurationInSeconds(); if(event.tick < tick) { const char name = event.at(1); if(sampler.isRecorded(name)) { sampler.play(name, duration); } else { sampler.record(name); cout << "REC" << endl; } indices.at(track)++; eventCounter++; unsigned percent = (float)eventCounter/(float)nEvents*100; if(percent!=oldPercent) { cout << percent << "%" << endl; } oldPercent = percent; } } else { indices.at(track)++; } } } }
void MidiTrack::readTrackData(istream & input) { long totalTicks = 0; while (!input.eof()) { VariableLengthInt delta(input); totalTicks += delta.getValue(); MidiEvent * E = MidiEvent::parseEvent(totalTicks, delta.getValue(), input); if (E == NULL) { cout << "Event skipped!"; continue; } if (VERBOSE) { cout << E->toString().c_str(); } // Not adding the EndOfTrack event here allows the track to be edited // after being read in from file. if (E->getType() == MetaEvent::END_OF_TRACK) { break; } mEvents.push_back(E); } }
int FILE_IO::getNextMidiMsg(int channel, int tick) { MidiEvent event; while((event = midiFile.getEvent(0, index)).tick == tick){ //if() continue; //cases to ignore printf("0\n"); MidiMessage msg; msg.setSize(event.getSize()); for(int i=0; i < event.getSize(); i++){ msg[i] = event[i]; } writeInMidiMsg(channel, msg); index++; if (index == midiFile.getNumEvents(0)){ resetIndex(); return 0; } } return 1; }
void MidiWinMM::processOutEvent( const MidiEvent& event, const MidiTime& time, const MidiPort* port ) { const DWORD shortMsg = ( event.type() + event.channel() ) + ( ( event.param( 0 ) & 0xff ) << 8 ) + ( ( event.param( 1 ) & 0xff ) << 16 ); QStringList outDevs; for( SubMap::ConstIterator it = m_outputSubs.begin(); it != m_outputSubs.end(); ++it ) { for( MidiPortList::ConstIterator jt = it.value().begin(); jt != it.value().end(); ++jt ) { if( *jt == port ) { outDevs += it.key(); break; } } } for( QMap<HMIDIOUT, QString>::Iterator it = m_outputDevices.begin(); it != m_outputDevices.end(); ++it ) { if( outDevs.contains( *it ) ) { midiOutShortMsg( it.key(), shortMsg ); } } }
int main(int argc, char* argv[]) { checkOptions(options, argc, argv); MidiFile outfile; outfile.joinTracks(); outfile.deltaTicks(); int i; int initQ = 0; for (i=1; i<=options.getArgCount(); i++) { appendMidi(outfile, options.getArg(i).data(), seconds, initQ++); } // insert an end-of track Meta Event int tpq = outfile.getTicksPerQuarterNote(); MidiEvent mfevent; mfevent.tick = tpq; mfevent.track = 0; mfevent.resize(3); mfevent[0] = 0xff; mfevent[1] = 0x2f; mfevent[2] = 0; outfile.addEvent(mfevent); if (binaryQ) { outfile.write(cout); } else { cout << outfile; } return 0; }
void printMidiEvent(MidiEvent& event) { // print the time: cout << "v" << event.tick << "\t"; // print the command byte in hex format (two digits): int commandbyte = event[0]; printHexByte(commandbyte); int i; switch (commandbyte & 0xf0) { case 0x90: case 0x80: for (i=1; i<(int)event.size(); i++) { cout << " "; printDecByte(event[i]); } break; default: for (i=1; i<(int)event.size(); i++) { cout << " "; printHexByte(event[i]); } } cout << endl; }
bool ZynAddSubFxInstrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset ) { // do not forward external MIDI Control Change events if the according // LED is not checked if( event.type() == MidiControlChange && event.sourcePort() != this && m_forwardMidiCcModel.value() == false ) { return true; } MidiEvent localEvent = event; localEvent.setChannel( 0 ); m_pluginMutex.lock(); if( m_remotePlugin ) { m_remotePlugin->processMidiEvent( localEvent, 0 ); } else { m_plugin->processMidiEvent( localEvent ); } m_pluginMutex.unlock(); return true; }
void MidiEvent::unlinkEvent(void) { if (m_eventlink == NULL) { return; } MidiEvent* mev = m_eventlink; m_eventlink = NULL; mev->unlinkEvent(); }
void mainloopalgorithms(void) { // 1. check to see if we are in a new measure and update the // metronome accordingly. If in 4/4, then the metronome will // be guarenteed to be between 0 and 3.99999 after the following // code is run. The update will make sure that the metronome remains // synced exactly in time with the absolute beat. (Useful for // polyphony, not really necessary in monophonic cases). if (metronome.expired() >= meter) { metronome.update(meter); } // 2. Determine the current beat of the meter. // We will want to play automated chords on beats one and three. beatfraction = metronome.getPeriodCount(); beat = (int)beatfraction + 1; beatfraction -= beat - 1; // 3. Process the incoming MIDI note messages (if any), keeping track // of the last note, and whether it is currently on or off. while (synth.getNoteCount() > 0) { notemessage = synth.extractNote(); if (notemessage.getP2() != 0) { note = notemessage.getP1(); notestates[note] = 1; } else { notestates[notemessage.getP1()] = 0; } } // 4. Determine the position in time in the current beat. // There are two beat-parts which are called states: // state == 0: we are at the start of the beat and may need to // choose a new chord. // state == 1: we are past the maximum wait time for a chord decision // Also, check to see if the state has changed from 0 to 1 or 1 to 0. oldstate = state; state = beatfraction < maxwait ? 0 : 1; stateChange = (state != oldstate); // 5. Check to see if a chord needs to be played. if (stateChange && state == 0) { playMetronome(beat); if (chordBeat(beat, meter)) { notescan = 1; } else { playChord(currentnote, OFF); } } if (notescan && notestates[note]) { // if note played in beat window currentnote = note; playChord(currentnote, ON); notescan = 0; } else if (notescan && state == 1) { // if too late for a new note playChord(currentnote, ON); notescan = 0; } }
void MidiTrack::closeTrack() { long lastTick = 0; if (mEvents.size() > 0) { MidiEvent * last = *(--mEvents.end()); lastTick = last->getTick() + 1; } insertEvent(new EndOfTrack(lastTick, 0)); }
long MidiTrack::getLengthInTicks() { if (mEvents.size() == 0) { return 0; } // get the last note MidiEvent * E = *(--mEvents.end()); return E->getTick(); }
QString MidiWinMM::sourcePortName( const MidiEvent& event ) const { if( event.sourcePort() ) { return m_inputDevices.value( *static_cast<const HMIDIIN *>( event.sourcePort() ) ); } return MidiClient::sourcePortName( event ); }
QString MidiAlsaSeq::sourcePortName( const MidiEvent & _event ) const { if( _event.sourcePort() ) { const snd_seq_addr_t * addr = static_cast<const snd_seq_addr_t *>( _event.sourcePort() ); return __portName( m_seqHandle, addr ); } return MidiClient::sourcePortName( _event ); }
void processMidiCommand(MidiEvent& message) { if (message.getP0() != 0x90 || message.getP2() == 0) { return; } switch (message.getP1()) { case 60: // Middle C = beat keyboardCommand(' '); break; case 61: // C# = amplitude control { double amp = performance.getAmp(); amp = amp * message.getP2() / 64; if (amp < 0) { amp = 0; } else if (amp > 127) { amp = 127; } performance.setAmp((int)amp); } break; case 71: // B = 1 beat tempo follow keyboardCommand('1'); break; case 72: // C = 2 beat tempo follow keyboardCommand('2'); break; case 73: // C# = 3 beat tempo follow keyboardCommand('3'); break; case 74: // D = 4 beat tempo follow keyboardCommand('4'); break; case 79: // G = constant tempo follow keyboardCommand('9'); break; case 80: // G# = automatic keyboardCommand('0'); break; case 62: // amplitude decrease keyboardCommand('['); break; case 63: // amplitude increase keyboardCommand(']'); break; case 64: // tempo decrease keyboardCommand('-'); break; case 65: // tempo increase keyboardCommand('='); break; } }
MIDIPacketList MidiApple::createMidiPacketList( const MidiEvent& event ) { MIDIPacketList packetList; packetList.numPackets = 1; MIDIPacket* firstPacket = &packetList.packet[0]; firstPacket->timeStamp = 0; // send immediately firstPacket->length = 3; firstPacket->data[0] = ( event.type() + event.channel() ); firstPacket->data[1] = ( event.param( 0 ) & 0xff ); firstPacket->data[2] = ( event.param( 1 ) & 0xff ); return packetList; }
void RemotePlugin::processMidiEvent( const MidiEvent & _e, const f_cnt_t _offset ) { message m( IdMidiEvent ); m.addInt( _e.type() ); m.addInt( _e.channel() ); m.addInt( _e.param( 0 ) ); m.addInt( _e.param( 1 ) ); m.addInt( _offset ); lock(); sendMessage( m ); unlock(); }
void MidiChannel::sendMidi(const Action* a, int localFrame) { if (isPlaying() && !mute) { if (midiOut) { MidiEvent event = a->event; event.setChannel(midiOutChan); kernelMidi::send(event.getRaw()); } #ifdef WITH_VST addVstMidiEvent(a->event.getRaw(), localFrame); #endif } }
MidiEvent MidiEvent::Build(const MidiEventSimple &simple) { MidiEvent ev; ev.m_delta_pulses = 0; ev.m_status = simple.status; ev.m_data1 = simple.byte1; ev.m_data2 = simple.byte2; if (ev.Type() == MidiEventType_Meta) throw MidiError(MidiError_MetaEventOnInput); return ev; }
bool PianoPanel::MIDITrackContainsNotes(int track, MidiFile* midifile) { for (int i = 0; i < midifile->getNumEvents(track); i++) { MidiEvent e = midifile->getEvent(track, i); if (e.isNote()) { return true; } } return false; }
int getTrackByteCount(MidiFile& midifile, int track) { int sum = 0; int i; int eventcount = midifile.getEventCount(track); MidiEvent event; for (i=0; i<eventcount; i++) { event = midifile.getEvent(track, i); sum += getVlvSize(event.tick); sum += event.size(); } return sum; }
void MidiTrack::insertEvent(MidiEvent * newEvent) { if (newEvent == NULL) { return; } if (mClosed) { cerr << "Error: Cannot add an event to a closed track."; return; } MidiEvent * prev = NULL, *next = NULL; std::vector<MidiEvent*>::iterator it; for (it = mEvents.begin(); it != mEvents.end(); it++) { next = *it; if (next->getTick() > newEvent->getTick()) { break; } prev = next; next = NULL; } mEvents.insert(it, newEvent); mSizeNeedsRecalculating = true; // Set its delta time based on the previous event (or itself if no previous event exists) if (prev != NULL) { newEvent->setDelta(newEvent->getTick() - prev->getTick()); } else { newEvent->setDelta(newEvent->getTick()); } // Update the next event's delta time relative to the new event. if (next != NULL) { next->setDelta(next->getTick() - newEvent->getTick()); } mSize += newEvent->getSize(); if (newEvent->getType() == MetaEvent::END_OF_TRACK) { if (next != NULL) { cerr << "Attempting to insert EndOfTrack before an existing event. Use closeTrack() when finished with MidiTrack."; return; } mClosed = true; } }
void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset ) { // do nothing if we do not have an instrument instance (e.g. when loading settings) if( m_instrument == NULL ) { return; } const MidiEvent transposedEvent = applyMasterKey( event ); const int key = transposedEvent.key(); switch( event.type() ) { case MidiNoteOn: m_midiNotesMutex.lock(); m_piano.setKeyState( event.key(), true ); // event.key() = original key if( key >= 0 && key < NumKeys ) { if( m_runningMidiNotes[key] > 0 ) { m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time, offset ); } ++m_runningMidiNotes[key]; m_instrument->handleMidiEvent( MidiEvent( MidiNoteOn, midiPort()->realOutputChannel(), key, event.velocity() ), time, offset ); } m_midiNotesMutex.unlock(); emit newNote(); break; case MidiNoteOff: m_midiNotesMutex.lock(); m_piano.setKeyState( event.key(), false ); // event.key() = original key if( key >= 0 && key < NumKeys && --m_runningMidiNotes[key] <= 0 ) { m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time, offset ); } m_midiNotesMutex.unlock(); break; default: m_instrument->handleMidiEvent( transposedEvent, time, offset ); break; } // if appropriate, midi-port does futher routing m_midiPort.processOutEvent( event, time ); }
void mainloopalgorithms(void) { if (synth.getNoteCount() > 0) { message = synth.extractNote(); if (message.getP2() != 0) { startHenon(message.getP1(), message.getP2()); } } if (nextnotetime < t_time) { nextnotetime += 100; key = nextHenon(); voice.play(key, 64); } }
MidiEventList MidiIn::readAllNotes() { MidiEventList allNotes; //TODO: should be possible to transform it into // a do while MidiEvent event = read(); while( event.get_type() == MidiEventType_NoteOff || event.get_type() == MidiEventType_NoteOn ) { allNotes.push_back(event); event = read(); } return allNotes; }
void createMidiFile(const char* filename, vector<vector<int> >& sequence) { MidiFile midifile; midifile.absoluteTicks(); midifile.addTrack(1); int tpq = 120; double beat = 0.0; midifile.setTicksPerQuarterNote(tpq); MidiEvent tempo; tempo.setMetaTempo(60.0); tempo.track = 0; tempo.tick = 0; midifile.addEvent(tempo); int maxlen = 0; int i, j; for (i=0; i<(int)sequence.size(); i++) { if ((int)sequence[i].size() > maxlen) { maxlen = sequence[i].size(); } } vector<int> notelist; MidiEvent noteon(0x90, 0, 64); MidiEvent noteoff(0x80, 0, 64); noteon.track = 1; noteoff.track = 1; for (i=0; i<maxlen; i++) { notelist.clear(); for (j=0; j<(int)sequence.size(); j++) { if (i<(int)sequence[j].size()) { notelist.push_back(sequence[j][i]); } } for (j=0; j<(int)notelist.size(); j++) { noteon[1] = 0x7f & notelist[j]; noteoff[1] = 0x7f & notelist[j]; noteon.tick = (int)(beat * tpq + 0.5); noteoff.tick = (int)(beat * tpq + 1 * tpq + 0.5); midifile.addEvent(noteon); midifile.addEvent(noteoff); } beat += 1.0; } midifile.sortTracks(); midifile.write(filename); }
void Zerberus::process(const MidiEvent& event) { if (busy) return; Channel* cp = _channel[int(event.channel())]; if (cp->instrument() == 0) { // printf("Zerberus::process(): no instrument for channel %d\n", event.channel()); return; } switch(event.type()) { case MidiEventType::NOTEOFF: processNoteOff(cp, event.dataA()); break; case MidiEventType::NOTEON: { int key = event.dataA(); int vel = event.dataB(); if (vel) processNoteOn(cp, key, vel); else processNoteOff(cp, key); } break; case MidiEventType::CONTROLLER: cp->controller(event.dataA(), event.dataB()); break; default: printf("event type 0x%02x\n", event.type()); break; } }
void keyboard(int key) { synth.play(0, keyboardnote, 0); noteMessage.tick = mainTimer.getTime(); noteMessage.setP0(0x90); noteMessage.setP1(keyboardnote); noteMessage.setP2(0); synth.insert(noteMessage); switch (key) { case 'z': keyboardnote = 12 * octave + 0; break; // C case 's': keyboardnote = 12 * octave + 1; break; // C# case 'x': keyboardnote = 12 * octave + 2; break; // D case 'd': keyboardnote = 12 * octave + 3; break; // D# case 'c': keyboardnote = 12 * octave + 4; break; // E case 'v': keyboardnote = 12 * octave + 5; break; // F case 'g': keyboardnote = 12 * octave + 6; break; // F# case 'b': keyboardnote = 12 * octave + 7; break; // G case 'h': keyboardnote = 12 * octave + 8; break; // G# case 'n': keyboardnote = 12 * octave + 9; break; // A case 'j': keyboardnote = 12 * octave + 10; break; // A# case 'm': keyboardnote = 12 * octave + 11; break; // B case ',': keyboardnote = 12 * octave + 12; break; // C default: return; } if (keyboardnote < 0) keyboardnote = 0; else if (keyboardnote > 127) keyboardnote = 127; noteMessage.tick = mainTimer.getTime(); noteMessage.setP0(0x90); noteMessage.setP1(keyboardnote); noteMessage.setP2(rand()%47 + 80); // random int from 1 to 127 synth.play(0, noteMessage.getP1(), noteMessage.getP2()); synth.insert(noteMessage); }
void MidiPort::processInEvent( const MidiEvent& event, const MidiTime& time ) { // mask event if( isInputEnabled() && ( inputChannel() == 0 || inputChannel()-1 == event.channel() ) ) { MidiEvent inEvent = event; if( event.type() == MidiNoteOn || event.type() == MidiNoteOff || event.type() == MidiKeyPressure ) { if( inEvent.key() < 0 || inEvent.key() >= NumKeys ) { return; } } if( fixedInputVelocity() >= 0 && inEvent.velocity() > 0 ) { inEvent.setVelocity( fixedInputVelocity() ); } m_midiEventProcessor->processInEvent( inEvent, time ); } }
MidiEvent InstrumentTrack::applyMasterKey( const MidiEvent& event ) { MidiEvent copy( event ); switch( event.type() ) { case MidiNoteOn: case MidiNoteOff: case MidiKeyPressure: copy.setKey( masterKey( event.key() ) ); break; default: break; } return copy; }
void mainloopalgorithms(void) { eventBuffer.checkPoll(); // see if any notes to play while (synth.getNoteCount() > 0) { message = synth.extractNote(); if (message.getP2() != 0) { lastnotes.insert(message.getP1()); lasttimes.insert(message.tick); distancee = lastnotes[0] - lastnotes[1]; duration = lasttimes[0] - lasttimes[1]; channel = 0x0f & message.getP0(); if (distancee != 0) { playgliss(message.getP1(), message.getP2(), channel, duration, distancee); } } } }