Author Topic: cracking sound when playing multiple channels  (Read 528 times)

daniel_mor

  • Posts: 16
I am developing a voice chat for my game. I use bass, opus and raknet. In my program there are 2 types of streams: global (heard as 2D sound) and local (3D sound with a position in the space of the game world). In each such stream I create 5 channels, for simultaneous playback of several players. Because, as I understand it, if you send packages of all players to one channel, you will get confusion. So, when I create two such streams, and send packets of players to the first channel of each stream, the crackling begins. Moreover, when the sound goes to one channel, the crackle disappears. But when two and more, reappears. I can hear what the players are saying, but this crack is unpleasant. I would be very grateful if someone tells you the reason. Sorry for my English.

Global stream constructor:
Code: [Select]
gstream() {
this->channel = BASS_StreamCreate(48000, 1, 0, STREAMPROC_PUSH, nullptr);
for (int i = 0; i < 5; i++) {
this->c_id[i] = 0xffff;
this->c_handle[i] = BASS_StreamCreate(48000, 1, 0, STREAMPROC_PUSH, nullptr);
this->c_ltime[i] = 0;
}
}

Local stream constructor:
Code: [Select]
lstream() {
if (this->channel = BASS_StreamCreate(48000, 1, BASS_SAMPLE_3D | BASS_SAMPLE_MUTEMAX, STREAMPROC_PUSH, nullptr)) {
BASS_ChannelSet3DAttributes(this->channel, BASS_3DMODE_NORMAL, distance * 0.1f, distance, -1, -1, -1);
BASS_ChannelSet3DPosition(
this->channel,
(BASS_3DVECTOR*)(vec_position),
(BASS_3DVECTOR*)(vec_orientation),
(BASS_3DVECTOR*)(vec_velocity)
);
}
for (int i = 0; i < 5; i++) {
this->c_id[i] = 0xffff;
if (this->c_handle[i] = BASS_StreamCreate(48000, 1, BASS_SAMPLE_3D | BASS_SAMPLE_MUTEMAX, STREAMPROC_PUSH, nullptr)) {
BASS_ChannelSet3DAttributes(this->c_handle[i], BASS_3DMODE_NORMAL, distance * 0.1f, distance, -1, -1, -1);
BASS_ChannelSet3DPosition(
this->c_handle[i],
(BASS_3DVECTOR*)(vec_position),
(BASS_3DVECTOR*)(vec_orientation),
(BASS_3DVECTOR*)(vec_velocity)
);
} this->c_ltime[i] = 0;
}
}

This thread update function is called in a loop. It changes the coordinates of the channels to the coordinates of the player:
Code: [Select]
void update(int64_t current_time) {
BASS_ChannelSet3DPosition(
this->channel,
(BASS_3DVECTOR*)(&vec_position),
(BASS_3DVECTOR*)(&vec_orientation),
(BASS_3DVECTOR*)(&vec_velocity)
);
for (int i = 0; i < 5; i++)
if (this->c_id[i] != 0xffff)
BASS_ChannelSet3DPosition(
this->c_handle[i],
(BASS_3DVECTOR*)(&vec_position),
(BASS_3DVECTOR*)(&vec_orientation),
(BASS_3DVECTOR*)(&vec_velocity)
);
}

This section of code is executed in a loop for each stream and determines whether the player speaks or stops. If you stop talking, then it stops the channel and clears the playback buffer:
Code: [Select]
for (int i = 0; i < 5; i++)
// interval 500 milliseconds
if ((this->c_id[i] != 0xffff) && (curtime - this->c_ltime[i] > 500)) {
logger::logdebug(SV_COLOR_DEBUG, "[debug:stream_%p:tick] : channel %d is released from player %hu", this, i, this->c_id[i]);
BASS_ChannelStop(this->c_handle[i]);
this->senders[this->c_id[i]].curseqid = 0;
this->senders[this->c_id[i]].curpackid = 0;
this->c_id[i] = 0xffff;
}

