void SaveCueBusIniFile(int _confId, const char* _busName, int _type, bool _trTemplate, const char* _trTemplatePath, bool _showRouting, int _soloDefeat, bool _sendToMaster, int* _hwOuts) { if (_confId>=0 && _confId<SNM_MAX_CUE_BUSS_CONFS && _busName && _trTemplatePath && _hwOuts) { char iniSection[64]=""; if (_snprintfStrict(iniSection, sizeof(iniSection), "CueBuss%d", _confId+1) > 0) { char buf[16]="", slot[16]=""; WDL_FastString escapedStr; escapedStr.SetFormatted(256, "\"%s\"", _busName); WritePrivateProfileString(iniSection,"name",escapedStr.Get(),g_SNM_IniFn.Get()); if (_snprintfStrict(buf, sizeof(buf), "%d" ,_type) > 0) WritePrivateProfileString(iniSection,"reatype",buf,g_SNM_IniFn.Get()); WritePrivateProfileString(iniSection,"track_template_enabled",_trTemplate ? "1" : "0",g_SNM_IniFn.Get()); escapedStr.SetFormatted(SNM_MAX_PATH, "\"%s\"", _trTemplatePath); WritePrivateProfileString(iniSection,"track_template_path",escapedStr.Get(),g_SNM_IniFn.Get()); WritePrivateProfileString(iniSection,"show_routing",_showRouting ? "1" : "0",g_SNM_IniFn.Get()); WritePrivateProfileString(iniSection,"send_to_masterparent",_sendToMaster ? "1" : "0",g_SNM_IniFn.Get()); if (_snprintfStrict(buf, sizeof(buf), "%d", _soloDefeat) > 0) WritePrivateProfileString(iniSection,"solo_defeat",buf,g_SNM_IniFn.Get()); for (int i=0; i<SNM_MAX_HW_OUTS; i++) if (_snprintfStrict(slot, sizeof(slot), "hwout%d", i+1) > 0 && _snprintfStrict(buf, sizeof(buf), "%d", _hwOuts[i]) > 0) WritePrivateProfileString(iniSection,slot,_hwOuts[i]?buf:NULL,g_SNM_IniFn.Get()); } } }
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 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; }
// appends _tr's state to _chunkOut //JFB TODO: save envs with beat position info (like it is done for items) void SaveSingleTrackTemplateChunk(MediaTrack* _tr, WDL_FastString* _chunkOut, bool _delItems, bool _delEnvs) { if (_tr && _chunkOut) { SNM_TrackEnvParserPatcher p(_tr, false); // no auto-commit! if (_delEnvs) p.RemoveEnvelopes(); // systematically remove items whatever is _delItems, then // replace them with items + optional beat pos info, if !_delItems (i.e. mimic native templates) p.RemoveSubChunk("ITEM", 2, -1); _chunkOut->Append(p.GetChunk()->Get()); if (!_delItems) { double d; WDL_FastString beatInfo; for (int i=0; i<GetTrackNumMediaItems(_tr); i++) { if (MediaItem* item = GetTrackMediaItem(_tr, i)) { SNM_ChunkParserPatcher pitem(item, false); // no auto-commit! int posChunk = pitem.GetLinePos(1, "ITEM", "POSITION", 1, 0); // look for the *next* line if (--posChunk>=0) { // --posChunk to zap "\n" TimeMap2_timeToBeats(NULL, *(double*)GetSetMediaItemInfo(item, "D_POSITION", NULL), NULL, NULL, &d, NULL); beatInfo.SetFormatted(32, " %.14f", d); pitem.GetChunk()->Insert(beatInfo.Get(), posChunk); } posChunk = pitem.GetLinePos(1, "ITEM", "SNAPOFFS", 1, 0); if (--posChunk>=0) { TimeMap2_timeToBeats(NULL, *(double*)GetSetMediaItemInfo(item, "D_SNAPOFFSET", NULL), NULL, NULL, &d, NULL); beatInfo.SetFormatted(32, " %.14f", d); pitem.GetChunk()->Insert(beatInfo.Get(), posChunk); } posChunk = pitem.GetLinePos(1, "ITEM", "LENGTH", 1, 0); if (--posChunk>=0) { TimeMap2_timeToBeats(NULL, *(double*)GetSetMediaItemInfo(item, "D_LENGTH", NULL), NULL, NULL, &d, NULL); beatInfo.SetFormatted(32, " %.14f", d); pitem.GetChunk()->Insert(beatInfo.Get(), posChunk); } _chunkOut->Insert(pitem.GetChunk(), _chunkOut->GetLength()-2); // -2: before ">\n" } } } } }
void FillHWoutDropDown(HWND _hwnd, int _idc) { char buf[128] = ""; lstrcpyn(buf, __LOCALIZE("None","sws_DLG_149"), sizeof(buf)); SendDlgItemMessage(_hwnd,_idc,CB_ADDSTRING,0,(LPARAM)buf); SendDlgItemMessage(_hwnd,_idc,CB_SETITEMDATA,0,0); // get mono outputs WDL_PtrList<WDL_FastString> monos; int monoIdx=0; while (GetOutputChannelName(monoIdx)) { monos.Add(new WDL_FastString(GetOutputChannelName(monoIdx))); monoIdx++; } // add stereo outputs WDL_PtrList<WDL_FastString> stereos; if (monoIdx) { for(int i=0; i < (monoIdx-1); i++) { WDL_FastString* hw = new WDL_FastString(); hw->SetFormatted(256, "%s / %s", monos.Get(i)->Get(), monos.Get(i+1)->Get()); stereos.Add(hw); } } // fill dropdown for(int i=0; i < stereos.GetSize(); i++) { SendDlgItemMessage(_hwnd,_idc,CB_ADDSTRING,0,(LPARAM)stereos.Get(i)->Get()); SendDlgItemMessage(_hwnd,_idc,CB_SETITEMDATA,i,i+1); // +1 for <none> } for(int i=0; i < monos.GetSize(); i++) { SendDlgItemMessage(_hwnd,_idc,CB_ADDSTRING,0,(LPARAM)monos.Get(i)->Get()); SendDlgItemMessage(_hwnd,_idc,CB_SETITEMDATA,i,i+1); // +1 for <none> } // SendDlgItemMessage(_hwnd,_idc,CB_SETCURSEL,x0,0); monos.Empty(true); stereos.Empty(true); }
bool GetMarkerRegionDesc(const char* _name, bool _isrgn, int _num, double _pos, double _end, int _flags, bool _wantNum, bool _wantName, bool _wantTime, char* _descOut, int _outSz) { if (_descOut && _outSz && ((_isrgn && _flags&SNM_REGION_MASK) || (!_isrgn && _flags&SNM_MARKER_MASK))) { WDL_FastString desc; bool comma = !_wantNum; if (_wantNum) desc.SetFormatted(64, "%d", _num); if (_wantName && _name && *_name) { if (!comma) { desc.Append(": "); comma = true; } desc.Append(_name); } if (_wantTime) { if (!comma) { desc.Append(": "); comma = true; } char timeStr[64] = ""; format_timestr_pos(_pos, timeStr, sizeof(timeStr), -1); desc.Append(" ["); desc.Append(timeStr); if (_isrgn) { desc.Append(" -> "); format_timestr_pos(_end, timeStr, sizeof(timeStr), -1); desc.Append(timeStr); } desc.Append("]"); } lstrcpyn(_descOut, desc.Get(), _outSz); return true; } return 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; }
// supports folders, multi-selection and routings between tracks too void SaveSelTrackTemplates(bool _delItems, bool _delEnvs, WDL_FastString* _chunkOut) { if (!_chunkOut) return; WDL_PtrList<MediaTrack> tracks; // append selected track chunks (+ folders) ------------------------------- for (int i=0; i <= GetNumTracks(); i++) // incl. master { MediaTrack* tr = CSurf_TrackFromID(i, false); if (tr && *(int*)GetSetMediaTrackInfo(tr, "I_SELECTED", NULL)) { SaveSingleTrackTemplateChunk(tr, _chunkOut, _delItems, _delEnvs); tracks.Add(tr); // folder: save child templates WDL_PtrList<MediaTrack>* childTracks = GetChildTracks(tr); if (childTracks) { for (int j=0; j < childTracks->GetSize(); j++) { SaveSingleTrackTemplateChunk(childTracks->Get(j), _chunkOut, _delItems, _delEnvs); tracks.Add(childTracks->Get(j)); } i += childTracks->GetSize(); // skip children delete childTracks; } } } // update receives ids ---------------------------------------------------- // no break keyword used here: multiple tracks in the template SNM_ChunkParserPatcher p(_chunkOut); WDL_FastString line; int occurence = 0; int pos = p.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "TRACK", "AUXRECV", occurence, 1, &line); while (pos > 0) { pos--; // see SNM_ChunkParserPatcher bool replaced = false; line.SetLen(line.GetLength()-1); // remove trailing '\n' LineParser lp(false); if (!lp.parse(line.Get()) && lp.getnumtokens() > 1) { int success, curId = lp.gettoken_int(1, &success); if (success) { MediaTrack* tr = CSurf_TrackFromID(curId+1, false); int newId = tracks.Find(tr); if (newId >= 0) { const char* p3rdTokenToEol = strchr(line.Get(), ' '); if (p3rdTokenToEol) p3rdTokenToEol = strchr((char*)(p3rdTokenToEol+1), ' '); if (p3rdTokenToEol) { WDL_FastString newRcv; newRcv.SetFormatted(SNM_MAX_CHUNK_LINE_LENGTH, "AUXRECV %d%s\n", newId, p3rdTokenToEol); replaced = p.ReplaceLine(pos, newRcv.Get()); if (replaced) occurence++; } } } } if (!replaced) replaced = p.ReplaceLine(pos, ""); if (!replaced) // skip, just in case.. occurence++; line.Set(""); pos = p.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "TRACK", "AUXRECV", occurence, 1, &line); } }