Skip to content

Commit 8a9e514

Browse files
committed
Merge branch 'fix-rec-node' of https://github.com/medengineer/plugin-GUI into development
2 parents e73b4b8 + 4c67031 commit 8a9e514

8 files changed

Lines changed: 166 additions & 117 deletions

File tree

Resources/Python/record_control_example_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,4 @@ def run_client():
7777

7878

7979
if __name__ == '__main__':
80-
run_client()
80+
run_client()

Source/Processors/ProcessorGraph/ProcessorGraph.cpp

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,10 @@ void ProcessorGraph::clearConnections()
266266

267267
}
268268

269-
/*
270-
addConnection(MESSAGE_CENTER_ID, midiChannelIndex,
271-
RECORD_NODE_ID, midiChannelIndex);
272-
*/
269+
for (auto& recordNode : getRecordNodes())
270+
addConnection(MESSAGE_CENTER_ID, midiChannelIndex,
271+
recordNode->getNodeId(), midiChannelIndex);
272+
273273
}
274274

275275

@@ -278,10 +278,6 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
278278

279279
clearConnections(); // clear processor graph
280280

281-
std::cout << "Updating connections:" << std::endl;
282-
std::cout << std::endl;
283-
std::cout << std::endl;
284-
285281
Array<GenericProcessor*> splitters;
286282

287283
// keep track of which splitter is currently being explored, in case there's another
@@ -453,10 +449,13 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
453449
}
454450

455451
getAudioNode()->updatePlaybackBuffer();
456-
//Update RecordNode internal channel mappings
452+
457453
Array<EventChannel*> extraChannels;
458454
getMessageCenter()->addSpecialProcessorChannels(extraChannels);
459-
//getRecordNode()->addSpecialProcessorChannels(extraChannels);
455+
456+
for (auto& recordNode : getRecordNodes())
457+
recordNode->addSpecialProcessorChannels(extraChannels);
458+
460459
} // end method
461460

462461
void ProcessorGraph::connectProcessors(GenericProcessor* source, GenericProcessor* dest,
@@ -492,12 +491,6 @@ void ProcessorGraph::connectProcessors(GenericProcessor* source, GenericProcesso
492491
midiChannelIndex); // destNodeChannelIndex
493492
}
494493

495-
// 3. connect record nodes
496-
if (dest->isRecordNode())
497-
{
498-
((RecordNode*)dest)->registerProcessor(source);
499-
}
500-
501494
}
502495

503496
void ProcessorGraph::connectProcessorToAudioNode(GenericProcessor* source)
@@ -702,7 +695,10 @@ bool ProcessorGraph::enableProcessors()
702695

703696
//Update special channels indexes, at the end
704697
//To change, as many other things, when the probe system is implemented
705-
//getRecordNode()->updateRecordChannelIndexes();
698+
for (auto& node : getRecordNodes())
699+
{
700+
node->updateRecordChannelIndexes();
701+
}
706702
getAudioNode()->updateRecordChannelIndexes();
707703

708704
// sendActionMessage("Acquisition started.");
@@ -748,15 +744,6 @@ bool ProcessorGraph::disableProcessors()
748744

749745
void ProcessorGraph::setRecordState(bool isRecording)
750746
{
751-
// actually start recording
752-
if (isRecording)
753-
{
754-
//getRecordNode()->setParameter(1,10.0f);
755-
}
756-
else
757-
{
758-
//getRecordNode()->setParameter(0,10.0f);
759-
}
760747

761748
for (int i = 0; i < getNumNodes(); i++)
762749
{
@@ -769,7 +756,6 @@ void ProcessorGraph::setRecordState(bool isRecording)
769756
}
770757
}
771758

772-
773759
}
774760

775761

Source/Processors/RecordNode/BinaryFormat/BinaryRecording.cpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,9 @@ String BinaryRecording::getEngineID() const
2020

2121
String BinaryRecording::getProcessorString(const InfoObjectCommon* channelInfo)
2222
{
23-
String fName = (channelInfo->getCurrentNodeName().replaceCharacter(' ', '_') + "-" +
24-
String(channelInfo->getCurrentNodeID()));
25-
if (channelInfo->getCurrentNodeID() == channelInfo->getSourceNodeID())
26-
// found the channel source
27-
{
28-
fName += "." + String(channelInfo->getSubProcessorIdx());
29-
}
30-
else
31-
{
32-
fName += "_" + String(channelInfo->getSourceNodeID()) + "." +
33-
String(channelInfo->getSubProcessorIdx());
34-
}
23+
String fName = (channelInfo->getSourceName().replaceCharacter(' ', '_') + "-" +
24+
String(channelInfo->getSourceNodeID()));
25+
fName += "." + String(channelInfo->getSubProcessorIdx());
3526
fName += File::separatorString;
3627
return fName;
3728
}