this->c_id is the id of the player who owns the channel this->c_handle (0xffff - player missing).

If necessary, I can attach more code.
« Last Edit: 31 Jul '19 - 09:08 by daniel_mor »

Ian @ un4seen

  • Administrator
  • Posts: 22829
Re: cracking sound when playing multiple channels
« Reply #1 on: 31 Jul '19 - 15:19 »
"cracking sound" could be caused by the stream running out of buffered sample data to play and briefly stalling. To check that, please try setting a BASS_SYNC_STALL sync on the streams (via BASS_ChannelSetSync) and see if that gets triggered.

Another possibility is that the combined level of the streams is too high, causing distortion. To test that, you could trying lowering the streams' BASS_ATTRIB_VOL settings via BASS_ChannelSetAttribute (or use BASS_CONFIG_GVOL_STREAM).

daniel_mor

  • Posts: 16
Re: cracking sound when playing multiple channels
« Reply #2 on: 31 Jul '19 - 16:07 »
"cracking sound" could be caused by the stream running out of buffered sample data to play and briefly stalling. To check that, please try setting a BASS_SYNC_STALL sync on the streams (via BASS_ChannelSetSync) and see if that gets triggered.

Another possibility is that the combined level of the streams is too high, causing distortion. To test that, you could trying lowering the streams' BASS_ATTRIB_VOL settings via BASS_ChannelSetAttribute (or use BASS_CONFIG_GVOL_STREAM).

Thanks for the reply, Ian. The installation of the sync showed that the channel has enough data to play and in the process it does not stop. I tried to reduce the volume of the channels, but it did not help. The volume of the crackle decreased, but it did not disappear. I also noticed that the instant sound of crackling occurs in the intervals between frames. I have frames that are between 40 and 120 milliseconds long. And when I change this interval in my program, the crackle interval also changes. I recorded a soundtrack(https://dropmefiles.com/QSoq0) for you. The first half is the reproduction of one stream, and the second is the reproduction of two streams. Do not pay attention to the split voice, I send the same package in two channels.

Ian @ un4seen

  • Administrator
  • Posts: 22829
Re: cracking sound when playing multiple channels
« Reply #3 on: 31 Jul '19 - 17:10 »
Just to be sure, did you set a BASS_SYNC_STALL sync on both streams? It might be that only one of them is stalling.

If there's no stalling then perhaps there's a discontinuity in the provided sample data, eg. some data is being skipped or extra data is being introduced. To check that, please try writing each stream to a WAV file and then check them in a sample editor to see if they're OK. You can use the BASSenc add-on to do that. For example:

Code: [Select]
BASS_Encode_Start(stream, outfilename, BASS_ENCODE_PCM | BASS_ENCODE_AUTOFREE, NULL, NULL);

I would suggest playing a sine wave (instead of your voice) for testing, as that should make it easier to see what's going on in the waveforms.

daniel_mor

  • Posts: 16
Re: cracking sound when playing multiple channels
« Reply #4 on: 31 Jul '19 - 19:05 »
Just to be sure, did you set a BASS_SYNC_STALL sync on both streams? It might be that only one of them is stalling.

If there's no stalling then perhaps there's a discontinuity in the provided sample data, eg. some data is being skipped or extra data is being introduced. To check that, please try writing each stream to a WAV file and then check them in a sample editor to see if they're OK. You can use the BASSenc add-on to do that. For example:

Code: [Select]
BASS_Encode_Start(stream, outfilename, BASS_ENCODE_PCM | BASS_ENCODE_AUTOFREE, NULL, NULL);

I would suggest playing a sine wave (instead of your voice) for testing, as that should make it easier to see what's going on in the waveforms.

I'm sorry, Ian. I did as you said. Recorded sound files were different. The first file is clear sound, and the second with cracking. After that, I analyzed the contents of the packages. It turns out the decoder OPUS differently decodes the same packet. As a result, your library is not to blame for the distorted sound. Now I will think why the decoder has this behavior.