2222*/
2323
2424#include < stdio.h>
25+ #include < utility>
26+ #include < map>
2527
2628#include " ProcessorGraph.h"
2729#include " ../GenericProcessor/GenericProcessor.h"
@@ -266,6 +268,34 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
266268 // splitter between the one being explored and its source.
267269 GenericProcessor* activeSplitter = nullptr ;
268270
271+ // stores the pointer to a source leading into a particular dest node
272+ // along with a boolean vector indicating the position of this source
273+ // relative to other sources entering the dest via mergers
274+ // and a vector indicating the splitter settings between the source and dest.
275+ // (when the mergerOrder vectors of all incoming nodes to a dest are
276+ // lexicographically sorted, the sources will be in the correct order)
277+ struct ConnectionInfo
278+ {
279+ // give friendlier names to the pair entries
280+ std::vector<bool > mergerOrder;
281+ std::vector<bool > splitterSettings;
282+ GenericProcessor* source;
283+
284+ // for SortedSet sorting:
285+ bool operator <(const ConnectionInfo& other) const
286+ {
287+ return mergerOrder < other.mergerOrder ;
288+ }
289+
290+ bool operator ==(const ConnectionInfo& other) const
291+ {
292+ return mergerOrder == other.mergerOrder ;
293+ }
294+ };
295+
296+ // each destination node gets a set of sources, sorted by their order as dictated by mergers
297+ std::unordered_map<GenericProcessor*, SortedSet<ConnectionInfo>> sourceMap;
298+
269299 for (int n = 0 ; n < tabs.size (); n++) // cycle through the tabs
270300 {
271301 std::cout << " Signal chain: " << n << std::endl;
@@ -296,21 +326,33 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
296326 std::cout << " NOT connecting to audio and record nodes." << std::endl;
297327 }
298328
299- // find the next dest that's not a merger or splitter
329+ // find the next dest that's not a merger or splitter
300330 GenericProcessor* prev = source;
331+
332+ ConnectionInfo conn;
333+ conn.source = source;
334+
301335 while (dest != nullptr && (dest->isMerger () || dest->isSplitter ()))
302336 {
303- if (dest->isSplitter () && dest != activeSplitter && !splitters. contains (dest) )
337+ if (dest->isSplitter ())
304338 {
305- // add to stack of splitters to explore
306- splitters.add (dest);
307- dest->switchIO (0 ); // go down first path
339+ if (dest != activeSplitter && !splitters.contains (dest))
340+ {
341+ // add to stack of splitters to explore
342+ splitters.add (dest);
343+ dest->switchIO (0 ); // go down first path
344+ }
345+
346+ int path = static_cast <Splitter*>(dest)->getPath ();
347+ conn.splitterSettings .push_back (bool (path));
308348 }
309- else if (dest->isMerger () && dest-> getSourceNode () != prev )
349+ else if (dest->isMerger ())
310350 {
311351 // keep the input aligned with the current path
312- dest->switchIO ();
313- jassert (dest->getSourceNode () == prev);
352+ int path = static_cast <Merger*>(dest)->switchToSourceNode (prev);
353+ jassert (path != -1 ); // merger not connected to prev?
354+
355+ conn.mergerOrder .insert (conn.mergerOrder .begin (), bool (path));
314356 }
315357
316358 prev = dest;
@@ -321,7 +363,7 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
321363 {
322364 if (dest->isEnabledState ())
323365 {
324- connectProcessors (source, dest);
366+ sourceMap[ dest]. add (conn );
325367 }
326368 }
327369 else
@@ -373,6 +415,18 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
373415
374416 } // end while source != 0
375417 } // end "tabs" for loop
418+
419+ // actually connect sources to each dest processor,
420+ // in correct order by merger topography
421+ for (const auto & destSources : sourceMap)
422+ {
423+ GenericProcessor* dest = destSources.first ;
424+
425+ for (const ConnectionInfo& conn : destSources.second )
426+ {
427+ connectProcessors (conn.source , dest, conn.splitterSettings );
428+ }
429+ }
376430
377431 getAudioNode ()->updatePlaybackBuffer ();
378432 // Update RecordNode internal channel mappings
@@ -381,7 +435,8 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
381435 getRecordNode ()->addSpecialProcessorChannels (extraChannels);
382436} // end method
383437
384- void ProcessorGraph::connectProcessors (GenericProcessor* source, GenericProcessor* dest)
438+ void ProcessorGraph::connectProcessors (GenericProcessor* source, GenericProcessor* dest,
439+ const std::vector<bool >& splitterSettings)
385440{
386441
387442 if (source == nullptr || dest == nullptr )
@@ -390,16 +445,23 @@ void ProcessorGraph::connectProcessors(GenericProcessor* source, GenericProcesso
390445 std::cout << " Connecting " << source->getName () << " " << source->getNodeId (); // " channel ";
391446 std::cout << " to " << dest->getName () << " " << dest->getNodeId () << std::endl;
392447
448+ // determine what to connect by looking at each merger
393449 bool connectContinuous = true ;
394450 bool connectEvents = true ;
451+ int splitterInd = 0 ;
395452
396- if ( source->getDestNode () != nullptr )
453+ for (GenericProcessor* curr = source->getDestNode (); curr != dest; curr = curr-> getDestNode () )
397454 {
398- if (source->getDestNode ()->isMerger ())
455+ jassert (curr != nullptr ); // should be a path from source to dest
456+ if (curr->isSplitter ())
457+ {
458+ curr->switchIO (int (splitterSettings[splitterInd++]));
459+ }
460+ else if (curr->isMerger ())
399461 {
400- Merger* merger = ( Merger*) source-> getDestNode ( );
401- connectContinuous = merger->sendContinuousForSource (source);
402- connectEvents = merger->sendEventsForSource (source);
462+ Merger* merger = static_cast < Merger*>(curr );
463+ connectContinuous & = merger->sendContinuousForSource (source);
464+ connectEvents & = merger->sendEventsForSource (source);
403465 }
404466 }
405467
0 commit comments