aboutsummaryrefslogtreecommitdiffstats
path: root/src/libsdr
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2017-11-18 08:49:13 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2017-12-03 08:45:55 +0100
commit016e72d6d70ea64dfb47a5a73727960cec4fc53a (patch)
tree4564f95f34535d29ae133377173b667ccf7e79c3 /src/libsdr
parentab59a26a519d4bfb88f9ca6f882da8baab90a95a (diff)
Restructure: Move display from common code to 'libdisplay'
Diffstat (limited to 'src/libsdr')
-rw-r--r--src/libsdr/Makefile.am6
-rw-r--r--src/libsdr/display_iq.c280
-rw-r--r--src/libsdr/display_spectrum.c292
3 files changed, 2 insertions, 576 deletions
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 <jolly@eversberg.eu>
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <math.h>
-#include <pthread.h>
-#include <stdlib.h>
-#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 <jolly@eversberg.eu>
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#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;
-}
-
-