aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFreeArtMan <dos21h@gmail.com>2015-10-01 19:54:52 +0100
committerFreeArtMan <dos21h@gmail.com>2015-10-01 19:54:52 +0100
commit240c02c5d64ee02659d0bcbbc61ef3680cbf8ea2 (patch)
treed8bc56d6d66b92b03334aec3b64b50403704eb4a
parent588b76e576108a82bcf7abb660def28b4a99ba5a (diff)
downloadradiola-240c02c5d64ee02659d0bcbbc61ef3680cbf8ea2.tar.gz
radiola-240c02c5d64ee02659d0bcbbc61ef3680cbf8ea2.zip
Added SDL waterfall prototype api
-rw-r--r--draw/glui.c121
-rw-r--r--draw/glui.h9
-rw-r--r--draw/make.mk2
-rw-r--r--test/Makefile2
-rw-r--r--test/ui_gl_waterfall.c251
-rw-r--r--test/ui_tui_waterfall.c4
6 files changed, 384 insertions, 5 deletions
diff --git a/draw/glui.c b/draw/glui.c
index e69de29..3e85646 100644
--- a/draw/glui.c
+++ b/draw/glui.c
@@ -0,0 +1,121 @@
+#include "glui.h"
+
+#define DEFAULT_TITLE "RADIOLA"
+#define SCREEN_X 640
+#define SCREEN_Y 480
+
+int glui_init( glui_t **t )
+{
+ int ret=-1;
+
+ glui_t *tui = NULL;
+
+ tui = malloc( sizeof(glui_t) );
+ if (tui == NULL)
+ {
+ return -1;
+ }
+
+ memset(tui, 0, sizeof(glui_t));
+
+ if ( SDL_Init(SDL_INIT_VIDEO) != 0)
+ {
+ printf("Cannot init sdl\n");
+ return -1;
+ }
+
+ tui->win = SDL_CreateWindow("Hello World!", 100, 100, SCREEN_X, SCREEN_Y, SDL_WINDOW_SHOWN);
+ if (tui->win == NULL)
+ {
+ printf("Couldnt create SDL window\n");
+ return -1;
+ }
+
+ tui->rend = SDL_CreateRenderer( tui->win, -1, SDL_RENDERER_ACCELERATED);
+
+
+
+ return ret;
+}
+
+
+//init waterfall
+int glui_waterfall( glui_t **t, glui_waterfall_t **w )
+{
+ int ret=-1;
+
+
+ return ret;
+}
+
+
+//first draw, draw all buffer
+int glui_waterfall_draw( glui_waterfall_t *w )
+{
+ int ret=-1;
+
+
+ return ret;
+}
+
+
+//redraw only changed lines
+int glui_waterfall_redraw( glui_waterfall_t *w )
+{
+ int ret=-1;
+
+
+ return ret;
+}
+
+
+//update params of waterfall and then need to draw not redraw
+int glui_waterfall_update( glui_t *w )
+{
+ int ret=-1;
+
+
+ return ret;
+}
+
+
+//push one line of data to buffer
+int glui_waterfall_data( glui_t *w, int len, uint8_t *buf )
+{
+ int ret=-1;
+
+
+ return ret;
+}
+
+
+//return color
+uint8_t glui_waterfall_color( uint8_t d )
+{
+ uint8_t c;
+
+
+ return c;
+}
+
+
+//close terminal ui
+int glui_close( glui_t *t )
+{
+ int ret=0;
+
+ if ( t->rend )
+ {
+ SDL_DestroyRenderer( t->rend );
+ }
+
+ if ( t->win != NULL )
+ {
+ SDL_DestroyWindow( t->win );
+ }
+
+ SDL_Quit();
+
+
+ return ret;
+} \ No newline at end of file
diff --git a/draw/glui.h b/draw/glui.h
index d55f931..f9f9bdf 100644
--- a/draw/glui.h
+++ b/draw/glui.h
@@ -8,6 +8,8 @@
#include <termios.h>
#include <unistd.h>
+#include <SDL2/SDL.h>
+
//to draw waterfall
typedef struct glui_waterfall_t
{
@@ -19,6 +21,9 @@ typedef struct glui_waterfall_t
typedef struct glui_t
{
+ SDL_Window *win;
+ SDL_Renderer *rend;
+
glui_waterfall_t *wf;
} glui_t;
@@ -37,4 +42,6 @@ int glui_waterfall_data( glui_t *w, int len, uint8_t *buf );
//return color
uint8_t glui_waterfall_color( uint8_t d );
//close terminal ui
-int glui_close( glui_t *t ); \ No newline at end of file
+int glui_close( glui_t *t );
+
+#endif \ No newline at end of file
diff --git a/draw/make.mk b/draw/make.mk
index 9756446..1c60780 100644
--- a/draw/make.mk
+++ b/draw/make.mk
@@ -1,7 +1,7 @@
DIR_DRAW = draw/
SOURCES_DRAW += draw/glui.c draw/tui.c draw/ui.c
OBJECTS_DRAW += $(SOURCES_DRAW:.c=.o)
-LDFLAGS += -lGL
+LDFLAGS += -lGL `sdl2-config --cflags --libs`
OBJECTS_DIR_DRAW += $(subst $(DIR_DRAW),$(BUILD_DIR)$(DIR_DRAW),$(OBJECTS_DRAW))
diff --git a/test/Makefile b/test/Makefile
index 348fd86..d14f27d 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,7 +1,7 @@
CC=gcc
CFLAGS=-I../
#LDFLAGS= `pkg-config --libs libusb` -L../../../r820t -lr820t -Wl,-rpath=../../../r820t
-LDFLAGS=`pkg-config --libs libusb` -lrtlsdr -lm ../radiola.o
+LDFLAGS=`pkg-config --libs libusb` `sdl2-config --cflags --libs` -lrtlsdr -lm ../radiola.o
SOURCE = $(wildcard *.c)
OBJECTS =
BIN = $(SOURCE:.c=)
diff --git a/test/ui_gl_waterfall.c b/test/ui_gl_waterfall.c
index 40872c8..1af4096 100644
--- a/test/ui_gl_waterfall.c
+++ b/test/ui_gl_waterfall.c
@@ -1,7 +1,258 @@
#include <stdio.h>
#include <stdlib.h>
+#include <math.h>
+
+//radiola
+#include <draw/tui.h>
+#include <hw/hw.h>
+
+#define SAMPLE_RATE 2048000
+
+#define CENTER_FREQ 446500000
+#define FFT_LEVEL 10
+#define FFT_SIZE (1 << FFT_LEVEL)
+#define BUF_LENGHT (2 * FFT_SIZE)
+#define PRESCALE 8
+#define POSTSCALE 2
+
+static rtlsdr_dev_t *dev = NULL;
+
+int16_t* Sinewave;
+int N_WAVE, LOG2_N_WAVE;
+double* power_table;
+
+int sdr_init()
+{
+ int ret;
+ uint32_t dev_index = 0;
+
+ //open tunner
+ ret = rtlsdr_open(&dev, (uint32_t)dev_index);
+ if ( ret < 0 )
+ {
+ printf("Cannot open device %02d\n", dev_index );
+ return -1;
+ }
+
+ ret = rtlsdr_reset_buffer(dev);
+ if ( ret < 0 )
+ {
+ printf("Couldnt reset buffer\n");
+ return -1;
+ }
+
+ ret = rtlsdr_set_sample_rate(dev, SAMPLE_RATE);
+ if ( ret < 0 )
+ {
+ printf("Coulnt set sample rate to %d\n", SAMPLE_RATE);
+ return -1;
+ }
+
+ ret = rtlsdr_set_center_freq( dev, CENTER_FREQ );
+ if ( ret < 0 )
+ {
+ printf("Couldnt set freq %d\n", CENTER_FREQ);
+ return -1;
+ }
+
+ ret = rtlsdr_set_tuner_gain_mode( dev, 1 );
+ if ( ret < 0 )
+ {
+ printf("Cannot set auto gain mode\n");
+ return -1;
+ }
+
+ ret = rtlsdr_set_agc_mode( dev, 1);
+ if ( ret < 0 )
+ {
+ printf("Cannot set agc mode\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int sdr_close()
+{
+ //close tunner
+ if ( dev != NULL)
+ {
+ rtlsdr_close( dev );
+ dev = NULL;
+ return 0;
+ }
+ return -1;
+}
+
+int sdr_get_samples( uint8_t *buf, int len )
+{
+ int ret, read_num;
+
+ ret = rtlsdr_read_sync( dev, buf, len, &read_num );
+ if (ret < 0)
+ {
+ printf("sync read failed\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+//better to have size size mod olen == 0
+int normalise( uint8_t *ibuf, int ilen, uint8_t *obuf, int olen )
+{
+ int i,j,m;
+ int ppi;
+
+ if ( ilen >= olen )
+ {
+ ppi = ilen / olen;
+ } else {
+ return -1;
+ }
+ m = 0;
+ i = 0;
+ while ( (i < ilen) && (m < olen) )
+ {
+ uint32_t sum=0;
+ for ( j=0; j<ppi; j++ );
+ sum += ibuf[i+j];
+ sum /= ppi;
+ obuf[m] = sum;
+ //printf("%d-", obuf[m] );
+
+ i += ppi;
+ m += 1;
+ }
+
+ return 0;
+}
+
+void sine_table(int size)
+{
+ int i;
+ double d;
+ LOG2_N_WAVE = size;
+ N_WAVE = 1 << LOG2_N_WAVE;
+ Sinewave = malloc(sizeof(int16_t) * N_WAVE*3/4);
+ power_table = malloc(sizeof(double) * N_WAVE);
+ for (i=0; i<N_WAVE*3/4; i++)
+ {
+ d = (double)i * 2.0 * M_PI / N_WAVE;
+ Sinewave[i] = (int)round(32767*sin(d));
+ }
+}
+
+int16_t FIX_MPY(int16_t a, int16_t b)
+/* fixed point multiply and scale */
+{
+ int c = ((int)a * (int)b) >> 14;
+ b = c & 0x01;
+ return (c >> 1) + b;
+}
+
+int32_t real_conj(int16_t real, int16_t imag)
+/* real(n * conj(n)) */
+{
+ return ((int32_t)real*(int32_t)real + (int32_t)imag*(int32_t)imag);
+}
+
+int fix_fft(int16_t iq[], int m)
+/* interleaved iq[], 0 <= n < 2**m, changes in place */
+{
+ int mr, nn, i, j, l, k, istep, n, shift;
+ int16_t qr, qi, tr, ti, wr, wi;
+ n = 1 << m;
+ if (n > N_WAVE)
+ {return -1;}
+ mr = 0;
+ nn = n - 1;
+ /* decimation in time - re-order data */
+ for (m=1; m<=nn; ++m) {
+ l = n;
+ do
+ {l >>= 1;}
+ while (mr+l > nn);
+ mr = (mr & (l-1)) + l;
+ if (mr <= m)
+ {continue;}
+ // real = 2*m, imag = 2*m+1
+ tr = iq[2*m];
+ iq[2*m] = iq[2*mr];
+ iq[2*mr] = tr;
+ ti = iq[2*m+1];
+ iq[2*m+1] = iq[2*mr+1];
+ iq[2*mr+1] = ti;
+ }
+ l = 1;
+ k = LOG2_N_WAVE-1;
+ while (l < n) {
+ shift = 1;
+ istep = l << 1;
+ for (m=0; m<l; ++m) {
+ j = m << k;
+ wr = Sinewave[j+N_WAVE/4];
+ wi = -Sinewave[j];
+ if (shift) {
+ wr >>= 1; wi >>= 1;}
+ for (i=m; i<n; i+=istep) {
+ j = i + l;
+ tr = FIX_MPY(wr,iq[2*j]) - FIX_MPY(wi,iq[2*j+1]);
+ ti = FIX_MPY(wr,iq[2*j+1]) + FIX_MPY(wi,iq[2*j]);
+ qr = iq[2*i];
+ qi = iq[2*i+1];
+ if (shift) {
+ qr >>= 1; qi >>= 1;}
+ iq[2*j] = qr - tr;
+ iq[2*j+1] = qi - ti;
+ iq[2*i] = qr + tr;
+ iq[2*i+1] = qi + ti;
+ }
+ }
+ --k;
+ l = istep;
+ }
+ return 0;
+}
+
+//fftize
+int simple_fft( uint8_t *buf, int len )
+{
+ int i,j;
+ uint16_t p;
+ int fft_len;
+
+ for (i=0; i<len; i++)
+ {
+ buf[i] = buf[i] * PRESCALE;
+ }
+
+ fix_fft( (uint16_t *)buf, FFT_LEVEL );
+
+ for (i=0; i<FFT_SIZE; i++)
+ {
+ //buf1[i] = rtl_out.buf[i];
+ //p = buf1[i] * buf1[i];
+ j = i*2;
+ p = (int16_t)real_conj(buf[j], buf[j + 1]);
+ buf[i] += p;
+ }
+
+ fft_len = FFT_SIZE / 2;
+ for (i=0; i<fft_len; i++)
+ {
+ buf[i] = (int)log10(POSTSCALE * (float)buf[i+fft_len]);
+ buf[i+fft_len] = (int)log10(POSTSCALE * (float)buf[i]);
+ }
+
+ return 0;
+}
int main()
{
+
+
+
return 0;
} \ No newline at end of file
diff --git a/test/ui_tui_waterfall.c b/test/ui_tui_waterfall.c
index 43a21e9..fe009eb 100644
--- a/test/ui_tui_waterfall.c
+++ b/test/ui_tui_waterfall.c
@@ -9,7 +9,7 @@
#define SAMPLE_RATE 2048000
-#define CENTER_FREQ 100500000
+#define CENTER_FREQ 446500000
#define FFT_LEVEL 10
#define FFT_SIZE (1 << FFT_LEVEL)
#define BUF_LENGHT (2 * FFT_SIZE)
@@ -333,4 +333,4 @@ main_exit:
sdr_close();
return 0;
-} \ No newline at end of file
+}