File indexing completed on 2022-09-27 14:37:22

0001 /*
0002  *  KCompactDisc - A CD drive interface for the KDE Project.
0003  *
0004  *  Copyright (C) 2007 Alexander Kern <alex.kern@gmx.de>
0005  *
0006  *  This program is free software; you can redistribute it and/or modify
0007  *  it under the terms of the GNU General Public License as published by
0008  *  the Free Software Foundation; either version 2, or (at your option)
0009  *  any later version.
0010  *
0011  *  This program is distributed in the hope that it will be useful,
0012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  *  GNU General Public License for more details.
0015  *
0016  *  You should have received a copy of the GNU General Public License
0017  *  along with this program; if not, write to the Free Software
0018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0019  */
0020 
0021 #include "kcompactdisc_p.h"
0022 
0023 #include "wmlib_interface.h"
0024 #include "phonon_interface.h"
0025 
0026 
0027 #include <KLocalizedString>
0028 
0029 Q_LOGGING_CATEGORY(CD_PLAYLIST, "cd.playlist")
0030 
0031 KCompactDiscPrivate::KCompactDiscPrivate(KCompactDisc *p, const QString& dev) :
0032     m_infoMode(KCompactDisc::Synchronous),
0033     m_deviceName(dev),
0034 
0035     m_status(KCompactDisc::NoDisc),
0036     m_statusExpected(KCompactDisc::NoDisc),
0037     m_discId(0),
0038     m_discLength(0),
0039     m_track(0),
0040     m_tracks(0),
0041     m_trackPosition(0),
0042     m_discPosition(0),
0043     m_trackExpectedPosition(0),
0044     m_seek(0),
0045 
0046     m_randSequence(QRandomGenerator::global()->generate()),
0047     m_loopPlaylist(false),
0048     m_randomPlaylist(false),
0049     m_autoMetadata(true),
0050 
0051     m_deviceVendor(QString()),
0052     m_deviceModel(QString()),
0053     m_deviceRevision(QString()),
0054 
0055     q_ptr(p)
0056 {
0057     m_interface = QLatin1String("dummy");
0058     m_trackStartFrames.clear();
0059     m_trackArtists.clear();
0060     m_trackTitles.clear();
0061     m_playlist.clear();
0062 }
0063 
0064 bool KCompactDiscPrivate::moveInterface(const QString &deviceName,
0065     const QString &audioSystem, const QString &audioDevice)
0066 {
0067     Q_Q(KCompactDisc);
0068 
0069     KCompactDiscPrivate *pOld, *pNew;
0070 
0071     qDebug() << "switch from " << q->d_ptr->m_interface << " on " << q->d_ptr->m_deviceName;
0072     qDebug() << "         to " << audioSystem << " on " << deviceName;
0073 
0074     /* switch temporary to dummy implementation */
0075     if(q->d_ptr != this) {
0076         pOld = q->d_ptr;
0077         q->d_ptr = this;
0078         delete pOld;
0079     }
0080 
0081 #ifdef USE_WMLIB
0082     if(audioSystem == QLatin1String("phonon"))
0083 #endif
0084         pNew = new KPhononCompactDiscPrivate(q, deviceName);
0085 #ifdef USE_WMLIB
0086     else
0087         pNew = new KWMLibCompactDiscPrivate(q, deviceName,
0088             audioSystem, audioDevice);
0089 #endif
0090 
0091     pNew->m_infoMode = m_infoMode;
0092 
0093     if(pNew->createInterface()) {
0094         q->d_ptr = pNew;
0095         return true;
0096     } else {
0097         delete pNew;
0098         return false;
0099     }
0100 }
0101 
0102 bool KCompactDiscPrivate::createInterface()
0103 {
0104     return true;
0105 }
0106 
0107 void KCompactDiscPrivate::make_playlist()
0108 {
0109     /* koz: 15/01/00. I want a random list that does not repeat tracks. Ie, */
0110     /* a list is created in which each track is listed only once. The tracks */
0111     /* are picked off one by one until the end of the list */
0112 
0113     unsigned selected = 0, size = m_tracks;
0114     bool rejected = false;
0115 
0116     qCDebug(CD_PLAYLIST) << "Playlist has " << size << " entries\n";
0117     m_playlist.clear();
0118     for(unsigned i = 0; i < size; ++i) {
0119         if(m_randomPlaylist) {
0120             do {
0121                 selected = 1 + m_randSequence.bounded(size);
0122                 rejected = (m_playlist.indexOf(selected) != -1);
0123             } while(rejected == true);
0124         } else {
0125             selected = 1 + i;
0126         }
0127         m_playlist.append(selected);
0128     }
0129 
0130     qCDebug(CD_PLAYLIST) << "dump playlist";
0131     QList<unsigned>::const_iterator it;
0132     for(it = m_playlist.constBegin(); it != m_playlist.constEnd(); ++it) {
0133         qCDebug(CD_PLAYLIST) << " " << *it;
0134     }
0135     qCDebug(CD_PLAYLIST) << "dump playlist end";
0136 }
0137 
0138 unsigned KCompactDiscPrivate::getNextTrackInPlaylist()
0139 {
0140     int current_index, min_index, max_index;
0141 
0142     if(m_playlist.empty())
0143         return 0;
0144 
0145     min_index = 0;
0146     max_index = m_playlist.size() - 1;
0147 
0148     current_index = m_playlist.indexOf(m_track);
0149     if(current_index < 0)
0150         current_index = min_index;
0151     else if(current_index >= max_index) {
0152         if(m_loopPlaylist) {
0153             //wrap around
0154             if(m_randomPlaylist)
0155                 make_playlist();
0156             current_index = min_index;
0157         } else {
0158             return 0;
0159         }
0160     } else {
0161         ++current_index;
0162     }
0163 
0164     return m_playlist[current_index];
0165 }
0166 
0167 unsigned KCompactDiscPrivate::getPrevTrackInPlaylist()
0168 {
0169     int current_index, min_index, max_index;
0170 
0171     if(m_playlist.empty())
0172         return 0;
0173 
0174     min_index = 0;
0175     max_index = m_playlist.size() - 1;
0176 
0177     current_index = m_playlist.indexOf(m_track);
0178     if(current_index < 0)
0179         current_index = min_index;
0180     else if(current_index <= min_index) {
0181         if(m_loopPlaylist) {
0182             //wrap around
0183             if(m_randomPlaylist)
0184                 make_playlist();
0185 
0186             current_index = max_index;
0187         } else {
0188             return 0;
0189         }
0190     } else {
0191         --current_index;
0192     }
0193 
0194     return m_playlist[current_index];
0195 }
0196 
0197 bool KCompactDiscPrivate::skipStatusChange(KCompactDisc::DiscStatus status)
0198 {
0199     Q_Q(KCompactDisc);
0200 
0201     if(m_status != status) {
0202         if(status == KCompactDisc::Stopped) {
0203             if(m_statusExpected == KCompactDisc::Ejected) {
0204                 eject();
0205             } else if(m_statusExpected != KCompactDisc::Stopped) {
0206                 unsigned track = getNextTrackInPlaylist();
0207                 if(track) {
0208                     playTrackPosition(track, 0);
0209                     return true;
0210                 }
0211             }
0212         }
0213 
0214         Q_EMIT q->discStatusChanged(status);
0215     }
0216 
0217     return false;
0218 }
0219 
0220 const QString KCompactDiscPrivate::discStatusI18n(KCompactDisc::DiscStatus status)
0221 {
0222     switch (status) {
0223     case KCompactDisc::Playing:
0224         return i18n("Playing");
0225     case KCompactDisc::Paused:
0226         return i18n("Paused");
0227     case KCompactDisc::Stopped:
0228         return i18n("Stopped");
0229     case KCompactDisc::Ejected:
0230         return i18n("Ejected");
0231     case KCompactDisc::NoDisc:
0232         return i18n("No Disc");
0233     case KCompactDisc::NotReady:
0234         return i18n("Not Ready");
0235     case KCompactDisc::Error:
0236     default:
0237         return i18n("Error");
0238     }
0239 }
0240 
0241 void KCompactDiscPrivate::clearDiscInfo()
0242 {
0243     Q_Q(KCompactDisc);
0244 
0245     m_discId = 0;
0246     m_discLength = 0;
0247     m_seek = 0;
0248     m_track = 0;
0249     m_tracks = 0;
0250     m_trackArtists.clear();
0251     m_trackTitles.clear();
0252     m_trackStartFrames.clear();
0253     Q_EMIT q->discChanged(m_tracks);
0254 }
0255 
0256 unsigned KCompactDiscPrivate::trackLength(unsigned)
0257 {
0258     return 0;
0259 }
0260 
0261 bool KCompactDiscPrivate::isTrackAudio(unsigned)
0262 {
0263     return false;
0264 }
0265 
0266 void KCompactDiscPrivate::playTrackPosition(unsigned, unsigned)
0267 {
0268 }
0269 
0270 void KCompactDiscPrivate::pause()
0271 {
0272 }
0273 
0274 void KCompactDiscPrivate::stop()
0275 {
0276 }
0277 
0278 void KCompactDiscPrivate::eject()
0279 {
0280 }
0281 
0282 void KCompactDiscPrivate::closetray()
0283 {
0284 }
0285 
0286 void KCompactDiscPrivate::setVolume(unsigned)
0287 {
0288 }
0289 
0290 void KCompactDiscPrivate::setBalance(unsigned)
0291 {
0292 }
0293 
0294 unsigned KCompactDiscPrivate::volume()
0295 {
0296     return 0;
0297 }
0298 
0299 unsigned KCompactDiscPrivate::balance()
0300 {
0301     return 50;
0302 }
0303 
0304 void KCompactDiscPrivate::queryMetadata()
0305 {
0306 }