예제 #1
0
bool MakeSingleTrackTemplateChunk(WDL_FastString* _in, WDL_FastString* _out, bool _delItems, bool _delEnvs, int _tmpltIdx, bool _obeyOffset)
{
	if (_in && _in->GetLength() && _out && _in!=_out)
	{
		_out->Set("");

		// truncate to the track #_tmpltIdx found in the template
		SNM_ChunkParserPatcher pin(_in);
		if (pin.GetSubChunk("TRACK", 1, _tmpltIdx, _out) >= 0)
		{
			int* offsOpt = _obeyOffset ? (int*)GetConfigVar("templateditcursor") : NULL; // >= REAPER v4.15

			// remove receives from the template as we deal with a single track
			// note: possible with multiple tracks in a same template file (w/ routings between those tracks)
			SNM_TrackEnvParserPatcher pout(_out);
			pout.RemoveLine("TRACK", "AUXRECV", 1, -1, "MIDIOUT");

			if (_delItems) // remove items from template (in one go)
				pout.RemoveSubChunk("ITEM", 2, -1);
			else if (offsOpt && *offsOpt) { // or offset them if needed
				double add = GetCursorPositionEx(NULL);
				pout.ParsePatch(SNM_D_ADD, 2, "ITEM", "POSITION", -1, 1, &add);
			}

			if (_delEnvs) // remove all envs from template (in one go)
				pout.RemoveEnvelopes();
			else if (offsOpt && *offsOpt) // or offset them if needed
				pout.OffsetEnvelopes(GetCursorPositionEx(NULL));
			return true;
		}
	}
	return false;
}
예제 #2
0
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_MidiEditor.cpp 프로젝트: tweed/sws
void ME_CCEventAtEditCursor (COMMAND_T* ct, int val, int valhw, int relmode, HWND hwnd)
{
	BR_MouseInfo mouseInfo(BR_MouseInfo::MODE_MIDI_EDITOR_ALL);
	if (mouseInfo.GetMidiEditor())
	{
		if (MediaItem_Take* take = MIDIEditor_GetTake(mouseInfo.GetMidiEditor()))
		{
			double positionPPQ = MIDI_GetPPQPosFromProjTime(take, GetCursorPositionEx(NULL));

			int lane, value;
			if (mouseInfo.GetCCLane(&lane, &value, NULL) && value >= 0)
			{
				if (lane == CC_TEXT_EVENTS || lane == CC_SYSEX || lane == CC_BANK_SELECT || lane == CC_VELOCITY)
					MessageBox((HWND)mouseInfo.GetMidiEditor(), __LOCALIZE("Can't insert in velocity, text, sysex and bank select lanes","sws_mbox"), __LOCALIZE("SWS/BR - Warning","sws_mbox"), MB_OK);
				else
				{
					bool do14bit    = (lane >= CC_14BIT_START) ? true : false;
					int type        = (lane == CC_PROGRAM) ? (STATUS_PROGRAM) : (lane == CC_CHANNEL_PRESSURE ? STATUS_CHANNEL_PRESSURE : (lane == CC_PITCH ? STATUS_PITCH : STATUS_CC));
					int channel     = MIDIEditor_GetSetting_int(mouseInfo.GetMidiEditor(), "default_note_chan");
					int msg2        = CheckBounds(lane, 0, 127) ? ((value >> 7) | 0) : (value & 0x7F);
					int msg3        = CheckBounds(lane, 0, 127) ? (value & 0x7F)     : ((value >> 7) | 0);

					int targetLane  = (do14bit) ? lane - CC_14BIT_START : lane;
					int targetLane2 = (do14bit) ? targetLane + 32       : lane;

					MIDI_InsertCC(take, true, false, positionPPQ, type,	channel, (CheckBounds(targetLane, 0, 127) ? targetLane : msg2), msg3);
					if (do14bit)
						MIDI_InsertCC(take, true, false, positionPPQ, type, channel, targetLane2, msg2);

					Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ITEMS, -1);
				}
			}
		}
	}
