Will there be an option to choose which AudioEmitters can be ignored by an AudioListener? It would be useful to avoid feedback loops (for in-game microphones that pick up everything), but not only.
Also, will there be a way to set more than 1 AudioInteractionGroup for the new Instances?
Will there be an option to choose which AudioEmitters can be ignored by an AudioListener?
Currently this can be controlled by the AudioInteractionGroup property – listeners will only hear emitters that are in the same group.
will there be a way to set more than 1 AudioInteractionGroup for the new Instances?
This is something we’ve discussed but don’t yet have any firm plans on – for now, in order to have audio emitted and heard by multiple listeners, you’d also need multiple emitters (each one in a different interaction group).
The good news is that those extra wires and emitters are pretty lightweight, but I understand it can contribute to an overall mess of disorganized, wire-spaghetti.
It would be more convenient if these behaved like CollisionGroups, where you can define cross-group interactions; but CollisionGroups had some limitations (e.x. maximum count) that dissuaded us from reusing them directly.
We actually just added two methods: AudioEmitter:GetInteractingListeners() and AudioListener:GetInteractingEmitters(). These can be used to list all the listeners that would hear a given emitter, or all the emitters that can be heard-by a given listener
Combining these and the helper method from above, you could
list all the emitters heard by a listener with listener:GetInteractingEmitters(),
for a particular emitter in the list of emitters, use getCFrameFrom(emitter) to get its position
Thank you for the follow up. I played with this a little and it seems very useful in altering listeners and emitters in groups.
I was wondering if you guys were planning on creating an event for when an AudioListener picks up any sound, it provides the AudioEmitter with it possibly, something like AudioListener.SoundDetected:Connect(someAudioEmitter: AudioEmitter)
Adding an event like that directly would come with a passive performance penalty, since the stream being produced by the AudioListener is already mixed; we’d have to comb back through the graph to unpack it/determine where it came from.
But, you can implement something similar with AudioAnalyzers if you don’t mind the overhead – a rough idea would be
wire up your AudioListener, as well as the inputs of each AudioEmitter to several AudioAnalyzers
periodically check the listener-analyzer’s PeakLevel property; whenever it crosses a threshold, get the listener’s interacting emitters
for each emitter, check whether its analyzer also has PeakLevel above a threshold
If both the Listener-analyzer and the Emitter-analyzer have crossed a volume threshold at about the same time, this indicates that the emitter is partially-responsible for whatever the listener heard
I’m encountering an issue where I hear a short pop or click when I create an AudioPlayer, set its AssetId, and immediately call :Play().
This is the code I’m using:
while true do
local audioPlayer = Instance.new("AudioPlayer", workspace)
audioPlayer.AssetId = "rbxassetid://7003103879"
audioPlayer:Play()
audioPlayer.Ended:Connect(function()
audioPlayer:Destroy()
end)
task.wait(0.1)
end
Observations
The issue occurs consistently when I use Bluetooth headphones.
When I use my laptop speakers, the issue does not seem to occur.
I haven’t tested it with wired headphones.
The problem is not limited to this specific AssetId; it also happens with other audio assets.
The issue persists regardless of whether the AudioPlayer is connected to an emitter or not.
Currently im having an issue and im not sure if its a client server authority issue or something else.
But for my needs under VoiceChatService I disable “EnableDefaultVoice”
On the server on player join im creating an AudioDeviceInput parented to the player instance… And on Character Added I am creating an audio emitter parented to the character.
From there on the client I create an Audio Output Device and put it in the client workspace camera. Depending on the state my game is in I either from the client will wire the server created AudioDeviceInput to the client created AudioOutputDevice (this works letting me hear every player).
But from the client when I try to wire the Server Created Audio Input Device to the server created AudioEmitter it will connect the wire, but no audio can be heard.
Any ideas why the client works with AudioInputDevice → AudioOutputDevice but not AudioInputDevice → AudioEmitter?
Ah so I saw in the example Place that is linked in the first post, that there is an:
AudioListner → AudioDeviceOutput in the client workspace camera.
So if im understanding correctly, by including that the audio listener in the camera would pick up the other player characters AudioEmitter and play the sound back to local player?
So when you create any AudioApi related instances using Instance.new() such as “AudioReverb” and then you :Destroy() it afterward. It doesn’t properly clear the memory usage despite using :Destroy() so it causes “Memory Leak.”
Reproducing this is easy
local CreatedInstances = {}
while task.wait() do
-- Create 5 new instances on every loop
for p=1,5 do
local NewInstance = Instance.new("AudioReverb") --> Any class related to AudioApi
NewInstance.Parent = script
table.insert(CreatedInstances,NewInstance)
end
-- Destroy them after
for i,v in CreatedInstances do
CreatedInstances[i] = nil
v:Destroy()
end
end
Run this in server script. It will create new AudioReverb instances then destroy it in a loop.
Then if you go to developer console (F9) > memory > server > PlaceMemory > Sound, you will see the graph skyrockets like crazy!
Hey @mastawba; I gave this script a try, and what I observed is that memory usage can climb for a while before garbage collection kicks in and knocks it back down – I was not able to reproduce a truly unbounded leak, though – what was the highest you saw memory usage go?
Using the code I provided in an new empty baseplate with UseAudioApi true and EnableDefaultVoice true. For 30 seconds the memory reached over 15,924 megabytes. That is way over than Roblox server’s maximum memory of estimated 6,300 megabytes.
Ah I had tested the code in a script with Client RunContext, and that does not leak; changing that to Server, I am seeing similar. Yikes – will look into what’s causing that.
Hey @JOSIMA33, a fix for these clicking noises should be going out in v638 – thanks for the report!
The problem occurs when creating an AudioPlayer and immediately playing it, so as a temporary workaround, creating AudioPlayers in advance, before playing them, avoids this. Even a single-frame wait is long enough:
while true do
local audioPlayer = Instance.new("AudioPlayer", workspace)
task.wait() -- waiting here avoids the click
audioPlayer.AssetId = "rbxassetid://7003103879"
audioPlayer:Play()
audioPlayer.Ended:Connect(function()
audioPlayer:Destroy()
end)
task.wait(0.1)
end
you could also pool & reuse AudioPlayers instead of calling Instance.new/Instance:Destroy,
local pool : {AudioPlayer} = {}
local function createAudioPlayer() : AudioPlayer
if #pool == 0 then
return Instance.new("AudioPlayer", workspace)
else
return table.remove(pool)
end
end
local function destroyAudioPlayer(audioPlayer : AudioPlayer)
audioPlayer.AssetId = ""
table.insert(pool, audioPlayer)
end
which only encounters the click the first few times, when the pool is empty.
@mastawba there’s a fix currently in-review for the server-side memory leak – hopefully should also be in v638 – thank you for reporting!
Do you plan to add an audio instance that could be used for vocoding?
You’d specify a frequency band or apply a parametric eq, and it’d use the resulting audio data to manipulate another input (that could also be mixed using eqs and ducked over the background to only modulate voice)