iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IPlugAPP_host.h
1/*
2 ==============================================================================
3
4 This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5
6 See LICENSE.txt for more info.
7
8 ==============================================================================
9*/
10
11#pragma once
12
31#include <cstdlib>
32#include <string>
33#include <vector>
34#include <limits>
35#include <memory>
36#include <optional>
37
38#include "wdltypes.h"
39#include "wdlstring.h"
40
41#include "IPlugPlatform.h"
42#include "IPlugConstants.h"
43
44#include "IPlugAPP.h"
45
46#include "config.h"
47
48#ifdef OS_WIN
49 #include <WindowsX.h>
50 #include <commctrl.h>
51 #include <shlobj.h>
52 #define DEFAULT_INPUT_DEV "Default Device"
53 #define DEFAULT_OUTPUT_DEV "Default Device"
54#elif defined(OS_MAC)
55 #include "IPlugSWELL.h"
56 #define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) )
57 #define DEFAULT_INPUT_DEV "Built-in Input"
58 #define DEFAULT_OUTPUT_DEV "Built-in Output"
59#elif defined(OS_LINUX)
60 #include "IPlugSWELL.h"
61#endif
62
63#include "RtAudio.h"
64#include "RtMidi.h"
65
66#define OFF_TEXT "off"
67
68extern HWND gHWND;
69extern HINSTANCE gHINSTANCE;
70
71BEGIN_IPLUG_NAMESPACE
72
73const int kNumBufferSizeOptions = 11;
74const std::string kBufferSizeOptions[kNumBufferSizeOptions] = {"32", "64", "96", "128", "192", "256", "512", "1024", "2048", "4096", "8192" };
75const int kDeviceDS = 0; const int kDeviceCoreAudio = 0; const int kDeviceAlsa = 0;
76const int kDeviceASIO = 1; const int kDeviceJack = 1;
77extern UINT gSCROLLMSG;
78
79class IPlugAPP;
80
83{
84public:
85
87 struct AppState
88 {
89 WDL_String mAudioInDev;
90 WDL_String mAudioOutDev;
91 WDL_String mMidiInDev;
92 WDL_String mMidiOutDev;
93 uint32_t mAudioDriverType;
94 uint32_t mAudioSR;
95 uint32_t mBufferSize;
96 uint32_t mMidiInChan;
97 uint32_t mMidiOutChan;
98
99 uint32_t mAudioInChanL;
100 uint32_t mAudioInChanR;
101 uint32_t mAudioOutChanL;
102 uint32_t mAudioOutChanR;
103
104 AppState()
105 : mAudioInDev(DEFAULT_INPUT_DEV)
106 , mAudioOutDev(DEFAULT_OUTPUT_DEV)
107 , mMidiInDev(OFF_TEXT)
108 , mMidiOutDev(OFF_TEXT)
109 , mAudioDriverType(0) // DirectSound / CoreAudio by default
110 , mBufferSize(512)
111 , mAudioSR(44100)
112 , mMidiInChan(0)
113 , mMidiOutChan(0)
114
115 , mAudioInChanL(1)
116 , mAudioInChanR(2)
117 , mAudioOutChanL(1)
118 , mAudioOutChanR(2)
119 {
120 }
121
122 AppState (const AppState& obj)
123 : mAudioInDev(obj.mAudioInDev.Get())
124 , mAudioOutDev(obj.mAudioOutDev.Get())
125 , mMidiInDev(obj.mMidiInDev.Get())
126 , mMidiOutDev(obj.mMidiOutDev.Get())
127 , mAudioDriverType(obj.mAudioDriverType)
128 , mBufferSize(obj.mBufferSize)
129 , mAudioSR(obj.mAudioSR)
130 , mMidiInChan(obj.mMidiInChan)
131 , mMidiOutChan(obj.mMidiOutChan)
132
133 , mAudioInChanL(obj.mAudioInChanL)
134 , mAudioInChanR(obj.mAudioInChanR)
135 , mAudioOutChanL(obj.mAudioOutChanL)
136 , mAudioOutChanR(obj.mAudioOutChanR)
137 {
138 }
139
140 bool operator==(const AppState& rhs) const {
141 return (rhs.mAudioDriverType == mAudioDriverType &&
142 rhs.mBufferSize == mBufferSize &&
143 rhs.mAudioSR == mAudioSR &&
144 rhs.mMidiInChan == mMidiInChan &&
145 rhs.mMidiOutChan == mMidiOutChan &&
146 (std::string_view(rhs.mAudioInDev.Get()) == mAudioInDev.Get()) &&
147 (std::string_view(rhs.mAudioOutDev.Get()) == mAudioOutDev.Get()) &&
148 (std::string_view(rhs.mMidiInDev.Get()) == mMidiInDev.Get()) &&
149 (std::string_view(rhs.mMidiOutDev.Get()) == mMidiOutDev.Get()) &&
150 rhs.mAudioInChanL == mAudioInChanL &&
151 rhs.mAudioInChanR == mAudioInChanR &&
152 rhs.mAudioOutChanL == mAudioOutChanL &&
153 rhs.mAudioOutChanR == mAudioOutChanR
154 );
155 }
156 bool operator!=(const AppState& rhs) const { return !operator==(rhs); }
157 };
158
159 static IPlugAPPHost* Create();
160 static std::unique_ptr<IPlugAPPHost> sInstance;
161
162 void PopulateSampleRateList(HWND hwndDlg, RtAudio::DeviceInfo* pInputDevInfo, RtAudio::DeviceInfo* pOutputDevInfo);
163 void PopulateAudioInputList(HWND hwndDlg, RtAudio::DeviceInfo* pInfo);
164 void PopulateAudioOutputList(HWND hwndDlg, RtAudio::DeviceInfo* pInfo);
165 void PopulateDriverSpecificControls(HWND hwndDlg);
166 void PopulateAudioDialogs(HWND hwndDlg);
167 bool PopulateMidiDialogs(HWND hwndDlg);
168 void PopulatePreferencesDialog(HWND hwndDlg);
169
170 IPlugAPPHost();
172
173 bool OpenWindow(HWND pParent);
174 void CloseWindow();
175
176 bool Init();
177 bool InitState();
178 void UpdateINI();
179
183 std::string GetAudioDeviceName(uint32_t deviceID) const;
184
188 std::optional<uint32_t> GetAudioDeviceID(const char* name) const;
189
193 int GetMIDIPortNumber(ERoute direction, const char* name) const;
194
195 void ProbeAudioIO();
196 void ProbeMidiIO();
197 bool InitMidi();
198 void CloseAudio();
199 bool InitAudio(uint32_t inId, uint32_t outId, uint32_t sr, uint32_t iovs);
200 bool AudioSettingsInStateAreEqual(AppState& os, AppState& ns);
201 bool MIDISettingsInStateAreEqual(AppState& os, AppState& ns);
202
203 bool TryToChangeAudioDriverType();
204 bool TryToChangeAudio();
205 bool SelectMIDIDevice(ERoute direction, const char* portName);
206
207 static int AudioCallback(void* pOutputBuffer, void* pInputBuffer, uint32_t nFrames, double streamTime, RtAudioStreamStatus status, void* pUserData);
208 static void MIDICallback(double deltatime, std::vector<uint8_t>* pMsg, void* pUserData);
209 static void ErrorCallback(RtAudioErrorType type, const std::string& errorText);
210
211 static WDL_DLGRET PreferencesDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
212 static WDL_DLGRET MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
213
214 IPlugAPP* GetPlug() { return mIPlug.get(); }
215private:
216 std::unique_ptr<IPlugAPP> mIPlug = nullptr;
217 std::unique_ptr<RtAudio> mDAC = nullptr;
218 std::unique_ptr<RtMidiIn> mMidiIn = nullptr;
219 std::unique_ptr<RtMidiOut> mMidiOut = nullptr;
220 int mMidiOutChannel = -1;
221 int mMidiInChannel = -1;
222
223 AppState mState;
225 AppState mTempState;
227 AppState mActiveState;
228
229 double mSampleRate = 44100.;
230 uint32_t mSamplesElapsed = 0;
231 uint32_t mVecWait = 0;
232 uint32_t mBufferSize = 512;
233 uint32_t mBufIndex = 0; // index for signal vector, loops from 0 to mSigVS
234 bool mExiting = false;
235 bool mAudioEnding = false;
236 bool mAudioDone = false;
237
239 std::optional<uint32_t> mDefaultInputDev;
241 std::optional<uint32_t> mDefaultOutputDev;
242
243 WDL_String mINIPath;
244
245 std::vector<uint32_t> mAudioInputDevIDs;
246 std::vector<uint32_t> mAudioOutputDevIDs;
247 std::vector<std::string> mMidiInputDevNames;
248 std::vector<std::string> mMidiOutputDevNames;
249
250 WDL_PtrList<double> mInputBufPtrs;
251 WDL_PtrList<double> mOutputBufPtrs;
252
253 friend class IPlugAPP;
254};
255
256END_IPLUG_NAMESPACE
IPlug Constant definitions, Types, magic numbers.
Include to get consistently named preprocessor macros for different platforms and logging functionali...
A class that hosts an IPlug as a standalone app and provides Audio/Midi I/O.
Definition: IPlugAPP_host.h:83
int GetMIDIPortNumber(ERoute direction, const char *name) const
std::optional< uint32_t > GetAudioDeviceID(const char *name) const
Returns the a validated audio device ID linked to a particular name.
std::string GetAudioDeviceName(uint32_t deviceID) const
Returns the name of the audio device with a given RTAudio device ID.
Standalone application base class for an IPlug plug-in.
Definition: IPlugAPP.h:37
ERoute
Used to identify whether a bus/channel connection is an input or an output.
Used to manage changes to app I/O.
Definition: IPlugAPP_host.h:88