Go to the documentation of this file.
   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)
 
  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;
 
  442     x = av_clipd(x, 0.0, 1.0);
 
  443     return lrint(x*255.0) << 16;
 
  448     x = av_clipd(x, 0.0, 1.0);
 
  449     return lrint(x*255.0) << 8;
 
  454     x = av_clipd(x, 0.0, 1.0);
 
  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 };
 
  466     int width = half ? 1920/2 : 1920, 
height = half ? 16 : 32;
 
  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)
 
  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;
 
  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;
 
  776                 *lp++ = 
lrintf(mul * 
c[x].rgb.r);
 
  777                 *lp++ = 
lrintf(mul * 
c[x].rgb.g);
 
  778                 *lp++ = 
lrintf(mul * 
c[x].rgb.b);
 
  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];
 
  881                 *lp++ = 
lrintf(
a * lpa[0] + (1.0
f - 
a) * 
c[x].rgb.r);
 
  882                 *lp++ = 
lrintf(
a * lpa[1] + (1.0
f - 
a) * 
c[x].rgb.g);
 
  883                 *lp++ = 
lrintf(
a * lpa[2] + (1.0
f - 
a) * 
c[x].rgb.b);
 
  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);
 
 1133     int64_t last_time, cur_time;
 
 1135 #define UPDATE_TIME(t) \ 
 1136     cur_time = av_gettime(); \ 
 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) {
 
 1394         s->remaining_fill_max = 
FFMIN(
s->remaining_fill_max, ceil(
inlink->sample_rate * 
s->attack));
 
 1396         if (!
s->attack_data)
 
 1399         for (k = 0; k < 
s->remaining_fill_max; k++) {
 
 1400             double y = 
M_PI * k / (
inlink->sample_rate * 
s->attack);
 
 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);
 
 1474                inlink->sample_rate, 
s->step);
 
 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 void error(const char *err)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
