3

I'm started to implement Oboe c++ library for Android. (According to Build a Musical Game using Oboe I just scale the sample for increasing the volume and it works but with crackling popping. can I increase the amplitude without getting the crackling popping? I tried to save my sample sounds with a little bit gain but it sounds very bad. Thanks.

Btw without increasing the volume, it sounds clear but very low volume compared to other music apps.

for (int i = 0; i < mNextFreeTrackIndex; ++i) {

    mTracks[i]->renderAudio(mixingBuffer, numFrames);

    for (int j = 0; j < numFrames * kChannelCount; ++j) {
        audioData[j] += (mixingBuffer[j] * ((float)volume));
    }

Edited:

int16_t Mixer::hardLimiter(int16_t sample) {
    int16_t audioData = sample * volume;
    if(audioData >= INT16_MAX){
        return INT16_MAX;
    }else if(audioData <= INT16_MIN){
        return  INT16_MIN;
    }
    return audioData;
};
Matan
  • 296
  • 5
  • 24
  • Sounds like turning up the volume is causing clipping. The remedy for that is don't turn up the volume, or turn it up less. – Robert Harvey Dec 07 '18 at 17:13
  • The remedy for that is don't turn up the volume? so? – Matan Dec 07 '18 at 17:19
  • Clipping is what you're describing. It occurs when the volume is turned up too high on any digital system. It's happening because you're running out of bits to represent the waveform. – Robert Harvey Dec 07 '18 at 17:21
  • I understand, but how can i "Protect" and avoid that noises? In my app, the volume must be set by the user and sometimes the audio file I played is low volume as well. – Matan Dec 07 '18 at 17:24
  • By not turning the volume up so high. – Robert Harvey Dec 07 '18 at 17:24
  • Can I create Limiter or something? – Matan Dec 07 '18 at 17:41
  • the buffer might be too small and therefore be exceeded. a limiter could only prevent peaks, but not prevent crackles due to buffer overflow. `PerformanceMode::LowLatency` sounds good... while the buffer might still need to be adjusted, depending on the hardware. – Martin Zeitler Dec 07 '18 at 17:55
  • @MartinZeitler It sounds like I meant "peaks" when the level is too high. Basically, my question is how can I know if after manipulating the mixingBuffer[j] with volume it will make peak noises or any unnecessary noises? and how in my code I can avoid it? – Matan Dec 08 '18 at 23:07
  • @Matt anything above 0db is peaking (rather sounds distorted)... crackles are buffer related. https://github.com/google/oboe/blob/master/docs/FullGuide.md – Martin Zeitler Dec 09 '18 at 05:28
  • Are you sure your source audio format is 16-bit ints? If its floats, or if the audio stream itself is floats (you can check with `stream->getFormat()`) then you might run into this kind of issue. – donturner Dec 12 '18 at 17:33

1 Answers1

0

The code which you've posted is from Mixer::renderAudio(int16_t *audioData, int32_t numFrames). Its job is to mix the sample values from the individual tracks together into a single array of 16-bit samples.

If you're mixing 2 or more tracks together without reducing the values first then you may exceed the maximum sample value of 32,767 (aka INT16_MAX). Doing so would cause wraparound (i.e. writing 32,768 to an int16_t will result in a value of -32,768 being stored) and therefore audible distortion/crackling.

With this in mind you could write a very basic (hard) limiter - do your volume scaling using an int32_t and only write it into the int16_t array if the value doesn't exceed the maximum, otherwise just write the maximum.

This isn't really a good approach though because you shouldn't be hitting the limits of 16-bit values. Better would be to scale down your input sample values first, then add a gain stage after the mixer (or on individual tracks inside the mixer) to bring the overall amplitude up to an acceptable level.

donturner
  • 17,867
  • 8
  • 59
  • 81