fosphor: Review the GL frequency mapping and switch zoom to {center,span}

Previously we were hiding the extrema bin, now we display it "half" on
each side which sort of maps better to the concept of circular spectrum

At the same time we move the zoom spec to {center,span} rather than
{start,stop} since it makes more sense and matches the channel specs

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This commit is contained in:
Sylvain Munaut 2020-01-31 10:21:53 +01:00
parent e8a64b7297
commit 09b31b4acf
4 changed files with 37 additions and 44 deletions

View File

@ -191,8 +191,8 @@ fosphor_render_defaults(struct fosphor_render *render)
render->histo_wf_ratio = 0.5f; render->histo_wf_ratio = 0.5f;
render->freq_n_div = 10; render->freq_n_div = 10;
render->freq_start = 0.0f; render->freq_center = 0.5f;
render->freq_stop = 1.0f; render->freq_span = 1.0f;
render->wf_span = 1.0f; render->wf_span = 1.0f;
} }

View File

@ -82,8 +82,8 @@ struct fosphor_render
int options; /*!< \brief Options (See FRO_??? constants) */ int options; /*!< \brief Options (See FRO_??? constants) */
float histo_wf_ratio; /*!< \brief Ratio histogram/waterfall ]0,1[ */ float histo_wf_ratio; /*!< \brief Ratio histogram/waterfall ]0,1[ */
int freq_n_div; /*!< \brief Number of frequency divisions */ int freq_n_div; /*!< \brief Number of frequency divisions */
float freq_start; /*!< \brief Frequency zoom start [0,1[ */ float freq_center; /*!< \brief Frequency zoom center ]0,1[ */
float freq_stop; /*!< \brief Frequency zoom stop ]0,1] */ float freq_span; /*!< \brief Frequency zoom span ]0,1] */
float wf_span; /*!< \brief Waterfall time zoom ]0,1] */ float wf_span; /*!< \brief Waterfall time zoom ]0,1] */
/*! \brief Displayed channels */ /*! \brief Displayed channels */

View File

