示例#1
0
void RestoreLastSelItemTrack(COMMAND_T* ct)
{
	PreventUIRefresh(1);
	for (int i = 1; i <= GetNumTracks(); i++)
	{
		MediaTrack* tr = CSurf_TrackFromID(i, false);
		if (*(int*)GetSetMediaTrackInfo(tr, "I_SELECTED", NULL))
		{
			GUID* g = (GUID*)GetSetMediaTrackInfo(tr, "GUID", NULL);
			for (int j = 0; j < g_selItemsTrack.Get()->GetSize(); j++)
				if (GuidsEqual(g, &g_selItemsTrack.Get()->Get(j)->m_guid))
				{
					g_selItemsTrack.Get()->Get(j)->PreviousSelection(tr);
					break;
				}
		}
	}
	PreventUIRefresh(-1);
	Undo_OnStateChangeEx(SWS_CMD_SHORTNAME(ct), UNDO_STATE_ITEMS, -1);
	UpdateArrange();
}
示例#2
0
void ME_ShowUsedCCLanesDetect14Bit (COMMAND_T* ct, int val, int valhw, int relmode, HWND hwnd)
{
	if (MediaItem_Take* take = MIDIEditor_GetTake(MIDIEditor_GetActive()))
	{
		RprTake rprTake(take);
		if (RprMidiCCLane* laneView = new (nothrow) RprMidiCCLane(rprTake))
		{
			int defaultHeight = 67; // same height FNG versions use (to keep behavior identical)
			set<int> usedCC = GetUsedCCLanes(MIDIEditor_GetTake(MIDIEditor_GetActive()), 2);

			for (int i = 0; i < laneView->countShown(); ++i)
				if (usedCC.find(laneView->getIdAt(i)) == usedCC.end())
					laneView->remove(i--);

			// Special case: Bank select and CC0 (from FNG version to keep behavior identical)
			if (usedCC.find(0) != usedCC.end() && usedCC.find(CC_BANK_SELECT) != usedCC.end() && !laneView->isShown(131))
				laneView->append(131, defaultHeight);

			for (set<int>::iterator it = usedCC.begin(); it != usedCC.end(); ++it)
			{
				if (!laneView->isShown(*it))
					laneView->append(*it, defaultHeight);
				else
				{
					for (int i = 0; i < laneView->countShown(); ++i)
					{
						if (laneView->getIdAt(i) == *it && laneView->getHeight(i) == 0)
							laneView->setHeightAt(i, defaultHeight);
					}
				}
			}

			if (laneView->countShown() == 0)
				laneView->append(-1, 0);

			delete laneView;
			Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ITEMS, -1);
		}
	}
}
示例#3
0
void SetMIDIInputChannel(COMMAND_T* _ct)
{
	bool updated = false;
	int ch = (int)_ct->user; // 0: all channels
	for (int i=1; i <= GetNumTracks(); i++) // skip master
	{
		MediaTrack* tr = CSurf_TrackFromID(i, false);
		if (tr && *(int*)GetSetMediaTrackInfo(tr, "I_SELECTED", NULL))
		{
			int in = *(int*)GetSetMediaTrackInfo(tr, "I_RECINPUT", NULL);
			if (((in & 0x1000) == 0x1000) && ((in & 0x1F) != ch))
			{
				in &= 0x1FE0;
				in |= ch;
				GetSetMediaTrackInfo(tr, "I_RECINPUT", &in);
				updated = true;
			}
		}
	}
	if (updated)
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(_ct), UNDO_STATE_ALL, -1);
}
示例#4
0
void PasteTrackGrouping(COMMAND_T* _ct)
{
	int updates = 0;
	for (int i=0; i <= GetNumTracks(); i++) // incl. master
	{
		MediaTrack* tr = CSurf_TrackFromID(i, false);
		if (tr && *(int*)GetSetMediaTrackInfo(tr, "I_SELECTED", NULL))
		{
			SNM_ChunkParserPatcher p(tr);
			updates += p.RemoveLines("GROUP_FLAGS", true); // brutal removing ok: "GROUP_FLAGS" is not part of freeze data
			int patchPos = p.Parse(SNM_GET_CHUNK_CHAR, 1, "TRACK", "TRACKHEIGHT", 0, 0, NULL, NULL, "MAINSEND");
			if (patchPos > 0)
			{
				p.GetChunk()->Insert(g_trackGrpClipboard.Get(), --patchPos);
				p.IncUpdates(); // as we're directly working on the cached chunk..
				updates++;
			}
		}
	}
	if (updates)
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(_ct), UNDO_STATE_ALL, -1);
}
示例#5
0
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 startLimit, endLimit;
			double positionPPQ = GetOriginalPpqPos(take, MIDI_GetPPQPosFromProjTime(take, GetCursorPositionEx(NULL)), NULL, &startLimit, &endLimit);
			if (!CheckBounds(positionPPQ, startLimit, endLimit))
				return;

			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 || lane == CC_VELOCITY_OFF)
					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);
				}
			}
		}
	}
