fmv4l2.c
资源名称:fmradio.zip [点击查看]
上传用户:ledjyj
上传日期:2014-08-27
资源大小:2639k
文件大小:7k
源码类别:
驱动编程
开发平台:
Unix_Linux
- /* fm.c - simple v4l compatible tuner for radio cards Copyright (C) 1998 Russell Kroll <rkroll@exploits.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <math.h> #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <getopt.h> #include <string.h> #include <asm/types.h> #include <sys/ioctl.h> //#include <linux/videodev.h> #include <signal.h> #include "videodev.h" #include "videodev2.h" void help(char *prog) { printf ("usage: %s [-h] [-o] [-q] [-t <tuner>] <freq>|on|off [<volume>]n", prog); printf ("n"); printf ("-h - display this helpn"); printf ("-o - override frequency range limits in cardn"); printf ("-q - quiet moden"); printf ("-t <tuner> - select tuner <tuner>n"); printf ("<tuner> - tuner number - first one is 0, next one 1, etcn"); printf ("<freq> - frequency in MHz (i.e. 94.3)n"); printf ("on - turn radio onn"); printf ("off - turn radio off (mute)n"); printf ("+ - increase volumen"); printf ("- - decrease volumen"); printf ("<volume> - intensity (0-65535)n"); exit (1); } int fd,count; void getconfig(int *defaultvol, int *increment) { FILE *conf; char buf[256], fn[256]; sprintf (fn, "%s/.fmrc", getenv("HOME")); conf = fopen (fn, "r"); if (!conf) return; while (fgets(buf, sizeof(buf), conf)) { buf[strlen(buf)-1] = 0; if (strncmp (buf, "VOL", 3) == 0) sscanf (buf, "%*s %i", defaultvol); if (strncmp (buf, "INCR", 3) == 0) sscanf (buf, "%*s %i", increment); } fclose (conf); return; } void signal_handler_IO()
- { int ret; struct RDS_DATA rds; FILE *conf; ret = read(fd,&rds, sizeof(rds)); printf("RDSA= %d,RDSB=%d,RDSC=%d,RDSD=%d n", rds.RDSA,rds.RDSB,rds.RDSC,rds.RDSD); conf=fopen("/usr/beck/rds","a"); fprintf(conf,"RDSA= %d,RDSB=%d,RDSC=%d,RDSD=%d n", rds.RDSA,rds.RDSB,rds.RDSC,rds.RDSD); //fwrite(&rds,sizeof(rds),1,conf); fclose(conf); } int main(int argc, char **argv) { int ret, tunevol, quiet=0, i, override = 0; int defaultvol = 100; /* default volume = 12.5% */ int increment = 20; /* default change = 10% */ //double fact; struct v4l2_frequency freq; struct video_audio va; struct v4l2_tuner vt; struct v4l2_control ctrl; struct radio_scan next; struct RDS_DATA rds; FILE *conf; struct sigaction sigaction_io; char *progname; extern char *optarg; extern int optind, opterr, optopt; int tuner = 0; freq.frequency =10170; if ((argc < 2) || (argc > 4)) { printf ("usage: %s [-h] [-o] [-q] [-t <tuner>] <freq>|on|off [<volume>]n", argv[0]); exit (1); } progname = argv[0]; /* used after getopt munges argv[] */ getconfig(&defaultvol, &increment); while ((i = getopt(argc, argv, "+qhot:")) != EOF) { switch (i) { case 'q': quiet = 1; break; case 'o': override = 1; break; case 't': tuner = atoi(optarg); break; case 'h': default: help(argv[0]); break; } } argc -= optind; argv += optind; if (argc == 2) tunevol = atoi (argv[1]); else tunevol = defaultvol; if (argc == 0) /* no frequency, on|off, or +|- given */ help (progname); /* moved here so -h works without a device */ fd = open ("/dev/radio0", O_RDONLY); if (fd == -1) { perror ("Unable to open /dev/radio0"); exit (1); } if (!strcmp("off", argv[0])) { /* mute the radio */ // va.audio = 0; //va.volume = 0; // va.flags = VIDEO_AUDIO_MUTE; ret = ioctl (fd, VIDIOC_RADIO_OFF, &va); if (!quiet) printf ("Radio offn"); exit (0); } if (!strcmp("on", argv[0])) { /* turn radio on */ //va.audio = 0; //va.volume = tunevol; //va.flags = 0; ret = ioctl (fd, VIDIOC_RADIO_ON, &va); if (!quiet) printf ("Radio onn "); exit (0); } if (!strcmp("seekup", argv[0])) { // va.audio = 0; //va.volume = 0; // va.flags = VIDEO_AUDIO_MUTE; next.direction = SEEKUP; ret = ioctl(fd, RADIO_SCAN_NEXT,&next); printf("seek up channel = %dn", next.channel); exit (0); } if (!strcmp("seekdown", argv[0])) { // va.audio = 0; //va.volume = 0; // va.flags = VIDEO_AUDIO_MUTE; next.direction = SEEKDOWN; ret = ioctl(fd, RADIO_SCAN_NEXT,&next); printf("seek down channel = %dn", next.channel); exit (0); } if (!strcmp("RSSI", argv[0])) { ret = ioctl(fd, VIDIOC_G_TUNER, &vt); /* get RSSI*/ printf ("Get RSSI=%dn",vt.signal); } if (!strcmp("frequency", argv[0])) { /* at this point, we are trying to tune to a frequency */ vt.audmode =V4L2_TUNER_MODE_STEREO; ret = ioctl(fd, VIDIOC_S_TUNER, &vt); /* set tuner # */ if (ret < 0) { perror ("set tuner n"); exit (1); } ret = ioctl(fd, VIDIOC_G_TUNER, &vt); /* get frequency range */ //if (ret == -1 || (vt.flags & VIDEO_TUNER_LOW) == 0) //fact = 16.; //else // fact = 16000.; //freq = ceil(atof(argv[0]) * fact); /* rounding up matters */ freq.frequency = atoi(argv[1]); printf ("Frequency %d,range (%d - %d KHz)n", freq.frequency , vt.rangelow , vt.rangehigh ); /* frequency sanity checked, proceed */ ret = ioctl (fd, VIDIOC_S_FREQUENCY, &freq); printf ("set freq n"); } if (!strcmp("volume", argv[0])) { // va.audio = 0; //va.volume = 0; // va.flags = VIDEO_AUDIO_MUTE; ctrl.id = V4L2_CID_AUDIO_VOLUME; ctrl.value = atoi(argv[1]); ret = ioctl(fd,VIDIOC_S_CTRL, &ctrl); printf("set volume %d n",ctrl.value); } if (!strcmp("mute", argv[0])) { // va.audio = 0; //va.volume = 0; // va.flags = VIDEO_AUDIO_MUTE; ctrl.id = V4L2_CID_AUDIO_MUTE; ctrl.value = atoi(argv[1]); ret = ioctl(fd,VIDIOC_S_CTRL, &ctrl); printf("mute fm %d n", ctrl.value); } if (!strcmp("RDS", argv[0])) { // va.audio = 0; //va.volume = 0; // va.flags = VIDEO_AUDIO_MUTE; ret = read(fd,&rds, sizeof(rds)); printf("RDSA= %d,RDSB=%d,RDSC=%d,RDSD=%d n", rds.RDSA,rds.RDSB,rds.RDSC,rds.RDSD); conf=fopen("/usr/beck/rds","a"); if(!conf) return 0; fprintf(conf,"RDSA= %d,RDSB=%d,RDSC=%d,RDSD=%d n", rds.RDSA,rds.RDSB,rds.RDSC,rds.RDSD); //fwrite(&rds,sizeof(rds),1,conf); fclose(conf); } if (!strcmp("RDS_SIG", argv[0])) { // va.audio = 0; //va.volume = 0; // va.flags = VIDEO_AUDIO_MUTE; sigaction_io.sa_handler = signal_handler_IO; sigemptyset (&(sigaction_io.sa_mask)); sigaction_io.sa_flags = 0; sigaction_io.sa_restorer = NULL; sigaction (SIGIO, &sigaction_io, NULL); fcntl(fd, F_SETFL, O_ASYNC); fcntl (fd, F_SETOWN, getpid ()); while(1); } close(fd); return (0); }