3D Audio: Moving Creates Little Bursts

I’ve encountered a bit of an odd audio issue: It seems that, if I have a looping sound attached to the listener of that sound, or updated to have the same position as that listener, rapid changes in position can produce little “bursts” of sound on one side or the other.

Here below is a short program that demonstrates the issue (at least on my machine). Simply run the program, and then press the left- and right- arrow-keys to move the smiley. Quick changes produce more “bursts”, making them easier to detect, but it seems to happen intermittently with any change in direction.

from direct.showbase.ShowBase import ShowBase

from panda3d.core import PandaNode, NodePath
from direct.showbase import Audio3DManager


class Game(ShowBase):
	def __init__(self):
		ShowBase.__init__(self)
		
		self.disableMouse()
		
		# The 3D Audio Manager
		self.audio3D = Audio3DManager.Audio3DManager(self.sfxManagerList[0], render)
		
		# The sound to be played
		self.sound = self.audio3D.loadSfx("noise.ogg")
		self.sound.setLoop(True)
		self.sound.set3dAttributes(0, 0, 0, 0, 0, 0)
		self.sound.setVolume(2)
		self.sound.play()
		
		# The player-object
		self.player = loader.loadModel("smiley")
		self.player.reparentTo(render)
		self.player.setPos(0, 0, 0)
		
		# Setting up the listener
		self.audio3D.attachListener(self.player)
		
		# Attaching the sound
		self.audio3D.attachSoundToObject(self.sound, self.player)
		
		# Final setup
		self.camera.setY(-40)
		
		self.setupKeys()
		
		self.taskMgr.add(self.update, "update")
			
	def setupKeys(self):
		self.keys = {
			"up" : False,
			"down" : False,
			"left" : False,
			"right" : False,
		}
		self.accept("w", self.setKey, extraArgs = ["up", True])
		self.accept("w-up", self.setKey, extraArgs = ["up", False])
		self.accept("s", self.setKey, extraArgs = ["down", True])
		self.accept("s-up", self.setKey, extraArgs = ["down", False])
		self.accept("a", self.setKey, extraArgs = ["left", True])
		self.accept("a-up", self.setKey, extraArgs = ["left", False])
		self.accept("d", self.setKey, extraArgs = ["right", True])
		self.accept("d-up", self.setKey, extraArgs = ["right", False])
		
	def setKey(self, key, state):
		self.keys[key] = state
		
	def update(self, task):
		dt = self.clock.getDt()
		
		# Move the player according to the keys
		if self.keys["left"]:
			self.player.setX(self.player, -10 * dt)
		if self.keys["right"]:
			self.player.setX(self.player, 10 * dt)
		
		return task.cont

app = Game()
app.run()

And here is the sound-file used by the above:
noise.zip (16.6 KB)
(The effect isn’t all that prominent with this sound, so you may have to listen closely.)

[edit] Note that this effect seems to also happen if one uses “set3dAttributes” in an update-task instead of “attachSoundToObject”.

I was able to reproduce the issue using your code as-is, however, it is a bit odd to attach the listener to self.player, which is the same object “emitting” the sound, I believe.

The following change implements what you’d presumably want in this kind of situation, which is the audio to pan left or right depending on where the moving object is relative to the perspective view:

# Setting up the listener
# self.audio3D.attachListener(self.player)
self.audio3D.attachListener(self.camera)

Perhaps you’re trying to demonstrate the self-emitting self-listening object error, but I haven’t heard the same glitching in the self.camera listening case.

Hmm, that’s interesting–perhaps it’s a matter of order of positional updates?

Perhaps the player–and in my original code, the listener–is being updated just before the sound’s position is updated, resulting in the sound being “left behind”?

As to attaching the listener to the camera (and then the camera to the player, so that the sound and listener remain in the same place relative to each other), that does incur the issue of the sound being much softer, due to the camera being further away…

It’s not exactly a case of the listener “emitting” the sound, but rather of the sound “following” the listener (as a result of the listener’s actions).

Specifically, my actual in-game use for this is in the sounds of the player pushing through foliage (seen from a third-person “isometric” view). Since the player’s actions ostensibly produce the sounds, the sounds “follow” the player.

(And I think that I’m specifically using “set3dAttributes” rather than directly attaching the sound to the object, but the results seem to be the same.)