void ShowStartupActions(COMMAND_T* _ct) { WDL_FastString msg(__LOCALIZE("No project startup action is defined","sws_startup_action")); if (int cmdId = SNM_NamedCommandLookup(g_prjActions.Get()->Get())) 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("."); msg.Append("\r\n\r\n"); if (int cmdId = SNM_NamedCommandLookup(g_globalAction.Get())) { msg.AppendFormatted(512, __LOCALIZE_VERFMT("'%s' is defined as global startup action", "sws_startup_action"), kbd_getTextFromCmd(cmdId, NULL)); } else { msg.Append(__LOCALIZE("No global startup action is defined","sws_startup_action")); } msg.Append("."); MessageBox(GetMainHwnd(), msg.Get(), SWS_CMD_SHORTNAME(_ct), MB_OK); }
int PromptClearProjectStartupAction(bool _clear) { int r=0, cmdId=SNM_NamedCommandLookup(g_prjActions.Get()->Get()); if (cmdId) { WDL_FastString msg; msg.AppendFormatted(256, _clear ? __LOCALIZE_VERFMT("Are you sure you want to clear the current startup action: '%s'?","sws_mbox") : __LOCALIZE_VERFMT("Are you sure you want to replace the current startup action: '%s'?","sws_mbox"), kbd_getTextFromCmd(cmdId, NULL)); r = MessageBox(GetMainHwnd(), msg.Get(), __LOCALIZE("S&M - Confirmation","sws_mbox"), MB_YESNO); } return r; }
void SetProjectStartupAction(COMMAND_T* _ct) { if (PromptClearProjectStartupAction(false) == IDNO) return; char idstr[SNM_MAX_ACTION_CUSTID_LEN]; lstrcpyn(idstr, __LOCALIZE("Paste command ID or identifier string here","sws_mbox"), 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)) { msg.SetFormatted(256, __LOCALIZE_VERFMT("%s failed: unreliable command ID '%s'!","sws_DLG_161"), SWS_CMD_SHORTNAME(_ct), idstr); msg.Append("\n"); // localization note: msgs shared with the CA editor 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_mbox")); 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_mbox")); MessageBox(GetMainHwnd(), msg.Get(), __LOCALIZE("S&M - Error","sws_DLG_161"), MB_OK); } else { g_prjActions.Get()->Set(idstr); Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(_ct), UNDO_STATE_MISCCFG, -1); msg.SetFormatted(256, __LOCALIZE_VERFMT("'%s' is defined as project startup action","sws_mbox"), kbd_getTextFromCmd(cmdId, NULL)); char prjFn[SNM_MAX_PATH] = ""; EnumProjects(-1, prjFn, sizeof(prjFn)); if (*prjFn) { msg.Append("\n"); msg.AppendFormatted(SNM_MAX_PATH, __LOCALIZE_VERFMT("for %s","sws_mbox"), prjFn); } msg.Append("."); MessageBox(GetMainHwnd(), msg.Get(), SWS_CMD_SHORTNAME(_ct), MB_OK); } } else { msg.SetFormatted(256, __LOCALIZE_VERFMT("%s failed: command ID or identifier string '%s' not found in the 'Main' section of the action list!","sws_DLG_161"), SWS_CMD_SHORTNAME(_ct), idstr); MessageBox(GetMainHwnd(), msg.Get(), __LOCALIZE("S&M - Error","sws_DLG_161"), MB_OK); } } }
// return true for successful analysis // wraps AnalyzePCM to check item validity and create a wait dialog bool AnalyzeItem(MediaItem* mi, ANALYZE_PCM* a) { a->dProgress = 0.0; a->pcm = (PCM_source*)mi; if (!a->pcm || strcmp(a->pcm->GetType(), "MIDI") == 0 || strcmp(a->pcm->GetType(), "MIDIPOOL") == 0) return false; a->pcm = a->pcm->Duplicate(); if (!a->pcm || !a->pcm->GetNumChannels()) return false; double dZero = 0.0; GetSetMediaItemInfo((MediaItem*)a->pcm, "D_POSITION", &dZero); const char* cName = NULL; MediaItem_Take* take = GetMediaItemTake(mi, -1); if (take) cName = (const char*)GetSetMediaItemTakeInfo(take, "P_NAME", NULL); CreateThread(NULL, 0, AnalyzePCMThread, a, 0, NULL); WDL_String title; title.AppendFormatted(100, __LOCALIZE_VERFMT("Please wait, analyzing %s...","sws_analysis"), cName ? cName : __LOCALIZE("item","sws_analysis")); SWS_WaitDlg wait(title.Get(), &a->dProgress); delete a->pcm; return true; }
// Return TRUE on delete send bool ResolveMissingRecv(MediaTrack* tr, int iSend, TrackSend* ts, WDL_PtrList<TrackSendFix>* pFix) { WDL_FastString str; char* cName = (char*)GetSetMediaTrackInfo(tr, "P_NAME", NULL); if (!cName || !cName[0]) cName = (char*)__LOCALIZE("(unnamed)","sws_DLG_114"); str.SetFormatted(200, __LOCALIZE_VERFMT("Send %d on track %d \"%s\" is missing its receive track!","sws_DLG_114"), iSend+1, CSurf_TrackToID(tr, false), cName); g_cErrorStr = str.Get(); g_ts = ts; g_send = tr; g_recv = NULL; DialogBox(g_hInst, MAKEINTRESOURCE(IDD_RECVMISSING), g_hwndParent, doResolve); if (g_iResolveRet == 1) return true; else if (g_iResolveRet == 2) { GUID* newGuid = (GUID*)GetSetMediaTrackInfo(g_recv, "GUID", NULL); if (pFix) pFix->Add(new TrackSendFix(ts->GetGuid(), newGuid)); ts->SetGuid(newGuid); } return false; }
HMENU SWS_TrackListWnd::OnContextMenu(int x, int y, bool* wantDefaultItems) { HMENU contextMenu = CreatePopupMenu(); AddToMenu(contextMenu, __LOCALIZE("Snapshot current track visibility","tracklistmenu"), SWSGetCommandID(NewVisSnapshot)); Snapshot* s; int i = 0; while((s = GetSnapshotPtr(i++)) != NULL) { if (s->m_iMask == VIS_MASK) { char cMenu[50]; int iCmd = SWSGetCommandID(GetSnapshot, s->m_iSlot); if (!iCmd) iCmd = LOADSNAP_MSG + s->m_iSlot; _snprintf(cMenu, 50, __LOCALIZE_VERFMT("Recall snapshot %s","tracklistmenu"), s->m_cName); AddToMenu(contextMenu, cMenu, iCmd); } } AddToMenu(contextMenu, __LOCALIZE("Show all tracks","tracklistmenu"), SWSGetCommandID(ShowAll)); AddToMenu(contextMenu, __LOCALIZE("Show SWS Snapshots","tracklistmenu"), SWSGetCommandID(OpenSnapshotsDialog)); SWS_ListItem* item = m_pLists.Get(0)->GetHitItem(x, y, NULL); if (item) { m_trLastTouched = (MediaTrack*)item; AddToMenu(contextMenu, SWS_SEPARATOR, 0); AddToMenu(contextMenu, __LOCALIZE("Rename","tracklistmenu"), RENAME_MSG); AddToMenu(contextMenu, SWS_SEPARATOR, 0); AddToMenu(contextMenu, __LOCALIZE("Show only in MCP","tracklistmenu"), SWSGetCommandID(ShowInMCPOnly)); AddToMenu(contextMenu, __LOCALIZE("Show only in TCP","tracklistmenu"), SWSGetCommandID(ShowInTCPOnly)); AddToMenu(contextMenu, __LOCALIZE("Show in both MCP and TCP","tracklistmenu"), SWSGetCommandID(ShowInMCPandTCP)); AddToMenu(contextMenu, __LOCALIZE("Hide in both MCP and TCP","tracklistmenu"), SWSGetCommandID(HideTracks)); AddToMenu(contextMenu, SWS_SEPARATOR, 0); AddToMenu(contextMenu, __LOCALIZE("Invert selection","tracklistmenu"), SWSGetCommandID(TogTrackSel)); AddToMenu(contextMenu, __LOCALIZE("Hide unselected","tracklistmenu"), SWSGetCommandID(HideUnSel)); HMENU fxSubMenu; if(AddFXSubMenu(&fxSubMenu, m_trLastTouched)) { AddToMenu(contextMenu, SWS_SEPARATOR, 0); AddSubMenu(contextMenu, fxSubMenu, __LOCALIZE("FX","tracklistmenu")); } // Check current state switch(GetTrackVis(m_trLastTouched)) { case 0: CheckMenuItem(contextMenu, SWSGetCommandID(HideTracks), MF_BYCOMMAND | MF_CHECKED); break; case 1: CheckMenuItem(contextMenu, SWSGetCommandID(ShowInMCPOnly), MF_BYCOMMAND | MF_CHECKED); break; case 2: CheckMenuItem(contextMenu, SWSGetCommandID(ShowInTCPOnly), MF_BYCOMMAND | MF_CHECKED); break; case 3: CheckMenuItem(contextMenu, SWSGetCommandID(ShowInMCPandTCP), MF_BYCOMMAND | MF_CHECKED); break; } } return contextMenu; }
void DoAnalyzeItem(COMMAND_T*) { WDL_TypedBuf<MediaItem*> items; SWS_GetSelectedMediaItems(&items); bool bDidWork = false; for (int i = 0; i < items.GetSize(); i++) { MediaItem* mi = items.Get()[i]; int iChannels = ((PCM_source*)mi)->GetNumChannels(); if (iChannels) { bDidWork = true; ANALYZE_PCM a; memset(&a, 0, sizeof(a)); a.iChannels = iChannels; a.dPeakVals = new double[iChannels]; a.dRMSs = new double[iChannels]; if (AnalyzeItem(mi, &a)) { WDL_String str; str.Set(__LOCALIZE("Peak level:","sws_analysis")); for (int i = 0; i < iChannels; i++) { str.Append(" "); str.AppendFormatted(50, __LOCALIZE_VERFMT("Channel %d = %.2f dB","sws_analysis"), i+1, VAL2DB(a.dPeakVals[i])); } str.Append("\n"); str.Append(__LOCALIZE("RMS level:","sws_analysis")); for (int i = 0; i < iChannels; i++) { str.Append(" "); str.AppendFormatted(50, __LOCALIZE_VERFMT("Channel %d = %.2f dB","sws_analysis"), i+1, VAL2DB(a.dRMSs[i])); } MessageBox(g_hwndParent, str.Get(), __LOCALIZE("Item analysis","sws_analysis"), MB_OK); } delete [] a.dPeakVals; delete [] a.dRMSs; } } if (!bDidWork) { MessageBox(NULL, __LOCALIZE("No items selected to analyze.","sws_analysis"), __LOCALIZE("SWS - Error","sws_analysis"), MB_OK); return; } }
void TrackCustomColor(int iCustColor) { COLORREF cr; UpdateCustomColors(); cr = g_custColors[iCustColor] | 0x1000000; for (int i = 0; i <= GetNumTracks(); i++) { MediaTrack* tr = CSurf_TrackFromID(i, false); if (*(int*)GetSetMediaTrackInfo(tr, "I_SELECTED", NULL)) GetSetMediaTrackInfo(tr, "I_CUSTOMCOLOR", &cr); } char cUndoText[100]; sprintf(cUndoText, __LOCALIZE_VERFMT("Set track(s) to custom color %d","sws_undo"), iCustColor+1); Undo_OnStateChangeEx(cUndoText, UNDO_STATE_TRACKCFG, -1); }
int PromptClearStartupAction(int _type, bool _clear) { int r=0, cmdId=SNM_NamedCommandLookup(_type ? g_globalAction.Get() : g_prjActions.Get()->Get()); if (cmdId) { WDL_FastString msg; if (!_type) { msg.AppendFormatted(512, _clear ? __LOCALIZE_VERFMT("Are you sure you want to clear the project startup action: '%s'?","sws_startup_action") : __LOCALIZE_VERFMT("Are you sure you want to replace the project startup action: '%s'?","sws_startup_action"), kbd_getTextFromCmd(cmdId, NULL)); } else { msg.AppendFormatted(512, _clear ? __LOCALIZE_VERFMT("Are you sure you want to clear the global startup action: '%s'?","sws_startup_action") : __LOCALIZE_VERFMT("Are you sure you want to replace the global startup action: '%s'?","sws_startup_action"), kbd_getTextFromCmd(cmdId, NULL)); } r = MessageBox(GetMainHwnd(), msg.Get(), __LOCALIZE("S&M - Confirmation","sws_mbox"), MB_YESNO); } return r; }
static int GetLoadCommandID(int iSlot, bool bCreateNew) { static int iLastRegistered = 0; if (iSlot > iLastRegistered && bCreateNew) { char cID[BUFFER_SIZE]; char cDesc[BUFFER_SIZE]; _snprintf(cID, BUFFER_SIZE, "SWS_OPENRELATED%d", iSlot+1); _snprintf(cDesc, BUFFER_SIZE, __LOCALIZE_VERFMT("SWS: Open related project %d","sws_actions"), iSlot+1); iLastRegistered = iSlot; return SWSRegisterCommandExt(OpenRelatedProject, cID, cDesc, iSlot, false); } return SWSGetCommandID(OpenRelatedProject, iSlot); }
void UpdateOpenProjectTabActions() { // Add more actions for project tabs if > 10 static int iActions = 10; int iProjs = iActions-1; while (EnumProjects(++iProjs, NULL, 0)); if (iProjs > iActions) for (; iActions < iProjs; iActions++) { char cID[BUFFER_SIZE]; char cDesc[BUFFER_SIZE]; _snprintf(cID, BUFFER_SIZE, "SWS_PROJTAB%d", iActions+1); _snprintf(cDesc, BUFFER_SIZE, __LOCALIZE_VERFMT("SWS: Switch to project tab %d","sws_actions"), iActions+1); SWSRegisterCommandExt(OpenProjectTab, cID, cDesc, iActions, false); } }
void ItemCustomColor(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)) GetSetMediaItemInfo(mi, "I_CUSTOMCOLOR", &cr); } } char cUndoText[100]; sprintf(cUndoText, __LOCALIZE_VERFMT("Set item(s) to custom color %d","sws_undo"), iCustColor+1); Undo_OnStateChange(cUndoText); UpdateTimeline(); }
void RestoreSelTrackSelItems(int iSlot) { 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)->Restore(tr, iSlot); break; } } } PreventUIRefresh(-1); char cUndoText[256]; sprintf(cUndoText, __LOCALIZE_VERFMT("Restore selected track(s) selected item(s), slot %d","sws_undo"), iSlot+1); Undo_OnStateChangeEx(cUndoText, UNDO_STATE_ITEMS, -1); UpdateArrange(); }
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; } }
INT_PTR WINAPI doColorDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { #ifndef _WIN32 static int iSettingColor = -1; #endif if (INT_PTR r = SNM_HookThemeColorsMessage(hwndDlg, uMsg, wParam, lParam)) return r; switch (uMsg) { case WM_INITDIALOG: UpdateCustomColors(); RestoreWindowPos(hwndDlg, COLORDLG_WINDOWPOS_KEY, false); return 0; case WM_DRAWITEM: { LPDRAWITEMSTRUCT pDI = (LPDRAWITEMSTRUCT)lParam; HBRUSH hb = NULL; switch (pDI->CtlID) { case IDC_COLOR1: hb = CreateSolidBrush(g_crGradStart); break; case IDC_COLOR2: hb = CreateSolidBrush(g_crGradEnd); break; } FillRect(pDI->hDC, &pDI->rcItem, hb); DeleteObject(hb); return 1; } #ifndef _WIN32 case WM_TIMER: { COLORREF cr; if (iSettingColor != -1 && GetChosenColor(&cr)) { switch (iSettingColor) { case 0: g_crGradStart = cr; break; case 1: g_crGradEnd = cr; break; case 2: UpdateCustomColors(); break; } PersistColors(); InvalidateRect(hwndDlg, NULL, 0); KillTimer(hwndDlg, 1); iSettingColor = -1; } break; } #endif case WM_COMMAND: { wParam = LOWORD(wParam); switch(wParam) { case IDC_COLOR1: case IDC_COLOR2: case IDC_SETCUST: { #ifdef _WIN32 CHOOSECOLOR cc; memset(&cc, 0, sizeof(CHOOSECOLOR)); cc.lStructSize = sizeof(CHOOSECOLOR); cc.hwndOwner = hwndDlg; cc.lpCustColors = g_custColors; cc.Flags = CC_FULLOPEN | CC_RGBINIT; if (wParam == IDC_COLOR1) { cc.rgbResult = g_crGradStart; if (ChooseColor(&cc)) { g_crGradStart = cc.rgbResult; PersistColors(); RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } } else if (wParam == IDC_COLOR2) { cc.rgbResult = g_crGradEnd; if (ChooseColor(&cc)) { g_crGradEnd = cc.rgbResult; PersistColors(); RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } } else if (wParam == IDC_SETCUST && ChooseColor(&cc)) PersistColors(); #else switch(wParam) { case IDC_COLOR1: iSettingColor = 0; ShowColorChooser(g_crGradStart); break; case IDC_COLOR2: iSettingColor = 1; ShowColorChooser(g_crGradEnd); break; case IDC_SETCUST: iSettingColor = 2; ShowColorChooser(g_custColors[0]); break; } SetTimer(hwndDlg, 1, 50, NULL); #endif break; } case IDC_SAVECOL: case IDC_LOADCOL: case IDC_LOADFROMTHEME: { char cPath[512] = { 0 }; const char* cExt = "SWS Color Files (*.SWSColor)\0*.SWSColor\0Color Theme Files (*.ReaperTheme)\0*.ReaperTheme\0All Files\0*.*\0"; GetPrivateProfileString("REAPER", "lastthemefn", "", cPath, 512, get_ini_file()); char* pC = strrchr(cPath, PATH_SLASH_CHAR); if (pC) *pC = 0; if (wParam == IDC_SAVECOL) { char cFilename[512]; UpdateCustomColors(); if (BrowseForSaveFile(__LOCALIZE("Save color theme","sws_color"), cPath, NULL, cExt, cFilename, 512)) { char key[32]; char val[32]; for (int i = 0; i < 16; i++) { sprintf(key, "custcolor%d", i+1); sprintf(val, "%d", g_custColors[i]); WritePrivateProfileString("SWS Color", key, val, cFilename); } sprintf(val, "%d", g_crGradStart); WritePrivateProfileString("SWS Color", "gradientStart", val, cFilename); sprintf(val, "%d", g_crGradEnd); WritePrivateProfileString("SWS Color", "gradientEnd", val, cFilename); } } else if (wParam == IDC_LOADCOL || wParam == IDC_LOADFROMTHEME) { #ifndef _WIN32 if (MessageBox(hwndDlg, __LOCALIZE("WARNING: Loading colors from file will overwrite your global personalized color choices.\nIf these are important to you, press press cancel to abort the loading of new colors!","sws_color"), __LOCALIZE("OSX Color Load WARNING","sws_color"), MB_OKCANCEL) == IDCANCEL) break; #endif if (wParam == IDC_LOADCOL) { char* cFile = BrowseForFiles(__LOCALIZE("Choose color theme file","sws_color"), cPath, NULL, false, cExt); if (cFile) { lstrcpyn(cPath, cFile, 512); free(cFile); } else cPath[0] = 0; } else GetPrivateProfileString("REAPER", "lastthemefn", "", cPath, 512, get_ini_file()); if (cPath[0]) { char key[32]; bool bFound = false; for (int i = 0; i < 16; i++) { sprintf(key, "custcolor%d", i+1); int iColor = GetPrivateProfileInt("SWS Color", key, -1, cPath); if (iColor != -1) { g_custColors[i] = iColor; bFound = true; } } if (!bFound) { char cMsg[512]; _snprintf(cMsg, 512, __LOCALIZE_VERFMT("No SWS custom colors found in %s.","sws_color"), cPath); MessageBox(hwndDlg, cMsg, __LOCALIZE("SWS Color Load","sws_color"), MB_OK); } g_crGradStart = GetPrivateProfileInt("SWS Color", "gradientStart", g_crGradStart, cPath); g_crGradEnd = GetPrivateProfileInt("SWS Color", "gradientEnd", g_crGradEnd, cPath); PersistColors(); #ifdef _WIN32 RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); #else InvalidateRect(hwndDlg, NULL, 0); #endif } } } break; case IDOK: // Do something ? // fall through! case IDCANCEL: #ifndef _WIN32 if (iSettingColor != -1) { HideColorChooser(); KillTimer(hwndDlg, 1); } #endif SaveWindowPos(hwndDlg, COLORDLG_WINDOWPOS_KEY); EndDialog(hwndDlg,0); break; } return 0; } } return 0; }
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; } }
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; } }
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; } }
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; } }
// _type: 0=Post-Fader (Post-Pan), 1=Pre-FX, 2=deprecated, 3=Pre-Fader (Post-FX) // _undoMsg: NULL=no undo bool CueBuss(const char* _undoMsg, const char* _busName, int _type, bool _showRouting, int _soloDefeat, char* _trTemplatePath, bool _sendToMaster, int* _hwOuts) { if (!SNM_CountSelectedTracks(NULL, false)) return false; WDL_FastString tmplt; if (_trTemplatePath && (!FileOrDirExists(_trTemplatePath) || !LoadChunk(_trTemplatePath, &tmplt) || !tmplt.GetLength())) { char msg[SNM_MAX_PATH] = ""; lstrcpyn(msg, __LOCALIZE("Cue buss not created!\nNo track template file defined","sws_DLG_149"), sizeof(msg)); if (*_trTemplatePath) _snprintfSafe(msg, sizeof(msg), __LOCALIZE_VERFMT("Cue buss not created!\nTrack template not found (or empty): %s","sws_DLG_149"), _trTemplatePath); MessageBox(GetMainHwnd(), msg, __LOCALIZE("S&M - Error","sws_DLG_149"), MB_OK); return false; } bool updated = false; MediaTrack * cueTr = NULL; SNM_SendPatcher* p = NULL; for (int i=1; i <= GetNumTracks(); i++) // skip master { MediaTrack* tr = CSurf_TrackFromID(i, false); if (tr && *(int*)GetSetMediaTrackInfo(tr, "I_SELECTED", NULL)) { GetSetMediaTrackInfo(tr, "I_SELECTED", &g_i0); // add the buss track, done once! if (!cueTr) { InsertTrackAtIndex(GetNumTracks(), false); TrackList_AdjustWindows(false); cueTr = CSurf_TrackFromID(GetNumTracks(), false); GetSetMediaTrackInfo(cueTr, "P_NAME", (void*)_busName); p = new SNM_SendPatcher(cueTr); if (tmplt.GetLength()) { WDL_FastString chunk; MakeSingleTrackTemplateChunk(&tmplt, &chunk, true, true, false); ApplyTrackTemplate(cueTr, &chunk, false, false, p); } updated = true; } // add a send if (cueTr && p && tr != cueTr) AddReceiveWithVolPan(tr, cueTr, _type, p); } } if (cueTr && p) { // send to master/parent init if (!tmplt.GetLength()) { // solo defeat if (_soloDefeat) { char one[2] = "1"; updated |= (p->ParsePatch(SNM_SET_CHUNK_CHAR, 1, "TRACK", "MUTESOLO", 0, 3, one) > 0); } // master/parend send WDL_FastString mainSend; mainSend.SetFormatted(SNM_MAX_CHUNK_LINE_LENGTH, "MAINSEND %d 0", _sendToMaster?1:0); // adds hw outputs if (_hwOuts) { int monoHWCount=0; while (GetOutputChannelName(monoHWCount)) monoHWCount++; bool cr = false; for(int i=0; i<SNM_MAX_HW_OUTS; i++) { if (_hwOuts[i]) { if (!cr) { mainSend.Append("\n"); cr = true; } if (_hwOuts[i] >= monoHWCount) mainSend.AppendFormatted(32, "HWOUT %d ", (_hwOuts[i]-monoHWCount) | 1024); else mainSend.AppendFormatted(32, "HWOUT %d ", _hwOuts[i]-1); mainSend.Append("0 "); mainSend.AppendFormatted(20, "%.14f ", *(double*)GetConfigVar("defhwvol")); mainSend.Append("0.00000000000000 0 0 0 -1.00000000000000 -1\n"); } } if (!cr) mainSend.Append("\n"); // hot } // patch both updates (no break keyword here: new empty track) updated |= p->ReplaceLine("TRACK", "MAINSEND", 1, 0, mainSend.Get()); } p->Commit(); delete p; if (updated) { GetSetMediaTrackInfo(cueTr, "I_SELECTED", &g_i1); UpdateTimeline(); ScrollSelTrack(true, true); if (_showRouting) Main_OnCommand(40293, 0); if (_undoMsg) Undo_OnStateChangeEx2(NULL, _undoMsg, UNDO_STATE_ALL, -1); } } return updated; }