Source/Processors/RecordNode/DataQueue.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ void DataQueue::fillTimestamps(int channel, int index, int size, int64 timestamp
134134
}
135135
}
136136

137-
void DataQueue::writeSynchronizedTimestampChannel(double start, double step, int destChannel, int64 nSamples)
137+
float DataQueue::writeSynchronizedTimestampChannel(double start, double step, int destChannel, int64 nSamples)
138138
{
139139

140140
int index1, size1, index2, size2;
@@ -169,6 +169,8 @@ void DataQueue::writeSynchronizedTimestampChannel(double start, double step, int
169169

170170
m_FTSFifos[destChannel]->finishedWrite(size1 + size2);
171171

172+
return 1.0f - (float)m_FTSFifos[destChannel]->getFreeSpace() / (float)m_FTSFifos[destChannel]->getTotalSize();
173+
172174
}
173175

174176

Source/Processors/RecordNode/DataQueue.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class DataQueue
5050
//Only the methods after this comment are considered thread-safe.
5151
//Caution must be had to avoid calling more than one of the methods above simulatenously
5252
void writeChannel(const AudioSampleBuffer& buffer, int srcChannel, int destChannel, int nSamples, int64 timestamp);
53-
void writeSynchronizedTimestampChannel(double start, double step, int destChannel, int64 nSamples);
53+
float writeSynchronizedTimestampChannel(double start, double step, int destChannel, int64 nSamples);
5454
bool startRead(Array<CircularBufferIndexes>& indexes, Array<int64>& timestamps, int nMax);
5555
bool startSynchronizedRead(Array<CircularBufferIndexes>& dataIndexes, Array<CircularBufferIndexes>& ftsIndexes, Array<int64>& timestamps, int nMax);
5656
const AudioSampleBuffer& getAudioBufferReference() const;

Source/Processors/RecordNode/RecordNode.cpp

Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using namespace std::chrono;
1111

1212
#define CONTINUOUS_CHANNELS_ON_BY_DEFAULT true
13+
#define RECEIVED_SOFTWARE_TIME (event.getVelocity() == 136)
1314

1415
EventMonitor::EventMonitor()
1516
: receivedEvents(0) {}
@@ -37,7 +38,8 @@ RecordNode::RecordNode()
3738
recordingNumber(0),
3839
isRecording(false),
3940
hasRecorded(false),
40-
settingsNeeded(false)
41+
settingsNeeded(false),
42+
receivedSoftwareTime(false)
4143
{
4244
setProcessorType(PROCESSOR_TYPE_RECORD_NODE);
4345

@@ -66,6 +68,45 @@ RecordNode::~RecordNode()
6668
{
6769
}
6870

71+
void RecordNode::addInputChannel(const GenericProcessor* sourceNode, int chan)
72+
{
73+
74+
if (chan != AccessClass::getProcessorGraph()->midiChannelIndex)
75+
{
76+
int channelIndex = getNextChannel(false);
77+
78+
const DataChannel* orig = sourceNode->getDataChannel(chan);
79+
DataChannel* newChannel = new DataChannel(*orig);
80+
newChannel->setRecordState(orig->getRecordState());
81+
dataChannelArray.add(newChannel);
82+
recordEngine->addDataChannel(channelIndex, dataChannelArray[channelIndex]);
83+
84+
}
85+
else
86+
{
87+
88+
for (int n = 0; n < sourceNode->getTotalEventChannels(); n++)
89+
{
90+
const EventChannel* orig = sourceNode->getEventChannel(n);
91+
//only add to the record node the events originating from this processor, to avoid duplicates
92+
if (orig->getSourceNodeID() == sourceNode->getNodeId())
93+
eventChannelArray.add(new EventChannel(*orig));
94+
95+
}
96+
97+
}
98+
99+
}
100+
101+
void RecordNode::addSpecialProcessorChannels(Array<EventChannel*>& channels)
102+
{
103+
104+
eventChannelArray.addArray(channels);
105+
settings.numInputs = dataChannelArray.size();
106+
setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 1024);
107+
108+
}
109+
69110
void RecordNode::setEngine(int index)
70111
{
71112
availableEngines = getAvailableRecordEngines();
@@ -213,6 +254,12 @@ void RecordNode::setParameter(int parameterIndex, float newValue)
213254

214255
}
215256

257+
void RecordNode::updateRecordChannelIndexes()
258+
{
259+
//Keep the nodeIDs of the original processor from each channel comes from
260+
updateChannelIndexes(false);
261+
}
262+
216263
void RecordNode::updateChannelStates(int srcIndex, int subProcIdx, std::vector<bool> channelStates)
217264
{
218265
this->dataChannelStates[srcIndex][subProcIdx] = channelStates;
@@ -255,6 +302,8 @@ void RecordNode::updateSubprocessorMap()
255302
ch++;
256303
}
257304
ch--;
305+
306+
fifoUsage[sourceID][subProcID] = 0.0f;
258307
}
259308

