qv4l2: add support for radio modulators.
authorHans Verkuil <hans.verkuil@cisco.com>
Sun, 10 Jun 2012 09:44:59 +0000 (11:44 +0200)
committerHans Verkuil <hans.verkuil@cisco.com>
Sun, 10 Jun 2012 09:44:59 +0000 (11:44 +0200)
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
utils/qv4l2/general-tab.cpp
utils/qv4l2/general-tab.h
utils/qv4l2/v4l2-api.cpp
utils/qv4l2/v4l2-api.h

index 784d19c..346a1ee 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <QSpinBox>
 #include <QComboBox>
+#include <QCheckBox>
 #include <QPushButton>
 #include <QLineEdit>
 #include <QDoubleValidator>
@@ -68,13 +69,16 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
        }
 
        g_tuner(m_tuner);
+       g_modulator(m_modulator);
 
        v4l2_input vin;
        bool needsStd = false;
        bool needsPreset = false;
        bool needsTimings = false;
 
-       if (m_tuner.type && m_tuner.capability & V4L2_TUNER_CAP_LOW)
+       if (m_tuner.capability && m_tuner.capability & V4L2_TUNER_CAP_LOW)
+               m_isRadio = true;
+       if (m_modulator.capability && m_modulator.capability & V4L2_TUNER_CAP_LOW)
                m_isRadio = true;
 
        if (!isRadio() && enum_input(vin, true)) {
@@ -165,7 +169,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
                connect(m_qryTimings, SIGNAL(clicked()), SLOT(qryTimingsClicked()));
        }
 
-       if (m_tuner.type) {
+       if (m_tuner.capability) {
                QDoubleValidator *val;
                double factor = (m_tuner.capability & V4L2_TUNER_CAP_LOW) ? 16 : 16000;
 
@@ -235,6 +239,41 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
                detectSubchansClicked();
        }
 
+       if (m_modulator.capability) {
+               QDoubleValidator *val;
+               double factor = (m_modulator.capability & V4L2_TUNER_CAP_LOW) ? 16 : 16000;
+
+               val = new QDoubleValidator(m_modulator.rangelow / factor, m_modulator.rangehigh / factor, 3, parent);
+               m_freq = new QLineEdit(parent);
+               m_freq->setValidator(val);
+               m_freq->setWhatsThis(QString("Frequency\nLow: %1\nHigh: %2")
+                               .arg(m_modulator.rangelow / factor).arg(m_modulator.rangehigh / factor));
+               connect(m_freq, SIGNAL(lostFocus()), SLOT(freqChanged()));
+               connect(m_freq, SIGNAL(returnPressed()), SLOT(freqChanged()));
+               updateFreq();
+               if (m_modulator.capability & V4L2_TUNER_CAP_LOW)
+                       addLabel("Frequency (kHz)");
+               else
+                       addLabel("Frequency (MHz)");
+               addWidget(m_freq);
+               if (m_modulator.capability & V4L2_TUNER_CAP_STEREO) {
+                       addLabel("Stereo");
+                       m_stereoMode = new QCheckBox(parent);
+                       m_stereoMode->setCheckState((m_modulator.txsubchans & V4L2_TUNER_SUB_STEREO) ?
+                                       Qt::Checked : Qt::Unchecked);
+                       addWidget(m_stereoMode);
+                       connect(m_stereoMode, SIGNAL(clicked()), SLOT(stereoModeChanged()));
+               }
+               if (m_modulator.capability & V4L2_TUNER_CAP_RDS) {
+                       addLabel("RDS");
+                       m_rdsMode = new QCheckBox(parent);
+                       m_rdsMode->setCheckState((m_modulator.txsubchans & V4L2_TUNER_SUB_RDS) ?
+                                       Qt::Checked : Qt::Unchecked);
+                       addWidget(m_rdsMode);
+                       connect(m_rdsMode, SIGNAL(clicked()), SLOT(rdsModeChanged()));
+               }
+       }
+
        if (isRadio())
                goto done;
 
@@ -446,6 +485,28 @@ void GeneralTab::detectSubchansClicked()
        m_subchannels->setText(chans);
 }
 
+void GeneralTab::stereoModeChanged()
+{
+       v4l2_modulator mod;
+       bool val = m_stereoMode->checkState() == Qt::Checked;
+
+       g_modulator(mod);
+       mod.txsubchans &= ~(V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO);
+       mod.txsubchans |= val ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
+       s_modulator(mod);
+}
+
+void GeneralTab::rdsModeChanged()
+{
+       v4l2_modulator mod;
+       bool val = m_rdsMode->checkState() == Qt::Checked;
+
+       g_modulator(mod);
+       mod.txsubchans &= ~V4L2_TUNER_SUB_RDS;
+       mod.txsubchans |= val ? V4L2_TUNER_SUB_RDS : 0;
+       s_modulator(mod);
+}
+
 void GeneralTab::vidCapFormatChanged(int idx)
 {
        v4l2_fmtdesc desc;
index 8805ed7..2d5ffa6 100644 (file)
@@ -28,6 +28,7 @@
 #include "v4l2-api.h"
 
 class QComboBox;
+class QCheckBox;
 class QSpinBox;
 class QPushButton;
 
@@ -61,6 +62,8 @@ private slots:
        void freqChanged();
        void audioModeChanged(int);
        void detectSubchansClicked();
+       void stereoModeChanged();
+       void rdsModeChanged();
        void vidCapFormatChanged(int);
        void frameWidthChanged();
        void frameHeightChanged();
@@ -106,6 +109,7 @@ private:
        bool m_isRadio;
        __u32 m_audioModes[5];
        struct v4l2_tuner m_tuner;
+       struct v4l2_modulator m_modulator;
        struct v4l2_capability m_querycap;
        __u32 m_pixelformat;
        __u32 m_width, m_height;
@@ -128,6 +132,8 @@ private:
        QComboBox *m_freqChannel;
        QComboBox *m_audioMode;
        QLabel *m_subchannels;
+       QCheckBox *m_stereoMode;
+       QCheckBox *m_rdsMode;
        QPushButton *m_detectSubchans;
        QComboBox *m_vidCapFormats;
        QComboBox *m_frameSize;
index 7df54e8..cf88eb5 100644 (file)
@@ -149,6 +149,17 @@ bool v4l2::s_tuner(v4l2_tuner &tuner)
        return ioctl("Set Tuner", VIDIOC_S_TUNER, &tuner);
 }
 
+bool v4l2::g_modulator(v4l2_modulator &modulator)
+{
+       memset(&modulator, 0, sizeof(modulator));
+       return ioctl(VIDIOC_G_MODULATOR, &modulator) >= 0;
+}
+
+bool v4l2::s_modulator(v4l2_modulator &modulator)
+{
+       return ioctl("Set Modulator", VIDIOC_S_MODULATOR, &modulator);
+}
+
 bool v4l2::g_input(int &input)
 {
        return ioctl(VIDIOC_G_INPUT, &input) >= 0;
index d015909..a451268 100644 (file)
@@ -60,6 +60,8 @@ public:
        bool querymenu(v4l2_querymenu &qm);
        bool g_tuner(v4l2_tuner &tuner);
        bool s_tuner(v4l2_tuner &tuner);
+       bool g_modulator(v4l2_modulator &modulator);
+       bool s_modulator(v4l2_modulator &modulator);
        bool g_input(int &input);
        bool s_input(int input);
        bool g_output(int &output);