File indexing completed on 2024-04-21 04:54:25
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 } 0307 0308 #include "moc_kcompactdisc_p.cpp"