Feature Request - Play on Stop

(Jesse Lyon) #1

We had a feature in our previous in house audio engine that would play out a specified audio track in a sfx event when receiving a stop event before killing the sound. This was used for pretty much every looping event that plays a tail sound on stop (ie. guns, engines, water , fire, etc). Currently in FMOD you would have to trigger this as a separate event. Would be great if it could all be contained within one event, would simplify and clean things up nicely.


(Brett Paterson) #2

You don’t need a separate event, you can break out of a loop with a parameter, and play the tail pretty easily.
ie, i just made a parameter called playtail from 0-1 and it only loops if playtail < 0.5, and setting it to 1.0 makes it break out.

If you dont like the parameter idea, you can do it by putting loop with its timeline, inside another event as a reference event. Just drag that loop event into a new event as an eventsound, and put a sustain point in the parent event, in that timeline, in the middle of the loop event’s box. Then all the programmer has to do is execute a keyoff command instead of stop to play a tail sound which can be just to the right of the loop sound.
This is done with getCue, and Cue::trigger(), instead of stop.


(Brett Paterson) #3

for the 2nd method, you can just use a sound with its loop button ticked on (top right of instrument panel down in the deck), rather than using an event with a loop region. It just depends how complex your loop is.

(Jesse Lyon) #4

Both great workarounds, thanks Brett! The first method is probably best, as I dont currently have a programmer available. However, adding a simple “play on stop” feature (such as a tickbox on the track) would be even better, as it would all be handled with the one stop command, and I wouldnt have to deal with additional in game parameters or programmers!

(Brett Paterson) #5

‘play’ what though? There is a timeline there, and the idea is that you want it to play forward after pausing in the timeline.
Another idea is to use a transition point that only leaves on a certain event (like a stop). You need some transition logic in your event, not just ‘play x or y’ , thats not a concept that is part of the studio interface, and sounds a bit hard-coded.

The keyoff method lets you do what you need, but the issue is the programmer has to trigger a cue instead of calling stop. Do you mean, if you use a stop command, it should not stop but automatically trigger a sustain point, or maybe my other idea, a transition that kicks in if stop is called?

(Jesse Lyon) #6

Exactly, when receiving a stop command from the game (UE4 in my case), it should not stop the looping event immediately, but play out a sustain point before killing the sound. I’ll play around with the transitions a bit more, I’m sure I can get it working that way with the suggestion you provided.

(Brett Paterson) #7

new method. cross posting from other thread

Here’s a new method I just came up with that only requires a stop call.

  1. If your sound is on the timeline put a loop region around it
  2. put a transition region on the same range
  3. add a parameter
  4. modulate the parameter with an AHDSR. ADHDSR has a special feature that when you call stop, the release phase plays out even after you call stop (as long as its not stop immediate).
  5. Add a parameter condition to your transition region, so that the condition triggers as soon as the release part of the AHDSR starts releasing. So if you have the condition 0-.99 and your AHDSR is set to 100% for everything except the release part, it should trigger the condition as soon as the release starts.
  6. add a destination marker, set it to be the transition regions target.
  7. place your tail sound at the new target marker.
  8. make sure the release in the AHDSR is long enough to handle the length of the tail sound.

To test it, you hold down the stop button, dont just click it. The stop button will start flashing and execute the release stage in the envelope, it flashes for as long as the release stage is active.

(Jesse Lyon) #8

Hi Brett, can you explain in a little more detail how to get the AHDSR release to play out on stop? I have it setup as you describe, and its transitioning properly based on the parameter condition, however I cant get the stop light to flash when I hold the stop button down. The AHDSR plays out immediately when pressing play (it actually jumps to the transition marker as soon as the envelope hits 100%)

(Brett Paterson) #9

when you play the event, if you hover over the stop button does it say ‘pause / hold for non immediate stop’ ? If not it may be your version of studio that you are using that doesnt have the feature. Which version are you using?

(Jesse Lyon) #10

Yes, it says ‘pause / hold for non immediate stop’. We’re on V1.07.03. When holding the stop button during play, playback always seems to stop after the amount of time the AHDSR release is set to, and does not transition to the target marker. The stop button will also not flash. Im also seeing that the loop portion will only play for the amount of time the Attack is set to, then immediately transitions to the target marker, it is not respecting the transition region’s parameter condition. (I would attach a screenshot, but not sure how to do that)

(Brett Paterson) #11

Yes the event will stop after the length of time specified in the AHDSR release. Try setting it to 5 seconds or something to test that. Is your release just really short so it doesn’t get time to flash?

