How do I stop sounds of specific tags at a specific duration of an audio track?

Not favoritedFavorited Favorited 1 favourites
  • 14 posts
From the Asset Store
Grenade Sound Library contains: 135 sounds 50 grenade sounds and 85 surface sounds
  • Disclaimer:

    Alright, so,

    Like it is common practice to place all your sprites on a sprite sheet, I have tried to do the same with audio.

    I have all my sound effects relevant to combat in my naval battle game on one audio track.

    Now, before we continue, I've got to say the problem I'm having has *nothing* to do with the fact I have all my audio on one track, rather, this trick is pretty efficient and expedites download times in certain edge cases.

    So yes, I am using this, and separating them isn't going to fix the problem.

    I have looked everywhere for this question, so I apologize if this was asked before, (It has been but unfortunately the person that was having trouble wasn't as experienced in C2-3 & in their case of this problem happening, the solution given to them was far less precise than what my problem requires.)

    Now, with that out of the way, what is the problem I'm having?:

    When you play a sound, you associate that sound with a tag, that way you can stop specific *groups* of that audio-by-tag or modify them.

    This is where the problem starts, for sounds that play frequently stopping audio of a specific tag stops ALL audio of that tag, which is to be expected yes, but frustrating.

    Let me go further into detail to give some more context, why am I stopping sounds?

    I have a cannon firing SFX, this will inevitably play so many times that the volume will increase exponentially until the sound ends, which, by the way, isn't one specific sound effect because all of them are stored on the same file.

    The obvious solution is playing them as separate audio like I said above that I wouldn't be doing, but, for development's sake its much faster for me to keep them in one place as I happen to be the one that produces these sounds, which is the other reason.

    What I've tried:

    1.)

    So, I have to create an audio limiter, that counts the number of times a tag is played and attempts to clamp it so that no new sounds are being played at the same duration.

    But predictably I can only do this by adding a number to each tag, and randomizing when a sound should stop.

    I.E

    play SFX "shoot" & round(random(1, 4))

    if shoot is playing & duration >= 4 seconds (length of that specific section of audio) stop SFX "shoot" & round(random(1,4))

    The problem with this is, there is a chance that this does not stop the audio, and so it continues playing until this function is ran again, and the dice finally lands on stopping that audio of that tag.

    2.)

    I was thinking I could probably combine the is playing condition and specify in its expressions box that if a tag is playing,

    "SFX" is playing & audio.duration >= 4, stop the audio.

    Does not work, seems to ignore the expression as though the condition only cares about the first valid tag thrown in there, never mind the fact there is a logical AND checking to see if that audio reached a certain duration.

    Kind of disappointing, but then again, it's likely I'm doing that wrong and that it is in-fact possible.

    3.)

    Google's AI told me you can stop the last played instance of a sound by using an empty tag "".

    Uh, tried it and it did nothing, I'm guessing this isn't a thing.

    Even if it were, I think this would also stop anything else playing recently, of any tag instead of specifically what I want it to stop.

    Shame.

    Verdict:

    In my opinion it would be far more efficient if there was a way to look for a tag, and have the option to test for duration, or some way to instance specific instances of a tag.

    If you could stop an audio track of tag by AGE or something, so much better than stopping ALL instances of that sound, or trying to roll some dice to split them up into instances.

    If I had separated my sounds, ultimately Id STILL run into this problem, except for individual sounds.

    Before you ask how it's possible for a single sound to play *that* many times where even separating audio into variations isn't enough:

    I want you to picture 20 ships on your side, 20 ships on the NPC side, each ship can have upwards of 50 cannons (technically it's just 20 turrets (1 for each ship), but I have a formula that divides the rate of fire according to the number of guns a ship has) this number comes from a number value stored in a ship and youll quickly reach 100 or so instances of that tag playing within a minute of firing.

    to be clear a ship, is just 2 instances, Im not literally adding 50 turrets to each ship, its just clever math and fire rate manipulation on one turret per ship.

    I'm not going to reduce the scope of my battles because it's a key part of the game's identity, or it will be.

    So, I'm posting this here hoping there is an elegant solution to this that I haven't thought of.

    Of course, I'll still be trying stuff out in the background like I usually do with these posts, because I do have to wait for a response and obviously there's a chance Ill close the post early if I find a solution on my own.

    Oh, I'm open to using plugins or Javascript to achieve the desired effect, so if what I'm doing isn't possible throw me some suggestions on what I can do to force a solution with these options.

  • The only other thing I can think of is,

    because I literally produced the audio,

    I can make a SFX variation on the same track that triggers when a certain number of sounds have played, and so it gets exponentially "broader" instead of loud.

    I.E

    SFX shoot once (sound of one cannon)

    SFX shoot salvo (sound of multiple cannons going off)

    SFX shoot fleet (sound of like 20 or so cannons going off but their audio is mixed in a way where it doesn't hurt your ears), its simple but I'll hold off on that until I'm really sure none of the solutions that we come up with aren't going to work.

  • Why not have a unique tag per sound you play? Like have a global variable ID and when you play a sound set the tag to “shoot”&ID then add one to the ID variable. To keep track of all those tags you could add them to an array, and remove them as they finish.

    I’m unfamiliar with playing multiple different sounds from the same file but I assume it involves having a start and stop time to each sound in the file.

    So roughly the idea would be this. Array.width would be the number of sounds playing.

    global number id=0
    Global text tag=“”
    Start of layout
    — set array size to (0,2,1)
    
    Keyboard: On space pressed
    — set tag to “shoot”&id
    — add 1 to id
    — array: push tag to front
    — audio: play sound with tag tag
    — audio: seek tag to startTime
    — array: set at (0,1) to endtime
    
    Global number vol=0
    Global number I=0
    
    Every tick:
    — set vol to 33*log10(1/array.width)
    — set i to 0
    
    While
    I<array.width
    — set tag to array.at(i)
    — audio: set volume of tag:tag to vol
    — compare: audio.duration(tag)>=array.at(i,1)
    — — audio: stop tag
    — — array: remove index i
    — else
    — — add 1 to i
  • Good idea! I'll give it a shot.

    I was away from this project for about a day and didn't see this notification.

  • I have zero clue how to send videos from my computer to construct, I swear that was a thing you could do but I don't see the option to anywhere.

    Having to upload a youtube video to send videos is kind of time consuming.

    So here is a picture of my events relevant to what I'm doing.

    It sort of works, but not all the time, not sure why.

    I'm guessing the array isn't being filled out properly.

    Let me see if this hyper link works to a local file, doubt it will but I'll give it a shot.

    file:///C:/Users/cjdan/Videos/WhatsWrong.mp4

    Edit: it did not work, no surprise there but would of been nice if it did.

  • In the loop you need to update shoottag. It should be array.at(i). As is it’s just stopping the shoottag of the last sound you started.

    Edit:

    That only partially matches the pseudocode i sent. I’ll have to screenshot the events later i suppose if it’s not clear.

  • My bad, I do have trouble reading pseudo code without drawing to a blank, I assume I didn't get the order wrong though; I just missed couple events.

    This should be abit closer to it now.

    Still doesn't work as intended.

  • Nope as far as I know, its filling the array correctly, it just doesn't seem to see the time limit at (I, 1) of the array.

  • Alright I got it to finally read the array:

    You can see the changes I did on the right-hand side.

    Least, I think its reading it.

    In the gif I have acouple variables Im keeping track of on the left-hand side.

    Relevant ones being:

    "DurationTest" which isn't important to its function, but it does show that the duration maximum is being set each time we create a new entry in the array.

    The correct time is 4 seconds maximum.

    "ShootTag" Is being properly set to "shoot"&shootID.

    "ShootID" Is incrementally going up each time the function is called, as intended.

    I Is incrementally going up, however I notice that it's supposed to reset back to 0 every tick, this does not happen.

    Either way I don't think this is entirely relevant to stopping audio, because all this does I think, is act as the index incrementing up for each new entry, even if this didn't work it should still stop the first entry on the list (I'm guessing), which it doesn't do.

    Changes I made:

    Some changes I did you might not immediately see that I might need your opinion on:

    on line 90 I changed "Audio.Duration(tag) >= Sounds.At(I, 1)" to "Audio.Duration(tag) = Sounds.At(I, 1)"

    because for some reason it just wouldnt create a new entry in the array, or play any sounds if I didnt do it this way.

    Verdict:

    Still doesn't work, but at least its closer to working than I started out with.

    PS:

    Also, your gradual audio thingy is a nice touch but I mixed my audio to taper off, so this isn't required to get this to function.

    I do appreciate it though.

    It also seems to only gradually change audio with every new entry added, which I dont think its supposed to do, I think you intended for it to gradually get quieter as the audio progresses.

    media.giphy.com/media/VANm4b6ZiJziAVskcc/giphy.gif

    Edit: I've been trying to get links to work for awhile now and I guess they just don't.

    I uploaded my gif to giphy and copied a link, I assume its not working because my account is new? I don't know.

  • Bump.

  • I managed to get it to the point where it stops audio at 4 seconds,

    The array is completely useless, or, at least, all it does is separate audio tags neatly.

    but in that case, I don't really need it.

    Construct has an issue with arrays in that they're incredibly useful yet unbelievably difficult to visualize making the amount I want to use them incredibly little.

    I know construct 3's arrays have more visuals to back them up but, it's just not enough.

    From my perspective, I have a 2d array, X contains the tag, Y contains the end-time for the audio.

    I managed to print that end time to show that its correct and its supposedly reading from the right location.

    But, when it comes time to actually use 0, 1 (the location of the stop time in the array)

    It's like its completely ignored or I guess it just can't see it.

    Now I know it sounds like I fixed the issue entirely but truthfully no I have not.

    When my ship's cannons stop firing, the audio continues.

    Which doesnt make much intuitive sense to me, I mean its a loop, it should always be active, not just while I'm shooting.

    The other issue I have is that this system doesn't exactly do what I wanted it to.

    What it does is merely stop audio thats been playing for too long, and keep track of multiple instances of said sound. (When it works anyway)

    What it doesn't do is stop audio from overlapping and thus increasing volume exponentially, which is one of the 3 major issues I wanted to solve.

    The other two is stopping, and playing separate tags of the same audio.

    I have one last idea left before I try to just, make broader audio ques and use my old audio system.

    My current one is to just do a mixture of all of these things and see if it works.

    - Play audio with a function,

    - Make sure played audio doesnt surpass a certain count,

    - Organize audio tags in an array,

    - Stop audio thats reached a currenttime* (not duration because for some reason duration doesnt do what I thought it did, I think duration refers to the TOTAL duration of an audio track, not how much time has elapsed for a given tag) of 4 seconds using those tags.

  • When I write so called pseudocode it usually can be written in the exact same way with events. However, it's probably not clear to most which is ok, but I am not around a computer often enough to whip up an example instead. Anyways, here is an example showing the idea since what I wrote is pretty exact. Only typos were 20 instead of 33 with the volume calculation and "duration" instead of "playbackTime".

    It has only one sound file, in which there are two sounds a gunshot and a monkey. I just wrote down the start and end time of both files.

    Then in the events to play a sound we get a unique tag, play the sound, and seek to the start time. I then add the tag and end time to an array so we can keep track of each sound to stop later.

    To avoid audio clipping from stacking sounds getting too loud I calculate a volume from the number of sounds playing. 1 sound: 100%, 2 sounds: 50%, 3: 33% and so on... The rest of the formula is convert percentage to decibels. It does avoid the clipping, but with a high number of sounds it does make things a bit quiet.

    An alternate idea to handle the clipping could to be to add an analyzer effect to the tags, sum up the peak levels of all the playing sounds, and ease the volume down if it gets too high. Might be a bit heavy though.

    dropbox.com/scl/fi/7574tn2yq9k3wimj8ywek/sub_sounds.capx

    It shows the number of playing sounds at any time.

    Anyways, its just an idea and an array works fine for this purpose.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I've never seen a self-advert bot on this platform before, not cool.

    Anyway, I'll try out what I see in the capx, I appreciate your help R0J0.

    I assumed I'd get something wrong but I'm not going to do what most people do where they take a solution face-value and not tweak it to get it to work in the instance, or to understand how a solution works.

    Otherwise, I wouldn't have known there were acouple issues with it and would of flat out said it was "broken" without giving any helpful feedback to iterate.

    Edit:

    Alright, I got it to work.

    This is definitely more extensive than the first version, function to array allows more sounds to be played.

    My project does have some separate audio, but I just didn't see the need to separate all audio, I have SFX in "packages" that I think are far more elegant to produce and add to my project than hundreds of individual sounds.

    In theory this would let me play SFX & Music at the same time and keep track of both.

    Music is separate, of course, but it would be interesting to see if I can make this even more elaborate to do what triple A studios do where they have separate tracks, but they add a track to build intensity, or subtract to decrease it, so it's like they *make* the music while you play.

    If I do decide to do that Ill post an updated version of this project because I think that's a rather novel way to add-onto what you already built, Perhaps incase they'd like to add it to their game.

    I'm thinking to get this to work Id likely need to create some method of timing it, shouldn't be too hard.

    Maybe I'll try that a week from now.

    Thanks again, R0J0.

  • Updated the formula to account for multiple ships.

    40*log10(1/Sounds.Width) / Ship.Count

    Works fine with 5 ships, each with 50 guns, at 100% laptop volume (headset plugged in).

    Least, I think it sounds fine, but I probably lost some hearing working on this so I have no clue lol

Jump to:
Active Users
There are 0 visitors browsing this topic (0 users and 0 guests)