// events are always specified as happening some period of time from now. // but we store them as taking place at a specific time, rather than a relative time. void NoteManager::addEvent(const float startTime, const float duration, Instrument & instrument) { int onAt = m_now + (int)(m_out.sampleRate() * ( startTime + m_noteOffset ) * 60.f / m_tempo); m_events[onAt].push_back( NoteEvent(&instrument, NoteEvent::NOTE_ON, duration) ); int offAt = onAt + (int)(m_out.sampleRate() * duration * m_durationFactor * 60.f / m_tempo); m_events[offAt].push_back( NoteEvent(&instrument, NoteEvent::NOTE_OFF, 0.f) ); }
void setMusicNotesFromMidi(Score *score, const QList<MidiNote> &midiNotes, const Fraction &onTime, const Fraction &len, Chord *chord, const Fraction &tick, const Drumset *drumset, bool useDrumset) { Fraction actualFraction = chord->actualFraction(); for (int i = 0; i < midiNotes.size(); ++i) { const MidiNote& mn = midiNotes[i]; Note* note = new Note(score); // TODO - does this need to be key-aware? note->setPitch(mn.pitch, pitch2tpc(mn.pitch, KEY_C, PREFER_NEAREST)); chord->add(note); note->setVeloType(MScore::USER_VAL); note->setVeloOffset(mn.velo); NoteEventList el; Fraction f = (onTime - tick) / actualFraction * 1000; int ron = f.numerator() / f.denominator(); f = len / actualFraction * 1000; int rlen = f.numerator() / f.denominator(); el.append(NoteEvent(0, ron, rlen)); note->setPlayEvents(el); if (useDrumset) { if (!drumset->isValid(mn.pitch)) qDebug("unmapped drum note 0x%02x %d", mn.pitch, mn.pitch); else chord->setStemDirection(drumset->stemDirection(mn.pitch)); } if (midiNotes[i].tie) { midiNotes[i].tie->setEndNote(note); midiNotes[i].tie->setTrack(note->track()); note->setTieBack(midiNotes[i].tie); } } }