From 016e72d6d70ea64dfb47a5a73727960cec4fc53a Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 18 Nov 2017 08:49:13 +0100 Subject: Restructure: Move display from common code to 'libdisplay' --- src/libsdr/Makefile.am | 6 +- src/libsdr/display_iq.c | 280 ---------------------------------------- src/libsdr/display_spectrum.c | 292 ------------------------------------------ 3 files changed, 2 insertions(+), 576 deletions(-) delete mode 100644 src/libsdr/display_iq.c delete mode 100644 src/libsdr/display_spectrum.c (limited to 'src/libsdr') diff --git a/src/libsdr/Makefile.am b/src/libsdr/Makefile.am index 5a00457..1d9f4fc 100644 --- a/src/libsdr/Makefile.am +++ b/src/libsdr/Makefile.am @@ -3,10 +3,8 @@ AM_CPPFLAGS = -Wall -Wextra -g $(all_includes) noinst_LIBRARIES = libsdr.a libsdr_a_SOURCES = \ -dd sdr_config.c \ - sdr.c \ - display_iq.c \ - display_spectrum.c + sdr_config.c \ + sdr.c AM_CPPFLAGS += -DHAVE_SDR diff --git a/src/libsdr/display_iq.c b/src/libsdr/display_iq.c deleted file mode 100644 index c6ab910..0000000 --- a/src/libsdr/display_iq.c +++ /dev/null @@ -1,280 +0,0 @@ -/* display IQ data form functions - * - * (C) 2016 by Andreas Eversberg - * All Rights Reserved - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include "../libsample/sample.h" -#include "../libmobile/sender.h" - -/* must be odd value! */ -#define SIZE 23 - -static char screen[SIZE][MAX_DISPLAY_WIDTH]; -static uint8_t screen_color[SIZE][MAX_DISPLAY_WIDTH]; -static uint8_t screen_history[SIZE * 2][MAX_DISPLAY_WIDTH]; -static int iq_on = 0; -static double db = 80; - -static dispiq_t disp; - -void display_iq_init(int samplerate) -{ - memset(&disp, 0, sizeof(disp)); - memset(&screen_history, 0, sizeof(screen_history)); - disp.interval_max = (double)samplerate * DISPLAY_INTERVAL + 0.5; - /* should not happen due to low interval */ - if (disp.interval_max < MAX_DISPLAY_IQ - 1) - disp.interval_max = MAX_DISPLAY_IQ - 1; -} - -void display_iq_on(int on) -{ - int j; - int w, h; - - get_win_size(&w, &h); - - if (iq_on) { - memset(&screen, ' ', sizeof(screen)); - memset(&screen_history, 0, sizeof(screen_history)); - printf("\0337\033[H"); - for (j = 0; j < SIZE; j++) { - screen[j][w] = '\0'; - puts(screen[j]); - } - printf("\0338"); fflush(stdout); - } - - if (on < 0) { - if (++iq_on == 3) - iq_on = 0; - } else - iq_on = on; -} - -void display_iq_limit_scroll(int on) -{ - int w, h; - - if (!iq_on) - return; - - get_win_size(&w, &h); - - printf("\0337"); - printf("\033[%d;%dr", (on) ? SIZE + 1 : 1, h); - printf("\0338"); -} - -/* - * plot IQ data: - * - * theoretical example: SIZE = 3 allows 6 steps plotted as dots - * - * Line 0: : - * Line 1: : - * Line 2: : - * - * The level of -1.0 .. 1.0 is scaled to -3 and 3. - * - * The lowest of the upper 3 dots ranges from 0.0 .. <1.5. - * The upper most dot ranges from 2.5 .. <3.5. - * The highest of the lower 3 dots ranges from <0.0 .. >-1.5; - * The lower most dot ranges from -2.5 .. >-3.5. - * - * The center column ranges from -0.5 .. <0.5. - * The columns about the center from -1.5 .. <1.5. - */ -void display_iq(float *samples, int length) -{ - int pos, max; - float *buffer; - int i, j, k; - int color = 9; /* default color */ - int x_center, y_center; - double I, Q, L, l, s; - int x, y; - int v, r; - int width, h; - - if (!iq_on) - return; - - get_win_size(&width, &h); - - /* at what line we draw our zero-line and what character we use */ - x_center = width >> 1; - y_center = (SIZE - 1) >> 1; - - pos = disp.interval_pos; - max = disp.interval_max; - buffer = disp.buffer; - - for (i = 0; i < length; i++) { - if (pos >= MAX_DISPLAY_IQ) { - if (++pos == max) - pos = 0; - continue; - } - buffer[pos * 2] = samples[i * 2]; - buffer[pos * 2 + 1] = samples[i * 2 + 1]; - pos++; - if (pos == MAX_DISPLAY_IQ) { - memset(&screen, ' ', sizeof(screen)); - memset(&screen_color, 7, sizeof(screen_color)); - /* render screen history to screen */ - for (y = 0; y < SIZE * 2; y++) { - for (x = 0; x < width; x++) { - v = screen_history[y][x]; - v -= 8; - if (v < 0) - v = 0; - screen_history[y][x] = v; - r = random() & 0x3f; - if (r >= v) - continue; - if (screen[y/2][x] == ':') - continue; - if (screen[y/2][x] == '.') { - if ((y & 1) == 0) - screen[y/2][x] = ':'; - continue; - } - if (screen[y/2][x] == '\'') { - if ((y & 1)) - screen[y/2][x] = ':'; - continue; - } - if ((y & 1) == 0) - screen[y/2][x] = '\''; - else - screen[y/2][x] = '.'; - screen_color[y/2][x] = 4; - } - } - /* plot current IQ date */ - for (j = 0; j < MAX_DISPLAY_IQ; j++) { - I = buffer[j * 2]; - Q = buffer[j * 2 + 1]; - L = I*I + Q*Q; - if (iq_on > 1) { - /* logarithmic scale */ - l = sqrt(L); - s = log10(l) * 20 + db; - if (s < 0) - s = 0; - I = (I / l) * (s / db); - Q = (Q / l) * (s / db); - } - x = x_center + (int)(I * (double)SIZE + (double)width + 0.5) - width; - if (x < 0) - continue; - if (x > width - 1) - continue; - if (Q >= 0) - y = SIZE - 1 - (int)(Q * (double)SIZE - 0.5); - else - y = SIZE - (int)(Q * (double)SIZE + 0.5); - if (y < 0) - continue; - if (y > SIZE * 2 - 1) - continue; - if (screen[y/2][x] == ':' && screen_color[y/2][x] >= 10) - goto cont; - if (screen[y/2][x] == '.' && screen_color[y/2][x] >= 10) { - if ((y & 1) == 0) - screen[y/2][x] = ':'; - goto cont; - } - if (screen[y/2][x] == '\'' && screen_color[y/2][x] >= 10) { - if ((y & 1)) - screen[y/2][x] = ':'; - goto cont; - } - if ((y & 1) == 0) - screen[y/2][x] = '\''; - else - screen[y/2][x] = '.'; -cont: - screen_history[y][x] = 255; - /* overdrive: - * red = close to -1..1 or above - * yellow = close to -0.5..0.5 or above - * Note: L is square of vector length, - * so we compare with square values. - */ - if (L > 0.9 * 0.9) - screen_color[y/2][x] = 11; - else if (L > 0.45 * 0.45 && screen_color[y/2][x] != 11) - screen_color[y/2][x] = 13; - else if (screen_color[y/2][x] < 10) - screen_color[y/2][x] = 12; - } - if (iq_on == 1) - sprintf(screen[0], "(IQ linear"); - else - sprintf(screen[0], "(IQ log %.0f dB", db); - *strchr(screen[0], '\0') = ')'; - printf("\0337\033[H"); - for (j = 0; j < SIZE; j++) { - for (k = 0; k < width; k++) { - if ((j == y_center || k == x_center) && screen[j][k] == ' ') { - /* cross */ - if (color != 4) { - color = 4; - printf("\033[0;34m"); - } - if (j == y_center) { - if (k == x_center) - putchar('o'); - else if (k == x_center - SIZE) - putchar('+'); - else if (k == x_center + SIZE) - putchar('+'); - else - putchar('-'); - } else { - if (j == 0 || j == SIZE - 1) - putchar('+'); - else - putchar('|'); - } - } else { - if (screen_color[j][k] != color) { - color = screen_color[j][k]; - printf("\033[%d;3%dm", color / 10, color % 10); - } - putchar(screen[j][k]); - } - } - printf("\n"); - } - /* reset color and position */ - printf("\033[0;39m\0338"); fflush(stdout); - } - } - - disp.interval_pos = pos; -} - - diff --git a/src/libsdr/display_spectrum.c b/src/libsdr/display_spectrum.c deleted file mode 100644 index 3c885b7..0000000 --- a/src/libsdr/display_spectrum.c +++ /dev/null @@ -1,292 +0,0 @@ -/* display spectrum of IQ data - * - * (C) 2016 by Andreas Eversberg - * All Rights Reserved - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include "../libsample/sample.h" -#include "../libmobile/sender.h" -#include "../libfft/fft.h" - -#define HEIGHT 20 - -static double buffer_max[MAX_DISPLAY_SPECTRUM]; -static char screen[HEIGHT][MAX_DISPLAY_WIDTH]; -static uint8_t screen_color[HEIGHT][MAX_DISPLAY_WIDTH]; -static int spectrum_on = 0; -static double db = 120; -static double center_frequency, frequency_range; - -static dispspectrum_t disp; - -void display_spectrum_init(int samplerate, double _center_frequency) -{ - memset(&disp, 0, sizeof(disp)); - disp.interval_max = (double)samplerate * DISPLAY_INTERVAL + 0.5; - /* should not happen due to low interval */ - if (disp.interval_max < MAX_DISPLAY_SPECTRUM - 1) - disp.interval_max = MAX_DISPLAY_SPECTRUM - 1; - memset(buffer_max, 0, sizeof(buffer_max)); - - center_frequency = _center_frequency; - frequency_range = (double)samplerate; -} - -void display_spectrum_on(int on) -{ - int j; - int w, h; - - get_win_size(&w, &h); - - if (spectrum_on) { - memset(&screen, ' ', sizeof(screen)); - printf("\0337\033[H"); - for (j = 0; j < HEIGHT; j++) { - screen[j][w] = '\0'; - puts(screen[j]); - } - printf("\0338"); fflush(stdout); - } - - if (on < 0) { - if (++spectrum_on == 2) - spectrum_on = 0; - } else - spectrum_on = on; -} - -void display_spectrum_limit_scroll(int on) -{ - int w, h; - - if (!spectrum_on) - return; - - get_win_size(&w, &h); - - printf("\0337"); - printf("\033[%d;%dr", (on) ? HEIGHT + 1 : 1, h); - printf("\0338"); -} - -/* - * plot spectrum data: - * - */ -void display_spectrum(float *samples, int length) -{ - sender_t *sender; - char print_channel[32], print_frequency[32]; - int width, h; - int pos, max; - double *buffer_I, *buffer_Q; - int color = 9; /* default color */ - int i, j, k, o; - double I, Q, v; - int s, e, l, n; - - if (!spectrum_on) - return; - - get_win_size(&width, &h); - if (width > MAX_DISPLAY_WIDTH) - width = MAX_DISPLAY_WIDTH; - - /* calculate size of FFT */ - int m, fft_size = 0, fft_taps = 0; - for (m = 0; m < 16; m++) { - if ((1 << m) > MAX_DISPLAY_SPECTRUM) - break; - if ((1 << m) <= width) { - fft_taps = m; - fft_size = 1 << m; - } - } - if (m == 16) { - fprintf(stderr, "Size of spectrum is not a power of 2, please fix!\n"); - abort(); - } - - int heigh[fft_size], low[fft_size]; - - pos = disp.interval_pos; - max = disp.interval_max; - buffer_I = disp.buffer_I; - buffer_Q = disp.buffer_Q; - - for (i = 0; i < length; i++) { - if (pos >= fft_size) { - if (++pos == max) - pos = 0; - continue; - } - buffer_I[pos] = samples[i * 2]; - buffer_Q[pos] = samples[i * 2 + 1]; - pos++; - if (pos == fft_size) { - fft_process(1, fft_taps, buffer_I, buffer_Q); - k = 0; - for (j = 0; j < fft_size; j++) { - /* scale result vertically */ - I = buffer_I[(j + fft_size / 2) % fft_size]; - Q = buffer_Q[(j + fft_size / 2) % fft_size]; - v = sqrt(I*I + Q*Q); - v = log10(v) * 20 + db; - if (v < 0) - v = 0; - v /= db; - buffer_max[j] -= DISPLAY_INTERVAL / 10.0; - if (v > buffer_max[j]) - buffer_max[j] = v; - - /* heigh is the maximum value */ - heigh[j] = (double)(HEIGHT * 2 - 1) * (1.0 - buffer_max[j]); - if (heigh[j] < 0) - heigh[j] = 0; - if (heigh[j] >= (HEIGHT * 2)) - heigh[j] = (HEIGHT * 2) - 1; - /* low is the current value */ - low[j] = (double)(HEIGHT * 2 - 1) * (1.0 - v); - if (low[j] < 0) - low[j] = 0; - if (low[j] >= (HEIGHT * 2)) - low[j] = (HEIGHT * 2) - 1; - } - /* plot scaled buffer */ - memset(&screen, ' ', sizeof(screen)); - memset(&screen_color, 7, sizeof(screen_color)); /* all white */ - sprintf(screen[0], "(spectrum log %.0f dB", db); - *strchr(screen[0], '\0') = ')'; - o = (width - fft_size) / 2; /* offset from left border */ - for (j = 0; j < fft_size; j++) { - s = l = n = low[j]; - /* get last and next value */ - if (j > 0) - l = (low[j - 1] + s) / 2; - if (j < fft_size - 1) - n = (low[j + 1] + s) / 2; - if (s > l && s > n) { - /* current value is a minimum */ - e = s; - s = (l < n) ? (l + 1) : (n + 1); - } else if (s < l && s < n) { - /* current value is a maximum */ - e = (l > n) ? l : n; - } else if (l < n) { - /* last value is higher, next value is lower */ - s = l + 1; - e = n; - } else if (l > n) { - /* last value is lower, next value is higher */ - s = n + 1; - e = l; - } else { - /* current, last and next values are equal */ - e = s; - } - if (s == e) { - if ((s & 1) == 0) - screen[s >> 1][j + o] = '\''; - else - screen[s >> 1][j + o] = '.'; - screen_color[s >> 1][j + o] = 13; - } else { - if ((s & 1) == 0) - screen[s >> 1][j + o] = '|'; - else - screen[s >> 1][j + o] = '.'; - screen_color[s >> 1][j + o] = 13; - if ((e & 1) == 0) - screen[e >> 1][j + o] = '\''; - else - screen[e >> 1][j + o] = '|'; - screen_color[e >> 1][j + o] = 13; - for (k = (s >> 1) + 1; k < (e >> 1); k++) { - screen[k][j + o] = '|'; - screen_color[k][j + o] = 13; - } - } - e = s; - s = heigh[j]; - if ((s >> 1) < (e >> 1)) { - if ((s & 1) == 0) - screen[s >> 1][j + o] = '|'; - else - screen[s >> 1][j + o] = '.'; - screen_color[s >> 1][j + o] = 4; - for (k = (s >> 1) + 1; k < (e >> 1); k++) { - screen[k][j + o] = '|'; - screen_color[k][j + o] = 4; - } - } - } - for (sender = sender_head; sender; sender = sender->next) { - j = (int)((sender->empfangsfrequenz - center_frequency) / frequency_range * (double) fft_size + width / 2 + 0.5); - if (j < 0 || j >= width) /* check out-of-range, should not happen */ - continue; - for (k = 0; k < HEIGHT; k++) { - /* skip yellow graph */ - if (screen_color[k][j] == 13) - continue; - screen[k][j] = ':'; - screen_color[k][j] = 12; - } - sprintf(print_channel, "Ch%d", sender->kanal); - for (o = 0; o < (int)strlen(print_channel); o++) { - s = j - strlen(print_channel) + o; - if (s >= 0 && s < width) { - screen[HEIGHT - 1][s] = print_channel[o]; - screen_color[HEIGHT - 1][s] = 7; - } - } - if (fmod(sender->empfangsfrequenz, 1000.0)) - sprintf(print_frequency, "%.4f", sender->empfangsfrequenz / 1e6); - else - sprintf(print_frequency, "%.3f", sender->empfangsfrequenz / 1e6); - for (o = 0; o < (int)strlen(print_frequency); o++) { - s = j + o + 1; - if (s >= 0 && s < width) { - screen[HEIGHT - 1][s] = print_frequency[o]; - screen_color[HEIGHT - 1][s] = 7; - } - } - } - printf("\0337\033[H"); - for (j = 0; j < HEIGHT; j++) { - for (k = 0; k < width; k++) { - if (screen_color[j][k] != color) { - color = screen_color[j][k]; - printf("\033[%d;3%dm", color / 10, color % 10); - } - putchar(screen[j][k]); - } - printf("\n"); - } - /* reset color and position */ - printf("\033[0;39m\0338"); fflush(stdout); - } - } - - disp.interval_pos = pos; -} - - -- cgit v1.2.3