aboutsummaryrefslogtreecommitdiffstats
path: root/src/common/display_wave.c
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2017-05-31 08:35:13 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2017-06-10 13:08:24 +0200
commitaef4cf09977a7b58d0b3e3671da7aa6b3ae6405c (patch)
tree9ecd7c69b29d2bc24c517b4f7eb649d550c2f5c8 /src/common/display_wave.c
parente0534db15cb04360bb22e63ac5878d323f71ba34 (diff)
Make spectrum display nicer by plotting continuous lines between samples
Diffstat (limited to 'src/common/display_wave.c')
-rw-r--r--src/common/display_wave.c93
1 files changed, 80 insertions, 13 deletions
diff --git a/src/common/display_wave.c b/src/common/display_wave.c
index e5e48b2..b42c584 100644
--- a/src/common/display_wave.c
+++ b/src/common/display_wave.c
@@ -105,11 +105,11 @@ void display_wave_limit_scroll(int on)
*
* theoretical example: HEIGHT = 3 allows 5 steps
*
- * Line 0: -_
- * Line 1: -_
- * Line 2: -
+ * Line 0: '.
+ * Line 1: '.
+ * Line 2: '
*
- * HEIGHT is odd, so the center line's char is '-' (otherwise '_')
+ * HEIGHT is odd, so the center line's char is ''' (otherwise '.')
* (HEIGHT - 1) / 2 = 1, so the center line is drawn in line 1
*
* y is in range of 0..4, so these are 5 steps, where 2 is the
@@ -120,7 +120,8 @@ void display_wave(sender_t *sender, sample_t *samples, int length, double range)
dispwav_t *disp = &sender->dispwav;
int pos, max;
sample_t *buffer;
- int i, j, k, y;
+ int i, j, k, s, e;
+ double last, current, next;
int color = 9; /* default color */
int center_line;
char center_char;
@@ -133,20 +134,20 @@ void display_wave(sender_t *sender, sample_t *samples, int length, double range)
/* at what line we draw our zero-line and what character we use */
center_line = (HEIGHT - 1) >> 1;
- center_char = (HEIGHT & 1) ? '-' : '_';
+ center_char = (HEIGHT & 1) ? '\'' : '.';
pos = disp->interval_pos;
max = disp->interval_max;
buffer = disp->buffer;
for (i = 0; i < length; i++) {
- if (pos >= width) {
+ if (pos >= width + 2) {
if (++pos == max)
pos = 0;
continue;
}
buffer[pos++] = samples[i];
- if (pos == width) {
+ if (pos == width + 2) {
memset(&screen, ' ', sizeof(screen));
for (j = 0; j < width; j++) {
/* Input value is scaled to range -1 .. 1 and then substracted from 1,
@@ -156,10 +157,76 @@ void display_wave(sender_t *sender, sample_t *samples, int length, double range)
* We always use odd number of steps, so there will be a center between
* values.
*/
- y = round((1.0 - buffer[j] / range) * (double)(HEIGHT - 1));
- /* only display level, if it is in range */
- if (y >= 0 && y < HEIGHT * 2 - 1)
- screen[y >> 1][j] = (y & 1) ? '_' : '-';
+ last = (1.0 - buffer[j] / range) * (double)(HEIGHT - 1);
+ current = (1.0 - buffer[j + 1] / range) * (double)(HEIGHT - 1);
+ next = (1.0 - buffer[j + 2] / range) * (double)(HEIGHT - 1);
+ /* calculate start and end for vertical line
+ * if the current value is a peak (above or below last AND next point),
+ * round this peak point to become one end of the vertical line.
+ * the other end is rounded up or down, so the end of the line will
+ * not overlap with the ends of the surrounding lines.
+ */
+ if (last > current) {
+ if (next > current) {
+ /* current point is a peak up */
+ s = round(current);
+ /* use lowest neighbor point and end is half way */
+ if (last > next)
+ e = floor((last + current) / 2.0);
+ else
+ e = floor((next + current) / 2.0);
+ /* end point must not be above start point */
+ if (e < s)
+ e = s;
+ } else {
+ /* current point is a transition upwards */
+ s = ceil((next + current) / 2.0);
+ e = floor((last + current) / 2.0);
+ /* end point must not be above start point */
+ if (e < s)
+ s = e = round(current);
+ }
+ } else {
+ if (next <= current) {
+ /* current point is a peak down */
+ e = round(current);
+ /* use heighes neighbor point and start is half way */
+ if (last <= next)
+ s = ceil((last + current) / 2.0);
+ else
+ s = ceil((next + current) / 2.0);
+ /* start point must not be below end point */
+ if (s > e)
+ s = e;
+ } else {
+ /* current point is a transition downwards */
+ s = ceil((last + current) / 2.0);
+ e = floor((next + current) / 2.0);
+ /* start point must not be below end point */
+ if (s > e)
+ s = e = round(current);
+ }
+ }
+ /* only draw line, if it is in range */
+ if (e >= 0 && s < HEIGHT * 2 - 1) {
+ /* clip */
+ if (s < 0)
+ s = 0;
+ if (e >= HEIGHT * 2 - 1)
+ e = HEIGHT * 2 - 1;
+ /* plot start and end point */
+ if ((s & 1))
+ screen[s >> 1][j] = '.';
+ else if (e != s)
+ screen[s >> 1][j] = '|';
+ if (!(e & 1))
+ screen[e >> 1][j] = '\'';
+ else if (e != s)
+ screen[e >> 1][j] = '|';
+ /* plot line between start and end point */
+ for (k = (s >> 1) + 1; k < (e >> 1); k++)
+ screen[k][j] = '|';
+ }
}
sprintf(screen[0], "(chan %d", sender->kanal);
*strchr(screen[0], '\0') = ')';
@@ -175,7 +242,7 @@ void display_wave(sender_t *sender, sample_t *samples, int length, double range)
printf("\033[0;34m");
}
putchar(center_char);
- } else if (screen[j][k] == '-' || screen[j][k] == '_') {
+ } else if (screen[j][k] == '\'' || screen[j][k] == '.' || screen[j][k] == '|') {
/* green scope curve */
if (color != 2) {
color = 2;