Beispiel #1
0
void RegionsFromItems(COMMAND_T* ct)
{
	// Ignore the fact that the user may have items selected with the exact same times.  Just blindly create regions!
	WDL_TypedBuf<MediaItem*> items;
	SWS_GetSelectedMediaItems(&items);
	bool bUndo = false;
	for (int i = 0; i < items.GetSize(); i++)
	{
		MediaItem_Take* take = GetActiveTake(items.Get()[i]);
		if (take)
		{
			char* cName = (char*)GetSetMediaItemTakeInfo(take, "P_NAME", NULL);
			double dStart = *(double*)GetSetMediaItemInfo(items.Get()[i], "D_POSITION", NULL);
			double dEnd = *(double*)GetSetMediaItemInfo(items.Get()[i], "D_LENGTH", NULL) + dStart;
			AddProjectMarker(NULL, true, dStart, dEnd, cName, -1);
			bUndo = true;
		}
		else if (!CountTakes(items.Get()[i]))  /* In case of an empty item there is no take so process item instead */
		{
			double dStart = *(double*)GetSetMediaItemInfo(items.Get()[i], "D_POSITION", NULL);
			double dEnd = *(double*)GetSetMediaItemInfo(items.Get()[i], "D_LENGTH", NULL) + dStart;
			AddProjectMarker(NULL, true, dStart, dEnd, NULL, -1);
			bUndo = true;
		}
	}
	if (bUndo)
	{
		UpdateTimeline();
		Undo_OnStateChangeEx(SWS_CMD_SHORTNAME(ct), UNDO_STATE_MISCCFG, -1);
	}
}
Beispiel #2
0
void SimpleExampleWindow::populate_listbox()
{
	int old_index = m_listbox1->getSelectedIndex();
	m_listbox1->clearItems();
	m_itemmap.clear();
	int numitems = CountMediaItems(nullptr);
	
	for (int i=0;i<numitems;++i)
	{
		MediaItem* item = GetMediaItem(nullptr,i);
		MediaItem_Take* take = GetActiveTake(item);
		if (item!=nullptr)
		{
			char namebuf[1024];
			if (GetSetMediaItemTakeInfo_String(take,"P_NAME",namebuf,false))
			{
				m_listbox1->addItem(namebuf, i);
				// Note that the item pointers stored into this map
				// may easily become invalid if the items are removed by the user etc...
				// It doesn't matter in this code as we don't dereference the pointers in any way yet.
				// Note how the validation can be done in the button3 handler lambda!
				m_itemmap[i]=item;
			}
			
		}
	}
	//readbg() << "listbox has " << m_listbox1->numItems() << " items\n";
}
Beispiel #3
0
/******************************************************************************
* BR_MidiItemTimePos                                                          *
******************************************************************************/
BR_MidiItemTimePos::BR_MidiItemTimePos (MediaItem* item) :
item         (item),
position     (GetMediaItemInfo_Value(item, "D_POSITION")),
length       (GetMediaItemInfo_Value(item, "D_LENGTH")),
timeBase     (GetMediaItemInfo_Value(item, "C_BEATATTACHMODE")),
looped       (!!GetMediaItemInfo_Value(item, "B_LOOPSRC")),
loopStart    (-1),
loopEnd      (-1),
loopedOffset (0)
{
	// When restoring position and lenght, the only way to restore it for looped MIDI items is to use MIDI_SetItemExtents which will disable looping
	// for the whole item. Since we have no idea what will happen before this->Restore() is called take data for active MIDI item right now instead of
	// in this->Restore() (for example, if client calls SetIgnoreTempo() from BR_Util.h before restoring to disable "ignore project tempo" length of MIDI item source may change)
	if (looped)
	{
		if (MediaItem_Take* activeTake = GetActiveTake(item))
		{
			double sourceLenPPQ = GetMidiSourceLengthPPQ(activeTake, true);
			loopStart = MIDI_GetProjTimeFromPPQPos(activeTake, sourceLenPPQ); // we're not using MIDI_GetProjTimeFromPPQPos(activeTake, 0) because later we will use MIDI_SetItemExtents to make sure looped item
			loopEnd = MIDI_GetProjTimeFromPPQPos(activeTake, sourceLenPPQ*2); // position info is restored and 0 PPQ in take could theoretically be behind project start in which case MIDI_SetItemExtents wont' work properly
			loopedOffset = GetMediaItemTakeInfo_Value(activeTake, "D_STARTOFFS");
		}
	}

	int takeCount = CountTakes(item);
	for (int i = 0; i < takeCount; ++i)
	{
		MediaItem_Take* take = GetTake(item, i);

		int noteCount, ccCount, textCount;
		int midiEventCount = MIDI_CountEvts(take, &noteCount, &ccCount, &textCount);

		// In case of looped item, if active take wasn't midi, get looped position here for first MIDI take
		if (looped && loopStart == -1 && loopEnd == -1 && IsMidi(take, NULL) && (midiEventCount > 0 || i == takeCount - 1))
		{
			double sourceLenPPQ = GetMidiSourceLengthPPQ(take, true);
			loopStart = MIDI_GetProjTimeFromPPQPos(take, sourceLenPPQ);
			loopEnd = MIDI_GetProjTimeFromPPQPos(take, sourceLenPPQ*2);
			loopedOffset = GetMediaItemTakeInfo_Value(take, "D_STARTOFFS");
		}


		if (midiEventCount > 0)
		{
			savedMidiTakes.push_back(BR_MidiItemTimePos::MidiTake(take, noteCount, ccCount, textCount));
			BR_MidiItemTimePos::MidiTake* midiTake = &savedMidiTakes.back();

			for (int i = 0; i < noteCount; ++i)
				midiTake->noteEvents.push_back(BR_MidiItemTimePos::MidiTake::NoteEvent(take, i));

			for (int i = 0; i < ccCount; ++i)
				midiTake->ccEvents.push_back(BR_MidiItemTimePos::MidiTake::CCEvent(take, i));

			for (int i = 0; i < textCount; ++i)
				midiTake->sysEvents.push_back(BR_MidiItemTimePos::MidiTake::SysEvent(take, i));
		}
	}
}
Beispiel #4
0
bool IsOpenInInlineEditor (MediaItem_Take* take)
{
	bool inProject = false;
	if (GetActiveTake(GetMediaItemTake_Item(take)) == take && IsMidi(take, &inProject) && inProject)
	{
		if (PCM_source* source = GetMediaItemTake_Source(take))
		{
			if (source->Extended(PCM_SOURCE_EXT_INLINEEDITOR, 0, 0, 0) > 0)
				return true;
		}
	}
	return false;
}
Beispiel #5
0
void GetMediaItemTakes(MediaItem* item, list<MediaItem_Take*> &takes, bool bActiveOnly)
{
	takes.clear();

	if(bActiveOnly)
	{
		MediaItem_Take* take = GetActiveTake(item);
		if(take)
			takes.push_back(take);
	}

	else
	{
		int takeIdx = 0;
		while(MediaItem_Take* take = GetTake(item, takeIdx))
		{
			if(take)
				takes.push_back(take);
			takeIdx++;
		}
	}
}
Beispiel #6
0
void TakeCustomColor(int iCustColor)
{
	COLORREF cr;
	UpdateCustomColors();
	cr = g_custColors[iCustColor] | 0x1000000;
	for (int i = 1; i <= GetNumTracks(); i++)
	{
		MediaTrack* tr = CSurf_TrackFromID(i, false);
		for (int j = 0; j < GetTrackNumMediaItems(tr); j++)
		{
			MediaItem* mi = GetTrackMediaItem(tr, j);
			if (*(bool*)GetSetMediaItemInfo(mi, "B_UISEL", NULL))
			{
				MediaItem_Take* take = GetActiveTake(mi);
				if (take)
					GetSetMediaItemTakeInfo(take, "I_CUSTOMCOLOR", &cr);
			}
		}
	}
	char cUndoText[100];
	sprintf(cUndoText, __LOCALIZE_VERFMT("Set take(s) to custom color %d","sws_undo"), iCustColor+1);
	Undo_OnStateChange(cUndoText);
	UpdateTimeline();
}
Beispiel #7
0
SimpleExampleWindow::SimpleExampleWindow(HWND parent, std::string title) : MRPWindow(parent,title)
{
	m_last_project_change_count = GetProjectStateChangeCount(nullptr);
	m_but1 = std::make_shared<WinButton>(this, "Get take name");
	m_but1->GenericNotifyCallback = [this](GenericNotifications)
	{
		if (CountSelectedMediaItems(nullptr) > 0)
		{
			MediaItem* item = GetSelectedMediaItem(nullptr, 0);
			MediaItem_Take* take = GetActiveTake(item);
			if (take != nullptr)
			{
				char buf[2048];
				GetSetMediaItemTakeInfo_String(take, "P_NAME", buf, false);
				m_edit1->setText(buf);
			}
		}
	};
	add_control(m_but1);
	m_but2 = std::make_shared<WinButton>(this, "Set take name");
	m_but2->GenericNotifyCallback = [this](GenericNotifications)
	{
		if (CountSelectedMediaItems(nullptr) > 0)
		{
			MediaItem* item = GetSelectedMediaItem(nullptr, 0);
			MediaItem_Take* take = GetActiveTake(item);
			if (take != nullptr)
			{
				GetSetMediaItemTakeInfo_String(take, "P_NAME", (char*)m_edit1->getText().c_str(), true);
				UpdateArrange();
			}
		}
	};
	add_control(m_but2);
	
	m_but3 = std::make_shared<WinButton>(this, "Refresh item list");
	m_but3->GenericNotifyCallback = [this](GenericNotifications)
	{
		populate_listbox();
	};
	add_control(m_but3);
	
	m_but4 = std::make_shared<WinButton>(this, "Remove selected listbox item foffoffooo");
	m_but4->GenericNotifyCallback = [this](GenericNotifications)
	{
		int selindex = m_listbox1->getSelectedIndex();
		if (selindex >= 0)
		{
			m_listbox1->removeItem(selindex);
			m_itemmap.erase(m_listbox1->userIDfromIndex(selindex));
		}
	};
	add_control(m_but4);
	
	m_edit1 = std::make_shared<WinLineEdit>(this, "No take name yet");
	add_control(m_edit1);
	m_listbox1 = std::make_shared<WinListBox>(this);
	
	m_listbox1->SelectedChangedCallback = [this](int index) mutable
	{
		if (index >= 0)
		{
			std::string temp = m_listbox1->getItemText(index);
			readbg() << "you chose " << temp << " from the listbox\n";
			int user_id = m_listbox1->userIDfromIndex(index);
			MediaItem* itemfromlist = m_itemmap[user_id];
			if (ValidatePtr((void*)itemfromlist, "MediaItem*") == true)
			{
				m_edit1->setText(std::string("You chose item with mem address " +
					std::to_string((uint64_t)itemfromlist) + " from the listbox"));
			}
			else m_edit1->setText(("You chose an item from listbox that's no longer valid!"));
		}
		else readbg() << "you managed to choose no item from the listbox\n";
	};
	add_control(m_listbox1);
	add_control(m_listbox1);
	
	m_checkbox1 = std::make_shared<WinCheckBox>(this,"The check box");
	add_control(m_checkbox1);
	m_checkbox1->GenericNotifyCallback = [this](GenericNotifications reason)
	{
		if (reason == GenericNotifications::Checked)
			readbg() << "check box was checked\n";
		else readbg() << "check box was unchecked\n";
	};
	
	m_label1 = std::make_shared<WinLabel>(this, "Ok, will all this text be shown by default...? I wonder...");
	add_control(m_label1);
	m_label1->setTopLeftPosition(150, 60);

	m_rectcontrol1 = std::make_shared<RectangleTestControl>(this);
	add_control(m_rectcontrol1);

	setSize(900, 650);
}
Beispiel #8
0
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 */

	if (IsRecording()) // Reaper won't preview anything during recording but extension will still think preview is in progress (could disrupt toggle states and send unneeded CC123)
		return;

	if (g_itemPreviewPlaying)
	{
		if (g_ItemPreview.preview_track)
		{
			StopTrackPreview(&g_ItemPreview);
			SendAllNotesOff((MediaTrack*)g_ItemPreview.preview_track);
		}
		else
		{
			StopPreview(&g_ItemPreview);
		}

		g_itemPreviewPlaying = false;
		delete g_ItemPreview.src;

		if (g_itemPreviewPaused && mode != 1) // requesting new preview while old one is still playing shouldn't unpause playback
		{
			if (IsPaused()) OnPauseButton();
			g_itemPreviewPaused = false;
		}

		if (mode == 2)
			return;
	}
	if (mode == 0)
		return;

	if (take)
	{
		MediaItem* item         = GetMediaItemTake_Item(take);
		MediaItem_Take* oldTake = GetActiveTake(item);
		bool itemMuteState      = *(bool*)GetSetMediaItemInfo(item, "B_MUTE", NULL);
		double effectiveTakeLen = EffectiveMidiTakeLength(take, true, true);

		GetSetMediaItemInfo(item, "B_MUTE", &g_bFalse);     // needs to be set before getting the source
		SetActiveTake(take);                                // active item take and editor take may differ
		PCM_source* src = ((PCM_source*)item)->Duplicate(); // must be item source otherwise item/take volume won't get accounted for

		if (src && effectiveTakeLen > 0 && effectiveTakeLen > startOffset)
		{
			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() && !IsPaused())
				OnPauseButton();

			if (g_ItemPreview.preview_track)
				g_itemPreviewPlaying = !!PlayTrackPreview2Ex(NULL, &g_ItemPreview, (measureSync) ? (1) : (0), measureSync);
			else
				g_itemPreviewPlaying = !!PlayPreviewEx(&g_ItemPreview, (measureSync) ? (1) : (0), measureSync);

			if (g_itemPreviewPlaying)
				plugin_register("timer",(void*)MidiTakePreviewTimer);
			else
				delete g_ItemPreview.src;
		}

		SetActiveTake(oldTake);
		GetSetMediaItemInfo(item, "B_MUTE", &itemMuteState);
	}
}
Beispiel #9
0
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);
	}
}
Beispiel #10
0
// param _allTakes only makes sense if jobTake() is used
bool FindWnd::FindMediaItem(int _dir, bool _allTakes, bool (*jobTake)(MediaItem_Take*,const char*), bool (*jobItem)(MediaItem*,const char*))
{
	bool update = false, found = false, sel = true;
	if (g_searchStr && *g_searchStr)
	{
		PreventUIRefresh(1);

		MediaItem* startItem = NULL;
		bool clearCurrentSelection = false;
		if (_dir)
		{
			WDL_PtrList<MediaItem> items;
			SNM_GetSelectedItems(NULL, &items);
			if (items.GetSize())
			{
				startItem = FindPrevNextItem(_dir, items.Get(_dir > 0 ? 0 : items.GetSize()-1));
				clearCurrentSelection = (startItem != NULL); 
			}
			else
				startItem = FindPrevNextItem(_dir, NULL);
		}
		else
		{
			startItem = FindPrevNextItem(1, NULL);
			clearCurrentSelection = (startItem != NULL); 
		}

		if (clearCurrentSelection)
		{
			Undo_BeginBlock2(NULL);
			Main_OnCommand(40289,0); // unselect all items
			update = true;
		}

		MediaItem* item = NULL;
		MediaTrack* startTr = startItem ? GetMediaItem_Track(startItem) : NULL;
		int startTrIdx = startTr ? CSurf_TrackToID(startTr, false) : -1;
		if (startTr && startItem && startTrIdx>=0)
		{
			// find startItem idx
			int startItemIdx=-1;
			while (item != startItem) 
				item = GetTrackMediaItem(startTr,++startItemIdx);

			bool firstItem=true, breakSelection=false;
			for (int i=startTrIdx; !breakSelection && i <= CountTracks(NULL) && i>=1; i += (!_dir ? 1 : _dir))
			{
				MediaTrack* tr = CSurf_TrackFromID(i, false); 
				int nbItems = GetTrackNumMediaItems(tr);
				for (int j = (firstItem ? startItemIdx : (_dir >= 0 ? 0 : (nbItems-1))); 
					 tr && !breakSelection && j < nbItems && j >= 0; 
					 j += (!_dir ? 1 : _dir))
				{
					item = GetTrackMediaItem(tr,j);
					firstItem = false;

					// search at item level 
					if (jobItem)
					{
						if (jobItem(item, g_searchStr))
						{
							if (!update) Undo_BeginBlock2(NULL);
							update = found = true;
							GetSetMediaItemInfo(item, "B_UISEL", &sel);
							if (_dir) breakSelection = true;
						}
					}
					// search at take level 
					else if (jobTake)
					{
						int nbTakes = GetMediaItemNumTakes(item);
						for (int k=0; item && k < nbTakes; k++)
						{
							MediaItem_Take* tk = GetMediaItemTake(item, k);
							if (tk && (_allTakes || (!_allTakes && tk == GetActiveTake(item))))
							{
								if (jobTake(tk, g_searchStr))
								{
									if (!update) Undo_BeginBlock2(NULL);
									update = found = true;
									GetSetMediaItemInfo(item, "B_UISEL", &sel);
									if (_dir) {
										breakSelection = true;
										break;
									}
								}
							}
						}
					}
				}
			}
		}
		UpdateNotFoundMsg(found);
		if (found && m_zoomSrollItems) {
			if (!_dir) ZoomToSelItems();
			else if (item) ScrollToSelItem(item);
		}

		PreventUIRefresh(-1);
	}

	if (update)
	{
		UpdateTimeline();
		Undo_EndBlock2(NULL, __LOCALIZE("Find: change media item selection","sws_undo"), UNDO_STATE_ALL);
	}
	return update;
}