(Jesse Lyon) #12

Ah, I couldnt see it flashing because I was continuing to hold the stop button. You will only see it flash if you hold stop for a few seconds and then release it.

OK, so I think I get how this works now, but the issue now is, I want the loop to remain looping until the user releases the trigger. The AHDSR will only play the loop for the amount of attack + hold time set, then it immediately releases. How would I go about having it ignore the attack and hold time and loop forever until it receives a stop trigger?

(Brett Paterson) #13

Ok this is maybe an even better method than the one posted. I forgot that a loop region can have a condition if it loops or not.

Get rid of the marker and transition region, butt the tail sound up to the loop, add a loop region to the start with a condition based on the same AHDSR logic, but this time it plays the loop if it is 0.99 to 1.0, and when the AHDSR triggers, it drops below 0.99 and leaves the loop.

Testament to the flexibility of studio!

(Jesse Lyon) #14

Getting closer, that solution works as far as playing out the tail when the parameter condition is met, but the issue is it dosent transition to the tail sound immediately, it waits until it reaches the end of the loop. This would be an ok solution for most scenarios, but wouldnt work for something like a gun loop that would need to be tightly synced to the player releasing the trigger.

Also, this still requires sending a parameter from the game in order to trigger the AHDSR. Its just as easy to trigger a separate event for the tail sound when the stop event is received.

Sorry, not trying to be a pain and please dont worry about it too much. Tthis is all quite useful for me while learning the features of Studio.

(Jesse Lyon) #15

Well I must be either missing something or Im misunderstanding your first method, as I cant seem to get it to loop indefinitely until receiving the stop command. It will only loop for the attack/hold time set in the envelope. Hopefully I can make it to GDC this year and we can look at this together in person!

(Brett Paterson) #16

that’s because the condition in the loop conditions is not met, so it leaves the loop.
This means you should be looking at your ADSR. You could delete your ADSR and modify the parameter by hand to test it.

Then the adsr is added to your parameter. Push every envelope point to the top, like in the picture, and set the initial value of your parameter to 1.0, then it should work.

(Brett Paterson) #17

The whole point of the new method was to play out the loop. I see I misinterpreted your original issue, where you said ‘it only loops until the AHDSR executes’ which isn’t true. The AHDSR jumps straight to the Sustain point and stays there until stop is called by the game. This means the parameter value should be staying at 1.0 until stop is called.

Both methods above do NOT require sending a parameter from the game. The whole point is you call stop, and the R part of the envelope triggers, which makes it automatically exit the loop. There is no game code required.

I thought originally you didn’t want it prematurely leaving the loop, so the new method lets the loop play out, which is perfect for something like gunfire.
If you want it breaking out in the middle of a loop, because your loop has multiple sounds in it, then that’s what the original method is for.

If you need to to break out of a loop at a specific point because you’re not looping a single bang noise, but say 4 bang noises per loop, that’s what quantization is for, you can set it in milliseconds, inside a transition region.

edit: better than a region in this case, is 4 transition markers instead of a region, then it will break out wherever you want it to.

(Jesse Lyon) #18

When I remove the ADSR it loops fine. When I add the ADSR and push every point to the top, it starts playing from the tail marker every time, no matter what the parameter is set to, even if I remove the parameter condition.

(Jesse Lyon) #19

Bah, I rebuilt it from scratch and now its working fine!

Thanks for your help Brett, sorry for the run around.

Edit: I figured out why it wasent working before, I had the parameter condition setup opposite from yours, with the condition valid at the high end (0.99-1) rather then the low end. Now its looping fine when set to 1, and then transitions and plays out the release when it gets the stop and parameter is set to 0. Thanks!!!

(Steve) #20

@ guys : Thanks for the interesting thread and methods there is just something I am confused about as I reread your thread a couple of times on this part : “Push every envelope point to the top, like in the picture, and set the initial value of your parameter to 1.0, then it should work.”

Why do we need to set the initial value to 1, what value does the one represent against the ADSR? I set the initial value to 0 and the tails play correctly when stoping (long click on stop) via Fmod. I did exactly the same as Brett : setting a condition from 0-0.99 on my loop, except having initial value at 0 and it does the same thing.

Although I noticed that If during playing I move the condition range to 1 (double end cursor on the transition region) then it plays automatically the tail…

If you set the condition from 0 to 0.99 on the loop does this mean o from 99 % of the ADSR, 100 % being the initial parameter so 1?

Just need to understand clearly, thanks!!