3
* Copyright (C) 2004-2007 Matthias Kretz <kretz@kde.org>
4
* Copyright (C) by Alexander Kern <alex.kern@gmx.de>
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Library General Public
8
* License as published by the Free Software Foundation; either
9
* version 2 of the License, or (at your option) any later version.
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Library General Public License for more details.
16
* You should have received a copy of the GNU Library General Public
17
* License along with this library; if not, write to the Free
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
* CDDA version taken from guitest in phonon test directory
24
#include "phonon_interface.h"
29
#include <Phonon/Global>
30
#include <Phonon/MediaObject>
31
#include <Phonon/AudioOutput>
32
#include <Phonon/Path>
33
#include <Phonon/MediaController>
35
#include <solid/device.h>
36
#include <solid/opticaldrive.h>
37
#include <solid/opticaldisc.h>
39
#define WM_MSG_CLASS WM_MSG_CLASS_PLATFORM
41
using namespace Phonon;
43
class ProducerWidget : public QObject
46
ProducerWidget(KPhononCompactDiscPrivate *, const QString &);
51
AudioOutput *m_output;
52
MediaController *m_mediaController;
55
ProducerWidget::ProducerWidget(KPhononCompactDiscPrivate *p, const QString &Udi) :
60
m_media = new MediaObject(this);
61
connect(m_media, SIGNAL(metaDataChanged()), SLOT(updateMetaData()));
62
m_media->setTickInterval(1000);
64
m_output = new AudioOutput(Phonon::MusicCategory, this);
65
Phonon::createPath(m_media, m_output);
67
connect(m_media, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
68
p, SLOT(stateChanged(Phonon::State,Phonon::State)));
70
connect(m_media, SIGNAL(tick(qint64)), p, SLOT(tick(qint64)));
72
MediaSource *m_mediaSource = new MediaSource(Phonon::Cd, Udi);
73
m_media->setCurrentSource(*m_mediaSource);
75
m_mediaController = new MediaController(m_media);
78
ProducerWidget::~ProducerWidget()
80
delete(m_mediaController);
85
KPhononCompactDiscPrivate::KPhononCompactDiscPrivate(KCompactDisc *p,
87
KCompactDiscPrivate(p, dev),
88
m_producerWidget(NULL),
89
m_udi(KCompactDisc::cdromDeviceUdi(dev))
91
m_interface = QLatin1String("phonon");
94
KPhononCompactDiscPrivate::~KPhononCompactDiscPrivate()
96
delete m_producerWidget;
97
m_producerWidget = NULL;
100
bool KPhononCompactDiscPrivate::createInterface()
102
Solid::Device opticalDevice(m_udi);
103
Solid::OpticalDrive *opticalDrive = opticalDevice.as<Solid::OpticalDrive>();
108
m_deviceVendor = opticalDevice.vendor();
109
m_deviceModel = opticalDevice.product();
111
emit q->discChanged(0);
121
ProducerWidget *KPhononCompactDiscPrivate::producer()
124
if(!m_producerWidget) {
125
Solid::Device opticalDevice(m_udi);
126
Solid::OpticalDrive *opticalDrive = opticalDevice.as<Solid::OpticalDrive>();
129
Solid::OpticalDisc *opticalDisc = opticalDevice.as<Solid::OpticalDisc>();
130
kDebug() << "opticalDisc " << opticalDisc;
131
//if(opticalDisc && (opticalDisc->availableContent() == Solid::OpticalDisc::Audio)) {
132
m_producerWidget = new ProducerWidget(this, m_udi);
137
return m_producerWidget;
140
unsigned KPhononCompactDiscPrivate::trackLength(unsigned track)
142
if(!producer() || m_producerWidget->m_mediaController->currentTitle() != track)
145
return MS2SEC(m_producerWidget->m_media->totalTime());
148
bool KPhononCompactDiscPrivate::isTrackAudio(unsigned)
153
void KPhononCompactDiscPrivate::playTrackPosition(unsigned track, unsigned position)
158
kDebug() << "play track " << track << " position " << position;
160
m_producerWidget->m_mediaController->setCurrentTitle(track);
161
m_producerWidget->m_media->seek(SEC2MS(position));
162
emit m_producerWidget->m_media->play();
165
void KPhononCompactDiscPrivate::pause()
170
emit m_producerWidget->m_media->pause();
173
void KPhononCompactDiscPrivate::stop()
178
emit m_producerWidget->m_media->stop();
181
void KPhononCompactDiscPrivate::eject()
183
Solid::Device opticalDevice(m_udi);
184
Solid::OpticalDrive *opticalDrive = opticalDevice.as<Solid::OpticalDrive>();
185
Solid::OpticalDisc *opticalDisc = opticalDevice.as<Solid::OpticalDisc>();
187
if(!opticalDrive || !opticalDisc)
190
opticalDrive->eject();
193
void KPhononCompactDiscPrivate::closetray()
195
Solid::Device opticalDevice(m_udi);
196
Solid::OpticalDrive *opticalDrive = opticalDevice.as<Solid::OpticalDrive>();
197
Solid::OpticalDisc *opticalDisc = opticalDevice.as<Solid::OpticalDisc>();
199
if(!opticalDrive || opticalDisc)
202
opticalDrive->eject();
205
void KPhononCompactDiscPrivate::setVolume(unsigned volume)
211
m_producerWidget->m_output->setVolume(volume * 0.01);
214
void KPhononCompactDiscPrivate::setBalance(unsigned)
218
unsigned KPhononCompactDiscPrivate::volume()
223
return (unsigned)(m_producerWidget->m_output->volume() * 100.0);
226
unsigned KPhononCompactDiscPrivate::balance()
231
void KPhononCompactDiscPrivate::queryMetadata()
238
QMultiMap<QString, QString> data = m_producerWidget->m_media->metaData();
239
kDebug() << "METADATA";
242
m_trackArtists[0] = data.take(QLatin1String( "ARTIST" ));
243
m_trackTitles[0] = data.take(QLatin1String( "ALBUM" ));
245
m_trackArtists[m_track] = data.take(QLatin1String( "ARTIST" ));
246
m_trackTitles[m_track] = data.take(QLatin1String( "TITLE" ));
248
emit q->discInformation(KCompactDisc::PhononMetadata);
251
KCompactDisc::DiscStatus KPhononCompactDiscPrivate::discStatusTranslate(Phonon::State state)
254
case Phonon::PlayingState:
255
return KCompactDisc::Playing;
256
case Phonon::PausedState:
257
return KCompactDisc::Paused;
258
case Phonon::StoppedState:
259
return KCompactDisc::Stopped;
260
case Phonon::ErrorState:
261
return KCompactDisc::NoDisc;
262
case Phonon::LoadingState:
263
case Phonon::BufferingState:
264
return KCompactDisc::NotReady;
266
return KCompactDisc::Error;
270
void KPhononCompactDiscPrivate::tick(qint64 t)
275
track = m_producerWidget->m_mediaController->currentTitle();
276
if(track != m_track) {
278
m_discLength = trackLength(m_track);
279
emit q->playoutTrackChanged(m_track);
281
/* phonon gives us Metadata only per Track */
286
m_trackPosition = MS2SEC(t);
287
m_discPosition = m_trackPosition;
288
// Update the current playing position.
290
kDebug() << "seek: " << m_seek << " trackPosition " << m_trackPosition;
291
if(abs((long)(m_trackExpectedPosition - m_trackPosition)) > m_seek)
294
m_seek = abs((long)(m_trackExpectedPosition - m_trackPosition));
298
emit q->playoutPositionChanged(m_trackPosition);
302
void KPhononCompactDiscPrivate::stateChanged(Phonon::State newstate, Phonon::State)
304
KCompactDisc::DiscStatus status;
307
status = discStatusTranslate(newstate);
309
if(m_status != status) {
310
if(skipStatusChange(status))
316
case KCompactDisc::Ejected:
317
case KCompactDisc::NoDisc:
322
m_tracks = m_producerWidget->m_mediaController->availableTitles();
324
kDebug() << "New disc with " << m_tracks << " tracks";
328
m_trackArtists.append(i18n("Unknown Artist"));
329
m_trackTitles.append(i18n("Unknown Title"));
330
for(unsigned i = 1; i <= m_tracks; i++) {
331
m_trackArtists.append(i18n("Unknown Artist"));
332
m_trackTitles.append(ki18n("Track %1").subs(i, 2).toString());
335
emit q->discChanged(m_tracks);
347
#include "phonon_interface.moc"