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, f32le
In thes
,u
,f
,le
,be
What do they stand for?
s
: Signed (Signed)u
: Unsignedf
: Floatle
: Little-endian modebe
: Big-endian mode
3. When describing the sampling format in SDL, for exampleAUDIO_S16LSB, AUDIO_F32MSB
In theLSB
,MSB
What 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,LIBS
What should I notice when adding FFmpeg and SDL libraries at the same time?
-L
和-l
There 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*a
Value 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