void BR_MidiItemTimePos::Restore (double timeOffset /*=0*/) { SetMediaItemInfo_Value(item, "C_BEATATTACHMODE", 0); for (size_t i = 0; i < savedMidiTakes.size(); ++i) { BR_MidiItemTimePos::MidiTake* midiTake = &savedMidiTakes[i]; MediaItem_Take* take = midiTake->take; int noteCount, ccCount, textCount; if (MIDI_CountEvts(take, ¬eCount, &ccCount, &textCount)) { for (int i = 0; i < noteCount; ++i) MIDI_DeleteNote(take, 0); for (int i = 0; i < ccCount; ++i) MIDI_DeleteCC(take, 0); for (int i = 0; i < textCount; ++i) MIDI_DeleteTextSysexEvt(take, 0); } if (looped && loopStart != -1 && loopEnd != -1) { SetMediaItemTakeInfo_Value(take, "D_STARTOFFS", 0); MIDI_SetItemExtents(item, TimeMap_timeToQN(loopStart), TimeMap_timeToQN(loopEnd)); SetMediaItemInfo_Value(item , "B_LOOPSRC", 1); // because MIDI_SetItemExtents() disables looping TrimItem(item, position, position + length, true); SetMediaItemTakeInfo_Value(take, "D_STARTOFFS", loopedOffset); } else { TrimItem(item, position, position + length, true); } for (size_t i = 0; i < midiTake->noteEvents.size(); ++i) midiTake->noteEvents[i].InsertEvent(take, timeOffset); for (size_t i = 0; i < midiTake->ccEvents.size(); ++i) midiTake->ccEvents[i].InsertEvent(take, timeOffset); for (size_t i = 0; i < midiTake->sysEvents.size(); ++i) midiTake->sysEvents[i].InsertEvent(take, timeOffset); } SetMediaItemInfo_Value(item, "C_BEATATTACHMODE", timeBase); }
void generate_items_sequence(std::shared_ptr<breakpoint_envelope> env, const char* fn) { SetCursorContext(1, NULL); Main_OnCommand(40182, 0); // select all items Main_OnCommand(40006, 0); // remove selected items MediaTrack* dest_track = GetTrack(nullptr, 0); double timepos = 0.0; double seqlen = 30.0; int sanity = 0; while (timepos < seqlen) { create_item_result r = create_item_with_take_and_source(dest_track, fn); SetMediaItemPosition(r.item, timepos, false); double srclen = GetMediaSourceLength(r.src, nullptr); double normtime = 1.0 / seqlen * timepos; double directionfactor = skip_near_zero(-1.0 + 2.0*env->interpolate(normtime), 0.02); if (directionfactor < 0.0) { //readbg() << "item " << sanity << " should be reversed\n"; SetMediaItemSelected(r.item, true); Main_OnCommand(41051, 0); // toggle reverse SetMediaItemSelected(r.item, false); } double absfactor = fabs(directionfactor); double itemlen = bound_value(0.02, srclen*absfactor, srclen); SetMediaItemLength(r.item, itemlen, false); SetMediaItemTakeInfo_Value(r.take, "D_PLAYRATE", 1.0 / absfactor); timepos += srclen*absfactor; ++sanity; if (sanity > 1000) { readbg() << "too many items created!\n"; break; } } UpdateArrange(); }
static void MidiTakePreview (int mode, MediaItem_Take* take, MediaTrack* track, double volume, double startOffset, double measureSync, bool pauseDuringPrev) { /* mode: 0 -> stop * * 1 -> start * * 2 -> toggle */ // First stop any ongoing preview RegisterCsurfPlayState(false, MidiTakePreviewPlayState); if (g_itemPreviewPlaying) { if (g_ItemPreview.preview_track) { StopTrackPreview(&g_ItemPreview); SendAllNotesOff((MediaTrack*)g_ItemPreview.preview_track); } else { StopPreview(&g_ItemPreview); } g_itemPreviewPlaying = false; plugin_register("-timer",(void*)MidiTakePreviewTimer); delete g_ItemPreview.src; if (g_itemPreviewPaused && mode != 1) // requesting new preview while old one is still playing shouldn't unpause playback { if (IsPaused(NULL)) OnPauseButtonEx(NULL); g_itemPreviewPaused = false; } // Toggled preview off...treat it as stop if (mode == 2) mode = 0; } // About IsRecording: REAPER won't preview anything during recording but extension will still think preview is in progress if we let it continue here if (mode == 0 || IsRecording(NULL)) return; if (take) { PreventUIRefresh(1); // item may get resized temporarily so hide it from the user MediaItem* item = GetMediaItemTake_Item(take); MediaItem_Take* oldTake = GetActiveTake(item); bool itemMuteState = *(bool*)GetSetMediaItemInfo(item, "B_MUTE", NULL); GetSetMediaItemInfo(item, "B_MUTE", &g_bFalse); // needs to be set before getting the source SetActiveTake(take); // active item take and editor take may differ // If timebase in MIDI editor is set to Beats (source), make sure item is croped so full MIDI source is visible beforing getting the source double itemStart = -1; double itemEnd = -1; double takeOffset = 0; double itemPositionOffset = 0; if (GetToggleCommandState2(SectionFromUniqueID(SECTION_MIDI_EDITOR), 40470) > 0) // Timebase: Beats(source) { itemStart = GetMediaItemInfo_Value(item, "D_POSITION"); itemEnd = itemStart + GetMediaItemInfo_Value(item, "D_LENGTH"); takeOffset = GetMediaItemTakeInfo_Value(take, "D_STARTOFFS"); double sourceLenPPQ = GetMidiSourceLengthPPQ(take, NULL); if (takeOffset != 0) SetMediaItemTakeInfo_Value(take, "D_STARTOFFS", 0); double itemSourceStart = MIDI_GetProjTimeFromPPQPos(take, 0); if (itemSourceStart < 0) { itemPositionOffset = abs(itemSourceStart); SetMediaItemInfo_Value(item, "D_POSITION", itemStart + itemPositionOffset); itemSourceStart = MIDI_GetProjTimeFromPPQPos(take, 0); } SetMediaItemInfo_Value(item, "D_POSITION", itemSourceStart); SetMediaItemInfo_Value(item, "D_LENGTH", MIDI_GetProjTimeFromPPQPos(take, sourceLenPPQ) - itemSourceStart); } double effectiveTakeLen = EffectiveMidiTakeEnd(take, true, true, true) - GetMediaItemInfo_Value(item, "D_POSITION"); PCM_source* src = DuplicateSource((PCM_source*)item); // must be item source otherwise item/take volume won't get accounted for if (src && effectiveTakeLen > 0) { GetSetMediaItemInfo((MediaItem*)src, "D_POSITION", &g_d0); GetSetMediaItemInfo((MediaItem*)src, "D_LENGTH", &effectiveTakeLen); if (!g_ItemPreview.src) { #ifdef _WIN32 InitializeCriticalSection(&g_ItemPreview.cs); #else pthread_mutex_init(&g_ItemPreview.mutex, NULL); #endif g_ItemPreview.loop = false; } g_ItemPreview.src = src; g_ItemPreview.m_out_chan = (track) ? (-1) : (0); g_ItemPreview.curpos = startOffset; g_ItemPreview.volume = volume; g_ItemPreview.preview_track = track; // Pause before preview otherwise MidiTakePreviewPlayState will stop it g_itemPreviewPaused = pauseDuringPrev; if (g_itemPreviewPaused && IsPlaying(NULL) && !IsPaused(NULL)) OnPauseButton(); if (g_ItemPreview.preview_track) g_itemPreviewPlaying = !!PlayTrackPreview2Ex(NULL, &g_ItemPreview, 1, measureSync); else g_itemPreviewPlaying = !!PlayPreviewEx(&g_ItemPreview, 1, measureSync); if (g_itemPreviewPlaying) { plugin_register("timer",(void*)MidiTakePreviewTimer); RegisterCsurfPlayState(true, MidiTakePreviewPlayState); } else delete g_ItemPreview.src; } if (itemStart != -1) { SetMediaItemInfo_Value(item, "D_POSITION", itemStart + itemPositionOffset); SetMediaItemInfo_Value(item, "D_LENGTH", itemEnd - itemStart); if (itemPositionOffset != 0) SetMediaItemInfo_Value(item, "D_POSITION", itemStart); if (takeOffset != 0) SetMediaItemTakeInfo_Value(take, "D_STARTOFFS", takeOffset); } SetActiveTake(oldTake); GetSetMediaItemInfo(item, "B_MUTE", &itemMuteState); PreventUIRefresh(-1); } }