Sampling rate.

Started by zahar,

zahar

There was a problem with the sampling rate. When I set the sampling rate to 48000, and, for example, the sampling rate of the microphone in the Windows system itself, for example, to 44100, then I have sound distortion, a clip appears, and so on. I understand that this shouldn't be the case, so the question is, how do I fix this moment?

Code:
bool speaker::Initialize(int rate)
{
    BASS_SetConfig(BASS_CONFIG_UPDATETHREADS, 4);
    BASS_SetConfig(BASS_CONFIG_BUFFER, 150);
    BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 5);
    BASS_SetConfig(BASS_CONFIG_DEV_BUFFER, 100);

    sampleRate = rate;

    mixerStream = BASS_Mixer_StreamCreate(
        sampleRate,
        1,
        BASS_SAMPLE_FLOAT | BASS_MIXER_NONSTOP
    );

    if (!mixerStream) {
        printf("[Speaker] Mixer stream create failed: %d\n", BASS_ErrorGetCode());
        return false;
    }

    outputStream = BASS_StreamCreate(
        sampleRate,
        1,
        BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE,
        STREAMPROC_PUSH,
        this
    );

    if (!BASS_Mixer_StreamAddChannel(
        mixerStream,
        outputStream,
        0
    )) {
        printf("[Speaker] Mixer add channel failed: %d\n", BASS_ErrorGetCode());
        BASS_StreamFree(outputStream);
        BASS_StreamFree(mixerStream);
        return false;
    }

    BASS_ChannelSetAttribute(mixerStream, BASS_ATTRIB_VOL, 1.0f);
    BASS_ChannelSetAttribute(outputStream, BASS_ATTRIB_VOL, 1.0f);

    ApplyVoiceFilters(mixerStream);
    //ApplyVoiceFilters(outputStream);
    //ApplyVoiceMegaphone(outputStream);

    BASS_ChannelPlay(mixerStream, FALSE);
    Sleep(20);

    printf("[Speaker] Initialized: mic monitor ready\n");
    return true;
}

The question is, is there any resampling in the BASS library out of the box?
I thought about it a bit and realized that the opus library (the codec I use) does not support sampling rate 44100, so I have to use 48000 and so far I have to set a different frequency to the microphone in the system, the same with the speakers.. The question is, maybe the BASS library has a billing option from 44100 to 48000? (if suddenly the user's frequency at the microphone and the speaker is 44100)

Ian @ un4seen

A mixer will resample its sources to its rate (set in the BASS_Mixer_StreamCreate call) if needed. And BASS will resample the mixer to the output device's rate if needed. So to avoid unnecessary resampling, it's usually best to create a mixer with the same rate as the output device. You can get the device's rate from BASS_GetInfo.

In the case of recording, you can get the device's native rate from BASS_RecordGetInfo. BASS will resample if you record at a different rate.

Resampling shouldn't generally cause clipping. Perhaps the clipping you're seeing is caused by something else, like the recording input level being too high?

zahar

The problem is that my codec (opus) does not support a sampling rate of 44100, but only supports a frequency of 48000, which is why the codec cannot adequately convert audio chunks to adequately output sound. I must say right away, there is no problem on the part of the BASS library. Then what about this sampling rate? Maybe there are some options to change the sampling rate from the C++ code? It is the system input (microphone), not the sampling rate of the channels, or the input/output. Namely, the system sampling rate

Ian @ un4seen

As far as I know, there are no public APIs for changing a device's sample rate on Windows - it can only be changed by the user in the "Sound" control panel. If the output is 44100Hz and the source is 48000Hz then resampling will be required. The important thing is to avoid resampling twice. If the mixer will only be playing 48000Hz sources then it'll be fine for the mixer to be 48000Hz too, otherwise it should have the same rate as the output device.

zahar

Can I clarify exactly what I need to do in the code? And due to the fact that the mixer does not allow using the decoding stream along with the BAS_SAMPLE_3D flag, I had to abandon the mixer and use just the usual playback streams for each player. Current code:

bool speaker::CreatePlayerStream(uint16_t playerId)
{
    HSTREAM stream = BASS_StreamCreate(sampleRate,
        1,
        BASS_SAMPLE_FLOAT | BASS_SAMPLE_3D,
        STREAMPROC_PUSH,
        this
    );

    if (!stream) {
        printf("[Speaker] ERROR: Failed to create stream for player %d (code %d)\n",
            playerId, BASS_ErrorGetCode());
        return false;
    }

    if (!BASS_ChannelPlay(stream, 0)) {
        printf("[Speaker] ERROR: Failed play stream!\n");
        return false;
    }

    PlayerStream playerStream;
    playerStream.stream = stream;
    playerStream.lastSequence = 0;

    //if (!BASS_Mixer_StreamAddChannel(
    //    mixerStream,
    //    stream,
    //    0))
    //{
    //    printf("[Speaker] ERROR: Failed to add player %d to mixer (code %d)\n",
    //        playerId, BASS_ErrorGetCode());
    //    BASS_StreamFree(stream);
    //    return false;
    //}

    if (!BASS_ChannelSetDSP(
        stream,                    // 0 = master device
        MasterLimiterDSP,
        limiter_,
        0
    )) {
        printf("Error BASS_ChannelSetDSP. Code: %i\n", BASS_ErrorGetCode());
    }

    ApplyVoiceFilters(stream);
    //ApplyVoiceMegaphone(stream);

    BASS_ChannelSetAttribute(stream, BASS_ATTRIB_VOL, 2.0f);
    playerStreams[playerId] = playerStream;
   
    printf("[Speaker] Created stream for player %d\n", playerId);
return true;
}