1 /*
2  *
3  *  TUNERADIO
4  *
5  *  Opens the the tuner device (ie. /dev/tuner) sets the frequency,
6  *  stereo/mono and AFC modes.  It then sits in a while loop to
7  *  keep the device open.
8  *
9  *  I needed this program to run on remote computers that stream
10  *  MP3 streams out to the net of radio stations.  This program
11  *  assumes the Brooktree 848 card and interface for *BSD.
12  *
13  *  Thanks to Jason Andresen for the patches to compile this on
14  *  FreeBSD 5.1 and cleaning up my code. :-)
15  *
16  *  Copyright (C) 2000-2003 Timothy Pozar pozar@lns.com
17  *
18  *  This program is free software; you can redistribute it and/or
19  *  modify it under the terms of the GNU General Public License
20  *  as published by the Free Software Foundation; either version 2
21  *  of the License, or (at your option) any later version.
22  *
23  *  This program is distributed in the hope that it will be useful,
24  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
25  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  *  GNU General Public License for more details.
27  *
28  *  You should have received a copy of the GNU General Public License
29  *  along with this program; if not, write to the Free Software
30  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
31  *
32  *  $Id: tuneradio.c,v 1.3 2003/10/31 05:53:37 pozar Exp $
33  *
34  */
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <fcntl.h>
39 #include <string.h>
40 #include <signal.h>
41 #include <unistd.h>
42 #include <sys/ioctl.h>
43 #include <sys/types.h>
44 #include <sys/param.h>
45 #if __FreeBSD_version >= 502100
46 #include <dev/bktr/ioctl_bt848.h>
47 #else
48 #include <machine/ioctl_bt848.h>
49 #endif
50 
51 #define TRUE 1
52 #define FALSE 0
53 #define BUF_SIZE 4096
54 
55 char device[BUF_SIZE] = "/dev/tuner";
56 int mono = FALSE;
57 int afc = FALSE;
58 int frequency = 8850;	/* 8850 = 88.5Mhz */
59 int devfh;
60 int setaudio;
61 static void cleanup (int);
62 static void cleanvoid (void);
63 static void cntlc_handler (int);
64 void banner(void);
65 
main(argc,argv)66 int main(argc,argv)
67 int argc;
68 char *argv[];
69 {
70 int gotmask, setmask, i;
71 
72    /* scan command line arguments, and look for files to work on. */
73    for (i = 1; i < argc; i++) {
74       switch (argv[i][1]){   /* be case indepenent... */
75          case 'A':   /* Run with AFC... */
76          case 'a':
77             afc = TRUE;
78             break;
79          case 'D':   /* dsp file name... */
80          case 'd':
81             i++;
82             strncpy(device,argv[i],BUF_SIZE);
83             break;
84          case 'F':   /* Frequency in 10 KHz... */
85          case 'f':
86             i++;
87             frequency = atoi(argv[i]);
88             if((frequency < 8800) || (frequency > 10800)){
89                printf("Frequency %i is out of range of 8800 to 10800\n",frequency);
90                exit(1);
91             }
92             break;
93          case 'H':   /* Help... */
94          case 'h':
95             banner();
96             exit(0);
97          case 'M':   /* Run in mono... */
98          case 'm':
99             mono = TRUE;
100             break;
101          default:
102             printf("I don't know the meaning of the command line argument: \"%s\".\n",argv[i]);
103             banner();
104             exit(1);
105       }
106    }
107 
108    if (atexit (cleanvoid) == -1)
109       perror ("atexit");
110 
111    if (signal (SIGINT, cntlc_handler) == SIG_ERR) {
112       perror ("Signal INT...");
113       exit (1);
114    }
115    if (signal (SIGHUP, cntlc_handler) == SIG_ERR) {
116       perror ("Signal HUP...");
117       exit (1);
118    }
119 
120    if((devfh = open(device, O_RDONLY)) == -1){
121       perror("opening dsp device");
122       exit(1);
123    }
124 
125    setaudio = AUDIO_INTERN;
126    if(ioctl(devfh, BT848_SAUDIO, &setaudio) == -1){
127       perror("set internal audio ");
128       exit(1);
129    }
130 
131    if(ioctl(devfh, RADIO_GETMODE, &gotmask) == -1){
132       perror("get mode");
133       exit(1);
134    }
135    setmask = gotmask;
136 
137    if(mono)
138       setmask |= RADIO_MONO;
139    else
140       setmask &= ~RADIO_MONO;
141 
142    if(afc)
143       setmask |= RADIO_AFC;
144    else
145       setmask &= ~RADIO_AFC;
146 
147    if(ioctl(devfh, RADIO_SETMODE, &setmask) == -1){
148       perror("set mode - mono/afc");
149       exit(1);
150    }
151 
152    if(ioctl(devfh, RADIO_SETFREQ, &frequency) == -1){
153       perror("set frequency");
154       exit(1);
155    }
156 
157    while(1){
158       sleep(1);
159    }
160 
161    exit(0);
162 }
163 
banner()164 void banner()
165 {
166    printf("tuneradio: Set \"%s\" frequency, AFC and stereo/mono mode,\n",device);
167    printf("           and then keep the tuner open.\n");
168    printf("   -a            Sets tuner to run with AFC.  Default is off.\n");
169    printf("   -d device     Sets device name for the tuner.  Default is \"%s\".\n",device);
170    printf("   -f frequency  Sets tuner frequency (10Khz ie 88.1Mhz = 8810).\n");
171    printf("                 Default is \"%i\".\n",frequency);
172    printf("   -m            Sets tuner to run in mono.  Default is stereo.\n");
173    return;
174 }
175 
176 /*
177  * cntlc_handler()
178  *
179  * runs when a user does a CNTL-C...
180  *
181  */
182 
183 void
cntlc_handler(int whatever)184 cntlc_handler (int whatever)
185 {
186   exit (0);
187 }
188 
189 /*
190  * cleanup()
191  *
192  * runs on exit...
193  *
194  */
cleanvoid()195 void cleanvoid ()
196 {
197 	cleanup(0);
198 }
199 
200 void
cleanup(int whatever)201 cleanup (int whatever)
202 {
203    printf ("Shutting down...\n");
204    setaudio = AUDIO_EXTERN;
205    if(ioctl(devfh, BT848_SAUDIO, &setaudio) == -1){
206       perror("set internal audio ");
207    }
208    setaudio = AUDIO_UNMUTE;
209    if(ioctl(devfh, BT848_SAUDIO, &setaudio) == -1){
210       perror("set unmute audio ");
211    }
212   close (devfh);
213 }
214 
215