No Repeat Metasound function not working

I’m finding that the No Repeat functionality in Metasounds is simply not working. Was told there was a fix for it in 5.5 which we recently upgraded to but still having the same problem unfortunately. Have tried with all the different shared state behaviours as well

Can you give us more information?

The primary thing that most folks are confused about is the no-repeats functionality as it approaches the number of variations in the array. We did check in a thing that properly clamps it so as to avoid the confusion. But the main thing is to make sure the no-repeats “max” is about half the array size.

Here’s a paste of a write up I gave about this issue for the JIRA that we fixed in 5.6:

"The issue here is that people are confused about repetition and patterns when the no-repeats value is set to something close to the size of the array. Due to the nature of no-repeats you end up repeating the last couple of elements over and over.

Say you have 5 values – 0, 1, 2, 3, 4 with a no-repeats of 4.

You randomly pick the first 4;

3, 2, 4, 0

Your only choice is 1:

3, 2, 4, 0, 1

Now you drop out the 3 since it can be chosen again:

2, 4, 0, 1 [ ]

But 3 is now your only choice so you get:

2, 4, 0, 1, 3

Drop out 2:

4, 0, 1, 3,

and so on – forever cycling the same pattern.

No repeats really only makes sense as a mechanism to avoid repetition (while maintaining a feeling of randomness) if the no-repeats is about half the size of the array or less."

Hey Aaron, I ran a few tests where I changed the No Repeat number and I still get the same sound repeating twice (or more) in a row. When I had 2 wavs, I tried a no repeat of 1, and I would still get the same sound triggering in a row. When I had 4 wavs, I did a No Repeat of 2, and same problem. This also occurs no matter what Shared State Behaviour I pick.

Is this No Repeat functionality meant to work when pressing play in a Metasound? Or only in-game? (I’ve been testing in a Metasound)

[Image Removed]

I’m also confused by your write-up.

"Now you drop out the 3 since it can be chosen again:

2, 4, 0, 1 [ ]"

Why does the 3 need to be dropped out here? The 3 was the very first number chosen (in 3, 2, 4, 0, 1), so by the time it gets to the second cycle, if it were to choose 3 again, then it would not be repeating 3 since it played 5 numbers ago.

So it would be (3, 2, 4, 0, 1) (3 ? ? ? )

I may not be understanding what you’re saying though :face_with_crossed_out_eyes:

I guess it depends on your definition of not repeating.

I would assume that most designers don’t want an endlessly repeating cycle of the same numbers over and over:

3, 2, 4, 0, 1

2, 4, 0, 1, 3

4, 0, 1, 3, 2

0, 1, 3, 2, 4

1, 3, 2, 4, 0

Obseve that this is the same sequence of numbers in a very repeated pattern. Any individual varaition choice is not repeated from the previous, but the cycle overall is a repetiion.

This would sound very bad in most contexts: if you were trying to play footsteps and using such a setup, it would end up sounding like music as the footsteps repeated the same exact cycle. It certainly would *not* sound random.

This extreme case of exact sequence repetition only happens if your no repeats is N-1 where N is the number of variations you have. It is still pretty bad though until you are at a NoRepeats of N/2. Basically, setting no repeats to about half your variation count guarantees a balance between variability and no repeats.

At low variation count, you run into the same issue. If you have only 2 variations and a no repeats of 1, you just get:

1, 0, 1, 0, 1, 0, 1

The problem perists until you have more than 3 variations.

We recently made is so 3 variations (so 3 or greater) can have a no repeats of 1 (basically the half-clamp rounded down).

When this node was first made, I argued to keep the situation as it is with no clamping and trusted designers to be able to understand the situation but there were many reports of people saying this feature didn’t work when it stemmed from a lack of understanding of the issue of no-repeats as a math sequence problem. The other thing is that MetaSound graphs are reused a lot, so input variations are often widely variant. So, rather than forcing people to do a bunch of logic to clamp their own no-repeats to do a reasonable thing, no matter the variation count, we decided to add the clamps on the low end and the clamp on N/2 so that “the best case” is optimized with the least amount of effort or understanding. But as you are experiencing, it still isn’t totally clear to people.

But, hopefully, that explains what you’re observing.

If you understand the situation now, how would you prefer this information and situation be presented to help us avoid future confusion from our users?

Yeah ok. I understand what you’re saying. Having a low-end clamp and an N/2 clamp on the upper-end makes a lot of sense, and that’s kind of what I would expect from something relating to this. I guess the problem for me specifically is that the No Repeats functionality simply doesn’t work at all (I’m assuming a bug on my end). When I have 2 variations and set a no repeats of 1, I can still get repeats (like 0, 1, 1, 0, 0, 1, 0, 0, 0) etc. It’s the most simple way of doing this and yet it doesn’t work for me so something must be wrong.

