|
|
|
@ -30,6 +30,11 @@ |
|
|
|
|
#include "filters.h" |
|
|
|
|
#include "formats.h" |
|
|
|
|
|
|
|
|
|
typedef struct SamplingContext { |
|
|
|
|
uint32_t phi; ///< current phase of the sine (2pi = 1<<32)
|
|
|
|
|
uint32_t dphi; ///< phase increment between two samples
|
|
|
|
|
} SamplingContext; |
|
|
|
|
|
|
|
|
|
typedef struct SineContext { |
|
|
|
|
const AVClass *class; |
|
|
|
|
double frequency; |
|
|
|
@ -40,13 +45,11 @@ typedef struct SineContext { |
|
|
|
|
int64_t duration; |
|
|
|
|
int16_t *sin; |
|
|
|
|
int64_t pts; |
|
|
|
|
uint32_t phi; ///< current phase of the sine (2pi = 1<<32)
|
|
|
|
|
uint32_t dphi; ///< phase increment between two samples
|
|
|
|
|
SamplingContext signal; |
|
|
|
|
SamplingContext beep; |
|
|
|
|
unsigned beep_period; |
|
|
|
|
unsigned beep_index; |
|
|
|
|
unsigned beep_length; |
|
|
|
|
uint32_t phi_beep; ///< current phase of the beep
|
|
|
|
|
uint32_t dphi_beep; ///< phase increment of the beep
|
|
|
|
|
} SineContext; |
|
|
|
|
|
|
|
|
|
#define CONTEXT SineContext |
|
|
|
@ -143,6 +146,16 @@ enum { |
|
|
|
|
VAR_VARS_NB |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static void sampling_init(SamplingContext *c, double frequency, int sample_rate) |
|
|
|
|
{ |
|
|
|
|
c->dphi = ldexp(frequency, 32) / sample_rate + 0.5; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static av_always_inline void sampling_advance(SamplingContext *c) |
|
|
|
|
{ |
|
|
|
|
c->phi += c->dphi; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static av_cold int init(AVFilterContext *ctx) |
|
|
|
|
{ |
|
|
|
|
int ret; |
|
|
|
@ -150,14 +163,13 @@ static av_cold int init(AVFilterContext *ctx) |
|
|
|
|
|
|
|
|
|
if (!(sine->sin = av_malloc(sizeof(*sine->sin) << LOG_PERIOD))) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
sine->dphi = ldexp(sine->frequency, 32) / sine->sample_rate + 0.5; |
|
|
|
|
sampling_init(&sine->signal, sine->frequency, sine->sample_rate); |
|
|
|
|
make_sin_table(sine->sin); |
|
|
|
|
|
|
|
|
|
if (sine->beep_factor) { |
|
|
|
|
sine->beep_period = sine->sample_rate; |
|
|
|
|
sine->beep_length = sine->beep_period / 25; |
|
|
|
|
sine->dphi_beep = ldexp(sine->beep_factor * sine->frequency, 32) / |
|
|
|
|
sine->sample_rate + 0.5; |
|
|
|
|
sampling_init(&sine->beep, sine->beep_factor * sine->frequency, sine->sample_rate); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret = av_expr_parse(&sine->samples_per_frame_expr, |
|
|
|
@ -241,11 +253,11 @@ static int activate(AVFilterContext *ctx) |
|
|
|
|
samples = (int16_t *)frame->data[0]; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < nb_samples; i++) { |
|
|
|
|
samples[i] = sine->sin[sine->phi >> (32 - LOG_PERIOD)]; |
|
|
|
|
sine->phi += sine->dphi; |
|
|
|
|
samples[i] = sine->sin[sine->signal.phi >> (32 - LOG_PERIOD)]; |
|
|
|
|
sampling_advance(&sine->signal); |
|
|
|
|
if (sine->beep_index < sine->beep_length) { |
|
|
|
|
samples[i] += sine->sin[sine->phi_beep >> (32 - LOG_PERIOD)] * 2; |
|
|
|
|
sine->phi_beep += sine->dphi_beep; |
|
|
|
|
samples[i] += sine->sin[sine->beep.phi >> (32 - LOG_PERIOD)] * 2; |
|
|
|
|
sampling_advance(&sine->beep); |
|
|
|
|
} |
|
|
|
|
if (++sine->beep_index == sine->beep_period) |
|
|
|
|
sine->beep_index = 0; |
|
|
|
|