How do I cap / clip audio volume via code?

Viewed 104

I am dealing with an audio file that shows sudden spikes:

enter image description here

When I try to normalize the audio file, the audio program sees this spike, notices that it is at 0 dB and won't normalize the audio any more.

To solve this issue, I have applied a Limiter that limits to -3 dB. I have used both Steinberg Wavelab and Audacity Hard Limiter. Instead, they both diminish the entire audio volume.

Both do not eliminate this spike.

Edit: I have found out that "Hard Clip" in Audacity does what I need, but now I still want to finish my own approach.

So I was thinking that they perhaps do not work correctly.

Then I tried to write my own limiter in VB6 in order to have full control over what's happening.

To do that, I'm loading the audio data of a wav file like this:

(I have stripped the process down very much)

Dim nSamples() As Integer
ReDim nSamples(0 To (lCountSamples - 1))

Get #iFile, , nSamples

I have the audio data in "nSamples" now.

    Dim i&
    For i = 1 To UBound(nSamples)
    
        Dim dblAmplitude As Double
        dblAmplitude = nSamples(i) / 32767

        Dim db As Double
        db = 20 * Log10(dblAmplitude)

        If db > -0.3 Then
            nSamples(i)=0 'how would I lower the volume here instead of just setting it to 0???
        End If

    Next

I'm not sure how I could calculate the dB from the sample data in order to clip it and how to clip it to -3dB.

I have now simply tried it with settings the clipping value to "0".

However, something strange happens here: The lower part of the audio is gone:

enter image description here

I expected that setting a value to 0 would mute the audio, but in my case, the lower wav form is gone.

What is wrong about my approach?

Thank you!

1 Answers

Calculating dB from audio samples isn't that simple. It sounds like what you want to do is find an appropriate threshold and then clip the audio with something like:

If Abs(nSamples(i)) > threshold Then
  nSamples(i) = threshold * Sgn(nSamples(i))

You could set the threshold to some fixed value if it's the same for all of your audio clips. Otherwise, it might be more accurate to sort the samples and search for a large gap between points near the top and bottom to find your threshold.

Related