260309
}
@@ -274,7 +323,7 @@ void RecordNode::updateSubprocessorMap()
274323
}
275324
}
276325

277-
eventChannelMap.clear();
326+
eventMap.clear();
278327
syncChannelMap.clear();
279328
syncOrderMap.clear();
280329
for (int ch = 0; ch < eventChannelArray.size(); ch++)
@@ -284,12 +333,10 @@ void RecordNode::updateSubprocessorMap()
284333
int sourceID = chan->getSourceNodeID();
285334
int subProcID = chan->getSubProcessorIdx();
286335

287-
int chCount = 0;
336+
eventMap[sourceID][subProcID] = chan->getNumChannels();
288337

289-
if (!syncChannelMap[sourceID][subProcID])
338+
if (dataChannelStates[sourceID][subProcID].size() && !syncChannelMap[sourceID][subProcID])
290339
{
291-
EventChannel* chan = eventChannelArray[ch];
292-
eventChannelMap[sourceID][subProcID] = chan->getNumChannels();
293340
syncOrderMap[sourceID][subProcID] = ch;
294341
syncChannelMap[sourceID][subProcID] = 0;
295342
synchronizer->setSyncChannel(chan->getSourceNodeID(), chan->getSubProcessorIdx(), ch);
@@ -311,7 +358,6 @@ void RecordNode::setMasterSubprocessor(int srcIndex, int subProcIdx)
311358

312359
void RecordNode::setSyncChannel(int srcIndex, int subProcIdx, int channel)
313360
{
314-
//eventChannelMap[srcIndex][subProcIdx];
315361
syncChannelMap[srcIndex][subProcIdx] = channel;
316362
synchronizer->setSyncChannel(srcIndex, subProcIdx, syncOrderMap[srcIndex][subProcIdx]+channel);
317363
}
@@ -330,11 +376,7 @@ bool RecordNode::isMasterSubprocessor(int srcIndex, int subProcIdx)
330376
void RecordNode::updateSettings()
331377
{
332378

333-
if (dataChannelArray.size() != lastDataChannelArraySize)
334-
{
335-
lastDataChannelArraySize = dataChannelArray.size();
336-
updateSubprocessorMap();
337-
}
379+
updateSubprocessorMap();
338380

339381
}
340382

@@ -373,7 +415,7 @@ void RecordNode::startRecording()
373415

374416
int recordedProcessorIdx = -1;
375417

376-
LOGD("Record Node ", getNodeId(), ": Total channels: ", totChans);
418+
//LOGD("Record Node ", getNodeId(), ": Total channels: ", totChans, " Total event channels: ", getTotalEventChannels());
377419

378420
for (int ch = 0; ch < totChans; ++ch)
379421
{
@@ -506,15 +548,15 @@ void RecordNode::handleEvent(const EventChannel* eventInfo, const MidiMessage& e
506548
int64 timestamp = Event::getTimestamp(event);
507549
uint64 eventChan = event.getChannel();
508550
int eventIndex;
509-
if (eventInfo && samplePosition > 0)
510-
{
551+
if (eventInfo)
511552
eventIndex = getEventChannelIndex(Event::getSourceIndex(event), Event::getSourceID(event), Event::getSubProcessorIdx(event));
512-
synchronizer->addEvent(Event::getSourceID(event), Event::getSubProcessorIdx(event), eventIndex, timestamp);
513-
}
514553
else
515554
eventIndex = -1;
516555

517-
if (isRecording && eventIndex >= 0)
556+
if (samplePosition > 0 && dataChannelStates[Event::getSourceID(event)][Event::getSubProcessorIdx(event)].size())
557+
synchronizer->addEvent(Event::getSourceID(event), Event::getSubProcessorIdx(event), eventIndex, timestamp);
558+
559+
if (isRecording)
518560
eventQueue->addEvent(event, timestamp, eventIndex);
519561

520562
}
@@ -541,7 +583,20 @@ void RecordNode::handleSpike(const SpikeChannel* spikeInfo, const MidiMessage& e
541583

542584
void RecordNode::handleTimestampSyncTexts(const MidiMessage& event)
543585
{
544-
handleEvent(nullptr, event, 0);
586+
587+
if (event.getVelocity() == 136)
588+
{
589+
if (!receivedSoftwareTime)
590+
{
591+
handleEvent(nullptr, event, 0);
592+
receivedSoftwareTime = true;
593+
}
594+
}
595+
else
596+
{
597+
handleEvent(nullptr, event, 0);
598+
}
599+
545600
}
546601

547602
void RecordNode::process(AudioSampleBuffer& buffer)
@@ -589,7 +644,7 @@ void RecordNode::process(AudioSampleBuffer& buffer)
589644
{
590645
double first = synchronizer->convertTimestamp(sourceID, subProcIdx, timestamp);
591646
double second = synchronizer->convertTimestamp(sourceID, subProcIdx, timestamp + 1);
592-
dataQueue->writeSynchronizedTimestampChannel(first, second - first, ftsChannelMap[ch], numSamples);
647+
fifoUsage[sourceID][subProcIdx] = dataQueue->writeSynchronizedTimestampChannel(first, second - first, ftsChannelMap[ch], numSamples);
593648
}
594649

595650
dataQueue->writeChannel(buffer, channelMap[ch], ch, numSamples, timestamp);
@@ -626,13 +681,10 @@ bool RecordNode::isFirstChannelInRecordedSubprocessor(int ch)
626681
return std::find(startRecChannels.begin(), startRecChannels.end(), ch) != startRecChannels.end();
627682
}
628683

629-
//TODO: Need to validate these methods
630-
631684
void RecordNode::registerProcessor(const GenericProcessor* sourceNode)
632685
{
633686
settings.numInputs += sourceNode->getNumOutputs();
634687
setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
635-
636688
recordEngine->registerProcessor(sourceNode);
637689
}
638690

Source/Processors/RecordNode/RecordNode.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,13 @@ class RecordNode : public GenericProcessor, public FilenameComponentListener
4949
RecordNode();
5050
~RecordNode();
5151

52+
void updateRecordChannelIndexes();
53+
5254
AudioProcessorEditor* createEditor() override;
5355
bool hasEditor() const override { return true; }
5456

55-
57+
void addSpecialProcessorChannels(Array<EventChannel*>& channels);
58+
5659
void updateSubprocessorMap();
5760
void setMasterSubprocessor(int srcIdx, int subProcIdx);
5861
bool isMasterSubprocessor(int srcIdx, int subProcIdx);
@@ -108,10 +111,12 @@ class RecordNode : public GenericProcessor, public FilenameComponentListener
108111
std::map<int, std::map<int, std::vector<bool>>> dataChannelStates;
109112
std::map<int, int> dataChannelOrder;
110113

111-
std::map<int, std::map<int, int>> eventChannelMap;
114+
std::map<int, std::map<int, int>> eventMap;
112115
std::map<int, std::map<int, int>> syncChannelMap;
113116
std::map<int, std::map<int, int>> syncOrderMap;
114117

118+
std::map<int, std::map<int, float>> fifoUsage;
119+
115120
Array<int> channelMap; //Map from record channel index to source channel index
116121
Array<int> ftsChannelMap; // Map from recorded channel index to recorded source processor idx
117122
std::vector<std::vector<int>> subProcessorMap;
@@ -120,6 +125,7 @@ class RecordNode : public GenericProcessor, public FilenameComponentListener
120125
bool isSyncReady;
121126

122127
//TODO: Need to validate these new methods
128+
void addInputChannel(const GenericProcessor* sourceNode, int chan);
123129

124130
/** Must be called by a spike recording source on the "enable" method
125131
*/
@@ -161,6 +167,8 @@ class RecordNode : public GenericProcessor, public FilenameComponentListener
161167

162168
private:
163169

170+
bool receivedSoftwareTime;
171+
164172
int lastDataChannelArraySize;
165173

166174
bool isProcessing;

0 commit comments

Comments
 (0)