45f8e065df7c4ac7ada1c8a1bd4d44c456c8f149
[rtl-433.git] / src / rtl_fm.c
1 /*
2  * rtl-sdr, turns your Realtek RTL2832 based DVB dongle into a SDR receiver
3  * Copyright (C) 2012 by Steve Markgraf <steve@steve-m.de>
4  * Copyright (C) 2012 by Hoernchen <la@tfc-server.de>
5  * Copyright (C) 2012 by Kyle Keen <keenerd@gmail.com>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21
22 /*
23  * written because people could not do real time
24  * FM demod on Atom hardware with GNU radio
25  * based on rtl_sdr.c and rtl_tcp.c
26  * todo: realtime ARMv5
27  *       remove float math (disqualifies complex.h)
28  *       in-place array operations
29  *       sanity checks
30  *       nicer FIR than square
31  *       scale squelch to other input parameters
32  *       test all the demodulations
33  *       pad output on hop
34  *       nearest gain approx
35  *       frequency ranges could be stored better
36  */
37
38 #include <errno.h>
39 #include <signal.h>
40 #include <string.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <math.h>
44
45 #ifndef _WIN32
46 #include <unistd.h>
47 #else
48 #include <Windows.h>
49 #include <fcntl.h>
50 #include <io.h>
51 #include "getopt/getopt.h"
52 #define usleep(x) Sleep(x/1000)
53 #define round(x) (x > 0.0 ? floor(x + 0.5): ceil(x - 0.5))
54 #endif
55
56 #include <semaphore.h>
57 #include <pthread.h>
58 #include <libusb.h>
59
60 #include "rtl-sdr.h"
61
62 #define DEFAULT_SAMPLE_RATE             24000
63 #define DEFAULT_ASYNC_BUF_NUMBER        32
64 #define DEFAULT_BUF_LENGTH              (1 * 16384)
65 #define MAXIMUM_OVERSAMPLE              16
66 #define MAXIMUM_BUF_LENGTH              (MAXIMUM_OVERSAMPLE * DEFAULT_BUF_LENGTH)
67 #define AUTO_GAIN                       -100
68
69 static pthread_t demod_thread;
70 static sem_t data_ready;
71 static int do_exit = 0;
72 static rtlsdr_dev_t *dev = NULL;
73 static int lcm_post[17] = {1,1,1,3,1,5,3,7,1,9,5,11,3,13,7,15,1};
74
75 struct fm_state
76 {
77         int      now_r;
78         int      now_j;
79         int      pre_r;
80         int      pre_j;
81         int      prev_index;
82         int      downsample;    /* min 1, max 256 */
83         int      post_downsample;
84         int      output_scale;
85         int      squelch_level;
86         int      conseq_squelch;
87         int      squelch_hits;
88         int      terminate_on_squelch;
89         int      exit_flag;
90         uint8_t  buf[MAXIMUM_BUF_LENGTH];
91         uint32_t buf_len;
92         int      signal[MAXIMUM_BUF_LENGTH];  /* 16 bit signed i/q pairs */
93         int16_t  signal2[MAXIMUM_BUF_LENGTH]; /* signal has lowpass, signal2 has demod */
94         int      signal_len;
95         int      signal2_len;
96         FILE     *file;
97         int      edge;
98         uint32_t freqs[1000];
99         int      freq_len;
100         int      freq_now;
101         uint32_t sample_rate;
102         int      output_rate;
103         int      fir_enable;
104         int      fir[256];  /* fir_len == downsample */
105         int      fir_sum;
106         int      custom_atan;
107         int      deemph;
108         int      deemph_a;
109         int      now_lpr;
110         int      prev_lpr_index;
111         void     (*mode_demod)(struct fm_state*);
112 };
113
114 void usage(void)
115 {
116         fprintf(stderr,
117                 "rtl_fm, a simple narrow band FM demodulator for RTL2832 based DVB-T receivers\n\n"
118                 "Use:\trtl_fm -f freq [-options] [filename]\n"
119                 "\t-f frequency_to_tune_to [Hz]\n"
120                 "\t (use multiple -f for scanning, requires squelch)\n"
121                 "\t (ranges supported, -f 118M:137M:25k)\n"
122                 "\t[-s sample_rate (default: 24k)]\n"
123                 "\t[-d device_index (default: 0)]\n"
124                 "\t[-g tuner_gain (default: automatic)]\n"
125                 "\t[-l squelch_level (default: 0/off)]\n"
126                 "\t[-o oversampling (default: 1, 4 recommended)]\n"
127                 "\t[-p ppm_error (default: 0)]\n"
128                 "\t[-E sets lower edge tuning (default: center)]\n"
129                 "\t[-N enables NBFM mode (default: on)]\n"
130                 "\t[-W enables WBFM mode (default: off)]\n"
131                 "\t (-N -s 170k -o 4 -A -r 32k -l 0 -D)\n"
132                 "\tfilename (a '-' dumps samples to stdout)\n"
133                 "\t (omitting the filename also uses stdout)\n\n"
134                 "Experimental options:\n"
135                 "\t[-r output_rate (default: same as -s)]\n"
136                 "\t[-t squelch_delay (default: 20)]\n"
137                 "\t (+values will mute/scan, -values will exit)\n"
138                 "\t[-M enables AM mode (default: off)]\n"
139                 "\t[-L enables LSB mode (default: off)]\n"
140                 "\t[-U enables USB mode (default: off)]\n"
141                 //"\t[-D enables DSB mode (default: off)]\n"
142                 "\t[-R enables raw mode (default: off, 2x16 bit output)]\n"
143                 "\t[-F enables high quality FIR (default: off/square)]\n"
144                 "\t[-D enables de-emphasis (default: off)]\n"
145                 "\t[-A enables high speed arctan (default: off)]\n\n"
146                 "Produces signed 16 bit ints, use Sox or aplay to hear them.\n"
147                 "\trtl_fm ... - | play -t raw -r 24k -e signed-integer -b 16 -c 1 -V1 -\n"
148                 "\t             | aplay -r 24k -f S16_LE -t raw -c 1\n"
149                 "\t  -s 22.5k - | multimon -t raw /dev/stdin\n\n");
150         exit(1);
151 }
152
153 #ifdef _WIN32
154 BOOL WINAPI
155 sighandler(int signum)
156 {
157         if (CTRL_C_EVENT == signum) {
158                 fprintf(stderr, "Signal caught, exiting!\n");
159                 do_exit = 1;
160                 rtlsdr_cancel_async(dev);
161                 return TRUE;
162         }
163         return FALSE;
164 }
165 #else
166 static void sighandler(int signum)
167 {
168         fprintf(stderr, "Signal caught, exiting!\n");
169         do_exit = 1;
170         rtlsdr_cancel_async(dev);
171 }
172 #endif
173
174 void rotate_90(unsigned char *buf, uint32_t len)
175 /* 90 rotation is 1+0j, 0+1j, -1+0j, 0-1j
176    or [0, 1, -3, 2, -4, -5, 7, -6] */
177 {
178         uint32_t i;
179         unsigned char tmp;
180         for (i=0; i<len; i+=8) {
181                 /* uint8_t negation = 255 - x */
182                 tmp = 255 - buf[i+3];
183                 buf[i+3] = buf[i+2];
184                 buf[i+2] = tmp;
185
186                 buf[i+4] = 255 - buf[i+4];
187                 buf[i+5] = 255 - buf[i+5];
188
189                 tmp = 255 - buf[i+6];
190                 buf[i+6] = buf[i+7];
191                 buf[i+7] = tmp;
192         }
193 }
194
195 void low_pass(struct fm_state *fm, unsigned char *buf, uint32_t len)
196 /* simple square window FIR */
197 {
198         int i=0, i2=0;
199         while (i < (int)len) {
200                 fm->now_r += ((int)buf[i]   - 128);
201                 fm->now_j += ((int)buf[i+1] - 128);
202                 i += 2;
203                 fm->prev_index++;
204                 if (fm->prev_index < fm->downsample) {
205                         continue;
206                 }
207                 fm->signal[i2]   = fm->now_r * fm->output_scale;
208                 fm->signal[i2+1] = fm->now_j * fm->output_scale;
209                 fm->prev_index = 0;
210                 fm->now_r = 0;
211                 fm->now_j = 0;
212                 i2 += 2;
213         }
214         fm->signal_len = i2;
215 }
216
217 void build_fir(struct fm_state *fm)
218 /* for now, a simple triangle 
219  * fancy FIRs are equally expensive, so use one */
220 /* point = sum(sample[i] * fir[i] * fir_len / fir_sum) */
221 {
222         int i, len;
223         len = fm->downsample;
224         for(i = 0; i < (len/2); i++) {
225                 fm->fir[i] = i;
226         }
227         for(i = len-1; i >= (len/2); i--) {
228                 fm->fir[i] = len - i;
229         }
230         fm->fir_sum = 0;
231         for(i = 0; i < len; i++) {
232                 fm->fir_sum += fm->fir[i];
233         }
234 }
235
236 void low_pass_fir(struct fm_state *fm, unsigned char *buf, uint32_t len)
237 /* perform an arbitrary FIR, doubles CPU use */
238 // possibly bugged, or overflowing
239 {
240         int i=0, i2=0, i3=0;
241         while (i < (int)len) {
242                 i3 = fm->prev_index;
243                 fm->now_r += ((int)buf[i]   - 128) * fm->fir[i3] * fm->downsample / fm->fir_sum;
244                 fm->now_j += ((int)buf[i+1] - 128) * fm->fir[i3] * fm->downsample / fm->fir_sum;
245                 i += 2;
246                 fm->prev_index++;
247                 if (fm->prev_index < fm->downsample) {
248                         continue;
249                 }
250                 fm->signal[i2]   = fm->now_r * fm->output_scale;
251                 fm->signal[i2+1] = fm->now_j * fm->output_scale;
252                 fm->prev_index = 0;
253                 fm->now_r = 0;
254                 fm->now_j = 0;
255                 i2 += 2;
256         }
257         fm->signal_len = i2;
258 }
259
260 int low_pass_simple(int16_t *signal2, int len, int step)
261 // no wrap around, length must be multiple of step
262 {
263         int i, i2, sum;
264         for(i=0; i < len; i+=step) {
265                 sum = 0;
266                 for(i2=0; i2<step; i2++) {
267                         sum += (int)signal2[i + i2];
268                 }
269                 //signal2[i/step] = (int16_t)(sum / step);
270                 signal2[i/step] = (int16_t)(sum);
271         }
272         signal2[i/step + 1] = signal2[i/step];
273         return len / step;
274 }
275
276 void low_pass_real(struct fm_state *fm)
277 /* simple square window FIR */
278 // add support for upsampling?
279 {
280         int i=0, i2=0;
281         int fast = (int)fm->sample_rate / fm->post_downsample;
282         int slow = fm->output_rate;
283         while (i < fm->signal2_len) {
284                 fm->now_lpr += fm->signal2[i];
285                 i++;
286                 fm->prev_lpr_index += slow;
287                 if (fm->prev_lpr_index < fast) {
288                         continue;
289                 }
290                 fm->signal2[i2] = (int16_t)(fm->now_lpr / (fast/slow));
291                 fm->prev_lpr_index -= fast;
292                 fm->now_lpr = 0;
293                 i2 += 1;
294         }
295         fm->signal2_len = i2;
296 }
297
298 /* define our own complex math ops
299    because ARMv5 has no hardware float */
300
301 void multiply(int ar, int aj, int br, int bj, int *cr, int *cj)
302 {
303         *cr = ar*br - aj*bj;
304         *cj = aj*br + ar*bj;
305 }
306
307 int polar_discriminant(int ar, int aj, int br, int bj)
308 {
309         int cr, cj;
310         double angle;
311         multiply(ar, aj, br, -bj, &cr, &cj);
312         angle = atan2((double)cj, (double)cr);
313         return (int)(angle / 3.14159 * (1<<14));
314 }
315
316 int fast_atan2(int y, int x)
317 /* pre scaled for int16 */
318 {
319         int yabs, angle;
320         int pi4=(1<<12), pi34=3*(1<<12);  // note pi = 1<<14
321         if (x==0 && y==0) {
322                 return 0;
323         }
324         yabs = y;
325         if (yabs < 0) {
326                 yabs = -yabs;
327         }
328         if (x >= 0) {
329                 angle = pi4  - pi4 * (x-yabs) / (x+yabs);
330         } else {
331                 angle = pi34 - pi4 * (x+yabs) / (yabs-x);
332         }
333         if (y < 0) {
334                 return -angle;
335         }
336         return angle;
337 }
338
339 int polar_disc_fast(int ar, int aj, int br, int bj)
340 {
341         int cr, cj;
342         multiply(ar, aj, br, -bj, &cr, &cj);
343         return fast_atan2(cj, cr);
344 }
345
346 void fm_demod(struct fm_state *fm)
347 {
348         int i, pcm;
349         pcm = polar_discriminant(fm->signal[0], fm->signal[1],
350                 fm->pre_r, fm->pre_j);
351         fm->signal2[0] = (int16_t)pcm;
352         for (i = 2; i < (fm->signal_len); i += 2) {
353                 if (fm->custom_atan) {
354                         pcm = polar_disc_fast(fm->signal[i], fm->signal[i+1],
355                                 fm->signal[i-2], fm->signal[i-1]);
356                 } else {
357                         pcm = polar_discriminant(fm->signal[i], fm->signal[i+1],
358                                 fm->signal[i-2], fm->signal[i-1]);
359                 }
360                 fm->signal2[i/2] = (int16_t)pcm;
361         }
362         fm->pre_r = fm->signal[fm->signal_len - 2];
363         fm->pre_j = fm->signal[fm->signal_len - 1];
364         fm->signal2_len = fm->signal_len/2;
365 }
366
367 void am_demod(struct fm_state *fm)
368 // todo, fix this extreme laziness
369 {
370         int i, pcm;
371         for (i = 0; i < (fm->signal_len); i += 2) {
372                 // hypot uses floats but won't overflow
373                 //fm->signal2[i/2] = (int16_t)hypot(fm->signal[i], fm->signal[i+1]);
374                 pcm = fm->signal[i] * fm->signal[i];
375                 pcm += fm->signal[i+1] * fm->signal[i+1];
376                 fm->signal2[i/2] = (int16_t)sqrt(pcm); // * fm->output_scale;
377         }
378         fm->signal2_len = fm->signal_len/2;
379         // lowpass? (3khz)  highpass?  (dc)
380 }
381
382 void usb_demod(struct fm_state *fm)
383 {
384         int i, pcm;
385         for (i = 0; i < (fm->signal_len); i += 2) {
386                 pcm = fm->signal[i] + fm->signal[i+1];
387                 fm->signal2[i/2] = (int16_t)pcm; // * fm->output_scale;
388         }
389         fm->signal2_len = fm->signal_len/2;
390 }
391
392 void lsb_demod(struct fm_state *fm)
393 {
394         int i, pcm;
395         for (i = 0; i < (fm->signal_len); i += 2) {
396                 pcm = fm->signal[i] - fm->signal[i+1];
397                 fm->signal2[i/2] = (int16_t)pcm; // * fm->output_scale;
398         }
399         fm->signal2_len = fm->signal_len/2;
400 }
401
402 void raw_demod(struct fm_state *fm)
403 {
404         /* hacky and pointless code */
405         int i;
406         for (i = 0; i < (fm->signal_len); i++) {
407                 fm->signal2[i] = (int16_t)fm->signal[i];
408         }
409         fm->signal2_len = fm->signal_len;
410 }
411
412 void deemph_filter(struct fm_state *fm)
413 {
414         static int avg;  // cheating...
415         int i, d;
416         // de-emph IIR
417         // avg = avg * (1 - alpha) + sample * alpha;
418         for (i = 0; i < fm->signal2_len; i++) {
419                 d = fm->signal2[i] - avg;
420                 if (d > 0) {
421                         avg += (d + fm->deemph_a/2) / fm->deemph_a;
422                 } else {
423                         avg += (d - fm->deemph_a/2) / fm->deemph_a;
424                 }
425                 fm->signal2[i] = (int16_t)avg;
426         }
427 }
428
429 int mad(int *samples, int len, int step)
430 /* mean average deviation */
431 {
432         int i=0, sum=0, ave=0;
433         if (len == 0)
434                 {return 0;}
435         for (i=0; i<len; i+=step) {
436                 sum += samples[i];
437         }
438         ave = sum / (len * step);
439         sum = 0;
440         for (i=0; i<len; i+=step) {
441                 sum += abs(samples[i] - ave);
442         }
443         return sum / (len / step);
444 }
445
446 int post_squelch(struct fm_state *fm)
447 /* returns 1 for active signal, 0 for no signal */
448 {
449         int dev_r, dev_j, len, sq_l;
450         /* only for small samples, big samples need chunk processing */
451         len = fm->signal_len;
452         sq_l = fm->squelch_level;
453         dev_r = mad(&(fm->signal[0]), len, 2);
454         dev_j = mad(&(fm->signal[1]), len, 2);
455         if ((dev_r > sq_l) || (dev_j > sq_l)) {
456                 fm->squelch_hits = 0;
457                 return 1;
458         }
459         fm->squelch_hits++;
460         return 0;
461 }
462
463 static void optimal_settings(struct fm_state *fm, int freq, int hopping)
464 {
465         int r, capture_freq, capture_rate;
466         fm->downsample = (1000000 / fm->sample_rate) + 1;
467         fm->freq_now = freq;
468         capture_rate = fm->downsample * fm->sample_rate;
469         capture_freq = fm->freqs[freq] + capture_rate/4;
470         capture_freq += fm->edge * fm->sample_rate / 2;
471         fm->output_scale = (1<<15) / (128 * fm->downsample);
472         if (fm->output_scale < 1) {
473                 fm->output_scale = 1;}
474         fm->output_scale = 1;
475         /* Set the frequency */
476         r = rtlsdr_set_center_freq(dev, (uint32_t)capture_freq);
477         if (hopping) {
478                 return;}
479         fprintf(stderr, "Oversampling input by: %ix.\n", fm->downsample);
480         fprintf(stderr, "Oversampling output by: %ix.\n", fm->post_downsample);
481         fprintf(stderr, "Buffer size: %0.2fms\n",
482                 1000 * 0.5 * lcm_post[fm->post_downsample] * (float)DEFAULT_BUF_LENGTH / (float)capture_rate);
483         if (r < 0) {
484                 fprintf(stderr, "WARNING: Failed to set center freq.\n");}
485         else {
486                 fprintf(stderr, "Tuned to %u Hz.\n", capture_freq);}
487
488         /* Set the sample rate */
489         fprintf(stderr, "Sampling at %u Hz.\n", capture_rate);
490         if (fm->output_rate > 0) {
491                 fprintf(stderr, "Output at %u Hz.\n", fm->output_rate);
492         } else {
493                 fprintf(stderr, "Output at %u Hz.\n", fm->sample_rate/fm->post_downsample);}
494         r = rtlsdr_set_sample_rate(dev, (uint32_t)capture_rate);
495         if (r < 0) {
496                 fprintf(stderr, "WARNING: Failed to set sample rate.\n");}
497
498 }
499
500 void full_demod(struct fm_state *fm)
501 {
502         int i, sr, freq_next, hop = 0;
503         rotate_90(fm->buf, fm->buf_len);
504         if (fm->fir_enable) {
505                 low_pass_fir(fm, fm->buf, fm->buf_len);
506         } else {
507                 low_pass(fm, fm->buf, fm->buf_len);
508         }
509         fm->mode_demod(fm);
510         if (fm->mode_demod == &raw_demod) {
511                 fwrite(fm->signal2, 2, fm->signal2_len, fm->file);
512                 return;
513         }
514         sr = post_squelch(fm);
515         if (!sr && fm->squelch_hits > fm->conseq_squelch) {
516                 if (fm->terminate_on_squelch) {
517                         fm->exit_flag = 1;}
518                 if (fm->freq_len == 1) {  /* mute */
519                         for (i=0; i<fm->signal_len; i++) {
520                                 fm->signal2[i] = 0;}
521                 }
522                 else {
523                         hop = 1;}
524         }
525         if (fm->post_downsample > 1) {
526                 fm->signal2_len = low_pass_simple(fm->signal2, fm->signal2_len, fm->post_downsample);}
527         if (fm->output_rate > 0) {
528                 low_pass_real(fm);
529         }
530         if (fm->deemph) {
531                 deemph_filter(fm);}
532         /* ignore under runs for now */
533         fwrite(fm->signal2, 2, fm->signal2_len, fm->file);
534         if (hop) {
535                 freq_next = (fm->freq_now + 1) % fm->freq_len;
536                 optimal_settings(fm, freq_next, 1);
537                 fm->squelch_hits = fm->conseq_squelch + 1;  /* hair trigger */
538                 /* wait for settling and flush buffer */
539                 usleep(5000);
540                 rtlsdr_read_sync(dev, NULL, 4096, NULL);
541         }
542 }
543
544 static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
545 {
546         struct fm_state *fm2 = ctx;
547         int dr_val;
548         if (do_exit) {
549                 return;}
550         if (!ctx) {
551                 return;}
552         memcpy(fm2->buf, buf, len);
553         fm2->buf_len = len;
554         /* single threaded uses 25% less CPU? */
555         /* full_demod(fm2); */
556         sem_getvalue(&data_ready, &dr_val);
557         if (dr_val <= 0) {
558                 sem_post(&data_ready);}
559 }
560
561 static void *demod_thread_fn(void *arg)
562 {
563         struct fm_state *fm2 = arg;
564         while (!do_exit) {
565                 sem_wait(&data_ready);
566                 full_demod(fm2);
567                 if (fm2->exit_flag) {
568                         do_exit = 1;
569                         rtlsdr_cancel_async(dev);}
570         }
571         return 0;
572 }
573
574 double atofs(char* f)
575 /* standard suffixes */
576 {
577         char* chop;
578         double suff = 1.0;
579         chop = malloc((strlen(f)+1)*sizeof(char));
580         strncpy(chop, f, strlen(f)-1);
581         switch (f[strlen(f)-1]) {
582                 case 'G':
583                         suff *= 1e3;
584                 case 'M':
585                         suff *= 1e3;
586                 case 'k':
587                         suff *= 1e3;
588                         suff *= atof(chop);}
589         free(chop);
590         if (suff != 1.0) {
591                 return suff;}
592         return atof(f);
593 }
594
595 void frequency_range(struct fm_state *fm, char *arg)
596 {
597         char *start, *stop, *step;
598         int i;
599         start = arg;
600         stop = strchr(start, ':') + 1;
601         stop[-1] = '\0';
602         step = strchr(stop, ':') + 1;
603         step[-1] = '\0';
604         for(i=(int)atofs(start); i<=(int)atofs(stop); i+=(int)atofs(step))
605         {
606                 fm->freqs[fm->freq_len] = (uint32_t)i;
607                 fm->freq_len++;
608         }
609         stop[-1] = ':';
610         step[-1] = ':';
611 }
612
613 int main(int argc, char **argv)
614 {
615 #ifndef _WIN32
616         struct sigaction sigact;
617 #endif
618         struct fm_state fm; 
619         char *filename = NULL;
620         int n_read, r, opt, wb_mode = 0;
621         int i, gain = AUTO_GAIN; // tenths of a dB
622         uint8_t *buffer;
623         uint32_t dev_index = 0;
624         int device_count;
625         int ppm_error = 0;
626         char vendor[256], product[256], serial[256];
627         fm.freqs[0] = 100000000;
628         fm.sample_rate = DEFAULT_SAMPLE_RATE;
629         fm.squelch_level = 0;
630         fm.conseq_squelch = 20;
631         fm.terminate_on_squelch = 0;
632         fm.freq_len = 0;
633         fm.edge = 0;
634         fm.fir_enable = 0;
635         fm.prev_index = 0;
636         fm.post_downsample = 1;  // once this works, default = 4
637         fm.custom_atan = 0;
638         fm.deemph = 0;
639         fm.output_rate = -1;  // flag for disabled
640         fm.mode_demod = &fm_demod;
641         sem_init(&data_ready, 0, 0);
642
643         while ((opt = getopt(argc, argv, "d:f:g:s:b:l:o:t:r:p:EFANWMULRD")) != -1) {
644                 switch (opt) {
645                 case 'd':
646                         dev_index = atoi(optarg);
647                         break;
648                 case 'f':
649                         if (strchr(optarg, ':'))
650                                 {frequency_range(&fm, optarg);}
651                         else
652                         {
653                                 fm.freqs[fm.freq_len] = (uint32_t)atofs(optarg);
654                                 fm.freq_len++;
655                         }
656                         break;
657                 case 'g':
658                         gain = (int)(atof(optarg) * 10);
659                         break;
660                 case 'l':
661                         fm.squelch_level = (int)atof(optarg);
662                         break;
663                 case 's':
664                         fm.sample_rate = (uint32_t)atofs(optarg);
665                         break;
666                 case 'r':
667                         fm.output_rate = (int)atofs(optarg);
668                         break;
669                 case 'o':
670                         fm.post_downsample = (int)atof(optarg);
671                         if (fm.post_downsample < 1 || fm.post_downsample > MAXIMUM_OVERSAMPLE) {
672                                 fprintf(stderr, "Oversample must be between 1 and %i\n", MAXIMUM_OVERSAMPLE);}
673                         break;
674                 case 't':
675                         fm.conseq_squelch = (int)atof(optarg);
676                         if (fm.conseq_squelch < 0) {
677                                 fm.conseq_squelch = -fm.conseq_squelch;
678                                 fm.terminate_on_squelch = 1;
679                         }
680                         break;
681                 case 'p':
682                         ppm_error = atoi(optarg);
683                         break;
684                 case 'E':
685                         fm.edge = 1;
686                         break;
687                 case 'F':
688                         fm.fir_enable = 1;
689                         break;
690                 case 'A':
691                         fm.custom_atan = 1;
692                         break;
693                 case 'D':
694                         fm.deemph = 1;
695                         break;
696                 case 'N':
697                         fm.mode_demod = &fm_demod;
698                         break;
699                 case 'W':
700                         wb_mode = 1;
701                         fm.mode_demod = &fm_demod;
702                         fm.sample_rate = 170000;
703                         fm.output_rate = 32000;
704                         fm.custom_atan = 1;
705                         fm.post_downsample = 4;
706                         fm.deemph = 1;
707                         fm.squelch_level = 0;
708                         break;
709                 case 'M':
710                         fm.mode_demod = &am_demod;
711                         break;
712                 case 'U':
713                         fm.mode_demod = &usb_demod;
714                         break;
715                 case 'L':
716                         fm.mode_demod = &lsb_demod;
717                         break;
718                 case 'R':
719                         fm.mode_demod = &raw_demod;
720                         break;
721                 default:
722                         usage();
723                         break;
724                 }
725         }
726         /* quadruple sample_rate to limit to Δθ to ±π/2 */
727         fm.sample_rate *= fm.post_downsample;
728
729         if (fm.freq_len > 1) {
730                 fm.terminate_on_squelch = 0;
731         }
732
733         if (argc <= optind) {
734                 //usage();
735                 filename = "-";
736         } else {
737                 filename = argv[optind];
738         }
739
740         buffer = malloc(lcm_post[fm.post_downsample] * DEFAULT_BUF_LENGTH * sizeof(uint8_t));
741
742         device_count = rtlsdr_get_device_count();
743         if (!device_count) {
744                 fprintf(stderr, "No supported devices found.\n");
745                 exit(1);
746         }
747
748         fprintf(stderr, "Found %d device(s):\n", device_count);
749         for (i = 0; i < device_count; i++) {
750                 rtlsdr_get_device_usb_strings(i, vendor, product, serial);
751                 fprintf(stderr, "  %d:  %s, %s, SN: %s\n", i, vendor, product, serial);
752         }
753         fprintf(stderr, "\n");
754
755         fprintf(stderr, "Using device %d: %s\n",
756                 dev_index, rtlsdr_get_device_name(dev_index));
757
758         r = rtlsdr_open(&dev, dev_index);
759         if (r < 0) {
760                 fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index);
761                 exit(1);
762         }
763 #ifndef _WIN32
764         sigact.sa_handler = sighandler;
765         sigemptyset(&sigact.sa_mask);
766         sigact.sa_flags = 0;
767         sigaction(SIGINT, &sigact, NULL);
768         sigaction(SIGTERM, &sigact, NULL);
769         sigaction(SIGQUIT, &sigact, NULL);
770         sigaction(SIGPIPE, &sigact, NULL);
771 #else
772         SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE );
773 #endif
774
775         /* WBFM is special */
776         if (wb_mode) {
777                 fm.freqs[0] += 16000;
778         }
779
780         if (fm.deemph) {
781                 fm.deemph_a = (int)round(1.0/((1.0-exp(-1.0/(fm.output_rate * 75e-6)))));
782         }
783
784         optimal_settings(&fm, 0, 0);
785         build_fir(&fm);
786
787         /* Set the tuner gain */
788         if (gain == AUTO_GAIN) {
789                 r = rtlsdr_set_tuner_gain_mode(dev, 0);
790         } else {
791                 r = rtlsdr_set_tuner_gain_mode(dev, 1);
792                 r = rtlsdr_set_tuner_gain(dev, gain);
793         }
794         if (r != 0) {
795                 fprintf(stderr, "WARNING: Failed to set tuner gain.\n");
796         } else if (gain == AUTO_GAIN) {
797                 fprintf(stderr, "Tuner gain set to automatic.\n");
798         } else {
799                 fprintf(stderr, "Tuner gain set to %0.2f dB.\n", gain/10.0);
800         }
801         r = rtlsdr_set_freq_correction(dev, ppm_error);
802
803         if (strcmp(filename, "-") == 0) { /* Write samples to stdout */
804                 fm.file = stdout;
805 #ifdef _WIN32
806                 _setmode(_fileno(fm.file), _O_BINARY);
807 #endif
808         } else {
809                 fm.file = fopen(filename, "wb");
810                 if (!fm.file) {
811                         fprintf(stderr, "Failed to open %s\n", filename);
812                         exit(1);
813                 }
814         }
815
816         /* Reset endpoint before we start reading from it (mandatory) */
817         r = rtlsdr_reset_buffer(dev);
818         if (r < 0) {
819                 fprintf(stderr, "WARNING: Failed to reset buffers.\n");}
820
821         pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(&fm));
822         rtlsdr_read_async(dev, rtlsdr_callback, (void *)(&fm),
823                               DEFAULT_ASYNC_BUF_NUMBER,
824                               lcm_post[fm.post_downsample] * DEFAULT_BUF_LENGTH);
825
826         if (do_exit) {
827                 fprintf(stderr, "\nUser cancel, exiting...\n");}
828         else {
829                 fprintf(stderr, "\nLibrary error %d, exiting...\n", r);}
830         rtlsdr_cancel_async(dev);
831
832         if (fm.file != stdout) {
833                 fclose(fm.file);}
834
835         rtlsdr_close(dev);
836         free (buffer);
837         return r >= 0 ? r : -r;
838 }