From: Dave Schmitz <[EMAIL PROTECTED]>
> I was curious to know if anyone is using both video tuning and FM
> tuning in the same (bttv) app.
Does not work with e.g. one hauppauge card. It has only one tuner and
cant tune both, tv and fm.
> I was wondering what the best approach is to use both devices.
> Do I need to close the /dev/video0 and open /dev/radio0 and vice
> versa when switching between functionality?
> Is there a way to open both devices?
Hm. Depends on the hardware. I've an extra radio card and both devices
dont know each other, of course. But with the same tuner on a grabber
card... Maybe you could select some other (tunerless) input for video
and use the radio part of that card... Try or ask Gerd... (-:
> Also, I've noticed a ioctl called VIDIOCGUNIT which is suppose to
> "obtain related devices if a driver has multiple components". What
> is this information used for?
Good question. I tried my litte C code (attached) on various /dev/xyz
with bttv 0.7.x. Only /dev/video0 reported something - very usefull to
find relationships form /dev/radioX to user things...
I wanted to write some radio app that time...
Okay, run my piece of C. It's for v4l1. The output here for /dev/radio
shows the behavior of "my" miropcm20 driver....
Bye,
Robert
bash-2.05$ ./v4l-test /dev/radio
Found Miro PCM20, which has 1 channel(s).
Unable to check for related units... <---------
Sorry, this device is unable to answer on VIDIOGCHAN for channel 0...
Setting to channel 0.
VIDIOCSCHAN failed. (This is normal...)
Tuner0 (FM): low: 87.000, high: 108.000
current frequency (97.150): stereo RDS (auto)
signal:48059
Audio0 (Radio): mode: mono stereo
flags: unmuted balance:-32768 step:0
/*
* Copyright (C) 2000 Robert Siemer <[EMAIL PROTECTED]>
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/videodev.h>
typedef struct {
unsigned int freq;
unsigned int signal;
unsigned int stereo :1;
unsigned int rds :1;
} station;
int main (int argc, char *argv[])
{
int fd, i;
struct video_capability vcap;
struct video_unit vu;
struct video_channel vchan;
struct video_tuner vt;
unsigned long freq;
struct video_audio va;
if (argc==0)
return 1;
fd=open(argv[1], O_RDONLY);
if (fd<0) {
perror(program_invocation_short_name);
return 1;
}
if (ioctl(fd, VIDIOCGCAP, &vcap)<0) {
perror(program_invocation_short_name);
return 1;
}
if (vcap.type&VID_TYPE_TUNER && !vcap.type&VID_TYPE_CAPTURE &&
!vcap.type&VID_TYPE_OVERLAY)
printf("Hmmm, does not look like a radio card - but I don't"
" care... [:\n");
if (vcap.audios!=1)
printf("Aehm, what does it mean: this device has %d"
" audio devices...\n", vcap.audios);
printf("Found %s, which has %d channel(s).\n", vcap.name,
vcap.channels);
if (ioctl(fd, VIDIOCGUNIT, &vu)<0)
printf("Unable to check for related units...\n");
else
printf("video:%d vbi:%d radio:%d audio:%d teletext:%d\n",
vu.video, vu.vbi, vu.radio, vu.audio, vu.teletext);
for (vchan.channel=0; vchan.channel<vcap.channels; vchan.channel++) {
if (ioctl(fd, VIDIOCGCHAN, &vchan)<0) {
printf("Sorry, this device is unable to answer on"
" VIDIOGCHAN for channel %d...\n",
vchan.channel);
continue;
}
printf("Channel%d (%s): ", vchan.channel, vchan.name);
if (vchan.tuners<1 && !(vchan.flags&VIDEO_VC_TUNER)) {
printf("no tuner --> no radio\n");
continue;
}
if ((vchan.tuners<1 && vchan.flags&VIDEO_VC_TUNER) ||
(vchan.tuners>=1 && !(vchan.flags&VIDEO_VC_TUNER)))
printf("device is unsure about having some (%d)"
" tuners on this channel...\n", vchan.tuners);
if (vchan.type&VIDEO_TYPE_TV || vchan.type&VIDEO_TYPE_CAMERA
|| !(vchan.flags&VIDEO_VC_AUDIO)) {
printf("A radio has audio and no tv/camera input. "
"This is not true here...\n");
continue;
}
printf("\n");
break;
}
if (vchan.channel==vcap.channels) vchan.channel=0, vchan.tuners=1;
printf("Setting to channel %d.\n", vchan.channel);
if (ioctl(fd, VIDIOCSCHAN, &vchan)<0) {
printf("VIDIOCSCHAN failed. (This is normal...)\n");
}
for (vt.tuner=0; vt.tuner<vchan.tuners; vt.tuner++) {
if (ioctl(fd, VIDIOCGTUNER, &vt)<0) {
printf("ioctl() problem with tuner %d.\n", vt.tuner);
continue;
}
printf("Tuner%d (%s): ", vt.tuner, vt.name);
i=(vt.flags&VIDEO_TUNER_LOW)? 16000 : 16;
printf("low: %.3f, high: %.3f\n",
(double)vt.rangelow/i, (double)vt.rangehigh/i);
if (ioctl(fd, VIDIOCSTUNER, &vt)<0 ||
ioctl(fd, VIDIOCGFREQ, &freq)<0) {
printf("Sorry, this tuner is just fucked up...\n");
continue;
}
printf(" current frequency (%.3f): ", (double)freq/i);
if (vt.flags&VIDEO_TUNER_STEREO_ON)
printf("stereo ");
if (vt.flags&VIDEO_TUNER_RDS_ON)
printf("RDS ");
if (vt.mode&VIDEO_MODE_AUTO)
printf("(auto)");
printf("\n");
printf(" signal:%d\n", vt.signal);
}
for (va.audio=0; va.audio<vcap.audios; va.audio++) {
if (ioctl(fd, VIDIOCGAUDIO, &va)<0) {
printf("ioctl() problem with audio %d.\n", va.audio);
continue;
}
printf("Audio%d (%s): ", va.audio, va.name);
printf("mode: ");
if (va.mode&VIDEO_SOUND_MONO)
printf("mono ");
if (va.mode&VIDEO_SOUND_STEREO)
printf("stereo ");
if (va.mode&VIDEO_SOUND_LANG1)
printf("lang1 ");
if (va.mode&VIDEO_SOUND_LANG2)
printf("lang2");
printf("\n");
printf(" flags: ");
if (va.flags&VIDEO_AUDIO_MUTABLE) {
if (va.flags&VIDEO_AUDIO_MUTE)
printf("muted ");
else
printf("unmuted ");
}
if (va.flags&VIDEO_AUDIO_VOLUME)
printf("volume:%d ", va.volume);
if (va.flags&VIDEO_AUDIO_BASS)
printf("bass:%d ", va.bass);
if (va.flags&VIDEO_AUDIO_TREBLE)
printf("treble:%d ", va.treble);
printf("balance:%d step:%d\n", va.balance-32768, va.step);
}
return 0;
}