44#if CONFIG_LIBFONTCONFIG
45#include <fontconfig/fontconfig.h>
50#define BASEFREQ 20.01523126408007475
51#define ENDFREQ 20495.59681441799654
52#define TLENGTH "384*tc/(384+tc*f)"
53#define TLENGTH_MIN 0.001
54#define VOLUME_MAX 100.0
55#define FONTCOLOR "st(0, (midi(f)-59.5)/12);" \
56 "st(1, if(between(ld(0),0,1), 0.5-0.5*cos(2*PI*ld(0)), 0));" \
57 "r(1-ld(1)) + b(ld(1))"
58#define CSCHEME "1|0.5|0|0|0.5|1"
60#define OFFSET(x) offsetof(ShowCQTContext, x)
61#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
118 av_log(
s->ctx,
level,
"fft_time = %16.3f s.\n",
s->fft_time * 1e-6);
120 av_log(
s->ctx,
level,
"cqt_time = %16.3f s.\n",
s->cqt_time * 1e-6);
121 if (
s->process_cqt_time)
122 av_log(
s->ctx,
level,
"process_cqt_time = %16.3f s.\n",
s->process_cqt_time * 1e-6);
123 if (
s->update_sono_time)
124 av_log(
s->ctx,
level,
"update_sono_time = %16.3f s.\n",
s->update_sono_time * 1e-6);
126 av_log(
s->ctx,
level,
"alloc_time = %16.3f s.\n",
s->alloc_time * 1e-6);
128 av_log(
s->ctx,
level,
"bar_time = %16.3f s.\n",
s->bar_time * 1e-6);
130 av_log(
s->ctx,
level,
"axis_time = %16.3f s.\n",
s->axis_time * 1e-6);
132 av_log(
s->ctx,
level,
"sono_time = %16.3f s.\n",
s->sono_time * 1e-6);
134 plot_time =
s->fft_time +
s->cqt_time +
s->process_cqt_time +
s->update_sono_time
135 +
s->alloc_time +
s->bar_time +
s->axis_time +
s->sono_time;
137 av_log(
s->ctx,
level,
"plot_time = %16.3f s.\n", plot_time * 1e-6);
139 s->fft_time =
s->cqt_time =
s->process_cqt_time =
s->update_sono_time
140 =
s->alloc_time =
s->bar_time =
s->axis_time =
s->sono_time = 0;
142 if (
s->axis_frame && !
s->axis_frame->buf[0]) {
144 for (k = 0; k < 4; k++)
145 s->axis_frame->data[k] =
NULL;
152 for (k = 0; k <
s->cqt_len; k++)
170 double log_base, log_end;
171 double rcp_n = 1.0 / n;
179 log_base = log(
base);
181 for (x = 0; x < n; x++) {
182 double log_freq = log_base + (x + 0.5) * (log_end - log_base) * rcp_n;
183 freq[x] =
exp(log_freq);
190 double nan_replace,
int idx)
194 av_log(log_ctx,
level,
"[%d] %s is nan, setting it to %g.\n",
195 idx,
name, nan_replace);
198 av_log(log_ctx,
level,
"[%d] %s is too low (%g), setting it to %g.\n",
202 av_log(log_ctx,
level,
"[%d] %s it too high (%g), setting it to %g.\n",
211 double ret = 12200.0*12200.0 * (
f*
f*
f*
f);
212 ret /= (
f*
f + 20.6*20.6) * (
f*
f + 12200.0*12200.0) *
213 sqrt((
f*
f + 107.7*107.7) * (
f*
f + 737.9*737.9));
219 double ret = 12200.0*12200.0 * (
f*
f*
f);
220 ret /= (
f*
f + 20.6*20.6) * (
f*
f + 12200.0*12200.0) * sqrt(
f*
f + 158.5*158.5);
226 double ret = 12200.0*12200.0 * (
f*
f);
227 ret /= (
f*
f + 20.6*20.6) * (
f*
f + 12200.0*12200.0);
233 const char *func_names[] = {
"a_weighting",
"b_weighting",
"c_weighting",
NULL };
234 const char *sono_names[] = {
"timeclamp",
"tc",
"frequency",
"freq",
"f",
"bar_v",
NULL };
235 const char *bar_names[] = {
"timeclamp",
"tc",
"frequency",
"freq",
"f",
"sono_v",
NULL };
242 if (!
s->sono_v_buf || !
s->bar_v_buf)
251 for (x = 0; x <
s->cqt_len; x++) {
252 double vars[] = {
s->timeclamp,
s->timeclamp,
s->freq[x],
s->freq[x],
s->freq[x], 0.0 };
256 s->bar_v_buf[x] = vol * vol;
259 s->sono_v_buf[x] = vol * vol;
274 int len,
int fft_len)
277 for (k = 0; k <
len; k++) {
280 for (x = 0; x < coeffs[k].
len; x++) {
281 float u = coeffs[k].
val[x];
286 b.re +=
u *
src[j].re;
287 b.im +=
u *
src[j].im;
296 dst[k].im =
r.re *
r.re +
r.im *
r.im;
302 const char *
var_names[] = {
"timeclamp",
"tc",
"frequency",
"freq",
"f",
NULL };
304 int rate =
s->ctx->inputs[0]->sample_rate;
305 int nb_cqt_coeffs = 0;
312 if (!(
s->coeffs =
av_calloc(
s->cqt_len,
sizeof(*
s->coeffs))))
315 for (k = 0; k <
s->cqt_len; k++) {
316 double vars[] = {
s->timeclamp,
s->timeclamp,
s->freq[k],
s->freq[k],
s->freq[k] };
317 double flen, center, tlength;
318 int start, end, m = k;
320 if (
s->freq[k] > 0.5 * rate)
325 flen = 8.0 *
s->fft_len / (tlength * rate);
326 center =
s->freq[k] *
s->fft_len / rate;
327 start =
FFMAX(0,
ceil(center - 0.5 * flen));
328 end =
FFMIN(
s->fft_len,
floor(center + 0.5 * flen));
330 s->coeffs[m].start = start & ~(
s->cqt_align - 1);
331 s->coeffs[m].len = (end | (
s->cqt_align - 1)) + 1 -
s->coeffs[m].start;
332 nb_cqt_coeffs +=
s->coeffs[m].len;
333 if (!(
s->coeffs[m].val =
av_calloc(
s->coeffs[m].len,
sizeof(*
s->coeffs[m].val))))
336 for (x = start; x <= end; x++) {
337 int sign = (x & 1) ? (-1) : 1;
338 double y = 2.0 *
M_PI * (x - center) * (1.0 / flen);
340 double w = 0.355768 + 0.487396 * cos(y) + 0.144232 * cos(2*y) + 0.012604 * cos(3*y);
341 w *= sign * (1.0 /
s->fft_len);
342 s->coeffs[m].val[x -
s->coeffs[m].start] =
w;
345 if (
s->permute_coeffs)
346 s->permute_coeffs(
s->coeffs[m].val,
s->coeffs[m].len);
356 for (k = 0; k <
s->cqt_len; k++)
376 memset(
out->data[0], 0,
out->linesize[0] *
h);
379 memset(
out->data[0], 16,
out->linesize[0] *
h);
380 memset(
out->data[1], 128,
out->linesize[1] * hh);
381 memset(
out->data[2], 128,
out->linesize[2] * hh);
383 memset(
out->data[3], 0,
out->linesize[3] *
h);
417 ret =
ff_scale_image(
s->axis_frame->data,
s->axis_frame->linesize,
s->width,
s->axis_h,
426 s->axis_frame->width =
s->width;
427 s->axis_frame->height =
s->axis_h;
436static double midi(
void *p,
double f)
438 return log2(
f/440.0) * 12.0 + 69.0;
444 return lrint(x*255.0) << 16;
450 return lrint(x*255.0) << 8;
456 return lrint(x*255.0);
461 const char *
var_names[] = {
"timeclamp",
"tc",
"frequency",
"freq",
"f",
NULL };
462 const char *func_names[] = {
"midi",
"r",
"g",
"b",
NULL };
468 int step =
half ? 2 : 1;
471 av_log(
s->ctx,
AV_LOG_WARNING,
"font axis rendering is not implemented in non-default frequency range,"
472 " please use axisfile option instead.\n");
476 if (
s->cqt_len == 1920)
487 for (x = 0,
xs = 0; x <
width; x++,
xs += step) {
488 double vars[] = {
s->timeclamp,
s->timeclamp, freq[
xs], freq[
xs], freq[
xs] };
492 int linesize =
tmp->linesize[0];
493 for (y = 0; y <
height; y++) {
494 data[linesize * y + 4 * x] =
r;
495 data[linesize * y + 4 * x + 1] =
g;
496 data[linesize * y + 4 * x + 2] =
b;
508#if CONFIG_LIBFREETYPE
509 const char *str =
"EF G A BC D ";
511 int linesize =
tmp->linesize[0];
512 FT_Library lib =
NULL;
514 int font_width = 16, font_height = 32;
515 int font_repeat = font_width * 12;
516 int linear_hori_advance = font_width * 65536;
517 int non_monospace_warning = 0;
523 if (FT_Init_FreeType(&lib))
526 if (FT_New_Face(lib, fontfile, 0, &face))
529 if (FT_Set_Char_Size(face, 16*64, 0, 0, 0))
532 if (FT_Load_Char(face,
'A', FT_LOAD_RENDER))
535 if (FT_Set_Char_Size(face, 16*64 * linear_hori_advance / face->glyph->linearHoriAdvance, 0, 0, 0))
538 for (x = 0; x < 12; x++) {
539 int sx, sy, rx, bx, by, dx, dy;
544 if (FT_Load_Char(face, str[x], FT_LOAD_RENDER))
547 if (face->glyph->advance.x != font_width*64 && !non_monospace_warning) {
549 non_monospace_warning = 1;
552 sy = font_height - 8 - face->glyph->bitmap_top;
553 for (rx = 0; rx < 10; rx++) {
554 sx = rx * font_repeat + x * font_width + face->glyph->bitmap_left;
555 for (by = 0; by < face->glyph->bitmap.rows; by++) {
559 if (dy >= font_height)
562 for (bx = 0; bx < face->glyph->bitmap.width; bx++) {
568 data[dy*linesize+4*dx+3] = face->glyph->bitmap.buffer[by*face->glyph->bitmap.width+bx];
575 FT_Done_FreeType(lib);
581 FT_Done_FreeType(lib);
592#if CONFIG_LIBFONTCONFIG
593 FcConfig *fontconfig;
594 FcPattern *pat, *best;
595 FcResult result = FcResultMatch;
602 for (
i = 0; font[
i];
i++) {
607 if (!(fontconfig = FcInitLoadConfigAndFonts())) {
612 if (!(pat = FcNameParse((uint8_t *)font))) {
614 FcConfigDestroy(fontconfig);
618 FcDefaultSubstitute(pat);
620 if (!FcConfigSubstitute(fontconfig, pat, FcMatchPattern)) {
622 FcPatternDestroy(pat);
623 FcConfigDestroy(fontconfig);
627 best = FcFontMatch(fontconfig, pat, &result);
628 FcPatternDestroy(pat);
631 if (!best || result != FcResultMatch) {
636 if (FcPatternGetString(best, FC_FILE, 0, (FcChar8 **)&filename) != FcResultMatch) {
644 FcPatternDestroy(best);
645 FcConfigDestroy(fontconfig);
656 const char *str =
"EF G A BC D ";
660 int linesize =
tmp->linesize[0];
664 uint8_t *startptr =
data + 4 * x;
665 for (
u = 0;
u < 12;
u++) {
666 for (v = 0; v <
height; v++) {
667 uint8_t *p = startptr + v * linesize +
height/2 * 4 *
u;
686 int default_font = 0;
705 if ((ret =
ff_scale_image(
s->axis_frame->data,
s->axis_frame->linesize,
s->width,
s->axis_h,
711 s->axis_frame->width =
s->width;
712 s->axis_frame->height =
s->axis_h;
732 return expf(logf(v) /
g);
738 for (x = 0; x <
len; x++) {
748 for (x = 0; x <
len; x++) {
753 c[x].yuv.y =
cm[0][0] *
r +
cm[0][1] *
g +
cm[0][2] *
b;
754 c[x].yuv.u =
cm[1][0] *
r +
cm[1][1] *
g +
cm[1][2] *
b;
755 c[x].yuv.v =
cm[2][0] *
r +
cm[2][1] *
g +
cm[2][2] *
b;
762 int x, y,
w =
out->width;
763 float mul, ht, rcp_bar_h = 1.0f / bar_h, rcp_bar_t = 1.0f / bar_t;
764 uint8_t *v =
out->data[0], *lp;
765 int ls =
out->linesize[0];
767 for (y = 0; y < bar_h; y++) {
768 ht = (bar_h - y) * rcp_bar_h;
770 for (x = 0; x <
w; x++) {
776 mul = (
h[x] - ht) * rcp_h[x];
777 mul = (mul < bar_t) ? (mul * rcp_bar_t) : 1.0f;
786#define DRAW_BAR_WITH_CHROMA(x) \
793 mul = (h[x] - ht) * rcp_h[x]; \
794 mul = (mul < bar_t) ? (mul * rcp_bar_t) : 1.0f; \
795 *lpy++ = lrintf(mul * c[x].yuv.y + 16.0f); \
796 *lpu++ = lrintf(mul * c[x].yuv.u + 128.0f); \
797 *lpv++ = lrintf(mul * c[x].yuv.v + 128.0f); \
801#define DRAW_BAR_WITHOUT_CHROMA(x) \
806 mul = (h[x] - ht) * rcp_h[x]; \
807 mul = (mul < bar_t) ? (mul * rcp_bar_t) : 1.0f; \
808 *lpy++ = lrintf(mul * c[x].yuv.y + 16.0f); \
815 int x, y, yh,
w =
out->width;
816 float mul, ht, rcp_bar_h = 1.0f / bar_h, rcp_bar_t = 1.0f / bar_t;
817 uint8_t *vy =
out->data[0], *vu =
out->data[1], *vv =
out->data[2];
818 uint8_t *lpy, *lpu, *lpv;
819 int lsy =
out->linesize[0], lsu =
out->linesize[1], lsv =
out->linesize[2];
820 int fmt =
out->format;
822 for (y = 0; y < bar_h; y += 2) {
824 ht = (bar_h - y) * rcp_bar_h;
829 for (x = 0; x <
w; x += 2) {
834 for (x = 0; x <
w; x += 2) {
840 ht = (bar_h - (y+1)) * rcp_bar_h;
841 lpy = vy + (y+1) * lsy;
842 lpu = vu + (y+1) * lsu;
843 lpv = vv + (y+1) * lsv;
845 for (x = 0; x <
w; x += 2) {
850 for (x = 0; x <
w; x += 2) {
855 for (x = 0; x <
w; x += 2) {
866 float a, rcp_255 = 1.0f / 255.0f;
869 for (y = 0; y <
h; y++) {
870 lp =
out->data[0] + (off + y) *
out->linesize[0];
872 for (x = 0; x <
w; x++) {
877 }
else if (lpa[3] == 255) {
882 a = rcp_255 * lpa[3];
892#define BLEND_WITH_CHROMA(c) \
895 *lpy = lrintf(c.yuv.y + 16.0f); \
896 *lpu = lrintf(c.yuv.u + 128.0f); \
897 *lpv = lrintf(c.yuv.v + 128.0f); \
898 } else if (255 == *lpaa) { \
903 float a = (1.0f/255.0f) * (*lpaa); \
904 *lpy = lrintf(a * (*lpay) + (1.0f - a) * (c.yuv.y + 16.0f)); \
905 *lpu = lrintf(a * (*lpau) + (1.0f - a) * (c.yuv.u + 128.0f)); \
906 *lpv = lrintf(a * (*lpav) + (1.0f - a) * (c.yuv.v + 128.0f)); \
908 lpy++; lpu++; lpv++; \
909 lpay++; lpau++; lpav++; lpaa++; \
912#define BLEND_WITHOUT_CHROMA(c, alpha_inc) \
915 *lpy = lrintf(c.yuv.y + 16.0f); \
916 } else if (255 == *lpaa) { \
919 float a = (1.0f/255.0f) * (*lpaa); \
920 *lpy = lrintf(a * (*lpay) + (1.0f - a) * (c.yuv.y + 16.0f)); \
923 lpay++; lpaa += alpha_inc; \
926#define BLEND_CHROMA2(c) \
928 if (!lpaa[0] && !lpaa[1]) { \
929 *lpu = lrintf(c.yuv.u + 128.0f); \
930 *lpv = lrintf(c.yuv.v + 128.0f); \
931 } else if (255 == lpaa[0] && 255 == lpaa[1]) { \
932 *lpu = *lpau; *lpv = *lpav; \
934 float a0 = (0.5f/255.0f) * lpaa[0]; \
935 float a1 = (0.5f/255.0f) * lpaa[1]; \
936 float b = 1.0f - a0 - a1; \
937 *lpu = lrintf(a0 * lpau[0] + a1 * lpau[1] + b * (c.yuv.u + 128.0f)); \
938 *lpv = lrintf(a0 * lpav[0] + a1 * lpav[1] + b * (c.yuv.v + 128.0f)); \
940 lpau += 2; lpav += 2; lpaa++; lpu++; lpv++; \
943#define BLEND_CHROMA2x2(c) \
945 if (!lpaa[0] && !lpaa[1] && !lpaa[lsaa] && !lpaa[lsaa+1]) { \
946 *lpu = lrintf(c.yuv.u + 128.0f); \
947 *lpv = lrintf(c.yuv.v + 128.0f); \
948 } else if (255 == lpaa[0] && 255 == lpaa[1] && \
949 255 == lpaa[lsaa] && 255 == lpaa[lsaa+1]) { \
950 *lpu = *lpau; *lpv = *lpav; \
952 float a0 = (0.25f/255.0f) * lpaa[0]; \
953 float a1 = (0.25f/255.0f) * lpaa[1]; \
954 float a2 = (0.25f/255.0f) * lpaa[lsaa]; \
955 float a3 = (0.25f/255.0f) * lpaa[lsaa+1]; \
956 float b = 1.0f - a0 - a1 - a2 - a3; \
957 *lpu = lrintf(a0 * lpau[0] + a1 * lpau[1] + a2 * lpau[lsau] + a3 * lpau[lsau+1] \
958 + b * (c.yuv.u + 128.0f)); \
959 *lpv = lrintf(a0 * lpav[0] + a1 * lpav[1] + a2 * lpav[lsav] + a3 * lpav[lsav+1] \
960 + b * (c.yuv.v + 128.0f)); \
962 lpau += 2; lpav += 2; lpaa++; lpu++; lpv++; \
969 uint8_t *vy =
out->data[0], *vu =
out->data[1], *vv =
out->data[2];
970 uint8_t *vay = axis->
data[0], *vau = axis->
data[1], *vav = axis->
data[2], *vaa = axis->
data[3];
971 int lsy =
out->linesize[0], lsu =
out->linesize[1], lsv =
out->linesize[2];
973 uint8_t *lpy, *lpu, *lpv, *lpay, *lpau, *lpav, *lpaa;
975 for (y = 0; y <
h; y += 2) {
977 lpy = vy + (off + y) * lsy;
978 lpu = vu + (offh + yh) * lsu;
979 lpv = vv + (offh + yh) * lsv;
980 lpay = vay + y * lsay;
981 lpau = vau + y * lsau;
982 lpav = vav + y * lsav;
983 lpaa = vaa + y * lsaa;
985 for (x = 0; x <
w; x += 2) {
990 for (x = 0; x <
w; x += 2) {
996 for (x = 0; x <
w; x += 2) {
1003 lpy = vy + (off + y + 1) * lsy;
1004 lpu = vu + (off + y + 1) * lsu;
1005 lpv = vv + (off + y + 1) * lsv;
1006 lpay = vay + (y + 1) * lsay;
1007 lpau = vau + (y + 1) * lsau;
1008 lpav = vav + (y + 1) * lsav;
1009 lpaa = vaa + (y + 1) * lsaa;
1011 for (x = 0; x <
w; x += 2) {
1016 for (x = 0; x <
w; x += 2) {
1022 for (x = 0; x <
w; x += 2) {
1040 for (y = 0; y <
h; y++) {
1041 memcpy(
out->data[0] + (off + y) *
out->linesize[0],
1045 for (
i = 1;
i < nb_planes;
i++) {
1047 for (y = 0; y <
h; y +=
inc) {
1049 memcpy(
out->data[
i] + (offh + yh) *
out->linesize[
i],
1060 for (x = 0; x <
w; x++) {
1070 uint8_t *lpy = sono->
data[0] + idx * sono->
linesize[0];
1071 uint8_t *lpu = sono->
data[1] + idx * sono->
linesize[1];
1072 uint8_t *lpv = sono->
data[2] + idx * sono->
linesize[2];
1074 for (x = 0; x <
w; x += 2) {
1075 *lpy++ =
lrintf(
c[x].yuv.y + 16.0f);
1076 *lpu++ =
lrintf(
c[x].yuv.u + 128.0f);
1077 *lpv++ =
lrintf(
c[x].yuv.v + 128.0f);
1078 *lpy++ =
lrintf(
c[x+1].yuv.y + 16.0f);
1080 *lpu++ =
lrintf(
c[x+1].yuv.u + 128.0f);
1081 *lpv++ =
lrintf(
c[x+1].yuv.v + 128.0f);
1089 if (!
s->sono_count) {
1090 for (x = 0; x <
s->cqt_len; x++) {
1091 s->h_buf[x] =
s->bar_v_buf[x] * 0.5f * (
s->cqt_result[x].re +
s->cqt_result[x].im);
1093 if (
s->fcount > 1) {
1094 float rcp_fcount = 1.0f /
s->fcount;
1095 for (x = 0; x <
s->width; x++) {
1097 for (
i = 0;
i <
s->fcount;
i++)
1098 h +=
s->h_buf[
s->fcount * x +
i];
1099 s->h_buf[x] = rcp_fcount *
h;
1102 for (x = 0; x <
s->width; x++) {
1104 s->rcp_h_buf[x] = 1.0f / (
s->h_buf[x] + 0.0001f);
1108 for (x = 0; x <
s->cqt_len; x++) {
1109 s->cqt_result[x].re *=
s->sono_v_buf[x];
1110 s->cqt_result[x].im *=
s->sono_v_buf[x];
1113 if (
s->fcount > 1) {
1114 float rcp_fcount = 1.0f /
s->fcount;
1115 for (x = 0; x <
s->width; x++) {
1117 for (
i = 0;
i <
s->fcount;
i++) {
1118 result.
re +=
s->cqt_result[
s->fcount * x +
i].re;
1119 result.
im +=
s->cqt_result[
s->fcount * x +
i].im;
1121 s->cqt_result[x].re = rcp_fcount * result.
re;
1122 s->cqt_result[x].im = rcp_fcount * result.
im;
1129 yuv_from_cqt(
s->c_buf,
s->cqt_result,
s->sono_g,
s->width,
s->cmatrix,
s->cscheme_v);
1138#define UPDATE_TIME(t) \
1139 cur_time = av_gettime_relative(); \
1140 t += cur_time - last_time; \
1141 last_time = cur_time
1145 memcpy(
s->fft_input,
s->fft_data,
s->fft_len *
sizeof(*
s->fft_data));
1146 if (
s->attack_data) {
1148 for (k = 0; k <
s->remaining_fill_max; k++) {
1149 s->fft_input[
s->fft_len/2+k].re *=
s->attack_data[k];
1150 s->fft_input[
s->fft_len/2+k].im *=
s->attack_data[k];
1157 s->cqt_calc(
s->cqt_result,
s->fft_result,
s->coeffs,
s->cqt_len,
s->fft_len);
1164 s->update_sono(
s->sono_frame,
s->c_buf,
s->sono_idx);
1168 if (!
s->sono_count) {
1174 out->colorspace =
s->csp;
1178 s->draw_bar(
out,
s->h_buf,
s->rcp_h_buf,
s->c_buf,
s->bar_h,
s->bar_t);
1183 s->draw_axis(
out,
s->axis_frame,
s->c_buf,
s->bar_h);
1188 s->draw_sono(
out,
s->sono_frame,
s->bar_h +
s->axis_h,
s->sono_idx);
1192 s->sono_count = (
s->sono_count + 1) %
s->count;
1194 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);
1360 outlink->
w =
s->width;
1361 outlink->
h =
s->height;
1368 s->bar_h,
s->axis_h,
s->sono_h);
1370 s->cqt_len =
s->width *
s->fcount;
1378 s->fft_len = 1 <<
s->fft_bits;
1382 s->fft_data =
av_calloc(
s->fft_len,
sizeof(*
s->fft_data));
1386 if (!
s->fft_ctx || !
s->fft_data || !
s->fft_result || !
s->cqt_result)
1389 s->remaining_fill_max =
s->fft_len / 2;
1390 if (
s->attack > 0.0) {
1395 if (!
s->attack_data)
1398 for (k = 0; k <
s->remaining_fill_max; k++) {
1400 s->attack_data[k] = 0.355768 + 0.487396 * cos(y) + 0.144232 * cos(2*y) + 0.012604 * cos(3*y);
1406 s->permute_coeffs =
NULL;
1418#if ARCH_X86 && HAVE_X86ASM
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);
1485 int remaining, step, ret, x,
i, j, m, got_frame = 0;
1490 while (
s->remaining_fill <
s->remaining_fill_max) {
1491 memset(&
s->fft_data[
s->fft_len/2 +
s->remaining_fill_max -
s->remaining_fill], 0,
sizeof(*
s->fft_data) *
s->remaining_fill);
1496 step =
s->step + (
s->step_frac.num +
s->remaining_frac) /
s->step_frac.den;
1497 s->remaining_frac = (
s->step_frac.num +
s->remaining_frac) %
s->step_frac.den;
1498 for (x = 0; x < (
s->fft_len/2 +
s->remaining_fill_max - step); x++)
1499 s->fft_data[x] =
s->fft_data[x+step];
1500 s->remaining_fill += step;
1504 out->pts =
s->next_pts;
1513 audio_data = (
float*) insamples->
data[0];
1517 j =
s->fft_len/2 +
s->remaining_fill_max -
s->remaining_fill;
1518 if (remaining >=
s->remaining_fill) {
1519 for (m =
FFMAX(0, -j); m <
s->remaining_fill; m++) {
1520 s->fft_data[j+m].re = audio_data[2*(
i+m)];
1521 s->fft_data[j+m].im = audio_data[2*(
i+m)+1];
1528 remaining -=
s->remaining_fill;
1542 step =
s->step + (
s->step_frac.num +
s->remaining_frac) /
s->step_frac.den;
1543 s->remaining_frac = (
s->step_frac.num +
s->remaining_frac) %
s->step_frac.den;
1544 for (m = 0; m <
s->fft_len/2 +
s->remaining_fill_max - step; m++)
1545 s->fft_data[m] =
s->fft_data[m+step];
1546 s->remaining_fill = step;
1548 for (m =
FFMAX(0, -j); m < remaining; m++) {
1549 s->fft_data[j+m].re = audio_data[2*(
i+m)];
1550 s->fft_data[j+m].im = audio_data[2*(
i+m)+1];
1552 s->remaining_fill -= remaining;
1567 int nb_samples, ret, status;
1573 nb_samples =
s->step + (
s->step_frac.num +
s->remaining_frac) /
s->step_frac.den;
1603 .p.name =
"showcqt",
1604 .p.description =
NULL_IF_CONFIG_SMALL(
"Convert input audio to a CQT (Constant/Clamped Q Transform) spectrum video output."),
1605 .p.priv_class = &showcqt_class,
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static enum AVSampleFormat sample_fmts[]
static double val(void *priv, double ch)
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static const char *const format[]
const FFFilter ff_avf_showcqt
const AVFilterPad ff_audio_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_AUDIO.
#define BLEND_CHROMA2x2(c)
static double * create_freq_table(double base, double end, int n)
static int init_axis_from_file(ShowCQTContext *s)
#define DRAW_BAR_WITH_CHROMA(x)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
static void rgb_from_cqt(ColorFloat *c, const AVComplexFloat *v, float g, int len, float cscheme[6])
static void process_cqt(ShowCQTContext *s)
#define BLEND_WITH_CHROMA(c)
static int init_volume(ShowCQTContext *s)
static enum AVPixelFormat convert_axis_pixel_format(enum AVPixelFormat format)
static void draw_sono(AVFrame *out, AVFrame *sono, int off, int idx)
static void cqt_calc(AVComplexFloat *dst, const AVComplexFloat *src, const Coeffs *coeffs, int len, int fft_len)
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 void common_uninit(ShowCQTContext *s)
static double c_weighting(void *p, double f)
static int plot_cqt(AVFilterContext *ctx, AVFrame **frameout)
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 AVFrame * alloc_frame_empty(enum AVPixelFormat format, int w, int h)
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static void init_colormatrix(ShowCQTContext *s)
static int render_fontconfig(ShowCQTContext *s, AVFrame *tmp, char *font)
static int activate(AVFilterContext *ctx)
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 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 void yuv_from_cqt(ColorFloat *c, const AVComplexFloat *v, float gamma, int len, float cm[3][3], float cscheme[6])
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_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Main libavfilter public API header.
static const uint8_t vars[2][12]
#define i(width, name, range_min, range_max)
#define xs(width, name, var, subs,...)
Public libavutil channel layout APIs header.
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static __device__ float sqrtf(float a)
static __device__ float ceil(float a)
static __device__ float floor(float a)
static const uint16_t channel_layouts[7]
int(* init)(AVBSFContext *ctx)
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
Underlying C type is two consecutive integers.
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_VIDEO_RATE
Underlying C type is AVRational.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
#define AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
#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_VERBOSE
Detailed information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static AVRational av_make_q(int num, int den)
Create an AVRational.
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.
AVSampleFormat
Audio sample formats.
static void scale(int *out, const int *in, const int w, const int h, const int shift)
int ff_load_image(struct AVFrame **outframe, const char *filename, void *log_ctx)
Load image from filename and put the resulting image in an AVFrame.
Miscellaneous utilities which make use of the libavformat library.
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int activate(AVBitStreamFilterContext *ctx)
static int config_output(AVBitStreamFilterLink *outlink)
#define u(width, name, range_min, range_max)
#define FILTER_INPUTS(array)
#define FILTER_OUTPUTS(array)
#define FF_FILTER_FORWARD_WANTED(outlink, inlink)
Forward the frame_wanted_out flag from an output link to an input link.
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
#define FFERROR_NOT_READY
Filters implementation helper functions and internal structures.
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
static FilterLink * ff_filter_link(AVFilterLink *link)
#define AVFILTER_DEFINE_CLASS(fname)
#define FILTER_QUERY_FUNC2(func)
Macro definitions for various function/variable attributes.
#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]
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
static uint8_t half(int a, int b)
static const char *const var_names[]
static int inc(int num, int period)
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 / derived in SMPTE RP 177 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 / functionally identical to above
@ AVCOL_SPC_FCC
FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
@ AVCOL_SPC_SMPTE240M
derived from 170M primaries and D65 white point, 170M is derived from BT470 System M's primaries
An AVChannelLayout holds information about the channel layout of audio data.
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
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
AVFilterContext * dst
dest filter
int format
agreed upon media format
A filter pad used for either input or output.
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, a positive or negative value, which is typically indicating the size in bytes of each pict...
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Link properties exposed to filter code, but not external callers.
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable.
#define av_malloc_array(a, b)
static void error(const char *err)
static AVFormatContext * ctx
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
@ AV_TX_FLOAT_FFT
Standard complex to complex FFT with sample data type of AVComplexFloat, AVComplexDouble or AVComplex...
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_get(void)
static const uint8_t vga16_font[4096]
CGA/EGA/VGA ROM font data.