1. How to resampling PCM files using command lines?

ffmpeg -ar 44100 -ac 2 -f s16le -i 44100_s16le_2.pcm -ar 44100 -ac 1 -f f32le 44100_f32le_1.pcm
Copy the code

2. Ffmepg describes the sampling format, e.gS16le, f32leIn thes,u,f,le,beWhat do they stand for?

  • s: Signed (Signed)
  • u: Unsigned
  • f: Float
  • le: Little-endian mode
  • be: Big-endian mode

3. When describing the sampling format in SDL, for exampleAUDIO_S16LSB, AUDIO_F32MSBIn theLSB,MSBWhat do they stand for?

  • LSB: Small endian mode (Least Significant Bit/Byte, Least Significant Bit/Byte)
  • MSB: Big-endian mode (Most Significant Bit/Byte, Most Significant Bit/Byte)

What is audio resampling? Why do I need audio resampling?

  • Audio Resample: Convert Audio A to Audio B, and the parameters (sampling rate, sampling format, number of channels) of Audio A and B are not exactly the same.
  • Some audio encoders require characteristic parameters for input raw PCM data.

5. Describe the main process of audio code resampling.

  • In.pcm → input buffer → Output buffer → out.pcm

6. In the.pro file,LIBSWhat should I notice when adding FFmpeg and SDL libraries at the same time?

  • -L-lThere can’t be any Spaces after it

7. int a[] = {1, 2, 3, 4, 5}a[0]a[3]What does that mean in essence?

  • a[0]Is equivalent to*(a+0)Is equivalent to*aValue is equal to the1
  • a[3]Is equivalent to*(a+3)Value is equal to the4

8. In C, Pointers and data can be switched. How to understand this sentence? (Very important)

int a[] = {1.2.3.4.5};
int *p = a;
printf("%d, %d, %d, \n", *a, *(a + 1), a[1]); // Use a and p exactly the same
printf("%d, %d, %d, \n", *p, *(p + 1), p[1]); // Use a and p exactly the same
Copy the code

9. Memory structure diagram for input and output streams (helpful for code understanding)

10. Audio resampling key code

#include "ffmpegs.h"
#include <QFile>
#include <QDebug>

extern "C" {
#include <libswresample/swresample.h>
#include <libavutil/avutil.h>
}

#define ERROR_BUF(ret) \
    char errbuf[1024]; \
    av_strerror(ret, errbuf, sizeof (errbuf));

FFmpegs::FFmpegs() {}void FFmpegs::resampleAudio(ResampleAudioSpec &in, ResampleAudioSpec &out) {
    resampleAudio(in.filename, in.sampleRate, in.sampleFmt, in.chLayout,
                  out.filename, out.sampleRate, out.sampleFmt, out.chLayout);
}

void FFmpegs::resampleAudio(const char *inFilename,
                          int inSampleRate,
                          AVSampleFormat inSampleFmt,
                          int inChLayout,
                          
                          const char *outFilename,
                          int outSampleRate,
                          AVSampleFormat outSampleFmt,
                                   int outChLayout) {
    
    / / file name
    QFile inFile(inFilename);
    QFile outFile(outFilename);
    
    // Input buffer
    // A pointer to the buffer
    uint8_t **inData = nullptr;
    // Buffer size
    int inLinesize = 0;
    / / track number
    int inChs = av_get_channel_layout_nb_channels(inChLayout);
    // The size of a sample
    int inBytesPerSample = inChs * av_get_bytes_per_sample(inSampleFmt);
    // The number of samples in the buffer
    int inSamples = 1024;
    // Read file data size
    int len = 0;
    
    
    // Output buffer
    // A pointer to the buffer
    uint8_t **outData = nullptr;
    // Buffer size
    int outLinesize = 0;
    / / track number
    int outChs = av_get_channel_layout_nb_channels(outChLayout);
    // The size of a sample
    int outBytesPerSample = outChs * av_get_bytes_per_sample(outSampleFmt);
    // The number of samples in the buffer
    int outSamples = av_rescale_rnd(outSampleRate, inSamples, inSampleRate, AV_ROUND_UP);
    /* inSampleRate inSamples ------------- = ----------- outSampleRate outSamples outSamples = outSampleRate * inSamples / inSampleRate */
    
    qDebug() < <"Input buffer" << inSampleRate << inSamples;
    qDebug() < <"Output buffer" << outSampleRate << outSamples;
    
    
    // Return the result
    int ret = 0;
    
    // Create a resampling context
    SwrContext *ctx = swr_alloc_set_opts(nullptr,
                                         outChLayout, outSampleFmt, outSampleRate,
                                         inChLayout, inSampleFmt, inSampleRate, 0.nullptr);
    
    if(! ctx) {qDebug() < <"swr_alloc_set_opts error";
        goto end;
    }
    
    // Initialize the resampling context
    ret = swr_init(ctx);
    if (ret < 0) {
        ERROR_BUF(ret);
        qDebug() < <"swr_init error" << errbuf;
        goto end;
    }
    
    
    // Create an input buffer
    ret = av_samples_alloc_array_and_samples(&inData,
                                             &inLinesize,
                                             inChs,
                                             inSamples,
                                             inSampleFmt,
                                             1);
    if (ret < 0) {
        ERROR_BUF(ret);
        qDebug() < <"av_samples_alloc_array_and_samples error:" << errbuf;
        goto end;
    }
    
    // Create an output buffer
    ret = av_samples_alloc_array_and_samples(&outData,
                                             &outLinesize,
                                             outChs,
                                             outSamples,
                                             outSampleFmt,
                                             1);
    
    if (ret < 0) {
        ERROR_BUF(ret);
        qDebug() < <"av_samples_alloc_array_and_samples error:" << errbuf;
        goto end;
    }
    
    // Open the file
    if(! inFile.open(QFile::ReadOnly)) {
        qDebug() < <"file open error:" << inFilename;
        goto end;
    }
    if(! outFile.open(QFile::WriteOnly)) {
        qDebug() < <"file open error:" << outFilename;
        goto end;
    }
    
    // Read file data
    // intData[0] == *inData
    while ((len = inFile.read((char *)inData[0], inLinesize)) > 0) {
        // The number of samples read
        inSamples = len / inBytesPerSample;
        
        / / re-sampling
        ret = swr_convert(ctx, outData, outSamples, (const uint8_t **)inData, inSamples);
        
        if (ret < 0) {
            ERROR_BUF(ret);
            qDebug() < <"swr_convert error:" << errbuf;
            goto end;
        }
        
        // Write the converted data to the output file
        // outData[0] == *outData
        outFile.write((char *)outData[0], ret * outBytesPerSample);
    }
    
    // Check the output buffer to see if there are any samples left (resampled, converted)
    
    while ((ret = swr_convert(ctx, outData, outSamples, nullptr.0)) > 0) {
        outFile.write((char *)outData[0], ret * outBytesPerSample);
    }
    
    
end:
    // Release resources
    // Close the file
    inFile.close(a); outFile.close(a);// Release the input buffer
    if (inData) {
        av_freep(&inData[0]);
    }
    av_freep(&inData);

    // Release the output buffer
    if (outData) {
        av_freep(&outData[0]);
    }
    av_freep(&outData);

    // Release the resampling context
    swr_free(&ctx);

// void *ptr = malloc(100);
// freep(&ptr);
// free(ptr);
// ptr = nullptr;
}

Copy the code