Reputation: 769
I use the FFmpeg library for a personnal project and I need help about one thing. I have a music file in stereo sound and I want to convert this stereo sound to mono sound ? Is it possible with this library ? Is there a function inside to do this job ? My project is in C/C++.
I searched on the Doxygen documentation on the FFmpeg website and on this forum but I didn't find something interesting.
Thanks for reading !
Upvotes: 62
Views: 83415
Reputation: 5334
As I mentioned in the comment, you could resample it yourself. It depends on what you already have and what format you use. I cannot give you code which would work instantly, but give you an example (pseudo/real code mix).
After you encoded the frame, and have done the things you have to do, your data buffer will be filled with the audio. Now it depends how your format is (see here) and how many channels you have. Let's assume it is signed 16bit stereo, than your buffer would look like:
+-----+-----+-----+-----+-----+
| LS1 | RS1 | LS2 | RS2 | ... |
+-----+-----+-----+-----+-----+
// LS = LEFT SAMPLE 16 Bit
// RS = RIGHT SAMPLE 16 Bit
Now iterate through the buffer and calculate left and right sample together.
for(int i=0; i<sample_size; i+=2) {
auto r = (static_cast<int32_t>(buffer[i]) + buffer[i+1]) / 2;
buffer[i] = buffer[i+1] = r;
}
Upvotes: 1
Reputation: 1581
You can just use ffmpeg. Direct command is present for the purpose-
ffmpeg -i stereo.flac -ac 1 mono.flac
Would convert your stereo file into mono channel. For more details, you can look at this page-
https://trac.ffmpeg.org/wiki/AudioChannelManipulation
Upvotes: 120
Reputation: 9794
Use swr_convert
from libswresample to convert between formats. Something like:
#include "libswresample/swresample.h"
au_convert_ctx = swr_alloc();
out_channel_layout = AV_CH_LAYOUT_MONO;
out_sample_fmt = AV_SAMPLE_FMT_S16;
out_sample_rate = 44100;
out_channels = av_get_channel_layout_nb_channels(out_channel_layout);
in_sample_fmt = pCodecCtx->sample_fmt;
in_channel_layout=av_get_default_channel_layout(pCodecCtx->channels);
au_convert_ctx=swr_alloc_set_opts(au_convert_ctx,out_channel_layout, out_sample_fmt, out_sample_rate,
in_channel_layout, in_sample_fmt, pCodecCtx->sample_rate, 0, NULL);
swr_init(au_convert_ctx);
//Generate your frame of original audio, then use swr_convert to convert to mono,
//converted number of samples will now be in out_buffer.
int converted = swr_convert(au_convert_ctx, &out_buffer, MAX_AUDIO_FRAME_SIZE, (const uint8_t **)&pFrame->data , pFrame->nb_samples);
//...
swr_free(&au_convert_ctx);
to get you started. This will convert whatever the original format happens to be to 44100 kHz mono. You could also use pCodecCtx->sample_rate
as the output sample rate as well.
It's the most flexible and easiest solution.
Upvotes: 9