Skip to content

Commit 7cf15de

Browse files
committed
Simplified copying of events and data. There is a bug where sometimes event representation gets timeshifted wrt data. I did not introduce that bug.
1 parent be287d7 commit 7cf15de

2 files changed

Lines changed: 103 additions & 159 deletions

File tree

Plugins/LfpDisplayNodeBeta/LfpDisplayNode.cpp

Lines changed: 93 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ using namespace LfpDisplayNodeBeta;
3131
LfpDisplayNode::LfpDisplayNode()
3232
: GenericProcessor ("LFP Viewer Beta")
3333
, displayGain (1)
34-
, bufferLength (20.0f)
34+
, bufferLength (20.0f) // seconds
3535
, abstractFifo (100)
3636
{
3737
setProcessorType (PROCESSOR_TYPE_SINK);
3838

39-
displayBuffer = new AudioSampleBuffer (8, 100);
39+
displayBuffer = new AudioSampleBuffer (8, 100); // channels, samples
40+
// (Size is later changed by resizeBuffer() to [bufferLength = 20] seconds.)
4041

4142
const int heapSize = 5000;
4243
arrayOfOnes = new float[heapSize];
@@ -68,15 +69,15 @@ void LfpDisplayNode::updateSettings()
6869
eventSourceNodes.clear();
6970
ttlState.clear();
7071

71-
for (int i = 0; i < eventChannelArray.size(); ++i)
72-
{
73-
uint32 sourceID = getChannelSourceID(eventChannelArray[i]);
74-
if (!eventSourceNodes.contains(sourceID))
75-
{
76-
eventSourceNodes.add(sourceID);
72+
for (int i = 0; i < eventChannelArray.size(); ++i)
73+
{
74+
uint32 sourceID = getChannelSourceID(eventChannelArray[i]);
75+
if (!eventSourceNodes.contains(sourceID))
76+
{
77+
eventSourceNodes.add(sourceID);
7778

78-
}
79-
}
79+
}
80+
}
8081

8182
numEventChannels = eventSourceNodes.size();
8283

@@ -96,7 +97,7 @@ void LfpDisplayNode::updateSettings()
9697

9798
uint32 LfpDisplayNode::getChannelSourceID(const EventChannel* event) const
9899
{
99-
return getProcessorFullId(event->getTimestampOriginProcessor(), event->getTimestampOriginSubProcessor());
100+
return getProcessorFullId(event->getTimestampOriginProcessor(), event->getTimestampOriginSubProcessor());
100101
}
101102

102103
bool LfpDisplayNode::resizeBuffer()
@@ -110,6 +111,9 @@ bool LfpDisplayNode::resizeBuffer()
110111
{
111112
abstractFifo.setTotalSize (nSamples);
112113
displayBuffer->setSize (nInputs + numEventChannels, nSamples); // add extra channels for TTLs
114+
displayBuffer->clear();
115+
//displayBufferIndex.clear();
116+
//displayBufferIndex.insertMultiple(0, 0, nInputs + numEventChannels);
113117

114118
return true;
115119
}
@@ -139,6 +143,7 @@ bool LfpDisplayNode::disable()
139143
{
140144
LfpDisplayEditor* editor = (LfpDisplayEditor*) getEditor();
141145
editor->disable();
146+
eventValueChanges.clear();
142147
return true;
143148
}
144149

@@ -158,169 +163,100 @@ void LfpDisplayNode::setParameter (int parameterIndex, float newValue)
158163
}
159164

160165

