summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/.gitignore1
-rw-r--r--test/ui_pipe_waterfall.c253
2 files changed, 254 insertions, 0 deletions
diff --git a/test/.gitignore b/test/.gitignore
index a37bb52..6605582 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -10,3 +10,4 @@ div20
*.o
dump0
dump_eeprom
+ui_pipe_waterfall
diff --git a/test/ui_pipe_waterfall.c b/test/ui_pipe_waterfall.c
new file mode 100644
index 0000000..a5f1769
--- /dev/null
+++ b/test/ui_pipe_waterfall.c
@@ -0,0 +1,253 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+
+//radiola
+#include <hw/hw.h>
+#include <hw/sdr.h>
+
+#define SAMPLE_RATE 2048000
+
+#define CENTER_FREQ 446018750
+#define FFT_LEVEL 10
+#define FFT_SIZE (1 << FFT_LEVEL)
+#define SAMPLE_LENGHT (2 * FFT_SIZE)
+#define PRESCALE 8
+#define POSTSCALE 2
+#define WIDTH_POINTS 32
+
+int16_t* Sinewave;
+int N_WAVE, LOG2_N_WAVE;
+double* power_table;
+
+//better to have size size mod olen == 0
+int normalise( uint8_t *ibuf, int ilen, uint8_t *obuf, int olen )
+{
+ uint32_t i,j,m;
+ uint32_t ppi;
+ uint32_t sum;
+ div_t d;
+
+ if ( ilen >= olen )
+ {
+ d = div(ilen,olen);
+ ppi = d.quot;
+ if (d.rem > 0)
+ ppi += 1;
+ } else {
+ printf("Input buffer smaller ther output buffer\n");
+ return -1;
+ }
+
+ m = 0;
+ i = 0;
+ for (i=0,m=0; i < ilen+ppi; i += ppi, m++)
+ {
+ sum = 0;
+ for (j=0;j<ppi;j++)
+ sum += ibuf[i+j];
+ obuf[m] = sum/ppi;
+ }
+
+ 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;
+ uint16_t buf1[SAMPLE_LENGHT];
+ uint16_t buf2[SAMPLE_LENGHT];
+ int fft_len;
+
+ for (i=0; i<len; i++)
+ {
+ buf1[i] = buf[i] * PRESCALE;
+ }
+
+ fix_fft( (uint16_t *)buf1, FFT_LEVEL );
+
+ for (i=0; i<FFT_SIZE; i+=1)
+ {
+ //buf1[i] = rtl_out.buf[i];
+ //p = buf1[i] * buf1[i];
+ j = i*2;
+ p = (int16_t)real_conj(buf1[j], buf1[j + 1]);
+ buf2[i] = p;
+ }
+
+ fft_len = FFT_SIZE / 2;
+ for (i=0; i<fft_len; i++)
+ {
+ buf[i] = (int)log10(POSTSCALE * (float)buf2[i+fft_len]);
+ buf[i+fft_len] = (int)log10(POSTSCALE * (float)buf2[i]);
+ }
+
+ return 0;
+}
+
+int pipe_watefall( int size, uint8_t *buf )
+{
+ int i;
+ for (i=0;i<size;i++)
+ {
+ printf("%02d",(unsigned char)buf[i]);
+ if (i!=size-1) printf(",");
+ }
+ printf("\n");
+ return 0;
+}
+
+int main()
+{
+
+ int i,j;
+ uint8_t *buf, *sample_buf;
+ int buf_len, sample_len;
+ uint32_t dev_num;
+
+ sdr_t *sdr = NULL;
+ dongle_t *dongle = NULL;
+
+
+ if ( (sdr = sdr_init()) == NULL )
+ {
+ printf("Cannot init sdr manager\n");
+ goto main_exit;
+ }
+
+ if ( sdr_open_device( sdr, 0 ) != 0 )
+ {
+ printf("Cannot open dongle 0\n");
+ goto main_exit;
+ }
+ dongle = sdr_get_device_id( sdr, 0 );
+ dongle_set_freq( dongle, CENTER_FREQ );
+ dongle_set_sample_rate( dongle, SAMPLE_RATE );
+
+ sine_table( FFT_LEVEL );
+
+
+
+
+ buf_len = WIDTH_POINTS;
+ buf = malloc( buf_len );
+
+ sample_len = SAMPLE_LENGHT;
+ sample_buf = malloc( sample_len );
+
+ srand(0); //fake seed
+ for ( i=0; i<40;i++ )
+ {
+
+ //read some samples
+ dongle_read_samples( dongle, sample_buf, sample_len );
+
+ //do fft
+ simple_fft( sample_buf, sample_len );
+
+ //prepare to show on the screen
+ if (normalise( sample_buf, sample_len/2, buf, buf_len ) == -1)
+ {
+ printf("Cannot normalise\n");
+ }
+ pipe_watefall( buf_len, buf );
+ usleep(1000000);
+ }
+
+main_exit:
+ //close gui, restore terminal mode
+ sdr_close( sdr );
+
+ return 0;
+}