1 /* fm.c - simple v4l compatible tuner for radio cards
3 Copyright (C) 1998 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <sys/ioctl.h>
33 #define DEFAULT_DEVICE "/dev/radio0"
37 printf("fmtools fm version %s\n\n", FMT_VERSION
);
38 printf("usage: %s [-h] [-o] [-q] [-d <dev>] [-t <tuner>] <freq>|on|off [<volume>]\n\n", prog
);
39 printf("A small controller for Video for Linux radio devices.\n\n");
40 printf(" -h display this help\n");
41 printf(" -o override frequency range limits of card\n");
42 printf(" -q quiet mode\n");
43 printf(" -d <dev> select device (default: /dev/radio0)\n");
44 printf(" -t <tuner> select tuner (default: 0)\n");
45 printf(" <freq> frequency in MHz (i.e. 94.3)\n");
46 printf(" on turn radio on\n");
47 printf(" off turn radio off (mute)\n");
48 printf(" + increase volume\n");
49 printf(" - decrease volume\n");
50 printf(" <volume> intensity (0-65535)\n");
54 void getconfig(int *defaultvol
, int *increment
)
57 char buf
[256], fn
[256];
59 sprintf(fn
, "%s/.fmrc", getenv("HOME"));
60 conf
= fopen(fn
, "r");
65 while(fgets(buf
, sizeof(buf
), conf
)) {
66 buf
[strlen(buf
)-1] = 0;
67 if (!strncmp(buf
, "VOL", 3))
68 sscanf(buf
, "%*s %i", defaultvol
);
69 if (!strncmp(buf
, "INCR", 3))
70 sscanf(buf
, "%*s %i", increment
);
76 int main(int argc
, char **argv
)
78 int fd
, ret
, tunevol
, quiet
=0, i
, override
= 0;
79 int defaultvol
= 8192; /* default volume = 12.5% */
80 int increment
= 6554; /* default change = 10% */
83 struct video_audio va
;
84 struct video_tuner vt
;
89 /* need at least a frequency */
91 printf("usage: %s [-h] [-o] [-q] [-d <dev>] [-t <tuner>] "
92 "<freq>|on|off [<volume>]\n", argv
[0]);
96 progname
= argv
[0]; /* used after getopt munges argv[] */
98 getconfig(&defaultvol
, &increment
);
100 while ((i
= getopt(argc
, argv
, "+qhot:d:")) != EOF
) {
109 tuner
= atoi(optarg
);
112 dev
= strdup(optarg
);
124 if (argc
== 0) /* no frequency, on|off, or +|- given */
128 tunevol
= atoi(argv
[1]);
130 tunevol
= defaultvol
;
133 dev
= DEFAULT_DEVICE
;
135 fd
= open(dev
, O_RDONLY
);
137 fprintf(stderr
, "Unable to open %s: %s\n",
138 dev
, strerror(errno
));
142 ret
= ioctl(fd
, VIDIOCGAUDIO
, &va
);
144 perror("ioctl VIDIOCGAUDIO");
148 /* initialize this so it doesn't pick up random junk data */
151 if (!strcmp("off", argv
[0])) { /* mute the radio */
154 va
.flags
= VIDEO_AUDIO_MUTE
;
155 ret
= ioctl(fd
, VIDIOCSAUDIO
, &va
);
157 perror("ioctl VIDIOCSAUDIO");
162 printf("Radio muted\n");
166 if (!strcmp("on", argv
[0])) { /* turn radio on */
170 ret
= ioctl(fd
, VIDIOCSAUDIO
, &va
);
172 perror("ioctl VIDIOCSAUDIO");
177 printf("Radio on at %2.2f%% volume\n",
182 if (argv
[0][0] == '+') { /* volume up */
183 if ((va
.volume
+ increment
) > 65535)
184 va
.volume
= 65535; /* catch overflows in __u16 */
186 va
.volume
+= increment
;
189 printf("Setting volume to %2.2f%%\n",
190 (va
.volume
/ 655.35));
192 ret
= ioctl(fd
, VIDIOCSAUDIO
, &va
);
194 perror("ioctl VIDIOCSAUDIO");
201 if (argv
[0][0] == '-') { /* volume down */
202 if ((va
.volume
- increment
) < 0)
203 va
.volume
= 0; /* catch negative numbers */
205 va
.volume
-= increment
;
208 printf("Setting volume to %2.2f%%\n",
209 (va
.volume
/ 655.35));
211 ret
= ioctl(fd
, VIDIOCSAUDIO
, &va
);
213 perror("ioctl VIDIOCSAUDIO");
220 /* at this point, we are trying to tune to a frequency */
223 ret
= ioctl(fd
, VIDIOCSTUNER
, &vt
); /* set tuner # */
225 perror("ioctl VIDIOCSTUNER");
229 ret
= ioctl(fd
, VIDIOCGTUNER
, &vt
); /* get frequency range */
231 perror("ioctl VIDIOCGTUNER");
235 if ((ret
== -1) || ((vt
.flags
& VIDEO_TUNER_LOW
) == 0))
240 freq
= rint(atof(argv
[0]) * fact
); /* rounding to nearest int */
242 if ((freq
< vt
.rangelow
) || (freq
> vt
.rangehigh
)) {
244 printf("Frequency %2.1f out of range (%2.1f - %2.1f MHz)\n",
245 (freq
/ fact
), (vt
.rangelow
/ fact
),
246 (vt
.rangehigh
/ fact
));
251 /* frequency sanity checked, proceed */
252 ret
= ioctl(fd
, VIDIOCSFREQ
, &freq
);
254 perror("ioctl VIDIOCSFREQ");
261 va
.mode
= VIDEO_SOUND_STEREO
;
263 ret
= ioctl(fd
, VIDIOCSAUDIO
, &va
); /* set the volume */
265 perror("ioctl VIDIOCSAUDIO");
270 printf("Radio tuned to %2.2f MHz at %2.2f%% volume\n",
271 (freq
/ fact
), (tunevol
/ 655.35));