1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-10 06:10:52 +02:00

avfilter/avf_showcwt: add two more options

This commit is contained in:
Paul B Mahol
2023-08-01 10:46:14 +02:00
parent d295b6b693
commit de71928383
2 changed files with 29 additions and 14 deletions

View File

@@ -30815,6 +30815,12 @@ Default is @code{20000} Hz. The real frequency upper limit
depends on input audio's sample rate and such will be enforced depends on input audio's sample rate and such will be enforced
on this value when it is set to value greater than Nyquist frequency. on this value when it is set to value greater than Nyquist frequency.
@item imin
Set the minimum intensity that will be used in output.
@item imax
Set the maximum intensity that will be used in output.
@item logb @item logb
Set the logarithmic basis for brightness strength when Set the logarithmic basis for brightness strength when
mapping calculated magnitude values to pixel values. mapping calculated magnitude values to pixel values.

View File

@@ -119,6 +119,7 @@ typedef struct ShowCWTContext {
int intensity_scale; int intensity_scale;
int frequency_scale; int frequency_scale;
float minimum_frequency, maximum_frequency; float minimum_frequency, maximum_frequency;
float minimum_intensity, maximum_intensity;
float deviation; float deviation;
float bar_ratio; float bar_ratio;
int bar_size; int bar_size;
@@ -152,6 +153,8 @@ static const AVOption showcwt_options[] = {
{ "qdrt", "qdrt", 0, AV_OPT_TYPE_CONST,{.i64=ISCALE_QDRT}, 0, 0, FLAGS, "iscale" }, { "qdrt", "qdrt", 0, AV_OPT_TYPE_CONST,{.i64=ISCALE_QDRT}, 0, 0, FLAGS, "iscale" },
{ "min", "set minimum frequency", OFFSET(minimum_frequency), AV_OPT_TYPE_FLOAT, {.dbl = 20.}, 1, 192000, FLAGS }, { "min", "set minimum frequency", OFFSET(minimum_frequency), AV_OPT_TYPE_FLOAT, {.dbl = 20.}, 1, 192000, FLAGS },
{ "max", "set maximum frequency", OFFSET(maximum_frequency), AV_OPT_TYPE_FLOAT, {.dbl = 20000.}, 1, 192000, FLAGS }, { "max", "set maximum frequency", OFFSET(maximum_frequency), AV_OPT_TYPE_FLOAT, {.dbl = 20000.}, 1, 192000, FLAGS },
{ "imin", "set minimum intensity", OFFSET(minimum_intensity), AV_OPT_TYPE_FLOAT, {.dbl = 0.}, 0, 1, FLAGS },
{ "imax", "set maximum intensity", OFFSET(maximum_intensity), AV_OPT_TYPE_FLOAT, {.dbl = 1.}, 0, 1, FLAGS },
{ "logb", "set logarithmic basis", OFFSET(logarithmic_basis), AV_OPT_TYPE_FLOAT, {.dbl = 0.0001}, 0, 1, FLAGS }, { "logb", "set logarithmic basis", OFFSET(logarithmic_basis), AV_OPT_TYPE_FLOAT, {.dbl = 0.0001}, 0, 1, FLAGS },
{ "deviation", "set frequency deviation", OFFSET(deviation), AV_OPT_TYPE_FLOAT, {.dbl = 1.}, 0, 100, FLAGS }, { "deviation", "set frequency deviation", OFFSET(deviation), AV_OPT_TYPE_FLOAT, {.dbl = 1.}, 0, 100, FLAGS },
{ "pps", "set pixels per second", OFFSET(pps), AV_OPT_TYPE_INT, {.i64 = 64}, 1, 1024, FLAGS }, { "pps", "set pixels per second", OFFSET(pps), AV_OPT_TYPE_INT, {.i64 = 64}, 1, 1024, FLAGS },
@@ -295,31 +298,37 @@ static void frequency_band(float *frequency_band,
} }
} }
static float remap_log(float value, int iscale, float log_factor) static float remap_log(ShowCWTContext *s, float value, int iscale, float log_factor)
{ {
const float max = s->maximum_intensity;
const float min = s->minimum_intensity;
float ret; float ret;
value += min;
switch (iscale) { switch (iscale) {
case ISCALE_LINEAR: case ISCALE_LINEAR:
ret = value * 20.f*expf(log_factor); ret = max - expf(value / log_factor);
break; break;
case ISCALE_LOG: case ISCALE_LOG:
value = logf(value) * log_factor; value = logf(value) * log_factor;
ret = max - av_clipf(value, 0.f, 1.f);
ret = 1.f - av_clipf(value, 0.f, 1.f);
break; break;
case ISCALE_SQRT: case ISCALE_SQRT:
ret = sqrtf(value * 20.f*expf(log_factor)); value = max - expf(value / log_factor);
ret = sqrtf(value);
break; break;
case ISCALE_CBRT: case ISCALE_CBRT:
ret = cbrtf(value * 20.f*expf(log_factor)); value = max - expf(value / log_factor);
ret = cbrtf(value);
break; break;
case ISCALE_QDRT: case ISCALE_QDRT:
ret = powf(value * 20.f*expf(log_factor), 0.25f); value = max - expf(value / log_factor);
ret = powf(value, 0.25f);
break; break;
} }
return ret; return av_clipf(ret, 0.f, 1.f);
} }
static int run_channel_cwt_prepare(AVFilterContext *ctx, void *arg, int jobnr, int ch) static int run_channel_cwt_prepare(AVFilterContext *ctx, void *arg, int jobnr, int ch)
@@ -517,9 +526,9 @@ static int draw(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
u = hypotf(src[0].re, src[0].im); u = hypotf(src[0].re, src[0].im);
v = hypotf(src2[0].re, src2[0].im); v = hypotf(src2[0].re, src2[0].im);
z = remap_log(z, iscale, log_factor); z = remap_log(s, z, iscale, log_factor);
u = remap_log(u, iscale, log_factor); u = remap_log(s, u, iscale, log_factor);
v = remap_log(v, iscale, log_factor); v = remap_log(s, v, iscale, log_factor);
Y = z; Y = z;
U = sinf((v - u) * M_PI_2); U = sinf((v - u) * M_PI_2);
@@ -553,7 +562,7 @@ static int draw(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
float z; float z;
z = hypotf(srcn[0].re, srcn[0].im); z = hypotf(srcn[0].re, srcn[0].im);
z = remap_log(z, iscale, log_factor); z = remap_log(s, z, iscale, log_factor);
Y += z * yf; Y += z * yf;
U += z * yf * sinf(2.f * M_PI * (ch * yf + rotation)); U += z * yf * sinf(2.f * M_PI * (ch * yf + rotation));
@@ -572,7 +581,7 @@ static int draw(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
break; break;
case 2: case 2:
Y = hypotf(src[0].re, src[0].im); Y = hypotf(src[0].re, src[0].im);
Y = remap_log(Y, iscale, log_factor); Y = remap_log(s, Y, iscale, log_factor);
U = atan2f(src[0].im, src[0].re); U = atan2f(src[0].im, src[0].re);
U = 0.5f + 0.5f * U * Y / M_PI; U = 0.5f + 0.5f * U * Y / M_PI;
V = 1.f - U; V = 1.f - U;
@@ -597,7 +606,7 @@ static int draw(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
break; break;
case 0: case 0:
Y = hypotf(src[0].re, src[0].im); Y = hypotf(src[0].re, src[0].im);
Y = remap_log(Y, iscale, log_factor); Y = remap_log(s, Y, iscale, log_factor);
dstY[0] = av_clip_uint8(lrintf(Y * 255.f)); dstY[0] = av_clip_uint8(lrintf(Y * 255.f));
if (dstA) if (dstA)