Rollover Sounds Produce Electric "Burr"

I have a short rollover sound applied to a number of UI-controls, and I find that if I sweep the mouse-cursor quickly over closely-set controls, the audio acquires an unpleasant electric “burr”.

The following short video shows the issue. First the mouse is passed over the controls at a moderate speed, in which case the sounds are, I think, much as expected. Then the mouse is passed over them at high speed, in which case the “burr” is heard.

I asked after this on another forum, and there it was put down to the sounds interrupting each other. Specifically, it was suggested that I “… [generate] multiple AL sources … and [cycle] through them every time [I] assign a buffer and call alSourcePlay …”.

That said, a quick test seemed to suggest that not all overlapping of these sounds produces the “burr”. I’m wondering, then, whether it’s not a matter of whether the sounds overlap but of the degree of overlapping. Perhaps I’m running out of audio channels, or some such?

It just , the sound stops and starts again. If expressed in terms of not enough polyphony for an audio manager. The problem should disappear if you create a copy of the sound for each button.

That’s a lot of copies of the sound, all told–the screen shown here isn’t the only one. Is that wise?

If this sound outputs Direct GUI? Most likely, he has his own audio manager for the buttons, which provides for the end of the playback of the previous sound in order to reproduce the new one. If there was a polyphony, it would create a piano effect. Most likely this is a GUI break. However, I use PYO for sound and now I don’t have such problems.

Indeed, I’m just assigning the sound in question to the buttons (and other controls) via the “rolloverSound” DirectGUI keyword.

Hmm… I’m not sure that this is the case–or if so, perhaps I’m missing it. I’m just using “loader.loadSfx” to load the sound-file in question–perhaps I should be loading them via a dedicated audio-manager?

I think that I do hear that if I try something similar on certain other controls. One (highly speculative and inexpert) thought is that it might be that those are far enough apart that I don’t get too many sounds overlapping, which might be flooding the available channels.

I don’t know that one. I’m glad that it’s working out for you! :slight_smile:

For myself, I’m loath to replace my entire sound solution at this point, I fear! I’m hoping that this can be fixed within Panda’s sound-system… ^^;

That’s what I was talking about. But this is not wise.

from direct.showbase.ShowBase import ShowBase
from direct.gui.DirectGui import DirectButton
from direct.task import Task

class MyApp(ShowBase): 

    def __init__(self): 
        ShowBase.__init__(self) 

        self.mySound = base.loader.loadSfx("shot.ogg")
        self.mySound1 = base.loader.loadSfx("shot1.ogg")
        self.mySound2 = base.loader.loadSfx("shot2.ogg")
        self.mySound3 = base.loader.loadSfx("shot3.ogg")
        self.mySound4 = base.loader.loadSfx("shot4.ogg")
        self.mySound5 = base.loader.loadSfx("shot5.ogg")
        self.mySound6 = base.loader.loadSfx("shot6.ogg")

        
        self.accept('space', self.shot)
        
        a = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (-0.2, 0, 0),scale=.05, command=None)
        s = DirectButton(text = ("OK"),rolloverSound = self.mySound1, pos = (-0.2, 0, -0.05), scale=.05, command=None)
        d = DirectButton(text = ("OK"),rolloverSound = self.mySound2, pos = (-0.2, 0, -0.1), scale=.05, command=None)
        f = DirectButton(text = ("OK"),rolloverSound = self.mySound3, pos = (-0.2, 0, -0.15), scale=.05, command=None)
        g = DirectButton(text = ("OK"),rolloverSound = self.mySound4, pos = (-0.2, 0, -0.2), scale=.05, command=None)
        h = DirectButton(text = ("OK"),rolloverSound = self.mySound5, pos = (-0.2, 0, -0.25), scale=.05, command=None)
        j = DirectButton(text = ("OK"),rolloverSound = self.mySound6, pos = (-0.2, 0, -0.3), scale=.05, command=None)
        
        a1 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, 0),scale=.05, command=None)
        s2 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, -0.05), scale=.05, command=None)
        d3 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, -0.1), scale=.05, command=None)
        f4 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, -0.15), scale=.05, command=None)
        g5 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, -0.2), scale=.05, command=None)
        h6 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, -0.25), scale=.05, command=None)
        j7 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, -0.3), scale=.05, command=None)
        
    def shot(self):
        self.mySound.play()

