"Connection Causes Loop" error when using Cue Points on Wave Player

I’m trying to flip between two tracks by crossfading one of them out, loading a new wav into the generator, and then crossfading back in at an arbitrary time.

I’m using cue points to keep things synced up, but when I try to connect the cue point from the 2nd player I get the Connection Causes Loop error. This is despite the fact that it can’t loop (I think) because it’s behind an accumulator that requires another input.

I’ve tried several ways to hide the cue point so that the system doesn’t think it’s looping. In the image I left up my latest attempt which was triggering a different trigger every other cue point. It still treats it as a loop.

How can I grab a cue point from both of these players and use them to retrigger each other?

You could try using a Delayed Get node instead of a regular Get node for your cue trigger variables, but even if that doesn’t cause a loop, I’m not certain the results would be what you’re intending to produce.

From what I can tell:

  • When the Metasound starts playing, Theme1 is going to loop forever until the graph is stopped.
  • When Theme2 starts playing, it too is going to loop forever until the graph is stopped.
  • You can crossfade between Theme1 and Theme2 using the knob.
  • At that point, the trigger counters won’t really be doing anything, as both wave players are still looping.

Perhaps I don’t fully understand what you’re going for, but if you’re simply trying to crossfade between two synchronized sounds, could you just have them both start playing at the exact same time, then crossfade between them?

It’s important to consider that Metasound triggers don’t behave the same way as blueprint execution pins—the entire Metasound graph is evaluated all at once for each audio render block. This has some tradeoffs for sure, but it’s what allows for the sample accurate precision that makes Metasounds so powerful.

You’re nearly correct, but outside of the metasound, a blueprint is changing out the .wav files feeding into the players. Imagine a cassette player ejecting tapes and inserting different ones. The triggers restart the wave player with the new .wav.

This part is working and I can cycle through any number of wav files I choose and crossfade between them. I can flip back and forth forever and play different .wavs all day.

However, since the trigger is activated from outside the metasound, it’s always late on the activation and the beat is off.

So, I added the accumulator trigger and cue points. This fixes the latency, but I can only do one “flip” because connecting the second wave player causes the loop error.

I know you can do this stuff with Quartz but I was hoping metasounds would allow you to do it much simpler.

Ahh, I see, thanks for the additional context.

The loop error would be caused by the possibility of both cue points happening in the same audio render block. Using GetDelayed nodes will prevent the loop from occurring, but there’ll be a small delay between the cue point and playing the next wave so that’s probably not a good enough solution.

I’m not sure how to work around this using cue points. It’d be nice to have “OnNearlyCuePoint” and “OnNearlyLooped” to match the OnNearlyFinished trigger which is the only output trigger on the wave player that allows for sample-precise audio concatenation. I may play around with this.

I have 3 things I’m going to try:

  1. There’s a “Trigger Repeat” that I should be able to use:
    Creating a Clock for Procedural Audio - MetaSound Tutorials for Unreal Engine 5 - YouTube

  2. Perhaps I can put some sort of gate in where it will only trigger if the other Cue Point is not triggered, and that will make it happy that no loops are happening.

  3. My “dirty” solution is using a third short, silent .wav file as a “metronome/clock” and use its cue points to trigger the other 2.

I will post an update in a day or so and hopefully I’ve found a solution.

If I can get around this without digging into Quartz I’ll be happy.

1 Like

I had a fundamental misunderstanding of how these worked. Thanks for your help.

I figured it out using Trigger Control, Trigger Delay, and Trigger Repeat.
My blueprint sends a trigger, which opens a gate, which allows the next beat from the clock/BPM counter to pass through, which triggers the Wave Player. After a delay, the Control gate is closed so that further beats won’t retrigger the Wave Player until I’m ready.

3 Likes

You can use the Trigger Once instead of the Trigger Delay with Trigger Control.