From e42911405c4bc2f8c097f47d4598baf8522ef3da Mon Sep 17 00:00:00 2001
From: FreeArtMan <dos21h@gmail.com>
Date: Sun, 8 May 2016 16:02:01 +0100
Subject: Moved source to src directory

---
 src/Kconfig               |  11 ++
 src/codec/Kconfig         |   0
 src/config.h              |  15 +++
 src/config/config_bsd.h   |  11 ++
 src/config/config_linux.h |  14 +++
 src/core/Kconfig          |  28 +++++
 src/core/make.mk          |  11 ++
 src/core/math.c           |  48 +++++++
 src/core/math.h           |  16 +++
 src/draw/Kconfig          |  20 +++
 src/draw/glui.c           | 174 +++++++++++++++++++++++++
 src/draw/glui.h           |  63 ++++++++++
 src/draw/make.mk          |  11 ++
 src/draw/tui.c            | 269 +++++++++++++++++++++++++++++++++++++++
 src/draw/tui.h            |  45 +++++++
 src/draw/ui.c             |   0
 src/draw/ui.h             |   0
 src/fft/Kconfig           |   0
 src/filt/Kconfig          |   0
 src/filt/filt.h           |  16 +++
 src/filt/filt_5th.c       |  32 +++++
 src/filt/filt_delay.c     |  51 ++++++++
 src/filt/make.mk          |  11 ++
 src/hw/Kconfig            |  39 ++++++
 src/hw/aud.c              |  77 ++++++++++++
 src/hw/aud.h              |  14 +++
 src/hw/hw.c               | 285 +++++++++++++++++++++++++++++++++++++++++
 src/hw/hw.h               |  64 ++++++++++
 src/hw/hw_eeprom.c        |  47 +++++++
 src/hw/hw_eeprom.h        |  15 +++
 src/hw/make.mk            |  12 ++
 src/hw/sdr.c              | 315 ++++++++++++++++++++++++++++++++++++++++++++++
 src/hw/sdr.h              |  99 +++++++++++++++
 src/mod/Kconfig           |  51 ++++++++
 src/mod/make.mk           |  11 ++
 src/mod/mod.h             |  11 ++
 src/mod/mod_fm.c          |  12 ++
 src/net/Kconfig           |   0
 src/plug/Kconfig          |   0
 src/radiola.c             |  17 +++
 src/utils/Kconfig         |   0
 src/version.h             |   0
 42 files changed, 1915 insertions(+)
 create mode 100644 src/Kconfig
 create mode 100644 src/codec/Kconfig
 create mode 100644 src/config.h
 create mode 100644 src/config/config_bsd.h
 create mode 100644 src/config/config_linux.h
 create mode 100644 src/core/Kconfig
 create mode 100644 src/core/make.mk
 create mode 100644 src/core/math.c
 create mode 100644 src/core/math.h
 create mode 100644 src/draw/Kconfig
 create mode 100644 src/draw/glui.c
 create mode 100644 src/draw/glui.h
 create mode 100644 src/draw/make.mk
 create mode 100644 src/draw/tui.c
 create mode 100644 src/draw/tui.h
 create mode 100644 src/draw/ui.c
 create mode 100644 src/draw/ui.h
 create mode 100644 src/fft/Kconfig
 create mode 100644 src/filt/Kconfig
 create mode 100644 src/filt/filt.h
 create mode 100644 src/filt/filt_5th.c
 create mode 100644 src/filt/filt_delay.c
 create mode 100644 src/filt/make.mk
 create mode 100644 src/hw/Kconfig
 create mode 100644 src/hw/aud.c
 create mode 100644 src/hw/aud.h
 create mode 100644 src/hw/hw.c
 create mode 100644 src/hw/hw.h
 create mode 100644 src/hw/hw_eeprom.c
 create mode 100644 src/hw/hw_eeprom.h
 create mode 100644 src/hw/make.mk
 create mode 100644 src/hw/sdr.c
 create mode 100644 src/hw/sdr.h
 create mode 100644 src/mod/Kconfig
 create mode 100644 src/mod/make.mk
 create mode 100644 src/mod/mod.h
 create mode 100644 src/mod/mod_fm.c
 create mode 100644 src/net/Kconfig
 create mode 100644 src/plug/Kconfig
 create mode 100644 src/radiola.c
 create mode 100644 src/utils/Kconfig
 create mode 100644 src/version.h

(limited to 'src')

