#include #include #include #include #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(); }