Issue with FMOD_ChannelGroup_Set3DAttributes

Hi,

We have a 2D engine, using FMOD 5 Low Level Api. We have issues when calling FMOD_ChannelGroup_Set3DAttributes.

We create a channelgroup (children of the master channelgroup) for each char, and attach the playing sounds on the char. To avoid looping over all the current playing channels, we call FMOD_ChannelGroup_Set3DAttributes to set the new char’s coordinate to let FMOD update all the playing channels. But we are having trouble, everytime we call FMOD_ChannelGroup_Set3DAttributes we get this error:

FMOD_ERR_NEEDS3D

Btw, all the sounds in the channels playing on the channelgroup are 3D and created with 3D flags.

Thanks in advance.

By default ChannelGroups are created as 2D, to change them to 3D you will need to use ChannelGroup::setMode with the flag FMOD_3D.

https://fmod.com/resources/documentation-api?page=content/generated/FMOD_ChannelGroup_SetMode.html#/

Reply added with more info. Code snippet is not working correctly, sorry! Thank you Cameron.

Hi,

We resolved this now, can properly set 3D Channel Groups using FMOD_ChannelGroup_Set3DAttributes.

Now we have another issue. The panning works correctly, it calculates properly the position of the source against the listener. The issue is that attenuation is not being made, the sound always returns 1 on FMOD_Channel_GetAudibility even at high distances from the listener.

We tested this using FMOD_Channel_Set3DAttributes on the playing channel and the attenuation works correctly. But our desired functionality is to control each “source” (moving source) with a channelgroup for recursive sound update.

Thanks.

The audibility value should change each time you call it, I have got it working testing it here. Can you share some of the code you are using for this?

Issue #1: Set3DAttributes not applying the attenuation

This is the code that plays a sound under a character’s channel group:

'Plays a sound on the master channel group (game events for characters)
Public Function PlayOnChar(ByVal intSoundIndex As Integer, ByVal intCharIndex As Integer) As Long

On Error GoTo ErrorHandler

If (intSoundIndex <= 0) Or (intSoundIndex > mNumSounds) Then Exit Function
If Not SoundData(intSoundIndex).Buffer.Loaded Then Exit Function

Dim lngResult As Long
Dim lngFMODChannel As Long
Dim lngChannelGroup As Long

If SoundData(intSoundIndex).Buffer.Is3D Then

Dim Pos As FMOD_VECTOR

If Not frmMain.Engine.Char_Coord_Get(intCharIndex, Pos.X, Pos.Y) Then Exit Function
Pos.Z = 0

lngChannelGroup = frmMain.Engine.Char_Sound_ChannelGroup_Get(intCharIndex)

If lngChannelGroup = 0 Then
    lngResult = FMOD_System_CreateChannelGroup(mFMODSystem, vbNullString, lngChannelGroup)
    If lngResult <> FMOD_OK Then Call Err.Raise(lngResult, , "FMOD_System_CreateChannelGroup (Char) Failed")

    lngResult = FMOD_ChannelGroup_SetMode(lngChannelGroup, FMOD_3D)
    If lngResult <> FMOD_OK Then Call Err.Raise(lngResult, , "FMOD_ChannelGroup_SetMode (Char) Failed")

    lngResult = FMOD_ChannelGroup_Set3DAttributes(lngChannelGroup, VarPtr(Pos), 0, 0)
    If lngResult <> FMOD_OK Then Call Err.Raise(lngResult, , "FMOD_ChannelGroup_Set3DAttributes (Char) Failed")

    lngResult = FMOD_ChannelGroup_AddGroup(mFMODSoundChannelGroup, lngChannelGroup, 0, 0)
    If lngResult <> FMOD_OK Then Call Err.Raise(lngResult, , "FMOD_ChannelGroup_AddGroup (Char) Failed")
    
    Call frmMain.Engine.Char_Sound_ChannelGroup_Set(intCharIndex, lngChannelGroup)
End If

lngResult = FMOD_System_PlaySound(mFMODSystem, SoundData(intSoundIndex).Buffer.handle, lngChannelGroup, 0, lngFMODChannel)
If lngResult <> FMOD_OK Then Call Err.Raise(lngResult, , "Error while playing sound #" & intSoundIndex)

'Always returns 1
Dim sngAudibility As Single
FMOD_Channel_GetAudibility lngFMODChannel, sngAudibility
Debug.Print sngAudibility

Else
lngResult = FMOD_System_PlaySound(mFMODSystem, SoundData(intSoundIndex).Buffer.handle, mFMODSoundChannelGroup, 0, lngFMODChannel)
If lngResult <> FMOD_OK Then Call Err.Raise(lngResult, , “Error while playing sound #” & intSoundIndex)
End If

PlayOnChar = lngFMODChannel

Exit Function

ErrorHandler:
Call Client_LogError(“clsSoundEngine->PlayOnChar”, Err.Description, Err.Number)

End Function

Issue N2: The documentation says that when a channelgroup is released it moves the channels to the master’s channelgroup. Is this behaviour still applied to channelgroups that have a “master” channelgroup added? (Like the example above)?

For now we are using this code to transfer the channelgroup’s channels to the desired channel group.

'Transfers a group to the local sound channel group (not the “master” channelgroup)
Public Function TransferGroup(ByVal lngFMODChannelGroup As Long) As Boolean

Dim lngResult As Long
Dim lngNumPlaying As Long

lngResult = FMOD_ChannelGroup_GetNumChannels(lngFMODChannelGroup, lngNumPlaying)
If lngResult <> FMOD_OK Then Call Err.Raise(lngResult, , “FMOD_ChannelGroup_GetNumPlaying Failed”)

If lngNumPlaying > 0 Then
Dim i As Long, lngFMODChannel As Long

For i = 0 To lngNumPlaying - 1
    lngResult = FMOD_ChannelGroup_GetChannel(lngFMODChannelGroup, i, lngFMODChannel)
    
    If lngResult = FMOD_OK Then
        'Transfer the channel to the local sound channelgroup
        lngResult = FMOD_Channel_SetChannelGroup(lngFMODChannel, mFMODSoundChannelGroup)
        If lngResult <> FMOD_OK Then Call Err.Raise(lngResult, , "FMOD_Channel_SetGroup Failed")
    End If
Next i

End If

'Release the old channelgroup
Call Audio_ReleaseChannelGroup(lngFMODChannelGroup)

End Function

After digging into this deeper, it does appear to be a bug with ChannelGroup audibility where the attenuation isn’t taken into account properly.

We have logged this as a task and will have a fix in a future release.

As for the second issue: if you release a channelGroup, anything that was attached to it will always be routed through the Master channel group. If you want it to be routed somewhere in particular other than the Master, you will have to do this manually.