Audio gain loudness analysis ReplayGain with complete C code example [transfer]

From: http://www.cnblogs.com/cpuimage/p/8846951.html

The well-known 3A algorithms for images are:

AF (Automatic Focus)
is the process of adjusting the focal length of the camera to automatically obtain a clear image

AE automatic exposure (Automatic Exposure)
automatic exposure is to make the photosensitive device obtain the appropriate exposure

AW Automatic White Balance (Automatic White Balance)
The essence of white balance is to make white objects appear white under any light source

 

The corresponding 3A algorithm for audio is:

AGC automatic gain control (Automatic Gain Control)
automatically adjusts the volume of the microphone, so that the participants receive a certain volume level.

ANS Background Noise Suppression (Automatic Noise Suppression)
detects background noise at a fixed frequency and eliminates background noise.

AEC is an echo canceller (Acoustic Echo Canceller)
. Based on the correlation between the speaker signal and the multipath echo generated by it, it establishes a speech model of the far-end signal, uses it to estimate the echo, and continuously modifies the coefficients of the filter. , so that the estimated value is closer to the real echo. The echo estimate is then subtracted from the microphone's input signal to eliminate echoes, and the AEC also compares the microphone's input to the speaker's past values ​​to eliminate delayed-delayed multiple reflections. Depending on how much of the past speaker output values ​​are stored in the memory, AEC can cancel various delayed echoes.

 

 I won't say much about the algorithm of the image, I have implemented the 3a algorithm of the image.

The main idea of ​​automatic white balance is how to judge whether the image has a color cast and how to fix it after the color cast.

Common are histogram equalization, automatic contrast, automatic levels and so on.

Auto exposure is also to do exposure evaluation, common are gama adjustment and so on.

When there is time in the future, I will post the corresponding code one after another.

Here, first sell a pass and occupy a pit.

 

In terms of audio algorithm, the algorithm of automatic gain compensation is somewhat similar to the automatic exposure algorithm of images.

The main thing to consider is how long the audio is and how to analyze the volume or intensity of the current audio.

Do a normalized stretch to the entire audio based on this intensity, and so on.

Image and audio go the same way.

And the algorithm with a long history is none other than ReplayGain

ReplayGain is a proposed standard published by David Robinson in 2001 to measure the loudness  of audio in computer audio formats .

Related wikis:

https://en.wikipedia.org/wiki/ReplayGain

Most audio players now support this feature.

According to the wiki, the open source implementation most used now is   MP3Gain

For information see:

http://wiki.hydrogenaud.io/index.php?title=Replaygain#Players_support

Open source project address:

http://mp3gain.sourceforge.net/

The project is C code, very clean.

See the main algorithm implementation files: gain_analysis.h and gain_analysis.c

The algorithm analyzes the decibel value that needs to be gained based on the incoming audio data.

If the gain is not required, it is 0, and if the gain is required, it is the corresponding floating-point positive or negative number.

Of course, too few audio samples can't be passed in, otherwise it can't be analyzed objectively.

The algorithm only needs to pass in the audio data and specify the sample length to be analyzed.

The final output is a decibel value of the recommended gain.

According to this decibel value, some specific audio processing can be performed on the target audio.

 

Paste the complete C code:

copy code
#ifdef __cplusplus
extern "C" {
#endif


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
//decode using https://github.com/mackron/dr_libs/blob/master/dr_wav.h
#define DR_WAV_IMPLEMENTATION

#include "dr_wav.h"
#include "gain_analysis.h"


#ifndef min
#define min(a, b)            (((a) < (b)) ? (a) : (b))
#endif

//read wav file
int16_t *wavRead_int16(char *filename, uint32_t *sampleRate, uint64_t *totalSampleCount) {
    unsigned int channels;
    int16_t *buffer = drwav_open_and_read_file_s16(filename, &channels, sampleRate, totalSampleCount);
    if (buffer == NULL) {
        printf("Failed to read wav file.");
    }
    // only handle single channel audio
    if (channels != 1) {
        drwav_free(buffer);
        buffer = NULL;
        *sampleRate = 0;
        *totalSampleCount = 0;
    }
    return buffer;
}


float getGaindB(int16_t *buffer, size_t totalSampleCount, int sampleRate, size_t analyzeSamples) {
    float ret = -0.00000000001f;
    if (totalSampleCount == 0) return ret;
    if (analyzeSamples == 0) return ret;
    const int maxSamples = 2400;
    analyzeSamples = min(maxSamples, analyzeSamples);
    ret = 1.0f;
    int num_channels = 1;
    Float_t inf_buffer[maxSamples];
    size_t totalCount = totalSampleCount / analyzeSamples;
    if (InitGainAnalysis(sampleRate) == INIT_GAIN_ANALYSIS_OK) {
        int16_t *input = buffer;
        for (int i = 0; i < totalCount; i++) {
            for (int n = 0; n < analyzeSamples; n++) {
                inf_buffer[n] = input[n];
            }
            if (AnalyzeSamples(inf_buffer, NULL, analyzeSamples, num_channels) != GAIN_ANALYSIS_OK)
                break;
            GetTitleGain ();
            //    printf("Recommended dB change for analyzeSamples %d: %+6.2f dB\n", i, titleGain);
            input += analyzeSamples;
        }
        ret = GetAlbumGain ();
    }
    if ((int) ret == GAIN_NOT_ENOUGH_SAMPLES) {
        ret = -0.00000000001f;
    }
    return ret;
}


void analyze(char *in_file, int ref_ms) {
    uint32_t sampleRate = 0;
    uint64_t totalSampleCount = 0;
    int16_t *wavBuffer = wavRead_int16(in_file, &sampleRate, &totalSampleCount);
    if (wavBuffer != NULL) {
        size_t analyzeSamples = ref_ms * (sampleRate / 1000);
        float gain = getGaindB(wavBuffer, totalSampleCount, sampleRate, analyzeSamples);

        printf("recommended dB change: %f \n", gain);
        free(wavBuffer);
    }
}

int main(int argc, char *argv[]) {
    printf("Replay Gain Analysis\n");
    printf("blog:http://cpuimage.cnblogs.com/\n");
    printf("e-mail:[email protected]\n");
    if (argc < 2)
        return -1;
    char *in_file = argv[1];
    //Specify the analysis length of 1 second
    int ref_ms = 1000;
    analyze(in_file, ref_ms);
    getchar();
    printf("press any key to exit. \n");
    return 0;
}

#ifdef __cplusplus
}
#endif
copy code

My habit, try to have as few comments as possible, and keep the code as clean and tidy as possible.

So let's just look at the code.

Project address: https://github.com/cpuimage/ReplayGainAnalysis

 

The specific process of the example is:

Load wav (drag and drop wav file to executable) -> output result -> save wav

 

After obtaining the corresponding evaluation results, what to do next depends on the specific needs of the judges.

 

If you have any other questions or needs, please contact me by email.

The email address is: 
[email protected]

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324758269&siteId=291194637