Re: [FFmpeg-devel] [PATCH] avfilter: add square audio source filter
Paul B Mahol (12019-07-14): > Signed-off-by: Paul B Mahol > --- > doc/filters.texi | 44 > libavfilter/Makefile | 1 + > libavfilter/allfilters.c | 1 + > libavfilter/asrc_sine.c | 86 ++-- > 4 files changed, 119 insertions(+), 13 deletions(-) > > diff --git a/doc/filters.texi b/doc/filters.texi > index 3108ad349e..b94eddefe5 100644 > --- a/doc/filters.texi > +++ b/doc/filters.texi > @@ -5895,6 +5895,50 @@ sine=1000:samples_per_frame='st(0,mod(n,5)); > 1602-not(not(eq(ld(0),1)+eq(ld(0),3 > @end example > @end itemize > > +@section square > + > +Generate an audio signal made of a square wave with custom amplitude. > + > +The audio signal is bit-exact. > + > +The filter accepts the following options: > + > +@table @option > +@item amplitude, a > +Set the carrier amplitude, Default is 0.2. > + > +@item frequency, f > +Set the carrier frequency. Default is 440 Hz. > + > +@item sample_rate, r > +Specify the sample rate, default is 44100. > + > +@item duration, d > +Specify the duration of the generated audio stream. > + > +@item samples_per_frame > +Set the number of samples per output frame. > + > +The expression can contain the following constants: > + > +@table @option > +@item n > +The (sequential) number of the output audio frame, starting from 0. > + > +@item pts > +The PTS (Presentation TimeStamp) of the output audio frame, > +expressed in @var{TB} units. > + > +@item t > +The PTS of the output audio frame, expressed in seconds. > + > +@item TB > +The timebase of the output audio frames. > +@end table > + > +Default is @code{1024}. > +@end table > + > @c man end AUDIO SOURCES > > @chapter Audio Sinks > diff --git a/libavfilter/Makefile b/libavfilter/Makefile > index 455c809b15..b958450a80 100644 > --- a/libavfilter/Makefile > +++ b/libavfilter/Makefile > @@ -148,6 +148,7 @@ OBJS-$(CONFIG_FLITE_FILTER) += > asrc_flite.o > OBJS-$(CONFIG_HILBERT_FILTER)+= asrc_hilbert.o > OBJS-$(CONFIG_SINC_FILTER) += asrc_sinc.o > OBJS-$(CONFIG_SINE_FILTER) += asrc_sine.o > +OBJS-$(CONFIG_SQUARE_FILTER) += asrc_sine.o > > OBJS-$(CONFIG_ANULLSINK_FILTER) += asink_anullsink.o > > diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c > index 04a3df7d56..510e0d65dd 100644 > --- a/libavfilter/allfilters.c > +++ b/libavfilter/allfilters.c > @@ -140,6 +140,7 @@ extern AVFilter ff_asrc_flite; > extern AVFilter ff_asrc_hilbert; > extern AVFilter ff_asrc_sinc; > extern AVFilter ff_asrc_sine; > +extern AVFilter ff_asrc_square; > > extern AVFilter ff_asink_anullsink; > > diff --git a/libavfilter/asrc_sine.c b/libavfilter/asrc_sine.c > index 3a87210b4b..e3153f03e4 100644 > --- a/libavfilter/asrc_sine.c > +++ b/libavfilter/asrc_sine.c > @@ -30,6 +30,7 @@ > > typedef struct SineContext { > const AVClass *class; > +double amplitude; > double frequency; > double beep_factor; > char *samples_per_frame; > @@ -38,6 +39,7 @@ typedef struct SineContext { > int64_t duration; > int16_t *sin; > int64_t pts; > +int square_amplitude; Only used locally, do not put it in the context. > uint32_t phi; ///< current phase of the sine (2pi = 1<<32) > uint32_t dphi; ///< phase increment between two samples > unsigned beep_period; > @@ -45,6 +47,8 @@ typedef struct SineContext { > unsigned beep_length; > uint32_t phi_beep; ///< current phase of the beep > uint32_t dphi_beep; ///< phase increment of the beep > + > +void (*generate)(struct SineContext *sine, AVFrame *frame); Ditto. There is really no need for a function pointer at all. > } SineContext; > > #define CONTEXT SineContext > @@ -141,11 +145,51 @@ enum { > VAR_VARS_NB > }; > > +static void generate_sine(SineContext *sine, AVFrame *frame) > +{ > +int16_t *samples = (int16_t *)frame->data[0]; > + > +for (int i = 0; i < frame->nb_samples; i++) { > +samples[i] = sine->sin[sine->phi >> (32 - LOG_PERIOD)]; > +sine->phi += sine->dphi; > +if (sine->beep_index < sine->beep_length) { > +samples[i] += sine->sin[sine->phi_beep >> (32 - LOG_PERIOD)] << > 1; > +sine->phi_beep += sine->dphi_beep; > +} > +if (++sine->beep_index == sine->beep_period) > +sine->beep_index = 0; > +} > +} > + > +static void generate_square(SineContext *sine, AVFrame *frame) > +{ > +int16_t *samples = (int16_t *)frame->data[0]; > + > +for (int i = 0; i < frame->nb_samples; i++) { > +int16_t sample = sine->sin[sine->phi >> (32 - LOG_PERIOD)]; > + > +if (sample >= 0) > +sample = sine->square_amplitude; > +else > +sample = -sine->square_amplitude; > + > +samples[i] = sample; > +sine->phi += sine->dphi; > +} > +} This looks like a needlessly complicated way of generating a
Re: [FFmpeg-devel] [PATCH] avfilter: add square audio source filter
Paul B Mahol (12019-07-26): > Nicolas, are you fine with this changes? Sorry, my mail server had trouble recently. On it. Regards, -- Nicolas George signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avfilter: add square audio source filter
Nicolas, are you fine with this changes? On Wed, Jul 24, 2019 at 1:29 PM Paul B Mahol wrote: > On 7/14/19, Paul B Mahol wrote: > > Signed-off-by: Paul B Mahol > > --- > > doc/filters.texi | 44 > > libavfilter/Makefile | 1 + > > libavfilter/allfilters.c | 1 + > > libavfilter/asrc_sine.c | 86 ++-- > > 4 files changed, 119 insertions(+), 13 deletions(-) > > > > Will apply ASAP! > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avfilter: add square audio source filter
On 7/14/19, Paul B Mahol wrote: > Signed-off-by: Paul B Mahol > --- > doc/filters.texi | 44 > libavfilter/Makefile | 1 + > libavfilter/allfilters.c | 1 + > libavfilter/asrc_sine.c | 86 ++-- > 4 files changed, 119 insertions(+), 13 deletions(-) > Will apply ASAP! ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avfilter: add square audio source filter
Signed-off-by: Paul B Mahol --- doc/filters.texi | 44 libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/asrc_sine.c | 86 ++-- 4 files changed, 119 insertions(+), 13 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 3108ad349e..b94eddefe5 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -5895,6 +5895,50 @@ sine=1000:samples_per_frame='st(0,mod(n,5)); 1602-not(not(eq(ld(0),1)+eq(ld(0),3 @end example @end itemize +@section square + +Generate an audio signal made of a square wave with custom amplitude. + +The audio signal is bit-exact. + +The filter accepts the following options: + +@table @option +@item amplitude, a +Set the carrier amplitude, Default is 0.2. + +@item frequency, f +Set the carrier frequency. Default is 440 Hz. + +@item sample_rate, r +Specify the sample rate, default is 44100. + +@item duration, d +Specify the duration of the generated audio stream. + +@item samples_per_frame +Set the number of samples per output frame. + +The expression can contain the following constants: + +@table @option +@item n +The (sequential) number of the output audio frame, starting from 0. + +@item pts +The PTS (Presentation TimeStamp) of the output audio frame, +expressed in @var{TB} units. + +@item t +The PTS of the output audio frame, expressed in seconds. + +@item TB +The timebase of the output audio frames. +@end table + +Default is @code{1024}. +@end table + @c man end AUDIO SOURCES @chapter Audio Sinks diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 455c809b15..b958450a80 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -148,6 +148,7 @@ OBJS-$(CONFIG_FLITE_FILTER) += asrc_flite.o OBJS-$(CONFIG_HILBERT_FILTER)+= asrc_hilbert.o OBJS-$(CONFIG_SINC_FILTER) += asrc_sinc.o OBJS-$(CONFIG_SINE_FILTER) += asrc_sine.o +OBJS-$(CONFIG_SQUARE_FILTER) += asrc_sine.o OBJS-$(CONFIG_ANULLSINK_FILTER) += asink_anullsink.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 04a3df7d56..510e0d65dd 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -140,6 +140,7 @@ extern AVFilter ff_asrc_flite; extern AVFilter ff_asrc_hilbert; extern AVFilter ff_asrc_sinc; extern AVFilter ff_asrc_sine; +extern AVFilter ff_asrc_square; extern AVFilter ff_asink_anullsink; diff --git a/libavfilter/asrc_sine.c b/libavfilter/asrc_sine.c index 3a87210b4b..e3153f03e4 100644 --- a/libavfilter/asrc_sine.c +++ b/libavfilter/asrc_sine.c @@ -30,6 +30,7 @@ typedef struct SineContext { const AVClass *class; +double amplitude; double frequency; double beep_factor; char *samples_per_frame; @@ -38,6 +39,7 @@ typedef struct SineContext { int64_t duration; int16_t *sin; int64_t pts; +int square_amplitude; uint32_t phi; ///< current phase of the sine (2pi = 1<<32) uint32_t dphi; ///< phase increment between two samples unsigned beep_period; @@ -45,6 +47,8 @@ typedef struct SineContext { unsigned beep_length; uint32_t phi_beep; ///< current phase of the beep uint32_t dphi_beep; ///< phase increment of the beep + +void (*generate)(struct SineContext *sine, AVFrame *frame); } SineContext; #define CONTEXT SineContext @@ -141,11 +145,51 @@ enum { VAR_VARS_NB }; +static void generate_sine(SineContext *sine, AVFrame *frame) +{ +int16_t *samples = (int16_t *)frame->data[0]; + +for (int i = 0; i < frame->nb_samples; i++) { +samples[i] = sine->sin[sine->phi >> (32 - LOG_PERIOD)]; +sine->phi += sine->dphi; +if (sine->beep_index < sine->beep_length) { +samples[i] += sine->sin[sine->phi_beep >> (32 - LOG_PERIOD)] << 1; +sine->phi_beep += sine->dphi_beep; +} +if (++sine->beep_index == sine->beep_period) +sine->beep_index = 0; +} +} + +static void generate_square(SineContext *sine, AVFrame *frame) +{ +int16_t *samples = (int16_t *)frame->data[0]; + +for (int i = 0; i < frame->nb_samples; i++) { +int16_t sample = sine->sin[sine->phi >> (32 - LOG_PERIOD)]; + +if (sample >= 0) +sample = sine->square_amplitude; +else +sample = -sine->square_amplitude; + +samples[i] = sample; +sine->phi += sine->dphi; +} +} + static av_cold int init(AVFilterContext *ctx) { int ret; SineContext *sine = ctx->priv; +if (!strcmp(ctx->filter->name, "square")) { +sine->square_amplitude = -sine->amplitude * INT16_MIN; +sine->generate = generate_square; +} else { +sine->generate = generate_sine; +} + if (!(sine->sin = av_malloc(sizeof(*sine->sin) << LOG_PERIOD))) return AVERROR(ENOMEM); sine->dphi = ldexp(sine->frequency, 32) / sine->sample_rate + 0.5; @@ -224,8 +268,7 @@