Skip to content

Commit 3be5da1

Browse files
authored
Merge pull request #277 from tne-lab/network-events-ttl-event
Network Events receive TTL event
2 parents aedf4ec + 6bb0d04 commit 3be5da1

2 files changed

Lines changed: 96 additions & 12 deletions

File tree

Source/Plugins/NetworkEvents/NetworkEvents.cpp

Lines changed: 83 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,22 @@ void NetworkEvents::restartConnection()
8383

8484
void NetworkEvents::createEventChannels()
8585
{
86-
EventChannel* chan = new EventChannel(EventChannel::TEXT, 1, MAX_MESSAGE_LENGTH, CoreServices::getGlobalSampleRate(), this);
86+
float sampleRate = CoreServices::getGlobalSampleRate();
87+
EventChannel* chan = new EventChannel(EventChannel::TEXT, 1, MAX_MESSAGE_LENGTH, sampleRate, this);
8788
chan->setName("Network messages");
8889
chan->setDescription("Messages received through the network events module");
8990
chan->setIdentifier("external.network.rawData");
9091
chan->addEventMetaData(new MetaDataDescriptor(MetaDataDescriptor::INT64, 1, "Software timestamp",
9192
"OS high resolution timer count when the event was received", "timestamp.software"));
9293
eventChannelArray.add(chan);
9394
messageChannel = chan;
95+
96+
EventChannel* TTLchan = new EventChannel(EventChannel::TTL, 8, 1, sampleRate, this);
97+
TTLchan->setName("Network Events output");
98+
TTLchan->setDescription("Triggers whenever \"TTL\" is received on the port.");
99+
TTLchan->setIdentifier("external.network.ttl");
100+
eventChannelArray.add(TTLchan);
101+
TTLChannel = TTLchan;
94102
}
95103

96104

@@ -102,11 +110,11 @@ AudioProcessorEditor* NetworkEvents::createEditor ()
102110
}
103111

104112

105-
void NetworkEvents::postTimestamppedStringToMidiBuffer (const StringTS& s)
113+
void NetworkEvents::postTimestamppedStringToMidiBuffer (const StringTS& s, juce::int64 timestamp)
106114
{
107115
MetaDataValueArray md;
108116
md.add(new MetaDataValue(MetaDataDescriptor::INT64, 1, &s.timestamp));
109-
TextEventPtr event = TextEvent::createTextEvent(messageChannel, CoreServices::getGlobalTimestamp(), s.str, md);
117+
TextEventPtr event = TextEvent::createTextEvent(messageChannel, timestamp, s.str, md);
110118
addEvent(messageChannel, event, 0);
111119
}
112120

@@ -181,8 +189,8 @@ String NetworkEvents::handleSpecialMessages(const String& s)
181189
if (CoreServices::getRecordingStatus())
182190
{
183191
CoreServices::setRecordingStatus (false);
184-
return String ("StoppedRecording");
185-
}
192+
}
193+
return String("StoppedRecording");
186194
}
187195
else if (cmd.compareIgnoreCase ("IsAcquiring") == 0)
188196
{
@@ -212,21 +220,85 @@ String NetworkEvents::handleSpecialMessages(const String& s)
212220
status += CoreServices::RecordNode::getExperimentNumber();
213221
return status;
214222
}
223+
else if (cmd.compareIgnoreCase ("TTL") == 0)
224+
{
225+
// Default to channel 0 and off (if no optional info sent)
226+
int channel = 0;
227+
bool onOff = 0;
228+
/** Set optional parameters (name/value pairs)*/
229+
String params = s.substring(cmd.length()).trim();
230+
StringPairArray dict = parseNetworkMessage(params);
231+
232+
StringArray keys = dict.getAllKeys();
233+
for (int i = 0; i < keys.size(); ++i)
234+
{
235+
String key = keys[i];
236+
int value = dict[key].getIntValue();
237+
238+
if (key.compareIgnoreCase("Channel") == 0)
239+
{
240+
// Make sure in range
241+
if (value <= 8 && value >= 1)
242+
{
243+
channel = value - 1;
244+
}
245+
else
246+
{
247+
return "InvalidChannel";
248+
}
249+
}
250+
else if (key.compareIgnoreCase("on") == 0)
251+
{
252+
onOff = value;
253+
}
254+
}
255+
{
256+
ScopedLock TTLlock(TTLqueueLock);
257+
if (CoreServices::getAcquisitionStatus())
258+
{
259+
TTLQueue.push({ onOff, channel });
260+
}
261+
}
262+
263+
264+
265+
return "TTLHandled: Channel=" + String(channel + 1) + " on=" + String(onOff);
266+
}
215267

