131 #define OFFSET(x) offsetof(ShowCWTContext, x)
132 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
206 for (
int n = 0; n <
s->nb_threads; n++)
212 for (
int n = 0; n <
s->nb_threads; n++)
218 for (
int n = 0; n <
s->frequency_band_count; n++)
256 int frequency_band_count,
257 float frequency_range,
258 float frequency_offset,
259 int frequency_scale,
float deviation)
264 for (
int y = 0; y < frequency_band_count; y++) {
265 float frequency = frequency_range * (1.f - (
float)y / frequency_band_count) + frequency_offset;
266 float frequency_derivative = frequency_range / frequency_band_count;
268 switch (frequency_scale) {
270 frequency =
powf(2.
f, frequency);
271 frequency_derivative *= logf(2.
f) * frequency;
274 frequency = 600.f * sinhf(frequency / 6.
f);
275 frequency_derivative *=
sqrtf(frequency * frequency + 360000.
f) / 6.f;
278 frequency = 700.f * (
powf(10.
f, frequency / 2595.
f) - 1.f);
279 frequency_derivative *= (frequency + 700.f) * logf(10.
f) / 2595.f;
282 frequency = 676170.4f / (47.06538f -
expf(frequency * 0.08950404
f)) - 14678.49
f;
283 frequency_derivative *= (frequency * frequency + 14990.4f * frequency + 4577850.f) / 160514.
f;
286 frequency = frequency * frequency;
287 frequency_derivative *= 2.f *
sqrtf(frequency);
290 frequency = frequency * frequency * frequency;
291 frequency_derivative *= 3.f *
powf(frequency, 2.
f / 3.
f);
294 frequency = frequency * frequency * frequency * frequency;
295 frequency_derivative *= 4.f *
powf(frequency, 3.
f / 4.
f);
298 frequency = 2.f *
powf(frequency, 3.
f / 2.
f) / 3.f;
299 frequency_derivative *=
sqrtf(frequency);
306 ret = 1.f / (frequency_derivative * deviation);
314 const float max =
s->maximum_intensity;
315 const float min =
s->minimum_intensity;
348 const int hop_size =
s->hop_size;
350 float *cache = (
float *)
s->cache->extended_data[ch];
353 const int offset = (
s->input_padding_size - hop_size) >> 1;
363 if (fin &&
s->hop_index + fin->
nb_samples < hop_size)
366 memset(
src, 0,
sizeof(
float) *
s->fft_size);
367 for (
int n = 0; n < hop_size; n++)
370 s->tx_fn(
s->fft[jobnr], dst,
src,
sizeof(*
src));
375 #define DRAW_BAR_COLOR(x) \
382 float mul = (Y - ht) * bh[0]; \
383 dstY[x] = av_clip_uint8(lrintf(Y * mul * 255.f)); \
384 dstU[x] = av_clip_uint8(lrintf((U-0.5f) * 128.f + 128)); \
385 dstV[x] = av_clip_uint8(lrintf((V-0.5f) * 128.f + 128)); \
390 float Y,
float U,
float V)
392 float *bh = ((
float *)
s->bh_out->extended_data[0]) + y;
393 const ptrdiff_t ylinesize =
s->outpicref->linesize[0];
394 const ptrdiff_t ulinesize =
s->outpicref->linesize[1];
395 const ptrdiff_t vlinesize =
s->outpicref->linesize[2];
396 const int direction =
s->direction;
397 const int sono_size =
s->sono_size;
398 const int bar_size =
s->bar_size;
399 const float rcp_bar_h = 1.f / bar_size;
400 uint8_t *dstY, *dstU, *dstV;
403 bh[0] = 1.f / (
Y + 0.0001f);
406 dstY =
s->outpicref->data[0] + y * ylinesize;
407 dstU =
s->outpicref->data[1] + y * ulinesize;
408 dstV =
s->outpicref->data[2] + y * vlinesize;
409 for (
int x = 0; x < bar_size; x++) {
410 float ht = (bar_size - x) * rcp_bar_h;
415 dstY =
s->outpicref->data[0] + y * ylinesize;
416 dstU =
s->outpicref->data[1] + y * ulinesize;
417 dstV =
s->outpicref->data[2] + y * vlinesize;
418 for (
int x = 0; x < bar_size; x++) {
419 float ht = x * rcp_bar_h;
424 dstY =
s->outpicref->data[0] +
w - 1 - y;
425 dstU =
s->outpicref->data[1] +
w - 1 - y;
426 dstV =
s->outpicref->data[2] +
w - 1 - y;
427 for (
int x = 0; x < bar_size; x++) {
428 float ht = (bar_size - x) * rcp_bar_h;
436 dstY =
s->outpicref->data[0] +
w - 1 - y + ylinesize * sono_size;
437 dstU =
s->outpicref->data[1] +
w - 1 - y + ulinesize * sono_size;
438 dstV =
s->outpicref->data[2] +
w - 1 - y + vlinesize * sono_size;
439 for (
int x = 0; x < bar_size; x++) {
440 float ht = x * rcp_bar_h;
453 const ptrdiff_t ylinesize =
s->outpicref->linesize[0];
454 const ptrdiff_t ulinesize =
s->outpicref->linesize[1];
455 const ptrdiff_t vlinesize =
s->outpicref->linesize[2];
456 const ptrdiff_t alinesize =
s->outpicref->linesize[3];
457 const float log_factor = 1.f/logf(
s->logarithmic_basis);
458 const int count =
s->frequency_band_count;
459 const int start = (count * jobnr) / nb_jobs;
460 const int end = (count * (jobnr+1)) / nb_jobs;
461 const int nb_channels =
s->nb_channels;
462 const int iscale =
s->intensity_scale;
463 const int ihop_index =
s->ihop_index;
464 const int ihop_size =
s->ihop_size;
465 const float rotation =
s->rotation;
466 const int direction =
s->direction;
467 uint8_t *dstY, *dstU, *dstV, *dstA;
468 const int sono_size =
s->sono_size;
469 const int bar_size =
s->bar_size;
470 const int mode =
s->mode;
471 const int w_1 =
s->w - 1;
472 const int x =
s->pos;
475 for (
int y = start; y < end; y++) {
477 0 * ihop_size + ihop_index;
485 dstY =
s->outpicref->data[0] + y * ylinesize;
486 dstU =
s->outpicref->data[1] + y * ulinesize;
487 dstV =
s->outpicref->data[2] + y * vlinesize;
488 dstA =
s->outpicref->data[3] ?
s->outpicref->data[3] + y * alinesize :
NULL;
492 dstY =
s->outpicref->data[0] + x * ylinesize + w_1 - y;
493 dstU =
s->outpicref->data[1] + x * ulinesize + w_1 - y;
494 dstV =
s->outpicref->data[2] + x * vlinesize + w_1 - y;
495 dstA =
s->outpicref->data[3] ?
s->outpicref->data[3] + x * alinesize + w_1 - y :
NULL;
505 switch (
s->direction) {
507 memmove(dstY, dstY + 1, w_1);
508 memmove(dstU, dstU + 1, w_1);
509 memmove(dstV, dstV + 1, w_1);
511 memmove(dstA, dstA + 1, w_1);
514 memmove(dstY + 1, dstY, w_1);
515 memmove(dstU + 1, dstU, w_1);
516 memmove(dstV + 1, dstV, w_1);
518 memmove(dstA + 1, dstA, w_1);
541 u = hypotf(
src[0].re,
src[0].im);
555 U = 0.5f + 0.5f * z *
u;
556 V = 0.5f + 0.5f * z * v;
572 const int nb_channels =
s->nb_channels;
573 const float yf = 1.f / nb_channels;
577 for (
int ch = 0; ch < nb_channels; ch++) {
581 z = hypotf(srcn[0].re, srcn[0].im);
585 U += z * yf *
sinf(2.
f *
M_PI * (ch * yf + rotation));
586 V += z * yf *
cosf(2.
f *
M_PI * (ch * yf + rotation));
602 Y = hypotf(
src[0].re,
src[0].im);
605 U = 0.5f + 0.5f *
U *
Y /
M_PI;
621 Y = 0.5f + 0.5f *
Y /
M_PI;
633 Y = hypotf(
src[0].re,
src[0].im);
654 const int ch = *(
int *)
arg;
658 const int output_padding_size =
s->output_padding_size;
659 const int input_padding_size =
s->input_padding_size;
660 const float scale = 1.f / input_padding_size;
661 const int ihop_size =
s->ihop_size;
662 const int count =
s->frequency_band_count;
663 const int start = (count * jobnr) / nb_jobs;
664 const int end = (count * (jobnr+1)) / nb_jobs;
666 for (
int y = start; y < end; y++) {
672 const unsigned *
index = (
const unsigned *)
s->index;
673 const int kernel_start =
s->kernel_start[y];
674 const int kernel_stop =
s->kernel_stop[y];
675 const int kernel_range = kernel_stop - kernel_start + 1;
678 if (kernel_start >= 0) {
680 memcpy(srcx, fft_out + kernel_start,
sizeof(*fft_out) * kernel_range);
683 memcpy(srcx+
offset, fft_out,
sizeof(*fft_out) * (kernel_range-
offset));
684 memcpy(srcx, fft_out+input_padding_size-
offset,
sizeof(*fft_out)*
offset);
687 s->fdsp->vector_fmul_scalar((
float *)srcx, (
const float *)srcx,
scale,
FFALIGN(kernel_range * 2, 4));
688 s->fdsp->vector_fmul((
float *)dstx, (
const float *)srcx,
689 (
const float *)kernel,
FFALIGN(kernel_range * 2, 16));
691 memset(isrc, 0,
sizeof(*isrc) * output_padding_size);
693 const unsigned *kindex =
index + kernel_start;
694 for (
int i = 0;
i < kernel_range;
i++) {
695 const unsigned n = kindex[
i];
697 isrc[n].re += dstx[
i].re;
698 isrc[n].im += dstx[
i].im;
701 for (
int i = 0;
i < kernel_range;
i++) {
702 const unsigned n = (
i-kernel_start) & (output_padding_size-1);
704 isrc[n].re += dstx[
i].re;
705 isrc[n].im += dstx[
i].im;
709 s->itx_fn(
s->ifft[jobnr], idst, isrc,
sizeof(*isrc));
711 memcpy(chout, idst,
sizeof(*chout) * ihop_size);
712 for (
int n = 0; n < ihop_size; n++) {
713 chout[n].
re += over[n].
re;
714 chout[n].
im += over[n].
im;
716 memcpy(over, idst + ihop_size,
sizeof(*over) * ihop_size);
725 const int size =
s->input_padding_size;
726 const int output_sample_count =
s->output_sample_count;
727 const int fsize =
s->frequency_band_count;
728 int *kernel_start =
s->kernel_start;
729 int *kernel_stop =
s->kernel_stop;
730 unsigned *
index =
s->index;
731 int range_min = INT_MAX;
732 int range_max = 0,
ret = 0;
739 for (
int y = 0; y <
fsize; y++) {
741 int start = INT_MIN, stop = INT_MAX;
742 const float frequency =
s->frequency_band[y*2];
743 const float deviation = 1.f / (
s->frequency_band[y*2+1] *
744 output_sample_count);
749 memset(tkernel, 0,
size *
sizeof(*tkernel));
750 for (
int n =
a; n <
b; n++) {
751 float ff,
f = n+0.5f-frequency;
753 ff =
expf(-
f*
f*deviation);
754 tkernel[n+
range] = ff;
757 for (
int n =
a; n <
b; n++) {
758 if (tkernel[n+
range] != 0.
f) {
759 if (tkernel[n+
range] > FLT_MIN)
766 for (
int n =
b; n >=
a; n--) {
767 if (tkernel[n+
range] != 0.
f) {
768 if (tkernel[n+
range] > FLT_MIN)
775 if (start == INT_MIN || stop == INT_MAX) {
780 kernel_start[y] = start;
781 kernel_stop[y] = stop;
789 for (
int n = 0; n <= stop - start; n++) {
790 kernel[n].
re = tkernel[n+
range+start];
791 kernel[n].
im = tkernel[n+
range+start];
794 range_min =
FFMIN(range_min, stop+1-start);
795 range_max =
FFMAX(range_max, stop+1-start);
797 s->kernel[y] = kernel;
800 for (
int n = 0; n <
size; n++)
801 index[n] = n & (
s->output_padding_size - 1);
816 const float limit_frequency =
inlink->sample_rate * 0.5f;
817 float maximum_frequency =
fminf(
s->maximum_frequency, limit_frequency);
818 float minimum_frequency =
s->minimum_frequency;
822 if (minimum_frequency >= maximum_frequency) {
824 minimum_frequency, maximum_frequency);
834 switch (
s->direction) {
837 s->bar_size =
s->w *
s->bar_ratio;
838 s->sono_size =
s->w -
s->bar_size;
839 s->frequency_band_count =
s->h;
843 s->bar_size =
s->h *
s->bar_ratio;
844 s->sono_size =
s->h -
s->bar_size;
845 s->frequency_band_count =
s->w;
849 switch (
s->frequency_scale) {
851 minimum_frequency = logf(minimum_frequency) / logf(2.
f);
852 maximum_frequency = logf(maximum_frequency) / logf(2.
f);
855 minimum_frequency = 6.f * asinhf(minimum_frequency / 600.
f);
856 maximum_frequency = 6.f * asinhf(maximum_frequency / 600.
f);
859 minimum_frequency = 2595.f *
log10f(1.
f + minimum_frequency / 700.
f);
860 maximum_frequency = 2595.f *
log10f(1.
f + maximum_frequency / 700.
f);
863 minimum_frequency = 11.17268f * logf(1.
f + (46.06538
f * minimum_frequency) / (minimum_frequency + 14678.49
f));
864 maximum_frequency = 11.17268f * logf(1.
f + (46.06538
f * maximum_frequency) / (maximum_frequency + 14678.49
f));
867 minimum_frequency =
sqrtf(minimum_frequency);
868 maximum_frequency =
sqrtf(maximum_frequency);
871 minimum_frequency =
cbrtf(minimum_frequency);
872 maximum_frequency =
cbrtf(maximum_frequency);
875 minimum_frequency =
powf(minimum_frequency, 0.25
f);
876 maximum_frequency =
powf(maximum_frequency, 0.25
f);
879 minimum_frequency =
powf(9.
f * (minimum_frequency * minimum_frequency) / 4.
f, 1.
f / 3.
f);
880 maximum_frequency =
powf(9.
f * (maximum_frequency * maximum_frequency) / 4.
f, 1.
f / 3.
f);
884 s->frequency_band =
av_calloc(
s->frequency_band_count,
885 sizeof(*
s->frequency_band) * 2);
886 if (!
s->frequency_band)
889 s->nb_consumed_samples =
inlink->sample_rate *
891 s->frequency_band_count, maximum_frequency - minimum_frequency,
892 minimum_frequency,
s->frequency_scale,
s->deviation);
893 s->nb_consumed_samples =
FFMIN(
s->nb_consumed_samples, 65536);
896 s->nb_channels =
inlink->ch_layout.nb_channels;
900 s->input_sample_count = 1 << (32 -
ff_clz(
s->nb_consumed_samples));
901 s->input_padding_size = 1 << (32 -
ff_clz(
s->input_sample_count));
903 s->output_padding_size = 1 << (32 -
ff_clz(
s->output_sample_count));
905 s->hop_size =
s->input_sample_count;
906 s->ihop_size =
s->output_padding_size >> 1;
919 for (
int n = 0; n <
s->nb_threads; n++) {
929 for (
int n = 0; n <
s->nb_threads; n++) {
940 s->kernel =
av_calloc(
s->frequency_band_count,
sizeof(*
s->kernel));
947 s->index =
av_calloc(
s->input_padding_size,
sizeof(*
s->index));
948 s->kernel_start =
av_calloc(
s->frequency_band_count,
sizeof(*
s->kernel_start));
949 s->kernel_stop =
av_calloc(
s->frequency_band_count,
sizeof(*
s->kernel_stop));
950 if (!
s->outpicref || !
s->fft_in || !
s->fft_out || !
s->src_x || !
s->dst_x || !
s->over ||
951 !
s->ifft_in || !
s->ifft_out || !
s->kernel_start || !
s->kernel_stop || !
s->ch_out ||
952 !
s->cache || !
s->index || !
s->bh_out || !
s->kernel)
955 s->ch_out->format =
inlink->format;
956 s->ch_out->nb_samples = 2 *
s->ihop_size *
inlink->ch_layout.nb_channels;
957 s->ch_out->ch_layout.nb_channels =
s->frequency_band_count;
962 s->ifft_in->format =
inlink->format;
963 s->ifft_in->nb_samples =
s->ifft_size * 2;
964 s->ifft_in->ch_layout.nb_channels =
s->nb_threads;
969 s->ifft_out->format =
inlink->format;
970 s->ifft_out->nb_samples =
s->ifft_size * 2;
971 s->ifft_out->ch_layout.nb_channels =
s->nb_threads;
976 s->src_x->format =
inlink->format;
977 s->src_x->nb_samples =
s->fft_size * 2;
978 s->src_x->ch_layout.nb_channels =
s->nb_threads;
983 s->dst_x->format =
inlink->format;
984 s->dst_x->nb_samples =
s->fft_size * 2;
985 s->dst_x->ch_layout.nb_channels =
s->nb_threads;
990 s->outpicref->sample_aspect_ratio = (
AVRational){1,1};
992 for (
int y = 0; y < outlink->
h; y++) {
993 memset(
s->outpicref->data[0] + y *
s->outpicref->linesize[0], 0, outlink->
w);
994 memset(
s->outpicref->data[1] + y *
s->outpicref->linesize[1], 128, outlink->
w);
995 memset(
s->outpicref->data[2] + y *
s->outpicref->linesize[2], 128, outlink->
w);
996 if (
s->outpicref->data[3])
997 memset(
s->outpicref->data[3] + y *
s->outpicref->linesize[3], 0, outlink->
w);
1003 for (
int n = 0; n <
s->frequency_band_count; n++) {
1004 s->frequency_band[2*n ] *=
factor;
1005 s->frequency_band[2*n+1] *=
factor;
1017 switch (
s->direction) {
1020 s->pos =
s->bar_size;
1024 s->pos =
s->sono_size;
1029 if (strcmp(
s->rate_str,
"auto")) {
1032 s->frame_rate =
s->auto_frame_rate;
1049 const int nb_planes = 3 + (
s->outpicref->data[3] !=
NULL);
1054 switch (
s->direction) {
1056 for (
int p = 0; p < nb_planes; p++) {
1057 ptrdiff_t linesize =
s->outpicref->linesize[p];
1059 for (
int y =
s->h - 1; y >
s->bar_size; y--) {
1060 uint8_t *dst =
s->outpicref->data[p] + y * linesize;
1062 memmove(dst, dst - linesize,
s->w);
1067 for (
int p = 0; p < nb_planes; p++) {
1068 ptrdiff_t linesize =
s->outpicref->linesize[p];
1070 for (
int y = 0; y <
s->sono_size; y++) {
1071 uint8_t *dst =
s->outpicref->data[p] + y * linesize;
1073 memmove(dst, dst + linesize,
s->w);
1086 switch (
s->direction) {
1089 if (
s->pos >=
s->w) {
1090 s->pos =
s->bar_size;
1097 s->pos =
s->sono_size;
1103 if (
s->pos >=
s->h) {
1104 s->pos =
s->bar_size;
1111 s->pos =
s->sono_size;
1118 switch (
s->direction) {
1121 s->pos =
s->bar_size;
1125 s->pos =
s->sono_size;
1132 switch (
s->direction) {
1134 for (
int p = 0; p < nb_planes; p++) {
1135 ptrdiff_t linesize =
s->outpicref->linesize[p];
1136 const int size =
s->w -
s->pos;
1137 const int fill = p > 0 && p < 3 ? 128 : 0;
1138 const int x =
s->pos;
1140 for (
int y = 0; y <
s->h; y++) {
1141 uint8_t *dst =
s->outpicref->data[p] + y * linesize + x;
1143 memset(dst, fill,
size);
1148 for (
int p = 0; p < nb_planes; p++) {
1149 ptrdiff_t linesize =
s->outpicref->linesize[p];
1150 const int size =
s->w -
s->pos;
1151 const int fill = p > 0 && p < 3 ? 128 : 0;
1153 for (
int y = 0; y <
s->h; y++) {
1154 uint8_t *dst =
s->outpicref->data[p] + y * linesize;
1156 memset(dst, fill,
size);
1161 for (
int p = 0; p < nb_planes; p++) {
1162 ptrdiff_t linesize =
s->outpicref->linesize[p];
1163 const int fill = p > 0 && p < 3 ? 128 : 0;
1165 for (
int y =
s->pos; y < s->
h; y++) {
1166 uint8_t *dst =
s->outpicref->data[p] + y * linesize;
1168 memset(dst, fill,
s->w);
1173 for (
int p = 0; p < nb_planes; p++) {
1174 ptrdiff_t linesize =
s->outpicref->linesize[p];
1175 const int fill = p > 0 && p < 3 ? 128 : 0;
1177 for (
int y =
s->h -
s->pos; y >= 0; y--) {
1178 uint8_t *dst =
s->outpicref->data[p] + y * linesize;
1180 memset(dst, fill,
s->w);
1190 int64_t pts_offset =
s->new_frame ? 0LL :
av_rescale(
s->ihop_index,
s->hop_size,
s->ihop_size);
1191 const int offset = (
s->input_padding_size -
s->hop_size) >> 1;
1195 s->outpicref->duration = 1;
1199 if (
s->ihop_index >=
s->ihop_size)
1200 s->ihop_index =
s->hop_index = 0;
1205 if (
s->old_pts <
s->outpicref->pts) {
1215 s->old_pts =
s->outpicref->pts;
1231 const int count =
s->nb_channels;
1232 const int start = (count * jobnr) / nb_jobs;
1233 const int end = (count * (jobnr+1)) / nb_jobs;
1235 for (
int ch = start; ch < end; ch++)
1254 if (
s->hop_index <
s->hop_size) {
1261 if (
ret > 0 ||
s->eof) {
1263 FFMIN(
s->nb_threads,
s->nb_channels));
1265 if (
s->hop_index == 0) {
1266 s->in_pts = fin->
pts;
1273 s->hop_index =
s->hop_size;
1278 if (
s->hop_index >=
s->hop_size ||
s->ihop_index > 0) {
1279 for (
int ch = 0; ch <
s->nb_channels &&
s->ihop_index == 0; ch++) {
1307 s->hop_index >=
s->hop_size ||
s->eof) {
1330 .description =
NULL_IF_CONFIG_SMALL(
"Convert input audio to a CWT (Continuous Wavelet Transform) spectrum video output."),
1337 .priv_class = &showcwt_class,