34 #if CONFIG_LIBFREETYPE
36 #include FT_FREETYPE_H
39 #if CONFIG_LIBFONTCONFIG
40 #include <fontconfig/fontconfig.h>
45 #define BASEFREQ 20.01523126408007475
46 #define ENDFREQ 20495.59681441799654
47 #define TLENGTH "384*tc/(384+tc*f)"
48 #define TLENGTH_MIN 0.001
49 #define VOLUME_MAX 100.0
50 #define FONTCOLOR "st(0, (midi(f)-59.5)/12);" \
51 "st(1, if(between(ld(0),0,1), 0.5-0.5*cos(2*PI*ld(0)), 0));" \
52 "r(1-ld(1)) + b(ld(1))"
53 #define CSCHEME "1|0.5|0|0|0.5|1"
55 #define PTS_TOLERANCE 1
57 #define OFFSET(x) offsetof(ShowCQTContext, x)
58 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
115 av_log(
s->ctx,
level,
"fft_time = %16.3f s.\n",
s->fft_time * 1e-6);
117 av_log(
s->ctx,
level,
"cqt_time = %16.3f s.\n",
s->cqt_time * 1e-6);
118 if (
s->process_cqt_time)
119 av_log(
s->ctx,
level,
"process_cqt_time = %16.3f s.\n",
s->process_cqt_time * 1e-6);
120 if (
s->update_sono_time)
121 av_log(
s->ctx,
level,
"update_sono_time = %16.3f s.\n",
s->update_sono_time * 1e-6);
123 av_log(
s->ctx,
level,
"alloc_time = %16.3f s.\n",
s->alloc_time * 1e-6);
125 av_log(
s->ctx,
level,
"bar_time = %16.3f s.\n",
s->bar_time * 1e-6);
127 av_log(
s->ctx,
level,
"axis_time = %16.3f s.\n",
s->axis_time * 1e-6);
129 av_log(
s->ctx,
level,
"sono_time = %16.3f s.\n",
s->sono_time * 1e-6);
131 plot_time =
s->fft_time +
s->cqt_time +
s->process_cqt_time +
s->update_sono_time
132 +
s->alloc_time +
s->bar_time +
s->axis_time +
s->sono_time;
134 av_log(
s->ctx,
level,
"plot_time = %16.3f s.\n", plot_time * 1e-6);
136 s->fft_time =
s->cqt_time =
s->process_cqt_time =
s->update_sono_time
137 =
s->alloc_time =
s->bar_time =
s->axis_time =
s->sono_time = 0;
139 if (
s->axis_frame && !
s->axis_frame->buf[0]) {
141 for (k = 0; k < 4; k++)
142 s->axis_frame->data[k] =
NULL;
150 for (k = 0; k <
s->cqt_len; k++)
167 double log_base, log_end;
168 double rcp_n = 1.0 / n;
176 log_base = log(
base);
178 for (x = 0; x < n; x++) {
179 double log_freq = log_base + (x + 0.5) * (log_end - log_base) * rcp_n;
180 freq[x] =
exp(log_freq);
187 double nan_replace,
int idx)
191 av_log(log_ctx,
level,
"[%d] %s is nan, setting it to %g.\n",
192 idx,
name, nan_replace);
195 av_log(log_ctx,
level,
"[%d] %s is too low (%g), setting it to %g.\n",
199 av_log(log_ctx,
level,
"[%d] %s it too high (%g), setting it to %g.\n",
208 double ret = 12200.0*12200.0 * (
f*
f*
f*
f);
209 ret /= (
f*
f + 20.6*20.6) * (
f*
f + 12200.0*12200.0) *
210 sqrt((
f*
f + 107.7*107.7) * (
f*
f + 737.9*737.9));
216 double ret = 12200.0*12200.0 * (
f*
f*
f);
217 ret /= (
f*
f + 20.6*20.6) * (
f*
f + 12200.0*12200.0) * sqrt(
f*
f + 158.5*158.5);
223 double ret = 12200.0*12200.0 * (
f*
f);
224 ret /= (
f*
f + 20.6*20.6) * (
f*
f + 12200.0*12200.0);
230 const char *func_names[] = {
"a_weighting",
"b_weighting",
"c_weighting",
NULL };
231 const char *sono_names[] = {
"timeclamp",
"tc",
"frequency",
"freq",
"f",
"bar_v",
NULL };
232 const char *bar_names[] = {
"timeclamp",
"tc",
"frequency",
"freq",
"f",
"sono_v",
NULL };
239 if (!
s->sono_v_buf || !
s->bar_v_buf)
248 for (x = 0; x <
s->cqt_len; x++) {
249 double vars[] = {
s->timeclamp,
s->timeclamp,
s->freq[x],
s->freq[x],
s->freq[x], 0.0 };
253 s->bar_v_buf[x] = vol * vol;
256 s->sono_v_buf[x] = vol * vol;
271 int len,
int fft_len)
274 for (k = 0; k <
len; k++) {
277 for (x = 0; x < coeffs[k].
len; x++) {
283 b.re +=
u *
src[j].re;
284 b.im +=
u *
src[j].im;
293 dst[k].
im =
r.re *
r.re +
r.im *
r.im;
299 const char *
var_names[] = {
"timeclamp",
"tc",
"frequency",
"freq",
"f",
NULL };
301 int rate =
s->ctx->inputs[0]->sample_rate;
302 int nb_cqt_coeffs = 0;
309 if (!(
s->coeffs =
av_calloc(
s->cqt_len,
sizeof(*
s->coeffs))))
312 for (k = 0; k <
s->cqt_len; k++) {
313 double vars[] = {
s->timeclamp,
s->timeclamp,
s->freq[k],
s->freq[k],
s->freq[k] };
314 double flen, center, tlength;
315 int start, end, m = k;
317 if (
s->freq[k] > 0.5 * rate)
322 flen = 8.0 *
s->fft_len / (tlength * rate);
323 center =
s->freq[k] *
s->fft_len / rate;
324 start =
FFMAX(0,
ceil(center - 0.5 * flen));
325 end =
FFMIN(
s->fft_len,
floor(center + 0.5 * flen));
327 s->coeffs[m].start = start & ~(
s->cqt_align - 1);
328 s->coeffs[m].len = (end | (
s->cqt_align - 1)) + 1 -
s->coeffs[m].start;
329 nb_cqt_coeffs +=
s->coeffs[m].len;
330 if (!(
s->coeffs[m].val =
av_calloc(
s->coeffs[m].len,
sizeof(*
s->coeffs[m].val))))
333 for (x = start; x <= end; x++) {
334 int sign = (x & 1) ? (-1) : 1;
335 double y = 2.0 *
M_PI * (x - center) * (1.0 / flen);
337 double w = 0.355768 + 0.487396 * cos(y) + 0.144232 * cos(2*y) + 0.012604 * cos(3*y);
338 w *= sign * (1.0 /
s->fft_len);
339 s->coeffs[m].val[x -
s->coeffs[m].start] =
w;
342 if (
s->permute_coeffs)
343 s->permute_coeffs(
s->coeffs[m].val,
s->coeffs[m].len);
353 for (k = 0; k <
s->cqt_len; k++)
373 memset(
out->data[0], 0,
out->linesize[0] *
h);
376 memset(
out->data[0], 16,
out->linesize[0] *
h);
377 memset(
out->data[1], 128,
out->linesize[1] * hh);
378 memset(
out->data[2], 128,
out->linesize[2] * hh);
380 memset(
out->data[3], 0,
out->linesize[3] *
h);
408 int tmp_w, tmp_h, ret;
410 if ((ret =
ff_load_image(tmp_data, tmp_linesize, &tmp_w, &tmp_h, &tmp_format,
411 s->axisfile,
s->ctx)) < 0)
418 if ((ret =
ff_scale_image(
s->axis_frame->data,
s->axis_frame->linesize,
s->width,
s->axis_h,
420 tmp_format,
s->ctx)) < 0)
423 s->axis_frame->width =
s->width;
424 s->axis_frame->height =
s->axis_h;
435 static double midi(
void *p,
double f)
437 return log2(
f/440.0) * 12.0 + 69.0;
443 return lrint(x*255.0) << 16;
449 return lrint(x*255.0) << 8;
455 return lrint(x*255.0);
460 const char *
var_names[] = {
"timeclamp",
"tc",
"frequency",
"freq",
"f",
NULL };
461 const char *func_names[] = {
"midi",
"r",
"g",
"b",
NULL };
467 int step =
half ? 2 : 1;
470 av_log(
s->ctx,
AV_LOG_WARNING,
"font axis rendering is not implemented in non-default frequency range,"
471 " please use axisfile option instead.\n");
475 if (
s->cqt_len == 1920)
486 for (x = 0,
xs = 0; x <
width; x++,
xs += step) {
487 double vars[] = {
s->timeclamp,
s->timeclamp, freq[
xs], freq[
xs], freq[
xs] };
491 int linesize =
tmp->linesize[0];
492 for (y = 0; y <
height; y++) {
493 data[linesize * y + 4 * x] =
r;
494 data[linesize * y + 4 * x + 1] =
g;
495 data[linesize * y + 4 * x + 2] =
b;
507 #if CONFIG_LIBFREETYPE
508 const char *
str =
"EF G A BC D ";
510 int linesize =
tmp->linesize[0];
511 FT_Library lib =
NULL;
513 int font_width = 16, font_height = 32;
514 int font_repeat = font_width * 12;
515 int linear_hori_advance = font_width * 65536;
516 int non_monospace_warning = 0;
522 if (FT_Init_FreeType(&lib))
525 if (FT_New_Face(lib, fontfile, 0, &face))
528 if (FT_Set_Char_Size(face, 16*64, 0, 0, 0))
531 if (FT_Load_Char(face,
'A', FT_LOAD_RENDER))
534 if (FT_Set_Char_Size(face, 16*64 * linear_hori_advance / face->glyph->linearHoriAdvance, 0, 0, 0))
537 for (x = 0; x < 12; x++) {
538 int sx, sy, rx, bx, by, dx, dy;
543 if (FT_Load_Char(face,
str[x], FT_LOAD_RENDER))
546 if (face->glyph->advance.x != font_width*64 && !non_monospace_warning) {
548 non_monospace_warning = 1;
551 sy = font_height - 8 - face->glyph->bitmap_top;
552 for (rx = 0; rx < 10; rx++) {
553 sx = rx * font_repeat + x * font_width + face->glyph->bitmap_left;
554 for (by = 0; by < face->glyph->bitmap.rows; by++) {
558 if (dy >= font_height)
561 for (bx = 0; bx < face->glyph->bitmap.width; bx++) {
567 data[dy*linesize+4*dx+3] = face->glyph->bitmap.buffer[by*face->glyph->bitmap.width+bx];
574 FT_Done_FreeType(lib);
580 FT_Done_FreeType(lib);
591 #if CONFIG_LIBFONTCONFIG
592 FcConfig *fontconfig;
593 FcPattern *pat, *best;
594 FcResult result = FcResultMatch;
601 for (
i = 0; font[
i];
i++) {
606 if (!(fontconfig = FcInitLoadConfigAndFonts())) {
611 if (!(pat = FcNameParse((
uint8_t *)font))) {
613 FcConfigDestroy(fontconfig);
617 FcDefaultSubstitute(pat);
619 if (!FcConfigSubstitute(fontconfig, pat, FcMatchPattern)) {
621 FcPatternDestroy(pat);
622 FcConfigDestroy(fontconfig);
626 best = FcFontMatch(fontconfig, pat, &result);
627 FcPatternDestroy(pat);
630 if (!best || result != FcResultMatch) {
635 if (FcPatternGetString(best, FC_FILE, 0, (FcChar8 **)&filename) != FcResultMatch) {
643 FcPatternDestroy(best);
644 FcConfigDestroy(fontconfig);
655 const char *
str =
"EF G A BC D ";
658 int linesize =
tmp->linesize[0];
663 for (
u = 0;
u < 12;
u++) {
664 for (v = 0; v <
height; v++) {
684 int default_font = 0;
703 if ((ret =
ff_scale_image(
s->axis_frame->data,
s->axis_frame->linesize,
s->width,
s->axis_h,
709 s->axis_frame->width =
s->width;
710 s->axis_frame->height =
s->axis_h;
729 return sqrtf(sqrtf(v));
730 return expf(logf(v) /
g);
736 for (x = 0; x <
len; x++) {
746 for (x = 0; x <
len; x++) {
751 c[x].yuv.y =
cm[0][0] *
r +
cm[0][1] *
g +
cm[0][2] *
b;
752 c[x].yuv.u =
cm[1][0] *
r +
cm[1][1] *
g +
cm[1][2] *
b;
753 c[x].yuv.v =
cm[2][0] *
r +
cm[2][1] *
g +
cm[2][2] *
b;
760 int x, y,
w =
out->width;
761 float mul, ht, rcp_bar_h = 1.0f / bar_h, rcp_bar_t = 1.0f / bar_t;
763 int ls =
out->linesize[0];
765 for (y = 0; y < bar_h; y++) {
766 ht = (bar_h - y) * rcp_bar_h;
768 for (x = 0; x <
w; x++) {
774 mul = (
h[x] - ht) * rcp_h[x];
775 mul = (
mul < bar_t) ? (
mul * rcp_bar_t) : 1.0f;
784 #define DRAW_BAR_WITH_CHROMA(x) \
791 mul = (h[x] - ht) * rcp_h[x]; \
792 mul = (mul < bar_t) ? (mul * rcp_bar_t) : 1.0f; \
793 *lpy++ = lrintf(mul * c[x].yuv.y + 16.0f); \
794 *lpu++ = lrintf(mul * c[x].yuv.u + 128.0f); \
795 *lpv++ = lrintf(mul * c[x].yuv.v + 128.0f); \
799 #define DRAW_BAR_WITHOUT_CHROMA(x) \
804 mul = (h[x] - ht) * rcp_h[x]; \
805 mul = (mul < bar_t) ? (mul * rcp_bar_t) : 1.0f; \
806 *lpy++ = lrintf(mul * c[x].yuv.y + 16.0f); \
813 int x, y, yh,
w =
out->width;
814 float mul, ht, rcp_bar_h = 1.0f / bar_h, rcp_bar_t = 1.0f / bar_t;
817 int lsy =
out->linesize[0], lsu =
out->linesize[1], lsv =
out->linesize[2];
818 int fmt =
out->format;
820 for (y = 0; y < bar_h; y += 2) {
822 ht = (bar_h - y) * rcp_bar_h;
827 for (x = 0; x <
w; x += 2) {
832 for (x = 0; x <
w; x += 2) {
838 ht = (bar_h - (y+1)) * rcp_bar_h;
839 lpy = vy + (y+1) * lsy;
840 lpu = vu + (y+1) * lsu;
841 lpv = vv + (y+1) * lsv;
843 for (x = 0; x <
w; x += 2) {
848 for (x = 0; x <
w; x += 2) {
853 for (x = 0; x <
w; x += 2) {
864 float a, rcp_255 = 1.0f / 255.0f;
867 for (y = 0; y <
h; y++) {
868 lp =
out->data[0] + (off + y) *
out->linesize[0];
870 for (x = 0; x <
w; x++) {
875 }
else if (lpa[3] == 255) {
880 a = rcp_255 * lpa[3];
890 #define BLEND_WITH_CHROMA(c) \
893 *lpy = lrintf(c.yuv.y + 16.0f); \
894 *lpu = lrintf(c.yuv.u + 128.0f); \
895 *lpv = lrintf(c.yuv.v + 128.0f); \
896 } else if (255 == *lpaa) { \
901 float a = (1.0f/255.0f) * (*lpaa); \
902 *lpy = lrintf(a * (*lpay) + (1.0f - a) * (c.yuv.y + 16.0f)); \
903 *lpu = lrintf(a * (*lpau) + (1.0f - a) * (c.yuv.u + 128.0f)); \
904 *lpv = lrintf(a * (*lpav) + (1.0f - a) * (c.yuv.v + 128.0f)); \
906 lpy++; lpu++; lpv++; \
907 lpay++; lpau++; lpav++; lpaa++; \
910 #define BLEND_WITHOUT_CHROMA(c, alpha_inc) \
913 *lpy = lrintf(c.yuv.y + 16.0f); \
914 } else if (255 == *lpaa) { \
917 float a = (1.0f/255.0f) * (*lpaa); \
918 *lpy = lrintf(a * (*lpay) + (1.0f - a) * (c.yuv.y + 16.0f)); \
921 lpay++; lpaa += alpha_inc; \
924 #define BLEND_CHROMA2(c) \
926 if (!lpaa[0] && !lpaa[1]) { \
927 *lpu = lrintf(c.yuv.u + 128.0f); \
928 *lpv = lrintf(c.yuv.v + 128.0f); \
929 } else if (255 == lpaa[0] && 255 == lpaa[1]) { \
930 *lpu = *lpau; *lpv = *lpav; \
932 float a0 = (0.5f/255.0f) * lpaa[0]; \
933 float a1 = (0.5f/255.0f) * lpaa[1]; \
934 float b = 1.0f - a0 - a1; \
935 *lpu = lrintf(a0 * lpau[0] + a1 * lpau[1] + b * (c.yuv.u + 128.0f)); \
936 *lpv = lrintf(a0 * lpav[0] + a1 * lpav[1] + b * (c.yuv.v + 128.0f)); \
938 lpau += 2; lpav += 2; lpaa++; lpu++; lpv++; \
941 #define BLEND_CHROMA2x2(c) \
943 if (!lpaa[0] && !lpaa[1] && !lpaa[lsaa] && !lpaa[lsaa+1]) { \
944 *lpu = lrintf(c.yuv.u + 128.0f); \
945 *lpv = lrintf(c.yuv.v + 128.0f); \
946 } else if (255 == lpaa[0] && 255 == lpaa[1] && \
947 255 == lpaa[lsaa] && 255 == lpaa[lsaa+1]) { \
948 *lpu = *lpau; *lpv = *lpav; \
950 float a0 = (0.25f/255.0f) * lpaa[0]; \
951 float a1 = (0.25f/255.0f) * lpaa[1]; \
952 float a2 = (0.25f/255.0f) * lpaa[lsaa]; \
953 float a3 = (0.25f/255.0f) * lpaa[lsaa+1]; \
954 float b = 1.0f - a0 - a1 - a2 - a3; \
955 *lpu = lrintf(a0 * lpau[0] + a1 * lpau[1] + a2 * lpau[lsau] + a3 * lpau[lsau+1] \
956 + b * (c.yuv.u + 128.0f)); \
957 *lpv = lrintf(a0 * lpav[0] + a1 * lpav[1] + a2 * lpav[lsav] + a3 * lpav[lsav+1] \
958 + b * (c.yuv.v + 128.0f)); \
960 lpau += 2; lpav += 2; lpaa++; lpu++; lpv++; \
969 int lsy =
out->linesize[0], lsu =
out->linesize[1], lsv =
out->linesize[2];
971 uint8_t *lpy, *lpu, *lpv, *lpay, *lpau, *lpav, *lpaa;
973 for (y = 0; y <
h; y += 2) {
975 lpy = vy + (off + y) * lsy;
976 lpu = vu + (offh + yh) * lsu;
977 lpv = vv + (offh + yh) * lsv;
978 lpay = vay + y * lsay;
979 lpau = vau + y * lsau;
980 lpav = vav + y * lsav;
981 lpaa = vaa + y * lsaa;
983 for (x = 0; x <
w; x += 2) {
988 for (x = 0; x <
w; x += 2) {
994 for (x = 0; x <
w; x += 2) {
1001 lpy = vy + (off + y + 1) * lsy;
1002 lpu = vu + (off + y + 1) * lsu;
1003 lpv = vv + (off + y + 1) * lsv;
1004 lpay = vay + (y + 1) * lsay;
1005 lpau = vau + (y + 1) * lsau;
1006 lpav = vav + (y + 1) * lsav;
1007 lpaa = vaa + (y + 1) * lsaa;
1009 for (x = 0; x <
w; x += 2) {
1014 for (x = 0; x <
w; x += 2) {
1020 for (x = 0; x <
w; x += 2) {
1037 for (y = 0; y <
h; y++) {
1038 memcpy(
out->data[0] + (off + y) *
out->linesize[0],
1042 for (
i = 1;
i < nb_planes;
i++) {
1044 for (y = 0; y <
h; y += inc) {
1046 memcpy(
out->data[
i] + (offh + yh) *
out->linesize[
i],
1057 for (x = 0; x <
w; x++) {
1071 for (x = 0; x <
w; x += 2) {
1072 *lpy++ =
lrintf(
c[x].yuv.y + 16.0f);
1073 *lpu++ =
lrintf(
c[x].yuv.u + 128.0f);
1074 *lpv++ =
lrintf(
c[x].yuv.v + 128.0f);
1075 *lpy++ =
lrintf(
c[x+1].yuv.y + 16.0f);
1077 *lpu++ =
lrintf(
c[x+1].yuv.u + 128.0f);
1078 *lpv++ =
lrintf(
c[x+1].yuv.v + 128.0f);
1086 if (!
s->sono_count) {
1087 for (x = 0; x <
s->cqt_len; x++) {
1088 s->h_buf[x] =
s->bar_v_buf[x] * 0.5f * (
s->cqt_result[x].re +
s->cqt_result[x].im);
1090 if (
s->fcount > 1) {
1091 float rcp_fcount = 1.0f /
s->fcount;
1092 for (x = 0; x <
s->width; x++) {
1094 for (
i = 0;
i <
s->fcount;
i++)
1095 h +=
s->h_buf[
s->fcount * x +
i];
1096 s->h_buf[x] = rcp_fcount *
h;
1099 for (x = 0; x <
s->width; x++) {
1101 s->rcp_h_buf[x] = 1.0f / (
s->h_buf[x] + 0.0001f);
1105 for (x = 0; x <
s->cqt_len; x++) {
1106 s->cqt_result[x].re *=
s->sono_v_buf[x];
1107 s->cqt_result[x].im *=
s->sono_v_buf[x];
1110 if (
s->fcount > 1) {
1111 float rcp_fcount = 1.0f /
s->fcount;
1112 for (x = 0; x <
s->width; x++) {
1114 for (
i = 0;
i <
s->fcount;
i++) {
1115 result.
re +=
s->cqt_result[
s->fcount * x +
i].re;
1116 result.
im +=
s->cqt_result[
s->fcount * x +
i].im;
1118 s->cqt_result[x].re = rcp_fcount * result.
re;
1119 s->cqt_result[x].im = rcp_fcount * result.
im;
1126 yuv_from_cqt(
s->c_buf,
s->cqt_result,
s->sono_g,
s->width,
s->cmatrix,
s->cscheme_v);
1135 #define UPDATE_TIME(t) \
1136 cur_time = av_gettime_relative(); \
1137 t += cur_time - last_time; \
1138 last_time = cur_time
1142 memcpy(
s->fft_result,
s->fft_data,
s->fft_len *
sizeof(*
s->fft_data));
1143 if (
s->attack_data) {
1145 for (k = 0; k <
s->remaining_fill_max; k++) {
1146 s->fft_result[
s->fft_len/2+k].re *=
s->attack_data[k];
1147 s->fft_result[
s->fft_len/2+k].im *=
s->attack_data[k];
1153 s->fft_result[
s->fft_len] =
s->fft_result[0];
1156 s->cqt_calc(
s->cqt_result,
s->fft_result,
s->coeffs,
s->cqt_len,
s->fft_len);
1163 s->update_sono(
s->sono_frame,
s->c_buf,
s->sono_idx);
1167 if (!
s->sono_count) {
1173 out->colorspace =
s->csp;
1177 s->draw_bar(
out,
s->h_buf,
s->rcp_h_buf,
s->c_buf,
s->bar_h,
s->bar_t);
1182 s->draw_axis(
out,
s->axis_frame,
s->c_buf,
s->bar_h);
1187 s->draw_sono(
out,
s->sono_frame,
s->bar_h +
s->axis_h,
s->sono_idx);
1190 out->pts =
s->next_pts;
1193 s->sono_count = (
s->sono_count + 1) %
s->count;
1195 s->sono_idx = (
s->sono_idx +
s->sono_h - 1) %
s->sono_h;
1211 kr = 0.299; kb = 0.114;
break;
1213 kr = 0.2126; kb = 0.0722;
break;
1215 kr = 0.30; kb = 0.11;
break;
1217 kr = 0.212; kb = 0.087;
break;
1219 kr = 0.2627; kb = 0.0593;
break;
1223 s->cmatrix[0][0] = 219.0 * kr;
1224 s->cmatrix[0][1] = 219.0 * kg;
1225 s->cmatrix[0][2] = 219.0 * kb;
1226 s->cmatrix[1][0] = -112.0 * kr / (1.0 - kb);
1227 s->cmatrix[1][1] = -112.0 * kg / (1.0 - kb);
1228 s->cmatrix[1][2] = 112.0;
1229 s->cmatrix[2][0] = 112.0;
1230 s->cmatrix[2][1] = -112.0 * kg / (1.0 - kr);
1231 s->cmatrix[2][2] = -112.0 * kb / (1.0 - kr);
1239 if (sscanf(
s->cscheme,
" %f | %f | %f | %f | %f | %f %1s", &
s->cscheme_v[0],
1240 &
s->cscheme_v[1], &
s->cscheme_v[2], &
s->cscheme_v[3], &
s->cscheme_v[4],
1241 &
s->cscheme_v[5], tail) != 6)
1244 for (k = 0; k < 6; k++)
1245 if (
isnan(
s->cscheme_v[k]) ||
s->cscheme_v[k] < 0.0f ||
s->cscheme_v[k] > 1.0f)
1263 if (
s->width != 1920 ||
s->height != 1080) {
1272 if (
s->axis_h < 0) {
1273 s->axis_h =
s->width / 60;
1276 if (
s->bar_h >= 0 &&
s->sono_h >= 0)
1277 s->axis_h =
s->height -
s->bar_h -
s->sono_h;
1278 if (
s->bar_h >= 0 &&
s->sono_h < 0)
1279 s->axis_h =
FFMIN(
s->axis_h,
s->height -
s->bar_h);
1280 if (
s->bar_h < 0 &&
s->sono_h >= 0)
1281 s->axis_h =
FFMIN(
s->axis_h,
s->height -
s->sono_h);
1285 s->bar_h = (
s->height -
s->axis_h) / 2;
1289 s->bar_h =
s->height -
s->sono_h -
s->axis_h;
1293 s->sono_h =
s->height -
s->axis_h -
s->bar_h;
1295 if ((
s->width & 1) || (
s->height & 1) || (
s->bar_h & 1) || (
s->axis_h & 1) || (
s->sono_h & 1) ||
1296 (
s->bar_h < 0) || (
s->axis_h < 0) || (
s->sono_h < 0) || (
s->bar_h >
s->height) ||
1297 (
s->axis_h >
s->height) || (
s->sono_h >
s->height) || (
s->bar_h +
s->axis_h +
s->sono_h !=
s->height)) {
1305 }
while(
s->fcount *
s->width < 1920 &&
s->fcount < 10);
1362 outlink->
w =
s->width;
1363 outlink->
h =
s->height;
1370 s->bar_h,
s->axis_h,
s->sono_h);
1372 s->cqt_len =
s->width *
s->fcount;
1380 s->fft_len = 1 <<
s->fft_bits;
1384 s->fft_data =
av_calloc(
s->fft_len,
sizeof(*
s->fft_data));
1385 s->fft_result =
av_calloc(
s->fft_len + 64,
sizeof(*
s->fft_result));
1387 if (!
s->fft_ctx || !
s->fft_data || !
s->fft_result || !
s->cqt_result)
1390 s->remaining_fill_max =
s->fft_len / 2;
1391 if (
s->attack > 0.0) {
1396 if (!
s->attack_data)
1399 for (k = 0; k <
s->remaining_fill_max; k++) {
1401 s->attack_data[k] = 0.355768 + 0.487396 * cos(y) + 0.144232 * cos(2*y) + 0.012604 * cos(3*y);
1407 s->permute_coeffs =
NULL;
1429 }
else if (
s->axisfile) {
1457 if (!
s->h_buf || !
s->rcp_h_buf || !
s->c_buf)
1463 s->remaining_fill =
s->remaining_fill_max;
1464 s->remaining_frac = 0;
1466 s->step = (
int)(
s->step_frac.num /
s->step_frac.den);
1467 s->step_frac.num %=
s->step_frac.den;
1468 if (
s->step_frac.num) {
1470 inlink->
sample_rate,
s->step,
s->step_frac.num,
s->step_frac.den);
1486 int remaining, step, ret, x,
i, j, m;
1491 while (
s->remaining_fill <
s->remaining_fill_max) {
1492 memset(&
s->fft_data[
s->fft_len/2 +
s->remaining_fill_max -
s->remaining_fill], 0,
sizeof(*
s->fft_data) *
s->remaining_fill);
1497 step =
s->step + (
s->step_frac.num +
s->remaining_frac) /
s->step_frac.den;
1498 s->remaining_frac = (
s->step_frac.num +
s->remaining_frac) %
s->step_frac.den;
1499 for (x = 0; x < (
s->fft_len/2 +
s->remaining_fill_max - step); x++)
1500 s->fft_data[x] =
s->fft_data[x+step];
1501 s->remaining_fill += step;
1510 audio_data = (
float*) insamples->
data[0];
1514 j =
s->fft_len/2 +
s->remaining_fill_max -
s->remaining_fill;
1515 if (remaining >=
s->remaining_fill) {
1516 for (m = 0; m <
s->remaining_fill; m++) {
1517 s->fft_data[j+m].re = audio_data[2*(
i+m)];
1518 s->fft_data[j+m].im = audio_data[2*(
i+m)+1];
1525 remaining -=
s->remaining_fill;
1528 pts += insamples->
nb_samples - remaining -
s->remaining_fill_max;
1544 step =
s->step + (
s->step_frac.num +
s->remaining_frac) /
s->step_frac.den;
1545 s->remaining_frac = (
s->step_frac.num +
s->remaining_frac) %
s->step_frac.den;
1546 for (m = 0; m <
s->fft_len/2 +
s->remaining_fill_max - step; m++)
1547 s->fft_data[m] =
s->fft_data[m+step];
1548 s->remaining_fill = step;
1550 for (m = 0; m < remaining; m++) {
1551 s->fft_data[j+m].re = audio_data[2*(
i+m)];
1552 s->fft_data[j+m].im = audio_data[2*(
i+m)+1];
1554 s->remaining_fill -= remaining;
1594 .description =
NULL_IF_CONFIG_SMALL(
"Convert input audio to a CQT (Constant/Clamped Q Transform) spectrum video output."),
1601 .priv_class = &showcqt_class,
static enum AVSampleFormat sample_fmts[]
static double val(void *priv, double ch)
static const AVFilterPad inputs[]
static const AVFilterPad outputs[]
static const char *const format[]
simple assert() macros that are a bit more flexible than ISO C assert().
#define BLEND_CHROMA2x2(c)
static AVFrame * alloc_frame_empty(enum AVPixelFormat format, int w, int h)
static int init_axis_from_file(ShowCQTContext *s)
#define DRAW_BAR_WITH_CHROMA(x)
AVFILTER_DEFINE_CLASS(showcqt)
static void rgb_from_cqt(ColorFloat *c, const FFTComplex *v, float g, int len, float cscheme[6])
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
static void yuv_from_cqt(ColorFloat *c, const FFTComplex *v, float gamma, int len, float cm[3][3], float cscheme[6])
static void process_cqt(ShowCQTContext *s)
#define BLEND_WITH_CHROMA(c)
static void cqt_calc(FFTComplex *dst, const FFTComplex *src, const Coeffs *coeffs, int len, int fft_len)
static int init_volume(ShowCQTContext *s)
static int query_formats(AVFilterContext *ctx)
static enum AVPixelFormat convert_axis_pixel_format(enum AVPixelFormat format)
static void draw_sono(AVFrame *out, AVFrame *sono, int off, int idx)
static int init_axis_empty(ShowCQTContext *s)
static double midi(void *p, double f)
static double g_func(void *p, double x)
static int init_axis_color(ShowCQTContext *s, AVFrame *tmp, int half)
static const AVFilterPad showcqt_inputs[]
static void common_uninit(ShowCQTContext *s)
static double c_weighting(void *p, double f)
static int plot_cqt(AVFilterContext *ctx, AVFrame **frameout)
static int request_frame(AVFilterLink *outlink)
static double * create_freq_table(double base, double end, int n)
static double clip_with_log(void *log_ctx, const char *name, double val, double min, double max, double nan_replace, int idx)
#define BLEND_WITHOUT_CHROMA(c, alpha_inc)
static int init_cscheme(ShowCQTContext *s)
static float calculate_gamma(float v, float g)
static void draw_axis_yuv(AVFrame *out, AVFrame *axis, const ColorFloat *c, int off)
#define DRAW_BAR_WITHOUT_CHROMA(x)
static double r_func(void *p, double x)
static int render_freetype(ShowCQTContext *s, AVFrame *tmp, char *fontfile)
static void init_colormatrix(ShowCQTContext *s)
static int render_fontconfig(ShowCQTContext *s, AVFrame *tmp, char *font)
static void update_sono_rgb(AVFrame *sono, const ColorFloat *c, int idx)
static void draw_bar_yuv(AVFrame *out, const float *h, const float *rcp_h, const ColorFloat *c, int bar_h, float bar_t)
static av_cold int init(AVFilterContext *ctx)
static const AVFilterPad showcqt_outputs[]
static int init_axis_from_font(ShowCQTContext *s)
static av_cold void uninit(AVFilterContext *ctx)
static double b_func(void *p, double x)
static int render_default_font(AVFrame *tmp)
static double b_weighting(void *p, double f)
static double a_weighting(void *p, double f)
static const AVOption showcqt_options[]
static int config_output(AVFilterLink *outlink)
static int init_cqt(ShowCQTContext *s)
static void update_sono_yuv(AVFrame *sono, const ColorFloat *c, int idx)
static void draw_axis_rgb(AVFrame *out, AVFrame *axis, const ColorFloat *c, int off)
static void draw_bar_rgb(AVFrame *out, const float *h, const float *rcp_h, const ColorFloat *c, int bar_h, float bar_t)
void ff_showcqt_init_x86(ShowCQTContext *s)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Main libavfilter public API header.
static const uint8_t vars[2][12]
#define u(width, name, range_min, range_max)
#define xs(width, name, var, subs,...)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static __device__ float ceil(float a)
static __device__ float floor(float a)
static const uint16_t channel_layouts[7]
static float mul(float src0, float src1)
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
simple arithmetic expression evaluator
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive integers
@ AV_OPT_TYPE_VIDEO_RATE
offset must point to AVRational
#define AV_CH_LAYOUT_STEREO_DOWNMIX
#define AV_CH_LAYOUT_STEREO
void av_fft_permute(FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling ff_fft_calc().
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init().
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT.
av_cold void av_fft_end(FFTContext *s)
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
#define AVERROR_EOF
End of file.
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
static AVRational av_make_q(int num, int den)
Create an AVRational.
static double av_q2d(AVRational a)
Convert an AVRational to a double.
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
AVSampleFormat
Audio sample formats.
int ff_load_image(uint8_t *data[4], int linesize[4], int *w, int *h, enum AVPixelFormat *pix_fmt, const char *filename, void *log_ctx)
Load image from filename and put the resulting image in data.
Miscellaneous utilities which make use of the libavformat library.
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static enum AVPixelFormat pix_fmts[]
static av_always_inline float cbrtf(float x)
int ff_scale_image(uint8_t *dst_data[4], int dst_linesize[4], int dst_w, int dst_h, enum AVPixelFormat dst_pix_fmt, uint8_t *const src_data[4], int src_linesize[4], int src_w, int src_h, enum AVPixelFormat src_pix_fmt, void *log_ctx)
Scale image using libswscale.
Miscellaneous utilities which make use of the libswscale library.
static const uint16_t mask[17]
static uint8_t half(int a, int b)
enum MovChannelLayoutTag * layouts
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
@ AVCOL_SPC_FCC
FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
@ AVCOL_SPC_SMPTE240M
functionally identical to above
static const char *const var_names[]
A list of supported channel layouts.
AVFilterLink ** inputs
array of pointers to input links
A link between two filters.
AVFilterFormatsConfig incfg
Lists of supported formats / etc.
int w
agreed upon image width
int h
agreed upon image height
AVFilterFormatsConfig outcfg
Lists of supported formats / etc.
AVFilterContext * src
source filter
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
int sample_rate
samples per second
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable; if left to 0/0,...
AVFilterContext * dst
dest filter
int format
agreed upon media format
A filter pad used for either input or output.
const char * name
Pad name.
const char * name
Filter name.
This structure describes decoded (raw) audio or video data.
int nb_samples
number of audio samples (per channel) described by this frame
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
#define av_malloc_array(a, b)
static void error(const char *err)
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
const uint8_t avpriv_vga16_font[4096]
CGA/EGA/VGA ROM font data.