fmtools 0.99.0.
[fmtools.git] / fmscan.c
blob229e888d475c6da3106df4179d3773701472b550
1 /* scan.c - v4l radio band scanner using signal strength
3 Copyright (C) 1999 Russell Kroll <rkroll@exploits.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 <asm/types.h>
28 #include <sys/ioctl.h>
29 #include <linux/videodev.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 */
34 #define THRESHOLD .5 /* minimum acceptable signal % */
36 void help(char *prog)
38 printf("usage: %s [-h] [-d <dev>] [-s <freq>] [-e <freq>] [-i <freq>]\n\n", prog);
40 printf(" -h - display this help\n");
41 printf(" -d <dev> - select device (default: /dev/radio0)\n");
42 printf(" -s <freq> - set start of scanning range to <freq>\n");
43 printf(" -e <freq> - set end of scanning range to <freq>\n");
44 printf(" -i <freq> - set increment value between channels to <freq>\n");
45 printf(" <freq> - a value in the format nnn.nn (MHz)\n");
47 exit (0);
50 int main(int argc, char **argv)
52 int fd, ret, i, tries = TRIES;
53 struct video_tuner vt;
54 float perc, begval, incval, endval;
55 long lowf, highf, freq, totsig, incr, fact;
56 char *progname, *dev = NULL;
58 progname = argv[0]; /* getopt munges argv[] later */
60 /* USA defaults */
61 begval = 87.9; /* start at 87.9 MHz */
62 incval = 0.20; /* increment 0.2 MHz */
63 endval = 107.9; /* stop at 107.9 MHz */
65 while ((i = getopt(argc, argv, "+e:hi:s:d:")) != EOF) {
66 switch (i) {
67 case 'd':
68 dev = strdup(optarg);
69 break;
70 case 'e':
71 endval = atof(optarg);
72 break;
73 case 'i':
74 incval = atof(optarg);
75 break;
76 case 's':
77 begval = atof(optarg);
78 break;
79 case 'h':
80 default:
81 help(progname);
82 break;
86 if (!dev)
87 dev = strdup("/dev/radio0"); /* default */
89 fd = open(dev, O_RDONLY);
90 if (fd < 0) {
91 fprintf(stderr, "Unable to open %s: %s\n", dev, strerror(errno));
92 exit(1);
95 vt.tuner = 0;
96 ret = ioctl(fd, VIDIOCGTUNER, &vt); /* get initial info */
97 if (ret < 0) {
98 perror("ioctl VIDIOCGTUNER");
99 exit(1);
102 if ((vt.flags & VIDEO_TUNER_LOW) == 0)
103 fact = 16;
104 else
105 fact = 16000;
107 /* cope with bizarre things from atof() like 95.099998 */
108 lowf = fact * (ceil(rint(begval * 10)) / 10);
109 highf = fact * (ceil(rint(endval * 10)) / 10);
111 incr = fact * incval;
113 printf("Scanning range: %2.1f - %2.1f MHz (%2.1f MHz increments)...\n",
114 begval, endval, incval);
116 for (freq = lowf; freq <= highf; freq += incr) {
117 ret = ioctl(fd, VIDIOCSFREQ, &freq); /* tune */
119 if (ret < 0) {
120 perror("ioctl VIDIOCSFREQ");
121 exit(1);
124 printf("%2.1f:\r", (freq / (double) fact));
125 fflush(stdout);
126 usleep(LOCKTIME); /* let it lock on */
128 totsig = 0;
129 for (i = 1; i < tries+1; i++) {
130 vt.tuner = 0;
131 ret = ioctl(fd, VIDIOCGTUNER, &vt); /* get info */
132 if (ret < 0) {
133 perror("ioctl VIDIOCGTUNER");
134 exit(1);
137 totsig += vt.signal;
138 perc = (totsig / (65535.0 * i));
140 printf("%2.1f: checking: %3.1f%% (%d/%d) \r",
141 (freq / (double) fact), perc * 100.0, i, tries);
142 fflush(stdout);
143 usleep(SAMPLEDELAY);
146 /* clean up the display */
147 printf(" \r");
149 perc = (totsig / (65535.0 * tries));
151 if (perc > THRESHOLD)
152 printf("%2.1f: %3.1f%% \n",
153 (freq / (double) fact), perc * 100.0);
156 close (fd);
157 return 0;