216268
return String ("NotHandled");
217269
}
218270

271+
void NetworkEvents::triggerTTLEvent(StringTTL TTLmsg, juce::int64 timestamp)
272+
{
273+
juce::uint8 ttlData = TTLmsg.onOff << TTLmsg.eventChannel;
274+
TTLEventPtr event = TTLEvent::createTTLEvent(TTLChannel, timestamp, &ttlData, sizeof(juce::uint8), TTLmsg.eventChannel);
275+
addEvent(TTLChannel, event, 0);
276+
}
277+
219278

220279
void NetworkEvents::process (AudioSampleBuffer& buffer)
221280
{
222-
setTimestampAndSamples(CoreServices::getGlobalTimestamp(),0);
281+
juce::int64 timestamp = CoreServices::getGlobalTimestamp();
282+
setTimestampAndSamples(timestamp,0);
223283

224-
ScopedLock lock(queueLock);
225-
while (! networkMessagesQueue.empty())
226284
{
227-
const StringTS& msg = networkMessagesQueue.front();
228-
postTimestamppedStringToMidiBuffer (msg);
229-
networkMessagesQueue.pop();
285+
ScopedLock lock(queueLock);
286+
while (!networkMessagesQueue.empty())
287+
{
288+
const StringTS& msg = networkMessagesQueue.front();
289+
postTimestamppedStringToMidiBuffer(msg, timestamp);
290+
networkMessagesQueue.pop();
291+
}
292+
}
293+
294+
{
295+
ScopedLock TTLlock(TTLqueueLock);
296+
while (!TTLQueue.empty())
297+
{
298+
const StringTTL& TTLmsg = TTLQueue.front();
299+
triggerTTLEvent(TTLmsg, timestamp);
300+
TTLQueue.pop();
301+
}
230302
}
231303
}
232304

Source/Plugins/NetworkEvents/NetworkEvents.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ class NetworkEvents : public GenericProcessor
9090
int64 timestamp;
9191
};
9292

93+
struct StringTTL
94+
{
95+
bool onOff;
96+
int eventChannel;
97+
};
98+
9399
class ZMQContext
94100
{
95101
public:
@@ -142,7 +148,7 @@ class NetworkEvents : public GenericProcessor
142148
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Responder);
143149
};
144150

145-
void postTimestamppedStringToMidiBuffer(const StringTS& s);
151+
void postTimestamppedStringToMidiBuffer(const StringTS& s, juce::int64 timestamp);
146152

147153
String handleSpecialMessages(const String& s);
148154

@@ -164,8 +170,14 @@ class NetworkEvents : public GenericProcessor
164170

165171
std::queue<StringTS> networkMessagesQueue;
166172
CriticalSection queueLock;
173+
174+
std::queue<StringTTL> TTLQueue;
175+
CriticalSection TTLqueueLock;
167176

168177
const EventChannel* messageChannel{ nullptr };
178+
const EventChannel* TTLChannel{ nullptr };
179+
180+
void triggerTTLEvent(StringTTL TTLmsg, juce::int64 timestamp);
169181

170182
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NetworkEvents);
171183
};

0 commit comments

Comments
 (0)