Better support radios that do not have volume control.
[fmtools.git] / fmscan.c
blob2b24f0bc032c96921ab1daac194e5e2c766c4f91
1 /* fmscan.c - v4l radio band scanner using signal strength
3 Copyright (C) 2004, 2006, 2009 Ben Pfaff <blp@cs.stanford.edu>
4 Copyright (C) 1999 Russell Kroll <rkroll@exploits.org>
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2 of the License, or (at your option)
9 any later version.
11 This program is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 more details.
16 You should have received a copy of the GNU General Public License along with
17 this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <math.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <fcntl.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <sys/ioctl.h>
29 #include "fmlib.h"
31 #define TRIES 25 /* get 25 samples */
32 #define LOCKTIME 400000 /* wait 400ms for card to lock on */
33 #define SAMPLEDELAY 15000 /* wait 15ms between samples */
35 static void
36 usage(void)
38 printf("fmtools fmscan version %s\n\n", VERSION);
39 printf("usage: %s [-h] [-d <dev>] [-T <tuner>] [-s <freq>] [-e <freq>] [-i <freq>] [-t <%%>]\n\n", program_name);
41 printf("Auxiliary program to scan a frequency band for radio stations.\n\n");
43 printf(" -h - display this help\n");
44 printf(" -d <dev> - select device (default: /dev/radio0)\n");
45 printf(" -T <tuner> - select tuner (default: 0)\n");
46 printf(" -s <freq> - set start of scanning range to <freq>\n");
47 printf(" -e <freq> - set end of scanning range to <freq>\n");
48 printf(" -i <freq> - set increment value between channels to <freq>\n");
49 printf(" -t <%%> - set signal strength percentage to lock onto <%%>\n");
50 printf(" <freq> - a value in the format nnn.nn (MHz)\n");
52 exit(EXIT_SUCCESS);
55 int main(int argc, char **argv)
57 struct tuner tuner;
58 int tries = TRIES;
59 double perc, begval, incval, endval, threshold, mhz;
60 const char *device = NULL;
61 bool override = false;
62 bool quiet = false;
63 int index = 0;
64 int i;
66 program_name = argv[0];
68 /* USA defaults */
69 begval = 87.9; /* start at 87.9 MHz */
70 incval = 0.20; /* increment 0.2 MHz */
71 endval = 107.9; /* stop at 107.9 MHz */
72 threshold = 0.5; /* 50% signal strength */
74 for (;;) {
75 int option = getopt(argc, argv, "+e:hi:s:od:T:t:q");
76 if (option == -1)
77 break;
79 switch (option) {
80 case 'd':
81 device = optarg;
82 break;
83 case 'T':
84 index = atoi(optarg);
85 break;
86 case 'e':
87 endval = atof(optarg);
88 break;
89 case 'i':
90 incval = atof(optarg);
91 break;
92 case 's':
93 begval = atof(optarg);
94 break;
95 case 'o':
96 override = true;
97 break;
98 case 't':
99 threshold = atof(optarg)/100.;
100 break;
101 case 'q':
102 quiet = true;
103 break;
104 case 'h':
105 default:
106 usage();
107 break;
111 tuner_open(&tuner, device, index);
113 if (!override) {
114 double min = tuner_get_min_freq(&tuner) / 16000.0;
115 double max = tuner_get_max_freq(&tuner) / 16000.0;
116 if (begval < min) {
117 begval = min;
118 printf("Setting start to tuner minimum %.1f MHz\n",
119 begval);
121 if (endval > max) {
122 endval = max;
123 printf("Setting end to tuner maximum %.1f MHz\n",
124 endval);
128 printf("Scanning range: %2.1f - %2.1f MHz (%2.1f MHz increments)...\n",
129 begval, endval, incval);
131 for (i = 0; (mhz = begval + i * incval) <= endval; i++) {
132 long long int freq;
133 long int totsig;
134 int i;
136 freq = mhz * 16000 + 0.5;
137 if (!override) {
138 if (freq < tuner_get_min_freq(&tuner))
139 freq = tuner_get_min_freq(&tuner);
140 else if (freq > tuner_get_max_freq(&tuner))
141 freq = tuner_get_max_freq(&tuner);
143 tuner_set_freq(&tuner, freq, override);
145 if (!quiet) {
146 printf("%2.1f:\r", mhz);
147 fflush(stdout);
149 tuner_usleep(&tuner, LOCKTIME);
151 totsig = 0;
152 for (i = 0; i < tries; i++) {
153 totsig += tuner_get_signal(&tuner);
154 perc = totsig / (65535.0 * (i + 1));
155 if (!quiet) {
156 printf("%2.1f: checking: %3.1f%% (%d/%d)"
157 " \r",
158 mhz, perc * 100.0, i + 1, tries);
159 fflush(stdout);
161 tuner_usleep(&tuner, SAMPLEDELAY);
164 /* clean up the display */
165 if (!quiet)
166 printf(" \r");
168 perc = totsig / (65535.0 * tries);
170 if (perc > threshold)
171 printf("%2.1f: %3.1f%%\n",
172 mhz, perc * 100.0);
175 tuner_close(&tuner);
176 return 0;