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., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <asm/types.h>
29 #include <sys/ioctl.h>
30 #include <linux/videodev.h>
34 printf("usage: %s [-h] [-o] [-q] [-d <dev>] [-t <tuner>] <freq>|on|off [<volume>]\n", prog
);
36 printf(" -h display this help\n");
37 printf(" -o override frequency range limits of card\n");
38 printf(" -q quiet mode\n");
39 printf(" -d <dev> select device (default: /dev/radio0)\n");
40 printf(" -t <tuner> select tuner (default: 0)\n");
41 printf(" <freq> frequency in MHz (i.e. 94.3)\n");
42 printf(" on turn radio on\n");
43 printf(" off turn radio off (mute)\n");
44 printf(" + increase volume\n");
45 printf(" - decrease volume\n");
46 printf(" <volume> intensity (0-65535)\n");
50 void getconfig(int *defaultvol
, int *increment
)
53 char buf
[256], fn
[256];
55 sprintf(fn
, "%s/.fmrc", getenv("HOME"));
56 conf
= fopen(fn
, "r");
61 while(fgets(buf
, sizeof(buf
), conf
)) {
62 buf
[strlen(buf
)-1] = 0;
63 if (!strncmp(buf
, "VOL", 3))
64 sscanf(buf
, "%*s %i", defaultvol
);
65 if (!strncmp(buf
, "INCR", 3))
66 sscanf(buf
, "%*s %i", increment
);
72 int main(int argc
, char **argv
)
74 int fd
, ret
, tunevol
, quiet
=0, i
, override
= 0;
75 int defaultvol
= 8192; /* default volume = 12.5% */
76 int increment
= 6554; /* default change = 10% */
79 struct video_audio va
;
80 struct video_tuner vt
;
85 /* need at least a frequency */
87 printf ("usage: %s [-h] [-o] [-q] [-d <dev>] [-t <tuner>] <freq>|on|off [<volume>]\n", argv
[0]);
91 progname
= argv
[0]; /* used after getopt munges argv[] */
93 getconfig(&defaultvol
, &increment
);
95 while ((i
= getopt(argc
, argv
, "+qhot:d:")) != EOF
) {
104 tuner
= atoi(optarg
);
107 dev
= strdup(optarg
);
119 if (argc
== 0) /* no frequency, on|off, or +|- given */
123 tunevol
= atoi(argv
[1]);
125 tunevol
= defaultvol
;
128 dev
= strdup("/dev/radio0"); /* use default */
130 fd
= open(dev
, O_RDONLY
);
132 fprintf(stderr
, "Unable to open %s: %s\n", dev
, strerror(errno
));
136 if (!strcmp("off", argv
[0])) { /* mute the radio */
139 va
.flags
= VIDEO_AUDIO_MUTE
;
140 ret
= ioctl(fd
, VIDIOCSAUDIO
, &va
);
142 perror("ioctl VIDIOCSAUDIO");
147 printf ("Radio muted\n");
151 if (!strcmp("on", argv
[0])) { /* turn radio on */
155 ret
= ioctl(fd
, VIDIOCSAUDIO
, &va
);
157 perror("ioctl VIDIOCSAUDIO");
162 printf("Radio on at %2.2f%% volume\n",
167 ret
= ioctl(fd
, VIDIOCGAUDIO
, &va
);
169 perror("ioctl VIDIOCGAUDIO");
173 if (argv
[0][0] == '+') { /* volume up */
174 if ((va
.volume
+ increment
) > 65535)
175 va
.volume
= 65535; /* catch overflows in __u16 */
177 va
.volume
+= increment
;
180 printf("Setting volume to %2.2f%%\n",
181 (va
.volume
/ 655.35));
183 ret
= ioctl (fd
, VIDIOCSAUDIO
, &va
);
185 perror("ioctl VIDIOCSAUDIO");
192 if (argv
[0][0] == '-') { /* volume down */
193 if ((va
.volume
- increment
) < 0)
194 va
.volume
= 0; /* catch negative numbers */
196 va
.volume
-= increment
;
199 printf("Setting volume to %2.2f%%\n",
200 (va
.volume
/ 655.35));
202 ret
= ioctl (fd
, VIDIOCSAUDIO
, &va
);
204 perror("ioctl VIDIOCSAUDIO");
211 /* at this point, we are trying to tune to a frequency */
214 ret
= ioctl(fd
, VIDIOCSTUNER
, &vt
); /* set tuner # */
216 perror("ioctl VIDIOCSTUNER");
220 ret
= ioctl(fd
, VIDIOCGTUNER
, &vt
); /* get frequency range */
222 perror("ioctl VIDIOCGTUNER");
226 if ((ret
== -1) || ((vt
.flags
& VIDEO_TUNER_LOW
) == 0))
231 freq
= ceil(atof(argv
[0]) * fact
); /* rounding up matters */
233 if ((freq
< vt
.rangelow
) || (freq
> vt
.rangehigh
)) {
235 printf("Frequency %2.1f out of range (%2.1f - %2.1f MHz)\n",
236 (freq
/ fact
), (vt
.rangelow
/ fact
),
237 (vt
.rangehigh
/ fact
));
242 /* frequency sanity checked, proceed */
243 ret
= ioctl(fd
, VIDIOCSFREQ
, &freq
);
245 perror("ioctl VIDIOCSFREQ");
252 va
.mode
= VIDEO_SOUND_STEREO
;
254 ret
= ioctl(fd
, VIDIOCSAUDIO
, &va
); /* set the volume */
256 perror("ioctl VIDIOCSAUDIO");
261 printf ("Radio tuned to %2.1f MHz at %2.2f%% volume\n",
262 (freq
/ fact
), (tunevol
/ 655.35));