[FFmpeg-devel] [PATCH] examples: add resampling_audio.c file
Michael Niedermayer
michaelni at gmx.at
Sun Dec 2 00:34:03 CET 2012
On Sat, Dec 01, 2012 at 08:21:47PM +0100, Stefano Sabatini wrote:
> On date Saturday 2012-12-01 05:09:04 +0100, Michael Niedermayer encoded:
> > On Fri, Nov 30, 2012 at 11:42:43PM +0100, Stefano Sabatini wrote:
> > > On date Friday 2012-11-30 19:58:51 +0100, Stefano Sabatini encoded:
> > > > ---
> > > > doc/examples/Makefile | 3 +-
> > > > doc/examples/resampling_audio.c | 208 +++++++++++++++++++++++++++++++++++++++
> > > > 2 files changed, 210 insertions(+), 1 deletion(-)
> > > > create mode 100644 doc/examples/resampling_audio.c
> > >
> > > Upped.
> > >
> > > Note, this doesn't work if I change destination layout MONO ->
> > > SURROUND, I got:
> > > $ resampling_audio out.raw
> > > ...
> > > Resampling succeeded. Play the output file with the command:
> > > ffplay -f s16le -channel_layout 7 -ac 3 -ar 44100 out.raw
> > > $ ffplay -f s16le -channel_layout 7 -ac 3 -ar 44100 out.raw
> > > ffplay version N-46906-ga5e382a Copyright (c) 2003-2012 the FFmpeg developers
> > > [...]
> > > [s16le @ 0x7f11080042d0] Estimating duration from bitrate, this may be inaccurate
> > > Input #0, s16le, from 'out.raw':
> > > Duration: 00:00:10.01, start: 0.000000, bitrate: 2116 kb/s
> > > Stream #0:0: Audio: pcm_s16le, 44100 Hz, 3.0, s16, 2116 kb/s
> > > SDL_OpenAudio (3 channels): 1 (mono) and 2 (stereo) channels supported
> > > [pcm_s16le @ 0x7f1108000ad0] Invalid PCM packet, data has size 2 but at least a size of 6 was expected
> > >
> > > and I got distorted sound. Any hint?
> >
> > try -channels 3
>
> Yes, this fixes it, still ffplay shows the wrong number of channels (6
> in place of 3).
>
> Patch updated, will push it in a couple of days, please comment.
> --
> FFmpeg = Faithless and Fostering Martial Puristic Exciting Genius
> Makefile | 1
> resampling_audio.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 214 insertions(+)
> 30e82c84ef67fae46e26d59d35f604e66999b9ba 0002-examples-add-resampling_audio.c-file.patch
> From c249e5a01288f9037a1b5e63855769c9e30e7360 Mon Sep 17 00:00:00 2001
> From: Stefano Sabatini <stefasab at gmail.com>
> Date: Fri, 30 Nov 2012 13:51:40 +0100
> Subject: [PATCH] examples: add resampling_audio.c file
>
> ---
> doc/examples/Makefile | 1 +
> doc/examples/resampling_audio.c | 213 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 214 insertions(+)
> create mode 100644 doc/examples/resampling_audio.c
>
> diff --git a/doc/examples/Makefile b/doc/examples/Makefile
> index 36c949a..c849daa 100644
> --- a/doc/examples/Makefile
> +++ b/doc/examples/Makefile
> @@ -17,6 +17,7 @@ EXAMPLES= decoding_encoding \
> filtering_audio \
> metadata \
> muxing \
> + resampling_audio \
> scaling_video \
>
> OBJS=$(addsuffix .o,$(EXAMPLES))
> diff --git a/doc/examples/resampling_audio.c b/doc/examples/resampling_audio.c
> new file mode 100644
> index 0000000..028ff20
> --- /dev/null
> +++ b/doc/examples/resampling_audio.c
> @@ -0,0 +1,213 @@
> +/*
> + * Copyright (c) 2012 Stefano Sabatini
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +/**
> + * @file
> + * libswresample API use example.
> + */
> +
> +#include <libavutil/opt.h>
> +#include <libavutil/channel_layout.h>
> +#include <libavutil/samplefmt.h>
> +#include <libswresample/swresample.h>
> +
> +static int get_format_from_sample_fmt(const char **fmt,
> + enum AVSampleFormat sample_fmt)
> +{
> + int i;
> + struct sample_fmt_entry {
> + enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
> + } sample_fmt_entries[] = {
> + { AV_SAMPLE_FMT_U8, "u8", "u8" },
> + { AV_SAMPLE_FMT_S16, "s16be", "s16le" },
> + { AV_SAMPLE_FMT_S32, "s32be", "s32le" },
> + { AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
> + { AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
> + };
> + *fmt = NULL;
> +
> + for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
> + struct sample_fmt_entry *entry = &sample_fmt_entries[i];
> + if (sample_fmt == entry->sample_fmt) {
> + *fmt = AV_NE(entry->fmt_be, entry->fmt_le);
> + return 0;
> + }
> + }
something like
{ AV_SAMPLE_FMT_U8, AV_NE("u8", "u8" ) },
{ AV_SAMPLE_FMT_S16, AV_NE("s16be", "s16le") },
...
should be slightly simpler
> +
> + fprintf(stderr,
> + "Sample format %s not supported as output format\n",
> + av_get_sample_fmt_name(sample_fmt));
> + return AVERROR(EINVAL);
> +}
> +
> +/**
> + * Fill dst buffer with nb_samples, generated starting from t.
> + */
> +void fill_samples(double *dst, int nb_samples, int nb_channels, int sample_rate, double *t)
> +{
> + int i, j;
> + double tincr = (double)1 / sample_rate, *dstp = dst;
> + const double c = 2 * M_PI * (double)440.0;
> +
> + /* generate sin tone with 440Hz frequency and duplicated channels */
> + for (i = 0; i < nb_samples; i++) {
> + *dstp = sin(c * *t);
> + for (j = 1; j < nb_channels; j++)
> + dstp[j] = dstp[0];
> + dstp += nb_channels;
> + *t += tincr;
> + }
> +}
> +
> +int alloc_samples_array_and_data(uint8_t ***data, int *linesize, int nb_channels,
> + int nb_samples, enum AVSampleFormat sample_fmt, int align)
> +{
> + int nb_planes = av_sample_fmt_is_planar(sample_fmt) ? nb_channels : 1;
> +
> + *data = av_malloc(sizeof(*data) * nb_planes);
> + if (!*data)
> + return AVERROR(ENOMEM);
> + return av_samples_alloc(*data, linesize, nb_channels,
> + nb_samples, sample_fmt, align);
> +}
> +
> +int main(int argc, char **argv)
> +{
> + int64_t src_ch_layout = AV_CH_LAYOUT_STEREO, dst_ch_layout = AV_CH_LAYOUT_SURROUND;
> + int src_rate = 48000, dst_rate = 44100;
> + uint8_t **src_data, **dst_data;
> + int src_nb_channels = 0, dst_nb_channels = 0;
> + int src_linesize, dst_linesize;
> + int src_nb_samples = 1024, dst_nb_samples;
> + enum AVSampleFormat src_sample_fmt = AV_SAMPLE_FMT_DBL, dst_sample_fmt = AV_SAMPLE_FMT_S16;
> + const char *dst_filename = NULL;
> + FILE *dst_file;
> + int dst_bufsize;
> + const char *fmt;
> + struct SwrContext *swr_ctx;
> + double t;
> + int ret;
> +
> + if (argc != 2) {
> + fprintf(stderr, "Usage: %s output_file output_opts\n"
> + "API example program to show how to resample an audio stream with libswresample.\n"
> + "This program generates a series of audio frames, resamples them to a specified "
> + "output format and rate and saves them to an output file named output_file.\n",
> + argv[0]);
> + exit(1);
> + }
> + dst_filename = argv[1];
> +
> + dst_file = fopen(dst_filename, "wb");
> + if (!dst_file) {
> + fprintf(stderr, "Could not open destination file %s\n", dst_filename);
> + exit(1);
> + }
> +
> + /* create resampler context */
> + swr_ctx = swr_alloc();
> + if (!swr_ctx) {
> + fprintf(stderr, "Could not allocate resampler context\n");
> + ret = AVERROR(ENOMEM);
> + goto end;
> + }
> +
> + /* set options */
> + av_opt_set_int(swr_ctx, "in_channel_layout", src_ch_layout, 0);
> + av_opt_set_int(swr_ctx, "in_sample_rate", src_rate, 0);
> + av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", src_sample_fmt, 0);
> +
> + av_opt_set_int(swr_ctx, "out_channel_layout", dst_ch_layout, 0);
> + av_opt_set_int(swr_ctx, "out_sample_rate", dst_rate, 0);
> + av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", dst_sample_fmt, 0);
> +
> + /* initialize the resampling context */
> + if ((ret = swr_init(swr_ctx)) < 0) {
> + fprintf(stderr, "Failed to initialize the resampling context\n");
> + goto end;
> + }
> +
> + /* allocate source and destination samples buffers */
> +
> + src_nb_channels = av_get_channel_layout_nb_channels(src_ch_layout);
> + ret = alloc_samples_array_and_data(&src_data, &src_linesize, src_nb_channels,
> + src_nb_samples, src_sample_fmt, 0);
> + if (ret < 0) {
> + fprintf(stderr, "Could not allocate source samples\n");
> + goto end;
> + }
> +
> + /* compute the number of converted samples: buffering is avoided
> + * ensuring that the output buffer will contain at least all the
> + * converted input samples */
> + dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, dst_rate) + src_nb_samples,
> + dst_rate, src_rate, AV_ROUND_UP);
isnt this mixing up src and dst rates ?
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
The worst form of inequality is to try to make unequal things equal.
-- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20121202/22a4acb3/attachment.asc>
More information about the ffmpeg-devel
mailing list