kopia lustrzana https://github.com/rs1729/RS
iq_svcl: test -> master (FFT csv)
rodzic
22ef6e1370
commit
2ce01d8b9a
|
@ -23,16 +23,23 @@ receive IF stream from baseband IQ via TCP, default `PORT=1280 (iq_svcl.h)`<br /
|
|||
`-0.5 < fq < 0.5`: (relative) frequency, `fq=frequency/sr` <br />
|
||||
`<if_sr>`: IF sample rate <br />
|
||||
`<bo>=8,16,32`: output/IF bits per (real) sample (u8, s16 or f32) <br />
|
||||
down-converts up to `MAX_FQ=(4+1) (iq_base.h)` channels/signals. More signals than number of CPUs/cores is not recommended.<br />
|
||||
down-converts up to `MAX_FQ=(4+1) (iq_base.h)` channels/signals. (On older CPUs, more signals than number of CPU cores is not recommended.)<br />
|
||||
(Note: If the baseband sample rate has no appropriate factors (e.g. if prime), the IF sample rate might be high and IF-processing slow.)<br />
|
||||
One channel can be used for scanning, `--fft <fft.txt>` makes FFT (2 seconds average).
|
||||
The FFT is saved in `<fft.txt>` as `<fq>;<dB>`, approx. 200 Hz per bin.<br />
|
||||
One channel can be used for scanning, e.g. `./iq_server --fft_avg <m> <fft_avg.csv>` makes *m* rows of avg-FFT (FFT_AVG=2 seconds average), and
|
||||
this channel will be reused for client FFT requests. Only one channel/thread can be used for FFT/scanning. A client can request a new FFT,
|
||||
if the last FFT has finished.<br />
|
||||
There are two kinds of FFTs, `fft_all` and `fft_avg`. `fft_avg` integrates over FFT_AVG=2 seconds and can be used for signal peak scanning.
|
||||
For waterfall display, `--fft_all <m> <fft_all.csv>` produces *m*\*FFT_AVG\*FFT_FPS/2 rows of FFT (FFT_AVG seconds, FFT_FPS/2 per sec).
|
||||
The FFT is saved in `<fft.csv>` as<br />
|
||||
`sec.ms,freq_min,freq_max,Hz/bin,N_bins, db_1,...,db_N`<br />
|
||||
approx. 200 Hz per bin.
|
||||
Choose `filename="-"` for `stdout`.<br />
|
||||
If no output bps is chosen (`--bo [8,16,32]`), the IF bps is equal to the baseband bps. It is recommended to use
|
||||
`--bo 32` (i.e. float32) output, then no quantization noise is introduced when converting from internal float32 samples.<br />
|
||||
|
||||
- Ex.2<br />
|
||||
[terminal 1]<br />
|
||||
`T1$ rtl_sdr -f 403.0M -s 1920000 - | ./iq_server --fft fft_server.txt --bo 32 - 1920000 8`<br />
|
||||
`T1$ rtl_sdr -f 403.0M -s 1920000 - | ./iq_server --fft_avg 1 fft_server.csv --bo 32 - 1920000 8`<br />
|
||||
[terminal 2]<br />
|
||||
`T2$ ./iq_client --freq -0.3125 | ./m10mod -c -vv --IQ 0.0 - 48000 32`<br />
|
||||
[terminal 3]<br />
|
||||
|
@ -41,7 +48,17 @@ receive IF stream from baseband IQ via TCP, default `PORT=1280 (iq_svcl.h)`<br /
|
|||
`T4$ ./iq_client -1` (*close channel 1*)<br />
|
||||
`T4$ ./iq_client --stop` (*close all clients and stop server*)<br />
|
||||
|
||||
The `iq_server` `--fft` option immediately starts reading the IQ stream (so buffering is reduced).<br />
|
||||
`./iq_client --fft <fft_cl.txt>` can also request FFT.<br />
|
||||
The IF sample rate `if_sr` is at least 48000 such that the baseband sample rate `sr` is a multiple of `if_sr`.
|
||||
- The `iq_server` FFT options immediately start reading the IQ stream (so buffering is reduced).<br />
|
||||
`./iq_client <fft_opt> <m> <fft_cl.txt>`, where `<fft_opt>=--fft_avg_cl` or `--fft_all_cl`, requests FFT from the server.<br />
|
||||
(`<fft_opt>=--fft_avg_sv/--fft_all_sv` would save the FFT at the server, but only if `./iq_server --enable_clsv_out`.)<br />
|
||||
The IF sample rate `if_sr` is at least 48000 and such that the baseband sample rate `sr` is a multiple of `if_sr`.
|
||||
|
||||
- Ex.3<br />
|
||||
[terminal 1]<br />
|
||||
`T1$ rtl_sdr -f 404550k -s 2048000 - | ./iq_server --fft_avg 1 fft_avg.csv --bo 32 - 2048000 8`<br />
|
||||
(scan FFT: `./scan_fft fft_avg.csv`)<br />
|
||||
[terminal 3]<br />
|
||||
`T3$ ./iq_client --fft_all_cl -1 - | python plot_fft_ani.py 3 -`<br />
|
||||
![FFT image](fft3-1.png "FFT")
|
||||
|
||||
|
||||
|
|
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 212 KiB |
|
@ -34,7 +34,10 @@ typedef struct {
|
|||
double xlt_fq;
|
||||
float complex *blk;
|
||||
int used;
|
||||
//
|
||||
int fft;
|
||||
int stop_fft;
|
||||
int fft_num;
|
||||
} thd_t;
|
||||
|
||||
|
||||
|
@ -97,6 +100,7 @@ typedef struct {
|
|||
thd_t thd;
|
||||
int fd;
|
||||
char *fname;
|
||||
FILE *fpo;
|
||||
} thargs_t;
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,27 @@
|
|||
*
|
||||
* gcc -O2 iq_client.c -o iq_client
|
||||
*
|
||||
* usage:
|
||||
* (request IF IQ samples)
|
||||
* ./iq_client [--ip <ip_adr>] [--port <pn>] --freq <fq> # -0.5 < fq < 0.5
|
||||
*
|
||||
* (request FFT)
|
||||
* ./iq_client <fft_opt> <m> <filename> # FFT csv output
|
||||
* <fft_opt>:
|
||||
* --fft_avg_cl # client out
|
||||
* --fft_all_cl # client out
|
||||
* --fft_avg_sv # server out (if iq_server --enable_clsv_out)
|
||||
* --fft_avg_sv # server out (if iq_server --enable_clsv_out)
|
||||
* <m>:
|
||||
* _avg_: m avg-FFTs
|
||||
* _all_: m*FFT_FPS/2 FFTs
|
||||
* m = -1 : continuous FFT output
|
||||
* <filename>:
|
||||
* csv filename ("-": stdout)
|
||||
*
|
||||
* ./iq_client -<n> # close client <n>
|
||||
* ./iq_client --stop # close all clients, stop server
|
||||
*
|
||||
* author: zilog80
|
||||
*/
|
||||
|
||||
|
@ -49,17 +70,24 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
else serv_port = port;
|
||||
}
|
||||
else if (strcmp(*argv, "--fft0") == 0) {
|
||||
sprintf(sendln, "%s", "--fft0");
|
||||
}
|
||||
else if (strcmp(*argv, "--fft") == 0) {
|
||||
sprintf(sendln, "%s", "--fft");
|
||||
++argv;
|
||||
if (*argv) {
|
||||
fname_fft = *argv;
|
||||
else if (strncmp(*argv, "--fft", 5) == 0) {
|
||||
char *arg_fft = *argv;
|
||||
int fft_num = 0;
|
||||
int opt_fft_cl = 0;
|
||||
if (strncmp(arg_fft+5, "_avg", 4) == 0) opt_fft_cl = OPT_FFT_AVG;
|
||||
else if (strncmp(arg_fft+5, "_all", 4) != 0) return -1;
|
||||
if (strncmp(arg_fft+5+4, "_cl", 3) == 0) {
|
||||
opt_fft_cl |= OPT_FFT_CLNT;
|
||||
re = 2;
|
||||
}
|
||||
else if (strncmp(arg_fft+5+4, "_sv", 3) == 0) opt_fft_cl |= OPT_FFT_SERV;
|
||||
else return -1;
|
||||
re = 2;
|
||||
++argv;
|
||||
if (*argv) fft_num = atoi(*argv); else return -1;
|
||||
++argv;
|
||||
if (*argv) fname_fft = *argv; else return -1;
|
||||
//sprintf(sendln, "%s_%s_%s", "--fft", (opt_fft_cl & OPT_FFT_AVG) ? "avg" : "all", (opt_fft_cl & OPT_FFT_CLNT) ? "cl" : "sv");
|
||||
sprintf(sendln, "%s %d %s", arg_fft, fft_num, fname_fft);
|
||||
}
|
||||
else if (strcmp(*argv, "--freq") == 0) {
|
||||
++argv;
|
||||
|
@ -155,7 +183,9 @@ int main(int argc, char *argv[]) {
|
|||
else if ( re == 2 )
|
||||
{
|
||||
// fft data
|
||||
FILE *fpo = fopen(fname_fft, "wb");
|
||||
FILE *fpo = NULL;
|
||||
if (fname_fft[0] == '-') fpo = stdout;
|
||||
else fpo = fopen(fname_fft, "wb");
|
||||
if (fpo != NULL) {
|
||||
|
||||
memset(recvln, 0, LINELEN+1);
|
||||
|
|
|
@ -7,6 +7,24 @@
|
|||
*
|
||||
* (gcc -O2 iq_client.c -o iq_client)
|
||||
*
|
||||
* usage:
|
||||
* ./iq_server [--enable_clsv_out] [--port <pn>] [iq_baseband.wav]
|
||||
* no wav-file: stdin
|
||||
*
|
||||
* ./iq_server [--bo <b>] - <sr> <bs> [iq_baseband.raw]
|
||||
* <b>=8,16,32 bit client/IF output
|
||||
*
|
||||
* ./iq_server <fft_opt> <m> <filename> [iq_baseband.wav] # FFT csv output
|
||||
* <fft_opt>:
|
||||
* --fft_avg
|
||||
* --fft_all
|
||||
* <m>:
|
||||
* _avg: m avg-FFTs
|
||||
* _all: m*FFT_FPS/2 FFTs
|
||||
* m = -1 : continuous FFT output
|
||||
* <filename>:
|
||||
* csv filename ("-": stdout)
|
||||
*
|
||||
* author: zilog80
|
||||
*/
|
||||
|
||||
|
@ -27,13 +45,13 @@
|
|||
#include "iq_svcl.h"
|
||||
#include "iq_base.h"
|
||||
|
||||
#define FFT_AVG 2 // fft_avg: integrate FFT_AVG seconds, 2*FFT_FPS FFTs
|
||||
#define FFT_FPS 16 // fft_all: output (ca.) FFT_FPS/2 per sec
|
||||
|
||||
#define FPOUT stderr
|
||||
|
||||
#define OPT_FFT_SERV 1 // server
|
||||
#define OPT_FFT_CLSV 2 // server (client request)
|
||||
#define OPT_FFT_CLNT 3 // server -> client
|
||||
|
||||
static int option_dbg = 0;
|
||||
static int option_clsv_out = 0;
|
||||
|
||||
static int tcp_eof = 0;
|
||||
|
||||
|
@ -275,21 +293,82 @@ static void *thd_IF(void *targs) { // pcm_t *pcm, double xlt_fq
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#define FFT_SEC 2
|
||||
#define FFT_FPS 20
|
||||
|
||||
static int fft_txt_prn(FILE *fpo, dft_t *dft, float *db) {
|
||||
int j;
|
||||
|
||||
fprintf(fpo, "# <freq/sr>;<dB> ## sr:%d , N:%d\n", dft->sr, dft->N);
|
||||
for (j = dft->N/2; j < dft->N/2 + dft->N; j++) {
|
||||
fprintf(fpo, "%+11.8f;%7.2f\n", bin2fq(dft, j % dft->N), db[j % dft->N]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fft_txt_tcp(int fd, dft_t *dft, float *db) {
|
||||
char sendln[LINELEN+1];
|
||||
int sendln_len;
|
||||
int j, l;
|
||||
|
||||
snprintf(sendln, LINELEN, "# <freq/sr>;<dB> ## sr:%d , N:%d\n", dft->sr, dft->N);
|
||||
sendln_len = strlen(sendln);
|
||||
l = write(fd, sendln, sendln_len);
|
||||
for (j = dft->N/2; j < dft->N/2 + dft->N; j++) {
|
||||
memset(sendln, 0, LINELEN+1);
|
||||
snprintf(sendln, LINELEN, "%+11.8f;%7.2f\n", bin2fq(dft, j % dft->N), db[j % dft->N]);
|
||||
sendln_len = strlen(sendln);
|
||||
l = write(fd, sendln, sendln_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int fft_csv_prn(FILE *fpo, dft_t *dft, float *db, double t_sec) {
|
||||
int j;
|
||||
|
||||
fprintf(fpo, "%7.3f, ", t_sec);
|
||||
fprintf(fpo, "%d, %d, ", (int)bin2freq(dft, dft->N/2), (int)bin2freq(dft, dft->N/2 - 1));
|
||||
fprintf(fpo, "%.2f, ", dft->sr/(double)dft->N);
|
||||
fprintf(fpo, "%d, ", dft->N);
|
||||
for (j = dft->N/2; j < dft->N/2 + dft->N; j++) {
|
||||
fprintf(fpo, "%7.2f%c", db[j % dft->N], j < dft->N/2 + dft->N-1 ? ',' : '\n');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fft_csv_tcp(int fd, dft_t *dft, float *db, double t_sec) {
|
||||
char sendln[LINELEN+1];
|
||||
int sendln_len;
|
||||
int j, l;
|
||||
|
||||
snprintf(sendln, LINELEN, "%7.3f, %d, %d, %.2f, %d, ",
|
||||
t_sec, (int)bin2freq(dft, dft->N/2), (int)bin2freq(dft, dft->N/2 - 1), dft->sr/(double)dft->N, dft->N);
|
||||
sendln_len = strlen(sendln);
|
||||
l = write(fd, sendln, sendln_len);
|
||||
for (j = dft->N/2; j < dft->N/2 + dft->N; j++) {
|
||||
memset(sendln, 0, LINELEN+1);
|
||||
snprintf(sendln, LINELEN, "%7.2f%c", db[j % dft->N], j < dft->N/2 + dft->N-1 ? ',' : '\n');
|
||||
sendln_len = strlen(sendln);
|
||||
l = write(fd, sendln, sendln_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void *thd_FFT(void *targs) {
|
||||
|
||||
thargs_t *tharg = targs;
|
||||
pcm_t *pcm = &(tharg->pcm);
|
||||
|
||||
FILE *fpo = NULL;
|
||||
char *fname_fft = "db_fft.txt";
|
||||
|
||||
int k;
|
||||
int bitQ = 0;
|
||||
|
||||
float complex *z = NULL;
|
||||
float *db = NULL;
|
||||
float *all_rZ = NULL;
|
||||
float *avg_rZ = NULL;
|
||||
float *avg_db = NULL;
|
||||
|
||||
|
@ -312,7 +391,6 @@ static void *thd_FFT(void *targs) {
|
|||
dsp.bps_out = pcm->bps_out;
|
||||
|
||||
|
||||
//(dsp.thd)->fft = 1;
|
||||
if (option_dbg) {
|
||||
fprintf(stderr, "init FFT buffers\n");
|
||||
}
|
||||
|
@ -326,6 +404,8 @@ static void *thd_FFT(void *targs) {
|
|||
|
||||
z = calloc(dsp.decM+1, sizeof(float complex)); if (z == NULL) goto exit_thread;
|
||||
|
||||
db = calloc(dsp.DFT.N+1, sizeof(float)); if (db == NULL) goto exit_thread;
|
||||
all_rZ = calloc(dsp.DFT.N+1, sizeof(float)); if (all_rZ == NULL) goto exit_thread;
|
||||
avg_rZ = calloc(dsp.DFT.N+1, sizeof(float)); if (avg_rZ == NULL) goto exit_thread;
|
||||
avg_db = calloc(dsp.DFT.N+1, sizeof(float)); if (avg_db == NULL) goto exit_thread;
|
||||
|
||||
|
@ -334,12 +414,16 @@ static void *thd_FFT(void *targs) {
|
|||
int len = dsp.DFT.N / dsp.decM;
|
||||
int mlen = len*dsp.decM;
|
||||
int sum_n = 0;
|
||||
int sec = FFT_SEC;
|
||||
int fft_step = dsp.sr_base/(dsp.DFT.N*FFT_FPS);
|
||||
int sum_fft = 0;
|
||||
int avg_sec = FFT_AVG;
|
||||
int fft_step = (int)(dsp.sr_base/(double)(dsp.DFT.N*FFT_FPS) + 0.5);
|
||||
int n_fft = 0;
|
||||
int th_used = 0;
|
||||
int readSamples = 1;
|
||||
|
||||
int n_out = 0;
|
||||
|
||||
|
||||
bitQ = 0;
|
||||
while ( bitQ != EOF )
|
||||
{
|
||||
|
@ -367,65 +451,95 @@ static void *thd_FFT(void *targs) {
|
|||
n++;
|
||||
if (n == len) { // mlen = len * decM <= DFT.N
|
||||
|
||||
n_fft += 1;
|
||||
|
||||
if ((dsp.thd)->fft && sum_n*n_fft*mlen < sec*dsp.sr_base && n_fft >= fft_step)
|
||||
if ( (dsp.thd)->fft )
|
||||
{
|
||||
for (j = 0; j < mlen; j++) {
|
||||
dsp.DFT.Z[j] *= dsp.DFT.win[j];
|
||||
if ((dsp.thd)->fft_num == 0)
|
||||
{
|
||||
if ( tharg->fpo ) { fclose(tharg->fpo); tharg->fpo = NULL; }
|
||||
else if ( tharg->fd > STDIN_FILENO ) { close(tharg->fd); tharg->fd = -1; }
|
||||
|
||||
(dsp.thd)->fft = 0;
|
||||
}
|
||||
while (j < dsp.DFT.N) dsp.DFT.Z[j++] = 0.0; // dft(Z[...]) != 0
|
||||
|
||||
raw_dft(&(dsp.DFT), dsp.DFT.Z);
|
||||
n_fft += 1;
|
||||
|
||||
for (j = 0; j < dsp.DFT.N; j++) avg_rZ[j] += cabs(dsp.DFT.Z[j]);
|
||||
if (sum_n*n_fft*mlen < avg_sec*dsp.sr_base && n_fft >= fft_step) {
|
||||
n_fft = fft_step;
|
||||
|
||||
sum_n++;
|
||||
n_fft = 0;
|
||||
}
|
||||
if (sum_n*fft_step*mlen >= sec*dsp.sr_base) {
|
||||
|
||||
for (j = 0; j < dsp.DFT.N; j++) avg_rZ[j] /= dsp.DFT.N*(float)sum_n;
|
||||
for (j = 0; j < dsp.DFT.N; j++) avg_db[j] = 20.0*log10(avg_rZ[j]+1e-20);
|
||||
|
||||
|
||||
pthread_mutex_lock( (dsp.thd)->mutex );
|
||||
fprintf(FPOUT, "<%d: FFT>\n", (dsp.thd)->tn);
|
||||
pthread_mutex_unlock( (dsp.thd)->mutex );
|
||||
|
||||
if ( (dsp.thd)->fft == OPT_FFT_CLNT ) { // send FFT data to client
|
||||
char sendln[LINELEN+1];
|
||||
int sendln_len;
|
||||
int l;
|
||||
snprintf(sendln, LINELEN, "# <freq/sr>;<dB> ## sr:%d , N:%d\n", dsp.DFT.sr, dsp.DFT.N);
|
||||
sendln_len = strlen(sendln);
|
||||
l = write(tharg->fd, sendln, sendln_len);
|
||||
for (j = dsp.DFT.N/2; j < dsp.DFT.N/2 + dsp.DFT.N; j++) {
|
||||
memset(sendln, 0, LINELEN+1);
|
||||
snprintf(sendln, LINELEN, "%+11.8f;%7.2f\n", bin2fq(&(dsp.DFT), j % dsp.DFT.N), avg_db[j % dsp.DFT.N]);
|
||||
sendln_len = strlen(sendln);
|
||||
l = write(tharg->fd, sendln, sendln_len);
|
||||
if (sum_fft == 0) {
|
||||
pthread_mutex_lock( (dsp.thd)->mutex );
|
||||
fprintf(FPOUT, "<%d: FFT_START>\n", (dsp.thd)->tn);
|
||||
pthread_mutex_unlock( (dsp.thd)->mutex );
|
||||
}
|
||||
}
|
||||
else { // save FFT at server
|
||||
if ( (dsp.thd)->fft == OPT_FFT_SERV ) fname_fft = tharg->fname;
|
||||
else /* OPT_FFT_CLSV */ fname_fft = "db_fft_cl.txt";
|
||||
fpo = fopen(fname_fft, "wb");
|
||||
if (fpo != NULL) {
|
||||
fprintf(fpo, "# <freq/sr>;<dB> ## sr:%d , N:%d\n", dsp.DFT.sr, dsp.DFT.N);
|
||||
for (j = dsp.DFT.N/2; j < dsp.DFT.N/2 + dsp.DFT.N; j++) {
|
||||
fprintf(fpo, "%+11.8f;%7.2f\n", bin2fq(&(dsp.DFT), j % dsp.DFT.N), avg_db[j % dsp.DFT.N]);
|
||||
|
||||
for (j = 0; j < mlen; j++) {
|
||||
dsp.DFT.Z[j] *= dsp.DFT.win[j];
|
||||
}
|
||||
while (j < dsp.DFT.N) dsp.DFT.Z[j++] = 0.0; // dft(Z[...]) != 0
|
||||
|
||||
raw_dft(&(dsp.DFT), dsp.DFT.Z);
|
||||
|
||||
for (j = 0; j < dsp.DFT.N; j++) {
|
||||
float rZ = cabs(dsp.DFT.Z[j]);
|
||||
avg_rZ[j] += rZ;
|
||||
all_rZ[j] += rZ;
|
||||
}
|
||||
|
||||
if ( (sum_fft&1)==1 && ((dsp.thd)->fft & OPT_FFT_AVG) == 0 ) {
|
||||
double t_sec = sum_fft*n_fft*mlen / (double)dsp.sr_base;
|
||||
for (j = 0; j < dsp.DFT.N; j++) { // if sum_fft odd,
|
||||
db[j] = 20.0*log10(0.5*all_rZ[j]/dsp.DFT.N+1e-20); // 0.5: rZ_0+rZ_1
|
||||
all_rZ[j] = 0.0f;
|
||||
}
|
||||
// sec.ms, freq_min, freq_max, Hz/bin, N_bins, db_1, ..., db_N
|
||||
if ( tharg->fpo ) { // save FFT at server
|
||||
fft_csv_prn(tharg->fpo, &(dsp.DFT), db, t_sec);
|
||||
}
|
||||
else if ( tharg->fd > STDIN_FILENO ) {
|
||||
fft_csv_tcp(tharg->fd, &(dsp.DFT), db, t_sec);
|
||||
}
|
||||
fclose(fpo);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "error: open %s\n", fname_fft);
|
||||
}
|
||||
}
|
||||
if ( (dsp.thd)->fft != OPT_FFT_SERV ) close(tharg->fd);
|
||||
|
||||
(dsp.thd)->fft = 0;
|
||||
sum_n = 0;
|
||||
sum_n++;
|
||||
sum_fft++;
|
||||
n_fft = 0;
|
||||
}
|
||||
if (sum_n*fft_step*mlen >= avg_sec*dsp.sr_base) {
|
||||
float nN = 1.0/(dsp.DFT.N*(float)sum_n);
|
||||
for (j = 0; j < dsp.DFT.N; j++) {
|
||||
avg_db[j] = 20.0*log10(nN*avg_rZ[j]+1e-20);
|
||||
avg_rZ[j] = 0.0f;
|
||||
}
|
||||
|
||||
if ( (dsp.thd)->fft & OPT_FFT_AVG ) {
|
||||
double t_sec = sum_fft*fft_step*mlen / (double)dsp.sr_base;
|
||||
if ( tharg->fpo ) { // send FFT data to client
|
||||
fft_csv_prn(tharg->fpo, &(dsp.DFT), avg_db, t_sec);
|
||||
}
|
||||
else if ( tharg->fd > STDIN_FILENO ) {
|
||||
fft_csv_tcp(tharg->fd, &(dsp.DFT), avg_db, t_sec);
|
||||
}
|
||||
}
|
||||
|
||||
n_out++;
|
||||
|
||||
if ((dsp.thd)->fft_num > 0 && n_out >= (dsp.thd)->fft_num)
|
||||
{
|
||||
if ( tharg->fpo ) { fclose(tharg->fpo); tharg->fpo = NULL; }
|
||||
else if ( tharg->fd > STDIN_FILENO ) { close(tharg->fd); tharg->fd = -1; }
|
||||
|
||||
(dsp.thd)->fft = 0;
|
||||
sum_fft = 0;
|
||||
n_out = 0;
|
||||
|
||||
pthread_mutex_lock( (dsp.thd)->mutex );
|
||||
fprintf(FPOUT, "<%d: FFT_STOP>\n", (dsp.thd)->tn);
|
||||
pthread_mutex_unlock( (dsp.thd)->mutex );
|
||||
|
||||
}
|
||||
|
||||
sum_n = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FFT_READ_SINK_MIN
|
||||
|
@ -445,12 +559,39 @@ static void *thd_FFT(void *targs) {
|
|||
|
||||
if ( (dsp.thd)->used == 0 )
|
||||
{
|
||||
(dsp.thd)->fft = 0;
|
||||
pthread_mutex_lock( (dsp.thd)->mutex );
|
||||
fprintf(FPOUT, "<%d: CLOSE>\n", (dsp.thd)->tn);
|
||||
pthread_mutex_unlock( (dsp.thd)->mutex );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( (dsp.thd)->stop_fft > 0 )
|
||||
{
|
||||
if ( tharg->fpo ) { fclose(tharg->fpo); tharg->fpo = NULL; }
|
||||
else if ( tharg->fd > STDIN_FILENO ) { close(tharg->fd); tharg->fd = -1; }
|
||||
|
||||
(dsp.thd)->fft = 0;
|
||||
(dsp.thd)->stop_fft = 0;
|
||||
sum_fft = 0;
|
||||
sum_n = 0;
|
||||
n_out = 0;
|
||||
|
||||
pthread_mutex_lock( (dsp.thd)->mutex );
|
||||
fprintf(FPOUT, "<%d: STOP_FFT>\n", (dsp.thd)->tn);
|
||||
pthread_mutex_unlock( (dsp.thd)->mutex );
|
||||
}
|
||||
}
|
||||
|
||||
if ((dsp.thd)->fft_num < 0)
|
||||
{
|
||||
if ( tharg->fpo ) { fclose(tharg->fpo); tharg->fpo = NULL; }
|
||||
else if ( tharg->fd > STDIN_FILENO ) { close(tharg->fd); tharg->fd = -1; }
|
||||
(dsp.thd)->fft = 0;
|
||||
|
||||
pthread_mutex_lock( (dsp.thd)->mutex );
|
||||
fprintf(FPOUT, "<%d: FFT_STOP>\n", (dsp.thd)->tn);
|
||||
pthread_mutex_unlock( (dsp.thd)->mutex );
|
||||
}
|
||||
|
||||
if (bitQ == EOF) {
|
||||
|
@ -465,6 +606,8 @@ static void *thd_FFT(void *targs) {
|
|||
exit_thread:
|
||||
|
||||
if (z) { free(z); z = NULL; }
|
||||
if (db) { free(db); db = NULL; }
|
||||
if (all_rZ) { free(all_rZ); all_rZ = NULL; }
|
||||
if (avg_rZ) { free(avg_rZ); avg_rZ = NULL; }
|
||||
if (avg_db) { free(avg_db); avg_db = NULL; }
|
||||
|
||||
|
@ -496,6 +639,8 @@ int main(int argc, char **argv) {
|
|||
char tcp_buf[TCPBUF_LEN];
|
||||
int th_used = 0;
|
||||
int tn_fft = -1;
|
||||
int opt_fft = 0;
|
||||
int fft_num = 0;
|
||||
|
||||
pcm_t pcm = {0};
|
||||
|
||||
|
@ -510,11 +655,15 @@ int main(int argc, char **argv) {
|
|||
|
||||
for (k = 0; k < MAX_FQ; k++) base_fqs[k] = 0.0;
|
||||
|
||||
// server options
|
||||
++argv;
|
||||
while ((*argv) && (!wavloaded)) {
|
||||
if (strcmp(*argv, "--dbg") == 0) {
|
||||
option_dbg = 1;
|
||||
}
|
||||
else if (strcmp(*argv, "--enable_clsv_out") == 0) {
|
||||
option_clsv_out = 1;
|
||||
}
|
||||
else if (strcmp(*argv, "--port") == 0) {
|
||||
int port = 0;
|
||||
++argv;
|
||||
|
@ -524,7 +673,11 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
else serv_port = port;
|
||||
}
|
||||
else if (strcmp(*argv, "--fft") == 0) {
|
||||
else if (strncmp(*argv, "--fft", 5) == 0) {
|
||||
char *arg_fft = *argv;
|
||||
if (strncmp(arg_fft+5, "_avg", 4) == 0) opt_fft = OPT_FFT_SERV | OPT_FFT_AVG;
|
||||
else if (strncmp(arg_fft+5, "_all", 4) == 0) opt_fft = OPT_FFT_SERV;
|
||||
else return -1;
|
||||
if (xlt_cnt < MAX_FQ) {
|
||||
base_fqs[xlt_cnt] = 0.0;
|
||||
rstype[xlt_cnt] = thd_FFT;
|
||||
|
@ -532,6 +685,8 @@ int main(int argc, char **argv) {
|
|||
xlt_cnt++;
|
||||
}
|
||||
++argv;
|
||||
if (*argv) fft_num = atoi(*argv); else return -1;
|
||||
++argv;
|
||||
if (*argv) fname_fft = *argv; else return -1;
|
||||
}
|
||||
else if (strcmp(*argv, "-") == 0) {
|
||||
|
@ -597,8 +752,21 @@ int main(int argc, char **argv) {
|
|||
|
||||
for (k = 0; k < xlt_cnt; k++) {
|
||||
if (k == tn_fft) {
|
||||
tharg[k].thd.fft = OPT_FFT_SERV;
|
||||
tharg[k].thd.fft = opt_fft;
|
||||
tharg[k].fname = fname_fft;
|
||||
tharg[k].thd.fft_num = fft_num;
|
||||
tharg[k].thd.stop_fft = 0;
|
||||
|
||||
if ( (tharg[k].thd.fft & 0xF) == OPT_FFT_SERV ) { // save FFT at server
|
||||
if (fname_fft) {
|
||||
if (fname_fft[0] == '-') tharg[k].fpo = stdout;
|
||||
else tharg[k].fpo = fopen(fname_fft, "wb");
|
||||
}
|
||||
else return -1;
|
||||
if (tharg[k].fpo == NULL) {
|
||||
fprintf(stderr, "error: open %s\n", fname_fft);
|
||||
}
|
||||
}
|
||||
}
|
||||
tharg[k].thd.tn = k;
|
||||
tharg[k].thd.tn_bit = (1<<k);
|
||||
|
@ -686,6 +854,7 @@ int main(int argc, char **argv) {
|
|||
//if (th_used == 0) break;
|
||||
|
||||
|
||||
// client commands
|
||||
if ( l > 1 ) {
|
||||
char *freq = tcp_buf;
|
||||
while (l > 1 && tcp_buf[l-1] < 0x20) l--;
|
||||
|
@ -701,23 +870,76 @@ int main(int argc, char **argv) {
|
|||
break;
|
||||
}
|
||||
else if ( strncmp(tcp_buf, "--fft", 5) == 0 ) {
|
||||
opt_fft = 0;
|
||||
if (strncmp(tcp_buf+5, "_avg", 4) == 0) opt_fft = OPT_FFT_AVG;
|
||||
else if (strncmp(tcp_buf+5, "_all", 4) != 0) return -1;
|
||||
if (strncmp(tcp_buf+5+4, "_cl", 3) == 0) opt_fft |= OPT_FFT_CLNT;
|
||||
else if (strncmp(tcp_buf+5+4, "_sv", 3) == 0) {
|
||||
if (option_clsv_out) opt_fft |= OPT_FFT_SERV;
|
||||
else {
|
||||
pthread_mutex_lock( &mutex );
|
||||
fprintf(FPOUT, "<NO CLSV OUT>\n");
|
||||
pthread_mutex_unlock( &mutex );
|
||||
close(conn_fd);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else return -1;
|
||||
if (tcp_buf+5+4+4) fft_num = atoi(tcp_buf+5+4+4); else fft_num = 0;
|
||||
char *fname_fft_cl = "db_fft_cl.txt";
|
||||
int opt_fft = strcmp(tcp_buf, "--fft0") == 0 ? OPT_FFT_CLSV : OPT_FFT_CLNT;
|
||||
//close(conn_fd);
|
||||
char *pbuf = tcp_buf;
|
||||
for (pbuf = tcp_buf+5+4+4; *pbuf; pbuf++) {
|
||||
if (*pbuf == ' ') break;
|
||||
}
|
||||
if (*pbuf == ' ') {
|
||||
fname_fft_cl = pbuf+1;
|
||||
}
|
||||
if ( !tcp_eof )
|
||||
{
|
||||
if (tn_fft >= 0) {
|
||||
tharg[tn_fft].thd.fft = opt_fft;
|
||||
tharg[tn_fft].fname = fname_fft_cl;
|
||||
tharg[tn_fft].fd = conn_fd;
|
||||
if (tharg[tn_fft].thd.fft == 0) {
|
||||
tharg[tn_fft].thd.fft_num = fft_num;
|
||||
tharg[tn_fft].thd.stop_fft = 0;
|
||||
tharg[tn_fft].fname = fname_fft_cl;
|
||||
tharg[tn_fft].fd = conn_fd;
|
||||
|
||||
if ( (opt_fft & 0xF) == OPT_FFT_SERV ) { // save FFT at server
|
||||
if (fname_fft_cl) {
|
||||
if (fname_fft_cl[0] == '-') tharg[tn_fft].fpo = stdout;
|
||||
else tharg[tn_fft].fpo = fopen(fname_fft_cl, "wb");
|
||||
}
|
||||
else return -1;
|
||||
if (tharg[tn_fft].fpo == NULL) {
|
||||
fprintf(stderr, "error: open %s\n", fname_fft_cl);
|
||||
}
|
||||
close(tharg[tn_fft].fd); tharg[tn_fft].fd = -1; // tharg[tn_fft].fd == conn_fd
|
||||
}
|
||||
else { // (opt_fft & 0xF) == OPT_FFT_CLNT : send FFT to client
|
||||
tharg[tn_fft].fpo = NULL;
|
||||
}
|
||||
|
||||
tharg[tn_fft].thd.fft = opt_fft;
|
||||
}
|
||||
else {
|
||||
pthread_mutex_lock( &mutex );
|
||||
fprintf(FPOUT, "<%d: FFT running>\n", tn_fft);
|
||||
pthread_mutex_unlock( &mutex );
|
||||
|
||||
close(conn_fd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (k = 0; k < MAX_FQ; k++) {
|
||||
if (tharg[k].thd.used == 0) break;
|
||||
if (tharg[k].thd.used == 0) {
|
||||
if (k != tn_fft) break;
|
||||
}
|
||||
}
|
||||
if (k < MAX_FQ) {
|
||||
tharg[k].thd.fft = opt_fft;
|
||||
tharg[k].thd.fft_num = fft_num;
|
||||
tharg[k].thd.stop_fft = 0;
|
||||
tharg[k].fname = fname_fft_cl;
|
||||
tharg[k].fd = conn_fd;
|
||||
|
||||
tn_fft = k;
|
||||
tharg[k].thd.tn = k;
|
||||
tharg[k].thd.tn_bit = (1<<k);
|
||||
|
@ -726,12 +948,26 @@ int main(int argc, char **argv) {
|
|||
//tharg[k].thd.lock = &lock;
|
||||
tharg[k].thd.blk = block_decMB;
|
||||
tharg[k].thd.xlt_fq = 0.0;
|
||||
|
||||
tharg[k].pcm = pcm;
|
||||
tharg[k].fd = conn_fd;
|
||||
|
||||
if ( (opt_fft & 0xF) == OPT_FFT_SERV ) { // save FFT at server
|
||||
if (fname_fft_cl) {
|
||||
if (fname_fft_cl[0] == '-') tharg[k].fpo = stdout;
|
||||
else tharg[k].fpo = fopen(fname_fft_cl, "wb");
|
||||
}
|
||||
else return -1;
|
||||
if (tharg[k].fpo == NULL) {
|
||||
fprintf(stderr, "error: open %s\n", fname_fft_cl);
|
||||
}
|
||||
close(tharg[k].fd); tharg[k].fd = -1; // tharg[k].fd == conn_fd
|
||||
}
|
||||
else { // (opt_fft & 0xF) == OPT_FFT_CLNT : send FFT to client
|
||||
tharg[k].fpo = NULL;
|
||||
}
|
||||
|
||||
rbf1 |= tharg[k].thd.tn_bit;
|
||||
tharg[k].thd.used = 1;
|
||||
tharg[k].thd.fft = opt_fft;
|
||||
|
||||
pthread_create(&tharg[k].thd.tid, NULL, thd_FFT, &tharg[k]);
|
||||
|
||||
|
@ -753,9 +989,14 @@ int main(int argc, char **argv) {
|
|||
else if (tcp_buf[0] == '-') { // -<n> : close <n>
|
||||
int num = atoi(tcp_buf+1);
|
||||
if (num >= 0 && num < MAX_FQ) {
|
||||
if (num != tn_fft) {
|
||||
if (num != tn_fft)
|
||||
{
|
||||
tharg[num].thd.used = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tharg[num].thd.stop_fft = 1;
|
||||
}
|
||||
}
|
||||
close(conn_fd);
|
||||
}
|
||||
|
@ -789,6 +1030,7 @@ int main(int argc, char **argv) {
|
|||
rbf1 |= tharg[k].thd.tn_bit;
|
||||
tharg[k].thd.used = 1;
|
||||
tharg[k].thd.fft = 0;
|
||||
tharg[k].thd.stop_fft = 0;
|
||||
|
||||
pthread_create(&tharg[k].thd.tid, NULL, thd_IF, &tharg[k]);
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
#define OPT_FFT_SERV 1 // server
|
||||
#define OPT_FFT_CLNT 2 // server -> client
|
||||
#define OPT_FFT_AVG 0x100
|
||||
|
||||
#define TCPBUF_LEN 1024
|
||||
#define SERV_BACKLOG 6
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import matplotlib.ticker as ticker
|
|||
|
||||
if len(sys.argv) < 2:
|
||||
print("usage:")
|
||||
print("\tpython %s <fft_file>" % sys.argv[0])
|
||||
print("\tpython %s <fft_file.csv>" % sys.argv[0])
|
||||
sys.exit()
|
||||
|
||||
fft_file = sys.argv[1]
|
||||
|
@ -18,10 +18,17 @@ if not os.path.isfile(fft_file):
|
|||
sys.exit()
|
||||
|
||||
|
||||
data = np.genfromtxt( fft_file, delimiter=';', names=['fq','db'] , skip_header=1 )
|
||||
raw_data = np.genfromtxt( fft_file, delimiter=',', max_rows=1)
|
||||
data1 = raw_data[:] # max_rows=2: raw_data[0,:]
|
||||
print(data1)
|
||||
|
||||
fq = data['fq']
|
||||
db = data['db']
|
||||
db = data1[5:]
|
||||
|
||||
sr = -2.0*data1[1]
|
||||
|
||||
freq_min = data1[1] / sr
|
||||
freq_max = data1[2] / sr
|
||||
fq = np.arange(freq_min, freq_max, 1.0/(data1[4]+1))
|
||||
|
||||
N = len(db)
|
||||
m = np.mean(db)
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.ticker as ticker
|
||||
import matplotlib.animation as animation
|
||||
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print("usage:")
|
||||
print("\tpython <1/2/3> %s <fft_all.csv>" % sys.argv[0])
|
||||
sys.exit()
|
||||
|
||||
OPT_FFT_L = 1
|
||||
OPT_FFT_W = 2
|
||||
OPT_FFT_B = 3
|
||||
|
||||
OPT_FFT = OPT_FFT_B
|
||||
if (sys.argv[1] == '1'):
|
||||
OPT_FFT = OPT_FFT_L
|
||||
elif (sys.argv[1] == '2'):
|
||||
OPT_FFT = OPT_FFT_W
|
||||
|
||||
fft_file = sys.argv[2]
|
||||
|
||||
|
||||
if (fft_file == "-"):
|
||||
f = sys.stdin
|
||||
else:
|
||||
try:
|
||||
f = open(fft_file)
|
||||
except IOError:
|
||||
print("error: open %s" % fft_file)
|
||||
sys.exit()
|
||||
|
||||
|
||||
FFT_FPS = 16/2
|
||||
WIN_SEC = 10
|
||||
win = WIN_SEC*FFT_FPS
|
||||
|
||||
line = f.readline()
|
||||
#line = f.readline()
|
||||
|
||||
row = np.fromstring(line, dtype=float, sep=',')
|
||||
data = row[5:]
|
||||
|
||||
l = len(data)
|
||||
m = np.mean(data)
|
||||
|
||||
data5 = np.full([win,l], m)
|
||||
for x in range(2, l-2):
|
||||
data5[0,x] = (data[x-2]+data[x-1]+data[x]+data[x+1]+data[x+2])/5.0
|
||||
|
||||
min_db = np.min(data5)
|
||||
max_db = np.max(data5)
|
||||
|
||||
sr = -2.0*row[1]
|
||||
|
||||
freq_min = row[1]
|
||||
freq_max = row[2]
|
||||
N = row[4]
|
||||
|
||||
limits = [freq_min/1e3, freq_max/1e3, WIN_SEC, 0.0]
|
||||
|
||||
fq = np.arange(freq_min/sr, freq_max/sr, 1.0/(row[4]+1))
|
||||
|
||||
|
||||
################################################################################################
|
||||
|
||||
if (OPT_FFT == OPT_FFT_L):
|
||||
fig = plt.figure(figsize=(12, 5))
|
||||
ax1 = fig.add_subplot(111)
|
||||
ax1.set_xlim([fq[0], fq[-1]])
|
||||
ax1.set_ylim([-110.0, -30.0])
|
||||
|
||||
lp, = ax1.plot( fq, data5[0,:], color='g', linewidth=0.4)
|
||||
|
||||
count = 0
|
||||
|
||||
def animate_lp(i):
|
||||
line = f.readline()
|
||||
if line:
|
||||
row = np.fromstring(line, dtype=float, sep=',')
|
||||
data = row[5:]
|
||||
|
||||
global count
|
||||
count += 1
|
||||
global data5
|
||||
#data5 = np.roll(data5, 1, axis=0)
|
||||
for x in range(2, l-2):
|
||||
data5[0,x] = (data[x-2]+data[x-1]+data[x]+data[x+1]+data[x+2])/5.0
|
||||
|
||||
lp.set_data(fq, data5[0,:])
|
||||
|
||||
return [lp]
|
||||
|
||||
ani = animation.FuncAnimation(fig, animate_lp, interval=10, blit=True)
|
||||
|
||||
################################################################################################
|
||||
|
||||
elif (OPT_FFT == OPT_FFT_W):
|
||||
fig = plt.figure(figsize=(12, 5))
|
||||
ax2 = fig.add_subplot(111)
|
||||
ax2.set_xlabel('Frequency (kHz)')
|
||||
ax2.set_ylabel('Time (s)')
|
||||
|
||||
im = ax2.imshow(data5, vmin=-110.0, vmax=-50.0, extent=limits, animated=True)
|
||||
ax2.set_aspect('auto')
|
||||
fig.colorbar(im, orientation='vertical')
|
||||
|
||||
count = 0
|
||||
|
||||
def animate_im(i):
|
||||
line = f.readline()
|
||||
if line:
|
||||
row = np.fromstring(line, dtype=float, sep=',')
|
||||
data = row[5:]
|
||||
|
||||
global count
|
||||
count += 1
|
||||
global data5
|
||||
data5 = np.roll(data5, 1, axis=0)
|
||||
for x in range(2, l-2):
|
||||
data5[0,x] = (data[x-2]+data[x-1]+data[x]+data[x+1]+data[x+2])/5.0
|
||||
|
||||
im.set_data(data5)
|
||||
|
||||
# update vmin/vmax
|
||||
if (count % win == 0):
|
||||
min_db = np.min(data5)
|
||||
max_db = np.max(data5)
|
||||
im.set_clim(vmin=min_db, vmax=max_db)
|
||||
return [im]
|
||||
|
||||
ani = animation.FuncAnimation(fig, animate_im, interval=10, blit=True)
|
||||
|
||||
################################################################################################
|
||||
|
||||
else:
|
||||
fig = plt.figure(figsize=(12, 8))
|
||||
ax1 = fig.add_subplot(211)
|
||||
ax1.set_xlim([fq[0], fq[-1]])
|
||||
ax1.set_ylim([-110.0, -30.0])
|
||||
ax2 = fig.add_subplot(212)
|
||||
ax2.set_xlabel('Frequency (kHz)')
|
||||
ax2.set_ylabel('Time (s)')
|
||||
|
||||
lp, = ax1.plot( fq, data5[0,:], color='g', linewidth=0.4)
|
||||
im = ax2.imshow(data5, vmin=-110.0, vmax=-50.0, extent=limits, animated=True)
|
||||
|
||||
ax2.set_aspect('auto')
|
||||
|
||||
count = 0
|
||||
|
||||
def animate(i):
|
||||
line = f.readline()
|
||||
if line:
|
||||
row = np.fromstring(line, dtype=float, sep=',')
|
||||
data = row[5:]
|
||||
|
||||
global count
|
||||
count += 1
|
||||
global data5
|
||||
data5 = np.roll(data5, 1, axis=0)
|
||||
for x in range(2, l-2):
|
||||
data5[0,x] = (data[x-2]+data[x-1]+data[x]+data[x+1]+data[x+2])/5.0
|
||||
|
||||
im.set_data(data5)
|
||||
lp.set_data(fq, data5[0,:])
|
||||
|
||||
# update vmin/vmax
|
||||
if (count % win == 0):
|
||||
min_db = np.min(data5)
|
||||
max_db = np.max(data5)
|
||||
im.set_clim(vmin=min_db, vmax=max_db)
|
||||
return [lp,im]
|
||||
|
||||
ani = animation.FuncAnimation(fig, animate, interval=10, blit=True)
|
||||
|
||||
################################################################################################
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.ticker as ticker
|
||||
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("usage:")
|
||||
print("\tpython %s <wfft_file>" % sys.argv[0])
|
||||
sys.exit()
|
||||
|
||||
fft_file = sys.argv[1]
|
||||
|
||||
if not os.path.isfile(fft_file):
|
||||
print("error: %s not found" % fft_file)
|
||||
sys.exit()
|
||||
|
||||
|
||||
raw_data = np.genfromtxt( fft_file, delimiter=',')
|
||||
data = raw_data[:,5:]
|
||||
|
||||
dim = np.shape(data)
|
||||
m = np.mean(data)
|
||||
data5 = np.full(dim, m)
|
||||
for y in range(dim[0]):
|
||||
for x in range(2, dim[1]-2):
|
||||
data5[y,x] = (data[y,x-2]+data[y,x-1]+data[y,x]+data[y,x+1]+data[y,x+2])/5.0
|
||||
|
||||
freq_min = raw_data[0,1] / 1e3
|
||||
freq_max = raw_data[0,2] / 1e3
|
||||
N = raw_data[0,4]
|
||||
tmin = raw_data[dim[0]-1,0]
|
||||
tmax = raw_data[0,0]
|
||||
limits = [freq_min, freq_max, tmin, tmax]
|
||||
|
||||
|
||||
fig = plt.figure(figsize=(15, 5))
|
||||
ax = fig.add_subplot(111)
|
||||
ax.set_title('Waterfall')
|
||||
ax.set_xlabel('Frequency (kHz)')
|
||||
ax.set_ylabel('Time (s)')
|
||||
|
||||
plt.imshow(data5, extent=limits)
|
||||
|
||||
ax.set_aspect('auto')
|
||||
plt.colorbar(orientation='vertical')
|
||||
plt.show()
|
||||
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
if (argv[1] == NULL) {
|
||||
fprintf(stderr, "usage:\n");
|
||||
fprintf(stderr, "\t%s <fft_file>\n", argv[0]);
|
||||
fprintf(stderr, "\t%s <fft_avg.csv>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
fp = fopen(argv[1], "rb");
|
||||
|
@ -61,9 +61,34 @@ int main(int argc, char **argv) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
memset(line, 0, LINELEN+1);
|
||||
|
||||
N = 0;
|
||||
j = 0;
|
||||
n = 0;
|
||||
// sec.ms,freq_min,freq_max,Hz/bin,N_bins, ...
|
||||
while ( (c = fgetc(fp)) != EOF) {
|
||||
if (c == '\n') N++;
|
||||
if (c == '\n') break;
|
||||
if (c == ' ') continue;
|
||||
if (c == ',') {
|
||||
if (n == 1) {
|
||||
int freq_min = atoi(line);
|
||||
sr = -2*freq_min;
|
||||
}
|
||||
if (n == 4) {
|
||||
N = atoi(line);
|
||||
break;
|
||||
}
|
||||
|
||||
n++;
|
||||
memset(line, 0, LINELEN+1);
|
||||
j = 0;
|
||||
}
|
||||
else {
|
||||
line[j] = c;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
db = calloc(N+1, sizeof(float)); if (db == NULL) return 2;
|
||||
|
@ -73,20 +98,30 @@ int main(int argc, char **argv) {
|
|||
intdb = calloc(N+1, sizeof(float)); if (intdb == NULL) return 2;
|
||||
peak = calloc(N+1, sizeof(float)); if (peak == NULL) return 2;
|
||||
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
pbuf = fgets(line, LINELEN, fp);
|
||||
p1 = strstr(line, "sr:");
|
||||
if (p1) sr = atoi(p1+3);
|
||||
for (n = 0; n < N; n++) {
|
||||
memset(line, 0, LINELEN+1);
|
||||
pbuf = fgets(line, LINELEN, fp);
|
||||
p1 = strstr(line, ";"); //p2 = strstr(p1+1, ";");
|
||||
if (p1) {
|
||||
fq[n] = atof(line); //freq[n] = atof(p1+1);
|
||||
db[n] = atof(p1+1); //atof(p2+1);
|
||||
// ..., db_1,...,db_N:
|
||||
memset(line, 0, LINELEN+1);
|
||||
j = 0;
|
||||
n = 0;
|
||||
while ( (c = fgetc(fp)) != EOF) {
|
||||
if (c == '\n') break;
|
||||
if (c == ' ') continue;
|
||||
if (c == ',') {
|
||||
if (n < N) {
|
||||
db[n] = atof(line);
|
||||
fq[n] = -0.5 + n/(float)N;
|
||||
}
|
||||
|
||||
n++;
|
||||
memset(line, 0, LINELEN+1);
|
||||
j = 0;
|
||||
}
|
||||
else {
|
||||
line[j] = c;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
f0 = N/2;
|
||||
|
||||
globmin = 0.0;
|
||||
|
@ -94,14 +129,12 @@ int main(int argc, char **argv) {
|
|||
float db_spike3 = 10.0;
|
||||
int spike_wl3 = 3; //freq2bin(&DFT, 200); // 3 // 200 Hz
|
||||
int spike_wl5 = 5; //freq2bin(&DFT, 200); // 3 // 200 Hz
|
||||
//float db_spike1 = 15.0;
|
||||
//int spike_wl1 = 1; //freq2bin(&DFT, 200); // 3 // 200 Hz
|
||||
|
||||
|
||||
dx = 200.0;
|
||||
if (sr) dx = sr*(fq[f0+1]-fq[f0]); //freq[f0+1]-freq[f0];
|
||||
dn = 2*(int)(2400.0/dx)+1; // (odd/symmetric) integration width: 4800+dx Hz
|
||||
if (option_verbose > 1) fprintf(stderr, "dn = %d\n", dn);
|
||||
//for (j = 0; j < N; j++) db[j] /= (float)n;
|
||||
|
||||
// dc-spike (N-1,)N,0,1(,2): subtract mean/avg
|
||||
// spikes in general:
|
||||
|
|
Ładowanie…
Reference in New Issue