+static int plot_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+ ShowSpectrumContext *s = ctx->priv;
+ const int h = s->orientation == VERTICAL ? s->channel_height : s->channel_width;
+ const int ch = jobnr;
+ float *magnitudes = s->magnitudes[ch];
+ float *phases = s->phases[ch];
+ float yf, uf, vf;
+ int y;
+
+ /* decide color range */
+ color_range(s, ch, &yf, &uf, &vf);
+
+ /* draw the channel */
+ for (y = 0; y < h; y++) {
+ int row = (s->mode == COMBINED) ? y : ch * h + y;
+ float *out = &s->color_buffer[ch][3 * row];
+ float a;
+
+ switch (s->data) {
+ case D_MAGNITUDE:
+ /* get magnitude */
+ a = magnitudes[y];
+ break;
+ case D_PHASE:
+ /* get phase */
+ a = phases[y];
+ break;
+ default:
+ av_assert0(0);
+ }
+
+ /* apply scale */
+ switch (s->scale) {
+ case LINEAR:
+ a = av_clipf(a, 0, 1);
+ break;
+ case SQRT:
+ a = av_clipf(sqrt(a), 0, 1);
+ break;
+ case CBRT:
+ a = av_clipf(cbrt(a), 0, 1);
+ break;
+ case FOURTHRT:
+ a = av_clipf(sqrt(sqrt(a)), 0, 1);
+ break;
+ case FIFTHRT:
+ a = av_clipf(pow(a, 0.20), 0, 1);
+ break;
+ case LOG:
+ a = 1 + log10(av_clipd(a, 1e-6, 1)) / 6; // zero = -120dBFS
+ break;
+ default:
+ av_assert0(0);
+ }
+
+ pick_color(s, yf, uf, vf, a, out);
+ }
+
+ return 0;
+}
+