diff --git a/src/Kconfig b/src/Kconfig
new file mode 100644
index 0000000..2af8bdc
--- /dev/null
+++ b/src/Kconfig
@@ -0,0 +1,11 @@
+source "codec/Kconfig"
+source "core/Kconfig"
+source "draw/Kconfig"
+source "fft/Kconfig"
+source "filt/Kconfig"
+source "hw/Kconfig"
+source "mod/Kconfig"
+source "plug/Kconfig"
+source "utils/Kconfig"
+
+
diff --git a/src/codec/Kconfig b/src/codec/Kconfig
new file mode 100644
index 0000000..e69de29
diff --git a/src/config.h b/src/config.h
new file mode 100644
index 0000000..92f562b
--- /dev/null
+++ b/src/config.h
@@ -0,0 +1,15 @@
+#ifndef ___CONFIG_H
+#define ___CONFIG_H
+/*
+Default configuration is linux configuration ofc
+*/
+
+#define def(X) defined(CONFIG_##X)
+
+#if def(OS_NETBSD)
+#include "config/config_bsd.h"
+#else
+#include "config/config_linux.h"
+#endif
+
+#endif
diff --git a/src/config/config_bsd.h b/src/config/config_bsd.h
new file mode 100644
index 0000000..f74e647
--- /dev/null
+++ b/src/config/config_bsd.h
@@ -0,0 +1,11 @@
+#ifndef __CONFIG_BSD_H
+#define __CONFIG_BSD_H
+#define CONFIG_CORE
+#define CONFIG_OS_NETBSD
+#define CONFIG_DRAW
+#define CONFIG_HW
+#define CONFIG_HW_LIB_ORIG
+#define CONFIG_HW_NO_AUDIO
+#define CONFIG_MOD
+#define CONFIG_MOD_FM_DEMOD
+#endif
diff --git a/src/config/config_linux.h b/src/config/config_linux.h
new file mode 100644
index 0000000..51c4a13
--- /dev/null
+++ b/src/config/config_linux.h
@@ -0,0 +1,14 @@
+#ifndef __CONFIG_LINUX_H
+#define __CONFIG_LINUX_H
+#define CONFIG_CORE
+#define CONFIG_OS_LINUX
+#define CONFIG_DRAW
+#define CONFIG_GL
+#define CONFIG_SDL2
+#define CONFIG_TUI
+#define CONFIG_HW
+#define CONFIG_HW_LIB_ORIG
+#define CONFIG_HW_ALSA
+#define CONFIG_MOD
+#define CONFIG_MOD_FM_DEMOD
+#endif
diff --git a/src/core/Kconfig b/src/core/Kconfig
new file mode 100644
index 0000000..28befc6
--- /dev/null
+++ b/src/core/Kconfig
@@ -0,0 +1,28 @@
+menuconfig CORE
+	bool "Set core features"
+	default y
+
+if CORE
+	choice 
+	prompt "OS support"
+	help 
+	  OS support configuration. Not all OS'es support all stuff
+	
+	config OS_LINUX
+		bool "Linux"
+		default y
+
+	config OS_NETBSD
+		bool "NetBSD"
+		default n
+
+	endchoice
+
+	config FUTURE
+		bool "Future features that planned to be added"
+		default n
+
+endif
+
+
+
diff --git a/src/core/make.mk b/src/core/make.mk
new file mode 100644
index 0000000..52f08ec
--- /dev/null
+++ b/src/core/make.mk
@@ -0,0 +1,11 @@
+DIR_CORE = core/
+SOURCES_CORE += $(SRC_DIR)core/math.c
+OBJECTS_CORE += $(SOURCES_CORE:.c=.o)
+LDFLAGS += -lm
+LDFLAGS_BSD += -lm
+
+
+OBJECTS_DIR_CORE += $(subst $(SRC_DIR)$(DIR_CORE),$(BUILD_DIR)$(SRC_DIR)$(DIR_CORE),$(OBJECTS_CORE))
+
+OBJECTS += $(OBJECTS_CORE)
+OBJECTS_FINAL += $(OBJECTS_DIR_CORE)
\ No newline at end of file
diff --git a/src/core/math.c b/src/core/math.c
new file mode 100644
index 0000000..f962534
--- /dev/null
+++ b/src/core/math.c
@@ -0,0 +1,48 @@
+#include "math.h"
+
+
+float to_float(uint8_t x) 
+{
+	return (1.0f/127.0f)*(((float)x)-127.0f);
+}
+
+
+//float ph_ch( uint8_t i1, uint8_t q1, uint8_t i2, uint8_t q2)
+float ph_ch( uint8_t i1, uint8_t q1 )
+{
+	static float complex last=0.0+0.0i;
+	float out;
+	float complex xy,c1;
+	//float c2;
+
+	c1 = to_float(i1) + I*to_float(q1);
+	//c1 = CMPLXF( to_float(i1), to_float(q1) );
+	//c2 = to_float(i2) + I*to_float(q2);
+	//c2 = CMPLXF( to_float(i2), to_float(q2) );
+	xy = conjf(last)*c1;
+	out = cargf( xy );
+	last = c1;
+
+	return out;
+}
+
+void rotate_90(uint8_t *buf, uint32_t len)
+/* 90 rotation is 1+0j, 0+1j, -1+0j, 0-1j
+   or [0, 1, -3, 2, -4, -5, 7, -6] */
+{
+	uint32_t i;
+	uint8_t tmp;
+	for (i=0; i<len; i+=8) {
+		/* uint8_t negation = 255 - x */
+		tmp = 255 - buf[i+3];
+		buf[i+3] = buf[i+2];
+		buf[i+2] = tmp;
+
+		buf[i+4] = 255 - buf[i+4];
+		buf[i+5] = 255 - buf[i+5];
+
+		tmp = 255 - buf[i+6];
+		buf[i+6] = buf[i+7];
+		buf[i+7] = tmp;
+	}
+}
\ No newline at end of file
diff --git a/src/core/math.h b/src/core/math.h
new file mode 100644
index 0000000..dff1ffa
--- /dev/null
+++ b/src/core/math.h
@@ -0,0 +1,16 @@
+#ifndef __RADIOLA_MATH
+#define __RADIOLA_MATH
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <complex.h>
+#include <math.h>
+
+float to_float(uint8_t x);
+
+float ph_ch( uint8_t i1, uint8_t q1 );
+
+void rotate_90(uint8_t *buf, uint32_t len);
+
+#endif
\ No newline at end of file
diff --git a/src/draw/Kconfig b/src/draw/Kconfig
new file mode 100644
index 0000000..486461f
--- /dev/null
+++ b/src/draw/Kconfig
@@ -0,0 +1,20 @@
+menuconfig DRAW
+	bool "Graphic library support"
+	default y
+
+if DRAW
+	config GL
+		bool "OpenGL support"
+		default y
+
+	config SDL2
+		bool "SDL2 support"
+		default y
+
+	config TUI
+		bool "Terminal interface support"
+		default y
+endif
+
+
+
diff --git a/src/draw/glui.c b/src/draw/glui.c
new file mode 100644
index 0000000..0f1e360
--- /dev/null
+++ b/src/draw/glui.c
@@ -0,0 +1,174 @@
+#include "glui.h"
+
+#if def(OS_LINUX)
+
+#define DEFAULT_TITLE "RADIOLA"
+#define SCREEN_X 1024
+#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->h = SCREEN_Y;
+	tui->w = SCREEN_X;
+	tui->win = SDL_CreateWindow("Hello World!", tui->w, tui->h, SCREEN_X, SCREEN_Y, SDL_WINDOW_SHOWN);
+	if (tui->win == NULL)
+	{
+		printf("Couldnt create SDL window\n");
+		return -1;
+	}
+
+	*t = tui;
+	ret = 0;
+
+	return ret;
+}
+
+
+//init waterfall
+int glui_waterfall( glui_t **t, glui_waterfall_t **w )
+{
+	int ret=-1;
+	
+	glui_waterfall_t *wtf = NULL;
+
+	wtf = malloc( sizeof(glui_waterfall_t) );
+	if ( wtf == NULL )
+	{
+		printf("Cannot alloc waterfall\n");
+		return -1;
+	}
+
+	memset( wtf, 0, sizeof(glui_waterfall_t) );
+
+	wtf->h = (*t)->h;
+	wtf->w = (*t)->w;
+	wtf->cur_h = 5;
+
+
+	wtf->rend = SDL_CreateRenderer( (*t)->win, -1, SDL_RENDERER_ACCELERATED);
+	if ( wtf->rend == NULL )
+	{
+		printf("Canno create SDL Rendered\n");
+		return -1;
+	}
+
+	(*w) = wtf;
+	(*t)->wf = wtf;
+
+	ret = 0;
+
+	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 *t, int len, uint8_t *buf )
+{
+	int ret=-1;
+	int i;
+	int y;
+	glui_color_t c = glui_waterfall_color(0);
+	SDL_Point *pt = NULL;
+
+	SDL_SetRenderDrawColor( t->wf->rend, c.r, c.g, c.b, c.a );
+	
+	y = t->wf->cur_h;
+	t->wf->cur_h += 1;
+	pt = malloc( sizeof(SDL_Point) );
+	for ( i=0; i<len; i++ )
+	{
+		c = glui_waterfall_color(buf[i]);
+		SDL_SetRenderDrawColor( t->wf->rend, c.r, c.g, c.b, c.a );
+		pt[0].x = i;
+		pt[0].y = y;
+		SDL_RenderDrawPoints( t->wf->rend, pt, 1 );	
+	}
+
+	
+	SDL_RenderPresent( t->wf->rend );
+	ret = 0;
+
+	return ret;
+}
+
+
+//return color
+glui_color_t glui_waterfall_color( uint8_t d )
+{
+	glui_color_t c;
+	
+	c.r = d*10;
+	c.g = d*10;
+	c.b = d*10;
+
+	return c;
+}
+
+
+//close terminal ui
+int glui_close( glui_t *t )
+{
+	int ret=0;
+	
+
+	if ( t->win != NULL )
+	{
+		SDL_DestroyWindow( t->win );
+	}
+
+	SDL_Quit();
+
+
+	return ret;
+}
+
+#endif
diff --git a/src/draw/glui.h b/src/draw/glui.h
new file mode 100644
index 0000000..9206bdf
--- /dev/null
+++ b/src/draw/glui.h
@@ -0,0 +1,63 @@
+#ifndef __RADIOLA_GLUI_H
+#define __RADIOLA_GLUI_H
+#include "../config.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#if def(OS_LINUX)
+
+#include <SDL2/SDL.h>
+
+//to draw waterfall
+typedef struct glui_waterfall_t
+{
+	int type;
+	int h,w;
+	uint8_t *buf;
+	size_t buf_len;
+	int cur_h;
+
+	SDL_Renderer *rend;
+} glui_waterfall_t;
+
+typedef struct glui_t
+{
+
+	int h, w;
+
+	SDL_Window *win;
+	
+	glui_waterfall_t *wf;
+} glui_t;
+
+typedef struct glui_color_t 
+{
+	uint8_t r;
+	uint8_t g;
+	uint8_t b;
+	uint8_t a;
+} glui_color_t;
+
+//prepare terminal ui
+int glui_init( glui_t **t );
+//init waterfall
+int glui_waterfall( glui_t **t, glui_waterfall_t **w );
+//first draw, draw all buffer
+int glui_waterfall_draw( glui_waterfall_t *w );
+//redraw only changed lines
+int glui_waterfall_redraw( glui_waterfall_t *w );
+//update params of waterfall and then need to draw not redraw
+int glui_waterfall_update( glui_t *w );
+//push one line of data to buffer
+int glui_waterfall_data( glui_t *w, int len, uint8_t *buf );
+//return color
+glui_color_t glui_waterfall_color( uint8_t d );
+//close terminal ui
+int glui_close( glui_t *t );
+#endif
+#endif
diff --git a/src/draw/make.mk b/src/draw/make.mk
new file mode 100644
index 0000000..5c0acc4
--- /dev/null
+++ b/src/draw/make.mk
@@ -0,0 +1,11 @@
+DIR_DRAW = draw/
+SOURCES_DRAW += $(SRC_DIR)draw/glui.c $(SRC_DIR)draw/tui.c $(SRC_DIR)draw/ui.c
+OBJECTS_DRAW += $(SOURCES_DRAW:.c=.o)
+LDFLAGS += -lGL `sdl2-config --cflags --libs`
+LDFLAGS_BSD +=
+
+
+OBJECTS_DIR_DRAW += $(subst $(SRC_DIR)$(DIR_DRAW),$(BUILD_DIR)$(SRC_DIR)$(DIR_DRAW),$(OBJECTS_DRAW))
+
+OBJECTS += $(OBJECTS_DRAW)
+OBJECTS_FINAL += $(OBJECTS_DIR_DRAW)
\ No newline at end of file
diff --git a/src/draw/tui.c b/src/draw/tui.c
new file mode 100644
index 0000000..c431a61
--- /dev/null
+++ b/src/draw/tui.c
@@ -0,0 +1,269 @@
+#include "tui.h"
+
+#define T_ESC "\x1b"
+
+//prepare terminal ui
+int tui_init( tui_t **t )
+{
+	int ret = -1;
+	tui_t *tui=NULL;
+
+	//should be empty pointer
+	if (*t != NULL)
+		return -1;
+
+	tui = malloc( sizeof(tui_t) );
+	if ( tui == NULL )
+		return -1;
+
+	memset( tui, 0, sizeof( tui_t ) );
+
+	tui->ifd = STDIN_FILENO;
+	tui->ofd = STDOUT_FILENO;
+
+	//if you whant raw mode then you should set it man
+	if ( tcgetattr( tui->ifd, &tui->orig_i ) == -1 ) 
+		goto exit_error;
+	tui->raw_i = tui->orig_i;
+
+	if ( tcgetattr( tui->ofd, &tui->orig_o ) == -1 ) 
+		goto exit_error;
+	tui->raw_o = tui->orig_o;
+
+	//set not to echo output
+	/* input modes: no break, no CR to NL, no parity check, no strip char,
+	 * no start/stop output control. */
+	tui->raw_i.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+	/* output modes - disable post raw */
+	tui->raw_i.c_oflag &= ~(OPOST);
+	/* control modes - set 8 bit chars */
+	tui->raw_i.c_cflag |= (CS8);
+	/* local modes - choing off, canonical off, no extended functions,
+	 * no signal chars (^Z,^C) */
+	tui->raw_i.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+	/* control chars - set return condition: min number of bytes and timer.
+	 * We want read to return every single byte, without timeout. */
+
+	/* put terminal in raw mode after flushing */
+	if (tcsetattr( tui->ifd, TCSAFLUSH, &tui->raw_i) < 0)
+	{
+		//ERROR("Cannot set new terminal input attribures\n");
+		goto exit_error;
+	}
+
+	*t = tui;
+	ret = 0;
+
+	return ret;
+
+exit_error:
+	free( tui );
+	return -1;
+}
+
+
+//init waterfall
+int tui_waterfall( tui_t **t, tui_waterfall_t **w )
+{
+	int ret=-1;
+	tui_waterfall_t *wtf = NULL;
+
+	//waterfall should be NULL
+	if ( *w != NULL )
+		return -1;
+
+
+	wtf = malloc( sizeof(tui_waterfall_t) );
+	if ( wtf == NULL )
+	{
+		return -1;
+	}
+
+	memset( wtf, 0, sizeof(tui_waterfall_t) );
+
+	*w = wtf;
+	(*t)->wf = wtf;
+	ret = 0;
+
+	return ret;
+
+//exit_error:
+
+//	return -1;
+}
+
+
+//first draw, draw all buffer
+int tui_waterfall_draw( tui_waterfall_t *w )
+{
+	int ret = -1;
+	return ret;
+}
+
+
+//redraw only changed lines
+int tui_waterfall_redraw( tui_waterfall_t *w )
+{
+	int ret = -1;
+	return ret;
+}
+
+
+//update params of waterfall and then need to draw not redraw
+int tui_waterfall_update( tui_t *t )
+{
+	int ret = -1;
+	int row=-1,col=-1;
+	char buf[32];
+	int i;
+
+	//we trust that all params are ok
+
+	/* go to right marging and get position */
+	if ( write( t->ofd, "\x1b[999C", 6 ) != 6 )
+		goto exit_error;
+
+	if ( write( t->ofd, "\x1b[6n", 4 ) != 4 ) 
+		goto exit_error;
+
+	i = 0;
+	//printf("here=%d\n", sizeof(buf));
+	while (i < sizeof(buf)-1)
+	{
+		if ( read( t->ifd, buf+i,1 ) != 1 ) break;
+		if (buf[i] == 'R') break;
+		i++;
+	}
+	buf[i] = '\0';
+	//printf("i=%d,buf=[%s]\n",i,buf);
+
+	if ( buf[0] != '\x1b' || buf[1] != '[' ) 
+	{
+		goto exit_error;
+	}
+
+	//printf("i=%d,buf=[%s]\n",i,buf);
+
+	if ( sscanf( buf+2, "%d;%d", &row, &col) != 2 ) 
+		goto exit_error;
+
+	//write( t->ofd, "\x1b[1C", 4 );
+	write( t->ofd, T_ESC "[H" T_ESC "[2J", 7 );
+	write( t->ofd, T_ESC "[0;0H", 6);
+
+	t->wf->w = col;
+
+	ret = 0;
+
+	return ret;
+
+exit_error:
+
+	return -1;
+}
+
+
+//push one line of data to buffer
+int tui_waterfall_data( tui_t *t, int len, uint8_t *buf )
+{
+	int ret = -1;
+	int i;
+
+
+
+	i = 0;
+	while ( (i< t->wf->w) && ( i<len) )
+	{
+		//printf("-%d", buf[i]);
+		uint8_t c = tui_waterfall_color( buf[i] );
+		char buf[32];
+		snprintf( buf, 32, T_ESC "[48;5;%dm " T_ESC "[0m",c);
+		write( t->ofd, buf, strlen(buf) );
+		i++;
+	}
+
+	return ret;
+}
+
+uint8_t tui_waterfall_color( uint8_t d )
+{
+	
+	uint8_t color=15;
+	
+	
+	/*
+	if ( d < 50 )
+	{
+		color = 17;
+	} else if ( d < 100 )
+	{
+		color = 18;
+	} else if ( d < 150 )
+	{
+		color = 19;
+	} else if ( d < 200 )
+	{
+		color = 20;
+	} else
+	{
+		color = 21;
+	}
+	*/
+	
+	
+	
+	if ( d == 0 )
+	{
+		color = 17;
+	} else if ( d == 1 )
+	{
+		color = 18;
+	} else if ( d == 2 )
+	{
+		color = 19;
+	} else if ( d == 3 )
+	{
+		color = 20;
+	} else if ( d == 4 )
+	{
+		color = 21;
+	} else if ( d == 5 )
+	{
+		color = 26;
+	} else if ( d == 6 )
+	{
+		color = 27;
+	} else if ( d == 7 )
+	{
+		color = 44;
+	} else
+	{
+		color = 45;
+	}
+	
+	/*
+	uint8_t col[] = { 16,17,18,19,20,21,26,27,44,45,86,87,230,229,228,227,226,214,202,196,160,124,88,52 };
+	int len = 24;
+	int step = 256/len;
+
+	color = col[d/step];
+	*/
+
+	return color;
+}
+
+
+//close terminal ui
+int tui_close( tui_t *t )
+{
+	int ret = -1;
+	
+	//shouldnt be empty pointer
+	if ( t == NULL )
+		return -1;
+	
+	//restore terminal mode after closing 
+	tcsetattr( t->ifd, TCSAFLUSH, &t->orig_i );
+
+	return ret;
+}
diff --git a/src/draw/tui.h b/src/draw/tui.h
new file mode 100644
index 0000000..a84379f
--- /dev/null
+++ b/src/draw/tui.h
@@ -0,0 +1,45 @@
+#ifndef __RADIOLA_TUI_H
+#define __RADIOLA_TUI_H
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+//to draw waterfall
+typedef struct tui_waterfall_t
+{
+	int type;
+	int h,w;
+	uint8_t *buf;
+	size_t buf_len;
+} tui_waterfall_t;
+
+typedef struct tui_t
+{
+	int ifd, ofd;
+	struct termios orig_i, orig_o;
+	struct termios raw_i, raw_o;
+	tui_waterfall_t *wf;
+} tui_t;
+
+//prepare terminal ui
+int tui_init( tui_t **t );
+//init waterfall
+int tui_waterfall( tui_t **t, tui_waterfall_t **w );
+//first draw, draw all buffer
+int tui_waterfall_draw( tui_waterfall_t *w );
+//redraw only changed lines
+int tui_waterfall_redraw( tui_waterfall_t *w );
+//update params of waterfall and then need to draw not redraw
+int tui_waterfall_update( tui_t *w );
+//push one line of data to buffer
+int tui_waterfall_data( tui_t *w, int len, uint8_t *buf );
+//return color
+uint8_t tui_waterfall_color( uint8_t d );
+//close terminal ui
+int tui_close( tui_t *t );
+
+#endif
\ No newline at end of file
diff --git a/src/draw/ui.c b/src/draw/ui.c
new file mode 100644
index 0000000..e69de29
diff --git a/src/draw/ui.h b/src/draw/ui.h
new file mode 100644
index 0000000..e69de29
diff --git a/src/fft/Kconfig b/src/fft/Kconfig
new file mode 100644
index 0000000..e69de29
diff --git a/src/filt/Kconfig b/src/filt/Kconfig
new file mode 100644
index 0000000..e69de29
diff --git a/src/filt/filt.h b/src/filt/filt.h
new file mode 100644
index 0000000..9ce2caa
--- /dev/null
+++ b/src/filt/filt.h
@@ -0,0 +1,16 @@
+#ifndef __RADIOLA_FILT_H
+#define __RADIOLA_FILT_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+//fifth order filter from rtlsdr
+void filt_5th(int16_t *data, int length, int16_t *hist);
+
+//delay filtering from https://github.com/dpiponi/mini_fm.git
+void filt_delay( uint8_t *buf, int buf_len );
+
+#endif
\ No newline at end of file
diff --git a/src/filt/filt_5th.c b/src/filt/filt_5th.c
new file mode 100644
index 0000000..23d5aab
--- /dev/null
+++ b/src/filt/filt_5th.c
@@ -0,0 +1,32 @@
+#include "filt.h"
+
+void f_5th(int16_t *data, int length, int16_t *hist)
+/* for half of interleaved data */
+{
+	int i;
+	int16_t a, b, c, d, e, f;
+	a = hist[1];
+	b = hist[2];
+	c = hist[3];
+	d = hist[4];
+	e = hist[5];
+	f = data[0];
+	/* a downsample should improve resolution, so don't fully shift */
+	data[0] = (a + (b+e)*5 + (c+d)*10 + f) >> 4;
+	for (i=4; i<length; i+=4) {
+		a = c;
+		b = d;
+		c = e;
+		d = f;
+		e = data[i-2];
+		f = data[i];
+		data[i/2] = (a + (b+e)*5 + (c+d)*10 + f) >> 4;
+	}
+	/* archive */
+	hist[0] = a;
+	hist[1] = b;
+	hist[2] = c;
+	hist[3] = d;
+	hist[4] = e;
+	hist[5] = f;
+}
diff --git a/src/filt/filt_delay.c b/src/filt/filt_delay.c
new file mode 100644
index 0000000..53da0b0
--- /dev/null
+++ b/src/filt/filt_delay.c
@@ -0,0 +1,51 @@
+#include "filt.h"
+
+//delay filtering
+void filt_delay( uint8_t *buf, int buf_len )
+{
+	//delay length
+	const int n=10;
+	
+	int i=0;
+	uint32_t cycle=0;
+	uint32_t avg_i=0, avg_q=0;
+	uint32_t cyc_buffer_i[n],delay_i=0;
+	uint32_t cyc_buffer_q[n],delay_q=0;
+	uint8_t in1=0,in2=0,out1=0,out2=0;
+
+	memset( cyc_buffer_i, 0, n*sizeof(uint32_t) );
+	memset( cyc_buffer_q, 0, n*sizeof(uint32_t) );
+
+	//for (i=0; i<(buf_len-(n*2));i+=2)
+	for (i=0 ; i<(buf_len-1) ; i+=2 )
+	//for (i=0; i<1000; i+=2)
+	{
+		in1 = buf[i];
+		in2 = buf[i+1];
+
+		//average
+		avg_i += (uint32_t)in1;
+		avg_q += (uint32_t)in2;
+
+		delay_i = cyc_buffer_i[cycle];
+		delay_q = cyc_buffer_q[cycle];
+		
+		cyc_buffer_i[cycle] = avg_i;
+		cyc_buffer_q[cycle] = avg_q;
+		cycle = cycle + 1;
+		if ( cycle >= n )
+		{
+			cycle = 0;
+		}
+
+		out1 = (avg_i - delay_i)/n;
+		out2 = (avg_q - delay_q)/n;
+
+		buf[i]   = out1;
+		buf[i+1] = out2;
+
+		//printf("%d,avg=[%d,%d],delay=[%d,%d],in=[%d,%d],out=[%d,%d]\n",
+		//	cycle, avg_i,avg_q,delay_i,delay_q,in1,in2,out1,out2);
+
+	}
+}
\ No newline at end of file
diff --git a/src/filt/make.mk b/src/filt/make.mk
new file mode 100644
index 0000000..51aa82a
--- /dev/null
+++ b/src/filt/make.mk
@@ -0,0 +1,11 @@
+DIR_FILT = filt/
+SOURCES_FILT += $(SRC_DIR)filt/filt_5th.c $(SRC_DIR)filt/filt_delay.c
+OBJECTS_FILT += $(SOURCES_FILT:.c=.o)
+LDFLAGS += 
+LDFLAGS_BSD +=
+
+
+OBJECTS_DIR_FILT += $(subst $(SRC_DIR)$(DIR_FILT),$(BUILD_DIR)$(SRC_DIR)$(DIR_FILT),$(OBJECTS_FILT))
+
+OBJECTS += $(OBJECTS_FILT)
+OBJECTS_FINAL += $(OBJECTS_DIR_FILT)
\ No newline at end of file
diff --git a/src/hw/Kconfig b/src/hw/Kconfig
new file mode 100644
index 0000000..f95a0f5
--- /dev/null
+++ b/src/hw/Kconfig
@@ -0,0 +1,39 @@
+menuconfig HW
+	bool "Hardware support"
+	default y
+
+if HW
+	choice 
+	prompt "RTLSDR library"
+	help
+		RTLSDR library
+	
+	config HW_LIB_ORIG
+		bool "librtlsdr original version"
+		default y
+
+	config HW_LIB_R820T
+		bool "libr820t for of librtlsdr by radiola"
+		default n
+		
+
+	endchoice
+
+	choice
+	prompt "Audio"
+	
+	config HW_ALSA
+		bool "Linux ALSA"
+		default y
+		depends on OS_LINUX
+
+	config HW_NO_AUDIO
+		bool "No audio support"
+		default n
+
+	endchoice
+
+endif
+
+
+
diff --git a/src/hw/aud.c b/src/hw/aud.c
new file mode 100644
index 0000000..ade60cb
--- /dev/null
+++ b/src/hw/aud.c
@@ -0,0 +1,77 @@
+#include "aud.h"
+
+#if def(OS_LINUX)
+//harc-copy from aplay.c static void device_list(void)
+int audio_get_devices()
+{
+	snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
+
+	snd_ctl_t *handle;
+	int card, err, dev, idx;
+	snd_ctl_card_info_t *info;
+	snd_pcm_info_t *pcminfo;
+	snd_ctl_card_info_alloca(&info);
+	snd_pcm_info_alloca(&pcminfo);
+
+	card = -1;
+	if (snd_card_next(&card) < 0 || card < 0) {
+		printf("no soundcards found...\n");
+		return -1;
+	}
+	printf("**** List of %s Hardware Devices ****\n",
+	       snd_pcm_stream_name(stream));
+	while (card >= 0) {
+		char name[32];
+		sprintf(name, "hw:%d", card);
+		if ((err = snd_ctl_open(&handle, name, 0)) < 0) {
+			printf("control open (%i): %s\n", card, snd_strerror(err));
+			goto next_card;
+		}
+		if ((err = snd_ctl_card_info(handle, info)) < 0) {
+			printf("control hardware info (%i): %s\n", card, snd_strerror(err));
+			snd_ctl_close(handle);
+			goto next_card;
+		}
+		dev = -1;
+		while (1) {
+			unsigned int count;
+			if (snd_ctl_pcm_next_device(handle, &dev)<0)
+				printf("snd_ctl_pcm_next_device\n");
+			if (dev < 0)
+				break;
+			snd_pcm_info_set_device(pcminfo, dev);
+			snd_pcm_info_set_subdevice(pcminfo, 0);
+			snd_pcm_info_set_stream(pcminfo, stream);
+			if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
+				if (err != -ENOENT)
+					printf("control digital audio info (%i): %s\n", card, snd_strerror(err));
+				continue;
+			}
+			printf("card %i: %s [%s], device %i: %s [%s]\n",
+				card, snd_ctl_card_info_get_id(info), snd_ctl_card_info_get_name(info),
+				dev,
+				snd_pcm_info_get_id(pcminfo),
+				snd_pcm_info_get_name(pcminfo));
+			count = snd_pcm_info_get_subdevices_count(pcminfo);
+			printf( "  Subdevices: %i/%i\n",
+				snd_pcm_info_get_subdevices_avail(pcminfo), count);
+			for (idx = 0; idx < (int)count; idx++) {
+				snd_pcm_info_set_subdevice(pcminfo, idx);
+				if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
+					printf("control digital audio playback info (%i): %s\n", card, snd_strerror(err));
+				} else {
+					printf("  Subdevice #%d: %s\n",
+						idx, snd_pcm_info_get_subdevice_name(pcminfo));
+				}
+			}
+		}
+		snd_ctl_close(handle);
+	next_card:
+		if (snd_card_next(&card) < 0) {
+			printf("snd_card_next\n");
+			break;
+		}
+	}
+	return 0;
+}
+#endif
diff --git a/src/hw/aud.h b/src/hw/aud.h
new file mode 100644
index 0000000..974646a
--- /dev/null
+++ b/src/hw/aud.h
@@ -0,0 +1,14 @@
+#ifndef __RADIOLA_AUD_H
+#define __RADIOLA_AUD_H
+#include "../config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#if def(OS_LINUX)
+#include <alsa/asoundlib.h>
+#endif
+int audio_get_devices();
+
+#endif
diff --git a/src/hw/hw.c b/src/hw/hw.c
new file mode 100644
index 0000000..4496a51
--- /dev/null
+++ b/src/hw/hw.c
@@ -0,0 +1,285 @@
+#include "hw.h"
+
+uint32_t hw_get_device_count(void)
+{
+	uint32_t ret;
+	ret = rtlsdr_get_device_count();
+	return ret;
+}
+
+
+const char* hw_get_device_name(uint32_t index)
+{
+	const char *ret;
+	ret = rtlsdr_get_device_name( index );
+	return ret;
+}
+
+
+int hw_get_device_usb_strings(uint32_t index,
+					     char *manufact,
+					     char *product,
+					     char *serial)
+{
+	int ret;
+	ret = rtlsdr_get_device_usb_strings( index, manufact, product, serial );
+	return ret;
+}
+
+
+int hw_get_index_by_serial(const char *serial)
+{
+	int ret;
+	rtlsdr_get_index_by_serial( serial );
+	return ret;
+}
+
+
+int hw_open(rtlsdr_dev_t **dev, uint32_t index)
+{
+	int ret;
+	ret = rtlsdr_open( dev, index );
+	return ret;
+}
+
+
+int hw_close(rtlsdr_dev_t *dev)
+{
+	int ret;
+	ret = rtlsdr_close( dev );
+	return ret;
+}
+
+
+int hw_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq,
+				    uint32_t tuner_freq)
+{
+	int ret;
+	ret = rtlsdr_set_xtal_freq( dev, rtl_freq, tuner_freq );
+	return ret;
+}
+
+
+int hw_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq,
+				    uint32_t *tuner_freq)
+{
+	int ret;
+	ret = rtlsdr_get_xtal_freq( dev, rtl_freq, tuner_freq );
+	return ret;
+}
+
+
+int hw_get_usb_strings(rtlsdr_dev_t *dev, char *manufact,
+				      char *product, char *serial)
+{
+	int ret;
+	ret = rtlsdr_get_usb_strings( dev, manufact, product, serial );
+	return ret;
+}
+
+
+int hw_write_eeprom(rtlsdr_dev_t *dev, uint8_t *data,
+				  uint8_t offset, uint16_t len)
+{
+	int ret;
+	ret = rtlsdr_write_eeprom( dev, data, offset, len );
+	return ret;
+}
+
+
+int hw_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data,
+				  uint8_t offset, uint16_t len)
+{
+	int ret;
+	ret = rtlsdr_read_eeprom( dev, data, offset, len );
+	return ret;
+}
+
+
+int hw_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq)
+{
+	int ret;
+	ret = rtlsdr_set_center_freq( dev, freq );
+	return ret;
+}
+
+
+uint32_t hw_get_center_freq(rtlsdr_dev_t *dev)
+{
+	uint32_t ret;
+	ret = rtlsdr_get_center_freq( dev );
+	return ret;
+}	
+
+
+int hw_set_freq_correction(rtlsdr_dev_t *dev, int ppm)
+{
+	int ret;
+	ret = rtlsdr_set_freq_correction( dev, ppm );
+	return ret;
+}
+
+
+int hw_get_freq_correction(rtlsdr_dev_t *dev)
+{
+	int ret;
+	ret = rtlsdr_get_freq_correction( dev );
+	return ret;
+}
+
+
+enum rtlsdr_tuner hw_get_tuner_type(rtlsdr_dev_t *dev)
+{
+	enum rtlsdr_tuner ret;
+	ret = rtlsdr_get_tuner_type( dev );
+	return ret;
+}
+
+
+int hw_get_tuner_gains(rtlsdr_dev_t *dev, int *gains)
+{
+	int ret;
+	ret = rtlsdr_get_tuner_gains( dev, gains );
+	return ret;
+}
+
+
+int hw_set_tuner_gain(rtlsdr_dev_t *dev, int gain)
+{
+	int ret;
+	ret = rtlsdr_set_tuner_gain( dev, gain );
+	return ret;
+}
+
+
+int hw_get_tuner_gain(rtlsdr_dev_t *dev)
+{
+	int ret;
+	ret = rtlsdr_get_tuner_gain( dev );
+	return ret;
+}
+
+
+int hw_set_tuner_if_gain(rtlsdr_dev_t *dev, int stage, int gain)
+{
+	int ret;
+	ret = rtlsdr_set_tuner_if_gain( dev, stage, gain );
+	return ret;
+}
+
+
+int hw_set_tuner_gain_mode(rtlsdr_dev_t *dev, int manual)
+{
+	int ret;
+	ret = rtlsdr_set_tuner_gain_mode( dev, manual );
+	return ret;
+}
+
+
+int hw_set_sample_rate(rtlsdr_dev_t *dev, uint32_t rate)
+{
+	int ret;
+	ret = rtlsdr_set_sample_rate( dev, rate );
+	return ret;
+}
+
+
+uint32_t hw_get_sample_rate(rtlsdr_dev_t *dev)
+{
+	uint32_t ret;
+	ret = rtlsdr_get_sample_rate( dev );
+	return ret;
+}
+
+
+int hw_set_testmode(rtlsdr_dev_t *dev, int on)
+{
+	int ret;
+	ret = rtlsdr_set_testmode( dev, on );
+	return ret;
+}
+
+
+int hw_set_agc_mode(rtlsdr_dev_t *dev, int on)
+{
+	int ret;
+	ret = rtlsdr_set_agc_mode( dev, on );
+	return ret;
+}
+
+
+int hw_set_direct_sampling(rtlsdr_dev_t *dev, int on)
+{
+	int ret;
+	ret = rtlsdr_set_direct_sampling( dev, on );
+	return ret;
+}
+
+
+int hw_get_direct_sampling(rtlsdr_dev_t *dev)
+{
+	int ret;
+	ret = rtlsdr_get_direct_sampling( dev );
+	return ret;
+}
+
+
+int hw_set_offset_tuning(rtlsdr_dev_t *dev, int on)
+{
+	int ret;
+	ret = rtlsdr_set_offset_tuning( dev, on );
+	return ret;
+}
+
+
+int hw_get_offset_tuning(rtlsdr_dev_t *dev)
+{
+	int ret;
+	ret = rtlsdr_get_offset_tuning( dev );
+	return ret;
+}
+
+
+
+int hw_reset_buffer(rtlsdr_dev_t *dev)
+{
+	int ret;
+	ret = rtlsdr_reset_buffer( dev );
+	return ret;
+}
+
+
+int hw_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read)
+{
+	int ret;
+	ret = rtlsdr_read_sync( dev, buf, len, n_read );
+	return ret;
+}
+
+
+int hw_wait_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx)
+{
+	int ret;
+	ret = rtlsdr_wait_async( dev, cb, ctx );
+	return ret;
+}
+
+
+int hw_read_async(rtlsdr_dev_t *dev,
+				 rtlsdr_read_async_cb_t cb,
+				 void *ctx,
+				 uint32_t buf_num,
+				 uint32_t buf_len)
+{
+	int ret;
+	ret = rtlsdr_read_async( dev, cb, ctx, buf_num, buf_len );
+	return ret;
+}
+
+
+int hw_cancel_async(rtlsdr_dev_t *dev)
+{
+	int ret;
+	ret = rtlsdr_cancel_async( dev );
+	return ret;
+}
\ No newline at end of file
diff --git a/src/hw/hw.h b/src/hw/hw.h
new file mode 100644
index 0000000..ac79431
--- /dev/null
+++ b/src/hw/hw.h
@@ -0,0 +1,64 @@
+#ifndef __RADIOLA_HW_H
+#define __RADIOLA_HW_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+//#include <r820t.h>
+#include <rtl-sdr.h>
+
+
+
+uint32_t hw_get_device_count(void);
+const char* hw_get_device_name(uint32_t index);
+int hw_get_device_usb_strings(uint32_t index,
+					     char *manufact,
+					     char *product,
+					     char *serial);
+int hw_get_index_by_serial(const char *serial);
+int hw_open(rtlsdr_dev_t **dev, uint32_t index);
+int hw_close(rtlsdr_dev_t *dev);
+int hw_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq,
+				    uint32_t tuner_freq);
+int hw_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq,
+				    uint32_t *tuner_freq);
+int hw_get_usb_strings(rtlsdr_dev_t *dev, char *manufact,
+				      char *product, char *serial);				 			    
+int hw_write_eeprom(rtlsdr_dev_t *dev, uint8_t *data,
+				  uint8_t offset, uint16_t len);
+int hw_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data,
+				  uint8_t offset, uint16_t len);
+int hw_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq);
+uint32_t hw_get_center_freq(rtlsdr_dev_t *dev);
+int hw_set_freq_correction(rtlsdr_dev_t *dev, int ppm);
+int hw_get_freq_correction(rtlsdr_dev_t *dev);
+enum rtlsdr_tuner hw_get_tuner_type(rtlsdr_dev_t *dev);
+int hw_get_tuner_gains(rtlsdr_dev_t *dev, int *gains);
+int hw_set_tuner_gain(rtlsdr_dev_t *dev, int gain);
+int hw_get_tuner_gain(rtlsdr_dev_t *dev);
+int hw_set_tuner_if_gain(rtlsdr_dev_t *dev, int stage, int gain);
+int hw_set_tuner_gain_mode(rtlsdr_dev_t *dev, int manual);
+int hw_set_sample_rate(rtlsdr_dev_t *dev, uint32_t rate);
+uint32_t hw_get_sample_rate(rtlsdr_dev_t *dev);
+int hw_set_testmode(rtlsdr_dev_t *dev, int on);
+int hw_set_agc_mode(rtlsdr_dev_t *dev, int on);
+int hw_set_direct_sampling(rtlsdr_dev_t *dev, int on);
+int hw_get_direct_sampling(rtlsdr_dev_t *dev);
+int hw_set_offset_tuning(rtlsdr_dev_t *dev, int on);
+int hw_get_offset_tuning(rtlsdr_dev_t *dev);
+int hw_reset_buffer(rtlsdr_dev_t *dev);
+int hw_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read);
+int hw_wait_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx);
+int hw_read_async(rtlsdr_dev_t *dev,
+				 rtlsdr_read_async_cb_t cb,
+				 void *ctx,
+				 uint32_t buf_num,
+				 uint32_t buf_len);
+int hw_cancel_async(rtlsdr_dev_t *dev);
+
+
+
+
+
+
+#endif
\ No newline at end of file
diff --git a/src/hw/hw_eeprom.c b/src/hw/hw_eeprom.c
new file mode 100644
index 0000000..10ae817
--- /dev/null
+++ b/src/hw/hw_eeprom.c
@@ -0,0 +1,47 @@
+#include "hw_eeprom.h"
+
+
+
+int dump_eeprom( rtlsdr_dev_t *dev, uint8_t *data, uint16_t len )
+{
+	int fret = 0;
+
+	if ( len != EEPROM_SIZE )
+	{
+		printf("EEPROM sump size expected to be %d\n", EEPROM_SIZE);
+		return -1;
+	}
+
+	fret = hw_read_eeprom( dev, data, 0, len );
+	if ( fret != 0 )
+	{
+		printf("Cannot read eeprom rtlsdr err (%d)\n", fret);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+int restore_eeprom( rtlsdr_dev_t *dev, uint8_t *data, uint16_t len )
+{
+	int fret = 0;
+
+	if ( len != EEPROM_SIZE )
+	{
+		printf("EEPROM sump size expected to be %d\n", EEPROM_SIZE);
+		return -1;
+	}
+
+	fret = hw_write_eeprom( dev, data, 0, len );
+	if ( fret != 0 )
+	{
+		printf("Cannot write eeprom rtlsdr err(%d)\n", fret);
+		return -1;
+	}
+
+
+	return 0;
+}
+
+
diff --git a/src/hw/hw_eeprom.h b/src/hw/hw_eeprom.h
new file mode 100644
index 0000000..ac3ec0a
--- /dev/null
+++ b/src/hw/hw_eeprom.h
@@ -0,0 +1,15 @@
+#ifndef __RADIOLA_HW_EEPROM_H
+#define __RADIOLA_HW_EEPROM_H
+
+#include "hw.h"
+
+#define EEPROM_SIZE 256
+
+int dump_eeprom( rtlsdr_dev_t *dev, uint8_t *data, uint16_t len );
+int restore_eeprom( rtlsdr_dev_t *dev, uint8_t *data, uint16_t len );
+
+//int eeprom_read_config();
+//int eeprom_write_config();
+
+
+#endif
\ No newline at end of file
diff --git a/src/hw/make.mk b/src/hw/make.mk
new file mode 100644
index 0000000..34d3e6f
--- /dev/null
+++ b/src/hw/make.mk
@@ -0,0 +1,12 @@
+DIR_HW = hw/
+SOURCES_HW += $(SRC_DIR)hw/aud.c $(SRC_DIR)hw/hw.c $(SRC_DIR)hw/hw_eeprom.c \
+$(SRC_DIR)hw/sdr.c
+OBJECTS_HW += $(SOURCES_HW:.c=.o)
+LDFLAGS += -lrtlsdr -lasound
+LDFLAGS_BSD += -lrtlsdr
+
+
+OBJECTS_DIR_HW += $(subst $(SRC_DIR)$(DIR_HW),$(BUILD_DIR)$(SRC_DIR)$(DIR_HW),$(OBJECTS_HW))
+
+OBJECTS += $(OBJECTS_HW)
+OBJECTS_FINAL += $(OBJECTS_DIR_HW)
\ No newline at end of file
diff --git a/src/hw/sdr.c b/src/hw/sdr.c
new file mode 100644
index 0000000..a9590da
--- /dev/null
+++ b/src/hw/sdr.c
@@ -0,0 +1,315 @@
+#include "sdr.h"
+
+sdr_t* sdr_init()
+{
+	sdr_t *sdr=NULL;
+
+	sdr = malloc( sizeof(sdr_t) );
+	if (sdr == NULL)
+		return NULL;
+
+	memset( sdr, 0, sizeof(sdr_t) );
+
+	return sdr;
+}
+
+
+//index of device in oter list
+//return inner device list
+int sdr_open_device( sdr_t *sdr, int dev_index )
+{
+	int ret;
+	dongle_t *dng=NULL;
+	rtlsdr_dev_t *rtl=NULL;
+
+	//for now only one device will be supported
+	if (sdr == NULL)
+		return -1;
+
+	if (sdr->dongle != NULL)
+		return -1;
+
+	dng = malloc(sizeof(dongle_t));
+	memset(dng, 0, sizeof(dongle_t));
+	//set default values for dongle_t
+	DEF_DONGLE_VALUES(dng);
+
+	ret = hw_open( &rtl, (uint32_t)dev_index );
+	if ( ret < 0 )
+	{
+		printf("Cannot open device %02d\n", dev_index );
+		goto exit_dng_err;
+	}
+
+	ret = hw_reset_buffer( rtl );
+	if ( ret < 0 )
+	{
+		printf("Couldnt reset buffer\n");
+		goto exit_dng_err;
+	}
+
+	ret = hw_set_sample_rate( rtl, dng->rate );
+	if ( ret < 0 )
+	{
+		printf("Couldnt set sample rate to %d\n", dng->rate);
+		goto exit_dng_err;
+	}
+
+	ret = hw_set_center_freq( rtl, dng->freq );
+	if ( ret < 0 )
+	{
+		printf("Couldnt set frequency %d\n", dng->freq );
+		goto exit_dng_err;
+	}
+
+	ret = hw_set_tuner_gain_mode( rtl, dng->gain );
+	if ( ret < 0 )
+	{
+		printf("Cannot set autogain mode\n");
+		goto exit_dng_err;
+	}
+
+	ret = hw_set_agc_mode( rtl, 1 );
+	if ( ret < 0 )
+	{
+		printf("Cannot set agc mode\n");
+		goto exit_dng_err;
+	}
+
+	dng->dev_index = dev_index;
+	dng->dev = rtl;
+	sdr->dongle = dng;
+
+	return 0;
+
+exit_dng_err:
+	free( dng );
+
+	return -1;
+}
+
+
+//associate audio device that going to be used
+//int sdr_open_audio( sdr_t *sdr, int dev_index );//?should be just device from list or device name?
+
+
+//get device structure from sdr manager by pluged device num
+//dont try to free it muahaha
+dongle_t* sdr_get_device_id( sdr_t *sdr, int dev_index)
+{
+	dongle_t *dng=NULL;
+
+	if ( sdr == NULL )
+		return NULL;
+
+	if (sdr->dongle == NULL)
+		return NULL;
+
+	if (sdr->dongle->dev_index != dev_index)
+	{
+		printf("Cannot find device with such device ID\n");
+		return NULL;
+	}
+
+	return sdr->dongle;
+}
+
+
+
+//get index in list of devices of structure from outer device index
+//? do we need?
+//int sdr_get_dongle_idx( sdr_t *sdr, int idx );
+//close device by internal list index
+int sdr_close_device( sdr_t *sdr, int dev_index )
+{
+	if ( sdr == NULL )
+		return -1;
+	
+	if ( sdr->dongle == NULL )
+	{
+		return -1;
+	}
+
+	if ( sdr->dongle->dev == NULL )
+		return -1;
+
+	if ( sdr->dongle->dev_index != dev_index )
+		return -1;
+
+	hw_close( sdr->dongle->dev );
+	free( sdr->dongle->dev );
+	sdr->dongle->dev = NULL;
+
+	free( sdr->dongle );
+	sdr->dongle = NULL;
+
+	return 0;
+}
+
+
+
+//close sdr
+//if there is opened audios then close
+//if there is opened devices then close
+int sdr_close( sdr_t *sdr )
+{
+	if ( sdr != NULL )
+	{	
+		if ( sdr->dongle != NULL )
+		{
+			if ( sdr->dongle->dev != NULL )
+			{
+				hw_close( sdr->dongle->dev );
+				//all ready free'd by rtlsdr
+				//free( sdr->dongle->dev );
+				sdr->dongle->dev = NULL;
+			}
+			free( sdr->dongle );
+			sdr->dongle = NULL;
+		}
+		free(sdr);
+		sdr = NULL;
+		return 0;
+	}
+	return -1;
+}
+
+
+
+//stop any action that associated with dongle
+//not yet implemented
+int dongle_stop( dongle_t *dongle )
+{
+	return -1;
+}
+
+
+//int dongle_open( sdr_t *);
+//set dongle frequency
+int dongle_set_freq( dongle_t *dongle, uint32_t freq)
+{
+	int ret = 0;
+	if ( dongle == NULL )
+		return -1;
+
+	if ( dongle->dev == NULL )
+		return -1;
+
+	ret = hw_set_center_freq( dongle->dev, freq );
+	if ( ret < 0 )
+	{
+		printf("Cannot set device frequency to %ud\n", freq);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+//set gain
+int dongle_set_gain( dongle_t *dongle, int gain)
+{
+
+	int ret;
+
+	if ( dongle == NULL )
+		return -1;
+
+	if ( dongle->dev == NULL )
+		return -1;
+
+	ret = hw_set_tuner_gain_mode( dongle->dev, gain );
+	if ( ret < 0 )
+	{
+		printf("Cannot set tunner gain level %d\n", gain );
+		return -1;
+	}
+
+	return 0;
+}
+
+
+//set dongle sample rate
+int dongle_set_sample_rate( dongle_t *dongle, uint32_t rate )
+{
+	int ret;
+
+	if ( dongle == NULL )
+	{
+		return -1;
+	}
+
+	if ( dongle->dev == NULL )
+		return -1;
+
+	ret = hw_set_sample_rate( dongle->dev, rate );
+	if ( ret < 0 )
+	{
+		printf("Cannot set sample rate to %uMsps\n", rate);
+		return -1;
+	}
+
+	return 0;
+}
+
+int dongle_set_agc( dongle_t *dongle, int mode)
+{
+	int ret;
+
+	if ( dongle == NULL )
+		return -1;
+
+	if ( dongle->dev == NULL )
+		return -1;
+
+	//need mode check things
+	ret = hw_set_agc_mode( dongle->dev, mode );
+	if ( ret < 0 )
+	{
+		printf("Cannot set agc gain mode\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+uint32_t dongle_get_freq( dongle_t *dongle )
+{
+	return dongle->freq;
+}
+
+
+int dongle_get_gain( dongle_t *dongle )
+{
+	return dongle->gain;
+}
+
+
+uint32_t dongle_get_sample_rate( dongle_t *dongle )
+{
+	return dongle->rate;
+}
+
+
+int dongle_read_samples( dongle_t *dongle, uint8_t *buf, int len )
+{
+	int ret, read_num;
+
+	if ( dongle == NULL )
+		return -1;
+
+	if ( dongle->dev == NULL )
+		return -1;
+
+
+
+	ret = hw_read_sync( dongle->dev, buf, len, &read_num );
+	if ( ret < 0 )
+	{
+		printf("Couldnt read samples\n");
+		return -1;
+	}
+
+	return 0;
+}
\ No newline at end of file
diff --git a/src/hw/sdr.h b/src/hw/sdr.h
new file mode 100644
index 0000000..ce4ef70
--- /dev/null
+++ b/src/hw/sdr.h
@@ -0,0 +1,99 @@
+#ifndef __RADIOLA_HW_SDR_H
+#define __RADIOLA_HW_SDR_H
+
+#include <string.h>
+
+#include "hw.h"
+
+
+//list of supported devices RTLSDR is rtlsdr tunners,
+//AUDIO is just used audio cards
+//NET get or send some info to server/client
+//PTT usb connected with audio link radios, trought PTT things
+typedef enum
+{
+	DEVICE_NONE=0,
+	DEVICE_RTLSDR,
+	DEVICE_AUDIO,
+	DEVICE_NET,
+	DEVICE_PTT
+} sdr_device;
+
+
+typedef struct dongle_t
+{
+	rtlsdr_dev_t *dev;
+	int dev_index;
+	uint32_t freq;
+	uint32_t rate;
+	int gain;
+} dongle_t;
+
+#define DONGLE_SAMPLE_RATE 2048000
+#define DONGLE_CENTER_FREQ 100000000
+#define DONGLE_GAIN        1
+
+//dongle pointer to dongle_t
+#define DEF_DONGLE_VALUES(DONGLE)\
+{\
+(DONGLE)->freq=DONGLE_CENTER_FREQ;\
+(DONGLE)->rate=DONGLE_SAMPLE_RATE;\
+(DONGLE)->gain=DONGLE_GAIN;\
+}
+
+
+typedef struct audio_t
+{
+} audio_t;
+
+
+typedef struct sdr_t 
+{
+	dongle_t   *dongle; //list of rtlsdr devices
+	uint32_t   d_used;  //not yes used
+	audio_t    *audio;  //audio devices used
+	uint32_t   a_used;  //not yet used
+} sdr_t;
+
+//init structure 
+
+sdr_t* sdr_init(); 
+//index of device in oter list
+//return inner device list
+int sdr_open_device( sdr_t *sdr, int dev_index );
+//associate audio device that going to be used
+//int sdr_open_audio( sdr_t *sdr, int dev_index );//?should be just device from list or device name?
+
+
+//get device structure from sdr manager
+dongle_t* sdr_get_device_id( sdr_t *sdr, int dev_index);
+
+//get index in list of devices of structure from outer device index
+//? do we need?
+//int sdr_get_dongle_idx( sdr_t *sdr, int idx );
+//close device by internal list index
+int sdr_close_device( sdr_t *sdr, int idx );
+
+//close sdr
+//if there is opened audios then close
+//if there is opened devices then close
+int sdr_close( sdr_t *sdr );
+
+//stop any action that associated with dongle
+int dongle_stop( dongle_t *dongle );
+//int dongle_open( sdr_t *);
+//set dongle frequency
+int dongle_set_freq( dongle_t *dongle, uint32_t freq);
+//set gain
+int dongle_set_gain( dongle_t *dongle, int gain);
+int dongle_set_agc( dongle_t *dongle, int mode);
+//set dongle sample rate
+int dongle_set_sample_rate( dongle_t *dongle, uint32_t rate );
+
+uint32_t dongle_get_freq( dongle_t *dongle );
+int      dongle_get_gain( dongle_t *dongle );
+uint32_t dongle_get_sample_rate( dongle_t *dongle );
+int      dongle_read_samples( dongle_t *dongle, uint8_t *buf, int len );
+//int dongle_close();
+
+#endif
\ No newline at end of file
diff --git a/src/mod/Kconfig b/src/mod/Kconfig
new file mode 100644
index 0000000..50413a0
--- /dev/null
+++ b/src/mod/Kconfig
@@ -0,0 +1,51 @@
+menuconfig MOD
+	bool "Modulation support"
+	default y
+
+if MOD
+	config MOD_FM
+	bool "FM mod"
+	default n
+	depends on FUTURE
+
+	config MOD_FM_DEMOD
+	bool "FM demod"
+	default n
+
+	config MOD_WBFM_DEMOD
+	bool "WBFM demod"
+	default n
+	depends on FUTURE
+
+	config MOD_AM_DEMOD
+	bool "AM demod"
+	default n
+	depends on FUTURE
+
+	config MOD_PSK_DEMOD
+	bool "PSK demod"
+	default n
+	depends on FUTURE
+
+	config MOD_PSK31_DEMOD
+	bool "PSK31 demod"
+	default n
+	depends on FUTURE
+
+endif
+
+menuconfig PROTO
+	bool "Protocol support"
+	default n
+
+if PROTO
+	config PROTO_AX25
+	bool "AX.25 radio packet support"
+	default n
+	depends on FUTURE
+
+	config PROTO_NOAA
+	bool "NOAA satelite recieving"
+	default n
+	depends on FUTURE
+endif
diff --git a/src/mod/make.mk b/src/mod/make.mk
new file mode 100644
index 0000000..b00ec90
--- /dev/null
+++ b/src/mod/make.mk
@@ -0,0 +1,11 @@
+DIR_MOD = mod/
+SOURCES_MOD += $(SRC_DIR)mod/mod_fm.c
+OBJECTS_MOD += $(SOURCES_MOD:.c=.o)
+LDFLAGS += 
+LDFLAGS_BSD +=
+
+
+OBJECTS_DIR_MOD += $(subst $(SRC_DIR)$(DIR_MOD),$(BUILD_DIR)$(SRC_DIR)$(DIR_MOD),$(OBJECTS_MOD))
+
+OBJECTS += $(OBJECTS_MOD)
+OBJECTS_FINAL += $(OBJECTS_DIR_MOD)
\ No newline at end of file
diff --git a/src/mod/mod.h b/src/mod/mod.h
new file mode 100644
index 0000000..288d40b
--- /dev/null
+++ b/src/mod/mod.h
@@ -0,0 +1,11 @@
+#ifndef __RADIOLA_MOD_H
+#define __RADIOLA_MOD_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+void fm_demod();
+void fm_mod();
+
+#endif
\ No newline at end of file
diff --git a/src/mod/mod_fm.c b/src/mod/mod_fm.c
new file mode 100644
index 0000000..22b296b
--- /dev/null
+++ b/src/mod/mod_fm.c
@@ -0,0 +1,12 @@
+#include "mod.h"
+
+
+void fm_demod()
+{
+
+}
+
+void fm_mod()
+{
+	
+}
diff --git a/src/net/Kconfig b/src/net/Kconfig
new file mode 100644
index 0000000..e69de29
diff --git a/src/plug/Kconfig b/src/plug/Kconfig
new file mode 100644
index 0000000..e69de29
diff --git a/src/radiola.c b/src/radiola.c
new file mode 100644
index 0000000..aaaf047
--- /dev/null
+++ b/src/radiola.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "hw/hw.h"
+
+int main()
+{
+#if def(OS_LINUX)
+	printf("Compiled in Linux comp mode\n");
+#elif def(OS_NETBSD)
+	printf("Compiled in NetBSD comp mode\n");
+#else
+	printf("Unknown mode\n");
+#endif
+	return 0;
+}
diff --git a/src/utils/Kconfig b/src/utils/Kconfig
new file mode 100644
index 0000000..e69de29
diff --git a/src/version.h b/src/version.h
new file mode 100644
index 0000000..e69de29
-- 
cgit v1.2.3