示例#6
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);
}
示例#7
0
void GotoMarker(COMMAND_T* _ct) {
	if (GotoMarkerRegion(NULL, ((int)_ct->user)+1, SNM_MARKER_MASK))
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(_ct), UNDO_STATE_ALL, -1);
}
示例#8
0
static void HideUnusedCCLanes(COMMAND_T* ct, int val, int valhw, int relmode, HWND hwnd)
{
	HideUnusedCCLanes(UNDO_STATE_ITEMS, &ct->user);
	Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ITEMS, -1);
}
示例#9
0
void ContinuousActionStopAll ()
{
	if (g_actionInProgress && g_actionInProgress->DoUndo && g_actionInProgress->DoUndo())
			Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(SWSGetCommandByID(g_actionInProgress->cmd)), UNDO_STATE_ALL, -1);
	ContinuousActionInit(false, 0, NULL);
}
示例#10
0
文件: BR_Tempo.cpp 项目: wolqws/sws
void EditTempoGradual (COMMAND_T* ct)
{
	// Get tempo map
	BR_Envelope tempoMap(GetTempoEnv());
	if (!tempoMap.CountSelected())
		return;

	// Get values and type of operation to be performed
	bool percentage = false;
	double diff;
	if (GetFirstDigit((int)ct->user) == 1)
		diff = (double)ct->user / 1000;
	else
	{
		diff = (double)ct->user / 200000;
		percentage = true;
	}

	// Loop through selected points and perform BPM calculations
	int skipped = 0;
	for (int i = 0; i < tempoMap.CountSelected(); ++i)
	{
		int id = tempoMap.GetSelected(i);

		// Hold new values for selected and next point
		double Nb1, Nt1;
		vector<double> selPos;
		vector<double> selBpm;

		///// CURRENT POINT /////
		/////////////////////////

		// Store new values for selected points into vectors
		int offset = 0;
		while (true)
		{
			// Get point currently in the loop and points surrounding it
			double t0, t1, t2, b0, b1, b2;
			int s0, s1;
			bool P0 = tempoMap.GetPoint(id+offset-1, &t0, &b0, &s0, NULL);
			tempoMap.GetPoint(id+offset,   &t1, &b1, &s1, NULL);
			tempoMap.GetPoint(id+offset+1, &t2, &b2, NULL, NULL);

			// If square or not selected, break
			if (s1 == SQUARE || !tempoMap.GetSelection(id+offset))
			{
				// If breaking on the first selected point, don't adjust i (so for loop doesn't go backwards).
				i += (offset == 0) ? (0) : (offset-1);
				--offset; // since this point is not taken into account, correct offset
				break;
			}

			// Get new BPM
			double bpm = b1 + ((percentage) ? (b1*diff) : (diff));
			if (bpm < MIN_BPM)
				bpm = MIN_BPM;
			else if (bpm > MAX_BPM)
				bpm = MAX_BPM;

			// Get new position (special case for the first point)
			double position;
			if (offset == 0)
			{
				if (P0 && s0 == LINEAR)
				{
					position = (t1*(b0+b1) + t0*(bpm-b1)) / (b0 + bpm); // first point moves but the one before it
					if (position - t0 < MIN_TEMPO_DIST)                 // doesn't so check if their distance is legal
						break;
				}
				else
					position = t1;
			}
			else
				position = ((b0+b1)*(t1-t0) + selPos.back() * (selBpm.back() + bpm)) / (selBpm.back() + bpm);

			// Store new values
			selPos.push_back(position);
			selBpm.push_back(bpm);
			++offset;
		}

		// Check for illegal position/no linear points encountered (in that case offset is -1 so skipped won't change)
		if (!selPos.size())
			SKIP(skipped, offset+1);

		///// NEXT POINT /////
		//////////////////////

		// Get points after the last selected point
		double t1, t2;
		double b1, b2;
		int s2;
		bool P1 = tempoMap.GetPoint(id+offset+1, &t1, &b1, &s2, NULL);
		bool P2 = tempoMap.GetPoint(id+offset+2, &t2, &b2, NULL, NULL);

		// Calculate new value and position for the next point
		if (P1)
		{
			// Get last selected tempo point (old and new)
			double Nb0 = selBpm.back();
			double Nt0 = selPos.back();
			double t0, b0;
			tempoMap.GetPoint(id+offset, &t0, &b0, NULL, NULL);

			if (P2)
			{
				if (s2 == SQUARE)
				{
					double f1 = (b0+b1)*(t1-t0);
					double f2 = b1*(t2-t1);
					double a = Nb0;
					double b = (a*(Nt0+t2) + f1+f2) / 2;
					double c = a*(Nt0*t2) + f1*t2 + f2*Nt0;
					Nt1 = c / (b + sqrt(pow(b,2) - a*c));
					Nb1 = f2 / (t2-Nt1);
				}
				else
				{
					double f1 = (b0+b1)*(t1-t0);
					double f2 = (b1+b2)*(t2-t1);
					double a = Nb0 - b2;
					double b = (a*(Nt0+t2) + f1+f2) / 2;
					double c = a*(Nt0*t2) + f1*t2 + f2*Nt0;
					Nt1 = c / (b + sqrt(pow(b,2) - a*c));
					Nb1 = f2 / (t2-Nt1) - b2;
				}
			}
			else
			{
				Nt1 = t1;
				Nb1 = (b0+b1)*(t1-t0) / (t1-Nt0) - Nb0;
			}

			// If points after selected point don't exist, fake them
			if (!P1)
				Nt1 = Nt0 + 1;
			if (!P2)
				t2 = Nt1 + 1;

			// Check new value is legal
			if (Nb1 > MAX_BPM || Nb1 < MIN_BPM)
				SKIP(skipped, offset+1);
			if ((Nt1-Nt0) < MIN_TEMPO_DIST || (t2 - Nt1) < MIN_TEMPO_DIST)
				SKIP(skipped, offset+1);
		}

		///// SET NEW BPM /////
		///////////////////////

		// Current point(s)
		for (int i = 0; i < (int)selPos.size(); ++i)
			tempoMap.SetPoint(id+i, &selPos[i], &selBpm[i], NULL, NULL);

		// Next point
		if (P1)
			tempoMap.SetPoint(id+offset+1, &Nt1, &Nb1, NULL, NULL);
	}

	// Commit changes
	if (tempoMap.Commit())
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ALL, -1);

	// Warn user if some points weren't processed
	static bool s_warnUser = true;
	if (s_warnUser && skipped != 0 && tempoMap.CountSelected() > 1 )
	{
		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;
	}
}
示例#11
0
// Command version with undo point and wnd update
void DeleteAllRegions(COMMAND_T* ct)
{
	DeleteAllRegions();
	Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_MISCCFG, -1);
	g_pMarkerList->Update();
}
示例#12
0
void CueBuss(COMMAND_T* _ct) {
	CueBuss(SWS_CMD_SHORTNAME(_ct), (int)_ct->user);
}
示例#13
0
void SetTrackToFirstUnusedGroup(COMMAND_T* _ct) {
	if (SetTrackGroup(FindFirstUnusedGroup()))
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(_ct), UNDO_STATE_ALL, -1);
}
示例#14
0
void SetTrackGroup(COMMAND_T* _ct) {
	if (SetTrackGroup((int)_ct->user))
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(_ct), UNDO_STATE_ALL, -1);
}
示例#15
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;
	}
}
示例#16
0
文件: BR_Tempo.cpp 项目: wolqws/sws
void EditTempo (COMMAND_T* ct)
{
	// Get tempo map
	BR_Envelope tempoMap(GetTempoEnv());
	if (!tempoMap.CountSelected())
		return;

	// Get values and type of operation to be performed
	bool percentage = false;
	double diff;
	if (GetFirstDigit((int)ct->user) == 1)
		diff = (double)ct->user / 1000;
	else
	{
		diff = (double)ct->user / 200000;
		percentage = true;
	}

	// Loop through selected points and perform BPM calculations
	int skipped = 0;
	for (int i = 0; i < tempoMap.CountSelected(); ++i)
	{
		int id = tempoMap.GetSelected(i);

		// Hold new values for selected and surrounding points
		double Nt1, Nt3, Nb1, Nb3;
		vector<double> selPos;
		vector<double> selBpm;

		///// CURRENT POINT /////
		/////////////////////////

		// Get all consequentially selected points into a vector with their new values. In case
		// there is consequential selection, middle musical position of a transition between first
		// and last selected point will preserve it's time position (where possible)
		int offset = 0;
		if (tempoMap.GetSelection(id+1))
		{
			// Store new values for selected points into vectors
			double musicalMiddle = 0;
			vector<double> musicalLength;
			while (true)
			{
				// Once unselected point is encountered, break
				if (!tempoMap.GetSelection(id+offset))
				{
					--offset;    // since this point is not taken into account, correct offset

					i += offset; // in case of consequential selection, points are treated as
					break;       // one big transition, so skip them all
				}

				// Get point currently in the loop and surrounding points
				double t0, t1, t2, b0, b1, b2;
				int s0, s1;
				bool P0 = tempoMap.GetPoint(id+offset-1, &t0, &b0, &s0, NULL);
				tempoMap.GetPoint(id+offset,   &t1, &b1, &s1, NULL);
				tempoMap.GetPoint(id+offset+1, &t2, &b2, NULL, NULL);

				// Get musical length for every transition but the last
				double mLen = 0;
				if (tempoMap.GetSelection(id+offset+1))
				{
					if (s1 == SQUARE)
						mLen = b1*(t2-t1) / 240;
					else
						mLen = (b1+b2)*(t2-t1) / 480;
				}
				musicalMiddle += mLen;

				// Get new BPM
				double bpm = b1 + (percentage ? (b1*diff) : (diff));
				if (bpm < MIN_BPM)
					bpm = MIN_BPM;
				else if (bpm > MAX_BPM)
					bpm = MAX_BPM;

				// Get new position (special case for the first point)
				double position;
				if (!offset)
				{
					if (P0 && s0 == LINEAR)
						position = (t1*(b0+b1) + t0*(bpm-b1)) / (b0 + bpm);
					else
						position = t1;
				}
				else
				{
					if (s0 == LINEAR)
						position = (480*musicalLength.back() + selPos.back()*(bpm + selBpm.back())) / (bpm + selBpm.back());
					else
						position = (240*musicalLength.back() + selPos.back()*selBpm.back()) / selBpm.back();
				}

				// Store new values
				selPos.push_back(position);
				selBpm.push_back(bpm);
				musicalLength.push_back(mLen);
				++offset;
			}

			// Find time position of musical middle and move all point so time position
			// of musical middle is preserved (only if previous point exists)
			musicalMiddle /= 2;
			if (tempoMap.GetPoint(id-1, NULL, NULL, NULL, NULL))
			{
				double temp = 0;
				for (int i = 0; i < (int)selPos.size()-1; ++i)
				{
					temp += musicalLength[i];
					if (temp >= musicalMiddle)
					{
						// Get length between the points that contain musical middle
						double len = musicalMiddle - (temp-musicalLength[i]);

						// Find original time position of musical middle
						double t0, t1, b0, b1; int s0;
						tempoMap.GetPoint(id+i,   &t0, &b0, &s0, NULL);
						tempoMap.GetPoint(id+i+1, &t1, &b1, NULL, NULL);
						double prevPos = t0 + PositionAtMeasure (b0, (s0 == 1 ? b0 : b1), t1-t0, len);

						// Find new time position of musical middle
						double newPos = t0 + PositionAtMeasure (selBpm[i], (s0 == 1 ? selBpm[i] : selBpm[i+1]), selPos[i+1] - selPos[i], len);

						// Reset time positions of selected points
						double diff = newPos - prevPos;
						for (size_t i = 0; i < selPos.size(); ++i)
							selPos[i] -= diff;
						break;
					}
				}
			}
		}
		else
		{
			// Get selected point
			double t, b;
			tempoMap.GetPoint(id, &t, &b, NULL, NULL);

			// Get new BPM
			b += (percentage) ? (b*diff) : (diff);
			if (b < MIN_BPM)
				b = MIN_BPM;
			else if (b > MAX_BPM)
				b = MAX_BPM;

			// Store it
			selPos.push_back(t);
			selBpm.push_back(b);
		}

		///// PREVIOUS POINT /////
		//////////////////////////

		// Get points before selected points
		double t0, t1, b0, b1;
		int s0, s1;
		bool P0 = tempoMap.GetPoint(id-2, &t0, &b0, &s0, NULL);
		bool P1 = tempoMap.GetPoint(id-1, &t1, &b1, &s1, NULL);

		if (P1)
		{
			// Get first selected point (old and new)
			double t2, b2;
			tempoMap.GetPoint(id, &t2, &b2, NULL, NULL);
			double Nb2 = selBpm.front();
			double Nt2 = selPos.front();

			// If point behind previous doesn't exist, fake it as square
			if (!P0)
				s0 = SQUARE;

			// Calculate new value and position for previous point
			if (!P0 || s0 == SQUARE)
			{
				if (s1 == SQUARE)
				{
					Nt1 = t1;
					Nb1 = b1*(t2-t1) / (Nt2-Nt1);
				}
				else
				{
					Nt1 = t1;
					Nb1 = (b1+b2)*(t2-t1) / (Nt2-Nt1) - Nb2;
				}
			}
			else
			{
				if (s1 == SQUARE)
				{
					double f1 = (b0+b1) *(t1-t0);
					double f2 = b1*(t2-t1);
					double a = b0;
					double b = (a*(t0+Nt2) + f1+f2) / 2;
					double c = a*(t0*Nt2) + f1*Nt2 + f2*t0;
					Nt1 = c / (b + sqrt(pow(b,2) - a*c));
					Nb1 = f2 / (Nt2 - Nt1);
				}
				else
				{
					double f1 = (b0+b1)*(t1-t0);
					double f2 = (b1+b2)*(t2-t1);
					double a = b0 - Nb2;
					double b = (a*(t0+Nt2) + f1+f2) / 2;
					double c = a*(t0*Nt2) + f1*Nt2 + f2*t0;
					Nt1 = c / (b + sqrt(pow(b,2) - a*c));
					Nb1 = f2 / (Nt2 - Nt1) - Nb2;
				}
			}

			// If point behind previous doesn't exist, fake it's position so it can pass legality check
			if (!P0)
				t0 = Nt1 - 1;

			// Check new value is legal
			if (Nb1 > MAX_BPM || Nb1 < MIN_BPM)
				SKIP(skipped, offset+1);
			if ((Nt1-t0) < MIN_TEMPO_DIST || (Nt2 - Nt1) < MIN_TEMPO_DIST)
				SKIP(skipped, offset+1 );
		}

		///// NEXT POINT /////
		//////////////////////

		// Get points after selected points
		double t3, t4, b3, b4;
		int s3;
		bool P3 = tempoMap.GetPoint(id+offset+1, &t3, &b3, &s3, NULL);
		bool P4 = tempoMap.GetPoint(id+offset+2, &t4, &b4, NULL, NULL);

		if (P3)
		{
			// Get last selected point (old and new)
			double t2, b2; int s2;
			tempoMap.GetPoint(id+offset, &t2, &b2, &s2, NULL);
			double Nb2 = selBpm.back();
			double Nt2 = selPos.back();

			// Calculate new value and position for next point
			if (s2 == SQUARE)
			{
				if (P4)
				{
					if (s3 == SQUARE)
					{
						Nt3 = (b2*(t3-t2) + Nb2*Nt2) / Nb2;
						Nb3 = b3*(t4-t3) / (t4-Nt3);
					}
					else
					{
						Nt3 = (b2*(t3-t2) + Nb2*Nt2) / Nb2;
						Nb3 = (b3+b4)*(t4-t3) / (t4-Nt3) - b4;
					}
				}
				else
				{
					Nt3 = (b2*(t3-t2) + Nb2*Nt2) / Nb2;
					Nb3 = b3;
				}
			}
			else
			{
				if (P4)
				{
					if (s3 == SQUARE)
					{
						double f1 = (b2+b3)*(t3-t2);
						double f2 = b3*(t4-t3);
						double a = Nb2;
						double b = (a*(Nt2+t4) + f1+f2) / 2;
						double c = a*(Nt2*t4) + f1*t4 + f2*Nt2;
						Nt3 = c / (b + sqrt(pow(b,2) - a*c));
						Nb3 = f2 / (t4-Nt3);
					}
					else
					{
						double f1 = (b2+b3)*(t3-t2);
						double f2 = (b3+b4)*(t4-t3);
						double a = Nb2 - b4;
						double b = (a*(Nt2+t4) + f1+f2) / 2;
						double c = a*(Nt2*t4) + f1*t4 + f2*Nt2;
						Nt3 = c / (b + sqrt(pow(b,2) - a*c));
						Nb3 = f2 / (t4-Nt3) - b4;
					}
				}
				else
				{
					Nt3 = t3;
					Nb3 = (b2+b3)*(t3-t2) / (Nt3-Nt2) - Nb2;
				}
			}

			// If point after the next doesn't exist fake it's position so it can pass legality check
			if (!P4)
				t4 = Nt3 + 1;

			// Check new value is legal
			if (Nb3 > MAX_BPM || Nb3 < MIN_BPM)
				SKIP(skipped, offset+1);
			if ((Nt3-Nt2) < MIN_TEMPO_DIST || (t4 - Nt3) < MIN_TEMPO_DIST)
				SKIP(skipped, offset+1);
		}

		///// SET BPM /////
		///////////////////

		// Previous point
		if (P1)
			tempoMap.SetPoint(id-1, &Nt1, &Nb1, NULL, NULL);

		// Current point(s)
		for (int i = 0; i < (int)selPos.size(); ++i)
			tempoMap.SetPoint(id+i, &selPos[i], &selBpm[i], NULL, NULL);

		// Next point
		if (P3)
			tempoMap.SetPoint(id+offset+1, &Nt3, &Nb3, NULL, NULL);
	}

	// Commit changes
	if (tempoMap.Commit())
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ALL, -1);

	// Warn user if some points weren't processed
	static bool s_warnUser = true;
	if (s_warnUser && skipped != 0 && tempoMap.CountSelected() > 1)
	{
		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;
	}
}
示例#17
0
void RestoreSelItems(COMMAND_T* ct)
{
	g_selItems.Get()->Restore(NULL);
	Undo_OnStateChangeEx(SWS_CMD_SHORTNAME(ct), UNDO_STATE_ITEMS, -1);
	UpdateTimeline();
}
示例#18
0
文件: BR_Tempo.cpp 项目: wolqws/sws
void DeleteTempo (COMMAND_T* ct)
{
	// Get tempo map
	BR_Envelope tempoMap(GetTempoEnv());
	if (!tempoMap.CountSelected())
		return;
	int offset = 0;

	// Loop through selected points and perform BPM calculations
	int skipped = 0;
	for (int i = 0; i < tempoMap.CountSelected(); ++i)
	{
		int id = tempoMap.GetSelected(i) + offset;
		if (id == 0)
			continue;

		// Get tempo points
		double t1, t2, t3, t4;
		double b1, b2, b3, b4;
		int s0, s1, s2, s3;

		tempoMap.GetPoint(id, &t2, &b2, &s2, NULL);
		bool P0 = tempoMap.GetPoint(id-2, NULL, NULL, &s0, NULL);
		bool P1 = tempoMap.GetPoint(id-1, &t1, &b1, &s1, NULL);
		bool P3 = tempoMap.GetPoint(id+1, &t3, &b3, &s3, NULL);
		bool P4 = tempoMap.GetPoint(id+2, &t4, &b4, NULL, NULL);

		// Hold new values
		double Nt1, Nb1;
		double Nt3, Nb3;

		// If previous point doesn't exist, fake it
		if (!P0)
			s0 = SQUARE;

		// Get P2-P3 length
		double m2;
		if (s2 == SQUARE)
			m2 = b2*(t3-t2) / 240;
		else
			m2 = (b2+b3)*(t3-t2) / 480;


		///// CALCULATE BPM VALUES /////
		////////////////////////////////
		if (P3)
		{
			if (s0 == SQUARE)
			{
				if (s1 == SQUARE)
				{
					Nt1 = t1;
					Nb1 = (240*m2 + b1*(t2-t1)) / (t3-t1);
				}
				else
				{
					Nt1 = t1;
					Nb1 = (480*m2 + (b1+b2)*(t2-t1)) / (t3-t1) - b3;
				}

				// Check new value is legal
				if (Nb1 > MAX_BPM || Nb1 < MIN_BPM)
					SKIP(skipped, 1);

				// Next point stays the same
				P3 = false;
			}
			else
			{
				// If P4 exists...
				if (P4)
				{
					if (s1 == SQUARE)
					{
						if (s3 == SQUARE)
						{
							Nt3 = t2 + 240*m2 / b1;
							Nb3 = b3*(t4-t3) / (t4-Nt3);
						}
						else
						{
							Nt3 = t2 + 240*m2 / b1;
							Nb3 = (b3+b4)*(t4-t3) / (t4-Nt3) - b4;
						}
					}
					else
					{
						if (s3 == SQUARE)
						{
							double f1 = (b1+b2)*(t2-t1) + 480*m2;
							double f2 = b3*(t4-t3);
							double a = b1;
							double b = (a*(t1+t4) + f1+f2) / 2;
							double c = a*(t1*t4) + f1*t4 + f2*t1;
							Nt3 = c / (b + sqrt(pow(b,2) - a*c));
							Nb3 = f2 / (t4 - Nt3);
						}
						else
						{
							double f1 = (b1+b2)*(t2-t1) + 480*m2;
							double f2 = (b3+b4)*(t4-t3);
							double a = b1-b4;
							double b = (a*(t1+t4) + f1+f2) / 2;
							double c = a*(t1*t4) + f1*t4 + f2*t1;
							Nt3 = c / (b + sqrt(pow(b,2) - a*c));
							Nb3 = f2 / (t4 - Nt3) - b4;
						}
					}

					// Check new position is legal
					if ((Nt3 - t1) < MIN_TEMPO_DIST || (t4 - Nt3) < MIN_TEMPO_DIST)
						SKIP(skipped, 1);
				}

				// If P4 does not exist
				else
				{

					if (s1 == SQUARE)
					{
						Nt3 = t2 + 240*m2 / b1;
						Nb3 = b3;
					}
					else
					{
						Nt3 = t3;
						Nb3 = (480*m2 + (b1+b2)*(t2-t1)) / (t3-t1) - b1;
					}

					// Check new position is legal
					if ((Nt3 - t1) < MIN_TEMPO_DIST)
						SKIP(skipped, 1);
				}

				// Check new value is legal
				if (Nb3 > MAX_BPM || Nb3 < MIN_BPM)
					SKIP(skipped, 1);

				// Previous point stays the same
				P1 = false;
			}
		}
		else
		{
			// No surrounding points get edited
			P1 = false;
			P3 = false;
		}

		///// SET NEW BPM /////
		///////////////////////

		// Previous point
		if (P1)
			tempoMap.SetPoint(id-1, &Nt1, &Nb1, NULL, NULL);

		// Next point
		if (P3)
			tempoMap.SetPoint(id+1, &Nt3, &Nb3, NULL, NULL);

		// Delete point
		tempoMap.DeletePoint(id);
		--offset;
	}

	// Commit changes
	if (tempoMap.Commit())
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ALL, -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;
	}
}
示例#19
0
文件: SnM_ME.cpp 项目: Jeff0S/sws
void MainHideCCLanes(COMMAND_T* _ct)
{
	if (replaceCCLanes("VELLANE -1 0 0\n")) 
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(_ct), UNDO_STATE_ALL, -1);
}
示例#20
0
void SetStartupAction(COMMAND_T* _ct)
{
	int type=(int)_ct->user;

	if (PromptClearStartupAction(type, false) == IDNO)
		return;

	char idstr[SNM_MAX_ACTION_CUSTID_LEN];
	lstrcpyn(idstr, __LOCALIZE("Paste command ID or identifier string here","sws_startup_action"), sizeof(idstr));
	if (PromptUserForString(GetMainHwnd(), SWS_CMD_SHORTNAME(_ct), idstr, sizeof(idstr), true))
	{
		WDL_FastString msg;
		if (int cmdId = SNM_NamedCommandLookup(idstr))
		{
			// more checks: http://forum.cockos.com/showpost.php?p=1252206&postcount=1618
			if (int tstNum = CheckSwsMacroScriptNumCustomId(idstr))
			{
				// localization note: msgs shared with the CA editor
				msg.SetFormatted(512, __LOCALIZE_VERFMT("%s failed: unreliable command ID '%s'!","sws_startup_action"), SWS_CMD_SHORTNAME(_ct), idstr);
				msg.Append("\r\n");

				if (tstNum==-1)
					msg.Append(__LOCALIZE("For SWS/S&M actions, you must use identifier strings (e.g. _SWS_ABOUT), not command IDs (e.g. 47145).\nTip: to copy such identifiers, right-click the action in the Actions window > Copy selected action cmdID/identifier string.","sws_startup_action"));
				else if (tstNum==-2)
					msg.Append(__LOCALIZE("For macros/scripts, you must use identifier strings (e.g. _f506bc780a0ab34b8fdedb67ed5d3649), not command IDs (e.g. 47145).\nTip: to copy such identifiers, right-click the macro/script in the Actions window > Copy selected action cmdID/identifier string.","sws_startup_action"));
				MessageBox(GetMainHwnd(), msg.Get(), __LOCALIZE("S&M - Error","sws_mbox"), MB_OK);
			}
			else
			{
				if (!type)
				{
					g_prjActions.Get()->Set(idstr);
					Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(_ct), UNDO_STATE_MISCCFG, -1);

					msg.SetFormatted(512, __LOCALIZE_VERFMT("'%s' is defined as project startup action","sws_startup_action"), kbd_getTextFromCmd(cmdId, NULL));          
					char prjFn[SNM_MAX_PATH] = "";
					EnumProjects(-1, prjFn, sizeof(prjFn));
					if (*prjFn)
					{
						msg.Append("\r\n");
						msg.AppendFormatted(SNM_MAX_PATH, __LOCALIZE_VERFMT("for %s","sws_startup_action"), prjFn);
						msg.Append(".\r\n\r\n");
						msg.Append(__LOCALIZE("Note: do not forget to save this project","sws_startup_action"));
					}
				}
				else
				{
					g_globalAction.Set(idstr);
					WritePrivateProfileString("Misc", "GlobalStartupAction", idstr, g_SNM_IniFn.Get()); 

					msg.SetFormatted(512, __LOCALIZE_VERFMT("'%s' is defined as global startup action","sws_startup_action"), kbd_getTextFromCmd(cmdId, NULL));
				}
				msg.Append(".");
				MessageBox(GetMainHwnd(), msg.Get(), SWS_CMD_SHORTNAME(_ct), MB_OK);
			}
		}
		else
		{
			msg.SetFormatted(512, __LOCALIZE_VERFMT("%s failed: command ID or identifier string '%s' not found in the 'Main' section of the action list!","sws_startup_action"), SWS_CMD_SHORTNAME(_ct), idstr);
			MessageBox(GetMainHwnd(), msg.Get(), __LOCALIZE("S&M - Error","sws_mbox"), MB_OK);
		}
	}
}
示例#21
0
static void SelectAllNearestEditCursor(COMMAND_T* ct, int val, int valhw, int relmode, HWND hwnd)
{
	SelectAllNearestEditCursor(0, &ct->user);
	Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ITEMS, -1);
}
示例#22
0
static void CycleThroughMidiLanes(COMMAND_T* ct, int val, int valhw, int relmode, HWND hwnd)
{
	CycleThroughMidiLanes(UNDO_STATE_ITEMS, &ct->user);
	Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ITEMS, -1);
}
示例#23
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);
}
示例#24
0
static void ShowOnlyTopCCLane(COMMAND_T* ct, int val, int valhw, int relmode, HWND hwnd)
{
	ShowOnlyTopCCLane(UNDO_STATE_ITEMS, &ct->user);
	Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ITEMS, -1);
}
示例#25
0
文件: BR_Tempo.cpp 项目: wolqws/sws
void TempoShapeSquare (COMMAND_T* ct)
{
	// Get tempo map
	BR_Envelope tempoMap (GetTempoEnv());
	if (!tempoMap.CountSelected())
		return;

	// Get splitting options
	double splitRatio;
	bool split = GetTempoShapeOptions(&splitRatio);

	// Loop through selected points and perform BPM calculations
	int skipped = 0;
	int count = tempoMap.Count()-1;
	for (int i = 0; i < tempoMap.CountSelected(); ++i)
	{
		int id = tempoMap.GetSelected(i);

		// Skip selected point if already square
		double t1, b1; int s1;
		tempoMap.GetPoint(id, &t1, &b1, &s1, NULL);
		if (s1 == SQUARE)
			continue;
		else
			s1 = SQUARE;

		// Get next point
		double b2; bool P2;
		if (id < count) // since we're creating points at the end of tempo map, check if dealing with the last point
			P2 = tempoMap.GetPoint(id+1, NULL, &b2, NULL, NULL);
		else
			P2 = false;

		// Get previous point
		double t0, b0; int s0;
		bool P0 = tempoMap.GetPoint(id-1, &t0, &b0, &s0, NULL);

		// Get new bpm of selected point
		double Nb1;
		if (P2 && b1 != b2)
			Nb1 = (b1+b2) / 2;
		else
			Nb1 = b1;

		// Check if new bpm is legal, if not, skip
		if (Nb1 < MIN_BPM || Nb1 > MAX_BPM)
			SKIP(skipped, 1);

		///// SET NEW SHAPE /////
		/////////////////////////

		// Create middle point(s) is needed
		if (P0 && s0 == LINEAR && P2 && Nb1 != b2)
		{
			// Get middle point's position and BPM
			double position, bpm = 120, measure = (b0+b1)*(t1-t0) / 480;
			FindMiddlePoint(&position, &bpm, measure, t0, t1, b0, Nb1);

			// Don't split middle point
			if (!split)
			{
				if (bpm<= MAX_BPM && bpm>=MIN_BPM && (position-t0)>=MIN_TEMPO_DIST && (t1-position)>=MIN_TEMPO_DIST)
					tempoMap.CreatePoint(tempoMap.Count(), position, bpm, LINEAR, 0, false);
				else
					SKIP(skipped, 1);
			}

			// Split middle point
			else
			{
				double position1, position2, bpm1, bpm2;
				SplitMiddlePoint (&position1, &position2, &bpm1, &bpm2, splitRatio, measure, t0, position, t1, b0, bpm, Nb1);

				if (bpm1>=MIN_BPM && bpm1<=MAX_BPM && bpm2>=MIN_BPM && bpm2<=MAX_BPM && (position1-t0)>=MIN_TEMPO_DIST && (position2-position1)>=MIN_TEMPO_DIST && (t1-position2)>=MIN_TEMPO_DIST)
				{
					tempoMap.CreatePoint(tempoMap.Count(), position1, bpm1, LINEAR, 0, false);
					tempoMap.CreatePoint(tempoMap.Count(), position2, bpm2, LINEAR, 0, false);
				}
				else
					SKIP(skipped, 1);
			}
		}

		// Change shape of the selected point
		tempoMap.SetPoint(id, NULL, &Nb1, &s1, NULL);
	}

	// Commit changes
	if (tempoMap.Commit())
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ALL, -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;
	}
}
示例#26
0
void GotoAnsSelectRegion(COMMAND_T* _ct) {
	if (GotoMarkerRegion(NULL, ((int)_ct->user)+1, SNM_REGION_MASK, true))
		Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(_ct), UNDO_STATE_ALL, -1);
}
示例#27
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);
}
示例#28
0
static void ApplyGrooveInMidiEditor(COMMAND_T* ct, int val, int valhw, int relmode, HWND hwnd)
{
	ApplyGrooveInMidiEditor(0, &ct->user);
	Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ITEMS, -1);
}
示例#29
0
// Import local files from m3u/pls playlists onto a new track
void PlaylistImport(COMMAND_T* ct)
{
	char cPath[256];
	vector<SPlaylistEntry> filelist;

	GetProjectPath(cPath, 256);
	string listpath = BrowseForFiles(__LOCALIZE("Import playlist","sws_mbox"), cPath, NULL, false, "Playlist files (*.m3u,*.pls)\0*.m3u;*.pls\0All Files (*.*)\0*.*\0");
	string ext = ParseFileExtension(listpath);

	// Decide what kind of playlist we have
	if(ext == "m3u")
	{
		ParseM3U(listpath, filelist);
	}
	else if(ext == "pls")
	{
		ParsePLS(listpath, filelist);
	}

	if(filelist.empty())
	{
		ShowMessageBox(__LOCALIZE("Failed to import playlist. No files found.","sws_mbox"), __LOCALIZE("Import playlist","sws_mbox"), 0);
		return;
	}

	// Validate files
	vector<string> badfiles;
	for(int i = 0, c = (int)filelist.size(); i < c; i++)
	{
		SPlaylistEntry e = filelist[i];
		if(!file_exists(e.path.c_str()))
		{
			badfiles.push_back(e.path);
		}
	}

	// If files can't be found, ask user what to do.
	bool includeMissing = false;
	if(!badfiles.empty())
	{
		stringstream ss;
		ss << __LOCALIZE("Cannot find some files. Create items anyway?\n","sws_mbox");

		unsigned int limit = min((int)badfiles.size(), 9); // avoid enormous messagebox
		for(unsigned int i = 0; i < limit; i++)
		{
			ss << "\n " << badfiles[i];
		}
		if(badfiles.size() > limit)
		{
			ss << "\n +" << badfiles.size() - limit << __LOCALIZE(" more files","sws_mbox");
		}

		switch(ShowMessageBox(ss.str().c_str(), __LOCALIZE("Import playlist","sws_mbox"), 3))
		{
		case 6 : // Yes
			includeMissing = true;
			break;

		case 7 : // No
			break;

		default :
			return;
		}
	}

	Undo_BeginBlock2(NULL);

	// Add new track
	int idx = GetNumTracks();
	int panMode = 5;		// Stereo pan
	double panLaw = 1.0;	// 0dB
	InsertTrackAtIndex(idx, false);
	MediaTrack *pTrack = GetTrack(NULL, idx);
	GetSetMediaTrackInfo(pTrack, "P_NAME", (void*) listpath.c_str());
	GetSetMediaTrackInfo(pTrack, "I_PANMODE", (void*) &panMode);
	GetSetMediaTrackInfo(pTrack, "D_PANLAW", (void*) &panLaw);
	SetOnlyTrackSelected(pTrack);

	// Add new items to track
	double pos = 0.0;
	for(int i = 0, c = (int)filelist.size(); i < c; i++)
	{
		SPlaylistEntry e = filelist[i];

		//TODO: Would be better if missing files were offline rather than just empty items.
		PCM_source *pSrc = PCM_Source_CreateFromFile(e.path.c_str());
		if(pSrc || includeMissing)
		{
			MediaItem *pItem = AddMediaItemToTrack(pTrack);
			if(pItem)
			{
				MediaItem_Take *pTake = AddTakeToMediaItem(pItem);
				if(pTake)
				{
					GetSetMediaItemTakeInfo(pTake, "P_SOURCE", pSrc);
					GetSetMediaItemTakeInfo(pTake, "P_NAME", (void*) e.title.c_str());
					SetMediaItemPosition(pItem, pos, false);
					SetMediaItemLength(pItem, e.length, false);
					pos += e.length;
				}
			}
		}
	}

	Undo_EndBlock2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ITEMS|UNDO_STATE_TRACKCFG);

	TrackList_AdjustWindows(false);
	UpdateTimeline();

	Main_OnCommand(40047, 0); // Build missing peaks
}