But back to the theory behind it, the behaviour that I “expect” when I see a “No Repeats” function is basically what you’re describing. The automatic clamping is great so as you said I don’t have to always do the maths based on how many variations there are. If I have lets say 7 assets, and I set a no repeats of 4, to me that implies that if one asset is chosen (lets say #1) then it cannot be chosen again until 3 “other” assets have played. And of course there’s no guarantee it will play after those other 3 assets since at that point it’s random between 1, 5, 6, and 7 (assuming the order of chosen numbers was 1, 2, 3, 4). So in this case there will always be 4 free numbers to randomly choose from. If I set the no repeats to 5, then the random choice number goes down to 3, and so on. And so yeah it makes sense that the optimal no repeats is around half the total variations.

I think what would make this more user friendly is to dynamically and automatically have the No Repeats set to half the number of assets, with an option for the user to (for whatever reason) change that to something lower or higher (I’m sure there are some rare cases where people would want to do this, but in the vast majority of cases, people want it to simply feel as randomized as possible). So instead of forcing the user to choose a No Repeats input number (on a node that is almost certainly going to have a different number of wave inputs depending on the metasound), I reckon just take that choice away unless the user opts to have it, and just have it do your clamping thing by default.

So maybe the wave player by default doesn’t even need an input for No Repeats, but you have a checkbox (or whatever way makes sense based on your current UX) to disable the automatic clamping and choose a custom value.

Hope that makes sense, keen to hear your thoughts.

“When I have 2 variations and set a no repeats of 1, I can still get repeats (like 0, 1, 1, 0, 0, 1, 0, 0, 0) etc. It’s the most simple way of doing this and yet it doesn’t work for me so something must be wrong.”

Yeah, this is what I was trying to explain. If you have 2 variations, with a no-repeats of 1, you would get:

1, 0, 1, 0, 1, 0, 1, 0

Again, if you define no repeats as avoiding a repeating seqeunce, a 1-0-1-0 sequence is very repetitive. The whole sequence (1 and 0) are repeated over and over.

So, effectively, if you want to avoid an immediate repetition, you want more than 3 variations. I think what is in the version you have has a check for > 3. The latest version in 5.7 is >= 3. So no-repeats of 1 w/ 4 variations will avoid immediate repetion. In 5.7, if you have 3 variations, you can do a no-repeats of 1. There was a debate where exactly to cut off the min variation count.

Yeah, I like your idea. We have node configuration as a new API coming in, so maybe we can add more advanced configuration options with the random-get node that lets designers do exactly what they want, even if it’s not exactly going to work as well as they like.

Ok I think I’ve realised that the No Repeats functionality doesn’t work in-editor, it only works in-game. I think that’s been confusing me big time. I was just pressing play in the metasound and hearing repeats no matter what amount of variations and what “no repeats” I had set. But then I tested out 3 variations + 1 no repeats in-game and it worked.

So as a rule of thumb, just always opt for half the amount of variations for no repeats, and if there’s an odd number, round down.

Thanks for your help in understanding this.

PS. Glad you like the idea.

Ah yes, every time you play the MetaSound from scratch, it’s a fresh global state, and it’s not tracked between plays. We reset the internal history on purpose.

However, I think this has been brought up before that it is confusing to folks who are pressing play multple times in the content browser or MetaSound editor.

I wonder if we can come up with some sort of toggle in the MetaSound Editor or content browser that tracks state between plays. What UX would you think would make the most sense to help us distinguish that? I don’t think we want to keep state always/forever as that would cause different more subtle confusion, but an option to enable that makes sense.

You can sort of simulate what it’d sound like if you use a trigger-repeat with your random get. It should work that way.

Good to know! I think part of the reason why it is confusing to me is because Concurrencies do apply when pressing play in the editor.

Hmm yeah an option to change between that state makes sense. I would say put it somewhere in the Metasound editor, but since you can trigger metasounds directly from the content browser, maybe it should live elsewhere. I’d say either an option in the top menu, or in the Metasound editor (it would make sense to have it in that little audition dropdown since it’s related to auditioning sounds). Perhaps you could have it there + somewhere else outside of the metasound editor incase they don’t have it open (that one I’m not really sure because I imagine you don’t want an audio setting in the content browser settings -- although maybe you do)

Also I just want to confirm. When you said “we decided to add the clamps on the low end and the clamp on N/2 so that “the best case” is optimized with the least amount of effort or understanding.”

Does that mean no matter what the number set in “No Repeats”, it will never be more than half of the variation count? Is that what you meant by N/2? What’s confusing to me is “low end” to me suggests the minimum number, whereas N/2 represents the maximum number. I was going to add my own logic in the metasound patch to basically just also do half of the variation count rounded down so we never need to add in a number manually. But do I even need to do that?

I don’t think you should need to do it, no. It should do it under the hood automatically. I believe the tool tip was also updated to reflect that.

On the no-repeats pin, the tooltip that pops up should be:

“The number of elements to track to avoid repeating in a row. This is clamped to be within half the array size. The output will end up repeating a clear pattern if set close to the array size. Set to -1 to automatically set to half the array size (which is the maximum no-repeats behavior)”

The TT does not say the min-clamp, but it also ignores no-repeat if your array size is too small. In 5.6, I believe it’s ignored for array sizes > 3. (i.e. you need 4 elements before no-repeats starts being listened to). In 5.7, it was changed to >=3 (i.e. you just need 3, and it ends up clamping no repeats to being just 1).

If you want “maximum no repeats” just set it to -1.

Yeah ok. Perhaps we’re getting confused with version numbers. I’m on 5.5 currently. Is the clamping only available in later versions? Mine only says "“The number of elements to track to avoid repeating in a row”. Also (sorry if we’re going in circles at this point), but in 5.5 specifically, if I set a no repeat of 1 and I have 2 assets, it should still never repeat the same one and just do a 1 2 1 2 1 2 pattern right? Because this doesn’t happen for me. I also tried a no repeat of 1 with 3 wavs, and the same sound can still play in a row many times. Even if I do a No Repeat of -1, still has the same sound repeating multiple times. I feel like I’m back to square one haha. I think it just doesn’t work in 5.5 maybe?

So I think I’ve finally figured out why the hell it hasn’t been working for us. It’s confusing and would love your clarification on this.

Many of our Metasound Sources use a base Metasound Patch which contains the Random Get/Wave Player. I figured out that if the MSP inside uses the Shared State Behaviour of “Get Node” then the No Repeats will not work.

The confusing thing though, is that if I simply use a Metasound SOURCE that doesn’t link to a Patch inside of it, and I use the “Get Node” behaviour, then the No Repeats does work. I just don’t really understate what these shared state options actually mean even after reading the descriptions.

I changed the Metasound Patch to “Get Data” and that has solved the issue for us finally (don’t understand why)

So my question is, how do these Shared State Behaviour options actually work (in laymans terms)?

The description for “Get Node” says: “State is shared with other instances of this individual node regardless of the Metasound it is in”. Me and my colleagues are all quite confused about what this exactly means. What does “This individual node” mean exactly? The node is a Random Get node right? So the wording is kind of saying that every single Random Get node in the project will have a shared state? But that doesn’t really make sense. Because what we care about is whether the selected Wav is repeated or not.

Just some friendly feedback from all of our experience with this issue, the descriptions for the shared state behaviours are just very hard to understand. Simply getting No Repeat to work properly has been a complete brain workout for something that is generally audio 101 stuff.

Would love to hear your clarification on this system and how it actually works. Thanks!

Have you checked out the different Shared State enumeration options? There are different ways to define shared state behavior:

SameNode:

“State is shared with other instances of this individual node regardless of the MetaSound it is in.”

Same Node in Composition:

“State is shared with other instances of this node with the same parent MetaSound graph(s). Useful for differentiating shared state between nodes used in different presets or multiple composed graphs.”

Same Data:

“State is shared with other nodes with the same input array data (by value) regardless of where the node is located. Useful for sharing state regardless of graph composition or between multiple nodes within a single MetaSound using the same input data. Input array type must implement a hash function.”

Maybe this is where you’re getting confused? If you step back and think about the problem of sharing state between executing graphs, you realize there is some nuance here and behavior you have to select and think about.

So one big caveat that was reminded to me by one of my team members is that MetaSounds are rendered asynchronously -- i.e. at the same time. So there isn’t necessarily a guarantee 100% of the time that the shared state is always going to be perfectly represented in reality. The shared state itself is thread safe, but we don’t “lock” the render of the whole graph while it executes it’s logic so two MetaSounds playing at the exact same time may have some variant behavior depending on when the MetaSound async task is scheduled. In practice, this is not a huge deal but if you’re building careful toy tests where you execute two MetaSounds at the same time, you may get variable behavior.