iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IPlugWAM.cpp
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#include "IPlugWAM.h"
12
13using namespace iplug;
14
15IPlugWAM::IPlugWAM(const InstanceInfo& info, const Config& config)
16: IPlugAPIBase(config, kAPIWAM)
17, IPlugProcessor(config, kAPIWAM)
18{
19 int nInputs = MaxNChannels(ERoute::kInput), nOutputs = MaxNChannels(ERoute::kOutput);
20
21 SetChannelConnections(ERoute::kInput, 0, nInputs, true);
22 SetChannelConnections(ERoute::kOutput, 0, nOutputs, true);
23}
24
25const char* IPlugWAM::init(uint32_t bufsize, uint32_t sr, void* pDesc)
26{
27 DBGMSG("init\n");
28
29 SetSampleRate(sr);
30 SetBlockSize(bufsize);
31
32 DBGMSG("%i %i\n", sr, bufsize);
33
34 WDL_String json;
35 json.Set("{\n");
36 json.AppendFormatted(8192, "\"audio\": { \"inputs\": [{ \"id\":0, \"channels\":%i }], \"outputs\": [{ \"id\":0, \"channels\":%i }] },\n", MaxNChannels(ERoute::kInput), MaxNChannels(ERoute::kOutput));
37 json.AppendFormatted(8192, "\"parameters\": [\n");
38
39 for (int idx = 0; idx < NParams(); idx++)
40 {
41 IParam* pParam = GetParam(idx);
42 pParam->GetJSON(json, idx);
43
44 if(idx < NParams()-1)
45 json.AppendFormatted(8192, ",\n");
46 else
47 json.AppendFormatted(8192, "\n");
48 }
49
50 json.Append("]\n}");
51
52 //TODO: correct place? - do we need a WAM reset message?
53 OnParamReset(kReset);
54 OnReset();
55 postMessage("StartIdleTimer", nullptr, nullptr);
56
57 return json.Get();
58}
59
60void IPlugWAM::onProcess(WAM::AudioBus* pAudio, void* pData)
61{
62 const int blockSize = GetBlockSize();
63
64 SetChannelConnections(ERoute::kInput, 0, MaxNChannels(ERoute::kInput), !IsInstrument()); //TODO: go elsewhere
65 SetChannelConnections(ERoute::kOutput, 0, MaxNChannels(ERoute::kOutput), true); //TODO: go elsewhere
66 AttachBuffers(ERoute::kInput, 0, NChannelsConnected(ERoute::kInput), pAudio->inputs, blockSize);
67 AttachBuffers(ERoute::kOutput, 0, NChannelsConnected(ERoute::kOutput), pAudio->outputs, blockSize);
68
69 ENTER_PARAMS_MUTEX
70 ProcessBuffers((float) 0.0f, blockSize);
71 LEAVE_PARAMS_MUTEX
72}
73
74void IPlugWAM::OnEditorIdleTick()
75{
76 while(mParamChangeFromProcessor.ElementsAvailable())
77 {
78 ParamTuple p;
79 mParamChangeFromProcessor.Pop(p);
80 SendParameterValueFromDelegate(p.idx, p.value, false);
81 }
82
83 while (mMidiMsgsFromProcessor.ElementsAvailable())
84 {
85 IMidiMsg msg;
86 mMidiMsgsFromProcessor.Pop(msg);
87 SendMidiMsgFromDelegate(msg);
88 }
89
90 OnIdle();
91}
92
93//WAM onMessageN
94void IPlugWAM::onMessage(char* verb, char* res, double data)
95{
96 if(strcmp(verb, "TICK") == 0) // special case for DSP OnIdle()
97 {
98 OnEditorIdleTick();
99 }
100 else if(strcmp(verb, "SMMFUI") == 0)
101 {
102 uint8_t data[3];
103 char* pChar = strtok(res, ":");
104 int i = 0;
105 while (pChar != nullptr) {
106 data[i++] = atoi(pChar);
107 pChar = strtok(nullptr, ":");
108 }
109
110 IMidiMsg msg = {0, data[0], data[1], data[2]};
111 ProcessMidiMsg(msg); // TODO: should queue to mMidiMsgsFromEditor?
112 }
113 else if(strcmp(verb, "SAMFUI") == 0) // SAMFUI
114 {
115 int data[2] = {-1, -1};
116 char* pChar = strtok(res, ":");
117 int i = 0;
118 while (pChar != nullptr) {
119 data[i++] = atoi(pChar);
120 pChar = strtok(nullptr, ":");
121 }
122
123 OnMessage(data[0], data[1], sizeof(double), reinterpret_cast<void*>(&data));
124 }
125}
126
127//WAM onMessageS
128void IPlugWAM::onMessage(char* verb, char* res, char* str)
129{
130}
131
132//WAM onMessageA
133void IPlugWAM::onMessage(char* verb, char* res, void* pData, uint32_t size)
134{
135 if(strcmp(verb, "SAMFUI") == 0)
136 {
137 int pos = 0;
138 IByteStream stream(pData, size);
139 int msgTag;
140 int ctrlTag;
141 int dataSize;
142 pos = stream.Get(&msgTag, pos);
143 pos = stream.Get(&ctrlTag, pos);
144 pos = stream.Get(&dataSize, pos);
145
146 OnMessage(msgTag, ctrlTag, dataSize, stream.GetData() + (sizeof(int) * 3));
147 }
148 else if(strcmp(verb, "SSMFUI") == 0)
149 {
150 //TODO
151 }
152 else
153 {
154 DBGMSG("onMessageA not handled\n");
155 }
156}
157
158void IPlugWAM::onMidi(byte status, byte data1, byte data2)
159{
160// DBGMSG("onMidi\n");
161 IMidiMsg msg = {0, status, data1, data2};
162 ProcessMidiMsg(msg); // onMidi is not called on HPT. We could queue things up, but just process the message straightaway for now
163 //mMidiMsgsFromProcessor.Push(msg);
164
165 WDL_String dataStr;
166 dataStr.SetFormatted(16, "%i:%i:%i", msg.mStatus, msg.mData1, msg.mData2);
167
168 // TODO: in the future this will be done via shared array buffer
169 // if onMidi ever gets called on HPT, should defer via queue
170 postMessage("SMMFD", dataStr.Get(), "");
171}
172
173void IPlugWAM::onParam(uint32_t idparam, double value)
174{
175// DBGMSG("IPlugWAM:: onParam %i %f\n", idparam, value);
176 SetParameterValue(idparam, value);
177}
178
179void IPlugWAM::onSysex(byte* pData, uint32_t size)
180{
181 ISysEx sysex = {0 /* no offset */, pData, (int) size };
182 ProcessSysEx(sysex);
183
184 WDL_String dataStr;
185 dataStr.SetFormatted(16, "%i", size);
186
187 // TODO: in the future this will be done via shared array buffer
188 // if onSysex ever gets called on HPT, should defer via queue
189 postMessage("SSMFD", dataStr.Get(), "");
190}
191
192void IPlugWAM::SendControlValueFromDelegate(int ctrlTag, double normalizedValue)
193{
194 WDL_String propStr;
195 WDL_String dataStr;
196
197 propStr.SetFormatted(16, "%i", ctrlTag);
198 dataStr.SetFormatted(16, "%f", normalizedValue);
199
200 // TODO: in the future this will be done via shared array buffer
201 postMessage("SCVFD", propStr.Get(), dataStr.Get());
202}
203
204void IPlugWAM::SendControlMsgFromDelegate(int ctrlTag, int msgTag, int dataSize, const void* pData)
205{
206 WDL_String propStr;
207 propStr.SetFormatted(16, "%i:%i", ctrlTag, msgTag);
208
209 // TODO: in the future this will be done via shared array buffer
210 postMessage("SCMFD", propStr.Get(), pData, (uint32_t) dataSize);
211}
212
213void IPlugWAM::SendParameterValueFromDelegate(int paramIdx, double value, bool normalized)
214{
215 WDL_String propStr;
216 WDL_String dataStr;
217 propStr.SetFormatted(16, "%i", paramIdx);
218 dataStr.SetFormatted(16, "%f", value);
219
220 // TODO: in the future this will be done via shared array buffer
221 postMessage("SPVFD", propStr.Get(), dataStr.Get());
222}
223
224void IPlugWAM::SendArbitraryMsgFromDelegate(int msgTag, int dataSize, const void* pData)
225{
226 WDL_String propStr;
227 propStr.SetFormatted(16, "%i", msgTag);
228
229 // TODO: in the future this will be done via shared array buffer
230 postMessage("SAMFD", propStr.Get(), pData, (uint32_t) dataSize);
231}
232
Manages a non-owned block of memory, for receiving arbitrary message byte streams.
Definition: IPlugStructs.h:268
IPlug's parameter class.
void GetJSON(WDL_String &json, int idx) const
Get a JSON description of the parameter.
The base class of an IPlug plug-in, which interacts with the different plug-in APIs.
Definition: IPlugAPIBase.h:43
virtual void OnIdle()
Override this method to get an "idle"" call on the main thread.
Definition: IPlugAPIBase.h:111
void SetParameterValue(int paramIdx, double normalizedValue)
SetParameterValue is called from the UI in the middle of a parameter change gesture (possibly via del...
The base class for IPlug Audio Processing.
virtual void ProcessMidiMsg(const IMidiMsg &msg)
Override this method to handle incoming MIDI messages.
bool IsInstrument() const
int NChannelsConnected(ERoute direction) const
int GetBlockSize() const
int MaxNChannels(ERoute direction) const
virtual void ProcessSysEx(ISysEx &msg)
Override this method to handle incoming MIDI System Exclusive (SysEx) messages.
virtual void OnReset()
Override this method in your plug-in class to do something prior to playback etc.
Encapsulates a MIDI message and provides helper functions.
Definition: IPlugMidi.h:31
A struct for dealing with SysEx messages.
Definition: IPlugMidi.h:539
In certain cases we need to queue parameter changes for transferral between threads.
Definition: IPlugStructs.h:33