summaryrefslogtreecommitdiff
path: root/fmrxservice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fmrxservice.cpp')
-rw-r--r--fmrxservice.cpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/fmrxservice.cpp b/fmrxservice.cpp
new file mode 100644
index 0000000..3a990bd
--- /dev/null
+++ b/fmrxservice.cpp
@@ -0,0 +1,154 @@
+#include <QtMultimedia/QAudioDeviceInfo>
+#include <QtMultimedia/QAudioOutput>
+#include <QtCore/QFile>
+#include <QtDebug>
+
+#include "fmrxservice.h"
+#include "fmrxcontrol.h"
+#include "fmrxproxy.h"
+
+// Again, this would be incredibly shorter if QAudioOuput could be used.
+// Unfortunately, it is completely useless in the Harmattan version.
+
+struct FmRxPriv
+{
+ QAudioOutput *out;
+ QFile *in;
+ int fd;
+ bool active;
+ double frequency;
+};
+
+FmRxService::FmRxService(QObject *parent) :
+ QMediaService(parent)
+{
+ m_proxy = new FmRxProxy(this);
+ m_control = new FmRxControl(this);
+ m_priv = new FmRxPriv;
+
+ QAudioFormat format;
+ format.setFrequency(48000);
+ format.setChannels(2);
+ format.setSampleType(QAudioFormat::SignedInt);
+ format.setSampleSize(16);
+ format.setByteOrder(QAudioFormat::LittleEndian);
+ format.setCodec("audio/pcm");
+
+ QAudioDeviceInfo info = QAudioDeviceInfo::defaultOutputDevice();
+ if (!info.isFormatSupported(format)) {
+ qWarning("FM radio format not supported by audio output");
+ }
+ qDebug("Starting output to %s", qPrintable(info.deviceName()));
+
+ m_priv->out = new QAudioOutput(info, format, this);
+ m_priv->in = new QFile(this);
+ m_priv->active = false;
+
+ connect(m_proxy, SIGNAL(Tuned(double)), this, SLOT(handleTuned(double)));
+ connect(m_proxy, SIGNAL(Stopped()), this, SLOT(handleStopped()));
+ connect(m_proxy, SIGNAL(PiReceived(ushort)), this, SIGNAL(piReceived(ushort)));
+ connect(m_proxy, SIGNAL(PsReceived(QString)), this, SIGNAL(psReceived(QString)));
+ connect(m_proxy, SIGNAL(RtReceived(QString)), this, SIGNAL(rtReceived(QString)));
+
+ connect(m_priv->out, SIGNAL(stateChanged(QAudio::State)),
+ this, SLOT(handleOutState(QAudio::State)));
+}
+
+FmRxService::~FmRxService()
+{
+ delete m_priv;
+}
+
+QMediaControl *FmRxService::requestControl(const char *name)
+{
+ if (qstrcmp(name, QRadioTunerControl_iid) == 0)
+ return m_control;
+
+ return 0;
+}
+
+void FmRxService::releaseControl(QMediaControl *control)
+{
+ // Do nothing
+}
+
+void FmRxService::start()
+{
+ m_priv->fd = m_proxy->Connect();
+ m_priv->in->open(m_priv->fd, QIODevice::ReadOnly);
+ m_priv->out->start(m_priv->in);
+ qDebug("Starting fmrx service");
+}
+
+void FmRxService::stop()
+{
+ m_priv->out->stop();
+ m_priv->in->close();
+ close(m_priv->fd);
+}
+
+bool FmRxService::isAvailable() const
+{
+ // TODO Check avaibility of fmrxd service
+ return true;
+}
+
+QtMultimediaKit::AvailabilityError FmRxService::availabilityError() const
+{
+ return QtMultimediaKit::NoError;
+}
+
+bool FmRxService::isActive() const
+{
+ return m_priv->active;
+}
+
+void FmRxService::handleTuned(double frequency)
+{
+ if (!qFuzzyCompare(m_priv->frequency, frequency)) {
+ m_priv->frequency = frequency;
+ emit tuned(frequency);
+ }
+ if (!m_priv->active) {
+ m_priv->active = true;
+ emit started();
+ }
+}
+
+void FmRxService::handleStopped()
+{
+ if (m_priv->active) {
+ m_priv->active = false;
+ emit stopped();
+ }
+}
+
+void FmRxService::handleOutState(QAudio::State state)
+{
+ qDebug() << "New out state = " << state;
+ if (state == QAudio::IdleState &&
+ m_priv->out->error() == QAudio::UnderrunError) {
+ qDebug() << "Restarting";
+ m_priv->out->start(m_priv->in);
+ }
+}
+
+double FmRxService::frequency()
+{
+ return m_priv->frequency;
+}
+
+void FmRxService::setFrequency(double frequency)
+{
+ m_proxy->Tune(frequency);
+}
+
+void FmRxService::searchForward()
+{
+ m_proxy->SearchForward();
+}
+
+void FmRxService::searchBackward()
+{
+ m_proxy->SearchBackward();
+}