// When trying to play a note using this plugin, but no instrument is assigned to it, // the user is asked whether a new instrument should be added. bool CAbstractVstEditor::ValidateCurrentInstrument() //-------------------------------------------------- { if (!CheckInstrument(m_nInstrument)) m_nInstrument = GetBestInstrumentCandidate(); //only show messagebox if plug is able to process notes. if(m_nInstrument < 0) { if(m_pVstPlugin->CanRecieveMidiEvents()) { CModDoc *pModDoc = m_pVstPlugin->GetModDoc(); if(pModDoc == nullptr) return false; if(!m_pVstPlugin->isInstrument() || pModDoc->GetSoundFile()->GetModSpecifications().instrumentsMax == 0 || AfxMessageBox(_T("You need to assign an instrument to this plugin before you can play notes from here.\nCreate a new instrument and assign this plugin to the instrument?"), MB_YESNO | MB_ICONQUESTION) == IDNO) { return false; } else { return CreateInstrument(); } } else { // Can't process notes return false; } } else { return true; } }
void CAbstractVstEditor::OnToggleEditor(UINT nID) { CModDoc* pModDoc = m_pVstPlugin->GetModDoc(); if (pModDoc) { pModDoc->TogglePluginEditor(nID-ID_PLUGSELECT); } }
void CAbstractVstEditor::UpdateInputMenu() { CMenu* pInfoMenu = m_pMenu->GetSubMenu(2); pInfoMenu->DeleteMenu(0, MF_BYPOSITION); CModDoc* pModDoc = m_pVstPlugin->GetModDoc(); module_renderer* pSndFile = pModDoc->GetSoundFile(); if (m_pInputMenu->m_hMenu) { m_pInputMenu->DestroyMenu(); } if (!m_pInputMenu->m_hMenu) { m_pInputMenu->CreatePopupMenu(); } CString name; CArray<CVstPlugin*, CVstPlugin*> inputPlugs; m_pVstPlugin->GetInputPlugList(inputPlugs); for (int nPlug=0; nPlug<inputPlugs.GetSize(); nPlug++) { name.Format("FX%02d: %s", inputPlugs[nPlug]->m_nSlot+1, inputPlugs[nPlug]->m_pMixStruct->Info.szName); m_pInputMenu->AppendMenu(MF_STRING, ID_PLUGSELECT+inputPlugs[nPlug]->m_nSlot, name); } CArray<UINT, UINT> inputChannels; m_pVstPlugin->GetInputChannelList(inputChannels); for (int nChn=0; nChn<inputChannels.GetSize(); nChn++) { if (nChn==0 && inputPlugs.GetSize()) { m_pInputMenu->AppendMenu(MF_SEPARATOR); } name.Format("Chn%02d: %s", inputChannels[nChn]+1, pSndFile->ChnSettings[inputChannels[nChn]].szName); m_pInputMenu->AppendMenu(MF_STRING, NULL, name); } CArray<UINT, UINT> inputInstruments; m_pVstPlugin->GetInputInstrumentList(inputInstruments); bool checked; for (int nIns=0; nIns<inputInstruments.GetSize(); nIns++) { checked=false; if (nIns==0 && (inputPlugs.GetSize() || inputChannels.GetSize())) { m_pInputMenu->AppendMenu(MF_SEPARATOR); } name.Format("Ins%02d: %s", inputInstruments[nIns], (LPCTSTR)pSndFile->GetInstrumentName(inputInstruments[nIns])); if (inputInstruments[nIns] == (UINT)m_nInstrument) checked=true; m_pInputMenu->AppendMenu(MF_STRING|(checked?MF_CHECKED:0), ID_SELECTINST+inputInstruments[nIns], name); } if ((inputPlugs.GetSize() == 0) && (inputChannels.GetSize() == 0) && (inputInstruments.GetSize() == 0)) { m_pInputMenu->AppendMenu(MF_STRING|MF_GRAYED, NULL, "None"); } pInfoMenu->InsertMenu(0, MF_BYPOSITION|MF_POPUP, (UINT)m_pInputMenu->m_hMenu, "I&nputs"); }
void CChildFrame::ActivateFrame(int nCmdShow) //------------------------------------------- { if ((glMdiOpenCount == 1) && (CMainFrame::gbMdiMaximize) && (nCmdShow == -1)) { nCmdShow = SW_SHOWMAXIMIZED; } CMDIChildWnd::ActivateFrame(nCmdShow); //rewbs.fix3185: When song first loads, initialise patternViewState // to point to start of song. CView *pView = GetActiveView(); CModDoc *pModDoc = NULL; if (pView) pModDoc = (CModDoc *)pView->GetDocument(); if ((m_hWndCtrl) && (pModDoc)) { if (m_bInitialActivation && m_ViewPatterns.nPattern==0) { m_ViewPatterns.nPattern=pModDoc->GetSoundFile()->Order[0]; m_ViewPatterns.nOrder=0; //just in case (should already be 0) m_ViewPatterns.nRow=0; //just in case m_bInitialActivation=false; } if (!pattern_test) { DEBUG_FUNC("creating my homie"); DEBUG_FUNC("pModDoc = %p", pModDoc); auto pSndFile = pModDoc->GetSoundFile(); if (pSndFile) { pattern_test = new modplug::gui::qt5::document_window( pSndFile, CMainFrame::GetMainFrame()->global_config, nullptr ); /* pattern_test->resize(400, 400); pattern_test->show(); */ CMainFrame::GetMainFrame() ->ui_root ->mainwindow.add_document_window(pattern_test); } } } //end rewbs.fix3185 }
void CViewComments::OnInitialUpdate() //----------------------------------- { if(m_nListId == 0) { m_nListId = IDC_LIST_SAMPLES; // For XM, set the instrument list as the default list CModDoc *pModDoc = GetDocument(); CSoundFile *pSndFile; if(pModDoc) { pSndFile= pModDoc->GetSoundFile(); if(pSndFile && (pSndFile->m_nType & MOD_TYPE_XM) && pSndFile->m_nInstruments > 0) { m_nListId = IDC_LIST_INSTRUMENTS; } } } CChildFrame *pFrame = (CChildFrame *)GetParentFrame(); CRect rect; if (pFrame) { COMMENTVIEWSTATE *pState = pFrame->GetCommentViewState(); if (pState->cbStruct == sizeof(COMMENTVIEWSTATE)) { m_nListId = pState->nId; } } GetClientRect(&rect); m_ToolBar.Create(WS_CHILD|WS_VISIBLE|CCS_NOPARENTALIGN, rect, this, IDC_TOOLBAR_DETAILS); m_ToolBar.Init(CMainFrame::GetMainFrame()->m_MiscIcons, CMainFrame::GetMainFrame()->m_MiscIconsDisabled); m_ItemList.Create(WS_CHILD|WS_VISIBLE|LVS_REPORT|LVS_SINGLESEL|LVS_EDITLABELS|LVS_NOSORTHEADER, rect, this, IDC_LIST_DETAILS); m_ItemList.ModifyStyleEx(0, WS_EX_STATICEDGE); // Add ToolBar Buttons m_ToolBar.AddButton(IDC_LIST_SAMPLES, IMAGE_SAMPLES); m_ToolBar.AddButton(IDC_LIST_INSTRUMENTS, IMAGE_INSTRUMENTS); //m_ToolBar.AddButton(IDC_LIST_PATTERNS, TIMAGE_TAB_PATTERNS); m_ToolBar.SetIndent(4); UpdateButtonState(); OnUpdate(NULL, HINT_MODTYPE, NULL); }
LRESULT CChildFrame::OnInstrumentSelected(WPARAM wParam, LPARAM lParam) //--------------------------------------------------------------------- { CView *pView = GetActiveView(); CModDoc *pModDoc = NULL; if (pView) pModDoc = (CModDoc *)pView->GetDocument(); if ((m_hWndCtrl) && (pModDoc)) { module_renderer *pSndFile = pModDoc->GetSoundFile(); UINT nIns = lParam; if ((!wParam) && (pSndFile->m_nInstruments > 0)) { nIns = pModDoc->FindSampleParent(nIns); } ::SendMessage(m_hWndCtrl, WM_MOD_CTRLMSG, CTRLMSG_PAT_SETINSTRUMENT, nIns); } return 0; }
void CModScrollView::OnDestroy() //------------------------------ { CModDoc *pModDoc = GetDocument(); CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); if ((pMainFrm) && (pModDoc)) { if (pMainFrm->GetFollowSong(pModDoc) == m_hWnd) { pMainFrm->SetFollowSong(pModDoc, NULL, FALSE); pModDoc->SetFollowWnd(NULL, 0); } if (pMainFrm->GetMidiRecordWnd() == m_hWnd) { pMainFrm->SetMidiRecordWnd(NULL); } } CScrollView::OnDestroy(); }
void CModControlView::UpdateView(uint32_t lHint, CObject *pObject) //------------------------------------------------------------- { CWnd *pActiveDlg = NULL; CModDoc *pDoc = GetDocument(); if (!pDoc) return; // Module type changed: update tabs if (lHint & HINT_MODTYPE) { module_renderer *pSndFile = pDoc->GetSoundFile(); UINT nCount = 4; UINT nType = pSndFile->GetType(); UINT mask = 1 | 2 | 4; if (nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)) { mask |= 8; //mask |= 32; //rewbs.graph nCount ++; } if (nCount != (UINT)m_TabCtrl.GetItemCount()) { UINT count = 0; if ((m_nActiveDlg >= 0) && (m_nActiveDlg < MAX_PAGES)) { pActiveDlg = m_Pages[m_nActiveDlg]; if (pActiveDlg) pActiveDlg->ShowWindow(SW_HIDE); } m_TabCtrl.DeleteAllItems(); if (mask & 1) m_TabCtrl.InsertItem(count++, "General", IDD_CONTROL_GLOBALS, IMAGE_GENERAL); if (mask & 2) m_TabCtrl.InsertItem(count++, "Patterns", IDD_CONTROL_PATTERNS, IMAGE_PATTERNS); } } // Update child dialogs for (UINT nIndex=0; nIndex<MAX_PAGES; nIndex++) { CModControlDlg *pDlg = m_Pages[nIndex]; if ((pDlg) && (pObject != pDlg)) pDlg->UpdateView(lHint, pObject); } // Restore the displayed child dialog if (pActiveDlg) pActiveDlg->ShowWindow(SW_SHOW); }
// Test file loading and saving void TestLoadSaveFile() //--------------------- { CString theFile = theApp.GetAppDirPath(); // Only run the tests when we're in the project directory structure. if(theFile.Mid(theFile.GetLength() - 6, 5) != "Debug") return; theFile.Delete(theFile.GetLength() - 6, 6); theFile.Append("../test/test."); // Test file loading CModDoc *pModDoc = (CModDoc *)theApp.OpenDocumentFile(theFile + "mptm"); TestLoadFile(pModDoc); // Test file saving pModDoc->DoSave(theFile + "saved.mptm"); pModDoc->OnCloseDocument(); // Reload the saved file and test if everything is still working correctly. pModDoc = (CModDoc *)theApp.OpenDocumentFile(theFile + "saved.mptm"); TestLoadFile(pModDoc); pModDoc->OnCloseDocument(); }
// Try to set up a new instrument that is linked to the current plugin. bool CAbstractVstEditor::CreateInstrument() //----------------------------------------- { CModDoc *pModDoc = m_pVstPlugin->GetModDoc(); module_renderer *pSndFile = m_pVstPlugin->GetSoundFile(); if(pModDoc == nullptr || pSndFile == nullptr) { return false; } bool bFirst = (pSndFile->GetNumInstruments() == 0); modplug::tracker::instrumentindex_t nIns = pModDoc->InsertInstrument(0); if(nIns == modplug::tracker::InstrumentIndexInvalid) { return false; } modplug::tracker::modinstrument_t *pIns = pSndFile->Instruments[nIns]; m_nInstrument = nIns; _snprintf(pIns->name, CountOf(pIns->name) - 1, _T("%d: %s"), m_pVstPlugin->GetSlot() + 1, pSndFile->m_MixPlugins[m_pVstPlugin->GetSlot()].Info.szName); strncpy(pIns->legacy_filename, pSndFile->m_MixPlugins[m_pVstPlugin->GetSlot()].Info.szLibraryName, CountOf(pIns->legacy_filename) - 1); pIns->nMixPlug = (PLUGINDEX)m_pVstPlugin->GetSlot() + 1; pIns->midi_channel = 1; // People will forget to change this anyway, so the following lines can lead to some bad surprises after re-opening the module. //pIns->wMidiBank = (uint16_t)((m_pVstPlugin->GetCurrentProgram() >> 7) + 1); //pIns->nMidiProgram = (uint8_t)((m_pVstPlugin->GetCurrentProgram() & 0x7F) + 1); pModDoc->UpdateAllViews(NULL, (nIns << HINT_SHIFT_INS) | HINT_INSTRUMENT | HINT_INSNAMES | HINT_ENVELOPE | (bFirst ? HINT_MODTYPE : 0)); if(pSndFile->GetModSpecifications().supportsPlugins) { pModDoc->SetModified(); } return true; }
void CViewComments::OnUpdate(CView *pSender, LPARAM lHint, CObject *) //------------------------------------------------------------------- { //CHAR s[256], stmp[256]; CHAR s[512], stmp[256]; //rewbs.fix3082 CModDoc *pModDoc = GetDocument(); LV_COLUMN lvc; LV_ITEM lvi, lvi2; if ((!pModDoc) || (pSender == this) || (!(m_ItemList.m_hWnd))) return; if (lHint & HINT_MPTOPTIONS) { m_ToolBar.UpdateStyle(); lHint &= ~HINT_MPTOPTIONS; } lHint &= (HINT_MODTYPE |HINT_SMPNAMES|HINT_SAMPLEINFO |HINT_INSNAMES|HINT_INSTRUMENT /*|HINT_PATNAMES|HINT_PATTERNROW*/); // pattern stuff currently unused if (!lHint) return; const CSoundFile &sndFile = pModDoc->GetrSoundFile(); m_ToolBar.ChangeBitmap(IDC_LIST_INSTRUMENTS, sndFile.GetNumInstruments() ? IMAGE_INSTRUMENTS : IMAGE_INSTRMUTE); m_ItemList.SetRedraw(FALSE); // Add sample headers if ((m_nListId != m_nCurrentListId) || (lHint & HINT_MODTYPE)) { UINT ichk = 0; m_ItemList.DeleteAllItems(); while ((m_ItemList.DeleteColumn(0)) && (ichk < 25)) ichk++; m_nCurrentListId = m_nListId; // Add Sample Headers if (m_nCurrentListId == IDC_LIST_SAMPLES) { UINT nCol = 0; for (UINT iSmp=0; iSmp<SMPLIST_COLUMNS; iSmp++) { MemsetZero(lvc); lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = (iSmp) ? LVCFMT_RIGHT : LVCFMT_LEFT; lvc.pszText = (LPTSTR)gSampleHeaders[iSmp].pszName; lvc.cx = gSampleHeaders[iSmp].cx; lvc.iSubItem = iSmp; m_ItemList.InsertColumn(nCol, &lvc); nCol++; } } else // Add Instrument Headers if (m_nCurrentListId == IDC_LIST_INSTRUMENTS) { UINT nCol = 0; for (UINT i=0; i<INSLIST_COLUMNS; i++) { MemsetZero(lvc); lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = (i) ? LVCFMT_RIGHT : LVCFMT_LEFT; lvc.pszText = (LPTSTR)gInstrumentHeaders[i].pszName; lvc.cx = gInstrumentHeaders[i].cx; lvc.iSubItem = i; m_ItemList.InsertColumn(nCol, &lvc); nCol++; } } else lHint |= HINT_MODTYPE; } // Add Items UINT nCount = m_ItemList.GetItemCount(); // Add Samples if ((m_nCurrentListId == IDC_LIST_SAMPLES) && (lHint & (HINT_MODTYPE|HINT_SMPNAMES|HINT_SAMPLEINFO))) { SAMPLEINDEX nMax = static_cast<SAMPLEINDEX>(nCount); if (nMax < sndFile.GetNumSamples()) nMax = sndFile.GetNumSamples(); for (SAMPLEINDEX iSmp = 0; iSmp < nMax; iSmp++) { if (iSmp < sndFile.GetNumSamples()) { UINT nCol = 0; for (UINT iCol=0; iCol<SMPLIST_COLUMNS; iCol++) { const ModSample &sample = sndFile.GetSample(iSmp + 1); s[0] = 0; switch(iCol) { case SMPLIST_SAMPLENAME: mpt::String::Copy(s, sndFile.m_szNames[iSmp + 1]); break; case SMPLIST_SAMPLENO: wsprintf(s, "%02d", iSmp + 1); break; case SMPLIST_SIZE: if (sample.nLength) { if(sample.GetSampleSizeInBytes() >= 1024) wsprintf(s, "%d KB", sample.GetSampleSizeInBytes() >> 10); else wsprintf(s, "%d B", sample.GetSampleSizeInBytes()); } break; case SMPLIST_TYPE: if(sample.nLength) { wsprintf(s, "%d Bit", sample.GetElementarySampleSize() * 8); } break; case SMPLIST_INSTR: if (sndFile.GetNumInstruments()) { bool first = true; for (INSTRUMENTINDEX i = 1; i <= sndFile.GetNumInstruments(); i++) { if (sndFile.IsSampleReferencedByInstrument(iSmp + 1, i)) { if (!first) strcat(s, ","); first = false; wsprintf(stmp, "%d", i); strcat(s, stmp); if (strlen(s) > sizeof(s) - 10) { strcat(s, "..."); break; } } } } break; case SMPLIST_MIDDLEC: if (sample.nLength) { wsprintf(s, "%d Hz", sample.GetSampleRate(sndFile.GetType())); } break; case SMPLIST_FILENAME: memcpy(s, sample.filename, sizeof(sample.filename)); s[CountOf(sample.filename)] = 0; break; } lvi.mask = LVIF_TEXT; lvi.iItem = iSmp; lvi.iSubItem = nCol; lvi.pszText = (LPTSTR)s; if ((iCol) || (iSmp < nCount)) { bool bOk = true; if (iSmp < nCount) { lvi2 = lvi; lvi2.pszText = (LPTSTR)stmp; lvi2.cchTextMax = sizeof(stmp); stmp[0] = 0; m_ItemList.GetItem(&lvi2); if (!strcmp(s, stmp)) bOk = false; } if (bOk) m_ItemList.SetItem(&lvi); } else { m_ItemList.InsertItem(&lvi); } nCol++; } } else
void CAbstractVstEditor::UpdateMacroMenu() //---------------------------------------- { CString label, macroName, macroText; char paramName[128]; bool greyed; int macroType,nParam,action; CModDoc* pModDoc = m_pVstPlugin->GetModDoc(); if (!pModDoc) { return; } CMenu* pInfoMenu = m_pMenu->GetSubMenu(2); pInfoMenu->DeleteMenu(2, MF_BYPOSITION); if (m_pMacroMenu->m_hMenu) { m_pMacroMenu->DestroyMenu(); } if (!m_pMacroMenu->m_hMenu) { m_pMacroMenu->CreatePopupMenu(); } for (int nMacro=0; nMacro<NUM_MACROS; nMacro++) { action=NULL; greyed=true; macroText = pModDoc->GetSoundFile()->m_MidiCfg.szMidiSFXExt[nMacro]; macroType = pModDoc->GetMacroType(macroText); switch (macroType) { case sfx_unused: macroName = "Unused. Learn Param..."; action=ID_LEARN_MACRO_FROM_PLUGGUI+nMacro; greyed=false; break; case sfx_cutoff: macroName = "Set Filter Cutoff"; break; case sfx_reso: macroName = "Set Filter Resonance"; break; case sfx_mode: macroName = "Set Filter Mode"; break; case sfx_drywet: macroName = "Set plugin dry/wet ratio"; greyed=false; break; case sfx_plug: { nParam = pModDoc->MacroToPlugParam(macroText); m_pVstPlugin->GetParamName(nParam, paramName, sizeof(paramName)); if (paramName[0] == 0) { strcpy(paramName, "N/A for this plug"); } else { greyed=false; } macroName.Format("%d - %s", nParam, paramName); break; } case sfx_custom: default: macroName.Format("Custom: %s", macroText); greyed=false; } label.Format("SF%X: %s", nMacro, macroName); m_pMacroMenu->AppendMenu(MF_STRING|(greyed?MF_GRAYED:0), action, label); } pInfoMenu->InsertMenu(2, MF_BYPOSITION|MF_POPUP, (UINT)m_pMacroMenu->m_hMenu, "&Macros"); }
// Test PC note serialization void TestPCnoteSerialization() //---------------------------- { theApp.OnFileNewMPT(); CMainFrame* pMainFrm = CMainFrame::GetMainFrame(); if(pMainFrm == nullptr) throw(std::runtime_error("pMainFrm is nullptr")); CModDoc* pModDoc = pMainFrm->GetActiveDoc(); if(pModDoc == nullptr) throw(std::runtime_error("pModdoc is nullptr")); module_renderer* pSndFile = pModDoc->GetSoundFile(); if(pSndFile == nullptr) throw(std::runtime_error("pSndFile is nullptr")); // Set maximum number of channels. pModDoc->ReArrangeChannels(std::vector<modplug::tracker::chnindex_t>(ModSpecs::mptm.channelsMax , 0)); pSndFile->Patterns.Remove(0); pSndFile->Patterns.Insert(0, ModSpecs::mptm.patternRowsMin); pSndFile->Patterns.Insert(1, 64); GenerateCommands(pSndFile->Patterns[1], 0.3, 0.3); pSndFile->Patterns.Insert(2, ModSpecs::mptm.patternRowsMax); GenerateCommands(pSndFile->Patterns[2], 0.5, 0.5); // vector<modplug::tracker::modevent_t> pat[3]; const size_t numCommands[] = { pSndFile->GetNumChannels() * pSndFile->Patterns[0].GetNumRows(), pSndFile->GetNumChannels() * pSndFile->Patterns[1].GetNumRows(), pSndFile->GetNumChannels() * pSndFile->Patterns[2].GetNumRows() }; pat[0].resize(numCommands[0]); pat[1].resize(numCommands[1]); pat[2].resize(numCommands[2]); for(size_t i = 0; i<3; i++) // Copy pattern data for comparison. { CPattern::const_iterator iter = pSndFile->Patterns[i].Begin(); for(size_t j = 0; j < numCommands[i]; j++, iter++) pat[i][j] = *iter; } std::strstream mem; WriteModPatterns(mem, pSndFile->Patterns); VERIFY_EQUAL_NONCONT( mem.good(), true ); // Clear patterns. pSndFile->Patterns[0].ClearCommands(); pSndFile->Patterns[1].ClearCommands(); pSndFile->Patterns[2].ClearCommands(); // Read data back. ReadModPatterns(mem, pSndFile->Patterns); // Compare. VERIFY_EQUAL_NONCONT( pSndFile->Patterns[0].GetNumRows(), ModSpecs::mptm.patternRowsMin); VERIFY_EQUAL_NONCONT( pSndFile->Patterns[1].GetNumRows(), 64); VERIFY_EQUAL_NONCONT( pSndFile->Patterns[2].GetNumRows(), ModSpecs::mptm.patternRowsMax); for(size_t i = 0; i < 3; i++) { bool bPatternDataMatch = true; CPattern::const_iterator iter = pSndFile->Patterns[i].Begin(); for(size_t j = 0; j < numCommands[i]; j++, iter++) { if(pat[i][j] != *iter) { bPatternDataMatch = false; break; } } VERIFY_EQUAL( bPatternDataMatch, true); } pModDoc->OnCloseDocument(); }