Question. 3D positioning.

Started by zahar,

zahar

The question arose: Is it possible to implement 3D sound positioning and mute depending on the position in the world using BASS? I studied BASS a bit, and saw functions such as BASS_Aply3D(), bas_set3dposition(), bas_set3dfactors(). If I understood correctly, the bas_set3dfactors() function is used to set the factors that affect the calculation of 3D sound.

zahar

If I'm not mistaken, the bas_set3dposition() function is used to set the position of the listener, and the BASS_ChannelSet3DPosition function is used to set the position of the sound source (where the sound is coming from)

Ian @ un4seen

Yes, that is correct: BASS_Set3DPosition sets the listener's 3D position and BASS_ChannelSet3DPosition sets the sound's 3D position. You can use the BASS_SAMPLE_MUTEMAX flag to mute a sound beyond its max distance (which you can set via BASS_ChannelSet3DAttributes).

zahar

Thank you, Jan. I have one more question: will my code be able to protect against peak clipping when players are talking at the same time? (5+, etc.) I understand that there may be very few situations where more than 2 players are talking, but nevertheless, we need protection from peak clipping. I have this compression code.:

void speaker::ApplyVoiceFilters(HSTREAM stream)
{
    if (!stream) return;

    HFX fxComp = BASS_ChannelSetFX(stream, BASS_FX_BFX_COMPRESSOR2, 0);
    if (fxComp)
    {
        BASS_BFX_COMPRESSOR2 compParams{};

        compParams.fThreshold = -12.0f;
        compParams.fRatio = 6.0f;
        compParams.fAttack = 3.0f;
        compParams.fRelease = 120.0f;
        compParams.fGain = 0.0f;

        BASS_FXSetParameters(fxComp, &compParams);
    }

    HFX fxLimit = BASS_ChannelSetFX(stream, BASS_FX_BFX_COMPRESSOR2, 1);
    if (fxLimit)
    {
        BASS_BFX_COMPRESSOR2 limitParams{};

        limitParams.fThreshold = -1.0f;
        limitParams.fRatio = 20.0f;
        limitParams.fAttack = 0.1f;
        limitParams.fRelease = 100.0f;
        limitParams.fGain = 0.0f;

        BASS_FXSetParameters(fxLimit, &limitParams);
    }
}

Ian @ un4seen

Perhaps you can lower the level of each voice stream (via their BASS_ATTRIB_VOL settings) when there are multiple playing? You can use BASS_ChannelSetAttribute to make the changes instantly, or BASS_ChannelSlideAttribute to make them more gradually. If you would like to ignore quiet streams (below some threshold), you can check the data levels with BASS_ChannelGetLevel(Ex).

zahar

The question is, will the compressor help me?

Ian @ un4seen

Probably not if it's applied to individual streams. You would need to apply it to the mix instead. You could apply it to BASS's output mix (see the STREAMPROC_DEVICE option) but that'll affect all sound, not only the voice streams. To only apply it to the voice streams, you could plug them all into a mixer (see the BASSmix add-on) and set the compressor on the mixer. You would want to set BASS_ATTRIB_BUFFER=0 on the mixer then to avoid adding latency (disable playback buffering).

zahar

I have a compressor applied to the main stream (mixer) and to the streams for each player. Is it bad to apply a compressor also to the streams that are created for players when a packet with voice data arrives?

zahar

#8
I studied the stream creation documentation a bit, as I wrote above, I want to do 3D sound positioning. But, I came across this: BASS_STREAM_DECODE Decode the sample data, without playing it. Use BASS_ChannelGetData to retrieve decoded sample data. The BASS_SAMPLE_3D, BASS_STREAM_AUTOFREE and SPEAKER flags cannot be used together with this flag. What should I do?

P.S. But can I create a mixing stream with the BASS_SAMPLE_3D flag, and at the same time change the 3D parameters for a completely different stream, while this "other" stream will be added to the mixer. In my case, this "other" stream is a stream for an individual player.

Ian @ un4seen

You can enable 3D processing on the mixer, but not on the its sources - they will all have the mixer's 3D position. So if you need to able to set a separate 3D position for the "other" stream, then you mustn't play it through the mixer.

zahar

Thanks Jan. I have another question (well, let's say for general understanding). Does the BASS library calculate the volume itself? So, I won't need to constantly transfer the distance between the players to some function, for example? Am I right?

Ian @ un4seen

Yes, the level of 3D sounds is automatically adjusted based on their distance from the listener (and their BASS_ChannelSet3DAttributes settings).