wiremod / wire

Garry's Mod add-on that allows users to wire up components in order to make more elaborate automatic and user-controlled contraptions.
http://www.wiremod.com
Apache License 2.0
547 stars 332 forks source link

Possible wiremod expression2 soundPlaying() bug #3091

Open raven1934 opened 2 weeks ago

raven1934 commented 2 weeks ago

Hello, I have tried to make another project which involves checking if a sound is already playing each tick of the chip as it only needs to be put on just once and then the pitch and volume is adjusted during it's use. I however utilized the use of soundPlaying() to check if the sound is already playing to prevent excessive sound resource use, but it seems to be unrealiable at times and causes even second long gaps at the update, this is very bad as during that second my chip reinitiates the sound to start playing and causes massive lag to server and myself... I'm unsure if I can use some conditional myself to prevent this from happening as a bypass, but I wanted to ask if someone more experienced has ran to same problem and if it's a bug or whether there's something I've overlooked.

The basically simplest setup to replicate the issue in my opinion is just making following setup, as I've managed to in my opinion to narrow it to the sound commands themselves. The result is choppy spammy sound that repeats from the sounds start, and since no other block of commands initiates the soundPlay of that particular sound it has to be here as there's no way the stopSound block is accidentally triggering as it's specific parameters aren't met. Thanks for whoever looks into this stuff btw!

if(!soundPlaying("EntitySound")) { Entity:soundPlay("EntitySound",soundDuration(SoundPath),SoundPath) }

runOnTick(1)

Fasteroid commented 6 days ago

You MIGHT be able to work around soundPlaying not working correctly if you do it yourself with a timer, like this:

@persist PlayingSounds:table

function entity:betterSoundPlay(ID:string, Duration:number, Path:string){
    PlayingSounds[ID, number] = 1
    timer("soundEnd_" + ID, Duration * 1000)
    This:soundPlay(ID, Duration, Path)
}

function number soundIsPlaying(ID:string){
    return PlayingSounds[ID, number] # if it doesn't exist, this will return 0
}

event tick(){
    foreach(ID:string, _:number = PlayingSounds){ # check everything that's playing
        if( clk("soundEnd_" + ID) {
            PlayingSounds:remove(ID)
        }
    }
}

Not tested ofc, I wrote this at work (lol), but it should be one or two easy fixes away from working.

Unfortunately, playing E2 sounds on the same id/entity within a few ticks of the previous one ending is still unreliable (in my experience), so if you need some seamless looping sound you might need to pingpong it between two different sound IDs and entities (I like to use holograms)

Good luck!