File indexing completed on 2024-04-21 04:48:09
0001 /* AUDEX CDDA EXTRACTOR 0002 * SPDX-FileCopyrightText: Copyright (C) 2007 Marco Nelles 0003 * <https://userbase.kde.org/Audex> 0004 * 0005 * SPDX-License-Identifier: GPL-3.0-or-later 0006 */ 0007 0008 #ifndef AUDEX_HEADER 0009 #define AUDEX_HEADER 0010 0011 #include <QDir> 0012 #include <QQueue> 0013 #include <QStorageInfo> 0014 #include <QString> 0015 #include <QTemporaryDir> 0016 #include <QTimer> 0017 0018 #include <KLocalizedString> 0019 0020 #include "models/cddamodel.h" 0021 #include "models/profilemodel.h" 0022 #include "utils/cddaextractthread.h" 0023 #include "utils/cuesheetwriter.h" 0024 #include "utils/discidcalculator.h" 0025 #include "utils/encoderwrapper.h" 0026 #include "utils/hashlist.h" 0027 #include "utils/parameters.h" 0028 #include "utils/playlist.h" 0029 #include "utils/schemeparser.h" 0030 #include "utils/upload.h" 0031 #include "utils/wavefilewriter.h" 0032 0033 #include "preferences.h" 0034 0035 class AudexJob : public QObject 0036 { 0037 Q_OBJECT 0038 public: 0039 explicit AudexJob(QObject *parent = nullptr) 0040 : QObject(parent) 0041 { 0042 source_filename = ""; 0043 target_filename = ""; 0044 _trackno = 0; 0045 } 0046 ~AudexJob() override 0047 { 0048 } 0049 void setSourceFilename(const QString &n) 0050 { 0051 source_filename = n; 0052 } 0053 QString sourceFilename() const 0054 { 0055 return source_filename; 0056 } 0057 void setTargetFilename(const QString &n) 0058 { 0059 target_filename = n; 0060 } 0061 QString targetFilename() const 0062 { 0063 return target_filename; 0064 } 0065 void setTrackNo(const int t) 0066 { 0067 _trackno = t; 0068 } 0069 int trackNo() const 0070 { 0071 return _trackno; 0072 } 0073 0074 private: 0075 QString source_filename; 0076 QString target_filename; 0077 int _trackno; 0078 }; 0079 0080 class AudexJobs : public QObject 0081 { 0082 Q_OBJECT 0083 public: 0084 explicit AudexJobs(QObject *parent = nullptr) 0085 : QObject(parent) 0086 { 0087 job_in_progress = false; 0088 } 0089 ~AudexJobs() override 0090 { 0091 for (int i = 0; i < cache.count(); i++) { 0092 // make really sure all files are away 0093 QFile file(cache.at(i)->sourceFilename()); 0094 if (file.exists()) 0095 file.remove(); 0096 delete cache.at(i); 0097 } 0098 } 0099 AudexJob *orderJob() 0100 { 0101 if (job_queue.isEmpty()) { 0102 return nullptr; 0103 } else { 0104 job_in_progress = true; 0105 return job_queue.dequeue(); 0106 } 0107 } 0108 void reportJobFinished() 0109 { 0110 job_in_progress = false; 0111 } 0112 bool jobInProgress() 0113 { 0114 return job_in_progress; 0115 } 0116 bool pendingJobs() 0117 { 0118 return (job_queue.count() > 0); 0119 } 0120 public Q_SLOTS: 0121 void addNewJob(const QString &sourceFilename, const QString &targetFilename, const int trackno) 0122 { 0123 auto *j = new AudexJob(); 0124 j->setSourceFilename(sourceFilename); 0125 j->setTargetFilename(targetFilename); 0126 j->setTrackNo(trackno); 0127 job_queue.enqueue(j); 0128 cache.append(j); 0129 Q_EMIT newJobAvailable(); 0130 } 0131 Q_SIGNALS: 0132 void newJobAvailable(); 0133 0134 private: 0135 QQueue<AudexJob *> job_queue; 0136 QList<AudexJob *> cache; 0137 bool job_in_progress; 0138 }; 0139 0140 class Audex : public QObject 0141 { 0142 Q_OBJECT 0143 0144 public: 0145 Audex(QWidget *parent, ProfileModel *profile_model, CDDAModel *cdda_model); 0146 ~Audex() override; 0147 0148 bool prepare(); 0149 0150 public Q_SLOTS: 0151 void start(); 0152 void cancel(); 0153 0154 const QStringList &extractLog(); 0155 const QStringList &encoderLog(); 0156 0157 private Q_SLOTS: 0158 void start_extract(); 0159 void finish_extract(); 0160 void start_encode(); 0161 void finish_encode(); 0162 0163 void calculate_speed_extract(); 0164 void calculate_speed_encode(); 0165 0166 void progress_extract(int percent_of_track, int sector, int overall_sectors_read); 0167 void progress_encode(int percent); 0168 0169 void write_to_wave(const QByteArray &data); 0170 0171 void slot_error(const QString &message, const QString &details = QString()); 0172 void slot_warning(const QString &message); 0173 void slot_info(const QString &message); 0174 0175 void check_if_thread_still_running(); 0176 0177 Q_SIGNALS: 0178 void changedExtractTrack(int no, int total, const QString &artist, const QString &title); 0179 void changedEncodeTrack(int no, int total, const QString &filename); 0180 0181 void progressExtractTrack(int percent); 0182 void progressExtractOverall(int percent); 0183 void progressEncodeTrack(int percent); 0184 void progressEncodeOverall(int percent); 0185 0186 void speedExtract(double times); 0187 void speedEncode(double times); 0188 0189 void finished(bool successful); 0190 0191 void timeout(); 0192 0193 void error(const QString &message, const QString &details = QString()); 0194 void warning(const QString &message); 0195 void info(const QString &message); 0196 0197 private: 0198 QWidget *parent; 0199 ProfileModel *profile_model; 0200 CDDAModel *cdda_model; 0201 EncoderWrapper *encoder_wrapper; 0202 CDDAExtractThread *cdda_extract_thread; 0203 AudexJobs *jobs; 0204 WaveFileWriter *wave_file_writer; 0205 QTemporaryDir tmp_dir; 0206 0207 QString p_profile_name; 0208 QString p_suffix; 0209 bool p_single_file; 0210 0211 bool construct_target_filename(QString &targetFilename, 0212 int trackno, 0213 int cdno, 0214 int nooftracks, 0215 int gindex, 0216 const QString &artist, 0217 const QString &title, 0218 const QString &tartist, 0219 const QString &ttitle, 0220 const QString &date, 0221 const QString &genre, 0222 const QString &isrc, 0223 const QString &ext, 0224 const QString &basepath, 0225 bool fat32_compatible, 0226 bool replacespaceswithunderscores, 0227 bool _2digitstracknum, 0228 bool overwrite_existing_files, 0229 bool is_first_track); 0230 0231 bool construct_target_filename_for_singlefile(QString &targetFilename, 0232 int cdno, 0233 int nooftracks, 0234 const QString &artist, 0235 const QString &title, 0236 const QString &date, 0237 const QString &genre, 0238 const QString &ext, 0239 const QString &basepath, 0240 bool overwrite_existing_files); 0241 0242 bool check(); 0243 0244 QString target_dir; 0245 0246 bool p_finished; 0247 bool p_finished_successful; 0248 void request_finish(bool successful); 0249 void execute_finish(); 0250 0251 int process_counter; 0252 bool timeout_done; 0253 int timeout_counter; 0254 0255 /*PROCESS 1: EXTRACTING*/ 0256 QString ex_track_source_filename; 0257 QString ex_track_target_filename; 0258 int ex_track_index; 0259 int ex_track_count; 0260 QTimer *timer_extract; 0261 int current_sector; 0262 int last_measuring_point_sector; 0263 int overall_frames; 0264 0265 /*PROCESS 2: ENCODING*/ 0266 QString en_track_filename; 0267 QString en_track_target_filename; 0268 int en_track_index; 0269 int en_track_count; 0270 QTimer *timer_encode; 0271 int current_encoder_percent; 0272 int last_measuring_point_encoder_percent; 0273 0274 bool p_prepare_dir(QString &filename, const QString &targetDirIfRelative, const bool overwrite = false); 0275 bool p_mkdir(const QString &absoluteFilePath); 0276 qreal p_size_of_all_files(const QStringList &filenames) const; 0277 }; 0278 0279 #endif