bool AreAllNotesUnselected (MediaItem_Take* take) { bool firstNote = false; MIDI_GetNote(take, 0, &firstNote, NULL, NULL, NULL, NULL, NULL, NULL); if (!firstNote && MIDI_EnumSelNotes(take, 0) == -1) return true; else return false; }
vector<int> GetSelectedNotes (MediaItem_Take* take) { vector<int> selectedNotes; int noteCount; MIDI_CountEvts(take, ¬eCount, NULL, NULL); for (int i = 0; i < noteCount; ++i) { bool selected = false; MIDI_GetNote(take, i, &selected, NULL, NULL, NULL, NULL, NULL, NULL); if (selected) selectedNotes.push_back(i); } return selectedNotes; }
vector<int> MuteUnselectedNotes (MediaItem_Take* take) { vector<int> muteStatus; int noteCount; if (MIDI_CountEvts(take, ¬eCount, NULL, NULL)) { for (int i = 0; i < noteCount; ++i) { bool selected, muted; MIDI_GetNote(take, i, &selected, &muted, NULL, NULL, NULL, NULL, NULL); muteStatus.push_back((int)muted); if (!selected) MIDI_SetNote(take, i, NULL, &g_bTrue, NULL, NULL, NULL, NULL, NULL, NULL); } } return muteStatus; }
bool BR_MidiEditor::IsNoteVisible (MediaItem_Take* take, int id) { bool visible = false; if (take) { if (!m_filterEnabled) { visible = true; } else { double start, end; int channel, velocity, pitch; if (MIDI_GetNote(take, id, NULL, NULL, &start, &end, &channel, &pitch, &velocity)) visible = this->CheckVisibility(take, STATUS_NOTE_ON, start, end, channel, pitch, velocity); } } return visible; }
/****************************************************************************** * Miscellaneous * ******************************************************************************/ vector<int> GetUsedNamedNotes (void* midiEditor, MediaItem_Take* take, bool used, bool named, int channelForNames) { /* Not really reliable, user could have changed default draw channel * * but without resetting note view settings, view won't get updated */ vector<int> allNotesStatus(127, 0); MediaItem_Take* midiTake = (midiEditor) ? SWS_MIDIEditor_GetTake(midiEditor) : take; if (named) { MediaTrack* track = GetMediaItemTake_Track(midiTake); for (int i = 0; i < 128; ++i) if (GetTrackMIDINoteNameEx(NULL, track, i, channelForNames)) allNotesStatus[i] = 1; } if (used) { int noteCount; if (MIDI_CountEvts(midiTake, ¬eCount, NULL, NULL)) { for (int i = 0; i < noteCount; ++i) { int pitch; MIDI_GetNote(midiTake, i, NULL, NULL, NULL, NULL, NULL, &pitch, NULL); allNotesStatus[pitch] = 1; } } } vector<int> notes; notes.reserve(128); for (int i = 0; i < 128; ++i) { if (allNotesStatus[i] == 1) notes.push_back(i); } return notes; }
void ME_PreviewActiveTake (COMMAND_T* ct, int val, int valhw, int relmode, HWND hwnd) { HWND midiEditor = MIDIEditor_GetActive(); if (MediaItem_Take* take = MIDIEditor_GetTake(midiEditor)) { MediaItem* item = GetMediaItemTake_Item(take); vector<int> options = GetDigits((int)ct->user); int toggle = options[0]; int type = options[1]; int selNotes = options[2]; int pause = options[3]; MediaTrack* track = GetMediaItem_Track(item); double volume = GetMediaItemInfo_Value(item, "D_VOL"); double start = 0; double measure = (type == 3) ? 1 : 0; bool pausePlay = (pause == 2) ? true : false; if (type == 2) { double mousePosition = ME_PositionAtMouseCursor(true, true); if (mousePosition != -1) { if (GetToggleCommandState2(SectionFromUniqueID(SECTION_MIDI_EDITOR), 40470) > 0) // Timebase: Beats(source) start = mousePosition - MIDI_GetProjTimeFromPPQPos(take, 0); else start = mousePosition - GetMediaItemInfo_Value(item, "D_POSITION"); } else return; } vector<int> muteState; if (selNotes == 2) { if (!AreAllNotesUnselected(take)) { muteState = MuteUnselectedNotes(take); if (type != 2) { BR_MidiEditor editor(midiEditor); double time; MIDI_GetNote(take, FindFirstSelectedNote(take, &editor), NULL, NULL, &time, NULL, NULL, NULL, NULL); start = MIDI_GetProjTimeFromPPQPos(take, time) - GetMediaItemInfo_Value(item, "D_POSITION"); if (start < 0) start = 0; } } else if (type != 2) { BR_MidiEditor editor(midiEditor); int id = FindFirstNote(take, &editor); if (id != -1) { double time; MIDI_GetNote(take, id, NULL, NULL, &time, NULL, NULL, NULL, NULL); start = MIDI_GetProjTimeFromPPQPos(take, time) - GetMediaItemInfo_Value(item, "D_POSITION"); if (start < 0) start = 0; } } } MidiTakePreview(toggle, take, track, volume, start, measure, pausePlay); if (muteState.size() > 0) SetMutedNotes(take, muteState); } }
double EffectiveMidiTakeStart (MediaItem_Take* take, bool ignoreMutedEvents, bool ignoreTextEvents, bool ignoreEventsOutsideItemBoundaries) { int noteCount, ccCount, sysCount; if (take && MIDI_CountEvts(take, ¬eCount, &ccCount, &sysCount)) { MediaItem* item = GetMediaItemTake_Item(take); double itemStart = GetMediaItemInfo_Value(item, "D_POSITION"); double itemStartPPQ = MIDI_GetPPQPosFromProjTime(take, itemStart); double itemEndPPQ = (!ignoreEventsOutsideItemBoundaries) ? 0 : MIDI_GetPPQPosFromProjTime(take, GetMediaItemInfo_Value(item, "D_LENGTH") + itemStart); int loopCount = (!ignoreEventsOutsideItemBoundaries) ? 0 : GetLoopCount(take, 0, NULL); double sourceLenPPQ = (!ignoreEventsOutsideItemBoundaries) ? 0 : GetMidiSourceLengthPPQ(take, true); bool validNote = false, validCC = false, validSys = false; double noteStart, ccStart, sysStart; double loopOffset = 0; for (int i = 0; i < noteCount; ++i) { bool muted; double start, end; MIDI_GetNote(take, i, NULL, &muted, &start, &end, NULL, NULL, NULL); if ((ignoreMutedEvents && !muted) || !ignoreMutedEvents) { if (!ignoreEventsOutsideItemBoundaries) { noteStart = start; validNote = true; break; } else { start += loopOffset; end += loopOffset; if (AreOverlapped(start, end, itemStartPPQ, itemEndPPQ)) { if (itemStartPPQ > start) start = itemStartPPQ; noteStart = start; validNote = true; break; } } } if (ignoreEventsOutsideItemBoundaries && loopCount > 0 && i == noteCount - 1) { if (sourceLenPPQ > 0 && loopOffset == 0) { loopOffset = sourceLenPPQ; i = -1; } } } loopOffset = 0; for (int i = 0; i < ccCount; ++i) { bool muted; double pos; MIDI_GetCC(take, i, NULL, &muted, &pos, NULL, NULL, NULL, NULL); if ((ignoreMutedEvents && !muted) || !ignoreMutedEvents) { if (!ignoreEventsOutsideItemBoundaries) { ccStart = pos; validCC = true; break; } else { pos += loopOffset; if (CheckBounds(pos, itemStartPPQ, itemEndPPQ)) { ccStart = pos; validCC = true; break; } } } if (ignoreEventsOutsideItemBoundaries && loopCount > 0 && i == ccCount - 1) { if (sourceLenPPQ > 0 && loopOffset == 0) { loopOffset = sourceLenPPQ; i = -1; } } } for (int i = 0; i < sysCount; ++i) { bool muted; double pos; int type; MIDI_GetTextSysexEvt(take, i, NULL, &muted, &pos, &type, NULL, NULL); if (((ignoreMutedEvents && !muted) || !ignoreMutedEvents) && ((ignoreTextEvents && type == -1) || !ignoreTextEvents)) { if (!ignoreEventsOutsideItemBoundaries) { sysStart = pos; validSys = true; break; } else { pos += loopOffset; if (CheckBounds(pos, itemStartPPQ, itemEndPPQ)) { sysStart = pos; validSys = true; break; } } } if (ignoreEventsOutsideItemBoundaries && loopCount > 0 && i == sysCount - 1) { if (sourceLenPPQ > 0 && loopOffset == 0) { loopOffset = sourceLenPPQ; i = -1; } } } if (validNote || validCC || validSys) { if (!validNote) noteStart = (validSys) ? sysStart : ccStart; if (!validCC) ccStart = (validSys) ? sysStart : noteStart; if (!validSys) sysStart = (ccStart) ? ccStart : noteStart; return MIDI_GetProjTimeFromPPQPos(take, min(min(noteStart, ccStart), sysStart)); } else { return GetMediaItemInfo_Value(item, "D_POSITION"); } } else { return GetMediaItemInfo_Value(GetMediaItemTake_Item(take), "D_POSITION"); } }
set<int> GetUsedCCLanes (void* midiEditor, int detect14bit, bool selectedEventsOnly) { MediaItem_Take* take = SWS_MIDIEditor_GetTake(midiEditor); set<int> usedCC; int noteCount, ccCount, sysCount; if (take && MIDI_CountEvts(take, ¬eCount, &ccCount, &sysCount)) { BR_MidiEditor editor(midiEditor); set<int> unpairedMSB; for (int id = 0; id < ccCount; ++id) { int chanMsg, chan, msg2; bool selected; if (!MIDI_GetCC(take, id, &selected, NULL, NULL, &chanMsg, &chan, &msg2, NULL) || !editor.IsCCVisible(take, id) || (selectedEventsOnly && !selected)) continue; if (chanMsg == STATUS_PROGRAM) usedCC.insert(CC_PROGRAM); else if (chanMsg == STATUS_CHANNEL_PRESSURE) usedCC.insert(CC_CHANNEL_PRESSURE); else if (chanMsg == STATUS_PITCH) usedCC.insert(CC_PITCH); else if (chanMsg == STATUS_CC) { if (msg2 > 63 || detect14bit == 0) usedCC.insert(msg2); else { if (detect14bit == 1) usedCC.insert(msg2); // If MSB also check for LSB that makes up 14 bit event if (msg2 <= 31) { int tmpId = id; if (MIDI_GetCC(take, tmpId + 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) { double pos; MIDI_GetCC(take, id, NULL, NULL, &pos, NULL, NULL, NULL, NULL); while (true) { double nextPos; int nextChanMsg, nextChan, nextMsg2; MIDI_GetCC(take, ++tmpId, NULL, NULL, &nextPos, &nextChanMsg, &nextChan, &nextMsg2, NULL); if (tmpId >= ccCount) break; if (nextPos > pos) { if (detect14bit == 2) { usedCC.insert(msg2); unpairedMSB.insert(msg2); } break; } if (nextChanMsg == STATUS_CC && msg2 == nextMsg2 - 32 && chan == nextChan) { usedCC.insert(msg2 + CC_14BIT_START); break; } } } else { if (detect14bit == 2) { usedCC.insert(msg2); unpairedMSB.insert(msg2); } } } // If LSB, just make sure it was paired else if (detect14bit == 2) { int tmpId = id; if (MIDI_GetCC(take, tmpId - 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) { double pos; MIDI_GetCC(take, id, NULL, NULL, &pos, NULL, NULL, NULL, NULL); while (true) { double prevPos; int prevChanMsg, prevChan, prevMsg2; MIDI_GetCC(take, --tmpId, NULL, NULL, &prevPos, &prevChanMsg, &prevChan, &prevMsg2, NULL); if (prevPos < pos) { if (detect14bit == 2) usedCC.insert(msg2); break; } if (prevChanMsg == STATUS_CC && msg2 == prevMsg2 + 32 && chan == prevChan) break; } } else usedCC.insert(msg2); } } } } if (detect14bit == 2) { for (set<int>::iterator it = unpairedMSB.begin(); it != unpairedMSB.end(); ++it) { if (usedCC.find(*it + CC_14BIT_START) != usedCC.end()) { usedCC.erase(*it + CC_14BIT_START); usedCC.insert(*it + 32); // MSB is already there, LSB doesn't have to be so add it } } } for (int i = 0; i < noteCount; ++i) { bool selected; int chan; MIDI_GetNote(take, i, &selected, NULL, NULL, NULL, &chan, NULL, NULL); if (editor.IsChannelVisible(chan) && (!selectedEventsOnly || (selectedEventsOnly && selected))) { usedCC.insert(-1); break; } } bool foundText = false, foundSys = false; for (int i = 0; i < sysCount; ++i) { bool selected; int type = 0; MIDI_GetTextSysexEvt(take, i, &selected, NULL, NULL, &type, NULL, NULL); if (type == -1) { if (!foundSys && (!selectedEventsOnly || (selectedEventsOnly && selected))) { usedCC.insert(CC_SYSEX); foundSys = true; if (foundText) break; } } else { if (!foundText && (!selectedEventsOnly || (selectedEventsOnly && selected))) { usedCC.insert(CC_TEXT_EVENTS); foundText = true; if (foundSys) break; } } } } return usedCC; }
BR_MidiItemTimePos::MidiTake::NoteEvent::NoteEvent (MediaItem_Take* take, int id) { MIDI_GetNote(take, id, &selected, &muted, &pos, &end, &chan, &pitch, &vel); pos = MIDI_GetProjTimeFromPPQPos(take, pos); end = MIDI_GetProjTimeFromPPQPos(take, end); }
double EffectiveMidiTakeEnd (MediaItem_Take* take, bool ignoreMutedEvents, bool ignoreTextEvents, bool ignoreEventsOutsideItemBoundaries) { int noteCount, ccCount, sysCount; if (take && MIDI_CountEvts(take, ¬eCount, &ccCount, &sysCount)) { MediaItem* item = GetMediaItemTake_Item(take); double itemStart = GetMediaItemInfo_Value(item, "D_POSITION"); double itemStartPPQ = MIDI_GetPPQPosFromProjTime(take, itemStart); double itemEndPPQ = (!ignoreEventsOutsideItemBoundaries) ? 0 : MIDI_GetPPQPosFromProjTime(take, GetMediaItemInfo_Value(item, "D_LENGTH") + itemStart); int loopCount = GetLoopCount(take, 0, NULL); double sourceLenPPQ = GetMidiSourceLengthPPQ(take, true); double effectiveTakeEndPPQ = -1; for (int i = 0; i < noteCount; ++i) { bool muted; double noteStart, noteEnd; MIDI_GetNote(take, i, NULL, &muted, ¬eStart, ¬eEnd, NULL, NULL, NULL); if (((ignoreMutedEvents && !muted) || !ignoreMutedEvents)) { noteEnd += loopCount*sourceLenPPQ; if (!ignoreEventsOutsideItemBoundaries) { if (noteEnd > effectiveTakeEndPPQ) effectiveTakeEndPPQ = noteEnd; } else { noteStart += loopCount*sourceLenPPQ; if (CheckBounds(noteStart, itemStartPPQ, itemEndPPQ)) { if (noteEnd > itemEndPPQ) noteEnd = itemEndPPQ; if (noteEnd > effectiveTakeEndPPQ) effectiveTakeEndPPQ = noteEnd; } else if (loopCount > 0) { noteStart -= sourceLenPPQ; if (CheckBounds(noteStart, itemStartPPQ, itemEndPPQ)) { noteEnd -= sourceLenPPQ; if (noteEnd > itemEndPPQ) noteEnd = itemEndPPQ; if (noteEnd > effectiveTakeEndPPQ) effectiveTakeEndPPQ = noteEnd; } } } } } for (int i = ccCount - 1; i >= 0; --i) { bool muted; double pos; MIDI_GetCC(take, i, NULL, &muted, &pos, NULL, NULL, NULL, NULL); if ((ignoreMutedEvents && !muted) || !ignoreMutedEvents) { pos += loopCount*sourceLenPPQ; if (!ignoreEventsOutsideItemBoundaries) { if (pos > effectiveTakeEndPPQ) effectiveTakeEndPPQ = pos + 1; // add 1 ppq so length definitely includes that last event break; } else { if (CheckBounds(pos, itemStartPPQ, itemEndPPQ)) { if (pos > effectiveTakeEndPPQ) { effectiveTakeEndPPQ = pos + 1; break; } } else if (loopCount > 0) { pos -= sourceLenPPQ; if (CheckBounds(pos, itemStartPPQ, itemEndPPQ)) { if (pos > effectiveTakeEndPPQ) { effectiveTakeEndPPQ = pos + 1; break; } } } } } } for (int i = 0; i < sysCount; ++i) { bool muted; double pos; int type; MIDI_GetTextSysexEvt(take, i, NULL, &muted, &pos, &type, NULL, NULL); if (((ignoreMutedEvents && !muted) || !ignoreMutedEvents) && ((ignoreTextEvents && type == -1) || !ignoreTextEvents)) { pos += loopCount*sourceLenPPQ; if (!ignoreEventsOutsideItemBoundaries) { if (pos > effectiveTakeEndPPQ) effectiveTakeEndPPQ = pos + 1; // add 1 ppq so length definitely includes that last event } else { if (CheckBounds(pos, itemStartPPQ, itemEndPPQ)) { if (pos > effectiveTakeEndPPQ) effectiveTakeEndPPQ = pos + 1; } else if (loopCount > 0) { pos -= sourceLenPPQ; if (CheckBounds(pos, itemStartPPQ, itemEndPPQ)) { if (pos > effectiveTakeEndPPQ) effectiveTakeEndPPQ = pos + 1; } } } } } return (effectiveTakeEndPPQ == -1) ? itemStart : MIDI_GetProjTimeFromPPQPos(take, effectiveTakeEndPPQ); } return 0; }