Checking if a sound is playing, not working!

If I had to guess, I’d start from here:

So when a sound is played it will check if it matches a sound file.

I setup an ambient_generic entity to loop a sound rain.mp3 located in sound/rain.mp3 and I made it print “IT’S RAINING” if the sound is playing (Which it always is) and another to print if it isn’t raining, for some reason it’s printing it’s not raining so my sound check may be wrong.

function SoundCheck()
for k, v in pairs(ents.GetAll()) do
if v:GetClass() == "ambient_generic" && v:EmitSound() == "sound/rain.mp3" then print("IT'S RAINING!") else print("not rain :(") return end
hook.Add( "EntityEmitSound", "SoundCheck", SoundCheck )

I also tried

if v:GetClass() == "ambient_generic" && v:EmitSound("sound/rain.mp3") then print("IT'S RAINING!") else print("not rain :(") return end

Here’s where it got really confusing, I just made a check if a sound was even playing at all and it always said no, even though there clearly was.

if v:GetClass() == "ambient_generic" && v:EmitSound() then print("IT'S RAINING!") else print("not rain :(") return end

And even more confusing, checking if there’s an ambient_generic always returns false as well, there most definitely is an ambient_generic entity in my map.

if v:GetClass() == "ambient_generic" then print("IT'S RAINING!") else print("not rain :(") return end

If I remove the

else print("not rain :(")

then the game crashes every time.

I am very stuck and would appreciate it if someone could help me out.

You can get the sound file and entity from the table provided to the

GM:EntityEmitSound hook. You should not have to call EmitSound, and you are crashing because EmitSound calls the EntityEmitSound hook, so you’re creating an infinite loop.

I don’t know what you mean.

[editline]28th October 2017[/editline]

After reading what code_gs said, I tried this:

function SoundCheck(SoundName)
local sounds = table.ToString(SoundName)
if sounds == {OriginalSoundName="Weapon_Crowbar.Single"} then print("Crowbar!") return end
hook.Add( "EntityEmitSound", "SoundCheck", SoundCheck)

If I do print(sounds) it does print sounds, but like this:

The problem is checking the sound:

if sounds == {OriginalSoundName="Weapon_Crowbar.Single"}

How do I check it right?

hook.Add( "EntityEmitSound", "blah", function( data )
    if data.OriginalSoundName == "Weapon_Crowbar.Single" then
end )

[editline]28th October 2017[/editline]

Or with your code:

local function SoundCheck(data) 
if data.OriginalSoundName=="Weapon_Crowbar.Single" then print("Crowbar!") return end
hook.Add( "EntityEmitSound", "SoundCheck", SoundCheck)

[editline]28th October 2017[/editline]

Please make your functions local

This works, thank you! However, it isn’t detecting the rain.mp3, does EntityEmitSound only look for game sounds?

I think the reason your rain check doesn’t work is because it doesn’t really make any logical sense. I’ll try to explain what it does, based on this code:

local function SoundCheck()
    for k, v in pairs( ents.GetAll() ) do
        if v:GetClass() == "ambient_generic" and v:EmitSound() == "sound/rain.mp3" then
            print("IT'S RAINING!")
            print("not rain :(")

hook.Add( "EntityEmitSound", "SoundCheck", SoundCheck )

So, whenever any entity emits a sound, you’re looping through every single entity in the game.
You’re checking all of them to see if any of them has the class “ambient_generic”. This bit works.
However, the problem is that v:EmitSound() DOES NOT return the sound currently playing.

v:GetClass() returns the class of an entity, because that makes sense.

However, v:EmitSound() does not work, because it only EMITS a sound.
Also, having no arguments for that function won’t help, because it needs a sound to play.

However, if v:GetEmittedSound() was a function, that would make sense.

Anyway, to fix this and to avoid looping through every single entity, you just need to use the data table correctly.

hook.Add( "EntityEmitSound", "blah", function( data )
    if data.Entity:GetClass() == "ambient_generic" and data.SoundName == "sound/rain.mp3" then
        print("IT'S RAINING!")
end )

If this does not work, the sound may be “rain.mp3” instead of “sound/rain.mp3”.

[editline]29th October 2017[/editline]

Sorry if this makes no sense, but I just think you need to think logically.
The logic of v:EmitSound() being used for anything other than emitting a sound is not very solid.

It makes sense, it means a lot to me that you took the time to explain all of that. I think a GetEmittedSound should be added.

I’ve tested it and I added

local datastring = table.ToString(data)

I’ve been watching the console for a while now, here’s the weird part, when I click disconnect, it logs the custom looping sound right before I leave. I even tried stopping/starting the sound, because I thought maybe the reason that was happening was because it was on a loop, but that wasn’t the case.

You could just use


I can only guess the sound is getting logged because it tries to restart the sound whenever the server does something. I have no clue really.