av_cold void av_fft_end(FFTContext *s)
A list of supported channel layouts.
#define AV_LOG_WARNING
Something somehow does not look correct.
AVPixelFormat
Pixel format.
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
static void draw_axis_yuv(AVFrame *out, AVFrame *axis, const ColorFloat *c, int off)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
static void draw_bar_yuv(AVFrame *out, const float *h, const float *rcp_h, const ColorFloat *c, int bar_h, float bar_t)
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
#define u(width, name, range_min, range_max)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
static enum AVSampleFormat sample_fmts[]
enum MovChannelLayoutTag * layouts
#define AVERROR_EOF
End of file.
@ AV_OPT_TYPE_VIDEO_RATE
offset must point to AVRational
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
static int init_cscheme(ShowCQTContext *s)
AVFilterFormats * in_formats
Lists of formats and channel layouts supported by the input and output filters respectively.
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static av_cold int end(AVCodecContext *avctx)
This structure describes decoded (raw) audio or video data.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
void av_fft_permute(FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling ff_fft_calc().
#define BLEND_WITH_CHROMA(c)
static double c_weighting(void *p, double f)
const char * name
Filter name.
static int render_default_font(AVFrame *tmp)
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
static void draw_axis_rgb(AVFrame *out, AVFrame *axis, const ColorFloat *c, int off)
A link between two filters.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
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.
static void rgb_from_cqt(ColorFloat *c, const FFTComplex *v, float g, int len, float cscheme[6])
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
static double a_weighting(void *p, double f)
static double val(void *priv, double ch)
static av_cold void uninit(AVFilterContext *ctx)
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
#define AV_CH_LAYOUT_STEREO
A filter pad used for either input or output.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static const uint16_t mask[17]
#define BLEND_WITHOUT_CHROMA(c, alpha_inc)
#define DRAW_BAR_WITHOUT_CHROMA(x)
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
static void init_colormatrix(ShowCQTContext *s)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
static double av_q2d(AVRational a)
Convert an AVRational to a double.
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
#define AV_CH_LAYOUT_STEREO_DOWNMIX
static const AVFilterPad outputs[]
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable; if left to 0/0,...
static enum AVPixelFormat pix_fmts[]
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
#define BLEND_CHROMA2x2(c)
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
static void cqt_calc(FFTComplex *dst, const FFTComplex *src, const Coeffs *coeffs, int len, int fft_len)
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static double clip_with_log(void *log_ctx, const char *name, double val, double min, double max, double nan_replace, int idx)
#define xs(width, name, var, subs,...)
and forward the result(frame or status change) to the corresponding input. If nothing is possible
static av_cold int init(AVFilterContext *ctx)
static const uint8_t vars[2][12]
static int render_freetype(ShowCQTContext *s, AVFrame *tmp, char *fontfile)
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive integers
AVFilterLink ** inputs
array of pointers to input links
static const AVFilterPad showcqt_inputs[]
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
static AVFrame * alloc_frame_empty(enum AVPixelFormat format, int w, int h)
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
static int init_axis_from_file(ShowCQTContext *s)
static void yuv_from_cqt(ColorFloat *c, const FFTComplex *v, float gamma, int len, float cm[3][3], float cscheme[6])
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static const AVFilterPad showcqt_outputs[]
static void process_cqt(ShowCQTContext *s)
static float calculate_gamma(float v, float g)
static int init_axis_color(ShowCQTContext *s, AVFrame *tmp, int half)
int format
agreed upon media format
static int init_axis_from_font(ShowCQTContext *s)
static AVRational av_make_q(int num, int den)
Create an AVRational.
static void update_sono_rgb(AVFrame *sono, const ColorFloat *c, int idx)
static int query_formats(AVFilterContext *ctx)
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.
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
AVFilterContext * src
source filter
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
static int init_volume(ShowCQTContext *s)
#define AV_LOG_INFO
Standard information.
@ AVCOL_SPC_SMPTE240M
functionally identical to above
static enum AVPixelFormat convert_axis_pixel_format(enum AVPixelFormat format)
static double * create_freq_table(double base, double end, int n)
int nb_samples
number of audio samples (per channel) described by this frame
static double b_weighting(void *p, double f)
const uint8_t avpriv_vga16_font[4096]
#define i(width, name, range_min, range_max)
static double b_func(void *p, double x)
static double r_func(void *p, double x)
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
int w
agreed upon image width
#define av_malloc_array(a, b)
AVSampleFormat
Audio sample formats.
static av_always_inline float cbrtf(float x)
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
const char * name
Pad name.
static void draw_bar_rgb(AVFrame *out, const float *h, const float *rcp_h, const ColorFloat *c, int bar_h, float bar_t)
@ AVCOL_RANGE_MPEG
the normal 219*2^(n-8) "MPEG" YUV ranges
static void common_uninit(ShowCQTContext *s)
static int plot_cqt(AVFilterContext *ctx, AVFrame **frameout)
static int config_output(AVFilterLink *outlink)
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT.
static const AVOption showcqt_options[]
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
static const char *const var_names[]
int h
agreed upon image height
@ AVCOL_SPC_FCC
FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
static double midi(void *p, double f)
static int init_cqt(ShowCQTContext *s)
static void update_sono_yuv(AVFrame *sono, const ColorFloat *c, int idx)
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
void ff_showcqt_init_x86(ShowCQTContext *s)
static double g_func(void *p, double x)
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
int64_t av_gettime(void)
Get the current time in microseconds.
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
static const uint16_t channel_layouts[7]
static int request_frame(AVFilterLink *outlink)
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
AVFILTER_DEFINE_CLASS(showcqt)
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
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.
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init().
static void draw_sono(AVFrame *out, AVFrame *sono, int off, int idx)
#define DRAW_BAR_WITH_CHROMA(x)
static int init_axis_empty(ShowCQTContext *s)
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.
static int render_fontconfig(ShowCQTContext *s, AVFrame *tmp, char *font)