161-
void LfpDisplayNode::handleEvent(const EventChannel* eventInfo, const MidiMessage& event, int samplePosition)
162-
{
163-
if (Event::getEventType(event) == EventChannel::TTL)
164-
{
165-
TTLEventPtr ttl = TTLEvent::deserializeFromMessage(event, eventInfo);
166-
167-
//int eventNodeId = *(dataptr+1);
168-
const int eventId = ttl->getState() ? 1 : 0;
169-
const int eventChannel = ttl->getChannel();
170-
const int eventTime = samplePosition;
171-
const uint32 eventSourceNodeId = getChannelSourceID(eventInfo);
172-
const int nSamples = getNumSourceSamples(eventSourceNodeId);
173-
int samplesToFill = nSamples - eventTime;
174-
if (samplesToFill < 0) samplesToFill = 0;
175-
176-
// std::cout << "Received event from " << eventSourceNode << ", channel "
177-
// << eventChannel << ", with ID " << eventId << ", copying to "
178-
// << channelForEventSource[eventSourceNode] << std::endl;
179-
////
180-
int bufferIndex = (displayBufferIndex[channelForEventSource[eventSourceNodeId]] + eventTime - nSamples)
181-
% displayBuffer->getNumSamples();
182-
183-
bufferIndex = bufferIndex >= 0
184-
? bufferIndex
185-
: displayBuffer->getNumSamples() + bufferIndex;
186-
187-
if (eventId == 1)
188-
{
189-
ttlState[eventSourceNodeId] |= (1L << eventChannel);
190-
}
191-
else
192-
{
193-
ttlState[eventSourceNodeId] &= ~(1L << eventChannel);
194-
}
195-
196-
if (samplesToFill + bufferIndex < displayBuffer->getNumSamples())
197-
{
198-
//std::cout << bufferIndex << " " << samplesToFill << " " << ttlState[eventSourceNode] << std::endl;
199-
200-
displayBuffer->copyFrom (channelForEventSource[eventSourceNodeId], // destChannel
201-
bufferIndex, // destStartSample
202-
arrayOfOnes, // source
203-
samplesToFill, // numSamples
204-
float (ttlState[eventSourceNodeId])); // gain
205-
}
206-
else
207-
{
208-
const int block2Size = (samplesToFill + bufferIndex) % displayBuffer->getNumSamples();
209-
const int block1Size = samplesToFill - block2Size;
210-
211-
displayBuffer->copyFrom (channelForEventSource[eventSourceNodeId], // destChannel
212-
bufferIndex, // destStartSample
213-
arrayOfOnes, // source
214-
block1Size, // numSamples
215-
float (ttlState[eventSourceNodeId])); // gain
216-
217-
displayBuffer->copyFrom (channelForEventSource[eventSourceNodeId], // destChannel
218-
0, // destStartSample
219-
arrayOfOnes, // source
220-
block2Size, // numSamples
221-
float (ttlState[eventSourceNodeId])); // gain
222-
}
223-
224-
// std::cout << "Received event from " << eventNodeId
225-
// << " on channel " << eventChannel
226-
// << " with value " << eventId
227-
// << " at timestamp " << event.getTimeStamp() << std::endl;
228-
}
166+
void LfpDisplayNode::handleEvent(const EventChannel* eventInfo,
167+
const MidiMessage& event, int samplePosition) {
168+
if (Event::getEventType(event) == EventChannel::TTL) {
169+
TTLEventPtr ttl = TTLEvent::deserializeFromMessage(event, eventInfo);
170+
const int eventChannel = ttl->getChannel();
171+
const int eventTime = samplePosition;
172+
const uint32 eventSourceNodeId = getChannelSourceID(eventInfo);
173+
int val = 1<<eventChannel;
174+
if (!ttl->getState())
175+
val = -val;
176+
eventValueChanges[eventSourceNodeId].push_back(EventValueChange(eventTime, val));
177+
}
229178
}
230179

180+
void LfpDisplayNode::initializeEventChannels() {
181+
for (int i=0; i<eventSourceNodes.size(); i++) {
182+
uint32 src = eventSourceNodes[i];
183+
eventValueChanges[src] = std::list<EventValueChange>();
184+
}
185+
}
231186

232-
void LfpDisplayNode::initializeEventChannels()
233-
{
234-
for (int i = 0; i < eventSourceNodes.size(); ++i)
235-
{
236-
const int chan = channelForEventSource[eventSourceNodes[i]];
237-
const int index = displayBufferIndex[chan];
238-
const int samplesLeft = displayBuffer->getNumSamples() - index;
239-
const int nSamples = getNumSourceSamples(eventSourceNodes[i]);
240-
241-
//std::cout << "Event source node " << i << ", channel " << chan << std::endl;
242-
243-
if (nSamples < samplesLeft)
244-
{
245-
// std::cout << getNumInputs()+1 << " " << displayBufferIndex << " " << totalSamples << " " << ttlState << std::endl;
246-
247-
displayBuffer->copyFrom (chan, // destChannel
248-
index, // destStartSample
249-
arrayOfOnes, // source
250-
nSamples, // numSamples
251-
float (ttlState[eventSourceNodes[i]])); // gain
252-
253-
displayBufferIndex.set (chan, index + nSamples);
254-
}
255-
else
256-
{
257-
int extraSamples = nSamples - samplesLeft;
258-
259-
displayBuffer->copyFrom (chan, // destChannel
260-
index, // destStartSample
261-
arrayOfOnes, // source
262-
samplesLeft, // numSamples
263-
float (ttlState[eventSourceNodes[i]])); // gain
264-
265-
displayBuffer->copyFrom (chan, // destChannel
266-
0, // destStartSample
267-
arrayOfOnes, // source
268-
extraSamples, // numSamples
269-
float (ttlState[eventSourceNodes[i]])); // gain
187+
void LfpDisplayNode::copyToEventChannel(uint32 src,
188+
int t0,
189+
int t1,
190+
float value) {
191+
int dispBufSamps = displayBuffer->getNumSamples();
192+
int chan = channelForEventSource[src];
193+
int destStart = t0 + displayBufferIndex[chan];
194+
int n = t1 - t0;
195+
while (destStart + n > dispBufSamps) {
196+
int m = dispBufSamps - destStart;
197+
displayBuffer->copyFrom(chan, destStart, arrayOfOnes, m, value);
198+
n -= m;
199+
destStart = 0;
200+
}
201+
if (n>0)
202+
displayBuffer->copyFrom(chan, destStart, arrayOfOnes, n, value);
203+
}
270204

271-
displayBufferIndex.set (chan, extraSamples);
272-
}
205+
void LfpDisplayNode::finalizeEventChannels() {
206+
for (int i=0; i<eventSourceNodes.size(); ++i) {
207+
uint32 src = eventSourceNodes[i];
208+
int chan = channelForEventSource[src];
209+
int index = displayBufferIndex[chan];
210+
printf("event index %i [%i]\n", index, displayBufferIndex[0]);
211+
int nSamples = getNumSourceSamples(src);
212+
int t0 = 0;
213+
for (EventValueChange const &evc: eventValueChanges[src]) {
214+
int t1 = evc.eventTime;
215+
//printf("T%i-%i: %Li\n", t0, t1, ttlState[src]);
216+
copyToEventChannel(src, t0, t1, ttlState[src]);
217+
if (evc.eventVal>0)
218+
ttlState[src] |= evc.eventVal;
219+
else
220+
ttlState[src] &= ~evc.eventVal;
221+
t0 = t1;
273222
}
223+
//printf("(T%i-%i): %Li\n", t0, nSamples, ttlState[src]);
224+
copyToEventChannel(src, t0, nSamples, ttlState[src]);
225+
displayBufferIndex.set(chan, (index + nSamples) % displayBuffer->getNumSamples());
226+
}
274227
}
275228

229+
void LfpDisplayNode::copyDataToDisplay(int chan, AudioSampleBuffer &srcbuf) {
230+
int n = getNumSamples(chan);
231+
int idx = displayBufferIndex[chan];
232+
int buflen = displayBuffer->getNumSamples();
233+
int t0 = 0;
234+
while (idx + n >= buflen) {
235+
int m = buflen - idx;
236+
displayBuffer->copyFrom(chan, idx, srcbuf, chan, t0, m);
237+
t0 += m;
238+
n -= m;
239+
idx = 0;
240+
}
241+
if (n>0) {
242+
displayBuffer->copyFrom(chan, idx, srcbuf, chan, t0, n);
243+
idx += n;
244+
}
245+
displayBufferIndex.set(chan, idx);
246+
}
276247

277248
void LfpDisplayNode::process (AudioSampleBuffer& buffer)
278249
{
279250
// 1. place any new samples into the displayBuffer
280251
//std::cout << "Display node sample count: " << nSamples << std::endl; ///buffer.getNumSamples() << std::endl;
281252

282253
initializeEventChannels();
283-
284254
checkForEvents (); // see if we got any TTL events
255+
finalizeEventChannels();
285256

286257
ScopedLock displayLock (displayMutex);
287258

288-
for (int chan = 0; chan < buffer.getNumChannels(); ++chan)
289-
{
290-
const int samplesLeft = displayBuffer->getNumSamples() - displayBufferIndex[chan];
291-
const int nSamples = getNumSamples (chan);
292-
293-
if (nSamples < samplesLeft)
294-
{
295-
displayBuffer->copyFrom (chan, // destChannel
296-
displayBufferIndex[chan], // destStartSample
297-
buffer, // source
298-
chan, // source channel
299-
0, // source start sample
300-
nSamples); // numSamples
301-
302-
displayBufferIndex.set (chan, displayBufferIndex[chan] + nSamples);
303-
}
304-
else
305-
{
306-
const int extraSamples = nSamples - samplesLeft;
307-
308-
displayBuffer->copyFrom (chan, // destChannel
309-
displayBufferIndex[chan], // destStartSample
310-
buffer, // source
311-
chan, // source channel
312-
0, // source start sample
313-
samplesLeft); // numSamples
314-
315-
displayBuffer->copyFrom (chan, // destChannel
316-
0, // destStartSample
317-
buffer, // source
318-
chan, // source channel
319-
samplesLeft, // source start sample
320-
extraSamples); // numSamples
321-
322-
displayBufferIndex.set (chan, extraSamples);
323-
}
324-
}
259+
for (int chan = 0; chan < buffer.getNumChannels(); ++chan)
260+
copyDataToDisplay(chan, buffer);
325261
}
326262

Plugins/LfpDisplayNodeBeta/LfpDisplayNode.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
#include <ProcessorHeaders.h>
2828
#include "LfpDisplayEditor.h"
29-
29+
#include <list>
3030

3131
class DataViewport;
3232

@@ -70,12 +70,20 @@ class LfpDisplayNode : public GenericProcessor
7070

7171
private:
7272
void initializeEventChannels();
73-
73+
void finalizeEventChannels();
74+
void copyToEventChannel(uint32 src, int t0, int t1, float value);
75+
void copyDataToDisplay(int chan, AudioSampleBuffer &srcbuf);
7476
ScopedPointer<AudioSampleBuffer> displayBuffer;
7577

7678
Array<int> displayBufferIndex;
7779
Array<uint32> eventSourceNodes;
7880
std::map<uint32, int> channelForEventSource;
81+
struct EventValueChange {
82+
int eventTime;
83+
int eventVal; // positive to set, negative to clear
84+
EventValueChange(int t=0, int v=0): eventTime(t), eventVal(v) { }
85+
};
86+
std::map<uint32, std::list<EventValueChange>> eventValueChanges;
7987

8088
int numEventChannels;
8189

0 commit comments

Comments
 (0)