diff --git a/NeuralAmpModeler/app/IPlugAPP_dialog.cpp b/NeuralAmpModeler/app/IPlugAPP_dialog.cpp new file mode 100644 index 000000000..d3220e5da --- /dev/null +++ b/NeuralAmpModeler/app/IPlugAPP_dialog.cpp @@ -0,0 +1,794 @@ +/* + ============================================================================== + + This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers. + + See LICENSE.txt for more info. + + ============================================================================== +*/ + +#include "IPlugAPP_host.h" +#include "config.h" +#include "resource.h" + +#ifdef OS_WIN +#include "asio.h" +#define GET_MENU() GetMenu(gHWND) +#elif defined OS_MAC +#define GET_MENU() SWELL_GetCurrentMenu() +#endif + +using namespace iplug; + +#if !defined NO_IGRAPHICS +#include "IGraphics.h" +using namespace igraphics; +#endif + +#if defined OS_MAC +extern int GetTitleBarOffset(); +#endif + +// check the input and output devices, find matching srs +void IPlugAPPHost::PopulateSampleRateList(HWND hwndDlg, RtAudio::DeviceInfo* inputDevInfo, RtAudio::DeviceInfo* outputDevInfo) +{ + WDL_String buf; + + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_SR,CB_RESETCONTENT,0,0); + + std::vector matchedSRs; + + if (inputDevInfo->probed && outputDevInfo->probed) + { + for (int i=0; isampleRates.size(); i++) + { + for (int j=0; jsampleRates.size(); j++) + { + if(inputDevInfo->sampleRates[i] == outputDevInfo->sampleRates[j]) + matchedSRs.push_back(inputDevInfo->sampleRates[i]); + } + } + } + + for (int k=0; kprobed) + return; + + WDL_String buf; + + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_L,CB_RESETCONTENT,0,0); + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_R,CB_RESETCONTENT,0,0); + + int i; + + for (i=0; iinputChannels -1; i++) + { + buf.SetFormatted(20, "%i", i+1); + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_L,CB_ADDSTRING,0,(LPARAM)buf.Get()); + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_R,CB_ADDSTRING,0,(LPARAM)buf.Get()); + } + + // TEMP + buf.SetFormatted(20, "%i", i+1); + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_R,CB_ADDSTRING,0,(LPARAM)buf.Get()); + + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_L,CB_SETCURSEL, mState.mAudioInChanL - 1, 0); + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_R,CB_SETCURSEL, mState.mAudioInChanR - 1, 0); +} + +void IPlugAPPHost::PopulateAudioOutputList(HWND hwndDlg, RtAudio::DeviceInfo* info) +{ + if(!info->probed) + return; + + WDL_String buf; + + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_L,CB_RESETCONTENT,0,0); + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_R,CB_RESETCONTENT,0,0); + + int i; + + for (i=0; ioutputChannels -1; i++) + { + buf.SetFormatted(20, "%i", i+1); + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_L,CB_ADDSTRING,0,(LPARAM)buf.Get()); + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_R,CB_ADDSTRING,0,(LPARAM)buf.Get()); + } + + // TEMP + buf.SetFormatted(20, "%i", i+1); + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_R,CB_ADDSTRING,0,(LPARAM)buf.Get()); + + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_L,CB_SETCURSEL, mState.mAudioOutChanL - 1, 0); + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_R,CB_SETCURSEL, mState.mAudioOutChanR - 1, 0); +} + +// This has to get called after any change to audio driver/in dev/out dev +void IPlugAPPHost::PopulateDriverSpecificControls(HWND hwndDlg) +{ +#ifdef OS_WIN + int driverType = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_DRIVER, CB_GETCURSEL, 0, 0); + if(driverType == kDeviceASIO) + { + ComboBox_Enable(GetDlgItem(hwndDlg, IDC_COMBO_AUDIO_IN_DEV), FALSE); + Button_Enable(GetDlgItem(hwndDlg, IDC_BUTTON_OS_DEV_SETTINGS), TRUE); + } + else + { + ComboBox_Enable(GetDlgItem(hwndDlg, IDC_COMBO_AUDIO_IN_DEV), TRUE); + Button_Enable(GetDlgItem(hwndDlg, IDC_BUTTON_OS_DEV_SETTINGS), FALSE); + } +#endif + + int indevidx = 0; + int outdevidx = 0; + + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_DEV,CB_RESETCONTENT,0,0); + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_DEV,CB_RESETCONTENT,0,0); + + for (int i = 0; igetDeviceInfo(mAudioInputDevs[indevidx]); + PopulateAudioInputList(hwndDlg, &inputDevInfo); + } + + if (mAudioOutputDevs.size()) + { + outputDevInfo = mDAC->getDeviceInfo(mAudioOutputDevs[outdevidx]); + PopulateAudioOutputList(hwndDlg, &outputDevInfo); + } + + PopulateSampleRateList(hwndDlg, &inputDevInfo, &outputDevInfo); +} + +void IPlugAPPHost::PopulateAudioDialogs(HWND hwndDlg) +{ + PopulateDriverSpecificControls(hwndDlg); + +// if (mState.mAudioInIsMono) +// { +// SendDlgItemMessage(hwndDlg,IDC_CB_MONO_INPUT,BM_SETCHECK, BST_CHECKED,0); +// } +// else +// { +// SendDlgItemMessage(hwndDlg,IDC_CB_MONO_INPUT,BM_SETCHECK, BST_UNCHECKED,0); +// } + +// Populate buffer size combobox + for (int i = 0; i< kNumBufferSizeOptions; i++) + { + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_BUF_SIZE,CB_ADDSTRING,0,(LPARAM)kBufferSizeOptions[i].c_str()); + } + + WDL_String str; + str.SetFormatted(32, "%i", mState.mBufferSize); + + LRESULT iovsidx = SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_BUF_SIZE, CB_FINDSTRINGEXACT, -1, (LPARAM) str.Get()); + SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_BUF_SIZE, CB_SETCURSEL, iovsidx, 0); +} + +bool IPlugAPPHost::PopulateMidiDialogs(HWND hwndDlg) +{ + if ( !mMidiIn || !mMidiOut ) + return false; + else + { + for (int i=0; imState; + AppState& mTempState = _this->mTempState; + AppState& mActiveState = _this->mActiveState; + + auto getComboString = [&](WDL_String& str, int item, WPARAM idx) { + std::string tempString; + long len = (long) SendDlgItemMessage(hwndDlg, item, CB_GETLBTEXTLEN, idx, 0) + 1; + tempString.reserve(len); + SendDlgItemMessage(hwndDlg, item, CB_GETLBTEXT, idx, (LPARAM) tempString.data()); + str.Set(tempString.c_str()); + }; + + int v = 0; + switch(uMsg) + { + case WM_INITDIALOG: + _this->PopulatePreferencesDialog(hwndDlg); + mTempState = mState; + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + if(mActiveState != mState) + _this->TryToChangeAudio(); + + EndDialog(hwndDlg, IDOK); // INI file will be changed see MainDialogProc + break; + case IDAPPLY: + _this->TryToChangeAudio(); + break; + case IDCANCEL: + EndDialog(hwndDlg, IDCANCEL); + + // if state has been changed reset to previous state, INI file won't be changed + if (!_this->AudioSettingsInStateAreEqual(mState, mTempState) + || !_this->MIDISettingsInStateAreEqual(mState, mTempState)) + { + mState = mTempState; + + _this->TryToChangeAudioDriverType(); + _this->ProbeAudioIO(); + _this->TryToChangeAudio(); + } + + break; + + case IDC_COMBO_AUDIO_DRIVER: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + v = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_DRIVER, CB_GETCURSEL, 0, 0); + + if(v != mState.mAudioDriverType) + { + mState.mAudioDriverType = v; + + _this->TryToChangeAudioDriverType(); + _this->ProbeAudioIO(); + + if (_this->mAudioInputDevs.size()) + mState.mAudioInDev.Set(_this->GetAudioDeviceName(_this->mAudioInputDevs[0]).c_str()); + + if (_this->mAudioOutputDevs.size()) + mState.mAudioOutDev.Set(_this->GetAudioDeviceName(_this->mAudioOutputDevs[0]).c_str()); + + // Reset IO + mState.mAudioOutChanL = 1; + mState.mAudioOutChanR = 2; + + _this->PopulateAudioDialogs(hwndDlg); + } + } + break; + + case IDC_COMBO_AUDIO_IN_DEV: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + int idx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_IN_DEV, CB_GETCURSEL, 0, 0); + getComboString(mState.mAudioInDev, IDC_COMBO_AUDIO_IN_DEV, idx); + + // Reset IO + mState.mAudioInChanL = 1; + mState.mAudioInChanR = 2; + + _this->PopulateDriverSpecificControls(hwndDlg); + } + break; + + case IDC_COMBO_AUDIO_OUT_DEV: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + int idx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_OUT_DEV, CB_GETCURSEL, 0, 0); + getComboString(mState.mAudioOutDev, IDC_COMBO_AUDIO_OUT_DEV, idx); + + // Reset IO + mState.mAudioOutChanL = 1; + mState.mAudioOutChanR = 2; + + _this->PopulateDriverSpecificControls(hwndDlg); + } + break; + + case IDC_COMBO_AUDIO_IN_L: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + mState.mAudioInChanL = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_IN_L, CB_GETCURSEL, 0, 0) + 1; + + //TEMP + mState.mAudioInChanR = mState.mAudioInChanL + 1; + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_R,CB_SETCURSEL, mState.mAudioInChanR - 1, 0); + // + } + break; + + case IDC_COMBO_AUDIO_IN_R: + if (HIWORD(wParam) == CBN_SELCHANGE) + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_R,CB_SETCURSEL, mState.mAudioInChanR - 1, 0); // TEMP + mState.mAudioInChanR = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_IN_R, CB_GETCURSEL, 0, 0); + break; + + case IDC_COMBO_AUDIO_OUT_L: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + mState.mAudioOutChanL = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_OUT_L, CB_GETCURSEL, 0, 0) + 1; + + //TEMP + mState.mAudioOutChanR = mState.mAudioOutChanL + 1; + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_R,CB_SETCURSEL, mState.mAudioOutChanR - 1, 0); + // + } + break; + + case IDC_COMBO_AUDIO_OUT_R: + if (HIWORD(wParam) == CBN_SELCHANGE) + SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_R,CB_SETCURSEL, mState.mAudioOutChanR - 1, 0); // TEMP + mState.mAudioOutChanR = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_OUT_R, CB_GETCURSEL, 0, 0); + break; + +// case IDC_CB_MONO_INPUT: +// if (SendDlgItemMessage(hwndDlg,IDC_CB_MONO_INPUT, BM_GETCHECK, 0, 0) == BST_CHECKED) +// mState.mAudioInIsMono = 1; +// else +// mState.mAudioInIsMono = 0; +// break; + + case IDC_COMBO_AUDIO_BUF_SIZE: // follow through + if (HIWORD(wParam) == CBN_SELCHANGE) + { + int iovsidx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_BUF_SIZE, CB_GETCURSEL, 0, 0); + mState.mBufferSize = atoi(kBufferSizeOptions[iovsidx].c_str()); + } + break; + case IDC_COMBO_AUDIO_SR: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + int idx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_SR, CB_GETCURSEL, 0, 0); + mState.mAudioSR = (uint32_t) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_SR, CB_GETITEMDATA, idx, 0); + } + break; + + case IDC_BUTTON_OS_DEV_SETTINGS: + if (HIWORD(wParam) == BN_CLICKED) { + #ifdef OS_WIN + if( (_this->mState.mAudioDriverType == kDeviceASIO) && (_this->mDAC->isStreamRunning() == true)) // TODO: still not right + ASIOControlPanel(); + #elif defined OS_MAC + if(SWELL_GetOSXVersion() >= 0x1200) { + system("open \"/System/Applications/Utilities/Audio MIDI Setup.app\""); + } else { + system("open \"/Applications/Utilities/Audio MIDI Setup.app\""); + } + #else + #error NOT IMPLEMENTED + #endif + } + break; + + case IDC_COMBO_MIDI_IN_DEV: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + int idx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_MIDI_IN_DEV, CB_GETCURSEL, 0, 0); + getComboString(mState.mMidiInDev, IDC_COMBO_MIDI_IN_DEV, idx); + _this->SelectMIDIDevice(ERoute::kInput, mState.mMidiInDev.Get()); + } + break; + + case IDC_COMBO_MIDI_OUT_DEV: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + int idx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_MIDI_OUT_DEV, CB_GETCURSEL, 0, 0); + getComboString(mState.mMidiOutDev, IDC_COMBO_MIDI_OUT_DEV, idx); + _this->SelectMIDIDevice(ERoute::kOutput, mState.mMidiOutDev.Get()); + } + break; + + case IDC_COMBO_MIDI_IN_CHAN: + if (HIWORD(wParam) == CBN_SELCHANGE) + mState.mMidiInChan = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_MIDI_IN_CHAN, CB_GETCURSEL, 0, 0); + break; + + case IDC_COMBO_MIDI_OUT_CHAN: + if (HIWORD(wParam) == CBN_SELCHANGE) + mState.mMidiOutChan = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_MIDI_OUT_CHAN, CB_GETCURSEL, 0, 0); + break; + + default: + break; + } + break; + default: + return FALSE; + } + return TRUE; +} + +static void ClientResize(HWND hWnd, int nWidth, int nHeight) +{ + RECT rcClient, rcWindow; + POINT ptDiff; + int screenwidth, screenheight; + int x, y; + + screenwidth = GetSystemMetrics(SM_CXSCREEN); + screenheight = GetSystemMetrics(SM_CYSCREEN); + x = (screenwidth / 2) - (nWidth / 2); + y = (screenheight / 2) - (nHeight / 2); + + GetClientRect(hWnd, &rcClient); + GetWindowRect(hWnd, &rcWindow); + + ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right; + ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom; + + SetWindowPos(hWnd, 0, x, y, nWidth + ptDiff.x, nHeight + ptDiff.y, 0); +} + +#ifdef OS_WIN +extern float GetScaleForHWND(HWND hWnd); +#endif + +//static +WDL_DLGRET IPlugAPPHost::MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + IPlugAPPHost* pAppHost = IPlugAPPHost::sInstance.get(); + + int width = 0; + int height = 0; + + switch (uMsg) + { + case WM_INITDIALOG: + { + gHWND = hwndDlg; + IPlugAPP* pPlug = pAppHost->GetPlug(); + + if (!pAppHost->OpenWindow(gHWND)) + DBGMSG("couldn't attach gui\n"); + + width = pPlug->GetEditorWidth(); + height = pPlug->GetEditorHeight(); + + ClientResize(hwndDlg, width, height); + + ShowWindow(hwndDlg, SW_SHOW); + return 1; + } + case WM_DESTROY: + pAppHost->CloseWindow(); + gHWND = NULL; + IPlugAPPHost::sInstance = nullptr; + + #ifdef OS_WIN + PostQuitMessage(0); + #else + SWELL_PostQuitMessage(hwndDlg); + #endif + + return 0; + case WM_CLOSE: + DestroyWindow(hwndDlg); + return 0; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case ID_QUIT: + { + DestroyWindow(hwndDlg); + return 0; + } + case ID_ABOUT: + { + IPlugAPP* pPlug = pAppHost->GetPlug(); + + bool pluginOpensAboutBox = pPlug->OnHostRequestingAboutBox(); + + if (pluginOpensAboutBox == false) + { + WDL_String info; + info.Append(PLUG_COPYRIGHT_STR"\nBuilt on " __DATE__); + MessageBox(hwndDlg, info.Get(), PLUG_NAME, MB_OK); + } + + return 0; + } + case ID_HELP: + { + IPlugAPP* pPlug = pAppHost->GetPlug(); + + bool pluginOpensHelp = pPlug->OnHostRequestingProductHelp(); + + if (pluginOpensHelp == false) + { + MessageBox(hwndDlg, "See the manual", PLUG_NAME, MB_OK); + } + return 0; + } + case ID_PREFERENCES: + { + INT_PTR ret = DialogBox(gHINSTANCE, MAKEINTRESOURCE(IDD_DIALOG_PREF), hwndDlg, IPlugAPPHost::PreferencesDlgProc); + + if(ret == IDOK) + pAppHost->UpdateINI(); + + return 0; + } +#if defined _DEBUG && !defined NO_IGRAPHICS + case ID_LIVE_EDIT: + { + IGEditorDelegate* pPlug = dynamic_cast(pAppHost->GetPlug()); + + if(pPlug) + { + IGraphics* pGraphics = pPlug->GetUI(); + + if(pGraphics) + { + bool enabled = pGraphics->LiveEditEnabled(); + pGraphics->EnableLiveEdit(!enabled); + CheckMenuItem(GET_MENU(), ID_LIVE_EDIT, (MF_BYCOMMAND | enabled) ? MF_UNCHECKED : MF_CHECKED); + } + } + + return 0; + } + case ID_SHOW_DRAWN: + { + IGEditorDelegate* pPlug = dynamic_cast(pAppHost->GetPlug()); + + if(pPlug) + { + IGraphics* pGraphics = pPlug->GetUI(); + + if(pGraphics) + { + bool enabled = pGraphics->ShowAreaDrawnEnabled(); + pGraphics->ShowAreaDrawn(!enabled); + CheckMenuItem(GET_MENU(), ID_SHOW_DRAWN, (MF_BYCOMMAND | enabled) ? MF_UNCHECKED : MF_CHECKED); + } + } + + return 0; + } + case ID_SHOW_BOUNDS: + { + IGEditorDelegate* pPlug = dynamic_cast(pAppHost->GetPlug()); + + if(pPlug) + { + IGraphics* pGraphics = pPlug->GetUI(); + + if(pGraphics) + { + bool enabled = pGraphics->ShowControlBoundsEnabled(); + pGraphics->ShowControlBounds(!enabled); + CheckMenuItem(GET_MENU(), ID_SHOW_BOUNDS, (MF_BYCOMMAND | enabled) ? MF_UNCHECKED : MF_CHECKED); + } + } + + return 0; + } + case ID_SHOW_FPS: + { + IGEditorDelegate* pPlug = dynamic_cast(pAppHost->GetPlug()); + + if(pPlug) + { + IGraphics* pGraphics = pPlug->GetUI(); + + if(pGraphics) + { + bool enabled = pGraphics->ShowingFPSDisplay(); + pGraphics->ShowFPSDisplay(!enabled); + CheckMenuItem(GET_MENU(), ID_SHOW_FPS, (MF_BYCOMMAND | enabled) ? MF_UNCHECKED : MF_CHECKED); + } + } + + return 0; + } +#endif + } + return 0; + case WM_GETMINMAXINFO: + { + if(!pAppHost) + return 1; + + IPlugAPP* pPlug = pAppHost->GetPlug(); + + MINMAXINFO* mmi = (MINMAXINFO*) lParam; + mmi->ptMinTrackSize.x = pPlug->GetMinWidth(); + mmi->ptMinTrackSize.y = pPlug->GetMinHeight(); + mmi->ptMaxTrackSize.x = pPlug->GetMaxWidth(); + mmi->ptMaxTrackSize.y = pPlug->GetMaxHeight(); + +#ifdef OS_WIN + float scale = GetScaleForHWND(hwndDlg); + mmi->ptMinTrackSize.x = static_cast(static_cast(mmi->ptMinTrackSize.x) * scale); + mmi->ptMinTrackSize.y = static_cast(static_cast(mmi->ptMinTrackSize.y) * scale); + mmi->ptMaxTrackSize.x = static_cast(static_cast(mmi->ptMaxTrackSize.x) * scale); + mmi->ptMaxTrackSize.y = static_cast(static_cast(mmi->ptMaxTrackSize.y) * scale); +#endif + + return 0; + } +#ifdef OS_WIN + case WM_DPICHANGED: + { + WORD dpi = HIWORD(wParam); + RECT* rect = (RECT*)lParam; + float scale = GetScaleForHWND(hwndDlg); + + POINT ptDiff; + RECT rcClient; + RECT rcWindow; + + GetClientRect(hwndDlg, &rcClient); + GetWindowRect(hwndDlg, &rcWindow); + + ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right; + ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom; + +#ifndef NO_IGRAPHICS + IGEditorDelegate* pPlug = dynamic_cast(pAppHost->GetPlug()); + + if (pPlug) + { + IGraphics* pGraphics = pPlug->GetUI(); + + if (pGraphics) + { + pGraphics->SetScreenScale(scale); + } + } +#else + IEditorDelegate* pPlug = dynamic_cast(pAppHost->GetPlug()); +#endif + + int w = pPlug->GetEditorWidth(); + int h = pPlug->GetEditorHeight(); + + SetWindowPos(hwndDlg, 0, rect->left, rect->top, w + ptDiff.x, h + ptDiff.y, 0); + + return 0; + } +#endif + case WM_SIZE: + { + IPlugAPP* pPlug = pAppHost->GetPlug(); + + switch (LOWORD(wParam)) + { + case SIZE_RESTORED: + case SIZE_MAXIMIZED: + { + RECT r; + GetClientRect(hwndDlg, &r); + float scale = 1.f; + #ifdef OS_WIN + scale = GetScaleForHWND(hwndDlg); + #endif + pPlug->OnParentWindowResize(static_cast(r.right / scale), static_cast(r.bottom / scale)); + return 1; + } + default: + return 0; + } + } + } + return 0; +} diff --git a/NeuralAmpModeler/app/IPlugAPP_host.cpp b/NeuralAmpModeler/app/IPlugAPP_host.cpp new file mode 100644 index 000000000..a3093498f --- /dev/null +++ b/NeuralAmpModeler/app/IPlugAPP_host.cpp @@ -0,0 +1,786 @@ +/* + ============================================================================== + + This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers. + + See LICENSE.txt for more info. + + ============================================================================== +*/ + +#include "IPlugAPP_host.h" + +#ifdef OS_WIN +#include +#endif + +#include "IPlugLogger.h" + +using namespace iplug; + +#ifndef MAX_PATH_LEN +#define MAX_PATH_LEN 2048 +#endif + +#define STRBUFSZ 100 + +std::unique_ptr IPlugAPPHost::sInstance; +UINT gSCROLLMSG; + +IPlugAPPHost::IPlugAPPHost() +: mIPlug(MakePlug(InstanceInfo{this})) +{ +} + +IPlugAPPHost::~IPlugAPPHost() +{ + mExiting = true; + + CloseAudio(); + + if(mMidiIn) + mMidiIn->cancelCallback(); + + if(mMidiOut) + mMidiOut->closePort(); +} + +//static +IPlugAPPHost* IPlugAPPHost::Create() +{ + sInstance = std::make_unique(); + return sInstance.get(); +} + +bool IPlugAPPHost::Init() +{ + mIPlug->SetHost("standalone", mIPlug->GetPluginVersion(false)); + + if (!InitState()) + return false; + + TryToChangeAudioDriverType(); // will init RTAudio with an API type based on gState->mAudioDriverType + ProbeAudioIO(); // find out what audio IO devs are available and put their IDs in the global variables gAudioInputDevs / gAudioOutputDevs + InitMidi(); // creates RTMidiIn and RTMidiOut objects + ProbeMidiIO(); // find out what midi IO devs are available and put their names in the global variables gMidiInputDevs / gMidiOutputDevs + SelectMIDIDevice(ERoute::kInput, mState.mMidiInDev.Get()); + SelectMIDIDevice(ERoute::kOutput, mState.mMidiOutDev.Get()); + + mIPlug->OnParamReset(kReset); + mIPlug->OnActivate(true); + + return true; +} + +bool IPlugAPPHost::OpenWindow(HWND pParent) +{ + return mIPlug->OpenWindow(pParent) != nullptr; +} + +void IPlugAPPHost::CloseWindow() +{ + mIPlug->CloseWindow(); +} + +bool IPlugAPPHost::InitState() +{ +#if defined OS_WIN + TCHAR strPath[MAX_PATH_LEN]; + SHGetFolderPathA( NULL, CSIDL_LOCAL_APPDATA, NULL, 0, strPath ); + mINIPath.SetFormatted(MAX_PATH_LEN, "%s\\%s\\", strPath, BUNDLE_NAME); +#elif defined OS_MAC + mINIPath.SetFormatted(MAX_PATH_LEN, "%s/Library/Application Support/%s/", getenv("HOME"), BUNDLE_NAME); +#else + #error NOT IMPLEMENTED +#endif + + struct stat st; + + if(stat(mINIPath.Get(), &st) == 0) // if directory exists + { + mINIPath.Append("settings.ini"); // add file name to path + + char buf[STRBUFSZ]; + + if(stat(mINIPath.Get(), &st) == 0) // if settings file exists read values into state + { + DBGMSG("Reading ini file from %s\n", mINIPath.Get()); + + mState.mAudioDriverType = GetPrivateProfileInt("audio", "driver", 0, mINIPath.Get()); + + GetPrivateProfileString("audio", "indev", "Built-in Input", buf, STRBUFSZ, mINIPath.Get()); mState.mAudioInDev.Set(buf); + GetPrivateProfileString("audio", "outdev", "Built-in Output", buf, STRBUFSZ, mINIPath.Get()); mState.mAudioOutDev.Set(buf); + + //audio + mState.mAudioInChanL = GetPrivateProfileInt("audio", "in1", 1, mINIPath.Get()); // 1 is first audio input + mState.mAudioInChanR = GetPrivateProfileInt("audio", "in2", 2, mINIPath.Get()); + mState.mAudioOutChanL = GetPrivateProfileInt("audio", "out1", 1, mINIPath.Get()); // 1 is first audio output + mState.mAudioOutChanR = GetPrivateProfileInt("audio", "out2", 2, mINIPath.Get()); + //mState.mAudioInIsMono = GetPrivateProfileInt("audio", "monoinput", 0, mINIPath.Get()); + + mState.mBufferSize = GetPrivateProfileInt("audio", "buffer", 512, mINIPath.Get()); + mState.mAudioSR = GetPrivateProfileInt("audio", "sr", 44100, mINIPath.Get()); + + //midi + GetPrivateProfileString("midi", "indev", "no input", buf, STRBUFSZ, mINIPath.Get()); mState.mMidiInDev.Set(buf); + GetPrivateProfileString("midi", "outdev", "no output", buf, STRBUFSZ, mINIPath.Get()); mState.mMidiOutDev.Set(buf); + + mState.mMidiInChan = GetPrivateProfileInt("midi", "inchan", 0, mINIPath.Get()); // 0 is any + mState.mMidiOutChan = GetPrivateProfileInt("midi", "outchan", 0, mINIPath.Get()); // 1 is first chan + } + + // if settings file doesn't exist, populate with default values, otherwise overrwrite + UpdateINI(); + } + else // folder doesn't exist - make folder and make file + { +#if defined OS_WIN + // folder doesn't exist - make folder and make file + CreateDirectory(mINIPath.Get(), NULL); + mINIPath.Append("settings.ini"); + UpdateINI(); // will write file if doesn't exist +#elif defined OS_MAC + mode_t process_mask = umask(0); + int result_code = mkdir(mINIPath.Get(), S_IRWXU | S_IRWXG | S_IRWXO); + umask(process_mask); + + if(!result_code) + { + mINIPath.Append("\\settings.ini"); + UpdateINI(); // will write file if doesn't exist + } + else + { + return false; + } +#else + #error NOT IMPLEMENTED +#endif + } + + return true; +} + +void IPlugAPPHost::UpdateINI() +{ + char buf[STRBUFSZ]; // temp buffer for writing integers to profile strings + const char* ini = mINIPath.Get(); + + sprintf(buf, "%u", mState.mAudioDriverType); + WritePrivateProfileString("audio", "driver", buf, ini); + + WritePrivateProfileString("audio", "indev", mState.mAudioInDev.Get(), ini); + WritePrivateProfileString("audio", "outdev", mState.mAudioOutDev.Get(), ini); + + sprintf(buf, "%u", mState.mAudioInChanL); + WritePrivateProfileString("audio", "in1", buf, ini); + sprintf(buf, "%u", mState.mAudioInChanR); + WritePrivateProfileString("audio", "in2", buf, ini); + sprintf(buf, "%u", mState.mAudioOutChanL); + WritePrivateProfileString("audio", "out1", buf, ini); + sprintf(buf, "%u", mState.mAudioOutChanR); + WritePrivateProfileString("audio", "out2", buf, ini); + //sprintf(buf, "%u", mState.mAudioInIsMono); + //WritePrivateProfileString("audio", "monoinput", buf, ini); + + WDL_String str; + str.SetFormatted(32, "%i", mState.mBufferSize); + WritePrivateProfileString("audio", "buffer", str.Get(), ini); + + str.SetFormatted(32, "%i", mState.mAudioSR); + WritePrivateProfileString("audio", "sr", str.Get(), ini); + + WritePrivateProfileString("midi", "indev", mState.mMidiInDev.Get(), ini); + WritePrivateProfileString("midi", "outdev", mState.mMidiOutDev.Get(), ini); + + sprintf(buf, "%u", mState.mMidiInChan); + WritePrivateProfileString("midi", "inchan", buf, ini); + sprintf(buf, "%u", mState.mMidiOutChan); + WritePrivateProfileString("midi", "outchan", buf, ini); +} + +std::string IPlugAPPHost::GetAudioDeviceName(int idx) const +{ + return mAudioIDDevNames.at(idx); +} + +int IPlugAPPHost::GetAudioDeviceIdx(const char* deviceNameToTest) const +{ + for(int i = 0; i < mAudioIDDevNames.size(); i++) + { + if(!strcmp(deviceNameToTest, mAudioIDDevNames.at(i).c_str() )) + return i; + } + + return -1; +} + +int IPlugAPPHost::GetMIDIPortNumber(ERoute direction, const char* nameToTest) const +{ + int start = 1; + + if(direction == ERoute::kInput) + { + if(!strcmp(nameToTest, OFF_TEXT)) return 0; + + #ifdef OS_MAC + start = 2; + if(!strcmp(nameToTest, "virtual input")) return 1; + #endif + + for (int i = 0; i < mMidiIn->getPortCount(); i++) + { + if(!strcmp(nameToTest, mMidiIn->getPortName(i).c_str())) + return (i + start); + } + } + else + { + if(!strcmp(nameToTest, OFF_TEXT)) return 0; + + #ifdef OS_MAC + start = 2; + if(!strcmp(nameToTest, "virtual output")) return 1; + #endif + + for (int i = 0; i < mMidiOut->getPortCount(); i++) + { + if(!strcmp(nameToTest, mMidiOut->getPortName(i).c_str())) + return (i + start); + } + } + + return -1; +} + +void IPlugAPPHost::ProbeAudioIO() +{ + std::cout << "\nRtAudio Version " << RtAudio::getVersion() << std::endl; + + RtAudio::DeviceInfo info; + + mAudioInputDevs.clear(); + mAudioOutputDevs.clear(); + mAudioIDDevNames.clear(); + + uint32_t nDevices = mDAC->getDeviceCount(); + + for (int i=0; igetDeviceInfo(i); + std::string deviceName = info.name; + +#ifdef OS_MAC + size_t colonIdx = deviceName.rfind(": "); + + if(colonIdx != std::string::npos && deviceName.length() >= 2) + deviceName = deviceName.substr(colonIdx + 2, deviceName.length() - colonIdx - 2); + +#endif + + mAudioIDDevNames.push_back(deviceName); + + if ( info.probed == false ) + std::cout << deviceName << ": Probe Status = Unsuccessful\n"; + else if ( !strcmp("Generic Low Latency ASIO Driver", deviceName.c_str() )) + std::cout << deviceName << ": Probe Status = Unsuccessful\n"; + else + { + if(info.inputChannels > 0) + mAudioInputDevs.push_back(i); + + if(info.outputChannels > 0) + mAudioOutputDevs.push_back(i); + + if (info.isDefaultInput) + mDefaultInputDev = i; + + if (info.isDefaultOutput) + mDefaultOutputDev = i; + } + } +} + +void IPlugAPPHost::ProbeMidiIO() +{ + if ( !mMidiIn || !mMidiOut ) + return; + else + { + int nInputPorts = mMidiIn->getPortCount(); + + mMidiInputDevNames.push_back(OFF_TEXT); + +#ifdef OS_MAC + mMidiInputDevNames.push_back("virtual input"); +#endif + + for (int i=0; igetPortName(i)); + } + + int nOutputPorts = mMidiOut->getPortCount(); + + mMidiOutputDevNames.push_back(OFF_TEXT); + +#ifdef OS_MAC + mMidiOutputDevNames.push_back("virtual output"); +#endif + + for (int i=0; igetPortName(i)); + //This means the virtual output port wont be added as an input + } + } +} + +bool IPlugAPPHost::AudioSettingsInStateAreEqual(AppState& os, AppState& ns) +{ + if (os.mAudioDriverType != ns.mAudioDriverType) return false; + if (strcmp(os.mAudioInDev.Get(), ns.mAudioInDev.Get())) return false; + if (strcmp(os.mAudioOutDev.Get(), ns.mAudioOutDev.Get())) return false; + if (os.mAudioSR != ns.mAudioSR) return false; + if (os.mBufferSize != ns.mBufferSize) return false; + if (os.mAudioInChanL != ns.mAudioInChanL) return false; + if (os.mAudioInChanR != ns.mAudioInChanR) return false; + if (os.mAudioOutChanL != ns.mAudioOutChanL) return false; + if (os.mAudioOutChanR != ns.mAudioOutChanR) return false; +// if (os.mAudioInIsMono != ns.mAudioInIsMono) return false; + + return true; +} + +bool IPlugAPPHost::MIDISettingsInStateAreEqual(AppState& os, AppState& ns) +{ + if (strcmp(os.mMidiInDev.Get(), ns.mMidiInDev.Get())) return false; + if (strcmp(os.mMidiOutDev.Get(), ns.mMidiOutDev.Get())) return false; + if (os.mMidiInChan != ns.mMidiInChan) return false; + if (os.mMidiOutChan != ns.mMidiOutChan) return false; + + return true; +} + +bool IPlugAPPHost::TryToChangeAudioDriverType() +{ + CloseAudio(); + + if (mDAC) + { + mDAC = nullptr; + } + +#if defined OS_WIN + if(mState.mAudioDriverType == kDeviceASIO) + mDAC = std::make_unique(RtAudio::WINDOWS_ASIO); + else + mDAC = std::make_unique(RtAudio::WINDOWS_DS); +#elif defined OS_MAC + if(mState.mAudioDriverType == kDeviceCoreAudio) + mDAC = std::make_unique(RtAudio::MACOSX_CORE); + //else + //mDAC = std::make_unique(RtAudio::UNIX_JACK); +#else + #error NOT IMPLEMENTED +#endif + + if(mDAC) + return true; + else + return false; +} + +bool IPlugAPPHost::TryToChangeAudio() +{ + int inputID = -1; + int outputID = -1; + +#if defined OS_WIN + if(mState.mAudioDriverType == kDeviceASIO) + inputID = GetAudioDeviceIdx(mState.mAudioOutDev.Get()); + else + inputID = GetAudioDeviceIdx(mState.mAudioInDev.Get()); +#elif defined OS_MAC + inputID = GetAudioDeviceIdx(mState.mAudioInDev.Get()); +#else + #error NOT IMPLEMENTED +#endif + outputID = GetAudioDeviceIdx(mState.mAudioOutDev.Get()); + + bool failedToFindDevice = false; + bool resetToDefault = false; + + if (inputID == -1) + { + if (mDefaultInputDev > -1) + { + resetToDefault = true; + inputID = mDefaultInputDev; + + if (mAudioInputDevs.size()) + mState.mAudioInDev.Set(GetAudioDeviceName(inputID).c_str()); + } + else + failedToFindDevice = true; + } + + if (outputID == -1) + { + if (mDefaultOutputDev > -1) + { + resetToDefault = true; + + outputID = mDefaultOutputDev; + + if (mAudioOutputDevs.size()) + mState.mAudioOutDev.Set(GetAudioDeviceName(outputID).c_str()); + } + else + failedToFindDevice = true; + } + + if (resetToDefault) + { + DBGMSG("couldn't find previous audio device, reseting to default\n"); + + UpdateINI(); + } + + if (failedToFindDevice) + MessageBox(gHWND, "Please check your soundcard settings in Preferences", "Error", MB_OK); + + if (inputID != -1 && outputID != -1) + { + return InitAudio(inputID, outputID, mState.mAudioSR, mState.mBufferSize); + } + + return false; +} + +bool IPlugAPPHost::SelectMIDIDevice(ERoute direction, const char* pPortName) +{ + int port = GetMIDIPortNumber(direction, pPortName); + + if(direction == ERoute::kInput) + { + if(port == -1) + { + mState.mMidiInDev.Set(OFF_TEXT); + UpdateINI(); + port = 0; + } + + //TODO: send all notes off? + if (mMidiIn) + { + mMidiIn->closePort(); + + if (port == 0) + { + return true; + } + #if defined OS_WIN + else + { + mMidiIn->openPort(port-1); + return true; + } + #elif defined OS_MAC + else if(port == 1) + { + std::string virtualMidiInputName = "To "; + virtualMidiInputName += BUNDLE_NAME; + mMidiIn->openVirtualPort(virtualMidiInputName); + return true; + } + else + { + mMidiIn->openPort(port-2); + return true; + } + #else + #error NOT IMPLEMENTED + #endif + } + } + else + { + if(port == -1) + { + mState.mMidiOutDev.Set(OFF_TEXT); + UpdateINI(); + port = 0; + } + + if (mMidiOut) + { + //TODO: send all notes off? + mMidiOut->closePort(); + + if (port == 0) + return true; +#if defined OS_WIN + else + { + mMidiOut->openPort(port-1); + return true; + } +#elif defined OS_MAC + else if(port == 1) + { + std::string virtualMidiOutputName = "From "; + virtualMidiOutputName += BUNDLE_NAME; + mMidiOut->openVirtualPort(virtualMidiOutputName); + return true; + } + else + { + mMidiOut->openPort(port-2); + return true; + } +#else + #error NOT IMPLEMENTED +#endif + } + } + + return false; +} + +void IPlugAPPHost::CloseAudio() +{ + if (mDAC && mDAC->isStreamOpen()) + { + if (mDAC->isStreamRunning()) + { + mAudioEnding = true; + + while (!mAudioDone) + Sleep(10); + + try + { + mDAC->abortStream(); + } + catch (RtAudioError& e) + { + e.printMessage(); + } + } + + mDAC->closeStream(); + } +} + +bool IPlugAPPHost::InitAudio(uint32_t inId, uint32_t outId, uint32_t sr, uint32_t iovs) +{ + CloseAudio(); + + RtAudio::StreamParameters iParams, oParams; + iParams.deviceId = inId; + iParams.nChannels = GetPlug()->MaxNChannels(ERoute::kInput); // TODO: flexible channel count + iParams.firstChannel = 0; // TODO: flexible channel count + + oParams.deviceId = outId; + oParams.nChannels = GetPlug()->MaxNChannels(ERoute::kOutput); // TODO: flexible channel count + oParams.firstChannel = 0; // TODO: flexible channel count + + mBufferSize = iovs; // mBufferSize may get changed by stream + + DBGMSG("\ntrying to start audio stream @ %i sr, %i buffer size\nindev = %i:%s\noutdev = %i:%s\ninputs = %i\noutputs = %i\n", + sr, mBufferSize, inId, GetAudioDeviceName(inId).c_str(), outId, GetAudioDeviceName(outId).c_str(), iParams.nChannels, oParams.nChannels); + + RtAudio::StreamOptions options; + options.flags = RTAUDIO_NONINTERLEAVED; + // options.streamName = BUNDLE_NAME; // JACK stream name, not used on other streams + + mBufIndex = 0; + mSamplesElapsed = 0; + mSampleRate = (double) sr; + mVecWait = 0; + mAudioEnding = false; + mAudioDone = false; + + mIPlug->SetBlockSize(APP_SIGNAL_VECTOR_SIZE); + mIPlug->SetSampleRate(mSampleRate); + mIPlug->OnReset(); + + try + { + mDAC->openStream(&oParams, iParams.nChannels > 0 ? &iParams : nullptr, RTAUDIO_FLOAT64, sr, &mBufferSize, &AudioCallback, this, &options /*, &ErrorCallback */); + + for (int i = 0; i < iParams.nChannels; i++) + { + mInputBufPtrs.Add(nullptr); //will be set in callback + } + + for (int i = 0; i < oParams.nChannels; i++) + { + mOutputBufPtrs.Add(nullptr); //will be set in callback + } + + mDAC->startStream(); + + mActiveState = mState; + } + catch (RtAudioError& e) + { + e.printMessage(); + return false; + } + + return true; +} + +bool IPlugAPPHost::InitMidi() +{ + try + { + mMidiIn = std::make_unique(); + } + catch (RtMidiError &error) + { + mMidiIn = nullptr; + error.printMessage(); + return false; + } + + try + { + mMidiOut = std::make_unique(); + } + catch (RtMidiError &error) + { + mMidiOut = nullptr; + error.printMessage(); + return false; + } + + mMidiIn->setCallback(&MIDICallback, this); + mMidiIn->ignoreTypes(false, true, false ); + + return true; +} + +void ApplyFades(double *pBuffer, int nChans, int nFrames, bool down) +{ + for (int i = 0; i < nChans; i++) + { + double *pIO = pBuffer + (i * nFrames); + + if (down) + { + for (int j = 0; j < nFrames; j++) + pIO[j] *= ((double) (nFrames - (j + 1)) / (double) nFrames); + } + else + { + for (int j = 0; j < nFrames; j++) + pIO[j] *= ((double) j / (double) nFrames); + } + } +} + +// static +int IPlugAPPHost::AudioCallback(void* pOutputBuffer, void* pInputBuffer, uint32_t nFrames, double streamTime, RtAudioStreamStatus status, void* pUserData) +{ + IPlugAPPHost* _this = (IPlugAPPHost*) pUserData; + + int nins = _this->GetPlug()->MaxNChannels(ERoute::kInput); + int nouts = _this->GetPlug()->MaxNChannels(ERoute::kOutput); + + double* pInputBufferD = static_cast(pInputBuffer); + double* pOutputBufferD = static_cast(pOutputBuffer); + + bool startWait = _this->mVecWait >= APP_N_VECTOR_WAIT; // wait APP_N_VECTOR_WAIT * iovs before processing audio, to avoid clicks + bool doFade = _this->mVecWait == APP_N_VECTOR_WAIT || _this->mAudioEnding; + + if (startWait && !_this->mAudioDone) + { + if (doFade) + ApplyFades(pInputBufferD, nins, nFrames, _this->mAudioEnding); + + for (int i = 0; i < nFrames; i++) + { + _this->mBufIndex %= APP_SIGNAL_VECTOR_SIZE; + + if (_this->mBufIndex == 0) + { + for (int c = 0; c < nins; c++) + { + _this->mInputBufPtrs.Set(c, (pInputBufferD + (c * nFrames)) + i); + } + + for (int c = 0; c < nouts; c++) + { + _this->mOutputBufPtrs.Set(c, (pOutputBufferD + (c * nFrames)) + i); + } + + _this->mIPlug->AppProcess(_this->mInputBufPtrs.GetList(), _this->mOutputBufPtrs.GetList(), APP_SIGNAL_VECTOR_SIZE); + + _this->mSamplesElapsed += APP_SIGNAL_VECTOR_SIZE; + } + + for (int c = 0; c < nouts; c++) + { + pOutputBufferD[c * nFrames + i] *= APP_MULT; + } + + _this->mBufIndex++; + } + + if (doFade) + ApplyFades(pOutputBufferD, nouts, nFrames, _this->mAudioEnding); + + if (_this->mAudioEnding) + _this->mAudioDone = true; + } + else + { + memset(pOutputBufferD, 0, nFrames * nouts * sizeof(double)); + } + + _this->mVecWait = std::min(_this->mVecWait + 1, uint32_t(APP_N_VECTOR_WAIT + 1)); + + return 0; +} + +// static +void IPlugAPPHost::MIDICallback(double deltatime, std::vector* pMsg, void* pUserData) +{ + IPlugAPPHost* _this = (IPlugAPPHost*) pUserData; + + if (pMsg->size() == 0 || _this->mExiting) + return; + + if (pMsg->size() > 3) + { + if(pMsg->size() > MAX_SYSEX_SIZE) + { + DBGMSG("SysEx message exceeds MAX_SYSEX_SIZE\n"); + return; + } + + SysExData data { 0, static_cast(pMsg->size()), pMsg->data() }; + + _this->mIPlug->mSysExMsgsFromCallback.Push(data); + return; + } + else if (pMsg->size()) + { + IMidiMsg msg; + msg.mStatus = pMsg->at(0); + pMsg->size() > 1 ? msg.mData1 = pMsg->at(1) : msg.mData1 = 0; + pMsg->size() > 2 ? msg.mData2 = pMsg->at(2) : msg.mData2 = 0; + + _this->mIPlug->mMidiMsgsFromCallback.Push(msg); + } +} + +// static +void IPlugAPPHost::ErrorCallback(RtAudioError::Type type, const std::string &errorText ) +{ + //TODO: +} + diff --git a/NeuralAmpModeler/app/IPlugAPP_host.h b/NeuralAmpModeler/app/IPlugAPP_host.h new file mode 100644 index 000000000..046e1f2b9 --- /dev/null +++ b/NeuralAmpModeler/app/IPlugAPP_host.h @@ -0,0 +1,261 @@ +/* + ============================================================================== + + This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers. + + See LICENSE.txt for more info. + + ============================================================================== +*/ + +#pragma once + +/** + + IPlug plug-in -> Standalone app wrapper, using Cockos' SWELL + + Oli Larkin 2014-2018 + + Notes: + + App settings are stored in a .ini (text) file. The location is as follows: + + Windows7: C:\Users\USERNAME\AppData\Local\BUNDLE_NAME\settings.ini + Windows XP/Vista: C:\Documents and Settings\USERNAME\Local Settings\Application Data\BUNDLE_NAME\settings.ini + macOS: /Users/USERNAME/Library/Application\ Support/BUNDLE_NAME/settings.ini + OR + /Users/USERNAME/Library/Containers/BUNDLE_ID/Data/Library/Application Support/BUNDLE_NAME/settings.ini + + */ + +#include +#include +#include +#include +#include + +#include "wdltypes.h" +#include "wdlstring.h" + +#include "IPlugPlatform.h" +#include "IPlugConstants.h" + +#include "IPlugAPP.h" + +#include "config.h" + +#ifdef OS_WIN + #include + #include + #include + #define DEFAULT_INPUT_DEV "Default Device" + #define DEFAULT_OUTPUT_DEV "Default Device" +#elif defined(OS_MAC) + #include "IPlugSWELL.h" + #define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) ) + #define DEFAULT_INPUT_DEV "Built-in Input" + #define DEFAULT_OUTPUT_DEV "Built-in Output" +#elif defined(OS_LINUX) + #include "IPlugSWELL.h" +#endif + +#include "RtAudio.h" +#include "RtMidi.h" + +#define OFF_TEXT "off" + +extern HWND gHWND; +extern HINSTANCE gHINSTANCE; + +BEGIN_IPLUG_NAMESPACE + +const int kNumBufferSizeOptions = 11; +const std::string kBufferSizeOptions[kNumBufferSizeOptions] = {"32", "64", "96", "128", "192", "256", "512", "1024", "2048", "4096", "8192" }; +const int kDeviceDS = 0; const int kDeviceCoreAudio = 0; const int kDeviceAlsa = 0; +const int kDeviceASIO = 1; const int kDeviceJack = 1; +extern UINT gSCROLLMSG; + +class IPlugAPP; + +/** A class that hosts an IPlug as a standalone app and provides Audio/Midi I/O */ +class IPlugAPPHost +{ +public: + + /** Used to manage changes to app i/o */ + struct AppState + { + WDL_String mAudioInDev; + WDL_String mAudioOutDev; + WDL_String mMidiInDev; + WDL_String mMidiOutDev; + uint32_t mAudioDriverType; + uint32_t mAudioSR; + uint32_t mBufferSize; + uint32_t mMidiInChan; + uint32_t mMidiOutChan; + + uint32_t mAudioInChanL; + uint32_t mAudioInChanR; + uint32_t mAudioOutChanL; + uint32_t mAudioOutChanR; + + AppState() + : mAudioInDev(DEFAULT_INPUT_DEV) + , mAudioOutDev(DEFAULT_OUTPUT_DEV) + , mMidiInDev(OFF_TEXT) + , mMidiOutDev(OFF_TEXT) + , mAudioDriverType(0) // DirectSound / CoreAudio by default + , mBufferSize(512) + , mAudioSR(44100) + , mMidiInChan(0) + , mMidiOutChan(0) + + , mAudioInChanL(1) + , mAudioInChanR(2) + , mAudioOutChanL(1) + , mAudioOutChanR(2) + { + } + + AppState (const AppState& obj) + : mAudioInDev(obj.mAudioInDev.Get()) + , mAudioOutDev(obj.mAudioOutDev.Get()) + , mMidiInDev(obj.mMidiInDev.Get()) + , mMidiOutDev(obj.mMidiOutDev.Get()) + , mAudioDriverType(obj.mAudioDriverType) + , mBufferSize(obj.mBufferSize) + , mAudioSR(obj.mAudioSR) + , mMidiInChan(obj.mMidiInChan) + , mMidiOutChan(obj.mMidiOutChan) + + , mAudioInChanL(obj.mAudioInChanL) + , mAudioInChanR(obj.mAudioInChanR) + , mAudioOutChanL(obj.mAudioInChanL) + , mAudioOutChanR(obj.mAudioInChanR) + { + } + + bool operator==(const AppState& rhs) const { + return (rhs.mAudioDriverType == mAudioDriverType && + rhs.mBufferSize == mBufferSize && + rhs.mAudioSR == mAudioSR && + rhs.mMidiInChan == mMidiInChan && + rhs.mMidiOutChan == mMidiOutChan && + (strcmp(rhs.mAudioInDev.Get(), mAudioInDev.Get()) == 0) && + (strcmp(rhs.mAudioOutDev.Get(), mAudioOutDev.Get()) == 0) && + (strcmp(rhs.mMidiInDev.Get(), mMidiInDev.Get()) == 0) && + (strcmp(rhs.mMidiOutDev.Get(), mMidiOutDev.Get()) == 0) && + + rhs.mAudioInChanL == mAudioInChanL && + rhs.mAudioInChanR == mAudioInChanR && + rhs.mAudioOutChanL == mAudioOutChanL && + rhs.mAudioOutChanR == mAudioOutChanR + + ); + } + bool operator!=(const AppState& rhs) const { return !operator==(rhs); } + }; + + static IPlugAPPHost* Create(); + static std::unique_ptr sInstance; + + void PopulateSampleRateList(HWND hwndDlg, RtAudio::DeviceInfo* pInputDevInfo, RtAudio::DeviceInfo* pOutputDevInfo); + void PopulateAudioInputList(HWND hwndDlg, RtAudio::DeviceInfo* pInfo); + void PopulateAudioOutputList(HWND hwndDlg, RtAudio::DeviceInfo* pInfo); + void PopulateDriverSpecificControls(HWND hwndDlg); + void PopulateAudioDialogs(HWND hwndDlg); + bool PopulateMidiDialogs(HWND hwndDlg); + void PopulatePreferencesDialog(HWND hwndDlg); + + IPlugAPPHost(); + ~IPlugAPPHost(); + + bool OpenWindow(HWND pParent); + void CloseWindow(); + + bool Init(); + bool InitState(); + void UpdateINI(); + + /** Returns the name of the audio device at idx + * @param idx The index RTAudio has given the audio device + * @return The device name. Core Audio device names are truncated. */ + std::string GetAudioDeviceName(int idx) const; + // returns the rtaudio device ID, based on the (truncated) device name + + /** Returns the audio device index linked to a particular name + * @param name The name of the audio device to test + * @return The integer index RTAudio has given the audio device */ + int GetAudioDeviceIdx(const char* name) const; + + /** @param direction Either kInput or kOutput + * @param name The name of the midi device + * @return An integer specifying the output port number, where 0 means any */ + int GetMIDIPortNumber(ERoute direction, const char* name) const; + + /** find out which devices have input channels & which have output channels, add their ids to the lists */ + void ProbeAudioIO(); + void ProbeMidiIO(); + bool InitMidi(); + void CloseAudio(); + bool InitAudio(uint32_t inId, uint32_t outId, uint32_t sr, uint32_t iovs); + bool AudioSettingsInStateAreEqual(AppState& os, AppState& ns); + bool MIDISettingsInStateAreEqual(AppState& os, AppState& ns); + + bool TryToChangeAudioDriverType(); + bool TryToChangeAudio(); + bool SelectMIDIDevice(ERoute direction, const char* portName); + + static int AudioCallback(void* pOutputBuffer, void* pInputBuffer, uint32_t nFrames, double streamTime, RtAudioStreamStatus status, void* pUserData); + static void MIDICallback(double deltatime, std::vector* pMsg, void* pUserData); + static void ErrorCallback(RtAudioError::Type type, const std::string& errorText); + + static WDL_DLGRET PreferencesDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + static WDL_DLGRET MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + + IPlugAPP* GetPlug() { return mIPlug.get(); } +private: + std::unique_ptr mIPlug = nullptr; + std::unique_ptr mDAC = nullptr; + std::unique_ptr mMidiIn = nullptr; + std::unique_ptr mMidiOut = nullptr; + int mMidiOutChannel = -1; + int mMidiInChannel = -1; + + /** */ + AppState mState; + /** When the preferences dialog is opened the existing state is cached here, and restored if cancel is pressed */ + AppState mTempState; + /** When the audio driver is started the current state is copied here so that if OK is pressed after APPLY nothing is changed */ + AppState mActiveState; + + double mSampleRate = 44100.; + uint32_t mSamplesElapsed = 0; + uint32_t mVecWait = 0; + uint32_t mBufferSize = 512; + uint32_t mBufIndex = 0; // index for signal vector, loops from 0 to mSigVS + bool mExiting = false; + bool mAudioEnding = false; + bool mAudioDone = false; + + /** The index of the operating systems default input device, -1 if not detected */ + int32_t mDefaultInputDev = -1; + /** The index of the operating systems default output device, -1 if not detected */ + int32_t mDefaultOutputDev = -1; + + WDL_String mINIPath; + + std::vector mAudioInputDevs; + std::vector mAudioOutputDevs; + std::vector mAudioIDDevNames; + std::vector mMidiInputDevNames; + std::vector mMidiOutputDevNames; + + WDL_PtrList mInputBufPtrs; + WDL_PtrList mOutputBufPtrs; + + friend class IPlugAPP; +}; + +END_IPLUG_NAMESPACE diff --git a/NeuralAmpModeler/app/IPlugAPP_main.cpp b/NeuralAmpModeler/app/IPlugAPP_main.cpp new file mode 100644 index 000000000..3010993da --- /dev/null +++ b/NeuralAmpModeler/app/IPlugAPP_main.cpp @@ -0,0 +1,421 @@ +/* + ============================================================================== + + This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers. + + See LICENSE.txt for more info. + + ============================================================================== +*/ + +#include +#include "wdltypes.h" +#include "wdlstring.h" + +#include "IPlugPlatform.h" +#include "IPlugAPP_host.h" + +#include "config.h" +#include "resource.h" + +using namespace iplug; + +#pragma mark - WINDOWS +#if defined OS_WIN +#include +#include + +extern WDL_DLGRET MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +HWND gHWND; +extern HINSTANCE gHINSTANCE; +UINT gScrollMessage; + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nShowCmd) +{ + try + { +#ifndef APP_ALLOW_MULTIPLE_INSTANCES + HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, BUNDLE_NAME); // BUNDLE_NAME used because it won't have spaces in it + + if (!hMutex) + hMutex = CreateMutex(0, 0, BUNDLE_NAME); + else + { + HWND hWnd = FindWindow(0, BUNDLE_NAME); + SetForegroundWindow(hWnd); + return 0; + } +#endif + gHINSTANCE = hInstance; + + InitCommonControls(); + gScrollMessage = RegisterWindowMessage("MSWHEEL_ROLLMSG"); + + IPlugAPPHost* pAppHost = IPlugAPPHost::Create(); + pAppHost->Init(); + pAppHost->TryToChangeAudio(); + + HACCEL hAccel = LoadAccelerators(gHINSTANCE, MAKEINTRESOURCE(IDR_ACCELERATOR1)); + + static UINT(WINAPI *__SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); + + double scale = 1.; + + if (!__SetProcessDpiAwarenessContext) + { + HINSTANCE h = LoadLibrary("user32.dll"); + if (h) *(void **)&__SetProcessDpiAwarenessContext = GetProcAddress(h, "SetProcessDpiAwarenessContext"); + if (!__SetProcessDpiAwarenessContext) + *(void **)&__SetProcessDpiAwarenessContext = (void*)(INT_PTR)1; + } + if ((UINT_PTR)__SetProcessDpiAwarenessContext > (UINT_PTR)1) + { + __SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + } + + CreateDialog(gHINSTANCE, MAKEINTRESOURCE(IDD_DIALOG_MAIN), GetDesktopWindow(), IPlugAPPHost::MainDlgProc); + +#if !defined _DEBUG || defined NO_IGRAPHICS + HMENU menu = GetMenu(gHWND); + RemoveMenu(menu, 1, MF_BYPOSITION); + DrawMenuBar(gHWND); +#endif + + for(;;) + { + MSG msg= {0,}; + int vvv = GetMessage(&msg, NULL, 0, 0); + + if (!vvv) + break; + + if (vvv < 0) + { + Sleep(10); + continue; + } + + if (!msg.hwnd) + { + DispatchMessage(&msg); + continue; + } + + if (gHWND && (TranslateAccelerator(gHWND, hAccel, &msg) || IsDialogMessage(gHWND, &msg))) + continue; + + // default processing for other dialogs + HWND hWndParent = NULL; + HWND temphwnd = msg.hwnd; + + do + { + if (GetClassLong(temphwnd, GCW_ATOM) == (INT)32770) + { + hWndParent = temphwnd; + if (!(GetWindowLong(temphwnd, GWL_STYLE) & WS_CHILD)) + break; // not a child, exit + } + } + while (temphwnd = GetParent(temphwnd)); + + if (hWndParent && IsDialogMessage(hWndParent,&msg)) + continue; + + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + // in case gHWND didnt get destroyed -- this corresponds to SWELLAPP_DESTROY roughly + if (gHWND) + DestroyWindow(gHWND); + +#ifndef APP_ALLOW_MULTIPLE_INSTANCES + ReleaseMutex(hMutex); +#endif + } + catch(std::exception e) + { + DBGMSG("Exception: %s", e.what()); + return 1; + } + return 0; +} +#pragma mark - MAC +#elif defined(OS_MAC) +#import +#include "IPlugSWELL.h" +#include "IPlugPaths.h" + +HWND gHWND; +extern HMENU SWELL_app_stocksysmenu; + +int main(int argc, char *argv[]) +{ +#if APP_COPY_AUV3 + //if invoked with an argument registerauv3 use plug-in kit to explicitly register auv3 app extension (doesn't happen from debugger) + if(strcmp(argv[2], "registerauv3")) + { + WDL_String appexPath; + appexPath.SetFormatted(1024, "pluginkit -a %s%s%s.appex", argv[0], "/../../Plugins/", appexPath.get_filepart()); + if(system(appexPath.Get()) > -1) + NSLog(@"Registered audiounit app extension\n"); + else + NSLog(@"Failed to register audiounit app extension\n"); + } +#endif + + if(AppIsSandboxed()) + DBGMSG("App is sandboxed, file system access etc restricted!\n"); + + return NSApplicationMain(argc, (const char **) argv); +} + +INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2) +{ + IPlugAPPHost* pAppHost = nullptr; + + switch (msg) + { + case SWELLAPP_ONLOAD: + pAppHost = IPlugAPPHost::Create(); + pAppHost->Init(); + pAppHost->TryToChangeAudio(); + break; + case SWELLAPP_LOADED: + { + pAppHost = IPlugAPPHost::sInstance.get(); + + HMENU menu = SWELL_GetCurrentMenu(); + + if (menu) + { + // work on a new menu + menu = SWELL_DuplicateMenu(menu); + HMENU src = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MENU1)); + + for (int x = 0; x < GetMenuItemCount(src)-1; x++) + { + HMENU sm = GetSubMenu(src,x); + + if (sm) + { + char str[1024]; + MENUITEMINFO mii = {sizeof(mii), MIIM_TYPE}; + mii.dwTypeData = str; + mii.cch = sizeof(str); + str[0] = 0; + GetMenuItemInfo(src, x, TRUE, &mii); + MENUITEMINFO mi= {sizeof(mi), MIIM_STATE|MIIM_SUBMENU|MIIM_TYPE,MFT_STRING, 0, 0, SWELL_DuplicateMenu(sm), NULL, NULL, 0, str}; + InsertMenuItem(menu, x+1, TRUE, &mi); + } + } + } + + if (menu) + { + HMENU sm = GetSubMenu(menu, 1); + DeleteMenu(sm, ID_QUIT, MF_BYCOMMAND); // remove QUIT from our file menu, since it is in the system menu on OSX + DeleteMenu(sm, ID_PREFERENCES, MF_BYCOMMAND); // remove PREFERENCES from the file menu, since it is in the system menu on OSX + + // remove any trailing separators + int a = GetMenuItemCount(sm); + + while (a > 0 && GetMenuItemID(sm, a-1) == 0) + DeleteMenu(sm, --a, MF_BYPOSITION); + + DeleteMenu(menu, 1, MF_BYPOSITION); // delete file menu + } +#if !defined _DEBUG || defined NO_IGRAPHICS + if (menu) + { + HMENU sm = GetSubMenu(menu, 1); + DeleteMenu(sm, ID_LIVE_EDIT, MF_BYCOMMAND); + DeleteMenu(sm, ID_SHOW_DRAWN, MF_BYCOMMAND); + DeleteMenu(sm, ID_SHOW_FPS, MF_BYCOMMAND); + + // remove any trailing separators + int a = GetMenuItemCount(sm); + + while (a > 0 && GetMenuItemID(sm, a-1) == 0) + DeleteMenu(sm, --a, MF_BYPOSITION); + + DeleteMenu(menu, 1, MF_BYPOSITION); // delete debug menu + } +#else + SetMenuItemModifier(menu, ID_LIVE_EDIT, MF_BYCOMMAND, 'E', FCONTROL); + SetMenuItemModifier(menu, ID_SHOW_DRAWN, MF_BYCOMMAND, 'D', FCONTROL); + SetMenuItemModifier(menu, ID_SHOW_BOUNDS, MF_BYCOMMAND, 'B', FCONTROL); + SetMenuItemModifier(menu, ID_SHOW_FPS, MF_BYCOMMAND, 'F', FCONTROL); +#endif + + HWND hwnd = CreateDialog(gHINST, MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL, IPlugAPPHost::MainDlgProc); + + if (menu) + { + SetMenu(hwnd, menu); // set the menu for the dialog to our menu (on Windows that menu is set from the .rc, but on SWELL + SWELL_SetDefaultModalWindowMenu(menu); // other windows will get the stock (bundle) menus + } + + break; + } + case SWELLAPP_ONCOMMAND: + // this is to catch commands coming from the system menu etc + if (gHWND && (parm1&0xffff)) + SendMessage(gHWND, WM_COMMAND, parm1 & 0xffff, 0); + break; + case SWELLAPP_DESTROY: + if (gHWND) + DestroyWindow(gHWND); + break; + case SWELLAPP_PROCESSMESSAGE: + MSG* pMSG = (MSG*) parm1; + NSView* pContentView = (NSView*) pMSG->hwnd; + NSEvent* pEvent = (NSEvent*) parm2; + int etype = (int) [pEvent type]; + + bool textField = [pContentView isKindOfClass:[NSText class]]; + + if (!textField && etype == NSKeyDown) + { + int flag, code = SWELL_MacKeyToWindowsKey(pEvent, &flag); + + if (!(flag&~FVIRTKEY) && (code == VK_RETURN || code == VK_ESCAPE)) + { + [pContentView keyDown: pEvent]; + return 1; + } + } + break; + } + return 0; +} + +#define CBS_HASSTRINGS 0 +#define SWELL_DLG_SCALE_AUTOGEN 1 +#define SET_IDD_DIALOG_PREF_SCALE 1.5 +#if PLUG_HOST_RESIZE +#define SWELL_DLG_FLAGS_AUTOGEN SWELL_DLG_WS_FLIPPED|SWELL_DLG_WS_RESIZABLE +#endif +#include "swell-dlggen.h" +#include "resources/main.rc_mac_dlg" +#include "swell-menugen.h" +#include "resources/main.rc_mac_menu" + +#pragma mark - LINUX +#elif defined(OS_LINUX) +//#include +//#include "swell-internal.h" // fixes problem with HWND forward decl +// +//HWND gHWND; +//UINT gScrollMessage; +//extern HMENU SWELL_app_stocksysmenu; +// +//int main(int argc, char **argv) +//{ +// SWELL_initargs(&argc, &argv); +// SWELL_Internal_PostMessage_Init(); +// SWELL_ExtendedAPI("APPNAME", (void*) "IGraphics Test"); +// +// HMENU menu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MENU1)); +// CreateDialog(gHINSTANCE, MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL, MainDlgProc); +// SetMenu(gHWND, menu); +// +// while (!gHWND->m_hashaddestroy) +// { +// SWELL_RunMessageLoop(); +// Sleep(10); +// }; +// +// if (gHWND) +// DestroyWindow(gHWND); +// +// return 0; +//} +// +//INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2) +//{ +// switch (msg) +// { +// case SWELLAPP_ONLOAD: +// break; +// case SWELLAPP_LOADED: +// { +// HMENU menu = SWELL_GetCurrentMenu(); +// +// if (menu) +// { +// // work on a new menu +// menu = SWELL_DuplicateMenu(menu); +// HMENU src = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MENU1)); +// +// for (auto x = 0; x < GetMenuItemCount(src)-1; x++) +// { +// HMENU sm = GetSubMenu(src,x); +// if (sm) +// { +// char str[1024]; +// MENUITEMINFO mii = {sizeof(mii), MIIM_TYPE}; +// mii.dwTypeData = str; +// mii.cch = sizeof(str); +// str[0] = 0; +// GetMenuItemInfo(src, x, TRUE, &mii); +// MENUITEMINFO mi= {sizeof(mi), MIIM_STATE|MIIM_SUBMENU|MIIM_TYPE,MFT_STRING, 0, 0, SWELL_DuplicateMenu(sm), NULL, NULL, 0, str}; +// InsertMenuItem(menu, x+1, TRUE, &mi); +// } +// } +// } +// +// if (menu) +// { +// HMENU sm = GetSubMenu(menu, 1); +// DeleteMenu(sm, ID_QUIT, MF_BYCOMMAND); // remove QUIT from our file menu, since it is in the system menu on OSX +// DeleteMenu(sm, ID_PREFERENCES, MF_BYCOMMAND); // remove PREFERENCES from the file menu, since it is in the system menu on OSX +// +// // remove any trailing separators +// int a = GetMenuItemCount(sm); +// +// while (a > 0 && GetMenuItemID(sm, a-1) == 0) +// DeleteMenu(sm, --a, MF_BYPOSITION); +// +// DeleteMenu(menu, 1, MF_BYPOSITION); // delete file menu +// } +// +// // if we want to set any default modifiers for items in the menus, we can use: +// // SetMenuItemModifier(menu,commandID,MF_BYCOMMAND,'A',FCONTROL) etc. +// +// HWND hwnd = CreateDialog(gHINST,MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL, MainDlgProc); +// +// if (menu) +// { +// SetMenu(hwnd, menu); // set the menu for the dialog to our menu (on Windows that menu is set from the .rc, but on SWELL +// SWELL_SetDefaultModalWindowMenu(menu); // other windows will get the stock (bundle) menus +// } +// +// break; +// } +// case SWELLAPP_ONCOMMAND: +// // this is to catch commands coming from the system menu etc +// if (gHWND && (parm1&0xffff)) +// SendMessage(gHWND, WM_COMMAND, parm1 & 0xffff, 0); +// break; +// case SWELLAPP_DESTROY: +// if (gHWND) +// DestroyWindow(gHWND); +// break; +// case SWELLAPP_PROCESSMESSAGE: // can hook keyboard input here +// // parm1 = (MSG*), should we want it -- look in swell.h to see what the return values refer to +// break; +// } +// return 0; +//} +// +//#define CBS_HASSTRINGS 0 +//#define SWELL_DLG_SCALE_AUTOGEN 1 +//#define SET_IDD_DIALOG_PREF_SCALE 1.5 +//#include "swell-dlggen.h" +//#include "resources/main.rc_mac_dlg" +//#include "swell-menugen.h" +//#include "resources/main.rc_mac_menu" +#endif diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj b/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj index 2639dd949..f62ad2960 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj @@ -301,7 +301,6 @@ - @@ -319,6 +318,7 @@ + @@ -376,15 +376,15 @@ - - - + + + diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj.filters b/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj.filters index f55ded252..6921e4179 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj.filters +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj.filters @@ -35,15 +35,6 @@ IPlug\APP - - IPlug\APP - - - IPlug\APP - - - IPlug\APP - IPlug\APP\RTAudioMidi @@ -114,6 +105,15 @@ dsp + + app + + + app + + + app + @@ -217,9 +217,6 @@ IPlug\APP - - IPlug\APP - IPlug\APP\RTAudioMidi @@ -364,6 +361,9 @@ NAM + + app + @@ -414,6 +414,9 @@ {f22f96a8-fd44-4509-987d-7683e32f3592} + + {720c216c-fbf2-49d7-a507-e5bb64c99c87} + diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-macOS.xcodeproj/project.pbxproj b/NeuralAmpModeler/projects/NeuralAmpModeler-macOS.xcodeproj/project.pbxproj index 759cacc84..409bc9be6 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-macOS.xcodeproj/project.pbxproj +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-macOS.xcodeproj/project.pbxproj @@ -61,7 +61,6 @@ 4F1A5285205D914A00CF2908 /* IPlugAAX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F1A5284205D914A00CF2908 /* IPlugAAX.cpp */; }; 4F1A528C205D916F00CF2908 /* IPlugAU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F1A528A205D916F00CF2908 /* IPlugAU.cpp */; }; 4F1B4AE42014D33600BC64D4 /* NeuralAmpModeler-macOS-MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4F1B4AE32014D33600BC64D4 /* NeuralAmpModeler-macOS-MainMenu.xib */; }; - 4F2EA978203A50EA008E4850 /* IPlugAPP_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F2EA977203A50E9008E4850 /* IPlugAPP_dialog.cpp */; }; 4F2FB1542A0047420027AB66 /* Resample.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F2FB13A2A0047420027AB66 /* Resample.h */; }; 4F2FB1552A0047420027AB66 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F2FB13B2A0047420027AB66 /* RecursiveLinearFilter.cpp */; }; 4F2FB1562A0047420027AB66 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F2FB13B2A0047420027AB66 /* RecursiveLinearFilter.cpp */; }; @@ -210,13 +209,10 @@ 4F3EE1D2231438D000004786 /* swell-misc.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D3F13B635A0001D0217 /* swell-misc.mm */; settings = {COMPILER_FLAGS = "-Wno-unreachable-code -Wno-shorten-64-to-32"; }; }; 4F3EE1D3231438D000004786 /* swell-wnd.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D4113B635AB001D0217 /* swell-wnd.mm */; settings = {COMPILER_FLAGS = "-Wno-unreachable-code -Wno-shorten-64-to-32"; }; }; 4F3EE1D4231438D000004786 /* swell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D4313B635B2001D0217 /* swell.cpp */; settings = {COMPILER_FLAGS = "-Wno-unreachable-code -Wno-shorten-64-to-32"; }; }; - 4F3EE1D5231438D000004786 /* IPlugAPP_host.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F690CA2203A45C700A4A13E /* IPlugAPP_host.cpp */; }; 4F3EE1D6231438D000004786 /* IPlugAPP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F1A5280205D913300CF2908 /* IPlugAPP.cpp */; }; 4F3EE1D7231438D000004786 /* IGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F03A55820A4621000EBDFFB /* IGraphics.cpp */; }; - 4F3EE1D8231438D000004786 /* IPlugAPP_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F2EA977203A50E9008E4850 /* IPlugAPP_dialog.cpp */; }; 4F3EE1D9231438D000004786 /* RtAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F10D3D3203A6711003EF82A /* RtAudio.cpp */; settings = {COMPILER_FLAGS = "-Wno-shorten-64-to-32"; }; }; 4F3EE1DA231438D000004786 /* IGraphicsCoreText.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F6FD2AF22675B6300FC59E6 /* IGraphicsCoreText.mm */; }; - 4F3EE1DB231438D000004786 /* IPlugAPP_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F690C9A203A345100A4A13E /* IPlugAPP_main.cpp */; }; 4F3EE1DD231438D000004786 /* IGraphicsMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FB1F58120E4AFEE004157C8 /* IGraphicsMac.mm */; }; 4F3EE1DE231438D000004786 /* NeuralAmpModeler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F3862ED2014BBEC0009F402 /* NeuralAmpModeler.cpp */; }; 4F3EE1E0231438D000004786 /* IPlugAPIBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8ED13B63BA40032E0F3 /* IPlugAPIBase.cpp */; }; @@ -233,6 +229,12 @@ 4F4856892773CA76005BCF8E /* NeuralAmpModelerAUv3Appex.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F4856812773BD16005BCF8E /* NeuralAmpModelerAUv3Appex.m */; }; 4F5C5F6921BED05B00E024A7 /* swellappmain.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D4613B635C8001D0217 /* swellappmain.mm */; }; 4F5C5F6B21BED08700E024A7 /* swell-appstub.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F5C5F6A21BED08700E024A7 /* swell-appstub.mm */; }; + 4F5C68022D871C4C009B81A1 /* IPlugAPP_host.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F5C67FF2D871C4C009B81A1 /* IPlugAPP_host.cpp */; }; + 4F5C68032D871C4C009B81A1 /* IPlugAPP_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F5C67FD2D871C4C009B81A1 /* IPlugAPP_dialog.cpp */; }; + 4F5C68042D871C4C009B81A1 /* IPlugAPP_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F5C68002D871C4C009B81A1 /* IPlugAPP_main.cpp */; }; + 4F5C68052D871C4C009B81A1 /* IPlugAPP_host.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F5C67FF2D871C4C009B81A1 /* IPlugAPP_host.cpp */; }; + 4F5C68062D871C4C009B81A1 /* IPlugAPP_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F5C67FD2D871C4C009B81A1 /* IPlugAPP_dialog.cpp */; }; + 4F5C68072D871C4C009B81A1 /* IPlugAPP_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F5C68002D871C4C009B81A1 /* IPlugAPP_main.cpp */; }; 4F5F344120C0226200487201 /* IPlugPaths.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F5F344020C0226200487201 /* IPlugPaths.mm */; }; 4F5F344220C0226200487201 /* IPlugPaths.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F5F344020C0226200487201 /* IPlugPaths.mm */; }; 4F5F344320C0226200487201 /* IPlugPaths.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F5F344020C0226200487201 /* IPlugPaths.mm */; }; @@ -251,8 +253,6 @@ 4F6369EE20A466470022C370 /* IControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F6369E920A466470022C370 /* IControl.cpp */; }; 4F6369EF20A466470022C370 /* IControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F6369E920A466470022C370 /* IControl.cpp */; }; 4F6369F120A466470022C370 /* IControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F6369E920A466470022C370 /* IControl.cpp */; }; - 4F690C9B203A345100A4A13E /* IPlugAPP_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F690C9A203A345100A4A13E /* IPlugAPP_main.cpp */; }; - 4F690CA3203A45C700A4A13E /* IPlugAPP_host.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F690CA2203A45C700A4A13E /* IPlugAPP_host.cpp */; }; 4F6FD2B022675B6300FC59E6 /* IGraphicsCoreText.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F6FD2AD22675B6300FC59E6 /* IGraphicsCoreText.h */; }; 4F6FD2B122675B6300FC59E6 /* IGraphicsCoreText.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F6FD2AF22675B6300FC59E6 /* IGraphicsCoreText.mm */; }; 4F6FD2B222675B6300FC59E6 /* IGraphicsCoreText.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F6FD2AF22675B6300FC59E6 /* IGraphicsCoreText.mm */; }; @@ -650,7 +650,6 @@ 4F23BA1313B647E50097A67E /* NeuralAmpModeler-AU-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "NeuralAmpModeler-AU-Info.plist"; path = "../resources/NeuralAmpModeler-AU-Info.plist"; sourceTree = ""; }; 4F23BA1413B647E50097A67E /* NeuralAmpModeler-macOS-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "NeuralAmpModeler-macOS-Info.plist"; path = "../resources/NeuralAmpModeler-macOS-Info.plist"; sourceTree = ""; }; 4F23BA1513B647E50097A67E /* NeuralAmpModeler-VST2-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "NeuralAmpModeler-VST2-Info.plist"; path = "../resources/NeuralAmpModeler-VST2-Info.plist"; sourceTree = ""; }; - 4F2EA977203A50E9008E4850 /* IPlugAPP_dialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugAPP_dialog.cpp; path = ../../iPlug2/IPlug/APP/IPlugAPP_dialog.cpp; sourceTree = ""; tabWidth = 2; }; 4F2FB13A2A0047420027AB66 /* Resample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Resample.h; sourceTree = ""; }; 4F2FB13B2A0047420027AB66 /* RecursiveLinearFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecursiveLinearFilter.cpp; sourceTree = ""; }; 4F2FB13C2A0047420027AB66 /* wav.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wav.h; sourceTree = ""; }; @@ -704,13 +703,14 @@ 4F4CC38D1549B92900A9EA21 /* AAXLibrary_common_release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = AAXLibrary_common_release.xcconfig; path = ../../iPlug2/Dependencies/IPlug/AAX_SDK/Libs/AAXLibrary/MacBuild/AAXLibrary_common_release.xcconfig; sourceTree = SOURCE_ROOT; }; 4F4CC4401549C15500A9EA21 /* IPlugAAX_Describe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugAAX_Describe.cpp; path = ../../iPlug2/IPlug/AAX/IPlugAAX_Describe.cpp; sourceTree = SOURCE_ROOT; tabWidth = 2; }; 4F5C5F6A21BED08700E024A7 /* swell-appstub.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-appstub.mm"; path = "../../iPlug2/WDL/swell/swell-appstub.mm"; sourceTree = ""; }; + 4F5C67FD2D871C4C009B81A1 /* IPlugAPP_dialog.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = IPlugAPP_dialog.cpp; sourceTree = ""; }; + 4F5C67FE2D871C4C009B81A1 /* IPlugAPP_host.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IPlugAPP_host.h; sourceTree = ""; }; + 4F5C67FF2D871C4C009B81A1 /* IPlugAPP_host.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = IPlugAPP_host.cpp; sourceTree = ""; }; + 4F5C68002D871C4C009B81A1 /* IPlugAPP_main.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = IPlugAPP_main.cpp; sourceTree = ""; }; 4F5F344020C0226200487201 /* IPlugPaths.mm */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.objcpp; name = IPlugPaths.mm; path = ../../iPlug2/IPlug/IPlugPaths.mm; sourceTree = ""; tabWidth = 2; }; 4F6369DC20A464BB0022C370 /* IGraphicsNanoVG_src.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGraphicsNanoVG_src.m; sourceTree = ""; }; 4F6369E820A466470022C370 /* IControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IControl.h; path = ../../iPlug2/IGraphics/IControl.h; sourceTree = ""; }; 4F6369E920A466470022C370 /* IControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IControl.cpp; path = ../../iPlug2/IGraphics/IControl.cpp; sourceTree = ""; }; - 4F690C9A203A345100A4A13E /* IPlugAPP_main.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; indentWidth = 2; name = IPlugAPP_main.cpp; path = ../../iPlug2/IPlug/APP/IPlugAPP_main.cpp; sourceTree = ""; tabWidth = 2; }; - 4F690CA0203A398900A4A13E /* IPlugAPP_host.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = IPlugAPP_host.h; path = ../../iPlug2/IPlug/APP/IPlugAPP_host.h; sourceTree = ""; tabWidth = 2; }; - 4F690CA2203A45C700A4A13E /* IPlugAPP_host.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugAPP_host.cpp; path = ../../iPlug2/IPlug/APP/IPlugAPP_host.cpp; sourceTree = ""; tabWidth = 2; }; 4F6D9DEB2016B7F7009E1E3E /* IPlugPlatform.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = IPlugPlatform.h; path = ../../iPlug2/IPlug/IPlugPlatform.h; sourceTree = ""; tabWidth = 2; }; 4F6FD2AD22675B6300FC59E6 /* IGraphicsCoreText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IGraphicsCoreText.h; path = ../../iPlug2/IGraphics/Platforms/IGraphicsCoreText.h; sourceTree = ""; }; 4F6FD2AF22675B6300FC59E6 /* IGraphicsCoreText.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = IGraphicsCoreText.mm; path = ../../iPlug2/IGraphics/Platforms/IGraphicsCoreText.mm; sourceTree = ""; }; @@ -1111,6 +1111,7 @@ 089C166AFE841209C02AAC07 /* IPlugExample */ = { isa = PBXGroup; children = ( + 4F5C68012D871C4C009B81A1 /* app */, 4F2FB1392A0047420027AB66 /* dsp */, 4F2FB1452A0047420027AB66 /* NAM */, AA355E2C295B688F0061AA3D /* Colors.h */, @@ -1397,6 +1398,18 @@ path = ../../iPlug2/IPlug/Extras; sourceTree = ""; }; + 4F5C68012D871C4C009B81A1 /* app */ = { + isa = PBXGroup; + children = ( + 4F5C67FD2D871C4C009B81A1 /* IPlugAPP_dialog.cpp */, + 4F5C67FE2D871C4C009B81A1 /* IPlugAPP_host.h */, + 4F5C67FF2D871C4C009B81A1 /* IPlugAPP_host.cpp */, + 4F5C68002D871C4C009B81A1 /* IPlugAPP_main.cpp */, + ); + name = app; + path = ../app; + sourceTree = SOURCE_ROOT; + }; 4F63695120A463090022C370 /* Controls */ = { isa = PBXGroup; children = ( @@ -1503,10 +1516,6 @@ 4F10D3D1203A6700003EF82A /* RTAudioMidi */, 4F1A5280205D913300CF2908 /* IPlugAPP.cpp */, 4F1A527F205D913200CF2908 /* IPlugAPP.h */, - 4F690C9A203A345100A4A13E /* IPlugAPP_main.cpp */, - 4F690CA0203A398900A4A13E /* IPlugAPP_host.h */, - 4F690CA2203A45C700A4A13E /* IPlugAPP_host.cpp */, - 4F2EA977203A50E9008E4850 /* IPlugAPP_dialog.cpp */, ); name = APP; sourceTree = ""; @@ -2726,6 +2735,9 @@ 4F3EE1C9231438D000004786 /* swellappmain.mm in Sources */, 4F3EE1CA231438D000004786 /* swell-kb.mm in Sources */, 4F3EE1CC231438D000004786 /* IPlugPaths.mm in Sources */, + 4F5C68052D871C4C009B81A1 /* IPlugAPP_host.cpp in Sources */, + 4F5C68062D871C4C009B81A1 /* IPlugAPP_dialog.cpp in Sources */, + 4F5C68072D871C4C009B81A1 /* IPlugAPP_main.cpp in Sources */, 4F3EE1CD231438D000004786 /* swell-miscdlg.mm in Sources */, 4F7C496F255DDFCB00DF7588 /* ITextEntryControl.cpp in Sources */, 4F3EE1CF231438D000004786 /* swell-menu.mm in Sources */, @@ -2739,16 +2751,13 @@ 4F3EE1D2231438D000004786 /* swell-misc.mm in Sources */, 4F3EE1D3231438D000004786 /* swell-wnd.mm in Sources */, 4F3EE1D4231438D000004786 /* swell.cpp in Sources */, - 4F3EE1D5231438D000004786 /* IPlugAPP_host.cpp in Sources */, 4F2FB15D2A0047420027AB66 /* RecursiveLinearFilter.cpp in Sources */, 4F3EE1D6231438D000004786 /* IPlugAPP.cpp in Sources */, 4F2FB17A2A0047430027AB66 /* ImpulseResponse.cpp in Sources */, 4F2FB18F2A0047430027AB66 /* util.cpp in Sources */, 4F3EE1D7231438D000004786 /* IGraphics.cpp in Sources */, - 4F3EE1D8231438D000004786 /* IPlugAPP_dialog.cpp in Sources */, 4F3EE1D9231438D000004786 /* RtAudio.cpp in Sources */, 4F3EE1DA231438D000004786 /* IGraphicsCoreText.mm in Sources */, - 4F3EE1DB231438D000004786 /* IPlugAPP_main.cpp in Sources */, 4F2FB1682A0047430027AB66 /* dsp.cpp in Sources */, 4F3EE1DD231438D000004786 /* IGraphicsMac.mm in Sources */, 4F3EE1DE231438D000004786 /* NeuralAmpModeler.cpp in Sources */, @@ -2954,6 +2963,9 @@ 4F5C5F6921BED05B00E024A7 /* swellappmain.mm in Sources */, 4FD16D3A13B63582001D0217 /* swell-kb.mm in Sources */, 4F5F344120C0226200487201 /* IPlugPaths.mm in Sources */, + 4F5C68022D871C4C009B81A1 /* IPlugAPP_host.cpp in Sources */, + 4F5C68032D871C4C009B81A1 /* IPlugAPP_dialog.cpp in Sources */, + 4F5C68042D871C4C009B81A1 /* IPlugAPP_main.cpp in Sources */, 4FD16D3C13B6358C001D0217 /* swell-miscdlg.mm in Sources */, 4F7C4957255DDFC300DF7588 /* ITextEntryControl.cpp in Sources */, 4FD16D3E13B63595001D0217 /* swell-menu.mm in Sources */, @@ -2967,16 +2979,13 @@ 4FD16D4013B635A0001D0217 /* swell-misc.mm in Sources */, 4FD16D4213B635AB001D0217 /* swell-wnd.mm in Sources */, 4FD16D4413B635B2001D0217 /* swell.cpp in Sources */, - 4F690CA3203A45C700A4A13E /* IPlugAPP_host.cpp in Sources */, 4F2FB1552A0047420027AB66 /* RecursiveLinearFilter.cpp in Sources */, 4F1A5282205D913300CF2908 /* IPlugAPP.cpp in Sources */, 4F2FB1722A0047430027AB66 /* ImpulseResponse.cpp in Sources */, 4F2FB1872A0047430027AB66 /* util.cpp in Sources */, 4F03A5AC20A4621100EBDFFB /* IGraphics.cpp in Sources */, - 4F2EA978203A50EA008E4850 /* IPlugAPP_dialog.cpp in Sources */, 4FAFFE5821495A4800A6E72D /* RtAudio.cpp in Sources */, 4F6FD2B122675B6300FC59E6 /* IGraphicsCoreText.mm in Sources */, - 4F690C9B203A345100A4A13E /* IPlugAPP_main.cpp in Sources */, 4F2FB1602A0047430027AB66 /* dsp.cpp in Sources */, 4FB1F58920E4B004004157C8 /* IGraphicsMac.mm in Sources */, 4F3862EF2014BBEC0009F402 /* NeuralAmpModeler.cpp in Sources */, @@ -4331,7 +4340,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 77BKRC84G3; + DEVELOPMENT_TEAM = 686EDA2T8T; DSTROOT = "$(APP_PATH)"; ENABLE_HARDENED_RUNTIME = YES; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -4366,7 +4375,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 77BKRC84G3; + DEVELOPMENT_TEAM = 686EDA2T8T; DSTROOT = "$(APP_PATH)"; ENABLE_HARDENED_RUNTIME = YES; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -4401,7 +4410,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 77BKRC84G3; + DEVELOPMENT_TEAM = 686EDA2T8T; DSTROOT = "$(APP_PATH)"; ENABLE_HARDENED_RUNTIME = YES; GCC_PREPROCESSOR_DEFINITIONS = (