Any ideas to achieve surround sound on the client *without* hidden parts?

Does anybody have any ideas how best to achieve surround sound (just left and right pan) audio local to the client and not necessarily parented to actual world objects.

One way is that for each sound with a different pan position, you could create an invisible part on the client and constantly CFrame it at the right distance and direction from the camera. I’d prefer not to do this if anyone has a neater way to pan sound without using physical parts, as it becomes a bit messy with lots of sounds.

Problem Definition

Background info and context:

I am working on a sound system for a city-building game where different buildings provide different sounds, e.g. carnival music for the carnival, coffee shop sounds for the cafe, etc.

The game is miniature, such that the immediate space around your character could contain many buildings, so to prevent noise and prevent having thousands of sounds across the city, I’ve devised a channel system where for N channels, the closest sounds are chosen to be played at a volume determined by the number of sources emitting the same sound and their distance from you. For example, two coffee shops next to each other will produce a higher volume of the same sound, rather than playing 2 copies of the sound emitting from each shop.

The max number of buildings is in excess of 1000 so it’s important to do it this way with the limited channels, and to save me moving invisible blocks around the map to play the sounds, I’m currently playing them on the client by having them parented to a folder instead of a 3D object. However, this creates a very flat sound and loses all directionality to where the sound is coming from.

Existing Feature Requests

The above requests already imply it’s not possible without being quite hacky. I’m hoping somebody has created a neater workaround than the one I mentioned using parts CFramed relative to the camera.

If nobody has any ideas I’ll probably add support to the existing threads for the ability to pan sound via a SoundEffect object, similar to the reverb, equalizer, compression and other effects Roblox already has.

2 Likes

So your channel system code, which I imagine runs only client-side/LocalScript in an update-/heartbeat-loop, already “knows” (by its calculations) which ‘buildings / shops / sources-of-particular-sound’ that is closest to the player… i.e. each sound/channel’s “closest position” is known, and these positions are static / anchored, as buildings/shops usually don’t move around.

Suggestion / Idea - (even though you explicitly stated otherwise):
Couldn’t you just “update/set the 3D-world position” of a transparent-part-that-emits-only-this-particular-sound (in mono) to that “closest position” of building/shop, and keep it positioned there in the 3D-world, until your channel system code determines that it either;

  • need to change/update its position to a newer “closest position” because the player moved, or
  • should be faded-out / muted, because some other “source(s)-of-particular-sound(s)” is closer / has higher priority.

And then let the Roblox sound-system do what it is build and optimized to do; make audio-sources in the 3D-world, give/play sound from “that static position & distance” relative to the player’s character position and orientation in the 3D-world.

I suspect that you already have a ‘identification / marking’-system for which type of building/shop that is placed in your 3D-world. And your code would also be made to recognize the exact count of individual “particular-sound” objects, and how many of these are allowed to be playing (e.g. the ‘N channels’). So perhaps the “moving transparent-non-colliding-blocks-with-sound-emitter to predetermined / static positions” and “fading-in / -out these sounds according to priority” (doing all this only client-side), might be “easier” to control & code, than trying to make “some hidden floating loudspeakers in a halo around the player character’s head, playing ambient sounds”?

Potentially. I’m willing to settle for this if it’s the best we’ve got. I’ll probably put the parts somewhere outside of Workspace as the dev hub only states the requirement for 3D sound to be the child of a basepart, not that the basepart needs to be in Workspace. That should eliminate any side effects of constantly moving them and will prevent the need to blacklist them from certain raycasts etc.

I’m still curious if anyone has any additional solutions to panning audio, though I suspect using the built-in 3D sound as intended will be the best currently available.