예제 #4
0
// replace or paste items sub-chunk _tmpltItems
// _paste==false for replace, paste otherwise
// _p: optional (to factorize chunk updates)
bool ReplacePasteItemsFromTrackTemplate(MediaTrack* _tr, WDL_FastString* _tmpltItems, bool _paste, SNM_ChunkParserPatcher* _p)
{
	bool updated = false;
	if (_tr && _tr != GetMasterTrack(NULL) && _tmpltItems) // no items on master
	{
		SNM_ChunkParserPatcher* p = (_p ? _p : new SNM_ChunkParserPatcher(_tr));

		 // delete current items?
		if (!_paste)
			updated |= p->RemoveSubChunk("ITEM", 2, -1);

		// insert template items
		if (_tmpltItems->GetLength())
		{
			WDL_FastString tmpltItems(_tmpltItems); // do not alter _tmpltItems!

			// offset items if needed
			int* offsOpt = (int*)GetConfigVar("templateditcursor"); // >= REAPER v4.15
			if (offsOpt && *offsOpt)
			{
				double add = GetCursorPositionEx(NULL);
				SNM_ChunkParserPatcher pitems(&tmpltItems);
				pitems.ParsePatch(SNM_D_ADD, 1, "ITEM", "POSITION", -1, 1, &add);
			}

			p->GetChunk()->Insert(tmpltItems.Get(), p->GetChunk()->GetLength()-2); // -2: before ">\n"
			p->IncUpdates(); // as we directly work on the chunk
			updated = true;
		}

		if (!_p)
			DELETE_NULL(p); // + auto-commit if needed
	}
	return updated;
}
예제 #5
0
파일: SnM_Project.cpp 프로젝트: tweed/sws
void InsertSilence(COMMAND_T* _ct)
{
	char val[64]="";
	lstrcpyn(val, g_lastSilenceVal[(int)_ct->user], sizeof(val));

	if (PromptUserForString(GetMainHwnd(), SWS_CMD_SHORTNAME(_ct), val, sizeof(val)) && *val)
	{
		double pos = GetCursorPositionEx(NULL), len = 0.0;
		switch ((int)_ct->user)
		{
			case 0: // s
				len = parse_timestr_len(val, pos, 3);
				break;
			case 1: // meas.beat
			{
/* no! would not take get tempo markers into account since 'val' is not inserted yet
				len = parse_timestr_len(val, pos, 2);
				break;
*/
				int in_meas = atoi(val);
				double in_beats = 0.0;
				char* p = strchr(val, '.');
				if (p && p[1]) in_beats = atof(p+1);

				double bpm; int num, den;
				TimeMap_GetTimeSigAtTime(NULL, pos, &num, &den, &bpm);
				len = in_beats*(60.0/bpm) + in_meas*((240.0*num/den)/bpm);
				break;
			}
			case 2: // smp
				len = parse_timestr_len(val, pos, 4);
				break;
		}

		if (len>0.0) {
			lstrcpyn(g_lastSilenceVal[(int)_ct->user], val, sizeof(val));
			InsertSilence(SWS_CMD_SHORTNAME(_ct), pos, len); // includes an undo point
		}
		else
			MessageBox(GetMainHwnd(), __LOCALIZE("Invalid input!","sws_mbox"), __LOCALIZE("S&M - Error","sws_mbox"), MB_OK);
	}
}
예제 #6
0
EnvelopeProcessor::ErrorCode EnvelopeProcessor::generateSelectedTrackEnvLfo()
{
	TrackEnvelope* envelope = GetSelectedTrackEnvelope(0);
	if(!envelope)
		return eERRORCODE_NOENVELOPE;

	Undo_BeginBlock2(0);

	//! \todo: use insert/goto actions AFTER error returns
	double dStartPos, dEndPos;
	GetTimeSegmentPositions(_parameters.timeSegment, dStartPos, dEndPos);

	if(dStartPos==dEndPos)
		return eERRORCODE_NULLTIMESELECTION;

	double dOrgCursorPos = GetCursorPositionEx(0);
	SetEditCurPos2(0, dStartPos-EPSILON_TIME, false, false);
	Main_OnCommandEx(ID_ENVELOPE_INSERT_POINT, 0, 0);
	SetEditCurPos2(0, dEndPos+EPSILON_TIME, false, false);
	Main_OnCommandEx(ID_ENVELOPE_INSERT_POINT, 0, 0);
	SetEditCurPos2(0, dOrgCursorPos, false, false);

	//Main_OnCommandEx(ID_MOVE_TIMESEL_NUDGE_LEFTEDGE_LEFT, 0, 0);
	//Main_OnCommandEx(ID_MOVE_TIMESEL_NUDGE_RIGHTEDGE_RIGHT, 0, 0);
	//Main_OnCommandEx(ID_GOTO_TIMESEL_START, 0, 0);
	//Main_OnCommandEx(ID_ENVELOPE_INSERT_POINT, 0, 0);
	//Main_OnCommandEx(ID_GOTO_TIMESEL_END, 0, 0);
	//Main_OnCommandEx(ID_ENVELOPE_INSERT_POINT, 0, 0);
	//Main_OnCommandEx(ID_MOVE_TIMESEL_NUDGE_LEFTEDGE_RIGHT, 0, 0);
	//Main_OnCommandEx(ID_MOVE_TIMESEL_NUDGE_RIGHTEDGE_LEFT, 0, 0);
	//Main_OnCommandEx(ID_ENVELOPE_DELETE_ALL_POINTS_TIMESEL, 0, 0);

	ErrorCode res = generateTrackLfo(envelope, dStartPos, dEndPos, _parameters.waveParams, _parameters.precision);
//UpdateTimeline();

	Undo_EndBlock2(NULL, __LOCALIZE("Track envelope LFO","sws_undo"), UNDO_STATE_TRACKCFG);
	return res;
}
예제 #7
0
파일: SnM_Find.cpp 프로젝트: AusRedNeck/sws
bool FindWnd::FindMarkerRegion(int _dir)
{
	if (!_dir)
		return false;

	bool update = false, found = false;
	if (g_searchStr && *g_searchStr)
	{
		double startPos = GetCursorPositionEx(NULL);
		int id, x = 0;
		bool bR;
		double dPos, dRend, dMinMaxPos = _dir < 0 ? -DBL_MAX : DBL_MAX;
		const char *cName;
		while ((x=EnumProjectMarkers2(NULL, x, &bR, &dPos, &dRend, &cName, &id)))
		{
			if (_dir == 1 && dPos > startPos) {
				if (stristr(cName, g_searchStr)) {
					found = true;
					dMinMaxPos = min(dPos, dMinMaxPos);
				}
			}
			else if (_dir == -1 && dPos < startPos) {
				if (stristr(cName, g_searchStr)) {
					found = true;
					dMinMaxPos = max(dPos, dMinMaxPos);
				}
			}
		}
		UpdateNotFoundMsg(found);	
		if (found) {
			SetEditCurPos2(NULL, dMinMaxPos, true, false);
			update = true;
		}
	}
	if (update)
		Undo_OnStateChangeEx2(NULL, __LOCALIZE("Find: change edit cursor position","sws_undo"), UNDO_STATE_ALL, -1); // in case the pref "undo pt for edit cursor positions" is enabled..
	return update;
}
예제 #8
0
void InsertMarker(COMMAND_T* _ct)
{
	AddProjectMarker2(NULL, false, (int)_ct->user && (GetPlayStateEx(NULL)&1) ? GetPlayPositionEx(NULL) : GetCursorPositionEx(NULL), 0.0, "", -1, 0);
	UpdateTimeline();
	Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(_ct), UNDO_STATE_MISCCFG, -1);
}
예제 #9
0
파일: BR_Tempo.cpp 프로젝트: wolqws/sws
void MoveTempo (COMMAND_T* ct)
{
	BR_Envelope tempoMap(GetTempoEnv());
	if (!tempoMap.Count())
		return;
	double cursor = GetCursorPositionEx(NULL);
	double tDiff = 0;
	int targetId = -1;

	// Find tempo marker closest to the edit cursor
	if ((int)ct->user == 3)
	{
		targetId = tempoMap.FindClosest(cursor);
		if (targetId == 0) ++targetId;
		if (!tempoMap.ValidateId(targetId))
			return;

		double cTime; tempoMap.GetPoint(targetId, &cTime, NULL, NULL, NULL);
		tDiff = cursor - cTime;
	}

	// Just get time difference for selected points
	else
	{
		if ((int)ct->user == 2 || (int)ct->user == -2)
			tDiff = 1 / GetHZoomLevel() * (double)ct->user / 2;
		else
			tDiff = (double)ct->user/10000;
	}

	if (tDiff == 0)
		return;

	// Loop through selected points
	int skipped = 0;
	int count = (targetId != -1) ? (1) : (tempoMap.CountSelected());
	for (int i = 0; i < count; ++i)
	{
		if (int id = ((int)ct->user == 3) ? (targetId) : (tempoMap.GetSelected(i))) // skip first point
			skipped += (MoveTempo(tempoMap, id, tDiff)) ? (0) : (1);
	}

	// Commit changes
	PreventUIRefresh(1); // prevent jumpy cursor
	if (tempoMap.Commit())
	{
		if ((int)ct->user == 3)
			SetEditCurPos2(NULL, cursor, false, false); // always keep cursor position when moving to closest tempo marker
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ALL, -1);
	}
	PreventUIRefresh(-1);

	// Warn user if some points weren't processed
	static bool s_warnUser = true;
	if (s_warnUser && skipped != 0)
	{
		char buffer[512];
		_snprintfSafe(buffer, sizeof(buffer), __LOCALIZE_VERFMT("%d of the selected points didn't get processed because some points would end up with illegal BPM or position. Would you like to be warned if it happens again?", "sws_mbox"), skipped);
		int userAnswer = ShowMessageBox(buffer, __LOCALIZE("SWS - Warning", "sws_mbox"), 4);
		if (userAnswer == 7)
			s_warnUser = false;
	}
}
예제 #10
0
파일: BR_Tempo.cpp 프로젝트: wolqws/sws
void MoveGridToEditPlayCursor (COMMAND_T* ct)
{
	// Find cursor immediately (in case of playback we want the most accurate position)
	double cursor = ((int)ct->user == 1 || (int)ct->user == 3) ? (GetPlayPositionEx(NULL)) : (GetCursorPositionEx(NULL));

	// Make sure tempo map already has at least one point created (for some reason it won't work if creating it directly in chunk)
	InitTempoMap();
	BR_Envelope tempoMap(GetTempoEnv());
	if (!tempoMap.Count())
		return;

	// Set preferences to prevent play cursor from jumping
	int seekmodes = 0;
	if ((int)ct->user == 1 || (int)ct->user == 3)
	{
		GetConfig("seekmodes", seekmodes);
		SetConfig("seekmodes", ClearBit(seekmodes, 5));
	}

	// Find closest grid
	double grid = 0;
	if      ((int)ct->user == 0 || (int)ct->user == 1) grid = GetClosestGrid(cursor);
	else if ((int)ct->user == 2 || (int)ct->user == 3) grid = GetClosestMeasureGrid(cursor);
	else if ((int)ct->user == 4)                       grid = GetClosestLeftSideGrid(cursor);
	else                                               grid = GetClosestRightSideGrid(cursor);
	int targetId = tempoMap.Find(grid, MIN_TEMPO_DIST);

	// No tempo marker on grid, create it
	if (!tempoMap.ValidateId(targetId))
	{
		int prevId  = tempoMap.FindPrevious(grid);
		double value = tempoMap.ValueAtPosition(grid);
		int shape;
		tempoMap.GetPoint(prevId, NULL, NULL, &shape, NULL);
		tempoMap.CreatePoint(prevId+1, grid, value, shape, 0, false);
		targetId = prevId+1;
	}
	double tDiff = cursor - grid;

	// Commit changes and warn user if needed
	if (tDiff != 0)
	{
		if (MoveTempo(tempoMap, targetId, tDiff))
		{
			PreventUIRefresh(1); // prevent jumpy cursor
			if (tempoMap.Commit())
			{
				// Restore edit cursor only if moving to it
				if ((int)ct->user != 1 && (int)ct->user != 3)
					SetEditCurPos2(NULL, cursor, false, false);
				Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ALL, -1);
			}
			PreventUIRefresh(-1);
		}
		else
		{
			static bool s_warnUser = true;
			if (s_warnUser)
			{
				int userAnswer = ShowMessageBox(__LOCALIZE("Moving grid failed because some tempo markers would end up with illegal BPM or position. Would you like to be warned if it happens again?", "sws_mbox"), __LOCALIZE("SWS - Warning", "sws_mbox"), 4);
				if (userAnswer == 7)
					s_warnUser = false;
			}
		}
	}

	// Restore preferences
	if ((int)ct->user == 1 || (int)ct->user == 3)
		SetConfig("seekmodes", seekmodes);
}