24#include "phonon_interface.h"
28#include <KLocalizedString>
30#include <phonon/Global>
31#include <phonon/MediaObject>
32#include <phonon/AudioOutput>
34#include <phonon/MediaController>
36#include <Solid/Device>
37#include <Solid/OpticalDrive>
38#include <Solid/OpticalDisc>
40#define WM_MSG_CLASS WM_MSG_CLASS_PLATFORM
44class ProducerWidget :
public QObject
47 ProducerWidget(KPhononCompactDiscPrivate *,
const QString &);
48 ~ProducerWidget()
override;
56ProducerWidget::ProducerWidget(KPhononCompactDiscPrivate *p,
const QString &Udi) :
59 m_mediaController(nullptr)
62 connect(m_media, SIGNAL(metaDataChanged()), SLOT(updateMetaData()));
63 m_media->setTickInterval(1000);
65 m_output =
new AudioOutput(Phonon::MusicCategory,
this);
66 Phonon::createPath(m_media, m_output);
68 connect(m_media, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
69 p, SLOT(stateChanged(Phonon::State,Phonon::State)));
71 connect(m_media, SIGNAL(tick(qint64)), p, SLOT(tick(qint64)));
74 m_media->setCurrentSource(*m_mediaSource);
79ProducerWidget::~ProducerWidget()
81 delete(m_mediaController);
86KPhononCompactDiscPrivate::KPhononCompactDiscPrivate(
KCompactDisc *p,
88 KCompactDiscPrivate(p, dev),
89 m_producerWidget(nullptr),
95KPhononCompactDiscPrivate::~KPhononCompactDiscPrivate()
97 delete m_producerWidget;
98 m_producerWidget =
nullptr;
101bool KPhononCompactDiscPrivate::createInterface()
103 qDebug() <<
"createInterface called";
110 m_deviceVendor = opticalDevice.vendor();
111 m_deviceModel = opticalDevice.product();
113 Q_EMIT q->discChanged(0);
123ProducerWidget *KPhononCompactDiscPrivate::producer()
126 if(!m_producerWidget) {
129 qDebug() <<
"producer called, opticalDrive is " << opticalDrive;
133 qDebug() <<
"opticalDisc " << opticalDisc;
135 m_producerWidget =
new ProducerWidget(
this, m_udi);
136 stateChanged(m_producerWidget->m_media->
state(), Phonon::StoppedState);
141 return m_producerWidget;
144unsigned KPhononCompactDiscPrivate::trackLength(
unsigned track)
146 if(!producer() || m_producerWidget->m_mediaController->currentTitle() != track)
149 return MS2SEC(m_producerWidget->m_media->
totalTime());
152bool KPhononCompactDiscPrivate::isTrackAudio(
unsigned)
157void KPhononCompactDiscPrivate::playTrackPosition(
unsigned track,
unsigned position)
162 qDebug() <<
"play track " << track <<
" position " << position;
165 m_producerWidget->m_media->
seek(SEC2MS(position));
166 Q_EMIT m_producerWidget->m_media->
play();
169void KPhononCompactDiscPrivate::pause()
174 Q_EMIT m_producerWidget->m_media->
pause();
177void KPhononCompactDiscPrivate::stop()
182 Q_EMIT m_producerWidget->m_media->
stop();
185void KPhononCompactDiscPrivate::eject()
191 if(!opticalDrive || !opticalDisc)
194 opticalDrive->
eject();
197void KPhononCompactDiscPrivate::closetray()
203 if(!opticalDrive || opticalDisc)
206 opticalDrive->
eject();
209void KPhononCompactDiscPrivate::setVolume(
unsigned volume)
215 m_producerWidget->m_output->setVolume(volume * 0.01);
218void KPhononCompactDiscPrivate::setBalance(
unsigned)
222unsigned KPhononCompactDiscPrivate::volume()
227 return (
unsigned)(m_producerWidget->m_output->
volume() * 100.0);
230unsigned KPhononCompactDiscPrivate::balance()
235void KPhononCompactDiscPrivate::queryMetadata()
243 qDebug() <<
"METADATA";
252 Q_EMIT q->discInformation(KCompactDisc::PhononMetadata);
255KCompactDisc::DiscStatus KPhononCompactDiscPrivate::discStatusTranslate(Phonon::State state)
258 case Phonon::PlayingState:
259 return KCompactDisc::Playing;
260 case Phonon::PausedState:
261 return KCompactDisc::Paused;
262 case Phonon::StoppedState:
263 return KCompactDisc::Stopped;
264 case Phonon::ErrorState:
265 return KCompactDisc::NoDisc;
266 case Phonon::LoadingState:
267 case Phonon::BufferingState:
268 return KCompactDisc::NotReady;
270 return KCompactDisc::Error;
274void KPhononCompactDiscPrivate::tick(qint64 t)
279 track = m_producerWidget->m_mediaController->currentTitle();
280 if(track != m_track) {
282 m_discLength = trackLength(m_track);
283 Q_EMIT q->playoutTrackChanged(m_track);
290 m_trackPosition = MS2SEC(t);
291 m_discPosition = m_trackPosition;
294 qDebug() <<
"seek: " << m_seek <<
" trackPosition " << m_trackPosition;
295 if(abs((
long)(m_trackExpectedPosition - m_trackPosition)) > m_seek)
298 m_seek = abs((
long)(m_trackExpectedPosition - m_trackPosition));
302 Q_EMIT q->playoutPositionChanged(m_trackPosition);
306void KPhononCompactDiscPrivate::stateChanged(Phonon::State newstate, Phonon::State)
308 qDebug() <<
"stateChanged with state " << newstate;
309 KCompactDisc::DiscStatus
status;
312 status = discStatusTranslate(newstate);
315 if(skipStatusChange(
status))
321 case KCompactDisc::Ejected:
322 case KCompactDisc::NoDisc:
327 m_tracks = m_producerWidget->m_mediaController->availableTitles();
328 qDebug() <<
"Got " << m_tracks <<
" tracks from media controller";
330 qDebug() <<
"New disc with " << m_tracks <<
" tracks";
334 m_trackArtists.append(
i18n(
"Unknown Artist"));
335 m_trackTitles.append(
i18n(
"Unknown Title"));
336 for(
unsigned i = 1; i <= m_tracks; ++i) {
337 m_trackArtists.append(
i18n(
"Unknown Artist"));
338 m_trackTitles.append(
ki18n(
"Track %1").subs(i, 2).
toString());
341 Q_EMIT q->discChanged(m_tracks);
353#include "moc_phonon_interface.cpp"
KCompactDisc - A CD drive interface for the KDE Project.
Q_SCRIPTABLE CaptureState status()
KLocalizedString KI18N_EXPORT ki18n(const char *text)
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)