app = MyApp()
app.run()

On the right side is your approach. And on the left - fix this problem. However, in the audio manager, the same sound refuses to copy during the new playback, it just plays again. This is a limitation of the audio manager, I think it needs fixing.

Sorry, I’m not clear on which “that” you’re referring to. Do you mean that you agree that it’s too many sounds overlapping, or that I should be using a dedicated audio-manager? (Or something else that I’ve missed?)

I take it that you mean “top” and “bottom”, respectively? That I should be loading once, and assigning many times?

If so, I was operating under the impression that the audio-system would work much like the model-loading system–that is, that subsequent “loads” wouldn’t necessarily replicate data, but instead use previously-loaded data. Am I mistaken in that?

Conversely, however, if I load once and assign many times, will the sounds overlap properly–after all, if there’s only one sound-object to be played, how can it overlap itself?

I’m honestly not sure of how Panda handles these things behind the scenes, and thus how I should use Panda’s features… ^^;

from direct.showbase.ShowBase import ShowBase
from direct.gui.DirectGui import DirectButton

class MyApp(ShowBase): 

    def __init__(self): 
        ShowBase.__init__(self) 

        self.mySound = base.loader.loadSfx("shot.ogg")
        self.mySound1 = base.loader.loadSfx("shot1.ogg")
        self.mySound2 = base.loader.loadSfx("shot2.ogg")
        self.mySound3 = base.loader.loadSfx("shot3.ogg")
        self.mySound4 = base.loader.loadSfx("shot4.ogg")
        self.mySound5 = base.loader.loadSfx("shot5.ogg")
        self.mySound6 = base.loader.loadSfx("shot6.ogg")

        
        # Solution, imitation of polyphon.
        a = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (-0.2, 0, 0),scale=.05, command=None)
        s = DirectButton(text = ("OK"),rolloverSound = self.mySound1, pos = (-0.2, 0, -0.05), scale=.05, command=None)
        d = DirectButton(text = ("OK"),rolloverSound = self.mySound2, pos = (-0.2, 0, -0.1), scale=.05, command=None)
        f = DirectButton(text = ("OK"),rolloverSound = self.mySound3, pos = (-0.2, 0, -0.15), scale=.05, command=None)
        g = DirectButton(text = ("OK"),rolloverSound = self.mySound4, pos = (-0.2, 0, -0.2), scale=.05, command=None)
        h = DirectButton(text = ("OK"),rolloverSound = self.mySound5, pos = (-0.2, 0, -0.25), scale=.05, command=None)
        j = DirectButton(text = ("OK"),rolloverSound = self.mySound6, pos = (-0.2, 0, -0.3), scale=.05, command=None)
        
        
        # Your way, this is monophony. 
        a1 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, 0),scale=.05, command=None)
        s2 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, -0.05), scale=.05, command=None)
        d3 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, -0.1), scale=.05, command=None)
        f4 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, -0.15), scale=.05, command=None)
        g5 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, -0.2), scale=.05, command=None)
        h6 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, -0.25), scale=.05, command=None)
        j7 = DirectButton(text = ("OK"),rolloverSound = self.mySound, pos = (0.2, 0, -0.3), scale=.05, command=None)
        
app = MyApp()
app.run()

Answered in the comments. If one copy of the sound is played and you need to play it again. Then she stop and starts to play again. “Burr” comes out like that.

Ah, I see. Thank you for clarifying! :slight_smile:

However, that’s not how I’m doing it at all. I’m not assigning my sounds to separate variables, but I am loading multiple times. In code, this is more or less what I’m doing:

