#include #include #include #include #include #include #include #include #include #include #include "rds.h" #include "tmc.h" sqlite3 *lcl_db; int OutputFlags; unsigned char pi_received = 0; unsigned char sid_received = 0; void test_rds_PI_cb(unsigned short PI, unsigned char ccode, unsigned char ptype, unsigned char pref, void *udata) { printf("New PI=%d ccode=%X ptype=%X '%s' '%s' pref=%d\n", PI, ccode, ptype, ptype_stext[ptype], ptype_ltext[ptype], pref); pi_received = 1; } void test_rds_sname_cb(char *sname, void *udata) { printf("RDS sname='%s'\n", sname); sid_received = 1; } void station_scan(int fd) { int ret; struct v4l2_frequency v4lfreq; struct v4l2_tuner v4ltuner; unsigned short rdsgroup[4]; v4ltuner.index = 0; ret = ioctl(fd, VIDIOC_G_TUNER, &v4ltuner); if (ret < 0) return; printf("tuner=%d\n", v4ltuner.index); if (v4ltuner.type == V4L2_TUNER_RADIO) printf(" is a radio tuner\n"); printf("name='%s'\n", v4ltuner.name); v4lfreq.tuner = v4ltuner.index; memset(&v4lfreq.reserved, 0, 32); ret = ioctl(fd, VIDIOC_G_FREQUENCY, &v4lfreq); if (ret < 0) return; v4lfreq.frequency = v4ltuner.rangelow; while (v4lfreq.frequency <= v4ltuner.rangehigh) { ret = ioctl(fd, VIDIOC_S_FREQUENCY, &v4lfreq); if (ret < 0) break; ret = ioctl(fd, VIDIOC_G_FREQUENCY, &v4lfreq); if (ret < 0) break; ret = ioctl(fd, VIDIOC_G_TUNER, &v4ltuner); if (ret < 0) break; printf("%lf %d %d %s %s\n", (double)v4lfreq.frequency * 62.5 / 1000000, v4lfreq.frequency, v4ltuner.signal, v4ltuner.rxsubchans & V4L2_TUNER_SUB_STEREO ? "stereo" : "mono", v4ltuner.rxsubchans & V4L2_TUNER_SUB_RDS ? "RDS" : "noRDS"); if (v4ltuner.signal > 30000) { /* seems to be a strong signal, so try RDS */ pi_received = 0; sid_received = 0; rds_radio_retuned(); while (pi_received == 0 || sid_received == 0) { if (rds_receive_group(fd, rdsgroup)) { /* group complete, start decode */ rds_decode_group(rdsgroup); } } } v4lfreq.frequency += 1600; /* 1600 for .1MHz steps, 800 for 0.05MHz */ } } int main(int argc, char **argv) { int fd, ret; struct v4l2_capability v4lcap; struct v4l2_frequency v4lfreq; struct v4l2_tuner v4ltuner; fd = open ("/dev/radio0", O_RDONLY); if (fd < 0) { printf("error opening fd\n"); perror("open"); return 1; } ret = ioctl(fd, VIDIOC_QUERYCAP, &v4lcap); if (ret < 0) return 1; printf("driver = '%s'\n", v4lcap.driver); printf("card = '%s'\n", v4lcap.card); printf("bus_info = '%s'\n", v4lcap.bus_info); printf("cap && RADIO = %s\n", (v4lcap.capabilities & V4L2_CAP_RADIO) ? "yes" : "no"); printf("cap && TUNER = %s\n", (v4lcap.capabilities & V4L2_CAP_TUNER) ? "yes" : "no"); printf("cap && RDS = %s\n", (v4lcap.capabilities & V4L2_CAP_RDS_CAPTURE) ? "yes" : "no"); v4ltuner.index = 0; ret = ioctl(fd, VIDIOC_G_TUNER, &v4ltuner); if (ret < 0) return 1; printf("tuner=%d\n", v4ltuner.index); if (v4ltuner.type == V4L2_TUNER_RADIO) printf(" is a radio tuner\n"); printf("name='%s'\n", v4ltuner.name); v4lfreq.tuner = v4ltuner.index; memset(&v4lfreq.reserved, 0, 32); ret = ioctl(fd, VIDIOC_G_FREQUENCY, &v4lfreq); if (ret >= 0) { if (v4ltuner.capability & V4L2_TUNER_CAP_LOW) { printf("range %3.2lf MHz - %3.2lf MHz\n", (double)v4ltuner.rangelow * 62.5 / 1000000, (double)v4ltuner.rangehigh * 62.5 / 1000000); printf("freq = %3.2lf MHz\n", (double)v4lfreq.frequency * 62.5 / 1000000); } else printf("freq = %lf kHz\n", (double)v4lfreq.frequency * 62.5); } printf("signal: %d %s\n", v4ltuner.signal, v4ltuner.rxsubchans & V4L2_TUNER_SUB_STEREO ? "stereo" : "mono"); printf("RDS signal present: %s\n", v4ltuner.rxsubchans & V4L2_TUNER_SUB_RDS ? "yes" : "no"); if (argc > 1 && strcmp(argv[1], "-s")==0) { rds_init(); tmc_init(); rds_set_sname_cb(test_rds_sname_cb, NULL); rds_set_PI_cb(test_rds_PI_cb, NULL); station_scan(fd); } close(fd); return 0; }