@ -368,31 +368,30 @@ fosphor_gl_draw(struct fosphor *self, struct fosphor_render *render)
struct fosphor_gl_state *gl = self->gl; struct fosphor_gl_state *gl = self->gl;
struct freq_axis freq_axis; struct freq_axis freq_axis;
float x[2], y[2], u[2], v[2]; float x[2], y[2], u[2], v[2];
float tw, bw; float tw;
int i; int i;
/* Utils */ /* Utils */
tw = 1.0f / (float)FOSPHOR_FFT_LEN; /* Texel width */ tw = 1.0f / (float)(FOSPHOR_FFT_LEN); /* Texel width */
bw = 1.0f / (float)(FOSPHOR_FFT_LEN-1); /* Bin width (displayed) */
/* Texture mapping notes: /* Texture mapping notes:
* *
* - The texture have the "DC" bin at texel 0, however we want it to * - The texture have the "DC" bin at texel 0, however we want it to
* be displayed centered and to do so, texture coordinates are used. * be displayed centered and to do so, texture coordinates are used.
* - One of the bin is not displayed (the one at u=0.5f) because * - The center of the extrema bin (which is neither positive or
* it is neither positive freq, nor negative ones, but both. To * negative) is mapped to the border of the texture.
* compensate for this, the (1.0f - tw) factor is used.
* *
* Vertex mapping notes: * Vertex mapping notes:
* *
* - We want the vertex to appear at the center of the displayed bins * - We want the vertex to appear at the center of the displayed bins
* - The vertex 'X' coordinates are filled in by the display kernel as * - The vertex 'X' coordinates are filled in by the display kernel as
* ((bin #) ^ (N >> 1)) / (N >> 1) - 1 * ((bin #) ^ (N >> 1)) / (N >> 1) - 1
* - So the DC bin is 0.0f and the undisplayed bin is -1. The others * - So the DC bin is 0.0 and the undisplayed bin is -1.0. The others
* are spread between [ -1+2*tw to 1-2*tw ] * are spread between [ -1.0 + (tw/2.0) to 1.0 - (tw/2.0) ]
* - For display, that range is first remapped to [0 to 1], then to * - For display, that range is first remapped to [0 to 1], then to
* [ bw/2 to 1-bw/2 ] (where bw is normalized displayed bin width) * [ tw to 1-tw ] (we skip 1 tw on each side. One half tw because of
* so that each point maps to the center of the bin on the textures. * the half not displayed extrema bin, and another half to center
* inside the first displayed bin on each side)
* - Finally the zoom is applied and then the transform to map on the * - Finally the zoom is applied and then the transform to map on the
* requested screen area * requested screen area
*/ */
@ -406,8 +405,8 @@ fosphor_gl_draw(struct fosphor *self, struct fosphor_render *render)
y[0] = render->_y_wf[0]; y[0] = render->_y_wf[0];
y[1] = render->_y_wf[1]; y[1] = render->_y_wf[1];
u[0] = 0.5f + tw + ((1.0f - tw) * render->freq_start); u[0] = 0.5f + (tw / 2.0f) + render->freq_center - (render->freq_span / 2.0f);
u[1] = 0.5f + tw + ((1.0f - tw) * render->freq_stop); u[1] = 0.5f + (tw / 2.0f) + render->freq_center + (render->freq_span / 2.0f);
v[1] = (float)render->_wf_pos / 1024.0f; v[1] = (float)render->_wf_pos / 1024.0f;
v[0] = v[1] - render->wf_span; v[0] = v[1] - render->wf_span;
@ -440,8 +439,8 @@ fosphor_gl_draw(struct fosphor *self, struct fosphor_render *render)
y[0] = render->_y_histo[0]; y[0] = render->_y_histo[0];
y[1] = render->_y_histo[1]; y[1] = render->_y_histo[1];
u[0] = 0.5f + tw + ((1.0f - tw) * render->freq_start); u[0] = 0.5f + (tw / 2.0f) + render->freq_center - (render->freq_span / 2.0f);
u[1] = 0.5f + tw + ((1.0f - tw) * render->freq_stop); u[1] = 0.5f + (tw / 2.0f) + render->freq_center + (render->freq_span / 2.0f);
v[0] = 0.0f; v[0] = 0.0f;
v[1] = 1.0f; v[1] = 1.0f;
@ -487,8 +486,14 @@ fosphor_gl_draw(struct fosphor *self, struct fosphor_render *render)
int idx[2], len; int idx[2], len;
/* Select end-points */ /* Select end-points */
idx[0] = 1 + (int)ceilf (render->freq_start * (float)(FOSPHOR_FFT_LEN - 1) - 0.5f); idx[0] = ceilf ((float)(FOSPHOR_FFT_LEN) * (render->freq_center - (render->freq_span / 2.0f)));
idx[1] = 1 + (int)floorf(render->freq_stop * (float)(FOSPHOR_FFT_LEN - 1) - 0.5f); idx[1] = floorf((float)(FOSPHOR_FFT_LEN) * (render->freq_center + (render->freq_span / 2.0f)));
if (idx[0] < 1)
idx[0] = 1;
if (idx[1] >= FOSPHOR_FFT_LEN)
idx[1] = FOSPHOR_FFT_LEN - 1;
len = idx[1] - idx[0] + 1; len = idx[1] - idx[0] + 1;
/* Setup */ /* Setup */
@ -512,12 +517,12 @@ fosphor_gl_draw(struct fosphor *self, struct fosphor_render *render)
glTranslatef(0.0f, self->power.offset, 0.0f); glTranslatef(0.0f, self->power.offset, 0.0f);
/* Spectrum range selection */ /* Spectrum range selection */
glScalef(1.0f / (render->freq_stop - render->freq_start), 1.0f, 1.0f); glScalef(1.0f / render->freq_span, 1.0f, 1.0f);
glTranslatef(-render->freq_start, 0.0f, 0.0f); glTranslatef(- render->freq_center + render->freq_span / 2.0f, 0.0f, 0.0f);
/* Map the center of each N-1 bins */ /* Map the center of each N-1 bins */
glTranslatef(0.5f * bw, 0.0f, 0.0f); glTranslatef(tw, 0.0f, 0.0f);
glScalef(1.0f - bw, 1.0f, 1.0f); glScalef(1.0f - 2.0 * tw, 1.0f, 1.0f);
/* Spectrum x scaling to [0.0 -> 1.0] range */ /* Spectrum x scaling to [0.0 -> 1.0] range */
glTranslatef(0.5f, 0.0f, 0.0f); glTranslatef(0.5f, 0.0f, 0.0f);
@ -559,21 +564,14 @@ fosphor_gl_draw(struct fosphor *self, struct fosphor_render *render)
} }
/* Setup frequency axis */ /* Setup frequency axis */
if (render->freq_start != 0.0f || render->freq_stop != 1.0f) if (render->freq_center != 0.5f || render->freq_span != 1.0f)
{ {
/* The freq_{start,stop} have some imprecisions due to the floating double view_center = self->frequency.center + self->frequency.span * (double)(render->freq_center - 0.5f);
* point nature. To avoid this crapping the display of the axis, we double view_span = self->frequency.span * (double)render->freq_span;
* try to 'round' them */
double freq_start = round(1e7 * render->freq_start) / 1e7;
double freq_stop = round(1e7 * render->freq_stop) / 1e7;
double rel_center = ((freq_stop + freq_start) / 2.0) - 0.5;
double rel_span = (freq_stop - freq_start);
freq_axis_build(&freq_axis, freq_axis_build(&freq_axis,
self->frequency.center + rel_center * self->frequency.span, view_center,
self->frequency.span * rel_span, view_span,
render->freq_n_div render->freq_n_div
); );
} }

View File

@ -195,8 +195,6 @@ glfw_render(GLFWwindow *wnd)
static void static void
_update_fosphor(void) _update_fosphor(void)
{ {
float f;
/* Configure the screen zones */ /* Configure the screen zones */
if (g_as->zoom_enable) if (g_as->zoom_enable)
{ {
@ -231,11 +229,8 @@ _update_fosphor(void)
g_as->render_main.channels[0].center = (float)g_as->zoom_center; g_as->render_main.channels[0].center = (float)g_as->zoom_center;
g_as->render_main.channels[0].width = (float)g_as->zoom_width; g_as->render_main.channels[0].width = (float)g_as->zoom_width;
f = (float)(g_as->zoom_center - g_as->zoom_width / 2.0); g_as->render_zoom.freq_center = g_as->zoom_center;
g_as->render_zoom.freq_start = f > 0.0f ? (f < 1.0f ? f : 1.0f) : 0.0f; g_as->render_zoom.freq_span = g_as->zoom_width;
f = (float)(g_as->zoom_center + g_as->zoom_width / 2.0);
g_as->render_zoom.freq_stop = f > 0.0f ? (f < 1.0f ? f : 1.0f) : 0.0f;
/* Update render options */ /* Update render options */
fosphor_render_refresh(&g_as->render_main); fosphor_render_refresh(&g_as->render_main);