1 /*
2 * Cantata
3 *
4 * Copyright (c) 2011-2020 Craig Drummond <craig.p.drummond@gmail.com>
5 *
6 * ----
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24 #include "albumscanner.h"
25 #include "config.h"
26 #include <QProcess>
27 #include <QApplication>
28
AlbumScanner(const QMap<int,QString> & files)29 AlbumScanner::AlbumScanner(const QMap<int, QString> &files)
30 : proc(0)
31 {
32 QMap<int, QString>::ConstIterator it=files.constBegin();
33 QMap<int, QString>::ConstIterator end=files.constEnd();
34
35 for (int i=0; it!=end; ++it, ++i) {
36 fileNames.append(it.value());
37 trackIndexMap[i]=it.key();
38 }
39 }
40
~AlbumScanner()41 AlbumScanner::~AlbumScanner()
42 {
43 stop();
44 }
45
start()46 void AlbumScanner::start()
47 {
48 if (!proc) {
49 proc=new QProcess(this);
50 proc->setProcessChannelMode(QProcess::MergedChannels);
51 proc->setReadChannel(QProcess::StandardOutput);
52 connect(proc, SIGNAL(finished(int)), this, SLOT(procFinished()));
53 connect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(read()));
54 proc->start(Utils::helper(QLatin1String("cantata-replaygain")), fileNames, QProcess::ReadOnly);
55 }
56 }
57
stop()58 void AlbumScanner::stop()
59 {
60 if (proc) {
61 disconnect(proc, SIGNAL(finished(int)), this, SLOT(procFinished()));
62 disconnect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(read()));
63 proc->terminate();
64 proc->deleteLater();
65 proc=0;
66 }
67 }
68
69 static const QString constProgLine=QLatin1String("PROGRESS: ");
70 static const QString constTrackLine=QLatin1String("TRACK: ");
71 static const QString constAlbumLine=QLatin1String("ALBUM: ");
72
read()73 void AlbumScanner::read()
74 {
75 if (!proc) {
76 return;
77 }
78
79 QString output = proc->readAllStandardOutput().data();
80 if (output.isEmpty()) {
81 return;
82 }
83
84 QStringList lines=output.split("\n", QString::SkipEmptyParts);
85
86 for (const QString &line: lines) {
87 if (line.startsWith(constProgLine)) {
88 emit progress(line.mid(constProgLine.length()).toUInt());
89 } else if (line.startsWith(constTrackLine)) {
90 QStringList parts=line.mid(constTrackLine.length()).split(" ", QString::SkipEmptyParts);
91 if (!parts.isEmpty()) {
92 int num=parts[0].toUInt();
93 Values vals;
94 if (parts.length()>=3) {
95 vals.gain=parts[1].toDouble();
96 vals.peak=parts[2].toDouble();
97 vals.ok=true;
98 }
99 tracks[trackIndexMap[num]]=vals;
100 }
101 } else if (line.startsWith(constAlbumLine)) {
102 QStringList parts=line.mid(constAlbumLine.length()).split(" ", QString::SkipEmptyParts);
103 if (parts.length()>=2) {
104 album.gain=parts[0].toDouble();
105 album.peak=parts[1].toDouble();
106 album.ok=true;
107 }
108 }
109 }
110 }
111
procFinished()112 void AlbumScanner::procFinished()
113 {
114 setFinished(true);
115 emit done();
116 }
117
118 #include "moc_albumscanner.cpp"
119