コード例 #1
0
ファイル: BR_MidiUtil.cpp プロジェクト: Breeder/sws
/******************************************************************************
* 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));
		}
	}
}
コード例 #2
0
ファイル: padreUtils.cpp プロジェクト: AusRedNeck/sws
void GetTimeSegmentPositions(TimeSegment timeSegment, double &dStartPos, double &dEndPos, MediaItem* item)
{
	double dOrgCursorPos = GetCursorPositionEx(0);
	bool bRefreshCurPos = false;

	switch(timeSegment)
	{
		case eTIMESEGMENT_TIMESEL:
			//Main_OnCommandEx(ID_GOTO_TIMESEL_END, 0, 0);
			//dEndPos = GetCursorPositionEx(0);
			//Main_OnCommandEx(ID_GOTO_TIMESEL_START, 0, 0);
			//dStartPos = GetCursorPositionEx(0);
			GetSet_LoopTimeRange2(0, false, false, &dStartPos, &dEndPos, false);
		break;
		case eTIMESEGMENT_SELITEM:
			if(item != NULL)
			{
				dStartPos = GetMediaItemInfo_Value(item, "D_POSITION");
				dEndPos = dStartPos + GetMediaItemInfo_Value(item, "D_LENGTH");
			}
			else
			{
				Main_OnCommandEx(ID_GOTO_SELITEM_END, 0, 0);
				dEndPos = GetCursorPositionEx(0);
				Main_OnCommandEx(ID_GOTO_SELITEM_START, 0, 0);
				dStartPos = GetCursorPositionEx(0);
				bRefreshCurPos = true;
			}
		break;
		case eTIMESEGMENT_LOOP:
			//Main_OnCommandEx(ID_GOTO_LOOP_END, 0, 0);
			//dEndPos = GetCursorPositionEx(0);
			//Main_OnCommandEx(ID_GOTO_LOOP_START, 0, 0);
			//dStartPos = GetCursorPositionEx(0);
			GetSet_LoopTimeRange2(0, false, true, &dStartPos, &dEndPos, false);
		break;
		case eTIMESEGMENT_PROJECT:
			Main_OnCommandEx(ID_GOTO_PROJECT_END, 0, 0);
			dEndPos = GetCursorPositionEx(0);
			//Main_OnCommandEx(ID_GOTO_PROJECT_START, 0, 0);
			//dStartPos = GetCursorPositionEx(0);
			dStartPos = *(int*)GetConfigVar("projtimeoffs");
			bRefreshCurPos = true;
		break;
		//case eTIMESEGMENT_CURRENTMEASURE:
		//	Main_OnCommandEx(ID_GOTO_CURMEASURE_START, 0, 0);
		//	dStartPos = GetCursorPositionEx(0);
		//	Main_OnCommandEx(ID_GOTO_NEXTMEASURE_START, 0, 0);
		//	dEndPos = GetCursorPositionEx(0);
		//break;
		default:
		break;
	}

	if(bRefreshCurPos)
		SetEditCurPos2(0, dOrgCursorPos, true, false);
}
コード例 #3
0
ファイル: BR_MidiUtil.cpp プロジェクト: Breeder/sws
double GetMidiSourceLengthPPQ (MediaItem_Take* take, bool accountPlayrateIfIgnoringProjTempo, bool* isMidiSource /*=NULL*/)
{
	bool   isMidi = false;
	double length = 0;
	if (take && IsMidi(take))
	{
		MediaItem* item = GetMediaItemTake_Item(take);
		double itemStart    = GetMediaItemInfo_Value(item, "D_POSITION");
		double takeOffset   = GetMediaItemTakeInfo_Value(take, "D_STARTOFFS");
		double sourceLength = GetMediaItemTake_Source(take)->GetLength();
		double startPPQ = MIDI_GetPPQPosFromProjTime(take, itemStart - takeOffset);
		double endPPQ   = MIDI_GetPPQPosFromProjTime(take, itemStart - takeOffset + sourceLength);

		isMidi = true;
		length = endPPQ - startPPQ;

		if (accountPlayrateIfIgnoringProjTempo)
		{
			bool ignoreProjTempo;
			if (GetMidiTakeTempoInfo(take, &ignoreProjTempo, NULL, NULL, NULL) && ignoreProjTempo)
				length /= GetMediaItemTakeInfo_Value(take, "D_PLAYRATE");
		}
	}

	WritePtr(isMidiSource, isMidi);
	return length;
}
コード例 #4
0
ファイル: padreEnvelopeProcessor.cpp プロジェクト: tweed/sws
EnvelopeProcessor::ErrorCode EnvelopeProcessor::generateTakeLfo(MediaItem_Take* take)
{
	MediaItem* parentItem = GetMediaItemTake_Item(take);
	double dItemStartPos = GetMediaItemInfo_Value(parentItem, "D_POSITION");
	double dItemEndPos = dItemStartPos + GetMediaItemInfo_Value(parentItem, "D_LENGTH");

	double dStartPos, dEndPos;
	GetTimeSegmentPositions(_parameters.timeSegment, dStartPos, dEndPos, parentItem);

	if(dEndPos>dItemEndPos)
		dEndPos = dItemEndPos;

	if(dStartPos<dItemStartPos)
		dStartPos = dItemStartPos;

	dStartPos -= dItemStartPos;
	dEndPos -= dItemStartPos;

	return generateTakeLfo(take, dStartPos, dEndPos, _parameters.takeEnvType, _parameters.waveParams, _parameters.precision);
}
コード例 #5
0
ファイル: padreEnvelopeProcessor.cpp プロジェクト: tweed/sws
EnvelopeProcessor::ErrorCode EnvelopeProcessor::processTakeEnv(MediaItem_Take* take)
{
	MediaItem* parentItem = GetMediaItemTake_Item(take);
	double dItemStartPos = GetMediaItemInfo_Value(parentItem, "D_POSITION");
	double dItemEndPos = dItemStartPos + GetMediaItemInfo_Value(parentItem, "D_LENGTH");

	double dStartPos, dEndPos;
	GetTimeSegmentPositions(_envModParams.timeSegment, dStartPos, dEndPos, parentItem);

	if(dEndPos>dItemEndPos)
		dEndPos = dItemEndPos;

	if(dStartPos<dItemStartPos)
		dStartPos = dItemStartPos;

	dStartPos -= dItemStartPos;
	dEndPos -= dItemStartPos;

	return processTakeEnv(take, dStartPos, dEndPos, _envModParams.takeEnvType, _envModParams.type, _envModParams.strength, _envModParams.offset);
}
コード例 #6
0
ファイル: BR_MidiEditor.cpp プロジェクト: wolqws/sws
void ME_PreviewActiveTake (COMMAND_T* ct, int val, int valhw, int relmode, HWND hwnd)
{
	if (MediaItem_Take* take = MIDIEditor_GetTake(MIDIEditor_GetActive()))
	{
		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)
				start = mousePosition - GetMediaItemInfo_Value(item, "D_POSITION");
			else
				return;
		}

		vector<int> muteState;
		if (selNotes == 2 && !AreAllNotesUnselected(take))
			muteState = MuteSelectedNotes(take);

		MidiTakePreview(toggle, take, track, volume, start, measure, pausePlay);

		if (muteState.size() > 0)
			SetMutedNotes(take, muteState);
	}
}
コード例 #7
0
ファイル: BR_Tempo.cpp プロジェクト: wolqws/sws
void DeleteTempoPreserveItems (COMMAND_T* ct)
{
	BR_Envelope tempoMap(GetTempoEnv());
	if (!tempoMap.CountSelected())
		return;

	// Get items' position info and set their timebase to time
	vector<BR_MidiItemTimePos> items;
	double firstMarker;
	tempoMap.GetPoint(tempoMap.GetSelected(0), &firstMarker, NULL, NULL, NULL);

	int itemCount = ((int)ct->user) ? CountSelectedMediaItems(NULL) : CountMediaItems(NULL);
	items.reserve(itemCount);
	for (int i = 0; i < itemCount; ++i)
	{
		MediaItem* item = ((int)ct->user) ? GetSelectedMediaItem(NULL, i) : GetMediaItem(NULL, i);
		double itemEnd = GetMediaItemInfo_Value(item, "D_POSITION") + GetMediaItemInfo_Value(item, "D_LENGTH");
		if (itemEnd >= firstMarker)
		{
			items.push_back(BR_MidiItemTimePos(item));
			SetMediaItemInfo_Value(item, "C_BEATATTACHMODE", 0);
		}
	}

	// Readjust unselected tempo markers
	double offset = 0;
	for (int i = 0; i < tempoMap.CountConseq(); ++i)
	{
		int startId, endId;
		tempoMap.GetConseq (i, &startId, &endId);

		if (endId == tempoMap.Count()-1) continue;         // no points after selection, nothing to adjust
		if (startId == 0 && (++startId > endId)) continue; // skip first point

		// Get musical length of selection
		double musicalLen = 0;
		for (int i = startId - 1; i <= endId; ++i )
		{
			double t0, t1, b0, b1; int s0;
			tempoMap.GetPoint(i,   &t0, &b0, &s0, NULL);
			tempoMap.GetPoint(i+1, &t1, &b1, NULL, NULL);
			if (i == startId-1) t0 -= offset; // readjust position to original (earlier iterations moved it)

			if (s0 == SQUARE)
				musicalLen += (t1-t0) * b0 / 240;
			else
				musicalLen += (t1-t0) * (b0+b1) / 480;
		}

		// Readjust points after selection
		double t0, t1, b0, b1; int s0;
		tempoMap.GetPoint(startId - 1, &t0, &b0, &s0, NULL);
		tempoMap.GetPoint(endId   + 1, &t1, &b1, NULL, NULL);

		if (s0 == SQUARE)
			offset = (t0 + (240*musicalLen) / b0) - t1;
		else
			offset = (t0 + (480*musicalLen) / (b0 + b1)) - t1;

		while (!tempoMap.GetSelection(++endId) && endId < tempoMap.Count())
		{
			double t;
			tempoMap.GetPoint(endId, &t, NULL, NULL, NULL);
			t += offset;
			tempoMap.SetPoint (endId, &t, NULL, NULL, NULL);
		}
	}

	// Delete selected tempo markers
	int idOffset = 0;
	for (int i = 0; i < tempoMap.CountSelected(); ++i)
	{
		int id = tempoMap.GetSelected(i) - idOffset;
		if (id != 0) // skip first point
		{
			tempoMap.DeletePoint(id);
			++idOffset;
		}
	}

	// Commit tempo map and restore position info
	PreventUIRefresh(1);
	if (tempoMap.Commit(false))
	{
		for (size_t i = 0; i < items.size(); ++i)
			items[i].Restore();
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ALL, -1);
	}
	PreventUIRefresh(-1);
}
コード例 #8
0
ファイル: BR_MidiEditor.cpp プロジェクト: Jeff0S/sws
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);
	}
}
コード例 #9
0
ファイル: BR_MidiEditor.cpp プロジェクト: Jeff0S/sws
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);
	}
}
コード例 #10
0
ファイル: BR_MidiUtil.cpp プロジェクト: Breeder/sws
double EffectiveMidiTakeStart (MediaItem_Take* take, bool ignoreMutedEvents, bool ignoreTextEvents, bool ignoreEventsOutsideItemBoundaries)
{
	int noteCount, ccCount, sysCount;
	if (take && MIDI_CountEvts(take, &noteCount, &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");
	}
}
コード例 #11
0
ファイル: BR_MidiUtil.cpp プロジェクト: Breeder/sws
bool BR_MidiEditor::Build ()
{
	m_take = (m_midiEditor) ? SWS_MIDIEditor_GetTake(m_midiEditor) : m_take;

	if (m_take)
	{
		MediaItem* item = GetMediaItemTake_Item(m_take);
		int takeId = GetTakeId(m_take, item);
		if (takeId >= 0)
		{
			SNM_TakeParserPatcher p(item, CountTakes(item));
			WDL_FastString takeChunk;
			if (p.GetTakeChunk(takeId, &takeChunk))
			{
				SNM_ChunkParserPatcher ptk(&takeChunk, false);
				LineParser lp(false);

				int laneId = 0;
				WDL_FastString lineLane;
				while (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "VELLANE", laneId++, -1, &lineLane))
				{
					lp.parse(lineLane.Get());
					m_ccLanes.push_back(lp.gettoken_int(1));
					m_ccLanesHeight.push_back(lp.gettoken_int(((m_midiEditor) ? 2 : 3)));
					if (!m_midiEditor && m_ccLanesHeight.back() == 0)
						m_ccLanesHeight.back() = INLINE_MIDI_LANE_DIVIDER_H; // sometimes REAPER will return 0 when lane is completely hidden, but divider will still be visible
					lineLane.DeleteSub(0, lineLane.GetLength());
				}

				WDL_FastString dataLine;
				if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "HASDATA", 0, -1, &dataLine))
				{
					lp.parse(dataLine.Get());
					m_ppq = lp.gettoken_int(2);
				}
				else if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "FILE", 0, -1, &dataLine))
				{
					lp.parse(dataLine.Get());
					m_ppq = GetMIDIFilePPQ (lp.gettoken_str(1));
					if (!m_ppq)
						return false;
				}
				else
					return false;

				WDL_FastString lineView;
				if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "CFGEDITVIEW", 0, -1, &lineView))
				{
					lp.parse(lineView.Get());
					m_startPos = (m_midiEditor) ? lp.gettoken_float(1) : GetMediaItemInfo_Value(GetMediaItemTake_Item(m_take), "D_POSITION");
					m_hZoom    = (m_midiEditor) ? lp.gettoken_float(2) : GetHZoomLevel();
					m_vPos     = (m_midiEditor) ? lp.gettoken_int(3) : lp.gettoken_int(7);
					m_vZoom    = (m_midiEditor) ? lp.gettoken_int(4) : lp.gettoken_int(6);
				}
				else
					return false;

				WDL_FastString lineFilter;
				if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "EVTFILTER", 0, -1, &lineFilter))
				{
					lp.parse(lineFilter.Get());
					m_filterEnabled        = !!GetBit(lp.gettoken_int(7), 0);
					m_filterInverted       = !!GetBit(lp.gettoken_int(7), 2);
					m_filterChannel        = lp.gettoken_int(1);
					m_filterEventType      = lp.gettoken_int(2);
					m_filterEventParam     = !!lp.gettoken_int(16);
					m_filterEventVal       = !!lp.gettoken_int(8);
					m_filterEventPos       = !!lp.gettoken_int(14);
					m_filterEventLen       = !!lp.gettoken_int(9);
					m_filterEventParamLo   = lp.gettoken_int(17);
					m_filterEventParamHi   = lp.gettoken_int(18);
					m_filterEventValLo     = lp.gettoken_int(4);
					m_filterEventValHi     = lp.gettoken_int(5);
					m_filterEventPosRepeat = lp.gettoken_float(15);
					m_filterEventPosLo     = lp.gettoken_float(12);
					m_filterEventPosHi     = lp.gettoken_float(13);
					m_filterEventLenLo     = lp.gettoken_float(10);
					m_filterEventLenHi     = lp.gettoken_float(11);
				}
				else
					return false;

				WDL_FastString lineProp;
				if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "CFGEDIT", 0, -1, &lineProp))
				{
					lp.parse(lineProp.Get());
					m_pianoroll    = (m_midiEditor) ? lp.gettoken_int(6) : 0; // inline midi editor doesn't have piano roll modes
					m_drawChannel  = lp.gettoken_int(9) - 1;
					m_noteshow     = lp.gettoken_int(18);
					m_timebase     = (m_midiEditor) ? lp.gettoken_int(19) : PROJECT_SYNC;
				}
				else
					return false;

				// A few "corrections" for easier manipulation afterwards
				if (m_filterChannel == 0)     m_filterChannel = ~m_filterChannel;
				if (m_filterEventParamLo < 0) m_filterEventParamLo = 0;
				if (m_filterEventParamHi < 0) m_filterEventParamHi = INT_MAX;
				if (m_filterEventValLo   < 0) m_filterEventValLo   = 0;
				if (m_filterEventValHi   < 0) m_filterEventValHi   = INT_MAX;
				if (m_filterEventPosLo   < 0) m_filterEventPosLo   = 0;
				if (m_filterEventPosHi   < 0) m_filterEventPosHi   = INT_MAX;
				m_filterEventLenLo     = (m_filterEventLenLo     < 0) ? (0)       : (m_ppq * 4 * m_filterEventLenLo);
				m_filterEventLenHi     = (m_filterEventLenHi     < 0) ? (INT_MAX) : (m_ppq * 4 * m_filterEventLenHi);
				m_filterEventPosLo     = (m_filterEventPosLo     < 0) ? (0)       : (m_ppq * 4 * m_filterEventPosLo);
				m_filterEventPosHi     = (m_filterEventPosHi     < 0) ? (INT_MAX) : (m_ppq * 4 * m_filterEventPosHi);
				m_filterEventPosRepeat = (m_filterEventPosRepeat < 0) ? (0)       : (m_ppq * 4 * m_filterEventPosRepeat);

				return true;
			}
		}
	}
	return false;
}
コード例 #12
0
ファイル: BR_MidiUtil.cpp プロジェクト: Breeder/sws
double GetOriginalPpqPos (MediaItem_Take* take, double ppqPos, bool* loopedItem, double* posVisInsertStartPpq, double* posVisInsertEndPpq)
{
	double returnPos = 0;
	MediaItem* item = GetMediaItemTake_Item(take);
	if (!take || !item || !IsMidi(take, NULL))
	{
		WritePtr(loopedItem,          false);
		WritePtr(posVisInsertStartPpq, 0.0);
		WritePtr(posVisInsertEndPpq,   0.0);
	}
	else
	{
		double itemStart = GetMediaItemInfo_Value(item, "D_POSITION");
		double itemEnd   = itemStart + GetMediaItemInfo_Value(item, "D_LENGTH");

		if (GetMediaItemInfo_Value(item, "B_LOOPSRC") == 0)
		{
			WritePtr(loopedItem,           false);
			WritePtr(posVisInsertStartPpq, MIDI_GetPPQPosFromProjTime(take, itemStart));
			WritePtr(posVisInsertEndPpq,   MIDI_GetPPQPosFromProjTime(take, itemEnd));
			returnPos = ppqPos;
		}
		else
		{
			WritePtr(loopedItem, true);

			double visibleItemStartPpq = MIDI_GetPPQPosFromProjTime(take, itemStart);
			double visibleItemEndPpq   = MIDI_GetPPQPosFromProjTime(take, itemEnd);
			double sourceLenPpq = GetMidiSourceLengthPPQ(take, true);

			// Deduct take offset to get correct current loop iteration
			double itemStartPpq = MIDI_GetPPQPosFromProjTime(take, itemStart - GetMediaItemTakeInfo_Value(take, "D_STARTOFFS"));
			int currentLoop;
			int loopCount = GetLoopCount(take, MIDI_GetProjTimeFromPPQPos(take, ppqPos), &currentLoop);

			returnPos = (ppqPos >= visibleItemStartPpq) ? (ppqPos - (currentLoop * sourceLenPpq)) : ppqPos;

			if (ppqPos > visibleItemEndPpq)                            // position after item end
			{
				WritePtr(posVisInsertStartPpq, 0.0);
				WritePtr(posVisInsertEndPpq,   0.0);
			}
			else if (ppqPos < visibleItemStartPpq || currentLoop == 0) // position in first loop iteration or before it
			{
				WritePtr(posVisInsertStartPpq, visibleItemStartPpq);
				WritePtr(posVisInsertEndPpq,   (visibleItemEndPpq - visibleItemStartPpq >= sourceLenPpq) ? itemStartPpq + sourceLenPpq : visibleItemEndPpq);
			}
			else if (currentLoop == loopCount)                        // position in last loop iteration
			{
				WritePtr(posVisInsertStartPpq, itemStartPpq);
				WritePtr(posVisInsertEndPpq,   itemStartPpq + (visibleItemEndPpq - (currentLoop * sourceLenPpq)));
			}
			else                                                     // position in other loop iterations
			{
				WritePtr(posVisInsertStartPpq, itemStartPpq);
				WritePtr(posVisInsertEndPpq,   itemStartPpq + sourceLenPpq);
			}
		}
	}

	return returnPos;
}
コード例 #13
0
ファイル: BR_MidiUtil.cpp プロジェクト: Breeder/sws
double EffectiveMidiTakeEnd (MediaItem_Take* take, bool ignoreMutedEvents, bool ignoreTextEvents, bool ignoreEventsOutsideItemBoundaries)
{
	int noteCount, ccCount, sysCount;
	if (take && MIDI_CountEvts(take, &noteCount, &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, &noteStart, &noteEnd, 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;
}