cat = DirectButton(text = "Meow",
                   rolloverSound = loader.loadSfx("meow.ogg"))
kitty = DirectButton(text = "Meow",
                     rolloverSound = loader.loadSfx("meow.ogg"))
kitten = DirectButton(text = "Meow",
                      rolloverSound = loader.loadSfx("meow.ogg"))
# And so on...

Note too that not all overlapping of the sounds seems to produce a “burr”. I’m not yet sure of whether this is due to the degree of overlap, or the number of overlapping sounds, or something to do with the UI-controls, or something else entirely. By guess at the moment is that it’s to do with the number of overlapping sounds–but that is very much a guess.

Most likely the panda does not distinguish between files with the same name and marks it as one. Just create multiple files physically on disk for verification. A burr is an interrupted sound at the beginning of an attack (sound term)

Hmm… On the other hand, I do think that I’ve heard sounds overlap in some cases, and a look at the waveform from a recording seems to support that idea. However, I may well be mistaken in that!

All that said, I may try your suggestion in the new day.

Until then, I remain open to further discussion!

I mean, I get what you’re saying. As I said, I may well try your suggestion in the new day–it’s late here.

I do agree that having a single audio-object could produce this effect. I’m just not convinced that it’s necessarily that. In particular, it seems odd that Panda would have an issue like that in its rollover-sound code.

Well, I tried your suggestion–and found that there seemed to be no difference between rollover sounds applied as I have generally been doing and applied using a separate file for each UI-control.

However! You were nevertheless more or less correct. Let me explain:

You see, as I said, when I tried your suggestion I found no difference between using a single sound-file and multiple sound-files. Specifically, neither case had that burr!

This seemed very odd. That, I think, was what prompted me to realise what was likely happening.

Look again at the video that I posted above: the UI controls that produce the offending sound are the items in a DirectOptionMenu. And how do we assign a rollover-sound to these? With a single keyword-parameter–and thus a single sound-object–passed into the menu’s constructor!

That, I think, is where my problem lies: due to the construction of the items, I have only a single sound-object for all of them.

So, the next problem, then, is that of how to give the items in a DirectOptionMenu separate rollover sound-objects, or to have them share from a pool of such objects…

(I could just omit rollover sounds for menus, but that would introduce an inconsistency in my UI, I feel.)

Sometimes you can not hear the difference due to the fact that the sound had time to play as short. Conclusion: that this problem is invisible on short sounds. However, there is a nuance, if there is silence at the beginning of the sound, then this exacerbates the effect.

I have already said that creating copies of audio files for each button will solve this problem, but if you use DirectOptionMenu, I cannot imagine how to do this.

ADD:

I have not used DirectGUI for a long time, but I vaguely remember that you can create a button and configure it and then add it to DirectOptionMenu.

I tried the experiment with the sound-file that was producing the “burr” in the video above, I believe, and the difference between having the “burr” present and not having it is quite audible, I feel.

As I said, this doesn’t seem to be the case. What does seem to help is having multiple sound-objects (that is, multiple "AudioSound"s).

But as you say, doing either with DirectOptionMenu might be somewhat tricky.

Hmm… What you say might work, and thinking about it, there’s also the option of iterating through the buttons in the menu and manually updating their “rolloverSound” keyword-property. The latter is probably more convenient for me right now, so I think that I’ll try that!

Thank you for your help. :slight_smile:

Thanks for the clarification, I thought it was a problem with identical file names.

Ah, right, and fair enough! :slight_smile:

In fact, it looks like having separate sound-objects for the menu-items might be easier than I’d thought: I’d forgotten that I’m using a custom sub-class of DirectOptionMenu that overrides the “setItems” method, and that already has code for iterating over the item-buttons. I haven’t finished implementing just yet, but it looks like it should be fairly straightforward. :slight_smile:

[edit] Done, and indeed, much better now I think! :slight_smile: