Overview
Submit package home:develop7:branches:Multimedia / flacon to package Multimedia / flacon
flacon.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Sun Sep 3 11:10:30 UTC 2017 - develop7@develop7.info
4
+
5
+- Update to 3.1.1
6
+ * Fix: The application incorrectly worked with large duration disks.
7
+ * Translations updated
8
+ * Small fixes
9
+
10
+- Update to 3.0.0
11
+ * Shntool is outdated (not updated since 2009) and caused a lot of problems.
12
+ Now the Flacon does not use it, and we hope that the amount of problems
13
+ will decrease.
14
+ * Use Qt5 by default
15
+ * Fix: Sometimes the program was crashed when removing a disc from the
16
+ project.
17
+ * Fix: Flacon doesn’t recognize when external tools are removed
18
+ * Translations updated
19
+ * Small fixes
20
+-------------------------------------------------------------------
21
Mon Jan 2 19:38:40 UTC 2017 - lazy.kent@opensuse.org
22
23
- Update to 2.1.1.
24
flacon.spec
Changed
18
1
2
3
4
Name: flacon
5
-Version: 2.1.1
6
+Version: 3.1.1
7
Release: 0
8
Summary: Split compressed Audio CD images to tracks
9
License: LGPL-2.1+
10
11
Requires: flac
12
Requires: lame
13
Requires: mac
14
-Requires: shntool
15
Requires: ttaenc
16
Requires: vorbis-tools
17
Requires: wavpack
18
flacon-2.1.1.tar.gz/outformats
Deleted
2
1
-(directory)
2
flacon-2.1.1.tar.gz/outformats/flac.cpp
Deleted
177
1
2
-/* BEGIN_COMMON_COPYRIGHT_HEADER
3
- * (c)LGPL2+
4
- *
5
- * Flacon - audio File Encoder
6
- * https://github.com/flacon/flacon
7
- *
8
- * Copyright: 2012-2013
9
- * Alexander Sokoloff <sokoloff.a@gmail.com>
10
- *
11
- * This library is free software; you can redistribute it and/or
12
- * modify it under the terms of the GNU Lesser General Public
13
- * License as published by the Free Software Foundation; either
14
- * version 2.1 of the License, or (at your option) any later version.
15
-
16
- * This library is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
- * Lesser General Public License for more details.
20
-
21
- * You should have received a copy of the GNU Lesser General Public
22
- * License along with this library; if not, write to the Free Software
23
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
- *
25
- * END_COMMON_COPYRIGHT_HEADER */
26
-
27
-
28
-#include "flac.h"
29
-#include "settings.h"
30
-#include "project.h"
31
-#include "inputaudiofile.h"
32
-
33
-#include <QDebug>
34
-
35
-OutFormat_Flac::OutFormat_Flac()
36
-{
37
- mId = "FLAC";
38
- mExt = "flac";
39
- mName = "Flac";
40
-}
41
-
42
-
43
-
44
-/************************************************
45
-
46
- ************************************************/
47
-bool OutFormat_Flac::check(QStringList *errors) const
48
-{
49
- bool res = OutFormat::check(errors);
50
-
51
- if (gainType() != OutFormat::GainDisable)
52
- {
53
- for (int i=0; i<project->count(); ++i)
54
- {
55
- if (project->disk(i)->audioFile()->sampleRate() > 48000)
56
- {
57
- *errors << QObject::tr("you can't use 'ReplayGain' for files with sample rates above 48kHz. Metaflac doesn't support such files.",
58
- "This string should begin with a lowercase letter. This is a part of the complex sentence.");
59
- res = false;
60
- break;
61
- }
62
- }
63
- }
64
-
65
- return res;
66
-}
67
-
68
-
69
-/************************************************
70
-
71
- ************************************************/
72
-QStringList OutFormat_Flac::encoderArgs(Track *track, const QString &outFile) const
73
-{
74
- QStringList args;
75
-
76
- args << settings->programName(encoderProgramName());
77
- args << "--force"; // Force overwriting of output files.
78
- args << "--silent"; // Suppress progress indicator
79
-
80
- // Settings .................................................
81
- args << QString("--compression-level-%1").arg(settings->value("Flac/Compression").toString());
82
-
83
-
84
- // Tags .....................................................
85
- if (!track->artist().isEmpty()) args << "--tag" << QString("artist=%1").arg(track->artist());
86
- if (!track->album().isEmpty()) args << "--tag" << QString("album=%1").arg(track->album());
87
- if (!track->genre().isEmpty()) args << "--tag" << QString("genre=%1").arg(track->genre());
88
- if (!track->date().isEmpty()) args << "--tag" << QString("date=%1").arg(track->date());
89
- if (!track->title().isEmpty()) args << "--tag" << QString("title=%1").arg(track->title());
90
- if (!track->comment().isEmpty()) args << "--tag" << QString("comment=%1").arg(track->comment());
91
- if (!track->disk()->discId().isEmpty()) args << "--tag" << QString("discId=%1").arg(track->disk()->discId());
92
- args << "--tag" << QString("TRACKNUMBER=%1").arg(track->trackNum());
93
- args << "--tag" << QString("TOTALTRACKS=%1").arg(track->disk()->count());
94
- args << "--tag" << QString("TRACKTOTAL=%1").arg(track->disk()->count());
95
-
96
-
97
- args << "-";
98
- args << "-o" << outFile;
99
- return args;
100
-}
101
-
102
-
103
-/************************************************
104
-
105
- ************************************************/
106
-QStringList OutFormat_Flac::gainArgs(const QStringList &files) const
107
-{
108
- QStringList args;
109
- args << settings->programName(gainProgramName());
110
- args << "--add-replay-gain";
111
- args << files;
112
-
113
- return args;
114
-}
115
-
116
-
117
-/************************************************
118
-
119
- ************************************************/
120
-QHash<QString, QVariant> OutFormat_Flac::defaultParameters() const
121
-{
122
- QHash<QString, QVariant> res;
123
- res.insert("Flac/Compression", 5);
124
- res.insert("Flac/ReplayGain", gainTypeToString(GainDisable));
125
- return res;
126
-}
127
-
128
-
129
-/************************************************
130
-
131
- ************************************************/
132
-EncoderConfigPage *OutFormat_Flac::configPage(QWidget *parent) const
133
-{
134
- return new ConfigPage_Flac(parent);
135
-}
136
-
137
-
138
-/************************************************
139
-
140
- ************************************************/
141
-ConfigPage_Flac::ConfigPage_Flac(QWidget *parent):
142
- EncoderConfigPage(parent)
143
-{
144
- setupUi(this);
145
-
146
- setLosslessToolTip(flacCompressionSlider);
147
- flacCompressionSpin->setToolTip(flacCompressionSlider->toolTip());
148
- fillReplayGainComboBox(flacGainCbx);
149
-}
150
-
151
-
152
-/************************************************
153
-
154
- ************************************************/
155
-void ConfigPage_Flac::load()
156
-{
157
- loadWidget("Flac/Compression", flacCompressionSlider);
158
- loadWidget("Flac/ReplayGain", flacGainCbx);
159
-}
160
-
161
-
162
-/************************************************
163
-
164
- ************************************************/
165
-void ConfigPage_Flac::write()
166
-{
167
- writeWidget("Flac/Compression", flacCompressionSlider);
168
- writeWidget("Flac/ReplayGain", flacGainCbx);
169
-}
170
-
171
-
172
-
173
-
174
-
175
-
176
-
177
flacon-2.1.1.tar.gz/outformats/flac.h
Deleted
64
1
2
-/* BEGIN_COMMON_COPYRIGHT_HEADER
3
- * (c)LGPL2+
4
- *
5
- * Flacon - audio File Encoder
6
- * https://github.com/flacon/flacon
7
- *
8
- * Copyright: 2012-2013
9
- * Alexander Sokoloff <sokoloff.a@gmail.com>
10
- *
11
- * This library is free software; you can redistribute it and/or
12
- * modify it under the terms of the GNU Lesser General Public
13
- * License as published by the Free Software Foundation; either
14
- * version 2.1 of the License, or (at your option) any later version.
15
-
16
- * This library is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
- * Lesser General Public License for more details.
20
-
21
- * You should have received a copy of the GNU Lesser General Public
22
- * License along with this library; if not, write to the Free Software
23
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
- *
25
- * END_COMMON_COPYRIGHT_HEADER */
26
-
27
-
28
-#ifndef FLAC_H
29
-#define FLAC_H
30
-
31
-#include "outformat.h"
32
-#include "configdialog.h"
33
-#include "ui_flac_config.h"
34
-
35
-class OutFormat_Flac: public OutFormat
36
-{
37
-public:
38
- OutFormat_Flac();
39
- bool check(QStringList *errors) const;
40
-
41
- virtual QString encoderProgramName() const { return "flac"; }
42
- virtual QString gainProgramName() const { return "metaflac"; }
43
-
44
- virtual QStringList encoderArgs(Track *track, const QString &outFile) const;
45
- virtual QStringList gainArgs(const QStringList &files) const;
46
-
47
- QHash<QString, QVariant> defaultParameters() const;
48
- EncoderConfigPage *configPage(QWidget *parent = 0) const;
49
-};
50
-
51
-
52
-class ConfigPage_Flac: public EncoderConfigPage, private Ui::ConfigPage_Flac
53
-{
54
- Q_OBJECT
55
-public:
56
- explicit ConfigPage_Flac(QWidget *parent = 0);
57
-
58
- virtual void load();
59
- virtual void write();
60
-
61
-};
62
-
63
-#endif // FLAC_H
64
flacon-2.1.1.tar.gz/outformats/wav.cpp
Deleted
140
1
2
-/* BEGIN_COMMON_COPYRIGHT_HEADER
3
- * (c)LGPL2+
4
- *
5
- * Flacon - audio File Encoder
6
- * https://github.com/flacon/flacon
7
- *
8
- * Copyright: 2012-2013
9
- * Alexander Sokoloff <sokoloff.a@gmail.com>
10
- *
11
- * This library is free software; you can redistribute it and/or
12
- * modify it under the terms of the GNU Lesser General Public
13
- * License as published by the Free Software Foundation; either
14
- * version 2.1 of the License, or (at your option) any later version.
15
-
16
- * This library is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
- * Lesser General Public License for more details.
20
-
21
- * You should have received a copy of the GNU Lesser General Public
22
- * License along with this library; if not, write to the Free Software
23
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
- *
25
- * END_COMMON_COPYRIGHT_HEADER */
26
-
27
-
28
-#include "wav.h"
29
-#include <QFile>
30
-
31
-
32
-/************************************************
33
-
34
- ************************************************/
35
-OutFormat_Wav::OutFormat_Wav()
36
-{
37
- mId = "WAV";
38
- mExt = "wav";
39
- mName = "WAV";
40
-}
41
-
42
-
43
-/************************************************
44
-
45
- ************************************************/
46
-QStringList OutFormat_Wav::encoderArgs(Track *track, const QString &outFile) const
47
-{
48
- return QStringList();
49
-}
50
-
51
-
52
-/************************************************
53
-
54
- ************************************************/
55
-QStringList OutFormat_Wav::gainArgs(const QStringList &files) const
56
-{
57
- return QStringList();
58
-}
59
-
60
-
61
-/************************************************
62
-
63
- ************************************************/
64
-Encoder *OutFormat_Wav::createEncoder(Track *track, QObject *parent) const
65
-{
66
- return new Encoder_Wav(this, track, parent);
67
-}
68
-
69
-
70
-/************************************************
71
-
72
- ************************************************/
73
-Gain *OutFormat_Wav::createGain(Disk *disk, Track *track, QObject *parent) const
74
-{
75
- return 0;
76
-}
77
-
78
-
79
-/************************************************
80
-
81
- ************************************************/
82
-QHash<QString, QVariant> OutFormat_Wav::defaultParameters() const
83
-{
84
- QHash<QString, QVariant> res;
85
- return res;
86
-}
87
-
88
-
89
-/************************************************
90
-
91
- ************************************************/
92
-EncoderConfigPage *OutFormat_Wav::configPage(QWidget *parent) const
93
-{
94
- return 0;
95
-}
96
-
97
-
98
-/************************************************
99
-
100
- ************************************************/
101
-Encoder_Wav::Encoder_Wav(const OutFormat *format, Track *track, QObject *parent):
102
- Encoder(format, track, parent)
103
-{
104
-}
105
-
106
-
107
-/************************************************
108
-
109
- ************************************************/
110
-void Encoder_Wav::doRun()
111
-{
112
- QFile srcFile(inputFile());
113
- QFile destFile(outFile());
114
-
115
- bool res = (!destFile.exists() || destFile.remove());
116
-
117
- if (res)
118
- res = srcFile.rename(outFile());
119
-
120
- if (!res)
121
- {
122
- error(track(),
123
- tr("I can't rename file:\n%1 to %2\n%3").arg(
124
- inputFile(),
125
- outFile(),
126
- srcFile.errorString()));
127
- }
128
-}
129
-
130
-
131
-/************************************************
132
-
133
- ************************************************/
134
-QStringList Encoder_Wav::processArgs() const
135
-{
136
- return QStringList();
137
-}
138
-
139
-
140
flacon-2.1.1.tar.gz/outformats/wav.h
Deleted
68
1
2
-/* BEGIN_COMMON_COPYRIGHT_HEADER
3
- * (c)LGPL2+
4
- *
5
- * Flacon - audio File Encoder
6
- * https://github.com/flacon/flacon
7
- *
8
- * Copyright: 2012-2013
9
- * Alexander Sokoloff <sokoloff.a@gmail.com>
10
- *
11
- * This library is free software; you can redistribute it and/or
12
- * modify it under the terms of the GNU Lesser General Public
13
- * License as published by the Free Software Foundation; either
14
- * version 2.1 of the License, or (at your option) any later version.
15
-
16
- * This library is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
- * Lesser General Public License for more details.
20
-
21
- * You should have received a copy of the GNU Lesser General Public
22
- * License along with this library; if not, write to the Free Software
23
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
- *
25
- * END_COMMON_COPYRIGHT_HEADER */
26
-
27
-
28
-#ifndef WAV_H
29
-#define WAV_H
30
-
31
-#include "outformat.h"
32
-#include "encoder.h"
33
-
34
-class OutFormat_Wav: public OutFormat
35
-{
36
-public:
37
- OutFormat_Wav();
38
-
39
- virtual QString encoderProgramName() const { return ""; }
40
- virtual QString gainProgramName() const { return ""; }
41
-
42
- virtual QStringList encoderArgs(Track *track, const QString &outFile) const;
43
- virtual QStringList gainArgs(const QStringList &files) const;
44
-
45
-
46
- QHash<QString, QVariant> defaultParameters() const;
47
- EncoderConfigPage *configPage(QWidget *parent = 0) const;
48
-
49
- virtual bool hasConfigPage() const { return false; }
50
-
51
- virtual Encoder *createEncoder(Track *track, QObject *parent = 0) const;
52
- virtual Gain *createGain(Disk *disk, Track *track, QObject *parent = 0) const;
53
-};
54
-
55
-
56
-class Encoder_Wav: public Encoder
57
-{
58
- Q_OBJECT
59
-public:
60
- explicit Encoder_Wav(const OutFormat *format, Track *track, QObject *parent = 0);
61
-
62
-protected:
63
- void doRun();
64
- virtual QStringList processArgs() const;
65
-};
66
-
67
-#endif // WAV_H
68
flacon-2.1.1.tar.gz/outformats/wv.cpp
Deleted
146
1
2
-/* BEGIN_COMMON_COPYRIGHT_HEADER
3
- * (c)LGPL2+
4
- *
5
- * Flacon - audio File Encoder
6
- * https://github.com/flacon/flacon
7
- *
8
- * Copyright: 2012-2013
9
- * Alexander Sokoloff <sokoloff.a@gmail.com>
10
- *
11
- * This library is free software; you can redistribute it and/or
12
- * modify it under the terms of the GNU Lesser General Public
13
- * License as published by the Free Software Foundation; either
14
- * version 2.1 of the License, or (at your option) any later version.
15
-
16
- * This library is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
- * Lesser General Public License for more details.
20
-
21
- * You should have received a copy of the GNU Lesser General Public
22
- * License along with this library; if not, write to the Free Software
23
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
- *
25
- * END_COMMON_COPYRIGHT_HEADER */
26
-
27
-
28
-#include "wv.h"
29
-#include "settings.h"
30
-#include <QDebug>
31
-
32
-/************************************************
33
-
34
- ************************************************/
35
-OutFormat_Wv::OutFormat_Wv()
36
-{
37
- mId = "WV";
38
- mExt = "wv";
39
- mName = "WavPack";
40
-}
41
-
42
-
43
-/************************************************
44
-
45
- ************************************************/
46
-QStringList OutFormat_Wv::encoderArgs(Track *track, const QString &outFile) const
47
-{
48
- QStringList args;
49
-
50
- args << settings->programName(encoderProgramName());
51
-
52
- args << "-q"; // Suppress progress indicator
53
-
54
- // Settings .................................................
55
- int compression = settings->value("WV/Compression").toInt();
56
- if (compression == 0) args << "-f";
57
- if (compression == 1) args << "-h";
58
- if (compression == 2) args << "-hh";
59
-
60
- // Tags .....................................................
61
- if (!track->artist().isEmpty()) args << "-w" << QString("Artist=%1").arg(track->artist());
62
- if (!track->album().isEmpty()) args << "-w" << QString("Album=%1").arg(track->album());
63
- if (!track->genre().isEmpty()) args << "-w" << QString("Genre=%1").arg(track->genre());
64
- if (!track->date().isEmpty()) args << "-w" << QString("Year=%1").arg(track->date());
65
- if (!track->title().isEmpty()) args << "-w" << QString("Title=%1").arg(track->title());
66
- if (!track->disk()->discId().isEmpty()) args << "-w" << QString("DiscId=%1").arg(track->disk()->discId());
67
- if (!track->comment().isEmpty()) args << "-w" << QString("Comment=%1").arg(track->comment());
68
- args << "-w" << QString("Track=%1/%2").arg(track->trackNum()).arg(track->disk()->count());
69
-
70
- args << "-";
71
- args << "-o" << outFile;
72
-
73
- return args;
74
-}
75
-
76
-
77
-/************************************************
78
-
79
- ************************************************/
80
-QStringList OutFormat_Wv::gainArgs(const QStringList &files) const
81
-{
82
- QStringList args;
83
- args << args << settings->programName(gainProgramName());
84
- args << "-a";
85
- args << files;
86
-
87
- return args;
88
-}
89
-
90
-
91
-/************************************************
92
-
93
- ************************************************/
94
-QHash<QString, QVariant> OutFormat_Wv::defaultParameters() const
95
-{
96
- QHash<QString, QVariant> res;
97
- res.insert("WV/Compression", 1);
98
- res.insert("WV/ReplayGain", gainTypeToString(GainDisable));
99
- return res;
100
-}
101
-
102
-
103
-/************************************************
104
-
105
- ************************************************/
106
-EncoderConfigPage *OutFormat_Wv::configPage(QWidget *parent) const
107
-{
108
- return new ConfigPage_Wv(parent);
109
-}
110
-
111
-
112
-/************************************************
113
-
114
- ************************************************/
115
-ConfigPage_Wv::ConfigPage_Wv(QWidget *parent):
116
- EncoderConfigPage(parent)
117
-{
118
- setupUi(this);
119
-
120
- setLosslessToolTip(wvCompressionSlider);
121
- wvCompressionSpin->setToolTip(wvCompressionSlider->toolTip());
122
- fillReplayGainComboBox(wvGainCbx);
123
-}
124
-
125
-
126
-/************************************************
127
-
128
- ************************************************/
129
-void ConfigPage_Wv::load()
130
-{
131
- loadWidget("WV/Compression", wvCompressionSlider);
132
- loadWidget("WV/ReplayGain", wvGainCbx);
133
-}
134
-
135
-
136
-/************************************************
137
-
138
- ************************************************/
139
-void ConfigPage_Wv::write()
140
-{
141
- writeWidget("WV/Compression", wvCompressionSlider);
142
- writeWidget("WV/ReplayGain", wvGainCbx);
143
-}
144
-
145
-
146
flacon-2.1.1.tar.gz/outformats/wv.h
Deleted
62
1
2
-/* BEGIN_COMMON_COPYRIGHT_HEADER
3
- * (c)LGPL2+
4
- *
5
- * Flacon - audio File Encoder
6
- * https://github.com/flacon/flacon
7
- *
8
- * Copyright: 2012-2013
9
- * Alexander Sokoloff <sokoloff.a@gmail.com>
10
- *
11
- * This library is free software; you can redistribute it and/or
12
- * modify it under the terms of the GNU Lesser General Public
13
- * License as published by the Free Software Foundation; either
14
- * version 2.1 of the License, or (at your option) any later version.
15
-
16
- * This library is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
- * Lesser General Public License for more details.
20
-
21
- * You should have received a copy of the GNU Lesser General Public
22
- * License along with this library; if not, write to the Free Software
23
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
- *
25
- * END_COMMON_COPYRIGHT_HEADER */
26
-
27
-
28
-#ifndef WV_H
29
-#define WV_H
30
-
31
-#include "outformat.h"
32
-#include "configdialog.h"
33
-#include "ui_wv_config.h"
34
-
35
-class OutFormat_Wv: public OutFormat
36
-{
37
-public:
38
- OutFormat_Wv();
39
-
40
- virtual QString encoderProgramName() const { return "wavpack"; }
41
- virtual QString gainProgramName() const { return "wvgain"; }
42
-
43
- virtual QStringList encoderArgs(Track *track, const QString &outFile) const;
44
- virtual QStringList gainArgs(const QStringList &files) const;
45
-
46
- QHash<QString, QVariant> defaultParameters() const;
47
- EncoderConfigPage *configPage(QWidget *parent = 0) const;
48
-};
49
-
50
-
51
-class ConfigPage_Wv: public EncoderConfigPage, private Ui::ConfigPage_Wv
52
-{
53
- Q_OBJECT
54
-public:
55
- explicit ConfigPage_Wv(QWidget *parent = 0);
56
-
57
- virtual void load();
58
- virtual void write();
59
-};
60
-
61
-#endif // WV_H
62
flacon-2.1.1.tar.gz/.travis.yml -> flacon-3.1.1.tar.gz/.travis.yml
Changed
15
1
2
- clang
3
4
install:
5
- - sudo apt-get update
6
- - sudo apt-get install cmake libqt4-dev libuchardet-dev shntool ffmpeg xvfb
7
+ - sudo apt-get -y update
8
+ - sudo apt-get -y install cmake libqt4-dev libuchardet-dev shntool xvfb python-software-properties
9
+ - sudo add-apt-repository -y ppa:flacon
10
+ - sudo apt-get -y update
11
+ - sudo apt-get -y install flac mac vorbis-tools wavpack lame vorbisgain mp3gain ttaenc
12
13
script:
14
- mkdir build
15
flacon-2.1.1.tar.gz/CMakeLists.txt -> flacon-3.1.1.tar.gz/CMakeLists.txt
Changed
172
1
2
3
project(flacon)
4
5
-set(MAJOR_VERSION 2)
6
+set(MAJOR_VERSION 3)
7
set(MINOR_VERSION 1)
8
set(PATCH_VERSION 1)
9
set(FLACON_VERSION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION})
10
11
gui/aboutdialog/translatorsinfo.h
12
gui/cuediskselectdialog/cuediskselectdialog.h
13
14
+ converter/wavheader.h
15
+ converter/decoder.h
16
converter/converterthread.h
17
converter/converter.h
18
converter/splitter.h
19
converter/encoder.h
20
converter/gain.h
21
22
- outformats/outformat.h
23
- outformats/aac.h
24
- outformats/flac.h
25
- outformats/mp3.h
26
- outformats/ogg.h
27
- outformats/wav.h
28
- outformats/wv.h
29
- outformats/opus.h
30
+ formats/format.h
31
+ formats/outformat.h
32
+ formats/aac.h
33
+ formats/flac.h
34
+ formats/mp3.h
35
+ formats/ogg.h
36
+ formats/wav.h
37
+ formats/wv.h
38
+ formats/opus.h
39
+ formats/ape.h
40
+ formats/tta.h
41
)
42
43
set(SOURCES
44
45
gui/aboutdialog/translatorsinfo.cpp
46
gui/cuediskselectdialog/cuediskselectdialog.cpp
47
48
+ converter/wavheader.cpp
49
+ converter/decoder.cpp
50
converter/converterthread.cpp
51
converter/converter.cpp
52
converter/splitter.cpp
53
converter/encoder.cpp
54
converter/gain.cpp
55
56
- outformats/outformat.cpp
57
- outformats/aac.cpp
58
- outformats/flac.cpp
59
- outformats/mp3.cpp
60
- outformats/ogg.cpp
61
- outformats/wav.cpp
62
- outformats/wv.cpp
63
- outformats/opus.cpp
64
+ formats/format.cpp
65
+ formats/outformat.cpp
66
+ formats/aac.cpp
67
+ formats/flac.cpp
68
+ formats/mp3.cpp
69
+ formats/ogg.cpp
70
+ formats/wav.cpp
71
+ formats/wv.cpp
72
+ formats/opus.cpp
73
+ formats/ape.cpp
74
+ formats/tta.cpp
75
)
76
77
set (MOCS
78
79
gui/aboutdialog/aboutdialog.h
80
gui/cuediskselectdialog/cuediskselectdialog.h
81
82
+ converter/decoder.h
83
converter/converterthread.h
84
converter/converter.h
85
converter/splitter.h
86
converter/encoder.h
87
converter/gain.h
88
89
- outformats/aac.h
90
- outformats/flac.h
91
- outformats/mp3.h
92
- outformats/ogg.h
93
- outformats/wav.h
94
- outformats/wv.h
95
- outformats/opus.h
96
+ formats/aac.h
97
+ formats/flac.h
98
+ formats/mp3.h
99
+ formats/ogg.h
100
+ formats/wav.h
101
+ formats/wv.h
102
+ formats/opus.h
103
)
104
105
set (FORMS
106
107
gui/aboutdialog/aboutdialog.ui
108
gui/cuediskselectdialog/cuediskselectdialog.ui
109
110
- outformats/flac_config.ui
111
- outformats/aac_config.ui
112
- outformats/mp3_config.ui
113
- outformats/ogg_config.ui
114
- outformats/wv_config.ui
115
- outformats/opus_config.ui
116
+ formats/flac_config.ui
117
+ formats/aac_config.ui
118
+ formats/mp3_config.ui
119
+ formats/ogg_config.ui
120
+ formats/wv_config.ui
121
+ formats/opus_config.ui
122
)
123
124
set(LIBRARIES
125
126
${CMAKE_CURRENT_SOURCE_DIR}
127
${CMAKE_SOURCE_DIR}
128
${CMAKE_CURRENT_BINARY_DIR}
129
- outformats
130
+ formats
131
converter
132
gui
133
gui/configdialog
134
135
136
if((USE_QT4 AND USE_QT5) OR
137
(NOT USE_QT4 AND NOT USE_QT5))
138
- find_package(Qt4 QUIET)
139
- if (QT4_FOUND)
140
- set(USE_QT4 ON)
141
- set(USE_QT5 OFF)
142
- else()
143
+ find_package(Qt5Core QUIET)
144
+ if (Qt5Core_FOUND)
145
set(USE_QT4 OFF)
146
set(USE_QT5 ON)
147
+ else()
148
+ set(USE_QT4 ON)
149
+ set(USE_QT5 OFF)
150
endif()
151
endif()
152
153
+
154
if(USE_QT4)
155
set(QT_USE_QTNETWORK 1)
156
find_package(Qt4 REQUIRED)
157
158
install(FILES ${QM_FILES} DESTINATION ${TRANSLATIONS_DIR})
159
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
160
161
-if(BUILD_TESTS STREQUAL "Yes")
162
- add_definitions(-DBUILD_TESTS)
163
- add_subdirectory(tests)
164
-else()
165
- status_message("For building tests use -DBUILD_TESTS=Yes option.")
166
-endif()
167
+
168
+addTests(tests)
169
170
171
# Man page **************************************
172
flacon-2.1.1.tar.gz/converter/converter.cpp -> flacon-3.1.1.tar.gz/converter/converter.cpp
Changed
78
1
2
************************************************/
3
Converter::Converter(QObject *parent) :
4
QObject(parent),
5
- mThreadCount(0)
6
+ mThreadCount(0),
7
+ mShowStatistic(true)
8
{
9
}
10
11
12
************************************************/
13
void Converter::createDiscThreads(Disk *disk, const OutFormat *format)
14
{
15
- Splitter *splitter = new Splitter(disk);
16
+ Splitter *splitter = new Splitter(disk, format);
17
mThreads << splitter;
18
19
Gain *albumGain = 0;
20
21
/************************************************
22
23
************************************************/
24
+void Converter::setShowStatistic(bool value)
25
+{
26
+ mShowStatistic = value;
27
+}
28
+
29
+
30
+/************************************************
31
+
32
+ ************************************************/
33
void Converter::stop()
34
{
35
if (!isRunning())
36
37
{
38
emit finished();
39
40
- int duration = QDateTime::currentDateTime().toTime_t() - mStartTime.toTime_t();
41
- if (!duration)
42
- duration = 1;
43
+ if (mShowStatistic)
44
+ {
45
+ int duration = QDateTime::currentDateTime().toTime_t() - mStartTime.toTime_t();
46
+ if (!duration)
47
+ duration = 1;
48
49
- int h = duration / 3600;
50
- int m = (duration - (h * 3600)) / 60;
51
- int s = duration - (h * 3600) - (m * 60);
52
+ int h = duration / 3600;
53
+ int m = (duration - (h * 3600)) / 60;
54
+ int s = duration - (h * 3600) - (m * 60);
55
56
- QString str;
57
+ QString str;
58
59
- if (h)
60
- str = QString("Encoding time %4h %3m %2s [%1 sec]").arg(duration).arg(s).arg(m).arg(h);
61
- else if (m)
62
- str = QString("Encoding time %3m %2s [%1 sec]").arg(duration).arg(s).arg(m);
63
- else
64
- str = QString("Encoding time %1 sec").arg(duration);
65
+ if (h)
66
+ str = QString("Encoding time %4h %3m %2s [%1 sec]").arg(duration).arg(s).arg(m).arg(h);
67
+ else if (m)
68
+ str = QString("Encoding time %3m %2s [%1 sec]").arg(duration).arg(s).arg(m);
69
+ else
70
+ str = QString("Encoding time %1 sec").arg(duration);
71
72
- std::cout << str.toLocal8Bit().constData() << std::endl;
73
+ std::cout << str.toLocal8Bit().constData() << std::endl;
74
+ }
75
76
qDeleteAll(mThreads);
77
mThreads.clear();
78
flacon-2.1.1.tar.gz/converter/converter.h -> flacon-3.1.1.tar.gz/converter/converter.h
Changed
19
1
2
bool isRunning();
3
bool canConvert() const;
4
5
+ bool showStatistic() const { return mShowStatistic; }
6
+ void setShowStatistic(bool value);
7
+
8
signals:
9
void finished();
10
11
12
QDateTime mStartTime;
13
int mThreadCount;
14
QList<ConverterThread*> mThreads;
15
+ bool mShowStatistic;
16
17
bool check(OutFormat *format) const;
18
void createDiscThreads(Disk *disk, const OutFormat *format);
19
flacon-2.1.1.tar.gz/converter/converterthread.cpp -> flacon-3.1.1.tar.gz/converter/converterthread.cpp
Changed
14
1
2
/************************************************
3
4
************************************************/
5
-ConverterThread::ConverterThread(Disk *disk, QObject *parent):
6
+ConverterThread::ConverterThread(Disk *disk, const OutFormat *format, QObject *parent):
7
QThread(parent),
8
- mDisk(disk)
9
+ mDisk(disk),
10
+ mFormat(format)
11
{
12
}
13
14
flacon-2.1.1.tar.gz/converter/converterthread.h -> flacon-3.1.1.tar.gz/converter/converterthread.h
Changed
28
1
2
#include <QThread>
3
#include <QString>
4
5
+class OutFormat;
6
+
7
class ConverterThread: public QThread
8
{
9
Q_OBJECT
10
public:
11
- explicit ConverterThread(Disk *disk, QObject *parent = 0);
12
+ explicit ConverterThread(Disk *disk, const OutFormat *format, QObject *parent = 0);
13
virtual ~ConverterThread();
14
15
Disk *disk() const { return mDisk; }
16
17
bool deleteFile(const QString &fileName);
18
19
void debugArguments(const QString &prog, const QStringList &args);
20
+ const OutFormat *format() const { return mFormat; }
21
+
22
private:
23
Disk *mDisk;
24
+ const OutFormat *mFormat;
25
};
26
27
#endif // CONVERTERTHREAD_H
28
flacon-3.1.1.tar.gz/converter/decoder.cpp
Added
337
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "decoder.h"
29
+#include "../cue.h"
30
+#include "../settings.h"
31
+
32
+#include <QIODevice>
33
+#include <QFile>
34
+#include <QProcess>
35
+#include <QDir>
36
+#include <QDebug>
37
+
38
+#define MAX_BUF_SIZE 4096
39
+
40
+
41
+
42
+/************************************************
43
+ *
44
+ ************************************************/
45
+qint64 timeToBytes(CueTime time, WavHeader wav)
46
+{
47
+ if (wav.isCdQuality())
48
+ {
49
+ return (qint64)((((double)time.frames() * (double)wav.byteRate()) / 75.0) + 0.5);
50
+ }
51
+ else
52
+ {
53
+ return (qint64)((((double)time.milliseconds() * (double)wav.byteRate()) / 1000.0) + 0.5);
54
+ }
55
+}
56
+
57
+
58
+/************************************************
59
+ *
60
+ ************************************************/
61
+Decoder::Decoder(QObject *parent) :
62
+ QObject(parent),
63
+ mFormat(NULL),
64
+ mProcess(NULL),
65
+ mFile(NULL),
66
+ mPos(0)
67
+{
68
+
69
+}
70
+
71
+
72
+/************************************************
73
+ *
74
+ ************************************************/
75
+Decoder::Decoder(const AudioFormat &format, QObject *parent) :
76
+ QObject(parent),
77
+ mFormat(&format),
78
+ mProcess(NULL),
79
+ mFile(NULL),
80
+ mPos(0)
81
+{
82
+
83
+}
84
+
85
+
86
+/************************************************
87
+ *
88
+ ************************************************/
89
+Decoder::~Decoder()
90
+{
91
+ close();
92
+ delete mFile;
93
+ delete mProcess;
94
+}
95
+
96
+
97
+/************************************************
98
+ *
99
+ ************************************************/
100
+bool Decoder::open(const QString fileName)
101
+{
102
+ mInputFile = fileName;
103
+ if (!mFormat)
104
+ mFormat = AudioFormat::formatForFile(fileName);
105
+
106
+ if (!mFormat)
107
+ {
108
+ mErrorString = "Unknown format";
109
+ return false;
110
+ }
111
+
112
+ if (!mFormat->decoderProgramName().isEmpty())
113
+ return openProcess();
114
+ else
115
+ return openFile();
116
+}
117
+
118
+
119
+/************************************************
120
+ *
121
+ ************************************************/
122
+bool Decoder::openFile()
123
+{
124
+ mFile = new QFile(mInputFile, this);
125
+ if (!mFile->open(QFile::ReadOnly))
126
+ {
127
+ mErrorString = mFile->errorString();
128
+ return false;
129
+ }
130
+
131
+ try
132
+ {
133
+ mWavHeader.load(mFile);
134
+ mPos = mWavHeader.dataStartPos();
135
+ return true;
136
+ }
137
+ catch (char const *err)
138
+ {
139
+ mErrorString = err;
140
+ return false;
141
+ }
142
+}
143
+
144
+
145
+/************************************************
146
+ *
147
+ ************************************************/
148
+bool Decoder::openProcess()
149
+{
150
+ mProcess = new QProcess(this);
151
+
152
+ QString program = settings->programName(mFormat->decoderProgramName());
153
+ mProcess->setReadChannel(QProcess::StandardOutput);
154
+ connect(mProcess, SIGNAL(readyReadStandardError()),
155
+ this, SLOT(readStandardError()));
156
+
157
+
158
+ mProcess->start(QDir::toNativeSeparators(program), mFormat->decoderArgs(mInputFile));
159
+ bool res = mProcess->waitForStarted();
160
+ if(!res)
161
+ {
162
+ mErrorString = QString("[Decoder] Can't start '%1': %2").arg(program, mProcess->errorString());
163
+ return false;
164
+ }
165
+
166
+
167
+ try
168
+ {
169
+ mWavHeader.load(mProcess);
170
+ mPos = mWavHeader.dataStartPos();
171
+ return true;
172
+ }
173
+ catch (char const *err)
174
+ {
175
+ mErrorString = err;
176
+ return false;
177
+ }
178
+}
179
+
180
+/************************************************
181
+ *
182
+ ************************************************/
183
+void Decoder::close()
184
+{
185
+ if (mFile)
186
+ mFile->close();
187
+
188
+ if (mProcess)
189
+ {
190
+ mProcess->terminate();
191
+ mProcess->waitForFinished();
192
+ }
193
+}
194
+
195
+
196
+/************************************************
197
+ *
198
+ ************************************************/
199
+bool Decoder::extract(const CueTime &start, const CueTime &end, QIODevice *outDevice)
200
+{
201
+ try
202
+ {
203
+ emit progress(0);
204
+
205
+ QIODevice *input;
206
+ if (mProcess)
207
+ input = mProcess;
208
+ else
209
+ input = mFile;
210
+
211
+ mErrorString = "";
212
+
213
+ quint64 bs = timeToBytes(start, mWavHeader) + mWavHeader.dataStartPos();
214
+ quint64 be = 0;
215
+
216
+ if (end.isNull())
217
+ be = mWavHeader.dataStartPos() + mWavHeader.dataSize();
218
+ else
219
+ be = timeToBytes(end, mWavHeader) + mWavHeader.dataStartPos();
220
+
221
+ outDevice->write(StdWavHeader(be - bs, mWavHeader).toByteArray());
222
+
223
+ qint64 pos = mPos;
224
+
225
+ // Skip bytes from current to start of track ......
226
+ qint64 len = bs - mPos;
227
+ if (len < 0)
228
+ {
229
+ mErrorString = "[Decoder] Incorrect start time.";
230
+ return false;
231
+ }
232
+
233
+ if (!mustSkip(input, len))
234
+ {
235
+ mErrorString = "[Decoder] Can't skip to start of track.";
236
+ return false;
237
+ }
238
+
239
+ pos += len;
240
+ // Skip bytes from current to start of track ......
241
+
242
+ // Read bytes from start to end of track ..........
243
+ len = be - bs;
244
+ if (len < 0)
245
+ {
246
+ mErrorString = "[Decoder] Incorrect start or end time.";
247
+ return false;
248
+ }
249
+
250
+
251
+ pos += len;
252
+ qint64 remains = len;
253
+ int percent = 0;
254
+
255
+ char buf[MAX_BUF_SIZE];
256
+ while (remains > 0)// input->bytesAvailable() || input->waitForReadyRead(1000))
257
+ {
258
+ input->bytesAvailable() || input->waitForReadyRead(1000);
259
+
260
+ int n = qMin(qint64(MAX_BUF_SIZE), remains);
261
+ n = input->read(buf, n);
262
+ remains -= n;
263
+
264
+ if (outDevice->write(buf, n) != n)
265
+ {
266
+ mErrorString = "[Decoder] " + outDevice->errorString();
267
+ return false;
268
+ }
269
+
270
+
271
+
272
+ if (remains == 0)
273
+ {
274
+ emit progress(100);
275
+ break;
276
+ }
277
+ else
278
+ {
279
+ int prev = percent;
280
+ percent = (len - remains) * 100.0 / len;
281
+ if (percent != prev)
282
+ {
283
+ emit progress(percent);
284
+ }
285
+ }
286
+ }
287
+ // Read bytes from start to end of track ..........
288
+ mPos= pos;
289
+ return true;
290
+ }
291
+
292
+ catch (char const *err)
293
+ {
294
+ mErrorString = "[Decoder] " + QString(err);
295
+ return false;
296
+ }
297
+}
298
+
299
+/************************************************
300
+ *
301
+ ************************************************/
302
+bool Decoder::extract(const CueTime &start, const CueTime &end, const QString &outFileName)
303
+{
304
+ QFile file(outFileName);
305
+ if (! file.open(QFile::WriteOnly | QFile::Truncate))
306
+ {
307
+ mErrorString = file.errorString();
308
+ return false;
309
+ }
310
+
311
+ bool res = extract(start, end, &file);
312
+ file.close();
313
+
314
+ return res;
315
+}
316
+
317
+
318
+/************************************************
319
+ *
320
+ ************************************************/
321
+void Decoder::readStandardError()
322
+{
323
+ mErrBuff += mProcess->readAllStandardError();
324
+
325
+ QList<QByteArray> lines = mErrBuff.split('\n');
326
+ int e = (mErrBuff.endsWith('\n')) ? lines.length() : lines.length() - 1;
327
+ for (int i=0 ; i < e; ++i)
328
+ {
329
+ QString s = mFormat->filterDecoderStderr(lines[i]);
330
+ if (!s.isEmpty())
331
+ qWarning("[Decoder] %s", s.toLocal8Bit().data());
332
+ }
333
+
334
+ if (!mErrBuff.endsWith('\n'))
335
+ mErrBuff = lines.last();
336
+}
337
flacon-3.1.1.tar.gz/converter/decoder.h
Added
85
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#ifndef DECODER_H
29
+#define DECODER_H
30
+
31
+#include "wavheader.h"
32
+#include <QObject>
33
+#include <QString>
34
+#include <QByteArray>
35
+#include "../cue.h"
36
+#include "../formats/format.h"
37
+
38
+class QIODevice;
39
+class QProcess;
40
+
41
+class Decoder : public QObject
42
+{
43
+ Q_OBJECT
44
+public:
45
+ explicit Decoder(QObject *parent = 0);
46
+ explicit Decoder(const AudioFormat &format, QObject *parent = 0);
47
+ virtual ~Decoder();
48
+
49
+ bool open(const QString fileName);
50
+ void close();
51
+
52
+ bool extract(const CueTime &start, const CueTime &end, QIODevice *outDevice);
53
+ bool extract(const CueTime &start, const CueTime &end, const QString &outFileName);
54
+
55
+ // Duration of audio in milliseconds.
56
+ uint duration() const { return mWavHeader.duration(); }
57
+
58
+ QString errorString() const { return mErrorString; }
59
+
60
+ WavHeader wavHeader() const { return mWavHeader; }
61
+
62
+signals:
63
+ void progress(int percent);
64
+
65
+private slots:
66
+ void readStandardError();
67
+
68
+private:
69
+ const AudioFormat *mFormat;
70
+ QProcess *mProcess;
71
+ QString mInputFile;
72
+ QFile *mFile;
73
+ WavHeader mWavHeader;
74
+ QString mErrorString;
75
+ quint64 mPos;
76
+ QByteArray mErrBuff;
77
+
78
+ bool openFile();
79
+ bool openProcess();
80
+};
81
+
82
+
83
+
84
+#endif // DECODER_H
85
flacon-2.1.1.tar.gz/converter/encoder.cpp -> flacon-3.1.1.tar.gz/converter/encoder.cpp
Changed
20
1
2
3
************************************************/
4
Encoder::Encoder(const OutFormat *format, Track *track, QObject *parent):
5
- ConverterThread(track->disk(), parent),
6
- mFormat(format),
7
+ ConverterThread(track->disk(), format, parent),
8
mTrack(track),
9
mProcess(0),
10
mTotal(0),
11
12
}
13
14
15
- QStringList args = mFormat->encoderArgs(track(), QDir::toNativeSeparators(outFile()));
16
+ QStringList args = format()->encoderArgs(track(), QDir::toNativeSeparators(outFile()));
17
QString prog = args.takeFirst();
18
19
if (mDebug)
20
flacon-2.1.1.tar.gz/converter/encoder.h -> flacon-3.1.1.tar.gz/converter/encoder.h
Changed
9
1
2
void processBytesWritten(qint64 bytes);
3
4
private:
5
- const OutFormat *mFormat;
6
Track *mTrack;
7
QString mWorkDir;
8
QString mInputFile;
9
flacon-2.1.1.tar.gz/converter/gain.cpp -> flacon-3.1.1.tar.gz/converter/gain.cpp
Changed
20
1
2
3
************************************************/
4
Gain::Gain(const OutFormat *format, Disk *disk, Track *track, QObject *parent):
5
- ConverterThread(disk, parent),
6
- mFormat(format),
7
+ ConverterThread(disk, format, parent),
8
mProcess(0)
9
{
10
if (track)
11
12
files << QDir::toNativeSeparators(i.value());
13
}
14
15
- QStringList args = mFormat->gainArgs(files);
16
+ QStringList args = format()->gainArgs(files);
17
QString prog = args.takeFirst();
18
19
if (mDebug)
20
flacon-2.1.1.tar.gz/converter/gain.h -> flacon-3.1.1.tar.gz/converter/gain.h
Changed
9
1
2
void doStop();
3
4
private:
5
- const OutFormat *mFormat;
6
QList<Track*> mTracks;
7
QHash<Track*, QString> mInputFiles;
8
QProcess *mProcess;
9
flacon-2.1.1.tar.gz/converter/splitter.cpp -> flacon-3.1.1.tar.gz/converter/splitter.cpp
Changed
301
1
2
#include "project.h"
3
#include "disk.h"
4
#include "inputaudiofile.h"
5
+#include "decoder.h"
6
7
#include <iostream>
8
#include <QFileInfo>
9
10
#include <QProcess>
11
#include <QRegExp>
12
#include <QTextCodec>
13
+#include <QUuid>
14
#include <QDebug>
15
16
//#define DEBUG_CUE_ON
17
18
/************************************************
19
20
************************************************/
21
-Splitter::Splitter(Disk *disk, QObject *parent):
22
- ConverterThread(disk, parent),
23
+Splitter::Splitter(Disk *disk, const OutFormat *format, QObject *parent):
24
+ ConverterThread(disk, format, parent),
25
mProcess(0),
26
- mPreGapExists(false)
27
+ mTrack(NULL)
28
{
29
QString tmpDir = settings->value(Settings::Encoder_TmpDir).toString();
30
31
32
mWorkDir = QFileInfo(disk->track(0)->resultFilePath()).dir().absolutePath();
33
else
34
mWorkDir = QDir(QString("%1/flacon.%2").arg(tmpDir).arg(QCoreApplication::applicationPid())).absolutePath();
35
-
36
- mFilePrefix = QString("tmp-%1-%2.").arg(QCoreApplication::applicationPid()).arg(project->indexOf(disk));
37
}
38
39
40
41
}
42
}
43
44
+struct SplitterRequest {
45
+ CueTime start;
46
+ CueTime end;
47
+ QString outFileName;
48
+ Track *track;
49
+};
50
51
/************************************************
52
Split audio file to temporary dir
53
************************************************/
54
void Splitter::doRun()
55
{
56
- QStringList args;
57
- args << "split";
58
- args << "-w";
59
- args << "-O" << "always";
60
- args << "-n" << "%04d";
61
- args << "-t" << mFilePrefix +"%n";
62
- args << "-d" << mWorkDir;
63
- args << QDir::toNativeSeparators(disk()->audioFileName());
64
- //qDebug() << args;
65
+ mTrack = disk()->track(0);
66
+ Decoder decoder;
67
+ connect(&decoder, SIGNAL(progress(int)),
68
+ this, SLOT(decoderProgress(int)));
69
70
- QString shntool = settings->value(Settings::Prog_Shntool).toString();
71
- mProcess = new QProcess();
72
- mProcess->setReadChannel(QProcess::StandardError);
73
+ if (!decoder.open(disk()->audioFileName()))
74
+ {
75
+ error(mTrack,
76
+ tr("I can't read <b>%1</b>:<br>%2",
77
+ "Splitter error. %1 is a file name, %2 is a system error text.")
78
+ .arg(disk()->audioFileName())
79
+ .arg(decoder.errorString()));
80
+ return;
81
+ }
82
83
- mProcess->start(QDir::toNativeSeparators(shntool), args);
84
- mProcess->waitForStarted();
85
+ bool separatePregap = format()->createCue() &&
86
+ disk()->track(0)->cueIndex(1).milliseconds() > 0 &&
87
+ OutFormat::currentFormat()->preGapType() == OutFormat::PreGapExtractToFile;
88
89
- sendCueData();
90
- mProcess->closeWriteChannel();
91
92
- parseOut();
93
- mProcess->waitForFinished(-1);
94
+ bool embededPregap = format()->createCue() &&
95
+ disk()->track(0)->cueIndex(1).milliseconds() > 0 &&
96
+ OutFormat::currentFormat()->preGapType() == OutFormat::PreGapAddToFirstTrack;
97
98
- QProcess *proc = mProcess;
99
- mProcess = 0;
100
- delete proc;
101
+ QList<SplitterRequest> requests;
102
103
- if (OutFormat::currentFormat()->createCue())
104
+
105
+ // Extract pregap to separate file ....................
106
+ if (separatePregap)
107
{
108
- CueCreator cue(disk());
109
- cue.setHasPregapFile(mPreGapExists);
110
- if (!cue.write())
111
- error(disk()->track(0), cue.errorString());
112
+ SplitterRequest req;
113
+ req.track = disk()->preGapTrack();
114
+ req.outFileName = QDir::toNativeSeparators(QString("%1/flacon_%2_%3.wav").arg(mWorkDir).arg("00").arg(QUuid::createUuid().toString().mid(1, 36)));
115
+ req.start = disk()->track(0)->cueIndex(0);
116
+ req.end = disk()->track(0)->cueIndex(1);
117
+ requests << req;
118
}
119
-}
120
+ // Extract pregap to separate file ....................
121
122
-/************************************************
123
+ for (int i=0; i<disk()->count(); ++i)
124
+ {
125
+ SplitterRequest req;
126
+ req.track = disk()->track(i);
127
+ req.outFileName = QDir::toNativeSeparators(QString("%1/flacon_%2_%3.wav").arg(mWorkDir).arg(i, 2, 10, QChar('0')).arg(QUuid::createUuid().toString().mid(1, 36)));
128
129
- ************************************************/
130
+ if (i==0 && embededPregap)
131
+ req.start = CueTime("00:00:00");
132
+ else
133
+ req.start = disk()->track(i)->cueIndex(1);
134
135
-void Splitter::parseOut()
136
-{
137
- Track *track = disk()->track(0);
138
+ if (i<disk()->count()-1)
139
+ req.end = disk()->track(i+1)->cueIndex(01);
140
141
- bool deletePregap = !OutFormat::currentFormat()->createCue();
142
- char c;
143
- QByteArray buf;
144
+ requests << req;
145
+ }
146
147
- while(mProcess->waitForReadyRead(-1))
148
+ foreach (SplitterRequest req, requests)
149
{
150
- while (mProcess->read(&c, 1))
151
+ mTrack = req.track;
152
+ bool ret = decoder.extract(req.start, req.end, req.outFileName);
153
+ if (!ret)
154
{
155
- // .......................................
156
- if (c == '\n')
157
- {
158
- if (buf.contains(": error:"))
159
- {
160
- error(track, QString::fromLocal8Bit(buf.mid(17)));
161
- return;
162
- }
163
- buf = "";
164
- }
165
-
166
-
167
- // .......................................
168
- else if (c == '%')
169
- {
170
- bool ok;
171
- int percent = buf.right(3).trimmed().toInt(&ok);
172
- if (!ok)
173
- continue;
174
-
175
-
176
- // Splitting [/home/user/inDir/input.wav] (10:00.000) --> [/home/user/outDir/tmp-15196-00000.wav] (0:00.440) : 100% OK
177
-
178
- QString pattern = "[" + mWorkDir + QDir::separator() + mFilePrefix;
179
- pattern.replace('\\', '/');
180
- QString sbuf = QString::fromLocal8Bit(buf);
181
- int n = sbuf.indexOf(pattern, disk()->audioFileName().length() + 20);
182
-
183
- if (n < 0 && sbuf.length() < n + pattern.length() + 4)
184
- {
185
- qWarning() << "I can't parse" << sbuf;
186
- continue;
187
- }
188
-
189
- QString fileName = sbuf.mid(n + 1, + pattern.length() - 1 + 4 + 4); // -1 for leading "[", 4 for 4 digits tracknum, 4 - file ext ".wav"
190
-
191
- int trackNum = fileName.mid(fileName.length() - 8, 4).toInt(&ok);
192
-
193
- if (!ok)
194
- {
195
- qWarning() << "I can't parse" << sbuf;
196
- continue;
197
- }
198
-
199
-
200
-
201
- if (trackNum > disk()->count())
202
- {
203
- error(disk()->track(0), tr("The number of tracks is higher than expected."));
204
- return;
205
- }
206
-
207
- track = (trackNum == 0) ? disk()->preGapTrack() : disk()->track(trackNum - 1);
208
- mPreGapExists = mPreGapExists || (trackNum == 0);
209
+ qWarning() << "Splitter error for track " << req.track->index() << ": " << decoder.errorString();
210
+ deleteFile(req.outFileName);
211
+ error(mTrack, decoder.errorString());
212
+ return;
213
+ }
214
215
- emit trackProgress(track, Track::Splitting, percent);
216
+ emit trackReady(req.track, req.outFileName);
217
+ }
218
219
- if (percent == 100)
220
- {
221
- if (trackNum == 0 && deletePregap)
222
- deleteFile(fileName);
223
- else
224
- emit trackReady(track, fileName);
225
- }
226
- }
227
- // .......................................
228
- else if (c == '\\')
229
- {
230
- buf += '/';
231
- }
232
- // .......................................
233
- else
234
- {
235
- buf += c;
236
- }
237
238
- //std::cerr << c;
239
- }
240
+ if (OutFormat::currentFormat()->createCue())
241
+ {
242
+ CueCreator cue(disk());
243
+ cue.setHasPregapFile(separatePregap);
244
+ if (!cue.write())
245
+ error(disk()->track(0), cue.errorString());
246
}
247
}
248
249
-
250
/************************************************
251
-
252
- ************************************************/
253
-void Splitter::sendCueData()
254
+ *
255
+ ***********************************************/
256
+void Splitter::decoderProgress(int percent)
257
{
258
- bool cdQuality = disk()->audioFile()->isCdQuality();
259
- OutFormat *format = OutFormat::currentFormat();
260
-
261
- bool fakeIndex = (format->createCue() and
262
- format->preGapType() == OutFormat::PreGapAddToFirstTrack);
263
-
264
- QString s = QString("FILE \"%1\" WAVE").arg(disk()->audioFileName());
265
- mProcess->write(s.toLocal8Bit() + "\n");
266
-
267
- for (int t=0; t<disk()->count(); ++t)
268
- {
269
- Track *track = disk()->track(t);
270
-
271
- QString s = QString("TRACK %1 AUDIO").arg(t + 1);
272
- DEBUG_CUE << s;
273
- mProcess->write(s.toLocal8Bit() + "\n");
274
-
275
- if (fakeIndex && t == 0)
276
- {
277
- QString s = cdQuality ? " INDEX 01 00:00:00" : " INDEX 01 00:00.000";
278
- DEBUG_CUE << s;
279
- mProcess->write(s.toLocal8Bit() + "\n");
280
- }
281
- else
282
- {
283
-
284
- for (int i=0; i<100; ++i)
285
- {
286
- if (!track->cueIndex(i).isNull())
287
- {
288
- QString s = QString(" INDEX %1 %2")
289
- .arg(i, 2, 10, QChar('0'))
290
- .arg(track->cueIndex(i).toString(cdQuality));
291
- DEBUG_CUE << s;
292
- mProcess->write(s.toLocal8Bit() + "\n");
293
- }
294
- }
295
- }
296
- }
297
+ emit trackProgress(mTrack, Track::Splitting, percent);
298
}
299
300
301
flacon-2.1.1.tar.gz/converter/splitter.h -> flacon-3.1.1.tar.gz/converter/splitter.h
Changed
29
1
2
{
3
Q_OBJECT
4
public:
5
- Splitter(Disk *disk, QObject *parent = 0);
6
+ Splitter(Disk *disk, const OutFormat *format, QObject *parent = 0);
7
8
bool isReadyStart() const;
9
QString workDir() const { return mWorkDir; }
10
11
void doRun();
12
void doStop();
13
14
+private slots:
15
+ void decoderProgress(int percent);
16
+
17
private:
18
QString mWorkDir;
19
- QString mFilePrefix;
20
QProcess *mProcess;
21
- bool mPreGapExists;
22
-
23
- void parseOut();
24
- void sendCueData();
25
+ Track *mTrack;
26
};
27
28
#endif // SPLITTER_H
29
flacon-3.1.1.tar.gz/converter/wavheader.cpp
Added
476
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2012-2013
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "wavheader.h"
29
+
30
+#include <QByteArray>
31
+#include <QtEndian>
32
+#include <QDebug>
33
+
34
+#define WAV_RIFF "RIFF"
35
+#define WAV_WAVE "WAVE"
36
+#define WAV_FMT "fmt "
37
+#define WAV_DATA "data"
38
+
39
+#define CD_NUM_CHANNELS 2
40
+#define CD_BITS_PER_SAMPLE 16
41
+#define CD_SAMPLE_RATE 44100
42
+#define CD_BYTE_RATE 176400
43
+#define CD_BLOCK_SIZE 2352
44
+
45
+#define CANONICAL_HEADER_SIZE 44
46
+#define BUF_SIZE 4096
47
+
48
+
49
+/************************************************
50
+ *
51
+ ************************************************/
52
+inline bool mustRead(QIODevice *device, char *data, qint64 size, int msecs)
53
+{
54
+ char *d = data;
55
+ qint64 left = size;
56
+ while (device->bytesAvailable() || device->waitForReadyRead(msecs))
57
+ {
58
+ qint64 n = device->read(d, left);
59
+
60
+ if (n==left)
61
+ return true;
62
+
63
+ d+=n;
64
+ left-=n;
65
+ }
66
+
67
+ return false;
68
+}
69
+
70
+
71
+/************************************************
72
+ *
73
+ ************************************************/
74
+bool mustSkip(QIODevice *device, qint64 size, int msecs)
75
+{
76
+ if (size == 0)
77
+ return true;
78
+
79
+ char buf[BUF_SIZE];
80
+ qint64 left = size;
81
+ while (device->bytesAvailable() || device->waitForReadyRead(msecs))
82
+ {
83
+ left -= device->read(buf, qMin(left, qint64(BUF_SIZE)));
84
+
85
+ if (!left)
86
+ return true;
87
+ }
88
+
89
+ return false;
90
+}
91
+
92
+
93
+/************************************************
94
+ *
95
+ ************************************************/
96
+bool readTag(QIODevice *device, char tag[5])
97
+{
98
+ tag[4] = '\0';
99
+ return mustRead(device, tag, 4);
100
+}
101
+
102
+
103
+struct SplitterError {
104
+ int trackNum;
105
+ QString msg;
106
+
107
+ SplitterError(int num, QString msg):
108
+ trackNum(num),
109
+ msg(msg)
110
+ {
111
+ }
112
+};
113
+
114
+
115
+/************************************************
116
+ *
117
+ ************************************************/
118
+quint32 readUInt32(QIODevice *stream)
119
+{
120
+ quint32 n;
121
+ if (stream->read((char*)&n, 4) != 4)
122
+ throw "Unexpected end of file";
123
+ return qFromLittleEndian(n);
124
+}
125
+
126
+
127
+/************************************************
128
+ *
129
+ ************************************************/
130
+quint16 readUInt16(QIODevice *stream)
131
+{
132
+ quint16 n;
133
+ if (stream->read((char*)&n, 2) != 2)
134
+ throw "Unexpected end of file";
135
+ return qFromLittleEndian(n);
136
+}
137
+
138
+
139
+/************************************************
140
+ * 52 49 46 46 RIFF
141
+ * 24 B9 4D 02 file size - 8
142
+ * 57 41 56 45 WAVE
143
+ *
144
+ * // Chanks
145
+ * 66 6D 74 20 SubchunkID "fmt "
146
+ * 10 00 00 00 SubchunkSize 16
147
+ * 01 00 AudioFormat PCM
148
+ * 02 00 NumChannels 2
149
+ * 44 AC 00 00 SampleRate 44100
150
+ * 10 B1 02 00 ByteRate 176400
151
+ * 04 00 BlockAlign 4
152
+ * 10 00 BitsPerSample 16
153
+ * // Data
154
+ * 64 61 74 61 SubchunkID "data"
155
+ * 00 B9 4D 02 SubchunkSize
156
+ ************************************************/
157
+WavHeader::WavHeader():
158
+ mFileSize(0),
159
+ mFormat(WavHeader::Format_Unknown),
160
+ mNumChannels(0),
161
+ mSampleRate(0),
162
+ mByteRate(0),
163
+ mBlockAlign(0),
164
+ mBitsPerSample(0),
165
+ mDataSize(0),
166
+ mDataStartPos(0)
167
+{
168
+}
169
+
170
+
171
+/************************************************
172
+ *
173
+ ************************************************/
174
+bool WavHeader::isCdQuality() const
175
+{
176
+ return mNumChannels == CD_NUM_CHANNELS &&
177
+ mBitsPerSample == CD_BITS_PER_SAMPLE &&
178
+ mSampleRate == CD_SAMPLE_RATE &&
179
+ mByteRate == CD_BYTE_RATE;
180
+}
181
+
182
+
183
+/************************************************
184
+ *
185
+ ************************************************/
186
+quint64 WavHeader::duration() const
187
+{
188
+ return (mDataSize * 1000ull) / mByteRate;
189
+}
190
+
191
+
192
+/************************************************
193
+ *
194
+ ************************************************/
195
+StdWavHeader::StdWavHeader(quint32 dataSize, const WavHeader &base):
196
+ WavHeader()
197
+{
198
+ mDataSize = dataSize;
199
+ mDataStartPos = CANONICAL_HEADER_SIZE;
200
+ mFileSize = mDataStartPos + mDataSize;
201
+ mFormat = base.format();
202
+ mNumChannels = base.numChannels();
203
+ mSampleRate = base.sampleRate();
204
+ mByteRate = base.byteRate();
205
+ mBlockAlign = base.blockAlign();
206
+ mBitsPerSample = base.bitsPerSample();
207
+}
208
+
209
+
210
+/************************************************
211
+ *
212
+ ************************************************/
213
+StdWavHeader::StdWavHeader(quint32 dataSize, quint32 sampleRate, quint16 bitsPerSample, quint8 numChannels):
214
+ WavHeader()
215
+{
216
+ mDataSize = dataSize;
217
+ mNumChannels = numChannels;
218
+ mSampleRate = sampleRate;
219
+ mBitsPerSample = bitsPerSample;
220
+
221
+ mDataStartPos = CANONICAL_HEADER_SIZE;
222
+ mFileSize = mDataStartPos + mDataSize;
223
+ mFormat = Format_PCM;
224
+ mByteRate = mSampleRate * mNumChannels * mBitsPerSample / 8;
225
+ mBlockAlign = mNumChannels * mBitsPerSample / 8;
226
+}
227
+
228
+
229
+/************************************************
230
+ *
231
+ ************************************************/
232
+StdWavHeader::StdWavHeader(quint32 dataSize, StdWavHeader::Quality quality)
233
+{
234
+ mDataSize = dataSize;
235
+
236
+ switch (quality)
237
+ {
238
+ case Quality_Stereo_CD:
239
+ mNumChannels = 2;
240
+ mBitsPerSample = 16;
241
+ mSampleRate = 44100;
242
+ break;
243
+
244
+
245
+ case Quality_Stereo_24_96:
246
+ mNumChannels = 2;
247
+ mBitsPerSample = 24;
248
+ mSampleRate = 96000;
249
+ break;
250
+
251
+ case Quality_Stereo_24_192:
252
+ mNumChannels = 2;
253
+ mBitsPerSample = 24;
254
+ mSampleRate = 192000;
255
+ break;
256
+
257
+ }
258
+
259
+ mDataStartPos = CANONICAL_HEADER_SIZE;
260
+ mFileSize = mDataStartPos + mDataSize;
261
+ mFormat = Format_PCM;
262
+ mByteRate = mSampleRate * mNumChannels * mBitsPerSample / 8;
263
+ mBlockAlign = mNumChannels * mBitsPerSample / 8;
264
+
265
+}
266
+
267
+
268
+/************************************************
269
+ *
270
+ ************************************************/
271
+quint32 StdWavHeader::bytesPerSecond(StdWavHeader::Quality quality)
272
+{
273
+ switch (quality)
274
+ {
275
+ case Quality_Stereo_CD: return 2 * 16 * 44100 / 8;
276
+ case Quality_Stereo_24_96: return 2 * 24 * 96000 / 8;
277
+ case Quality_Stereo_24_192: return 2 * 24 * 192000 / 8;
278
+ }
279
+ return 0;
280
+}
281
+
282
+
283
+/************************************************
284
+ * See WAV specoification
285
+ * http://soundfile.sapp.org/doc/WaveFormat/
286
+ * https://en.wikipedia.org/wiki/WAV
287
+ ************************************************/
288
+void WavHeader::load(QIODevice *stream)
289
+{
290
+ char tag[5] = { '\0' };
291
+ // look for "RIFF" in header
292
+ if (!readTag(stream, tag) || strcmp(tag, WAV_RIFF) != 0)
293
+ throw "WAVE header is missing RIFF tag while processing file";
294
+
295
+ this->mFileSize = readUInt32(stream) + 8;
296
+
297
+ if (!readTag(stream, tag) || strcmp(tag, WAV_WAVE) != 0)
298
+ throw "WAVE header is missing WAVE tag while processing file";
299
+
300
+
301
+ char chunkID[5];
302
+ quint32 chunkSize;
303
+ quint64 pos=12;
304
+ while (!stream->atEnd())
305
+ {
306
+ if (!readTag(stream, chunkID))
307
+ throw "[WAV] can't read chunk ID";
308
+
309
+ chunkSize = readUInt32(stream);
310
+ pos+=8;
311
+ //qDebug()<< QString("found chunk: [%1] with length %2").arg(chunkID.data()).arg(chunkSize);
312
+
313
+ if (strcmp(chunkID, WAV_FMT) == 0)
314
+ {
315
+ pos+=chunkSize;
316
+ if (chunkSize < 16)
317
+ throw "fmt chunk in WAVE header was too short";
318
+
319
+ this->mFormat = static_cast<Format>(readUInt16(stream));
320
+ this->mNumChannels = readUInt16(stream);
321
+ this->mSampleRate = readUInt32(stream);
322
+ this->mByteRate = readUInt32(stream);
323
+ this->mBlockAlign = readUInt16(stream);
324
+ this->mBitsPerSample = readUInt16(stream);
325
+
326
+ if (chunkSize > 16)
327
+ stream->seek(stream->pos() + chunkSize - 16);
328
+
329
+ }
330
+
331
+ else if (strcmp(chunkID, WAV_DATA) == 0)
332
+ {
333
+ this->mDataSize = chunkSize;
334
+ this->mDataStartPos = pos;
335
+ return;
336
+ }
337
+
338
+ else
339
+ {
340
+ pos+=chunkSize;
341
+ mustSkip(stream, chunkSize);
342
+ }
343
+ }
344
+
345
+ throw "data chunk not found";
346
+}
347
+
348
+
349
+/************************************************
350
+ *
351
+ ************************************************/
352
+QByteArray& operator<<(QByteArray& out, const char val[4])
353
+{
354
+ out += val;
355
+ return out;
356
+}
357
+
358
+
359
+/************************************************
360
+ *
361
+ ************************************************/
362
+QByteArray& operator<<(QByteArray& out, quint32 val)
363
+{
364
+ union {
365
+ quint32 n;
366
+ char bytes[4];
367
+ };
368
+
369
+ n = qToLittleEndian(val);
370
+ out += bytes[0];
371
+ out += bytes[1];
372
+ out += bytes[2];
373
+ out += bytes[3];
374
+
375
+ return out;
376
+}
377
+
378
+
379
+/************************************************
380
+ *
381
+ ************************************************/
382
+QByteArray& operator<<(QByteArray& out, quint16 val)
383
+{
384
+ union {
385
+ quint32 n;
386
+ char bytes[2];
387
+ };
388
+
389
+ n = qToLittleEndian(val);
390
+ out += bytes[0];
391
+ out += bytes[1];
392
+
393
+ return out;
394
+}
395
+
396
+/************************************************
397
+ * 52 49 46 46 RIFF
398
+ * 24 B9 4D 02 file size - 8
399
+ * 57 41 56 45 WAVE
400
+ *
401
+ * // Chanks
402
+ * 66 6D 74 20 SubchunkID "fmt "
403
+ * 10 00 00 00 SubchunkSize 16
404
+ * 01 00 AudioFormat PCM
405
+ * 02 00 NumChannels 2
406
+ * 44 AC 00 00 SampleRate 44100
407
+ * 10 B1 02 00 ByteRate 176400
408
+ * 04 00 BlockAlign 4
409
+ * 10 00 BitsPerSample 16
410
+ * // Data
411
+ * 64 61 74 61 SubchunkID "data"
412
+ * 00 B9 4D 02 SubchunkSize
413
+ ************************************************/
414
+QByteArray WavHeader::toByteArray() const
415
+{
416
+ QByteArray res;
417
+ res.reserve(mDataStartPos -1);
418
+ res << WAV_RIFF;
419
+ res << (mFileSize - 8);
420
+ res << WAV_WAVE;
421
+
422
+ res << WAV_FMT;
423
+ res << quint32(16);
424
+ res << (quint16)(mFormat);
425
+ res << mNumChannels;
426
+ res << mSampleRate;
427
+ res << mByteRate;
428
+ res << mBlockAlign;
429
+ res << mBitsPerSample;
430
+ res << WAV_DATA;
431
+ res << mDataSize;
432
+
433
+ return res;
434
+}
435
+
436
+QDebug operator<<(QDebug dbg, const WavHeader &header)
437
+{
438
+ QString format;
439
+ switch (header.format())
440
+ {
441
+ case WavHeader::Format_Unknown: format = "Unknown"; break;
442
+ case WavHeader::Format_PCM: format = "PCM"; break;
443
+ case WavHeader::Format_ADPCM: format = "ADPCM"; break;
444
+ case WavHeader::Format_IEEE_FLOAT: format = "IEEE_FLOAT"; break;
445
+ case WavHeader::Format_ALAW: format = "ALAW"; break;
446
+ case WavHeader::Format_MULAW: format = "MULAW"; break;
447
+ case WavHeader::Format_OKI_ADPCM: format = "OKI_ADPCM"; break;
448
+ case WavHeader::Format_IMA_ADPCM: format = "IMA_ADPCM"; break;
449
+ case WavHeader::Format_DIGISTD: format = "DIGISTD"; break;
450
+ case WavHeader::Format_DIGIFIX: format = "DIGIFIX"; break;
451
+ case WavHeader::Format_DOLBY_AC2: format = "DOLBY_AC2"; break;
452
+ case WavHeader::Format_GSM610: format = "Unknown"; break;
453
+ case WavHeader::Format_ROCKWELL_ADPCM: format = "ROCKWELL_ADPCM"; break;
454
+ case WavHeader::Format_ROCKWELL_DIGITALK: format = "ROCKWELL_DIGITALK"; break;
455
+ case WavHeader::Format_G721_ADPCM: format = "G721_ADPCM"; break;
456
+ case WavHeader::Format_G728_CELP: format = "G728_CELP"; break;
457
+ case WavHeader::Format_MPEG: format = "MPEG"; break;
458
+ case WavHeader::Format_MPEGLAYER3: format = "MPEGLAYER3"; break;
459
+ case WavHeader::Format_G726_ADPCM: format = "G726_ADPCM"; break;
460
+ case WavHeader::Format_G722_ADPCM: format = "Unknown"; break;
461
+ }
462
+
463
+
464
+ dbg.nospace() << "file size: " << header.fileSize() << "\n";
465
+ dbg.nospace() << "format: " << format << "\n";
466
+ dbg.nospace() << "num channels: " << header.numChannels() << "\n";
467
+ dbg.nospace() << "sample rate: " << header.sampleRate() << "\n";
468
+ dbg.nospace() << "byte rate: " << header.byteRate() << "\n";
469
+ dbg.nospace() << "block align: " << header.blockAlign() << "\n";
470
+ dbg.nospace() << "bits per sample: " << header.bitsPerSample() << "\n";
471
+ dbg.nospace() << "data size: " << header.dataSize() << "\n";
472
+ dbg.nospace() << "data start pos: " << header.dataStartPos() << "\n";
473
+
474
+ return dbg.space();
475
+}
476
flacon-3.1.1.tar.gz/converter/wavheader.h
Added
129
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2012-2013
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#ifndef WAVHEADER_H
29
+#define WAVHEADER_H
30
+
31
+#include <QtGlobal>
32
+#include <QIODevice>
33
+
34
+class WavHeader {
35
+public:
36
+ enum Format{
37
+ Format_Unknown = 0x0000,
38
+ Format_PCM = 0x0001,
39
+ Format_ADPCM = 0x0002,
40
+ Format_IEEE_FLOAT = 0x0003,
41
+ Format_ALAW = 0x0006,
42
+ Format_MULAW = 0x0007,
43
+ Format_OKI_ADPCM = 0x0010,
44
+ Format_IMA_ADPCM = 0x0011,
45
+ Format_DIGISTD = 0x0015,
46
+ Format_DIGIFIX = 0x0016,
47
+ Format_DOLBY_AC2 = 0x0030,
48
+ Format_GSM610 = 0x0031,
49
+ Format_ROCKWELL_ADPCM = 0x003b,
50
+ Format_ROCKWELL_DIGITALK = 0x003c,
51
+ Format_G721_ADPCM = 0x0040,
52
+ Format_G728_CELP = 0x0041,
53
+ Format_MPEG = 0x0050,
54
+ Format_MPEGLAYER3 = 0x0055,
55
+ Format_G726_ADPCM = 0x0064,
56
+ Format_G722_ADPCM = 0x0065
57
+
58
+ };
59
+
60
+
61
+ WavHeader();
62
+
63
+ quint32 fileSize() const { return mFileSize; }
64
+ Format format() const { return mFormat; }
65
+ quint16 numChannels() const { return mNumChannels; }
66
+ quint32 sampleRate() const { return mSampleRate; }
67
+ quint32 byteRate() const { return mByteRate; }
68
+ quint16 blockAlign() const { return mBlockAlign; }
69
+ quint16 bitsPerSample() const { return mBitsPerSample; }
70
+ quint32 dataSize() const { return mDataSize; }
71
+ quint32 dataStartPos() const { return mDataStartPos; }
72
+ bool isCdQuality() const;
73
+
74
+ /// Duration of audio in milliseconds.
75
+ quint64 duration() const;
76
+
77
+ void load(QIODevice* stream);
78
+
79
+ QByteArray toByteArray() const;
80
+
81
+protected:
82
+ quint32 mFileSize;
83
+ Format mFormat;
84
+ quint16 mNumChannels;
85
+ quint32 mSampleRate;
86
+ quint32 mByteRate;
87
+ quint16 mBlockAlign;
88
+ quint16 mBitsPerSample;
89
+ quint32 mDataSize;
90
+ quint32 mDataStartPos;
91
+
92
+private:
93
+
94
+};
95
+
96
+QDebug operator<<(QDebug dbg, const WavHeader &header);
97
+
98
+class StdWavHeader: public WavHeader
99
+{
100
+public:
101
+ enum Quality {
102
+ Quality_Stereo_CD = 2 * 16 * 44100,
103
+ Quality_Stereo_24_96 = 2 * 24 * 96000,
104
+ Quality_Stereo_24_192 = 2 * 24 * 192000
105
+
106
+ };
107
+ StdWavHeader(quint32 dataSize, const WavHeader &base);
108
+
109
+ /**
110
+ * dataSize - This is the number of bytes in the audio data. NumSamples * NumChannels * BitsPerSample/8
111
+ * sampleRate - 8000, 44100, etc.
112
+ * bitsPerSample - 8 bits = 8, 16 bits = 16, etc.
113
+ * numChannels - Mono = 1, Stereo = 2, etc.
114
+ */
115
+ explicit StdWavHeader(quint32 dataSize, quint32 sampleRate, quint16 bitsPerSample, quint8 numChannels);
116
+
117
+
118
+ explicit StdWavHeader(quint32 dataSize, Quality quality);
119
+
120
+ static quint32 bytesPerSecond(Quality quality);
121
+};
122
+
123
+#define READ_DELAY 1000
124
+inline bool mustRead(QIODevice *device, char *data, qint64 size, int msecs = READ_DELAY);
125
+bool mustSkip(QIODevice *device, qint64 size, int msecs = READ_DELAY);
126
+
127
+
128
+#endif // WAVHEADER_H
129
flacon-2.1.1.tar.gz/cue.cpp -> flacon-3.1.1.tar.gz/cue.cpp
Changed
19
1
2
3
/************************************************
4
Complete cue sheet syntax documentation
5
- http://digitalx.org/cue-sheet/syntax/
6
+ https://github.com/flacon/flacon/blob/master/cuesheet_syntax.md
7
************************************************/
8
bool CueReader::parse(QFile &file)
9
{
10
11
12
/************************************************
13
Complete cue sheet syntax documentation
14
- http://digitalx.org/cue-sheet/syntax/
15
+ https://github.com/flacon/flacon/blob/master/cuesheet_syntax.md
16
************************************************/
17
bool CueReader::parseOneDiskTags(QFile &file, CueTagSet *tags)
18
{
19
flacon-2.1.1.tar.gz/cue.h -> flacon-3.1.1.tar.gz/cue.h
Changed
17
1
2
bool operator!=(const CueIndex &other) const;
3
4
uint milliseconds() const { return mHiValue; }
5
+ uint frames() const { return mCdValue; }
6
7
private:
8
bool mNull;
9
10
bool parse(const QString &str);
11
};
12
13
+typedef CueIndex CueTime;
14
15
class CueTagSet: public TagSet
16
{
17
flacon-3.1.1.tar.gz/cuesheet_syntax.md
Added
359
1
2
+Cue-Sheet Syntax
3
+================
4
+
5
+
6
+[CATALOG](#catalog) | [CDTEXTFILE](#cdtextfile) | [FILE](#file) | [FLAGS](#flags) | [INDEX](#index) | [ISRC](#isrc) | [PERFORMER](#performer) | [POSTGAP](#postgap) | [PREGAP](#pregap) | [REM](#rem) | [SONGWRITER](#songwriter) | [TITLE](#title) | [TRACK](#track)
7
+
8
+
9
+
10
+CATALOG
11
+-------
12
+
13
+**Description:**
14
+This command is used to specify the disc's "Media Catalog Number". It will typically be used only when mastering a CDROM for commercial production.
15
+
16
+**Syntax:**
17
+```
18
+CATALOG [media-catalog-number]
19
+```
20
+
21
+**Examples:**
22
+```
23
+CATALOG 1234567890123
24
+CATALOG 8340218374610
25
+```
26
+
27
+**Rules:**
28
+The catalog number must be 13 digits long and is encoded according to UPC/EAN rules. This command can appear only once in the CUE SHEET file (it will usually be the first line, but this is not mandatory).
29
+
30
+
31
+
32
+
33
+CDTEXTFILE
34
+----------
35
+
36
+**Description:**
37
+This command is used to specify the name of the file that contains the encoded CD-TEXT information for the disc. This command is only used with files that were either created with the graphical CD-TEXT editor or generated automatically by the software when copying a CD-TEXT enhanced disc.
38
+
39
+**Syntax:**
40
+```
41
+CDTEXTFILE [filename]
42
+```
43
+
44
+**Parameters:**
45
+ * **filename** – Filename (can include device/directory). If the filename contains any spaces, then it must be enclosed in quotation marks.
46
+
47
+**Examples:**
48
+```
49
+CDTEXTFILE C:\TEST\DISC.CDT
50
+CDTEXTFILE "C:\LONG FILENAME.CDT"
51
+```
52
+
53
+**Rules:**
54
+If your recorder does not support CD-TEXT, then this command will be ignored.
55
+
56
+
57
+
58
+
59
+FILE
60
+----
61
+
62
+**Description:**
63
+This command is used to specify a data/audio file that will be written to the recorder.
64
+
65
+**Syntax:**
66
+```
67
+FILE [filename] [filetype]
68
+```
69
+
70
+**Parameters:**
71
+ * **filename** – Filename (can include device/directory). If the filename contains any spaces, then it must be enclosed in quotation marks.
72
+ * **filetype** – Filetype The following filetypes are allowed…
73
+ * *BINARY* – Intel binary file (least significant byte first)
74
+ * *MOTOROLA* – Motorola binary file (most significant byte first)
75
+ * *AIFF* – Audio AIFF file
76
+ * *WAVE* – Audio WAVE file
77
+ * *MP3* – Audio MP3 file
78
+
79
+**Note:**
80
+All audio files (WAVE, AIFF, and MP3) must be in 44.1KHz 16-bit stereo format.
81
+
82
+**Examples:**
83
+```
84
+FILE "C:\DATA\TRACK1.ISO" BINARY
85
+FILE "C:\MUSIC\TRACK2.WAV" WAVE
86
+FILE "C:\MUSIC\LONG FILENAME.MP3″ MP3
87
+```
88
+
89
+**Rules:**
90
+FILE commands must appear before any other command except CATALOG. This rule contradicts the examples on this site: Note.
91
+
92
+**Note:**
93
+For AUDIO files, if the length of the data within the file is not an exact multiple of the CDROM sector size (2352 bytes), then the last sector will be padded with zeros when it is recorded to the blank disc.
94
+
95
+
96
+
97
+FLAGS
98
+-----
99
+
100
+**Description:**
101
+This command is used to set special subcode flags within a track. These flags are rarely used on any discs made today.
102
+
103
+**Syntax:**
104
+```
105
+FLAGS [flags]
106
+```
107
+
108
+**Parameters:**
109
+
110
+ * **flags** – Specifies one or more track flags. The following flags are allowed…
111
+ * *DCP* – Digital copy permitted
112
+ * *4CH* – Four channel audio
113
+ * *PRE* – Pre-emphasis enabled (audio tracks only)
114
+ * *SCMS* – Serial copy management system (not supported by all recorders)
115
+
116
+**Example:**
117
+```
118
+FLAGS DCP
119
+FLAGS 4CH PRE
120
+```
121
+
122
+**Rules:**
123
+The FLAGS command must appear after a TRACK command, but before any INDEX commands. Only one FLAGS command is allowed per track.
124
+
125
+**Note:**
126
+There is a fourth subcode flag called "DATA" which is set for all non-audio tracks. This flag is set automatically based on the datatype of the track.
127
+
128
+
129
+
130
+INDEX
131
+-----
132
+
133
+**Description:**
134
+This command is used to specify indexes (or subindexes) within a track.
135
+
136
+**Syntax:**
137
+```
138
+INDEX [number] [mm:ss:ff]
139
+```
140
+
141
+**Parameters:**
142
+ * **number** – Index number (0-99)
143
+ * **mm:ss:ff** – Starting time in minutes, seconds, and frames (75 frames/second).
144
+
145
+**Note:**
146
+All times are relative to the beginning of the current file.
147
+
148
+**Example:**
149
+```
150
+INDEX 01 00:00:00
151
+INDEX 05 02:34:50
152
+```
153
+
154
+**Rules:**
155
+All index numbers must be between 0 and 99 inclusive. The first index must be 0 or 1 with all other indexes being sequential to the first one. The first index of a file must start at 00:00:00.
156
+
157
+*INDEX 0* Specifies the starting time of the track "pregap".
158
+
159
+*INDEX 1* Specifies the starting time of the track data. This is the only index that is stored in the disc’s table-of-contents.
160
+
161
+*INDEX > 1* Specifies a subindex within a track.
162
+
163
+
164
+
165
+ISRC
166
+----
167
+
168
+**Description:**
169
+This command is used to specify a track’s "International Standard Recording Code" (ISRC). It will typically be used only when mastering a CD for commercial disc production.
170
+
171
+**Syntax:**
172
+```
173
+ISRC (code)
174
+```
175
+
176
+**Example:**
177
+```
178
+ISRC ABCDE1234567
179
+```
180
+
181
+**Rules:**
182
+The ISRC must be 12 characters in length. The first five characters are alphanumeric, but the last seven are numeric only. If it is used, the ISRC command must be specified after a TRACK command, but before any INDEX commands.
183
+
184
+
185
+
186
+PERFORMER
187
+---------
188
+
189
+**Description:**
190
+This command is used to specify the name of a perfomer for a CD-TEXT enhanced disc.
191
+
192
+**Syntax:**
193
+```
194
+PERFORMER [performer-string]
195
+```
196
+
197
+**Parameters:**
198
+ * **performer-string** – Name of performer. If the string contains any spaces, then it must be enclosed in quotation marks. Strings should be limited to 80 character or less.
199
+
200
+**Example:**
201
+```
202
+PERFORMER "The Beatles"
203
+```
204
+
205
+**Rules:**
206
+If the PERFORMER command appears before any TRACK commands, then the string will be encoded as the performer of the entire disc. If the command appears after a TRACK command, then the string will be encoded as the performer of the current track. Note: If your recorder does not support CD-TEXT, then this command will be ignored.
207
+
208
+
209
+
210
+
211
+POSTGAP
212
+-------
213
+
214
+**Description:**
215
+This command is used to specify the length of a track postgap. The postgap data is generated internally by your cdr software. No data is consumed from the current data file.
216
+
217
+**Syntax:**
218
+```
219
+POSTGAP [mm:ss:ff]
220
+```
221
+
222
+**Parameters:**
223
+ * **mm:ss:ff** – Specifies the postgap length in minutes, seconds, and frames.
224
+
225
+**Example:**
226
+```
227
+POSTGAP 00:02:00
228
+```
229
+
230
+**Rules:**
231
+The POSTGAP command must appear after all INDEX commands for the current track. Only one POSTGAP command is allowed per track.
232
+
233
+
234
+
235
+PREGAP
236
+------
237
+
238
+**Description:**
239
+This command is used to specify the length of a track pregap. The pregap data is generated internally by your cdr software. No data is consumed from the current data file.
240
+
241
+**Syntax:**
242
+```
243
+PREGAP [mm:ss:ff]
244
+```
245
+
246
+**Parameters:**
247
+ * **mm:ss:ff** – Specifies the pregap length in minutes, seconds, and frames.
248
+
249
+**Example:**
250
+```
251
+PREGAP 00:02:00
252
+```
253
+
254
+**Rules:**
255
+The PREGAP command must appear after a TRACK command, but before any INDEX commands. Only one PREGAP command is allowed per track.
256
+
257
+
258
+
259
+REM
260
+---
261
+
262
+**Description:**
263
+This command is used to put comments in your CUE SHEET file.
264
+
265
+**Syntax:**
266
+```
267
+REM (comment)
268
+```
269
+
270
+**Example:**
271
+```
272
+REM This is a comment
273
+```
274
+
275
+
276
+
277
+SONGWRITER
278
+----------
279
+
280
+**Description:**
281
+This command is used to specify the name of a songwriter for a CD-TEXT enhanced disc.
282
+
283
+**Syntax:**
284
+```
285
+SONGWRITER [songwriter-string]
286
+```
287
+
288
+**Parameters:**
289
+ * **songwriter-string** – Name of songwriter. If the string contains any spaces, then it must be enclosed in quotation marks. Strings should be limited to 80 character or less.
290
+
291
+**Example:**
292
+```
293
+SONGWRITER "Paul McCartney"
294
+```
295
+
296
+**Rules:**
297
+If the SONGWRITER command appears before any TRACK commands, then the string will be encoded as the songwriter of the entire disc. If the command appears after a TRACK command, then the string will be encoded as the songwriter of the current track. Note: If your recorder does not support CD-TEXT, then this command will be ignored.
298
+
299
+
300
+
301
+TITLE
302
+-----
303
+
304
+**Description:**
305
+This command is used to specify a title for a CD-TEXT enhanced disc.
306
+
307
+**Syntax:**
308
+```
309
+TITLE [title-string]
310
+```
311
+
312
+**Parameters:**
313
+ * **title-string** – Title of disc or track. If the string contains any spaces, then it must be enclosed in quotation marks. Strings should be limited to 80 character or less.
314
+
315
+**Example:**
316
+```
317
+TITLE "The Beatles – Abbey Road"
318
+TITLE "Here Comes the Sun"
319
+```
320
+
321
+**Rules:**
322
+If the TITLE command appears before any TRACK commands, then the string will be encoded as the title of the entire disc. If the command appears after a TRACK command, then the string will be encoded as the title of the current track. Note: If your recorder does not support CD-TEXT, then this command will be ignored.
323
+
324
+
325
+
326
+TRACK
327
+-----
328
+
329
+**Description:**
330
+This command is used to start a new TRACK.
331
+
332
+**Syntax:**
333
+```
334
+TRACK [number] [datatype]
335
+```
336
+
337
+**Parameters:**
338
+ * **number** – Track number (1-99)
339
+ * **datatype** – Track datatype The following datatypes are allowed…
340
+ * *AUDIO* – Audio/Music (2352)
341
+ * *CDG* – Karaoke CD+G (2448)
342
+ * *MODE1/2048* – CDROM Mode1 Data (cooked)
343
+ * *MODE1/2352* – CDROM Mode1 Data (raw)
344
+ * *MODE2/2336* – CDROM-XA Mode2 Data
345
+ * *MODE2/2352* – CDROM-XA Mode2 Data
346
+ * *CDI/2336* – CDI Mode2 Data
347
+ * *CDI/2352* – CDI Mode2 Data
348
+
349
+Supported datatypes and blocksizes by recorder model…
350
+
351
+**Rules:**
352
+All track numbers must be between 1 and 99 inclusive. The first track number can be greater than one, but all track numbers after the first must be sequential. You must specify at least one track per file.
353
+
354
+
355
+====
356
+
357
+<sup>*From http://digitalx.org/cue-sheet/syntax/index.html*</sup>
358
\ No newline at end of file
359
flacon-2.1.1.tar.gz/disk.cpp -> flacon-3.1.1.tar.gz/disk.cpp
Changed
31
1
2
#include "settings.h"
3
#include "project.h"
4
#include "inputaudiofile.h"
5
+#include "formats/format.h"
6
#include "outformat.h"
7
#include "internet/dataprovider.h"
8
9
10
}
11
12
QString audioExt;
13
- foreach (InputAudioFormat format, InputAudioFormat::allFormats())
14
- audioExt += (audioExt.isEmpty() ? "\\." : "|\\.") + format.ext();
15
+ foreach (const AudioFormat *format, AudioFormat::inputFormats())
16
+ audioExt += (audioExt.isEmpty() ? "\\." : "|\\.") + format->ext();
17
18
foreach (const QString &pattern, patterns)
19
{
20
21
return;
22
23
QStringList exts;
24
- foreach (InputAudioFormat format, InputAudioFormat::allFormats())
25
- exts << QString("*.%1").arg(format.ext());
26
+ foreach (const AudioFormat *format, AudioFormat::inputFormats())
27
+ exts << QString("*.%1").arg(format->ext());
28
29
QFileInfo cueFile(mCueFile);
30
QFileInfoList files = cueFile.dir().entryInfoList(exts, QDir::Files | QDir::Readable);
31
flacon-3.1.1.tar.gz/doc
Added
2
1
+(directory)
2
flacon-3.1.1.tar.gz/doc/WavPack5FileFormat.pdf
Added
flacon-3.1.1.tar.gz/formats
Added
2
1
+(directory)
2
flacon-3.1.1.tar.gz/formats/aac.cpp
Changed
2
1
(renamed from outformats/aac.cpp)
2
flacon-3.1.1.tar.gz/formats/aac.h
Changed
2
1
(renamed from outformats/aac.h)
2
flacon-3.1.1.tar.gz/formats/aac_config.ui
Changed
2
1
(renamed from outformats/aac_config.ui)
2
flacon-3.1.1.tar.gz/formats/ape.cpp
Added
64
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "ape.h"
29
+
30
+REGISTER_FORMAT(Format_Ape)
31
+
32
+
33
+/************************************************
34
+ *
35
+ ************************************************/
36
+QStringList Format_Ape::decoderArgs(const QString &fileName) const
37
+{
38
+ QStringList args;
39
+ args << fileName;
40
+ args << "-";
41
+ args << "-d";
42
+
43
+ return args;
44
+}
45
+
46
+
47
+/************************************************
48
+ *
49
+ ************************************************/
50
+QString Format_Ape::filterDecoderStderr(const QString &stdErr) const
51
+{
52
+ if (stdErr.startsWith("Progress:"))
53
+ return "";
54
+
55
+ if (stdErr.contains("-- Monkey's Audio Console Front End"))
56
+ return "";
57
+
58
+ if (stdErr.startsWith("Decompressing..."))
59
+ return "";
60
+
61
+ return stdErr;
62
+
63
+}
64
flacon-3.1.1.tar.gz/formats/ape.h
Added
54
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#ifndef APE_H
29
+#define APE_H
30
+
31
+#include "format.h"
32
+
33
+class Format_Ape: public AudioFormat
34
+{
35
+public:
36
+ virtual QString name() const { return "APE"; }
37
+ virtual QString ext() const { return "ape"; }
38
+ virtual bool isInputFormat() const { return true; }
39
+
40
+ virtual QByteArray magic() const { return "MAC "; }
41
+ virtual uint const magicOffset() const { return 0; }
42
+
43
+
44
+ virtual QString decoderProgramName() const { return "mac"; }
45
+ virtual QStringList decoderArgs(const QString &fileName) const;
46
+ virtual QString filterDecoderStderr(const QString &stdErr) const;
47
+
48
+ virtual bool isOutputFormat() const { return false; }
49
+
50
+
51
+};
52
+
53
+#endif // APE_H
54
flacon-3.1.1.tar.gz/formats/flac.cpp
Added
197
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2012-2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "flac.h"
29
+#include "settings.h"
30
+#include "project.h"
31
+#include "inputaudiofile.h"
32
+
33
+#include <QDebug>
34
+
35
+REGISTER_FORMAT(Format_Flac)
36
+
37
+
38
+/************************************************
39
+ *
40
+ ************************************************/
41
+QStringList Format_Flac::decoderArgs(const QString &fileName) const
42
+{
43
+ QStringList args;
44
+ args << "-c";
45
+ args << "-d";
46
+ args << "-s";
47
+ args << fileName;
48
+ args << "-";
49
+
50
+ return args;
51
+}
52
+
53
+
54
+/************************************************
55
+ *
56
+ ************************************************/
57
+OutFormat_Flac::OutFormat_Flac()
58
+{
59
+ mId = "FLAC";
60
+ mExt = "flac";
61
+ mName = "Flac";
62
+}
63
+
64
+
65
+
66
+/************************************************
67
+
68
+ ************************************************/
69
+bool OutFormat_Flac::check(QStringList *errors) const
70
+{
71
+ bool res = OutFormat::check(errors);
72
+
73
+ if (gainType() != OutFormat::GainDisable)
74
+ {
75
+ for (int i=0; i<project->count(); ++i)
76
+ {
77
+ if (project->disk(i)->audioFile()->sampleRate() > 48000)
78
+ {
79
+ *errors << QObject::tr("you can't use 'ReplayGain' for files with sample rates above 48kHz. Metaflac doesn't support such files.",
80
+ "This string should begin with a lowercase letter. This is a part of the complex sentence.");
81
+ res = false;
82
+ break;
83
+ }
84
+ }
85
+ }
86
+
87
+ return res;
88
+}
89
+
90
+
91
+/************************************************
92
+
93
+ ************************************************/
94
+QStringList OutFormat_Flac::encoderArgs(Track *track, const QString &outFile) const
95
+{
96
+ QStringList args;
97
+
98
+ args << settings->programName(encoderProgramName());
99
+ args << "--force"; // Force overwriting of output files.
100
+ args << "--silent"; // Suppress progress indicator
101
+
102
+ // Settings .................................................
103
+ args << QString("--compression-level-%1").arg(settings->value("Flac/Compression").toString());
104
+
105
+
106
+ // Tags .....................................................
107
+ if (!track->artist().isEmpty()) args << "--tag" << QString("artist=%1").arg(track->artist());
108
+ if (!track->album().isEmpty()) args << "--tag" << QString("album=%1").arg(track->album());
109
+ if (!track->genre().isEmpty()) args << "--tag" << QString("genre=%1").arg(track->genre());
110
+ if (!track->date().isEmpty()) args << "--tag" << QString("date=%1").arg(track->date());
111
+ if (!track->title().isEmpty()) args << "--tag" << QString("title=%1").arg(track->title());
112
+ if (!track->comment().isEmpty()) args << "--tag" << QString("comment=%1").arg(track->comment());
113
+ if (!track->disk()->discId().isEmpty()) args << "--tag" << QString("discId=%1").arg(track->disk()->discId());
114
+ args << "--tag" << QString("TRACKNUMBER=%1").arg(track->trackNum());
115
+ args << "--tag" << QString("TOTALTRACKS=%1").arg(track->disk()->count());
116
+ args << "--tag" << QString("TRACKTOTAL=%1").arg(track->disk()->count());
117
+
118
+
119
+ args << "-";
120
+ args << "-o" << outFile;
121
+ return args;
122
+}
123
+
124
+
125
+/************************************************
126
+
127
+ ************************************************/
128
+QStringList OutFormat_Flac::gainArgs(const QStringList &files) const
129
+{
130
+ QStringList args;
131
+ args << settings->programName(gainProgramName());
132
+ args << "--add-replay-gain";
133
+ args << files;
134
+
135
+ return args;
136
+}
137
+
138
+
139
+/************************************************
140
+
141
+ ************************************************/
142
+QHash<QString, QVariant> OutFormat_Flac::defaultParameters() const
143
+{
144
+ QHash<QString, QVariant> res;
145
+ res.insert("Flac/Compression", 5);
146
+ res.insert("Flac/ReplayGain", gainTypeToString(GainDisable));
147
+ return res;
148
+}
149
+
150
+
151
+/************************************************
152
+
153
+ ************************************************/
154
+EncoderConfigPage *OutFormat_Flac::configPage(QWidget *parent) const
155
+{
156
+ return new ConfigPage_Flac(parent);
157
+}
158
+
159
+
160
+/************************************************
161
+
162
+ ************************************************/
163
+ConfigPage_Flac::ConfigPage_Flac(QWidget *parent):
164
+ EncoderConfigPage(parent)
165
+{
166
+ setupUi(this);
167
+
168
+ setLosslessToolTip(flacCompressionSlider);
169
+ flacCompressionSpin->setToolTip(flacCompressionSlider->toolTip());
170
+ fillReplayGainComboBox(flacGainCbx);
171
+}
172
+
173
+
174
+/************************************************
175
+
176
+ ************************************************/
177
+void ConfigPage_Flac::load()
178
+{
179
+ loadWidget("Flac/Compression", flacCompressionSlider);
180
+ loadWidget("Flac/ReplayGain", flacGainCbx);
181
+}
182
+
183
+
184
+/************************************************
185
+
186
+ ************************************************/
187
+void ConfigPage_Flac::write()
188
+{
189
+ writeWidget("Flac/Compression", flacCompressionSlider);
190
+ writeWidget("Flac/ReplayGain", flacGainCbx);
191
+}
192
+
193
+
194
+
195
+
196
+
197
flacon-3.1.1.tar.gz/formats/flac.h
Added
80
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2012-2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#ifndef FLAC_H
29
+#define FLAC_H
30
+
31
+#include "outformat.h"
32
+#include "format.h"
33
+#include "configdialog.h"
34
+#include "ui_flac_config.h"
35
+
36
+class OutFormat_Flac: public OutFormat
37
+{
38
+public:
39
+ OutFormat_Flac();
40
+ bool check(QStringList *errors) const;
41
+
42
+ virtual QString encoderProgramName() const { return "flac"; }
43
+ virtual QString gainProgramName() const { return "metaflac"; }
44
+
45
+ virtual QStringList encoderArgs(Track *track, const QString &outFile) const;
46
+ virtual QStringList gainArgs(const QStringList &files) const;
47
+
48
+ QHash<QString, QVariant> defaultParameters() const;
49
+ EncoderConfigPage *configPage(QWidget *parent = 0) const;
50
+};
51
+
52
+class Format_Flac: public AudioFormat
53
+{
54
+public:
55
+ virtual QString name() const { return "FLAC"; }
56
+ virtual QString ext() const { return "flac"; }
57
+ virtual bool isInputFormat() const { return true; }
58
+
59
+ virtual QString decoderProgramName() const { return "flac"; }
60
+ virtual QStringList decoderArgs(const QString &fileName) const;
61
+
62
+ virtual QByteArray magic() const { return "fLaC"; }
63
+ virtual uint const magicOffset() const { return 0; }
64
+};
65
+
66
+
67
+class ConfigPage_Flac: public EncoderConfigPage, private Ui::ConfigPage_Flac
68
+{
69
+ Q_OBJECT
70
+public:
71
+ explicit ConfigPage_Flac(QWidget *parent = 0);
72
+
73
+ virtual void load();
74
+ virtual void write();
75
+
76
+};
77
+
78
+
79
+#endif // FLAC_H
80
flacon-3.1.1.tar.gz/formats/flac_config.ui
Changed
2
1
(renamed from outformats/flac_config.ui)
2
flacon-3.1.1.tar.gz/formats/format.cpp
Added
174
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "format.h"
29
+
30
+#include "flac.h"
31
+#include <QDebug>
32
+#include <QIODevice>
33
+#include <QByteArray>
34
+#include <QFile>
35
+
36
+AudioFormatList AudioFormat::mAllFormats;
37
+
38
+
39
+/************************************************
40
+ *
41
+ ************************************************/
42
+bool AudioFormat::registerFormat(const AudioFormat &f)
43
+{
44
+ // Some formats can be embedded as a chunk of RIFF stream.
45
+ // So the WAV format should be last and be checked in the last turn.
46
+ if (f.ext() == "wav")
47
+ mAllFormats.append(&f);
48
+ else
49
+ mAllFormats.insert(0, &f);
50
+ return true;
51
+}
52
+
53
+
54
+/************************************************
55
+ *
56
+ ************************************************/
57
+AudioFormat::AudioFormat()
58
+{
59
+}
60
+
61
+
62
+/************************************************
63
+ *
64
+ ************************************************/
65
+AudioFormat::~AudioFormat()
66
+{
67
+}
68
+
69
+
70
+/************************************************
71
+ *
72
+ ************************************************/
73
+const AudioFormatList &AudioFormat::allFormats()
74
+{
75
+ return mAllFormats;
76
+}
77
+
78
+
79
+/************************************************
80
+ *
81
+ ************************************************/
82
+const AudioFormatList &AudioFormat::inputFormats()
83
+{
84
+ static AudioFormatList res;
85
+ if (res.isEmpty())
86
+ {
87
+ foreach (const AudioFormat* f, allFormats())
88
+ {
89
+ if (f->isInputFormat())
90
+ res << f;
91
+ }
92
+ }
93
+
94
+ return res;
95
+}
96
+
97
+
98
+/************************************************
99
+ *
100
+ ************************************************/
101
+const AudioFormatList &AudioFormat::outFormats()
102
+{
103
+ static AudioFormatList res;
104
+ if (res.isEmpty())
105
+ {
106
+ foreach (const AudioFormat* f, allFormats())
107
+ {
108
+ if (f->isOutputFormat())
109
+ res << f;
110
+ }
111
+ }
112
+
113
+ return res;
114
+}
115
+
116
+
117
+/************************************************
118
+ *
119
+ ************************************************/
120
+bool AudioFormat::checkMagic(const QByteArray &data) const
121
+{
122
+ return data.mid(magicOffset(), magic().length()) == magic();
123
+}
124
+
125
+
126
+/************************************************
127
+ *
128
+ ************************************************/
129
+QString AudioFormat::filterDecoderStderr(const QString &stdErr) const
130
+{
131
+ return stdErr;
132
+}
133
+
134
+
135
+/************************************************
136
+ *
137
+ ************************************************/
138
+const AudioFormat *AudioFormat::formatForFile(QIODevice *device)
139
+{
140
+ int bufSize = 0;
141
+ foreach (const AudioFormat *format, allFormats())
142
+ bufSize = qMax(bufSize, int(format->magicOffset() + format->magic().length()));
143
+
144
+ QByteArray buf = device->read(bufSize);
145
+ if (buf.size() < bufSize)
146
+ return NULL;
147
+
148
+ foreach (const AudioFormat *format, allFormats())
149
+ {
150
+ if (format->checkMagic(buf))
151
+ return format;
152
+ }
153
+
154
+ return NULL;
155
+}
156
+
157
+
158
+/************************************************
159
+ *
160
+ ************************************************/
161
+const AudioFormat *AudioFormat::formatForFile(const QString &fileName)
162
+{
163
+ QFile file(fileName);
164
+ if (! file.open(QFile::ReadOnly))
165
+ {
166
+ return NULL;
167
+ }
168
+
169
+ const AudioFormat *res = formatForFile(&file);
170
+ file.close();
171
+ return res;
172
+}
173
+
174
flacon-3.1.1.tar.gz/formats/format.h
Added
86
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#ifndef FORMAT_H
29
+#define FORMAT_H
30
+
31
+#include <QList>
32
+#include <QStringList>
33
+#include <QByteArray>
34
+class QIODevice;
35
+
36
+class AudioFormat;
37
+typedef QList<const AudioFormat*> AudioFormatList;
38
+
39
+class AudioFormat
40
+{
41
+public:
42
+ AudioFormat();
43
+ virtual ~AudioFormat();
44
+
45
+ virtual QString name() const = 0;
46
+ virtual QString ext() const = 0;
47
+
48
+ virtual bool isInputFormat() const { return false; }
49
+
50
+ virtual QString decoderProgramName() const { return ""; }
51
+ virtual QStringList decoderArgs(const QString &fileName) const { return QStringList(); }
52
+ virtual QByteArray magic() const = 0;
53
+ virtual uint const magicOffset() const { return 0; }
54
+
55
+
56
+ // Out format
57
+ virtual bool isOutputFormat() const { return false; }
58
+
59
+ static const AudioFormatList &allFormats();
60
+ static const AudioFormatList &inputFormats();
61
+ static const AudioFormatList &outFormats();
62
+
63
+ static const AudioFormat *formatForFile(QIODevice *device);
64
+ static const AudioFormat *formatForFile(const QString &fileName);
65
+
66
+ static bool registerFormat(const AudioFormat &f);
67
+
68
+ virtual QString filterDecoderStderr(const QString &stdErr) const;
69
+
70
+
71
+protected:
72
+ virtual bool checkMagic(const QByteArray &data) const;
73
+
74
+private:
75
+ static QList<const AudioFormat*> mAllFormats;
76
+};
77
+
78
+
79
+
80
+
81
+#define REGISTER_FORMAT(FORMAT) \
82
+ static FORMAT static_##FORMAT##_Instance; \
83
+ static bool is_##FORMAT##_loaded = AudioFormat::registerFormat(static_##FORMAT##_Instance);
84
+
85
+#endif // FORMAT_H
86
flacon-3.1.1.tar.gz/formats/mp3.cpp
Changed
2
1
(renamed from outformats/mp3.cpp)
2
flacon-3.1.1.tar.gz/formats/mp3.h
Changed
2
1
(renamed from outformats/mp3.h)
2
flacon-3.1.1.tar.gz/formats/mp3_config.ui
Changed
2
1
(renamed from outformats/mp3_config.ui)
2
flacon-3.1.1.tar.gz/formats/ogg.cpp
Changed
2
1
(renamed from outformats/ogg.cpp)
2
flacon-3.1.1.tar.gz/formats/ogg.h
Changed
2
1
(renamed from outformats/ogg.h)
2
flacon-3.1.1.tar.gz/formats/ogg_config.ui
Changed
2
1
(renamed from outformats/ogg_config.ui)
2
flacon-3.1.1.tar.gz/formats/opus.cpp
Changed
2
1
(renamed from outformats/opus.cpp)
2
flacon-3.1.1.tar.gz/formats/opus.h
Changed
2
1
(renamed from outformats/opus.h)
2
flacon-3.1.1.tar.gz/formats/opus_config.ui
Changed
2
1
(renamed from outformats/opus_config.ui)
2
flacon-3.1.1.tar.gz/formats/outformat.cpp
Changed
2
1
(renamed from outformats/outformat.cpp)
2
flacon-3.1.1.tar.gz/formats/outformat.h
Changed
2
1
(renamed from outformats/outformat.h)
2
flacon-3.1.1.tar.gz/formats/tta.cpp
Added
60
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "tta.h"
29
+#include <QDebug>
30
+
31
+REGISTER_FORMAT(Format_Tta)
32
+
33
+
34
+/************************************************
35
+ *
36
+ ************************************************/
37
+QStringList Format_Tta::decoderArgs(const QString &fileName) const
38
+{
39
+ QStringList args;
40
+ args << fileName;
41
+ args << "-";
42
+ args << "-d";
43
+
44
+ return args;
45
+}
46
+
47
+
48
+/************************************************
49
+ *
50
+ ************************************************/
51
+QString Format_Tta::filterDecoderStderr(const QString &stdErr) const
52
+{
53
+
54
+ int pos = stdErr.indexOf("Error:");
55
+ if (pos>-1)
56
+ return stdErr.mid(pos + 6).trimmed();
57
+
58
+ return "";
59
+}
60
flacon-3.1.1.tar.gz/formats/tta.h
Added
53
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#ifndef TTA_H
29
+#define TTA_H
30
+
31
+#include "format.h"
32
+
33
+class Format_Tta: public AudioFormat
34
+{
35
+public:
36
+ virtual QString name() const { return "TTA"; }
37
+ virtual QString ext() const { return "tta"; }
38
+ virtual QByteArray magic() const { return "TTA1"; }
39
+ virtual uint const magicOffset() const { return 0; }
40
+
41
+
42
+ virtual bool isInputFormat() const { return true; }
43
+ virtual QString decoderProgramName() const { return "ttaenc"; }
44
+ virtual QStringList decoderArgs(const QString &fileName) const;
45
+ virtual QString filterDecoderStderr(const QString &stdErr) const;
46
+
47
+ virtual bool isOutputFormat() const { return false; }
48
+
49
+
50
+};
51
+
52
+#endif // TTA_H
53
flacon-3.1.1.tar.gz/formats/wav.cpp
Added
153
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2012-2013
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "wav.h"
29
+#include <QFile>
30
+
31
+REGISTER_FORMAT(Format_Wav)
32
+
33
+/************************************************
34
+ *
35
+ ************************************************/
36
+QStringList Format_Wav::decoderArgs(const QString &fileName) const
37
+{
38
+ return QStringList();
39
+}
40
+
41
+
42
+/************************************************
43
+
44
+ ************************************************/
45
+OutFormat_Wav::OutFormat_Wav()
46
+{
47
+ mId = "WAV";
48
+ mExt = "wav";
49
+ mName = "WAV";
50
+}
51
+
52
+
53
+/************************************************
54
+
55
+ ************************************************/
56
+QStringList OutFormat_Wav::encoderArgs(Track *track, const QString &outFile) const
57
+{
58
+ return QStringList();
59
+}
60
+
61
+
62
+/************************************************
63
+
64
+ ************************************************/
65
+QStringList OutFormat_Wav::gainArgs(const QStringList &files) const
66
+{
67
+ return QStringList();
68
+}
69
+
70
+
71
+/************************************************
72
+
73
+ ************************************************/
74
+Encoder *OutFormat_Wav::createEncoder(Track *track, QObject *parent) const
75
+{
76
+ return new Encoder_Wav(this, track, parent);
77
+}
78
+
79
+
80
+/************************************************
81
+
82
+ ************************************************/
83
+Gain *OutFormat_Wav::createGain(Disk *disk, Track *track, QObject *parent) const
84
+{
85
+ return 0;
86
+}
87
+
88
+
89
+/************************************************
90
+
91
+ ************************************************/
92
+QHash<QString, QVariant> OutFormat_Wav::defaultParameters() const
93
+{
94
+ QHash<QString, QVariant> res;
95
+ return res;
96
+}
97
+
98
+
99
+/************************************************
100
+
101
+ ************************************************/
102
+EncoderConfigPage *OutFormat_Wav::configPage(QWidget *parent) const
103
+{
104
+ return 0;
105
+}
106
+
107
+
108
+/************************************************
109
+
110
+ ************************************************/
111
+Encoder_Wav::Encoder_Wav(const OutFormat *format, Track *track, QObject *parent):
112
+ Encoder(format, track, parent)
113
+{
114
+}
115
+
116
+
117
+/************************************************
118
+
119
+ ************************************************/
120
+void Encoder_Wav::doRun()
121
+{
122
+ QFile srcFile(inputFile());
123
+ QFile destFile(outFile());
124
+
125
+ bool res = (!destFile.exists() || destFile.remove());
126
+
127
+ if (res)
128
+ res = srcFile.rename(outFile());
129
+
130
+ if (!res)
131
+ {
132
+ error(track(),
133
+ tr("I can't rename file:\n%1 to %2\n%3").arg(
134
+ inputFile(),
135
+ outFile(),
136
+ srcFile.errorString()));
137
+ }
138
+}
139
+
140
+
141
+/************************************************
142
+
143
+ ************************************************/
144
+QStringList Encoder_Wav::processArgs() const
145
+{
146
+ return QStringList();
147
+}
148
+
149
+
150
+
151
+
152
+
153
flacon-3.1.1.tar.gz/formats/wav.h
Added
83
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2012-2013
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#ifndef WAV_H
29
+#define WAV_H
30
+
31
+#include "outformat.h"
32
+#include "format.h"
33
+#include "encoder.h"
34
+
35
+class OutFormat_Wav: public OutFormat
36
+{
37
+public:
38
+ OutFormat_Wav();
39
+
40
+ virtual QString encoderProgramName() const { return ""; }
41
+ virtual QString gainProgramName() const { return ""; }
42
+
43
+ virtual QStringList encoderArgs(Track *track, const QString &outFile) const;
44
+ virtual QStringList gainArgs(const QStringList &files) const;
45
+
46
+
47
+ QHash<QString, QVariant> defaultParameters() const;
48
+ EncoderConfigPage *configPage(QWidget *parent = 0) const;
49
+
50
+ virtual bool hasConfigPage() const { return false; }
51
+
52
+ virtual Encoder *createEncoder(Track *track, QObject *parent = 0) const;
53
+ virtual Gain *createGain(Disk *disk, Track *track, QObject *parent = 0) const;
54
+};
55
+
56
+
57
+class Encoder_Wav: public Encoder
58
+{
59
+ Q_OBJECT
60
+public:
61
+ explicit Encoder_Wav(const OutFormat *format, Track *track, QObject *parent = 0);
62
+
63
+protected:
64
+ void doRun();
65
+ virtual QStringList processArgs() const;
66
+};
67
+
68
+class Format_Wav: public AudioFormat
69
+{
70
+public:
71
+ virtual QString name() const { return "WAV"; }
72
+ virtual QString ext() const { return "wav"; }
73
+ virtual bool isInputFormat() const { return true; }
74
+
75
+ virtual QString decoderProgramName() const { return ""; }
76
+ virtual QStringList decoderArgs(const QString &fileName) const;
77
+
78
+ virtual QByteArray magic() const { return "RIFF"; }
79
+ virtual uint const magicOffset() const { return 0; }
80
+};
81
+
82
+#endif // WAV_H
83
flacon-3.1.1.tar.gz/formats/wv.cpp
Added
171
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2012-2013
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "wv.h"
29
+#include "settings.h"
30
+#include <QDebug>
31
+
32
+REGISTER_FORMAT(Format_Wv)
33
+
34
+/************************************************
35
+ * As I understand WavPack can be embedded as a chunk of a RIFF stream.
36
+ * I have not such a file, if anyone has one, please send me.
37
+ ************************************************/
38
+bool Format_Wv::checkMagic(const QByteArray &data) const
39
+{
40
+ return data.contains(magic());
41
+}
42
+
43
+
44
+/************************************************
45
+ *
46
+ ************************************************/
47
+QStringList Format_Wv::decoderArgs(const QString &fileName) const
48
+{
49
+ QStringList args;
50
+ args << "-q";
51
+ args << "-y";
52
+ args << fileName;
53
+ args << "-o" << "-";
54
+
55
+ return args;
56
+}
57
+
58
+
59
+/************************************************
60
+
61
+ ************************************************/
62
+OutFormat_Wv::OutFormat_Wv()
63
+{
64
+ mId = "WV";
65
+ mExt = "wv";
66
+ mName = "WavPack";
67
+}
68
+
69
+
70
+/************************************************
71
+
72
+ ************************************************/
73
+QStringList OutFormat_Wv::encoderArgs(Track *track, const QString &outFile) const
74
+{
75
+ QStringList args;
76
+
77
+ args << settings->programName(encoderProgramName());
78
+
79
+ args << "-q"; // Suppress progress indicator
80
+
81
+ // Settings .................................................
82
+ int compression = settings->value("WV/Compression").toInt();
83
+ if (compression == 0) args << "-f";
84
+ if (compression == 1) args << "-h";
85
+ if (compression == 2) args << "-hh";
86
+
87
+ // Tags .....................................................
88
+ if (!track->artist().isEmpty()) args << "-w" << QString("Artist=%1").arg(track->artist());
89
+ if (!track->album().isEmpty()) args << "-w" << QString("Album=%1").arg(track->album());
90
+ if (!track->genre().isEmpty()) args << "-w" << QString("Genre=%1").arg(track->genre());
91
+ if (!track->date().isEmpty()) args << "-w" << QString("Year=%1").arg(track->date());
92
+ if (!track->title().isEmpty()) args << "-w" << QString("Title=%1").arg(track->title());
93
+ if (!track->disk()->discId().isEmpty()) args << "-w" << QString("DiscId=%1").arg(track->disk()->discId());
94
+ if (!track->comment().isEmpty()) args << "-w" << QString("Comment=%1").arg(track->comment());
95
+ args << "-w" << QString("Track=%1/%2").arg(track->trackNum()).arg(track->disk()->count());
96
+
97
+ args << "-";
98
+ args << "-o" << outFile;
99
+
100
+ return args;
101
+}
102
+
103
+
104
+/************************************************
105
+
106
+ ************************************************/
107
+QStringList OutFormat_Wv::gainArgs(const QStringList &files) const
108
+{
109
+ QStringList args;
110
+ args << args << settings->programName(gainProgramName());
111
+ args << "-a";
112
+ args << files;
113
+
114
+ return args;
115
+}
116
+
117
+
118
+/************************************************
119
+
120
+ ************************************************/
121
+QHash<QString, QVariant> OutFormat_Wv::defaultParameters() const
122
+{
123
+ QHash<QString, QVariant> res;
124
+ res.insert("WV/Compression", 1);
125
+ res.insert("WV/ReplayGain", gainTypeToString(GainDisable));
126
+ return res;
127
+}
128
+
129
+
130
+/************************************************
131
+
132
+ ************************************************/
133
+EncoderConfigPage *OutFormat_Wv::configPage(QWidget *parent) const
134
+{
135
+ return new ConfigPage_Wv(parent);
136
+}
137
+
138
+
139
+/************************************************
140
+
141
+ ************************************************/
142
+ConfigPage_Wv::ConfigPage_Wv(QWidget *parent):
143
+ EncoderConfigPage(parent)
144
+{
145
+ setupUi(this);
146
+
147
+ setLosslessToolTip(wvCompressionSlider);
148
+ wvCompressionSpin->setToolTip(wvCompressionSlider->toolTip());
149
+ fillReplayGainComboBox(wvGainCbx);
150
+}
151
+
152
+
153
+/************************************************
154
+
155
+ ************************************************/
156
+void ConfigPage_Wv::load()
157
+{
158
+ loadWidget("WV/Compression", wvCompressionSlider);
159
+ loadWidget("WV/ReplayGain", wvGainCbx);
160
+}
161
+
162
+
163
+/************************************************
164
+
165
+ ************************************************/
166
+void ConfigPage_Wv::write()
167
+{
168
+ writeWidget("WV/Compression", wvCompressionSlider);
169
+ writeWidget("WV/ReplayGain", wvGainCbx);
170
+}
171
flacon-3.1.1.tar.gz/formats/wv.h
Added
83
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2012-2013
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#ifndef WV_H
29
+#define WV_H
30
+
31
+#include "format.h"
32
+#include "outformat.h"
33
+#include "configdialog.h"
34
+#include "ui_wv_config.h"
35
+
36
+class OutFormat_Wv: public OutFormat
37
+{
38
+public:
39
+ OutFormat_Wv();
40
+
41
+ virtual QString encoderProgramName() const { return "wavpack"; }
42
+ virtual QString gainProgramName() const { return "wvgain"; }
43
+
44
+ virtual QStringList encoderArgs(Track *track, const QString &outFile) const;
45
+ virtual QStringList gainArgs(const QStringList &files) const;
46
+
47
+ QHash<QString, QVariant> defaultParameters() const;
48
+ EncoderConfigPage *configPage(QWidget *parent = 0) const;
49
+
50
+};
51
+
52
+class Format_Wv: public AudioFormat
53
+{
54
+public:
55
+ virtual QString name() const { return "WavPack"; }
56
+ virtual QString ext() const { return "wv"; }
57
+ virtual QByteArray magic() const { return "wvpk"; }
58
+ virtual uint const magicOffset() const { return 0; }
59
+
60
+
61
+ virtual bool isInputFormat() const { return true; }
62
+ virtual QString decoderProgramName() const { return "wvunpack"; }
63
+ virtual QStringList decoderArgs(const QString &fileName) const;
64
+
65
+ virtual bool isOutputFormat() const { return false; }
66
+
67
+protected:
68
+ virtual bool checkMagic(const QByteArray &data) const;
69
+
70
+};
71
+
72
+class ConfigPage_Wv: public EncoderConfigPage, private Ui::ConfigPage_Wv
73
+{
74
+ Q_OBJECT
75
+public:
76
+ explicit ConfigPage_Wv(QWidget *parent = 0);
77
+
78
+ virtual void load();
79
+ virtual void write();
80
+};
81
+
82
+#endif // WV_H
83
flacon-3.1.1.tar.gz/formats/wv_config.ui
Changed
2
1
(renamed from outformats/wv_config.ui)
2
flacon-2.1.1.tar.gz/gui/aboutdialog/aboutdialog.cpp -> flacon-3.1.1.tar.gz/gui/aboutdialog/aboutdialog.cpp
Changed
11
1
2
{
3
AboutInfo result;
4
5
- result.add("shntool",
6
- "http://etree.org/shnutils/shntool");
7
-
8
result.add("flac and metaflac",
9
"http://flac.sourceforge.net");
10
11
flacon-2.1.1.tar.gz/gui/controls.cpp -> flacon-3.1.1.tar.gz/gui/controls.cpp
Changed
10
1
2
void ProgramEdit::openDialog()
3
{
4
QString flt = tr("%1 program",
5
- "This is part of filter for 'select program' dialog. %1 is a name of required program. Example: 'shntool program (shntool)'"
6
+ "This is part of filter for 'select program' dialog. %1 is a name of required program. Example: 'flac program (flac)'"
7
).arg(mProgramName) +
8
QString(" (%1);;").arg(mProgramName) +
9
tr("All files", "This is part of filter for 'select program' dialog. 'All files (*)'") +
10
flacon-2.1.1.tar.gz/gui/mainwindow.cpp -> flacon-3.1.1.tar.gz/gui/mainwindow.cpp
Changed
23
1
2
#include "converter/converter.h"
3
#include "outformat.h"
4
#include "inputaudiofile.h"
5
+#include "formats/format.h"
6
#include "configdialog/configdialog.h"
7
#include "aboutdialog/aboutdialog.h"
8
#include "cuediskselectdialog/cuediskselectdialog.h"
9
10
11
if (includeAudio)
12
{
13
- foreach(InputAudioFormat format, InputAudioFormat::allFormats())
14
+ foreach(const AudioFormat *format, AudioFormat::inputFormats())
15
{
16
- allFlt << QString(" *.%1").arg(format.ext());
17
- flt << fltPattern.arg(format.name(), format.ext());
18
+ allFlt << QString(" *.%1").arg(format->ext());
19
+ flt << fltPattern.arg(format->name(), format->ext());
20
}
21
}
22
23
flacon-2.1.1.tar.gz/gui/trackview.cpp -> flacon-3.1.1.tar.gz/gui/trackview.cpp
Changed
46
1
2
QModelIndexList idxs = selectionModel()->selectedIndexes();
3
foreach(QModelIndex index, idxs)
4
{
5
- QObject *obj = static_cast<QObject*>(index.internalPointer());
6
- Track *track = qobject_cast<Track*>(obj);
7
+ Track *track = mModel->trackByIndex(index);
8
if (track)
9
res << track;
10
}
11
12
QModelIndexList idxs = selectionModel()->selectedIndexes();
13
foreach(QModelIndex index, idxs)
14
{
15
- QObject *obj = static_cast<QObject*>(index.internalPointer());
16
- Track *track = qobject_cast<Track*>(obj);
17
- if (track)
18
- set << track->disk();
19
-
20
- Disk *disk = qobject_cast<Disk*>(obj);
21
+ Disk *disk = mModel->diskByIndex(index);
22
if (disk)
23
set << disk;
24
}
25
26
for (int i=0; i<this->model()->rowCount(); ++i)
27
{
28
QModelIndex index = this->model()->index(i, 0);
29
- QObject *obj = static_cast<QObject*>(index.internalPointer());
30
31
- Disk *d = qobject_cast<Disk*>(obj);
32
+ Disk *d = mModel->diskByIndex(index);
33
if (d && d == disk)
34
{
35
this->selectionModel()->select(index, QItemSelectionModel::Clear | QItemSelectionModel::Select);
36
37
************************************************/
38
void TrackView::showTrackMenu(const QModelIndex &index, const QRect &buttonRect)
39
{
40
- QObject *obj = static_cast<QObject*>(index.internalPointer());
41
- Disk *disk = qobject_cast<Disk*>(obj);
42
+ Disk *disk = mModel->diskByIndex(index);
43
if(!disk)
44
return;
45
46
flacon-2.1.1.tar.gz/gui/trackviewdelegate.cpp -> flacon-3.1.1.tar.gz/gui/trackviewdelegate.cpp
Changed
149
1
2
#include "trackviewdelegate.h"
3
#include "trackview.h"
4
#include "trackviewmodel.h"
5
-#include "disk.h"
6
#include "project.h"
7
#include "internet/dataprovider.h"
8
9
10
************************************************/
11
void TrackViewDelegate::drawBranch(QPainter *painter, const QRect &rect, const QModelIndex &index) const
12
{
13
- QColor bgColor = (index.row() % 2) ? mTrackView->palette().base().color() : mTrackView->palette().alternateBase().color();
14
+ QColor bgColor = mTrackView->palette().base().color();
15
if (rect.isValid())
16
painter->fillRect(rect, bgColor);
17
18
19
QStyleOptionViewItem opt = option;
20
opt.state &= ~QStyle::State_Selected;
21
22
- QObject *obj = static_cast<QObject*>(index.internalPointer());
23
- Track *track = qobject_cast<Track*>(obj);
24
- if (track)
25
- {
26
- QColor bgColor = (index.row() % 2) ? mTrackView->palette().base().color() : mTrackView->palette().alternateBase().color();
27
- painter->fillRect(opt.rect, bgColor);
28
+ TrackViewModel::ItemType type = TrackViewModel::ItemType(index.data(TrackViewModel::RoleItemType).toInt());
29
30
- paintTrack(painter, opt, index, track);
31
+ if (type == TrackViewModel::TrackItem)
32
+ {
33
+#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
34
+ if (index.row() % 2)
35
+ painter->fillRect(option.rect, mTrackView->palette().base().color());
36
+ else
37
+ painter->fillRect(option.rect, mTrackView->palette().alternateBase().color());
38
+#else
39
+ if (index.row() % 2)
40
+ opt.features &= ~QStyleOptionViewItemV2::Alternate;
41
+ else
42
+ opt.features |= QStyleOptionViewItemV2::Alternate;
43
+#endif
44
+ paintTrack(painter, opt, index);
45
return;
46
}
47
48
- if (index.column() == 0)
49
+
50
+ if (type == TrackViewModel::DiskItem && index.column() == 0)
51
{
52
- Disk *disk = qobject_cast<Disk*>(obj);
53
- if (disk)
54
+ QColor bgColor = mTrackView->palette().base().color();
55
+ painter->fillRect(opt.rect, bgColor);
56
+
57
+ if (mTrackView-> selectionModel()->isSelected(index))
58
{
59
- QColor bgColor = mTrackView->palette().base().color();
60
- painter->fillRect(opt.rect, bgColor);
61
-
62
- if (mTrackView-> selectionModel()->isSelected(index))
63
- {
64
- QRect rect = opt.rect;
65
- if (index.row() > 0)
66
- rect.setTop(rect.top() + TOP_PADDING);
67
- drawSelectionMark(painter, rect);
68
- }
69
-
70
- paintDisk(painter, opt, index, disk);
71
+ QRect rect = opt.rect;
72
+ if (index.row() > 0)
73
+ rect.setTop(rect.top() + TOP_PADDING);
74
+ drawSelectionMark(painter, rect);
75
}
76
+
77
+ paintDisk(painter, opt, index);
78
+ return;
79
}
80
}
81
82
83
/************************************************
84
85
************************************************/
86
-void TrackViewDelegate::paintTrack(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, const Track *track) const
87
+void TrackViewDelegate::paintTrack(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
88
{
89
QStyledItemDelegate::paint(painter, option, index);
90
91
92
93
const QPixmap *icon = 0;
94
QString txt;
95
- int progress = track->progress();
96
+ int progress = index.data(TrackViewModel::RolePercent).toInt();
97
98
- switch (track->status())
99
+ switch (index.data(TrackViewModel::RoleStatus).toInt())
100
{
101
case Track::NotRunning: txt = ""; progress = -1; break;
102
case Track::Canceled: txt = ""; break;
103
104
}
105
106
107
-
108
painter->save();
109
painter->translate(option.rect.left() + 30, option.rect.top());
110
QRect windowRect(0, 0, option.rect.width() - 31, option.rect.height());
111
112
/************************************************
113
114
************************************************/
115
-void TrackViewDelegate::paintDisk(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, const Disk *disk) const
116
+void TrackViewDelegate::paintDisk(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
117
{
118
QRect paintRect = option.rect;
119
paintRect.setLeft(0);
120
121
QRect tFileRect(l, tTop, windowRect.width(), th);
122
QRect aFileRect(l, aTop, windowRect.width(), th);
123
124
- tFileRect = drawFile(disk->tagsTitle(), tFileRect, painter);
125
- QFileInfo fi(disk->audioFileName());
126
+ tFileRect = drawFile(index.data(TrackViewModel::RoleTitle).toString(), tFileRect, painter);
127
+ QFileInfo fi(index.data(TrackViewModel::RoleAudioFileName).toString());
128
aFileRect = drawFile(fi.fileName(), aFileRect, painter);
129
130
131
132
// Draw bottom line ................................
133
painter->setPen(mTrackView->palette().dark().color());
134
int y = option.rect.height() - BOTTOM_PADDING - 2;
135
- painter->drawLine(MARGIN, y, windowRect.right(), y);
136
+ painter->drawLine(MARGIN * 2, y, windowRect.right(), y);
137
138
// Draw warning mark ...............................
139
QRect markRect(imgRect.right() - MARK_HEIGHT, imgRect.bottom() - MARK_HEIGHT, MARK_HEIGHT, MARK_HEIGHT);
140
- if (!disk->canConvert())
141
+ if (!index.data(TrackViewModel::RoleCanConvert).toBool())
142
painter->drawPixmap(markRect, mWarnPix);
143
144
- cache->isWaiting = disk->isDownloads();
145
+ cache->isWaiting = index.data(TrackViewModel::RoleIsDownloads).toBool();
146
if (cache->isWaiting)
147
{
148
painter->drawPixmap(markRect, mDownloadMovie.currentPixmap());
149
flacon-2.1.1.tar.gz/gui/trackviewdelegate.h -> flacon-3.1.1.tar.gz/gui/trackviewdelegate.h
Changed
21
1
2
#include <QRect>
3
#include <QMovie>
4
5
-class Track;
6
-class Disk;
7
class TrackView;
8
class TrackViewCache;
9
class DataProvider;
10
11
12
QFont titleFont(const QFont &font) const;
13
QFont filesFont(const QFont &font) const;
14
- void paintTrack(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, const Track *track) const;
15
- void paintDisk(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, const Disk *disk) const;
16
+ void paintTrack(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
17
+ void paintDisk(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
18
QRect drawLabel(const QString &text, QRect rect, QPainter *painter) const;
19
QRect drawFile(const QString &text, QRect rect, QPainter *painter) const;
20
void drawSelectionMark(QPainter *painter, const QRect &rect) const;
21
flacon-2.1.1.tar.gz/gui/trackviewmodel.cpp -> flacon-3.1.1.tar.gz/gui/trackviewmodel.cpp
Changed
295
1
2
#include <QDebug>
3
#include <QSet>
4
5
+class IndexData
6
+{
7
+public:
8
+ explicit IndexData(const QModelIndex &index)
9
+ {
10
+ mDiskId = (quint32(index.internalId()) & 0xFFFFFF);
11
+ mTrackId = (quint32(index.internalId()) >> 16);
12
+ }
13
+
14
+ explicit IndexData(quint16 diskNum, quint16 trackNum)
15
+ {
16
+ mDiskId = diskNum + 1;
17
+ mTrackId = trackNum + 1;
18
+ }
19
+
20
+ explicit IndexData(quint16 diskNum)
21
+ {
22
+ mDiskId = diskNum + 1;
23
+ mTrackId = 0;
24
+ }
25
+
26
+#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
27
+ quint32 asPtr()
28
+ {
29
+ return quint32((mTrackId << 16) | mDiskId);
30
+ }
31
+#else
32
+ quintptr asPtr()
33
+ {
34
+ return quintptr((mTrackId << 16) | mDiskId);
35
+ }
36
+#endif
37
+
38
+
39
+ bool isDisk() const { return mDiskId > 0; }
40
+ bool isTrack() const { return mTrackId > 0; }
41
+
42
+ int diskNum() const { return mDiskId - 1; }
43
+ int trackNum() const { return mTrackId - 1; }
44
+
45
+ Disk *disk() const
46
+ {
47
+ if (mDiskId && mDiskId-1 < project->count())
48
+ return project->disk(mDiskId - 1);
49
+
50
+ return NULL;
51
+ }
52
+
53
+ Track *track() const
54
+ {
55
+ if (mTrackId)
56
+ {
57
+ Disk *disk = this->disk();
58
+ if (disk && mTrackId -1 < disk->count())
59
+ return disk->track(mTrackId - 1);
60
+ }
61
+ return NULL;
62
+ }
63
+
64
+private:
65
+ quint16 mDiskId;
66
+ quint16 mTrackId;
67
+};
68
+
69
70
/************************************************
71
72
73
connect(project, SIGNAL(diskChanged(Disk*)), this, SLOT(diskDataChanged(Disk*)));
74
connect(project, SIGNAL(trackChanged(int,int)), this, SLOT(trackDataChanged(int,int)));
75
connect(project, SIGNAL(layoutChanged()), this, SIGNAL(layoutChanged()));
76
- connect(project, SIGNAL(beforeRemoveDisk(Disk*)), this, SLOT(beforeRemoveDisk(Disk*)));
77
- connect(project, SIGNAL(afterRemoveDisk()), this, SLOT(afterRemoveDisk()));
78
+ connect(project, SIGNAL(afterRemoveDisk()), this, SIGNAL(layoutChanged()));
79
80
connect(project, SIGNAL(trackProgress(const Track*)), this, SLOT(trackProgressChanged(const Track*)));
81
-
82
- //connect(project, SIGNAL("downloadStarted(int)"), self._downloadStarted)
83
- //self.connect(project, SIGNAL("downloadFinished(int)"), self._downloadFinished)
84
}
85
86
87
88
}
89
90
91
-
92
-
93
/************************************************
94
95
************************************************/
96
97
return QModelIndex();
98
99
100
- if (parent.internalPointer() == project)
101
- return createIndex(row, column, project->disk(row));
102
-
103
- QObject *obj = static_cast<QObject*>(parent.internalPointer());
104
- Disk *disk = qobject_cast<Disk*>(obj);
105
- if(disk)
106
- return createIndex(row, column, disk->track(row));
107
- else
108
- return createIndex(row, column, project->disk(row));
109
+ if (IndexData(parent).isTrack())
110
+ return QModelIndex();
111
112
+ if (IndexData(parent).isDisk())
113
+ return createIndex(row, column, IndexData(parent.row(), row).asPtr());
114
115
- return QModelIndex();
116
+ return createIndex(row, column, IndexData(row).asPtr());
117
}
118
119
120
121
if (!child.isValid())
122
return QModelIndex();
123
124
- QObject *obj = static_cast<QObject*>(child.internalPointer());
125
- Track *track = qobject_cast<Track*>(obj);
126
- if (track)
127
- {
128
- int row = project->indexOf(track->disk());
129
- return index(row, 0, QModelIndex());
130
- }
131
+ IndexData data(child);
132
+ if (data.isTrack())
133
+ return index(data.diskNum(), 0, QModelIndex());
134
135
return QModelIndex();
136
}
137
138
if (!index.isValid())
139
return QVariant();
140
141
- Track *track = trackByIndex(index);
142
+ IndexData indexData(index);
143
+
144
+ Track *track = indexData.track();
145
if (track)
146
return trackData(track, index, role);
147
148
- Disk *disk = diskByIndex(index);
149
+ Disk *disk = indexData.disk();
150
if(disk)
151
return diskData(disk, index, role);
152
153
154
return QVariant();
155
156
}
157
- // StatusPercent ::::::::::::::::::::::::::::::::::::
158
-// if (role == StatusPercentRole)
159
-// {
160
-// // return track.progress()
161
-// }
162
-
163
-// // Status :::::::::::::::::::::::::::::::::::::::::::
164
-// if (role == StatusRole)
165
-// {
166
-// // return track.status();
167
-// }
168
+
169
+ switch (role)
170
+ {
171
+ case RoleItemType: return TrackItem;
172
+ case RolePercent: return track->progress();
173
+ case RoleStatus: return track->status();
174
+ case RoleTracknum: return track->trackNum();
175
+ case RoleDuration: return track->duration();
176
+ case RoleTitle: return track->title();
177
+ case RoleArtist: return track->artist();
178
+ case RoleAlbum: return track->album();
179
+ case RoleComment: return track->album();
180
+ case RoleFileName: return track->resultFileName();
181
+ default: return QVariant();
182
+ }
183
184
return QVariant();
185
}
186
187
188
}
189
190
-//# StatusPercent ::::::::::::::::::::::::::::::::::::
191
-//elif (role == self.StatusPercentRole):
192
-// try:
193
-// return QVariant(self._downloadsStates[index.row()])
194
-// except KeyError:
195
-// return QVariant()
196
-
197
-//# Download pixmap ::::::::::::::::::::::::::::::::::
198
-//elif role == self.DownloadPxmapRole:
199
-// try:
200
-// self._downloadsStates[index.row()]
201
-// return QVariant(self._downloadMovie.currentPixmap())
202
-// except KeyError:
203
-// return QVariant()
204
-
205
+ switch (role)
206
+ {
207
+ case RoleItemType: return DiskItem;
208
+ case RoleTitle: return disk->tagsTitle();
209
+ case RoleAudioFileName: return disk->audioFileName();
210
+ case RoleCanConvert: return disk->canConvert();
211
+ case RoleIsDownloads: return disk->isDownloads();
212
+ default: return QVariant();
213
+ }
214
215
return QVariant();
216
-
217
}
218
219
220
221
if (!parent.isValid())
222
return project->count();
223
224
- QObject *obj = static_cast<QObject*>(parent.internalPointer());
225
- Disk *disk = qobject_cast<Disk*>(obj);
226
+ IndexData data(parent);
227
+ if (data.isTrack())
228
+ return 0;
229
+
230
+
231
+ Disk *disk = data.disk();
232
if(disk)
233
return disk->count();
234
235
236
237
Qt::ItemFlags res = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
238
239
- QObject *obj = static_cast<QObject*>(index.internalPointer());
240
- Track *track = qobject_cast<Track*>(obj);
241
- if (track)
242
+ if (IndexData(index).isTrack())
243
{
244
switch (index.column())
245
{
246
247
}
248
249
250
+
251
/************************************************
252
253
************************************************/
254
Disk *TrackViewModel::diskByIndex(const QModelIndex &index)
255
{
256
- QObject *obj = static_cast<QObject*>(index.internalPointer());
257
- return qobject_cast<Disk*>(obj);
258
+ return IndexData(index).disk();
259
}
260
261
262
263
************************************************/
264
Track *TrackViewModel::trackByIndex(const QModelIndex &index)
265
{
266
- QObject *obj = static_cast<QObject*>(index.internalPointer());
267
- return qobject_cast<Track*>(obj);
268
+ return IndexData(index).track();
269
}
270
271
272
273
}
274
275
276
-/************************************************
277
-
278
- ************************************************/
279
-void TrackViewModel::beforeRemoveDisk(Disk *disk)
280
-{
281
- int n = project->indexOf(disk);
282
- beginRemoveRows(QModelIndex(), n, n);
283
-}
284
-
285
-
286
-/************************************************
287
-
288
- ************************************************/
289
-void TrackViewModel::afterRemoveDisk()
290
-{
291
- endRemoveRows();
292
-}
293
-
294
-
295
flacon-2.1.1.tar.gz/gui/trackviewmodel.h -> flacon-3.1.1.tar.gz/gui/trackviewmodel.h
Changed
72
1
2
3
class TrackViewModel : public QAbstractItemModel
4
{
5
+ friend class TrackView;
6
+ friend class TrackViewDelegate;
7
Q_OBJECT
8
public:
9
explicit TrackViewModel(TrackView *parent = 0);
10
11
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
12
QModelIndex index(int row, int column, const QModelIndex &parent) const;
13
- QModelIndex index(const Disk *disk, int col = 0) const;
14
- QModelIndex index(const Track *track, int col = 0) const;
15
QModelIndex parent(const QModelIndex &child) const;
16
17
QVariant data(const QModelIndex &index, int role) const;
18
19
20
TrackView *view() const { return mView; }
21
22
- static Disk *diskByIndex(const QModelIndex &index);
23
- static Track *trackByIndex(const QModelIndex &index);
24
-
25
-
26
27
public slots:
28
29
+protected:
30
+ enum ItemType {
31
+ TrackItem = 1,
32
+ DiskItem = 2
33
+ };
34
+
35
+ enum Roles{
36
+ RoleItemType = Qt::UserRole + 1,
37
+ RolePercent,
38
+ RoleStatus,
39
+ RoleTracknum,
40
+ RoleDuration,
41
+ RoleTitle,
42
+ RoleArtist,
43
+ RoleAlbum,
44
+ RoleComment,
45
+ RoleFileName,
46
+ RoleAudioFileName,
47
+ RoleCanConvert,
48
+ RoleIsDownloads,
49
+ RoleItemID,
50
+ RoleTrack
51
+ };
52
+
53
+ Disk *diskByIndex(const QModelIndex &index);
54
+ Track *trackByIndex(const QModelIndex &index);
55
56
private slots:
57
void diskDataChanged(Disk *disk);
58
void trackDataChanged(int disk, int track);
59
- void beforeRemoveDisk(Disk *disk);
60
- void afterRemoveDisk();
61
void trackProgressChanged(const Track *track);
62
63
private:
64
QVariant trackData(const Track *track, const QModelIndex &index, int role) const;
65
QVariant diskData(const Disk *disk, const QModelIndex &index, int role) const;
66
QString trackDurationToString(uint milliseconds) const;
67
+ QModelIndex index(const Disk *disk, int col = 0) const;
68
+ QModelIndex index(const Track *track, int col = 0) const;
69
70
TrackView *mView;
71
};
72
flacon-2.1.1.tar.gz/inputaudiofile.cpp -> flacon-3.1.1.tar.gz/inputaudiofile.cpp
Changed
190
1
2
3
4
#include "inputaudiofile.h"
5
+#include "decoder.h"
6
+#include "format.h"
7
#include <settings.h>
8
#include <QProcess>
9
#include <QStringList>
10
11
#include <QFileInfo>
12
#include <QDir>
13
14
-void initInputAudioFormat(QList<InputAudioFormat> *formats)
15
-{
16
- *formats << InputAudioFormat("APE", "ape", "mac");
17
- *formats << InputAudioFormat("FLAC", "flac", "flac");
18
- *formats << InputAudioFormat("WavPack", "wv", "wvunpack");
19
- *formats << InputAudioFormat("TTA", "tta", "ttaenc");
20
- *formats << InputAudioFormat("WAV", "wav", "");
21
-}
22
+//void initInputAudioFormat(QList<InputAudioFormat> *formats)
23
+//{
24
+// *formats << InputAudioFormat("APE", "ape", "mac");
25
+// *formats << InputAudioFormat("FLAC", "flac", "flac");
26
+// *formats << InputAudioFormat("WavPack", "wv", "wvunpack");
27
+// *formats << InputAudioFormat("TTA", "tta", "ttaenc");
28
+// *formats << InputAudioFormat("WAV", "wav", "");
29
+//}
30
31
-/************************************************
32
+///************************************************
33
34
- ************************************************/
35
-InputAudioFormat::InputAudioFormat(const QString &name, const QString &ext, const QString &program):
36
- mName(name),
37
- mExt(ext),
38
- mProgram(program)
39
-{
40
-}
41
+// ************************************************/
42
+//InputAudioFormat::InputAudioFormat(const QString &name, const QString &ext, const QString &program):
43
+// mName(name),
44
+// mExt(ext),
45
+// mProgram(program)
46
+//{
47
+//}
48
49
50
-/************************************************
51
+///************************************************
52
53
- ************************************************/
54
-QList<InputAudioFormat> InputAudioFormat::allFormats()
55
-{
56
- QList<InputAudioFormat> formats;
57
- if (formats.count() == 0)
58
- initInputAudioFormat(&formats);
59
+// ************************************************/
60
+//QList<InputAudioFormat> InputAudioFormat::allFormats()
61
+//{
62
+// QList<InputAudioFormat> formats;
63
+// if (formats.count() == 0)
64
+// initInputAudioFormat(&formats);
65
66
- return formats;
67
-}
68
+// return formats;
69
+//}
70
71
72
/************************************************
73
74
mValid(false),
75
mSampleRate(0),
76
mCdQuality(false),
77
- mDuration(0)
78
+ mDuration(0),
79
+ mFormat(0)
80
81
{
82
mValid = load();
83
84
mSampleRate = other.mSampleRate;
85
mCdQuality = other.mCdQuality;
86
mDuration = other.mDuration;
87
+ mFormat = other.mFormat;
88
}
89
90
InputAudioFile &InputAudioFile::operator =(const InputAudioFile &other)
91
92
mSampleRate = other.mSampleRate;
93
mCdQuality = other.mCdQuality;
94
mDuration = other.mDuration;
95
+ mFormat = other.mFormat;
96
return *this;
97
}
98
99
100
return false;
101
}
102
103
- QString shntool = QDir::toNativeSeparators(settings->value(Settings::Prog_Shntool).toString());
104
- if (shntool.isEmpty())
105
- {
106
- qWarning() << "Program shntool not found.";
107
- mErrorString = QObject::tr("I can't find program <b>%1</b>.").arg("shntool");
108
- return false;
109
- }
110
-
111
- QProcess proc;
112
113
- QStringList args;
114
- args << "info";
115
- args << QDir::toNativeSeparators(mFileName);
116
-
117
- proc.start(shntool, args);
118
-
119
- if (!proc.waitForFinished())
120
+ mFormat = AudioFormat::formatForFile(mFileName);
121
+ if (!mFormat)
122
{
123
- qWarning("------------------------------------");
124
- qWarning() << "Test audio command:" << (shntool + " " + args.join(" "));
125
- qWarning() << "shntool info waitForFinished failed";
126
- qWarning() << proc.readAllStandardError();
127
- qWarning("------------------------------------");
128
+ mErrorString = QObject::tr("File <b>%1</b> is not a supported audio file. <br>"
129
+ "<br>Verify that all required programs are installed and in your preferences.").arg(mFileName);
130
+
131
return false;
132
}
133
134
-
135
- if (proc.exitCode() != 0)
136
+ Decoder dec(*mFormat);
137
+ if (!dec.open(mFileName))
138
{
139
- qWarning("------------------------------------");
140
- qWarning() << "Test audio command:" << (shntool + " " + args.join(" "));
141
- qWarning() << "shntool info nonzero exit code:" << proc.exitCode();
142
- qWarning() << proc.readAllStandardError();
143
- qWarning("------------------------------------");
144
mErrorString = QObject::tr("File <b>%1</b> is not a supported audio file. <br>"
145
"<br>Verify that all required programs are installed and in your preferences.").arg(mFileName);
146
+ mErrorString += ": " + dec.errorString();
147
return false;
148
}
149
150
- QTextStream stream(&proc);
151
- while (!stream.atEnd())
152
- {
153
- QString line = stream.readLine();
154
- QString name = QString(line).section(':', 0, 0).toUpper().trimmed();
155
- QString value =QString(line).section(':', 1).trimmed();
156
-
157
- if (name == "SAMPLES/SEC")
158
- {
159
- mSampleRate = value.toInt();
160
- continue;
161
- }
162
-
163
- if (name == "CD QUALITY" && value.toUpper() == "YES")
164
- {
165
- mCdQuality = true;
166
- continue;
167
- }
168
-
169
-
170
- if (name == "LENGTH")
171
- {
172
- // 0h 0m 3s - Length: 0:03.00
173
- // 1h 2m 5s - Length: 62:05.00
174
- QRegExp re("(\\d+):(\\d+)\\.(\\d+)");
175
- if (re.exactMatch(value))
176
- {
177
- mDuration = re.cap(1).toInt() * 60 * 1000 +
178
- re.cap(2).toInt() * 1000 +
179
- re.cap(3).toInt();
180
- }
181
- continue;
182
- }
183
- }
184
+ mSampleRate = dec.wavHeader().sampleRate();
185
+ mCdQuality = dec.wavHeader().isCdQuality();
186
+ mDuration = dec.duration();
187
188
return true;
189
}
190
flacon-2.1.1.tar.gz/inputaudiofile.h -> flacon-3.1.1.tar.gz/inputaudiofile.h
Changed
40
1
2
#include <QString>
3
#include <QList>
4
5
-class InputAudioFormat
6
-{
7
-public:
8
- InputAudioFormat(const QString &name, const QString &ext, const QString &program);
9
-
10
- QString name() const { return mName; }
11
- QString ext() const { return mExt; }
12
- QString program() const { return mProgram; }
13
-
14
- static QList<InputAudioFormat> allFormats();
15
-private:
16
- QString mName;
17
- QString mExt;
18
- QString mProgram;
19
-};
20
+class AudioFormat;
21
22
class InputAudioFile
23
{
24
25
QString errorString() const { return mErrorString; }
26
uint duration() const { return mDuration; }
27
28
+ const AudioFormat *format() const { return mFormat; }
29
private:
30
31
QString mFileName;
32
33
int mSampleRate;
34
bool mCdQuality;
35
uint mDuration;
36
+ const AudioFormat *mFormat;
37
38
bool load();
39
};
40
flacon-2.1.1.tar.gz/scanner.cpp -> flacon-3.1.1.tar.gz/scanner.cpp
Changed
25
1
2
3
4
#include "scanner.h"
5
+#include "formats/format.h"
6
#include "inputaudiofile.h"
7
+
8
#include "project.h"
9
10
#include <QStringList>
11
12
mAbort = false;
13
14
QStringList exts;
15
- foreach(InputAudioFormat format, InputAudioFormat::allFormats())
16
- exts << QString("*.%1").arg(format.ext());
17
-
18
+ foreach(const AudioFormat *format, AudioFormat::inputFormats())
19
+ {
20
+ exts << QString("*.%1").arg(format->ext());
21
+ }
22
23
QQueue<QString> query;
24
query << startDir;
25
flacon-2.1.1.tar.gz/settings.cpp -> flacon-3.1.1.tar.gz/settings.cpp
Changed
73
1
2
* END_COMMON_COPYRIGHT_HEADER */
3
4
5
+#include "formats/format.h"
6
#include "settings.h"
7
#include "inputaudiofile.h"
8
#include "outformat.h"
9
10
#endif
11
12
QString Settings::mFileName;
13
+static Settings *inst = NULL;
14
15
/************************************************
16
17
************************************************/
18
Settings *Settings::instance()
19
{
20
- static Settings *inst = 0;
21
-
22
if (!inst)
23
{
24
if (mFileName.isEmpty())
25
26
void Settings::setFileName(const QString &fileName)
27
{
28
mFileName = fileName;
29
+ delete inst;
30
+ inst = 0;
31
}
32
33
34
35
setDefaultValue(ConfigureDialog_Height, 425);
36
37
38
- mPrograms << "shntool";
39
-
40
foreach(OutFormat *format, OutFormat::allFormats())
41
{
42
QHashIterator<QString, QVariant> i(format->defaultParameters());
43
44
}
45
46
47
- foreach (InputAudioFormat format, InputAudioFormat::allFormats())
48
+ foreach (const AudioFormat *format, AudioFormat::inputFormats())
49
{
50
- mPrograms << format.program();
51
+ mPrograms << format->decoderProgramName();
52
}
53
54
mPrograms.remove("");
55
56
foreach(QString program, mPrograms)
57
{
58
- if (value("Programs/" + program).toString().isEmpty())
59
+ if (!checkProgram(program))
60
setValue("Programs/" + program, findProgram(program));
61
}
62
}
63
64
// Internet ****************************
65
case Inet_CDDBHost: return "Inet/CDDBHost";
66
67
- // Programs ****************************
68
- case Prog_Shntool: return "Programs/shntool";
69
-
70
71
// Misc *********************************
72
case Misc_LastDir: return "Misc/LastDirectory";
73
flacon-2.1.1.tar.gz/settings.h -> flacon-3.1.1.tar.gz/settings.h
Changed
11
1
2
// Internet *****************************
3
Inet_CDDBHost,
4
5
- // Programs *****************************
6
- Prog_Shntool,
7
-
8
// Misc *********************************
9
Misc_LastDir,
10
11
flacon-2.1.1.tar.gz/tests/CMakeLists.txt -> flacon-3.1.1.tar.gz/tests/CMakeLists.txt
Changed
21
1
2
3
4
set(TEST_HEADERS
5
+ tools.h
6
testflacon.h
7
)
8
9
set(TEST_SOURCES
10
+ tools.cpp
11
+ inittestcase.cpp
12
testflacon.cpp
13
+ test_decoder.cpp
14
+ test_wavheader.cpp
15
+ test_format.cpp
16
+ test_inputaudiofile.cpp
17
+ test_convert.cpp
18
)
19
20
set(TEST_MOCS
21
flacon-2.1.1.tar.gz/tests/data/testConvert/05.expected.cue -> flacon-3.1.1.tar.gz/tests/data/testConvert/05.expected.cue
Changed
32
1
2
REM DISCID 123456789
3
PERFORMER "Artist"
4
TITLE "Album"
5
-FILE "01 - Song01.wav" WAVE
6
+FILE "01 - Song Title 01.wav" WAVE
7
TRACK 01 AUDIO
8
- TITLE "Song01"
9
+ TITLE "Song Title 01"
10
INDEX 00 00:00:00
11
INDEX 01 00:00:33
12
TRACK 02 AUDIO
13
- TITLE "Song02"
14
-FILE "02 - Song02.wav" WAVE
15
+ TITLE "Song Title 02"
16
+FILE "02 - Song Title 02.wav" WAVE
17
INDEX 01 00:00:00
18
TRACK 03 AUDIO
19
- TITLE "Song03"
20
+ TITLE "Song Title 03"
21
INDEX 00 00:36:22
22
-FILE "03 - Song03.wav" WAVE
23
+FILE "03 - Song Title 03.wav" WAVE
24
INDEX 01 00:00:00
25
TRACK 04 AUDIO
26
- TITLE "Song04"
27
+ TITLE "Song Title 04"
28
INDEX 00 01:14:44
29
-FILE "04 - Song04.wav" WAVE
30
+FILE "04 - Song Title 04.wav" WAVE
31
INDEX 01 00:00:00
32
flacon-3.1.1.tar.gz/tests/inittestcase.cpp
Added
190
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+#include "testflacon.h"
28
+#include "tools.h"
29
+#include "converter/wavheader.h"
30
+#include "../settings.h"
31
+
32
+#include <QString>
33
+#include <QProcessEnvironment>
34
+#include <QFileInfo>
35
+#include <QDir>
36
+#include <QDebug>
37
+
38
+#ifdef Q_OS_WIN
39
+ #define PATH_ENV_SEPARATOR ';'
40
+ #define BINARY_EXT ".exe"
41
+
42
+#elif defined(Q_OS_OS2)
43
+ #define PATH_ENV_SEPARATOR ';'
44
+ #define BINARY_EXT ".exe"
45
+
46
+#else
47
+ #define PATH_ENV_SEPARATOR ':'
48
+ #define BINARY_EXT ""
49
+
50
+#endif
51
+
52
+
53
+/************************************************
54
+ *
55
+ ************************************************/
56
+QString findProgram(const QString &program)
57
+{
58
+ QStringList paths = QProcessEnvironment::systemEnvironment().value("PATH").split(PATH_ENV_SEPARATOR);
59
+ foreach(QString path, paths)
60
+ {
61
+ QFileInfo fi(path + QDir::separator() + program + BINARY_EXT);
62
+ if (fi.exists() && fi.isExecutable())
63
+ return fi.absoluteFilePath();
64
+ }
65
+ return "";
66
+}
67
+
68
+
69
+
70
+/************************************************
71
+ *
72
+ ************************************************/
73
+void TestFlacon::initTestCase()
74
+{
75
+ Settings::setFileName(TEST_OUT_DIR "/flacon.conf");
76
+
77
+ if (findProgram("mac").isEmpty()) QFAIL("mac program not found");
78
+ if (findProgram("flac").isEmpty()) QFAIL("flac program not found");
79
+ if (findProgram("wavpack").isEmpty()) QFAIL("wavpack program not found");
80
+ if (findProgram("ttaenc").isEmpty()) QFAIL("ttaenc program not found");
81
+
82
+ if (!QDir().mkpath(mTmpDir))
83
+ QTest::qFail(QString("Can't create directory '%1'").arg(mTmpDir).toLocal8Bit(), __FILE__, __LINE__);
84
+
85
+
86
+ mAudio_cd_wav = mTmpDir + "CD.wav";
87
+ mAudio_cd_ape = mTmpDir + "CD.ape";
88
+ mAudio_cd_flac = mTmpDir + "CD.flac";
89
+ mAudio_cd_wv = mTmpDir + "CD.wv";
90
+ mAudio_cd_tta = mTmpDir + "CD.tta";
91
+
92
+ createWavFile( mAudio_cd_wav, 900, StdWavHeader::Quality_Stereo_CD);
93
+ encodeAudioFile(mAudio_cd_wav, mAudio_cd_ape);
94
+ encodeAudioFile(mAudio_cd_wav, mAudio_cd_flac);
95
+ encodeAudioFile(mAudio_cd_wav, mAudio_cd_wv);
96
+ encodeAudioFile(mAudio_cd_wav, mAudio_cd_tta);
97
+
98
+
99
+ mAudio_24x96_wav = mTmpDir + "24x96.wav";
100
+ mAudio_24x96_ape = mTmpDir + "24x96.ape";
101
+ mAudio_24x96_flac = mTmpDir + "24x96.flac";
102
+ mAudio_24x96_wv = mTmpDir + "24x96.wv";
103
+ mAudio_24x96_tta = mTmpDir + "24x96.tta";
104
+
105
+ createWavFile( mAudio_24x96_wav, 900, StdWavHeader::Quality_Stereo_24_96);
106
+ encodeAudioFile(mAudio_24x96_wav, mAudio_24x96_ape);
107
+ encodeAudioFile(mAudio_24x96_wav, mAudio_24x96_flac);
108
+ encodeAudioFile(mAudio_24x96_wav, mAudio_24x96_wv);
109
+ encodeAudioFile(mAudio_24x96_wav, mAudio_24x96_tta);
110
+
111
+}
112
+
113
+QString safePath(const QString &path)
114
+{
115
+ QString res = path;
116
+ res = res.replace(' ', '_');
117
+ res = res.replace('\t', '_');
118
+ res = res.replace('\n', '_');
119
+ res = res.replace('/', '_');
120
+ return res;
121
+}
122
+
123
+
124
+QString TestFlacon::dir()
125
+{
126
+ QString test = QString::fromLocal8Bit(QTest::currentTestFunction());
127
+ QString subtest = QString::fromLocal8Bit(QTest::currentDataTag());
128
+
129
+
130
+ return QDir::cleanPath(QString("%1/%2/%3")
131
+ .arg(TEST_OUT_DIR)
132
+ .arg(safePath(test))
133
+ .arg(safePath(subtest)));
134
+
135
+}
136
+
137
+
138
+
139
+#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
140
+bool removeRecursively(QString dirName)
141
+{
142
+ bool result = true;
143
+ QDir dir(dirName);
144
+
145
+ if (dir.exists(dirName))
146
+ {
147
+ foreach(QFileInfo fi, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst))
148
+ {
149
+ if (fi.isDir())
150
+ result = removeRecursively(fi.absoluteFilePath());
151
+ else
152
+ result = QFile::remove(fi.absoluteFilePath());
153
+
154
+ if (!result)
155
+ return result;
156
+ }
157
+
158
+ result = dir.rmdir(dirName);
159
+ }
160
+
161
+ return result;
162
+}
163
+
164
+#endif
165
+
166
+void TestFlacon::init()
167
+{
168
+ static QString prevTestFunction;
169
+ if (prevTestFunction != QTest::currentTestFunction())
170
+ {
171
+ prevTestFunction = QTest::currentTestFunction();
172
+ mTestNum++;
173
+ }
174
+
175
+ QString dir = this->dir();
176
+
177
+#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
178
+ removeRecursively(dir);
179
+#else
180
+ QDir(dir).removeRecursively();
181
+#endif
182
+ if (!QDir().mkpath(dir))
183
+ {
184
+ QTest::qFail(QString("Can't create directory '%1'").arg(dir).toLocal8Bit(), __FILE__, __LINE__);
185
+ }
186
+
187
+ Settings::setFileName(dir + "/flacon.conf");
188
+}
189
+
190
flacon-3.1.1.tar.gz/tests/test_convert.cpp
Added
374
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+#include "testflacon.h"
28
+#include "../settings.h"
29
+#include "outformat.h"
30
+#include "../converter/wavheader.h"
31
+#include "tools.h"
32
+#include "project.h"
33
+#include "../inputaudiofile.h"
34
+#include "../converter/converter.h"
35
+
36
+#include <QDir>
37
+#include <QDebug>
38
+
39
+
40
+
41
+
42
+class ConverterTester
43
+{
44
+public:
45
+ ConverterTester(const QString &cueFile,
46
+ const QString &audioFile,
47
+ const QString &expectedCue,
48
+ const QString &resultFiles);
49
+
50
+
51
+ void run(const QString &name);
52
+
53
+ Disk *disk() { return mDisk; }
54
+
55
+private:
56
+ Disk *mDisk;
57
+ QStringList mResultFiles;
58
+ QString mExpectedCue;
59
+ ConverterTester(const ConverterTester &other) {}
60
+};
61
+
62
+
63
+
64
+
65
+/************************************************
66
+
67
+ ************************************************/
68
+ConverterTester::ConverterTester(const QString &cueFile, const QString &audioFile, const QString &expectedCue, const QString &resultFiles)
69
+{
70
+ mResultFiles = resultFiles.split(';', QString::SkipEmptyParts);
71
+ mExpectedCue = expectedCue;
72
+ project->clear();
73
+ mDisk = loadFromCue(cueFile);
74
+ InputAudioFile audio(audioFile);
75
+ mDisk->setAudioFile(audio);
76
+ project->addDisk(mDisk);
77
+}
78
+
79
+/************************************************
80
+
81
+ ************************************************/
82
+void ConverterTester::run(const QString &name)
83
+{
84
+ Converter conv;
85
+ conv.setShowStatistic(false);
86
+ QEventLoop loop;
87
+ loop.connect(&conv, SIGNAL(finished()), &loop, SLOT(quit()));
88
+ conv.start();
89
+
90
+ if (!conv.isRunning())
91
+ {
92
+ QString msg;
93
+ mDisk->canConvert(&msg);
94
+ QFAIL(QString("Can't start converter: \"%1\"").arg(msg).toLocal8Bit());
95
+ }
96
+
97
+ loop.exec();
98
+
99
+ QDir outDir = QFileInfo(mDisk->track(0)->resultFilePath()).dir();
100
+ QStringList files = outDir.entryList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::Files);
101
+ project->clear();
102
+ if (!mExpectedCue.isEmpty())
103
+ QFile::copy(mExpectedCue, outDir.absoluteFilePath("expected.cue"));
104
+
105
+ QStringList missing;
106
+ foreach(QString f, mResultFiles)
107
+ {
108
+ QString file = f.section(':', 0, 0).trimmed();
109
+ QString hash = f.section(':', 1).trimmed();
110
+
111
+ if (files.removeAll(file) == 0)
112
+ missing << file;
113
+
114
+ if (!hash.isEmpty())
115
+ {
116
+ compareAudioHash(outDir.absoluteFilePath(file), hash);
117
+ }
118
+ }
119
+
120
+
121
+ QString msg = "";
122
+ if (!missing.isEmpty())
123
+ msg += QString("\nFiles not exists:\n *%1").arg(missing.join("\n *"));
124
+
125
+ if (!files.isEmpty())
126
+ msg += QString("\nFiles exists:\n *%1").arg(files.join("\n *"));
127
+
128
+
129
+ if (!mExpectedCue.isEmpty())
130
+ {
131
+ //QString resCueFile;
132
+ files = outDir.entryList(QStringList() << "*.cue", QDir::Files);
133
+ if (files.isEmpty())
134
+ {
135
+ msg += "\nResult CUE file not found.";
136
+ }
137
+ else
138
+ {
139
+ QString err;
140
+ if (!TestFlacon::compareCue(outDir.absoluteFilePath(files.first()), mExpectedCue, &err))
141
+ msg += "\n" + err;
142
+ }
143
+ }
144
+
145
+ if (!msg.isEmpty())
146
+ QFAIL(name.toLocal8Bit() + "\n" + msg.toLocal8Bit());
147
+
148
+}
149
+
150
+
151
+/************************************************
152
+ *
153
+ ************************************************/
154
+void TestFlacon::testConvert()
155
+{
156
+
157
+ QFETCH(QString, cueFile);
158
+ QFETCH(QString, audioFile);
159
+ QFETCH(QString, expectedCue);
160
+ QFETCH(QString, tags);
161
+ QFETCH(QString, resultFiles);
162
+ QFETCH(bool, createCue);
163
+ QFETCH(int, preGapType);
164
+
165
+ settings->setValue(Settings::OutFiles_Directory, dir());
166
+ settings->setValue(Settings::OutFiles_Pattern, "%a/%n - %t");
167
+ settings->setValue(Settings::OutFiles_Format, "WAV");
168
+ settings->setValue(Settings::PerTrackCue_FlaconTags, false);
169
+ settings->setValue(Settings::PerTrackCue_Create, createCue);
170
+ settings->setValue(Settings::PerTrackCue_Pregap, OutFormat::preGapTypeToString(OutFormat::PreGapType(preGapType)));
171
+ settings->setValue(Settings::OutFiles_Directory, dir());
172
+ settings->setValue(Settings::Encoder_TmpDir, "");
173
+
174
+ QString srcAudioFile = audioFile.section(':', 0, 0);
175
+ QString destAudioFile = audioFile.section(':', 1);
176
+ if (!destAudioFile.isEmpty())
177
+ {
178
+ destAudioFile = dir() + "/" + destAudioFile;
179
+ QFileInfo(destAudioFile).dir().mkpath(".");
180
+ QFile::copy(srcAudioFile, destAudioFile);
181
+ }
182
+ else
183
+ {
184
+ destAudioFile = srcAudioFile;
185
+ }
186
+
187
+ ConverterTester conv(
188
+ cueFile,
189
+ destAudioFile,
190
+ expectedCue,
191
+ resultFiles
192
+ );
193
+
194
+ foreach (QString line, tags.split(';'))
195
+ {
196
+ line = line.trimmed();
197
+ if (line.isEmpty())
198
+ continue;
199
+
200
+ int n = line.section(' ', 0, 0).toInt() - 1;
201
+ Track *track = conv.disk()->track(n);
202
+
203
+ foreach (QString s, line.section(' ', 1).split(','))
204
+ {
205
+ track->setTag(s.section(':', 0, 0).trimmed(), s.section(':', 1).trimmed());
206
+ }
207
+ }
208
+
209
+ conv.run(QTest::currentDataTag());
210
+
211
+}
212
+
213
+
214
+/************************************************
215
+ *
216
+ ************************************************/
217
+void TestFlacon::testConvert_data()
218
+{
219
+ QTest::addColumn<QString>("cueFile");
220
+ QTest::addColumn<QString>("audioFile");
221
+ QTest::addColumn<QString>("expectedCue");
222
+ QTest::addColumn<QString>("resultFiles");
223
+ QTest::addColumn<QString>("tags");
224
+ QTest::addColumn<bool>("createCue");
225
+ QTest::addColumn<int>("preGapType");
226
+
227
+ QString inDir = mDataDir + "/testConvert/";
228
+
229
+
230
+
231
+ QTest::newRow("01.1 With pregap and HTOA, w.o cue")
232
+ << inDir + "01.cuecreator.cue"
233
+ << mAudio_24x96_wav
234
+ << ""
235
+ << "01 - Song01.wav : a86e2d59bf1e272b5ab7e9a16009455d;"
236
+ "02 - Song02.wav : 1a199e8e2badff1e643a9f1697ac4140;"
237
+ "03 - Song03.wav : 71db07cb54faee8545cbed90fe0be6a3;"
238
+ "04 - Song04.wav : 2e5df99b43b96c208ab26983140dd19f;"
239
+ << ""
240
+ << false
241
+ << int(OutFormat::PreGapExtractToFile);
242
+
243
+
244
+
245
+ QTest::newRow("01.2 With pregap and HTOA, with cue")
246
+ << inDir + "01.cuecreator.cue"
247
+ << mAudio_24x96_wav
248
+ << inDir + "01.expected.cue"
249
+ << "01 - Song01.wav : a86e2d59bf1e272b5ab7e9a16009455d;"
250
+ "02 - Song02.wav : 1a199e8e2badff1e643a9f1697ac4140;"
251
+ "03 - Song03.wav : 71db07cb54faee8545cbed90fe0be6a3;"
252
+ "04 - Song04.wav : 2e5df99b43b96c208ab26983140dd19f;"
253
+ "00 - (HTOA).wav : afb9e4434b212bacdd62e585461af757;"
254
+ "Artist-Album.cue;"
255
+ << ""
256
+ << true
257
+ << int(OutFormat::PreGapExtractToFile);
258
+
259
+
260
+ QTest::newRow("02.1 W.o pregap, w.o HTOA")
261
+ << inDir + "02.cuecreator.cue"
262
+ << mAudio_24x96_wav
263
+ << inDir + "02.expected.cue"
264
+ << "01 - Song01.wav : 07bb5c5fbf7b9429c05e9b650d9df467;"
265
+ "02 - Song02.wav : 1a199e8e2badff1e643a9f1697ac4140;"
266
+ "03 - Song03.wav : 71db07cb54faee8545cbed90fe0be6a3;"
267
+ "04 - Song04.wav : 2e5df99b43b96c208ab26983140dd19f;"
268
+ "Artist-Album.cue;"
269
+ << ""
270
+ << true
271
+ << int(OutFormat::PreGapAddToFirstTrack);
272
+
273
+
274
+ QTest::newRow("02.2 W.o pregap, w.o HTOA")
275
+ << inDir + "02.cuecreator.cue"
276
+ << mAudio_24x96_wav
277
+ << inDir + "02.expected.cue"
278
+ << "01 - Song01.wav : 07bb5c5fbf7b9429c05e9b650d9df467;"
279
+ "02 - Song02.wav : 1a199e8e2badff1e643a9f1697ac4140;"
280
+ "03 - Song03.wav : 71db07cb54faee8545cbed90fe0be6a3;"
281
+ "04 - Song04.wav : 2e5df99b43b96c208ab26983140dd19f;"
282
+ "Artist-Album.cue;"
283
+ << ""
284
+ << true
285
+ << int(OutFormat::PreGapExtractToFile);
286
+
287
+
288
+
289
+ QTest::newRow("03.1 With pregap, w.o HTOA")
290
+ << inDir + "03.cuecreator.cue"
291
+ << mAudio_24x96_wav
292
+ << inDir + "03.expected.cue"
293
+ << "01 - Song01.wav : 07bb5c5fbf7b9429c05e9b650d9df467;"
294
+ "02 - Song02.wav : 1a199e8e2badff1e643a9f1697ac4140;"
295
+ "03 - Song03.wav : 71db07cb54faee8545cbed90fe0be6a3;"
296
+ "04 - Song04.wav : 2e5df99b43b96c208ab26983140dd19f;"
297
+ "Artist-Album.cue;"
298
+ << ""
299
+ << true
300
+ << int(OutFormat::PreGapAddToFirstTrack);
301
+
302
+
303
+ QTest::newRow("04.1 All tags")
304
+ << inDir + "04.cuecreator.cue"
305
+ << mAudio_24x96_wav
306
+ << inDir + "04.expected.cue"
307
+ << "01 - Song01.wav : 07bb5c5fbf7b9429c05e9b650d9df467;"
308
+ "02 - Song02.wav : 1a199e8e2badff1e643a9f1697ac4140;"
309
+ "03 - Song03.wav : 71db07cb54faee8545cbed90fe0be6a3;"
310
+ "04 - Song04.wav : 2e5df99b43b96c208ab26983140dd19f;"
311
+ "Artist-Album.cue;"
312
+ << ""
313
+ << true
314
+ << int(OutFormat::PreGapAddToFirstTrack);
315
+
316
+
317
+ QTest::newRow("05.1 Cue w.o tags + tags form the separate file")
318
+ << inDir + "05.cuecreator.cue"
319
+ << mAudio_24x96_wav
320
+ << inDir + "05.expected.cue"
321
+ << "01 - Song Title 01.wav : 07bb5c5fbf7b9429c05e9b650d9df467;"
322
+ "02 - Song Title 02.wav : 1a199e8e2badff1e643a9f1697ac4140;"
323
+ "03 - Song Title 03.wav : 71db07cb54faee8545cbed90fe0be6a3;"
324
+ "04 - Song Title 04.wav : 2e5df99b43b96c208ab26983140dd19f;"
325
+ "Artist-Album.cue;"
326
+ << "01 PERFORMER: Artist, ALBUM: Album, GENRE: Genre, DATE: 2013, TITLE: Song Title 01;"
327
+ "02 PERFORMER: Artist, ALBUM: Album, GENRE: Genre, DATE: 2013, TITLE: Song Title 02;"
328
+ "03 PERFORMER: Artist, ALBUM: Album, GENRE: Genre, DATE: 2013, TITLE: Song Title 03;"
329
+ "04 PERFORMER: Artist, ALBUM: Album, GENRE: Genre, DATE: 2013, TITLE: Song Title 04;"
330
+ << true
331
+ << int(OutFormat::PreGapAddToFirstTrack);
332
+
333
+
334
+ QTest::newRow("06.1 Garbage in the CUE")
335
+ << inDir + "06.garbageInTags.cue"
336
+ << mAudio_24x96_wav
337
+ << ""
338
+ << "01 - Song01.wav : a86e2d59bf1e272b5ab7e9a16009455d;"
339
+ "02 - Song02.wav : 1a199e8e2badff1e643a9f1697ac4140;"
340
+ "03 - Song03.wav : 71db07cb54faee8545cbed90fe0be6a3;"
341
+ "04 - Song04.wav : 2e5df99b43b96c208ab26983140dd19f;"
342
+ << ""
343
+ << false
344
+ << int(OutFormat::PreGapExtractToFile);
345
+
346
+
347
+ QTest::newRow("07.1 with symbols and space")
348
+ << inDir + "07.path(with.symbols and space )/07.path(with.symbols and space ).cue"
349
+ << mAudio_24x96_wav +
350
+ ":Test_07.path(with.symbols and space )/Audio file (with.symbols and space ).wav"
351
+ << ""
352
+ << "01 - Song01.wav : a86e2d59bf1e272b5ab7e9a16009455d;"
353
+ "02 - Song02.wav : 1a199e8e2badff1e643a9f1697ac4140;"
354
+ "03 - Song03.wav : 71db07cb54faee8545cbed90fe0be6a3;"
355
+ "04 - Song04.wav : 2e5df99b43b96c208ab26983140dd19f;"
356
+ << ""
357
+ << false
358
+ << int(OutFormat::PreGapExtractToFile);
359
+
360
+
361
+ QTest::newRow("08.1 Test_8/Музыка")
362
+ << inDir + "01.cuecreator.cue"
363
+ << mAudio_24x96_wav
364
+ << ""
365
+ << "01 - Song01.wav : a86e2d59bf1e272b5ab7e9a16009455d;"
366
+ "02 - Song02.wav : 1a199e8e2badff1e643a9f1697ac4140;"
367
+ "03 - Song03.wav : 71db07cb54faee8545cbed90fe0be6a3;"
368
+ "04 - Song04.wav : 2e5df99b43b96c208ab26983140dd19f;"
369
+ << ""
370
+ << false
371
+ << int(OutFormat::PreGapExtractToFile);
372
+
373
+}
374
flacon-3.1.1.tar.gz/tests/test_decoder.cpp
Added
243
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "testflacon.h"
29
+#include "tools.h"
30
+#include "../converter/decoder.h"
31
+#include "../formats/wav.h"
32
+#include "../formats/flac.h"
33
+
34
+#include <QTest>
35
+#include <QVector>
36
+#include <QDebug>
37
+
38
+struct TestTrack {
39
+ QString start;
40
+ QString end;
41
+ QString hash;
42
+};
43
+
44
+
45
+/************************************************
46
+ *
47
+ ************************************************/
48
+void TestFlacon::testDecoder()
49
+{
50
+ QFETCH(QStringList, data);
51
+ QString inputFile = data.first();
52
+
53
+ QVector<TestTrack> tracks;
54
+ for (int i=1; i < data.count(); i+=3)
55
+ {
56
+ TestTrack track = {data.at(i), data.at(i+1), data.at(i+2)};
57
+ tracks << track;
58
+ }
59
+
60
+
61
+ // Flacon decoder ___________________________
62
+ const AudioFormat *format = AudioFormat::formatForFile(inputFile);
63
+ if (!format)
64
+ QFAIL("Unknown format");
65
+
66
+ Decoder decoder(*format);
67
+ if (!decoder.open(inputFile))
68
+ QFAIL(QString("Can't open input file '%1': %2").arg(inputFile, decoder.errorString()).toLocal8Bit());
69
+
70
+ for (int i=0; i < tracks.count(); ++i)
71
+ {
72
+ TestTrack track = tracks.at(i);
73
+
74
+ QString flaconFile = QString("%1/%2-flacon.wav").arg(dir()).arg(i + 1, 3, 10, QChar('0'));
75
+
76
+ bool res = decoder.extract(
77
+ CueTime(track.start),
78
+ CueTime(track.end),
79
+ flaconFile);
80
+
81
+ if (!res)
82
+ QFAIL(QString("Can't extract file '%1' [%2-%3]: %4")
83
+ .arg(inputFile)
84
+ .arg(track.start, track.end)
85
+ .arg(decoder.errorString()).toLocal8Bit());
86
+ }
87
+ decoder.close();
88
+
89
+
90
+ // Checks ___________________________________
91
+ for (int i=0; i < tracks.count(); ++i)
92
+ {
93
+ compareAudioHash(
94
+ QString("%1/%2-flacon.wav").arg(dir()).arg(i + 1, 3, 10, QChar('0')),
95
+ tracks.at(i).hash);
96
+ }
97
+
98
+
99
+}
100
+
101
+
102
+/************************************************
103
+ *
104
+ ************************************************/
105
+void TestFlacon::testDecoder_data()
106
+{
107
+ QTest::addColumn<QStringList>("data");
108
+
109
+
110
+ // Wav ______________________________________
111
+ QTest::newRow("WAV 001 cd")
112
+ << (QStringList()
113
+ << mAudio_cd_wav
114
+ << "00:00:00" << "00:30:00" << "7d6351521a02b625905edd28970b5a73"
115
+ << "00:30:00" << "01:30:00" << "ac122fd6541d84bd3fad555f3f0a67df"
116
+ << "01:30:00" << "02:30:00" << "128aa3a57539d70cdb225a9b1b76a3c2"
117
+ );
118
+
119
+ QTest::newRow("WAV 002 cd")
120
+ << (QStringList()
121
+ << mAudio_cd_wav
122
+ << "00:00:10" << "00:30:00" << "2310ce664e1dc134ccbf8af5b52710bc"
123
+ << "00:30:00" << "01:30:20" << "26575693c3c50c4f91563769ec9dee02"
124
+ << "01:30:20" << "02:30:30" << "f0c8971a53aa4be86093da31145b5d87"
125
+ );
126
+
127
+ QTest::newRow("WAV 003 24x96")
128
+ << (QStringList()
129
+ << mAudio_24x96_wav
130
+ << "00:00:000" << "00:30:000" << "a20d655209861b734d96e79e80e967cd"
131
+ << "00:30:000" << "01:30:000" << "f53a6b3612b407fc1c42a755d1130e62"
132
+ << "01:30:000" << "02:30:000" << "ac3eb3dec93094791e5358f9151fadd0"
133
+ );
134
+
135
+
136
+
137
+ // Flac _____________________________________
138
+ QTest::newRow("FLAC 001 cd")
139
+ << (QStringList()
140
+ << mAudio_cd_flac
141
+ << "00:00:00" << "00:30:00" << "7d6351521a02b625905edd28970b5a73"
142
+ << "00:30:00" << "01:30:00" << "ac122fd6541d84bd3fad555f3f0a67df"
143
+ << "01:30:00" << "02:30:00" << "128aa3a57539d70cdb225a9b1b76a3c2"
144
+ );
145
+
146
+ QTest::newRow("FLAC 002 cd")
147
+ << (QStringList()
148
+ << mAudio_cd_flac
149
+ << "00:00:10" << "00:30:00" << "2310ce664e1dc134ccbf8af5b52710bc"
150
+ << "00:30:00" << "01:30:20" << "26575693c3c50c4f91563769ec9dee02"
151
+ << "01:30:20" << "02:30:30" << "f0c8971a53aa4be86093da31145b5d87"
152
+ );
153
+
154
+ QTest::newRow("FLAC 003 24x96")
155
+ << (QStringList()
156
+ << mAudio_24x96_flac
157
+ << "00:00:000" << "00:30:000" << "a20d655209861b734d96e79e80e967cd"
158
+ << "00:30:000" << "01:30:000" << "f53a6b3612b407fc1c42a755d1130e62"
159
+ << "01:30:000" << "02:30:000" << "ac3eb3dec93094791e5358f9151fadd0"
160
+ );
161
+
162
+
163
+ // APE ______________________________________
164
+ QTest::newRow("APE 001 cd")
165
+ << (QStringList()
166
+ << mAudio_cd_ape
167
+ << "00:00:00" << "00:30:00" << "7d6351521a02b625905edd28970b5a73"
168
+ << "00:30:00" << "01:30:00" << "ac122fd6541d84bd3fad555f3f0a67df"
169
+ << "01:30:00" << "02:30:00" << "128aa3a57539d70cdb225a9b1b76a3c2"
170
+ );
171
+
172
+ QTest::newRow("APE 002 cd")
173
+ << (QStringList()
174
+ << mAudio_cd_ape
175
+ << "00:00:10" << "00:30:00" << "2310ce664e1dc134ccbf8af5b52710bc"
176
+ << "00:30:00" << "01:30:20" << "26575693c3c50c4f91563769ec9dee02"
177
+ << "01:30:20" << "02:30:30" << "f0c8971a53aa4be86093da31145b5d87"
178
+ );
179
+
180
+ QTest::newRow("APE 003 24x96")
181
+ << (QStringList()
182
+ << mAudio_24x96_ape
183
+ << "00:00:000" << "00:30:000" << "a20d655209861b734d96e79e80e967cd"
184
+ << "00:30:000" << "01:30:000" << "f53a6b3612b407fc1c42a755d1130e62"
185
+ << "01:30:000" << "02:30:000" << "ac3eb3dec93094791e5358f9151fadd0"
186
+ );
187
+
188
+
189
+ // TTA ______________________________________
190
+ QTest::newRow("TTA 001 cd")
191
+ << (QStringList()
192
+ << mAudio_cd_tta
193
+ << "00:00:00" << "00:30:00" << "7d6351521a02b625905edd28970b5a73"
194
+ << "00:30:00" << "01:30:00" << "ac122fd6541d84bd3fad555f3f0a67df"
195
+ << "01:30:00" << "02:30:00" << "128aa3a57539d70cdb225a9b1b76a3c2"
196
+ );
197
+
198
+ QTest::newRow("TTA 002 cd")
199
+ << (QStringList()
200
+ << mAudio_cd_tta
201
+ << "00:00:10" << "00:30:00" << "2310ce664e1dc134ccbf8af5b52710bc"
202
+ << "00:30:00" << "01:30:20" << "26575693c3c50c4f91563769ec9dee02"
203
+ << "01:30:20" << "02:30:30" << "f0c8971a53aa4be86093da31145b5d87"
204
+ );
205
+
206
+ QTest::newRow("TTA 003 24x96")
207
+ << (QStringList()
208
+ << mAudio_24x96_tta
209
+ << "00:00:000" << "00:30:000" << "a20d655209861b734d96e79e80e967cd"
210
+ << "00:30:000" << "01:30:000" << "f53a6b3612b407fc1c42a755d1130e62"
211
+ << "01:30:000" << "02:30:000" << "ac3eb3dec93094791e5358f9151fadd0"
212
+ );
213
+
214
+
215
+ // WV ______________________________________
216
+ QTest::newRow("WV 001 cd")
217
+ << (QStringList()
218
+ << mAudio_cd_wv
219
+ << "00:00:00" << "00:30:00" << "7d6351521a02b625905edd28970b5a73"
220
+ << "00:30:00" << "01:30:00" << "ac122fd6541d84bd3fad555f3f0a67df"
221
+ << "01:30:00" << "02:30:00" << "128aa3a57539d70cdb225a9b1b76a3c2"
222
+ );
223
+
224
+ QTest::newRow("WV 002 cd")
225
+ << (QStringList()
226
+ << mAudio_cd_wv
227
+ << "00:00:10" << "00:30:00" << "2310ce664e1dc134ccbf8af5b52710bc"
228
+ << "00:30:00" << "01:30:20" << "26575693c3c50c4f91563769ec9dee02"
229
+ << "01:30:20" << "02:30:30" << "f0c8971a53aa4be86093da31145b5d87"
230
+ );
231
+
232
+ QTest::newRow("WV 003 24x96")
233
+ << (QStringList()
234
+ << mAudio_24x96_wv
235
+ << "00:00:000" << "00:30:000" << "a20d655209861b734d96e79e80e967cd"
236
+ << "00:30:000" << "01:30:000" << "f53a6b3612b407fc1c42a755d1130e62"
237
+ << "01:30:000" << "02:30:000" << "ac3eb3dec93094791e5358f9151fadd0"
238
+ );
239
+
240
+}
241
+
242
+
243
flacon-3.1.1.tar.gz/tests/test_format.cpp
Added
143
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "testflacon.h"
29
+#include "tools.h"
30
+#include "../formats/format.h"
31
+#include "../formats/wav.h"
32
+#include "../formats/flac.h"
33
+#include "../settings.h"
34
+
35
+#include <QTest>
36
+#include <QString>
37
+#include <QBuffer>
38
+#include <QDebug>
39
+
40
+/************************************************
41
+ *
42
+ ************************************************/
43
+void TestFlacon::testFormatWavLast()
44
+{
45
+ if (AudioFormat::allFormats().last()->ext() != "wav")
46
+ QFAIL("Last format is not wav in allFormats.");
47
+
48
+
49
+ if (AudioFormat::inputFormats().last()->ext() != "wav")
50
+ QFAIL("Last format is not wav in inputFormats.");
51
+
52
+}
53
+
54
+
55
+/************************************************
56
+ *
57
+ ************************************************/
58
+void TestFlacon::testFormat()
59
+{
60
+ QFETCH(QString, testdata);
61
+ QFETCH(QString, ext);
62
+
63
+ QBuffer data;
64
+ data.open(QBuffer::ReadWrite);
65
+ writeHexString(testdata, &data);
66
+ data.seek(0);
67
+
68
+ const AudioFormat *format = AudioFormat::formatForFile(&data);
69
+ if (!format)
70
+ QFAIL("Can't find format");
71
+
72
+ if (format->ext() != ext)
73
+ QFAIL(QString("Incorrect format found:\n found '%1',\n expected '%2' ").arg(format->ext(), ext).toLocal8Bit());
74
+
75
+}
76
+
77
+
78
+/************************************************
79
+ *
80
+ ************************************************/
81
+void TestFlacon::testFormat_data()
82
+{
83
+ QTest::addColumn<QString>("testdata");
84
+ QTest::addColumn<QString>("ext");
85
+
86
+ QTest::newRow("01 WAV")
87
+ << "52 49 46 46" // RIFF
88
+ << "wav";
89
+
90
+ QTest::newRow("02 FLAC")
91
+ << "66 4C 61 43" // fLaC
92
+ << "flac";
93
+
94
+}
95
+
96
+
97
+/************************************************
98
+ *
99
+ ************************************************/
100
+void TestFlacon::testFormatFromFile()
101
+{
102
+ QFETCH(QString, filename);
103
+ QFETCH(QString, ext);
104
+
105
+ const AudioFormat *format = AudioFormat::formatForFile(filename);
106
+ if (!format)
107
+ QFAIL("Can't find format");
108
+
109
+ if (format->ext() != ext)
110
+ QFAIL(QString("Incorrect format found:\n found '%1',\n expected '%2' ").arg(format->ext(), ext).toLocal8Bit());
111
+}
112
+
113
+
114
+/************************************************
115
+ *
116
+ ************************************************/
117
+void TestFlacon::testFormatFromFile_data()
118
+{
119
+ QTest::addColumn<QString>("filename");
120
+ QTest::addColumn<QString>("ext");
121
+
122
+ // WAV ______________________________________
123
+ QTest::newRow("WAV 01") << mAudio_cd_wav << "wav";
124
+ QTest::newRow("WAV 02") << mAudio_24x96_wav << "wav";
125
+
126
+ // FLAC _____________________________________
127
+ QTest::newRow("FLAC 01") << mAudio_cd_flac << "flac";
128
+ QTest::newRow("FLAC 02") << mAudio_24x96_flac << "flac";
129
+
130
+ // APE ______________________________________
131
+ QTest::newRow("APE 01") << mAudio_cd_ape << "ape";
132
+ QTest::newRow("APE 02") << mAudio_24x96_ape << "ape";
133
+
134
+ // TTA ______________________________________
135
+ QTest::newRow("TTA 01") << mAudio_cd_tta << "tta";
136
+ QTest::newRow("TTA 02") << mAudio_24x96_tta << "tta";
137
+
138
+ // WV ______________________________________
139
+ QTest::newRow("WV 01") << mAudio_cd_wv << "wv";
140
+ QTest::newRow("WV 02") << mAudio_24x96_wv << "wv";
141
+
142
+}
143
flacon-3.1.1.tar.gz/tests/test_inputaudiofile.cpp
Added
124
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "testflacon.h"
29
+#include "tools.h"
30
+#include "../formats/format.h"
31
+//#include "../formats/wav.h"
32
+//#include "../formats/flac.h"
33
+//#include "../settings.h"
34
+#include "../inputaudiofile.h"
35
+
36
+#include <QTest>
37
+#include <QString>
38
+#include <QBuffer>
39
+#include <QDebug>
40
+
41
+
42
+void TestFlacon::testInputAudioFile()
43
+{
44
+ QFETCH(QString, fileName);
45
+ QFETCH(QString, duration);
46
+ QFETCH(QString, format);
47
+
48
+ uint dur = duration.toInt();
49
+
50
+
51
+ InputAudioFile ia(fileName);
52
+ if (!ia.isValid())
53
+ {
54
+ FAIL(QString("Can't open '%1': %2").arg(fileName, ia.errorString()));
55
+ return;
56
+ }
57
+
58
+ QCOMPARE(ia.duration(), dur);
59
+ QCOMPARE(ia.format()->name(), format);
60
+}
61
+
62
+
63
+void TestFlacon::testInputAudioFile_data()
64
+{
65
+ QTest::addColumn<QString>("fileName");
66
+ QTest::addColumn<QString>("duration");
67
+ QTest::addColumn<QString>("format");
68
+
69
+ QTest::newRow("01 mAudio_cd_ape")
70
+ << mAudio_cd_ape
71
+ << "900000"
72
+ << "APE";
73
+
74
+ QTest::newRow("02 mAudio_cd_flac")
75
+ << mAudio_cd_flac
76
+ << "900000"
77
+ << "FLAC";
78
+
79
+
80
+ QTest::newRow("03 mAudio_cd_tta")
81
+ << mAudio_cd_tta
82
+ << "900000"
83
+ << "TTA";
84
+
85
+ QTest::newRow("04 mAudio_cd_wav")
86
+ << mAudio_cd_wav
87
+ << "900000"
88
+ << "WAV";
89
+
90
+ QTest::newRow("05 mAudio_cd_wv")
91
+ << mAudio_cd_wv
92
+ << "900000"
93
+ << "WavPack";
94
+
95
+
96
+
97
+ QTest::newRow("06 mAudio_24x96_ape")
98
+ << mAudio_24x96_ape
99
+ << "900000"
100
+ << "APE";
101
+
102
+ QTest::newRow("07 mAudio_24x96_flac")
103
+ << mAudio_24x96_flac
104
+ << "900000"
105
+ << "FLAC";
106
+
107
+
108
+ QTest::newRow("08 mAudio_24x96_tta")
109
+ << mAudio_24x96_tta
110
+ << "900000"
111
+ << "TTA";
112
+
113
+ QTest::newRow("09 mAudio_24x96_wav")
114
+ << mAudio_24x96_wav
115
+ << "900000"
116
+ << "WAV";
117
+
118
+ QTest::newRow("10 mAudio_24x96_wv")
119
+ << mAudio_24x96_wv
120
+ << "900000"
121
+ << "WavPack";
122
+
123
+}
124
flacon-3.1.1.tar.gz/tests/test_wavheader.cpp
Added
172
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "../converter/wavheader.h"
29
+#include "testflacon.h"
30
+#include "tools.h"
31
+#include <QTest>
32
+#include <QString>
33
+#include<QBuffer>
34
+
35
+
36
+/************************************************
37
+ *
38
+ ************************************************/
39
+void TestFlacon::testReadWavHeader()
40
+{
41
+ QFETCH(QString, testdata);
42
+ QFETCH(QString, file_size);
43
+ QFETCH(QString, data_size);
44
+ QFETCH(QString, duration);
45
+
46
+ quint32 fileSize = file_size.toLongLong();
47
+ quint32 dataSize = data_size.toLongLong();
48
+ quint64 uduration = duration.toLongLong();
49
+
50
+ try
51
+ {
52
+ QBuffer data;
53
+ data.open(QBuffer::ReadWrite);
54
+ writeHexString(testdata, &data);
55
+ data.seek(0);
56
+
57
+
58
+ WavHeader header;
59
+ header.load(&data);
60
+
61
+ QCOMPARE(header.fileSize(), fileSize);
62
+ QCOMPARE(header.dataSize(), dataSize);
63
+ QCOMPARE(header.duration(), uduration);
64
+ }
65
+ catch (char const *err)
66
+ {
67
+ QFAIL(err);
68
+ }
69
+
70
+
71
+}
72
+
73
+
74
+/************************************************
75
+ *
76
+ ************************************************/
77
+void TestFlacon::testReadWavHeader_data()
78
+{
79
+ QTest::addColumn<QString>("testdata");
80
+ QTest::addColumn<QString>("file_size");
81
+ QTest::addColumn<QString>("data_size");
82
+ QTest::addColumn<QString>("duration");
83
+
84
+ QTest::newRow("1") <<
85
+ "52 49 46 46" // RIFF
86
+ "24 B9 4D 02" // file size - 8
87
+ "57 41 56 45" // WAVE
88
+
89
+ "66 6D 74 20" // "fmt "
90
+ "10 00 00 00" // Chunk size
91
+ "01 00" // AudioFormat
92
+ "02 00" // NumChannels
93
+
94
+ "44 AC 00 00" // mSampleRate
95
+ "10 B1 02 00" // mByteRate
96
+ "04 00" // mBlockAlign
97
+ "10 00" // mBitsPerSample
98
+
99
+ "64 61 74 61" // data
100
+ "00 B9 4D 02" // data size
101
+ "00"
102
+
103
+ << "38648108" // file size
104
+ << "38648064" // data size
105
+ << "219093" // duration 3 min 39 s 93 ms
106
+ ;
107
+
108
+
109
+ QTest::newRow("2") <<
110
+ "52 49 46 46" // RIFF
111
+ "46 B9 4D 02" // file size - 8
112
+ "57 41 56 45" // WAVE
113
+
114
+ "66 6D 74 20" // "fmt "
115
+ "10 00 00 00" // Chunk size
116
+ "01 00" // AudioFormat
117
+ "02 00" // NumChannels
118
+
119
+ "44 AC 00 00" // mSampleRate
120
+ "10 B1 02 00" // mByteRate
121
+ "04 00" // mBlockAlign
122
+ "10 00" // mBitsPerSample
123
+
124
+ "4C 49 53 54" // LIST
125
+ "1A 00 00 00" // Chunk size
126
+ "49 4E 46 4F"
127
+ "49 53 46 54"
128
+ "0E 00 00 00"
129
+ "4C 61 76 66"
130
+ "35 37 2E 34"
131
+ "31 2E 31 30"
132
+ "30 00 "
133
+
134
+ "64 61 74 61" // data
135
+ "00 B9 4D 02" // data size
136
+ "00"
137
+
138
+ << "38648142" // file size
139
+ << "38648064" // data size
140
+ << "219093" // duration 3 min 39 s 93 ms
141
+ ;
142
+
143
+
144
+ QTest::newRow("3") <<
145
+ "52 49 46 46" // RIFF
146
+ "24 A3 23 A8" // file size - 8
147
+ "57 41 56 45" // WAVE
148
+
149
+ "66 6D 74 20" // "fmt "
150
+ "10 00 00 00" // Chunk size
151
+ "01 00" // AudioFormat
152
+ "02 00" // NumChannels
153
+
154
+ "00 EE 02 00" // mSampleRate
155
+ "00 94 11 00" // mByteRate
156
+ "06 00" // mBlockAlign
157
+ "18 00" // mBitsPerSample
158
+
159
+ "64 61 74 61" // data
160
+ "00 A3 23 A8" // data size
161
+
162
+ << "2820907820" // file size
163
+ << "2820907776" // data size
164
+ << "2448704" // duration 40 min 48 s 704 ms
165
+ ;
166
+
167
+}
168
+
169
+
170
+
171
+
172
flacon-2.1.1.tar.gz/tests/testflacon.cpp -> flacon-3.1.1.tar.gz/tests/testflacon.cpp
Changed
958
1
2
3
4
#include "testflacon.h"
5
+#include "tools.h"
6
#include "../disk.h"
7
#include "../settings.h"
8
#include "../project.h"
9
#include "../inputaudiofile.h"
10
#include "converter/converter.h"
11
+#include "converter/wavheader.h"
12
+#include "converter/splitter.h"
13
#include "outformat.h"
14
15
#include <QTest>
16
-#include <QFile>
17
-#include <QFileInfo>
18
#include <QDebug>
19
-#include <QProcessEnvironment>
20
-#include <QSettings>
21
-#include <QDir>
22
#include <QProcess>
23
+#include <QBuffer>
24
+#include <QFileInfo>
25
+#include <QDir>
26
+#include <QThreadPool>
27
28
#define protected public;
29
30
-#define FAIL(message) \
31
-do {\
32
- QTest::qFail(message, __FILE__, __LINE__);\
33
-} while (0)
34
+
35
36
#ifdef Q_OS_WIN
37
#define USE_DEV_RANDOM 0
38
39
#define USE_DEV_RANDOM 1
40
#endif
41
42
+int TestFlacon::mTestNum = -1;
43
44
-/************************************************
45
- *
46
- ************************************************/
47
-Disk *loadFromCue(const QString &cueFile)
48
-{
49
- CueReader cueReader(cueFile);
50
- if (!cueReader.isValid())
51
- FAIL(cueReader.errorString().toLocal8Bit());
52
-
53
- Disk *res = new Disk();
54
- res->loadFromCue(cueReader.disk(0));
55
- return res;
56
-}
57
58
59
/************************************************
60
61
}
62
63
64
-/************************************************
65
-
66
- ************************************************/
67
-void TestFlacon::initTestCase()
68
-{
69
- QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, QString::fromLocal8Bit(TEST_OUT_DIR));
70
- QSettings::setPath(QSettings::NativeFormat, QSettings::UserScope, QString::fromLocal8Bit(TEST_OUT_DIR));
71
-
72
- QString shntool = settings->findProgram("shntool");
73
- if (shntool.isEmpty())
74
- FAIL(QString("Program \"%1\" not found.").arg("shntool").toLocal8Bit());
75
-
76
- settings->setValue(Settings::Prog_Shntool, shntool);
77
- settings->sync();
78
-
79
- mFfmpeg = settings->findProgram("avconv");
80
- if (mFfmpeg.isEmpty())
81
- mFfmpeg = settings->findProgram("ffmpeg");
82
-
83
- if (mFfmpeg.isEmpty())
84
- FAIL(QString("Program \"%1\" not found.").arg("avconv/ffmpeg").toLocal8Bit());
85
-
86
- mCdAudioFile = mTmpDir + "CD.wav";
87
- createAudioFile(mFfmpeg, mCdAudioFile, 900, true);
88
-
89
- mHdAudioFile = mTmpDir + "HD.wav";
90
- createAudioFile(mFfmpeg, mHdAudioFile, 900, false);
91
-}
92
-
93
-
94
-/************************************************
95
-
96
- ************************************************/
97
-void TestFlacon::createAudioFile(const QString &program, const QString &fileName, int duration, bool cdQuality)
98
-{
99
- if (QFileInfo(fileName).exists())
100
- return;
101
-
102
- QStringList args;
103
-# if USE_DEV_RANDOM
104
- args << "-y"; // Overwrite output files."
105
- args << "-ar" << (cdQuality ? "44100" : " 48000");
106
- args << "-f" << "s16le";
107
- args << "-acodec" << "pcm_s16le";
108
- args << "-ac" << "2";
109
- args << "-i" << "/dev/urandom";
110
- args << "-t" << QString("%1").arg(duration);
111
- args << fileName;
112
-#else
113
- args << "-y"; // Overwrite output files."
114
- args << "-t" << QString("%1").arg(duration);
115
- args << "-f" << "lavfi";
116
- args << "-i" << "anullsrc";
117
- args << "-ar" << (cdQuality ? "44100" : " 48000");
118
- args << "-acodec" << "pcm_s16le";
119
- args << "-ac" << "2";
120
- args << QDir::toNativeSeparators(fileName);
121
-#endif
122
-
123
- QProcess proc;
124
- //proc.setProcessChannelMode(QProcess::ForwardedChannels);
125
-
126
- proc.start(program, args);
127
- proc.waitForFinished(3 * 60 * 10000);
128
- if (proc.exitCode() != 0)
129
- {
130
- QString err = proc.readAllStandardError();
131
- QFAIL(QString("Can't create audio file: %1").arg(err).toLocal8Bit());
132
- }
133
-}
134
-
135
136
/************************************************
137
138
139
}
140
141
142
+
143
+
144
/************************************************
145
146
************************************************/
147
148
{
149
if (mStandardDisk == 0)
150
{
151
- QString cueFile = mTmpDir + "testTrackResultFileName.cue";
152
+ QString cueFile = dir() + "testTrackResultFileName.cue";
153
154
QStringList cue;
155
cue << "REM GENRE \"Genre\"";
156
157
}
158
159
160
-/************************************************
161
-
162
- ************************************************/
163
-ConverterTester::ConverterTester(const QString &cueFile, const QString &audioFile, const QString &expectedCue, const QString &resultFiles)
164
-{
165
- mResultFiles = resultFiles.split(';', QString::SkipEmptyParts);
166
- mExpectedCue = expectedCue;
167
- project->clear();
168
- mDisk = loadFromCue(cueFile);
169
- InputAudioFile audio(audioFile);
170
- mDisk->setAudioFile(audio);
171
- project->addDisk(mDisk);
172
-}
173
-
174
-/************************************************
175
-
176
- ************************************************/
177
-void ConverterTester::run(const QString &name)
178
-{
179
- Converter conv;
180
- QEventLoop loop;
181
- loop.connect(&conv, SIGNAL(finished()), &loop, SLOT(quit()));
182
- conv.start();
183
-
184
- if (!conv.isRunning())
185
- {
186
- QString msg;
187
- mDisk->canConvert(&msg);
188
- QFAIL(QString("Can't start converter: \"%1\"").arg(msg).toLocal8Bit());
189
- }
190
-
191
- loop.exec();
192
-
193
- QDir outDir = QFileInfo(mDisk->track(0)->resultFilePath()).dir();
194
- QStringList files = outDir.entryList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::Files);
195
- project->clear();
196
-
197
- QStringList missing;
198
- foreach(QString f, mResultFiles)
199
- {
200
- if (files.removeAll(f) == 0)
201
- missing << f;
202
- }
203
-
204
-
205
- QString msg = "";
206
- if (!missing.isEmpty())
207
- msg += QString("\nFiles not exists:\n *%1").arg(missing.join("\n *"));
208
209
- if (!files.isEmpty())
210
- msg += QString("\nFiles exists:\n *%1").arg(files.join("\n *"));
211
212
213
- if (!mExpectedCue.isEmpty())
214
- {
215
- QString resCueFile;
216
- files = outDir.entryList(QStringList() << "*.cue", QDir::Files);
217
- if (files.isEmpty())
218
- {
219
- msg += "\nResult CUE file not found.";
220
- }
221
- else
222
- {
223
- QString err;
224
- if (!TestFlacon::compareCue(outDir.absoluteFilePath(files.first()), mExpectedCue, &err))
225
- msg += "\n" + err;
226
- }
227
- }
228
-
229
- if (!msg.isEmpty())
230
- QFAIL(name.toLocal8Bit() + "\n" + msg.toLocal8Bit());
231
-
232
-}
233
-
234
-
235
-/************************************************
236
-
237
- ************************************************/
238
-void TestFlacon::testConvert()
239
-{
240
- QString resultDir = mTmpDir + QString("/converted/");
241
- clearDir(resultDir);
242
-
243
- settings->setValue(Settings::OutFiles_Directory, resultDir);
244
- settings->setValue(Settings::OutFiles_Pattern, "%a/%n - %t");
245
- settings->setValue(Settings::OutFiles_Format, "WAV");
246
- settings->setValue(Settings::PerTrackCue_FlaconTags, false);
247
-
248
- QString inDir = mDataDir + "/testConvert/";
249
- QString outDir;
250
- //## 1.1 ##############################################
251
- // With pregap and HTOA
252
- {
253
- outDir = resultDir + "Test_1.1";
254
- settings->setValue(Settings::PerTrackCue_Create, false);
255
- settings->setValue(Settings::PerTrackCue_Pregap, OutFormat::preGapTypeToString(OutFormat::PreGapExtractToFile));
256
- settings->setValue(Settings::OutFiles_Directory, outDir);
257
-
258
- ConverterTester conv(
259
- inDir + "01.cuecreator.cue",
260
- mHdAudioFile,
261
- "",
262
- "01 - Song01.wav;"
263
- "02 - Song02.wav;"
264
- "03 - Song03.wav;"
265
- "04 - Song04.wav;"
266
- );
267
-
268
- conv.run("1.1. With pregap and HTOA, w/o cue");
269
- }
270
- //## 1.1 ##############################################
271
-
272
- //## 1.2 ##############################################
273
- // With pregap and HTOA
274
- {
275
- outDir = resultDir + "Test_1.2";
276
- settings->setValue(Settings::PerTrackCue_Create, true);
277
- settings->setValue(Settings::PerTrackCue_Pregap, OutFormat::preGapTypeToString(OutFormat::PreGapExtractToFile));
278
- settings->setValue(Settings::OutFiles_Directory, outDir);
279
-
280
- ConverterTester conv(
281
- inDir + "01.cuecreator.cue",
282
- mHdAudioFile,
283
- inDir + "01.expected.cue",
284
- "01 - Song01.wav;"
285
- "02 - Song02.wav;"
286
- "03 - Song03.wav;"
287
- "04 - Song04.wav;"
288
- "00 - (HTOA).wav;"
289
- "Artist-Album.cue;"
290
- );
291
-
292
- conv.run("1.2. With pregap and HTOA, with cue");
293
- }
294
- //## 1.2 ##############################################
295
-
296
- //## 2.1 ##############################################
297
- // W/o pregap, w/o HTOA
298
- {
299
- outDir = resultDir + "Test_2.1";
300
- settings->setValue(Settings::PerTrackCue_Create, true);
301
- settings->setValue(Settings::PerTrackCue_Pregap, OutFormat::preGapTypeToString(OutFormat::PreGapAddToFirstTrack));
302
- settings->setValue(Settings::OutFiles_Directory, outDir);
303
-
304
- ConverterTester conv(
305
- inDir + "02.cuecreator.cue",
306
- mHdAudioFile,
307
- inDir + "02.expected.cue",
308
- "01 - Song01.wav;"
309
- "02 - Song02.wav;"
310
- "03 - Song03.wav;"
311
- "04 - Song04.wav;"
312
- "Artist-Album.cue;"
313
- );
314
-
315
- conv.run("2.1 W/o pregap, w/o HTOA");
316
- }
317
- //## 2.1 ##############################################
318
-
319
- //## 2.2 ##############################################
320
- // W/o pregap, w/o HTOA
321
- {
322
- outDir = resultDir + "Test_2.2";
323
- settings->setValue(Settings::PerTrackCue_Create, true);
324
- settings->setValue(Settings::PerTrackCue_Pregap, OutFormat::preGapTypeToString(OutFormat::PreGapExtractToFile));
325
- settings->setValue(Settings::OutFiles_Directory, outDir);
326
-
327
-
328
- ConverterTester conv(
329
- inDir + "02.cuecreator.cue",
330
- mHdAudioFile,
331
- inDir + "02.expected.cue",
332
- "01 - Song01.wav;"
333
- "02 - Song02.wav;"
334
- "03 - Song03.wav;"
335
- "04 - Song04.wav;"
336
- "Artist-Album.cue;"
337
- );
338
-
339
- conv.run("2.2. W/o pregap, w/o HTOA");
340
- }
341
- //## 2.2 ##############################################
342
-
343
- //## 3 ################################################
344
- // With pregap, w/o HTOA
345
- {
346
- outDir = resultDir + "Test_3";
347
- settings->setValue(Settings::PerTrackCue_Create, true);
348
- settings->setValue(Settings::PerTrackCue_Pregap, OutFormat::preGapTypeToString(OutFormat::PreGapAddToFirstTrack));
349
- settings->setValue(Settings::OutFiles_Directory, outDir);
350
-
351
- ConverterTester conv(
352
- inDir + "03.cuecreator.cue",
353
- mHdAudioFile,
354
- inDir + "03.expected.cue",
355
- "01 - Song01.wav;"
356
- "02 - Song02.wav;"
357
- "03 - Song03.wav;"
358
- "04 - Song04.wav;"
359
- "Artist-Album.cue;"
360
- );
361
-
362
- conv.run("3. With pregap, w/o HTOA");
363
- }
364
- //## 3 ################################################
365
-
366
- //## 4 ################################################
367
- // All tags
368
- {
369
- outDir = resultDir + "Test_4";
370
- settings->setValue(Settings::PerTrackCue_Create, true);
371
- settings->setValue(Settings::PerTrackCue_Pregap, OutFormat::preGapTypeToString(OutFormat::PreGapAddToFirstTrack));
372
- settings->setValue(Settings::OutFiles_Directory, outDir);
373
-
374
- ConverterTester conv(
375
- inDir + "04.cuecreator.cue",
376
- mHdAudioFile,
377
- inDir + "04.expected.cue",
378
- "01 - Song01.wav;"
379
- "02 - Song02.wav;"
380
- "03 - Song03.wav;"
381
- "04 - Song04.wav;"
382
- "Artist-Album.cue;"
383
- );
384
-
385
- conv.run("4. All tags");
386
- }
387
- //## 4 ################################################
388
-
389
- //## 5 ################################################
390
- // Cue w/o tags + tags form the separate file
391
- {
392
- outDir = resultDir + "Test_5";
393
- settings->setValue(Settings::PerTrackCue_Create, true);
394
- settings->setValue(Settings::PerTrackCue_Pregap, OutFormat::preGapTypeToString(OutFormat::PreGapAddToFirstTrack));
395
- settings->setValue(Settings::OutFiles_Directory, outDir);
396
-
397
- ConverterTester conv(
398
- inDir + "05.cuecreator.cue",
399
- mHdAudioFile,
400
- inDir + "05.expected.cue",
401
- "01 - Song01.wav;"
402
- "02 - Song02.wav;"
403
- "03 - Song03.wav;"
404
- "04 - Song04.wav;"
405
- "Artist-Album.cue;"
406
- );
407
-
408
- for (int i=0; i<conv.disk()->count(); ++i)
409
- {
410
- Track *track = conv.disk()->track(i);
411
- track->setArtist("Artist");
412
- track->setAlbum("Album");
413
- track->setTitle(QString("Song%1").arg(i+1, 2, 10, QChar('0')));
414
- track->setGenre("Genre");
415
- track->setDate("2013");
416
- }
417
-
418
- conv.run("5. Cue w/o tags + tags form the separate file");
419
- }
420
- //## 5 ################################################
421
-
422
- //## 6 ################################################
423
- // Garbage in the CUE
424
- {
425
- outDir = resultDir + "Test_6";
426
- settings->setValue(Settings::PerTrackCue_Create, false);
427
- settings->setValue(Settings::PerTrackCue_Pregap, OutFormat::preGapTypeToString(OutFormat::PreGapExtractToFile));
428
- settings->setValue(Settings::OutFiles_Directory, outDir);
429
-
430
- ConverterTester conv(
431
- inDir + "06.garbageInTags.cue",
432
- mHdAudioFile,
433
- "",
434
- "01 - Song01.wav;"
435
- "02 - Song02.wav;"
436
- "03 - Song03.wav;"
437
- "04 - Song04.wav;"
438
- );
439
-
440
- conv.run("6. Garbage in the CUE");
441
- }
442
- //## 6 #################################################
443
-
444
-
445
- //## 7 #################################################
446
- // With pregap and HTOA
447
- {
448
- QString dir = resultDir + "Test_07.path(with.symbols and space )";
449
- QDir().mkpath(dir);
450
- QString audioFile = dir + "CD_10Min.wav";
451
- createAudioFile(mFfmpeg, audioFile, 600, true);
452
-
453
-
454
-
455
- outDir = resultDir + "Test_7";
456
- settings->setValue(Settings::PerTrackCue_Create, false);
457
- settings->setValue(Settings::PerTrackCue_Pregap, OutFormat::preGapTypeToString(OutFormat::PreGapExtractToFile));
458
- settings->setValue(Settings::OutFiles_Directory, dir);
459
- settings->setValue(Settings::Encoder_TmpDir, "");
460
- ConverterTester conv(
461
- inDir + "07.path(with.symbols and space )/07.path(with.symbols and space ).cue",
462
- audioFile,
463
- "",
464
- "01 - Song01.wav;"
465
- "02 - Song02.wav;"
466
- "03 - Song03.wav;"
467
- "04 - Song04.wav;"
468
- );
469
-
470
- conv.run("7. With pregap and HTOA");
471
- }
472
- //## 7 #################################################
473
-
474
-
475
- //## 8 #################################################
476
- // With pregap and HTOA
477
- {
478
- outDir = resultDir + QString::fromUtf8("Test_8/Музыка");
479
- settings->setValue(Settings::PerTrackCue_Create, false);
480
- settings->setValue(Settings::PerTrackCue_Pregap, OutFormat::preGapTypeToString(OutFormat::PreGapExtractToFile));
481
- settings->setValue(Settings::OutFiles_Directory, outDir);
482
-
483
- ConverterTester conv(
484
- inDir + "01.cuecreator.cue",
485
- mHdAudioFile,
486
- "",
487
- "01 - Song01.wav;"
488
- "02 - Song02.wav;"
489
- "03 - Song03.wav;"
490
- "04 - Song04.wav;"
491
- );
492
-
493
- conv.run("8. With pregap and HTOA");
494
- }
495
- //## 8 #################################################
496
-
497
-}
498
499
500
/************************************************
501
502
************************************************/
503
void TestFlacon::testTrackResultFileName()
504
{
505
- QFETCH(QString, cueFile);
506
+ QFETCH(QString, cue);
507
QFETCH(QString, pattern);
508
QFETCH(QString, expected);
509
510
settings->setValue(Settings::OutFiles_Pattern, pattern);
511
settings->setValue(Settings::OutFiles_Format, "WAV");
512
513
+
514
+ QString cueFile = dir() + "/input.cue";
515
+ writeTextFile(cueFile, cue);
516
+
517
Disk *disk = loadFromCue(cueFile);
518
519
QString result = disk->track(0)->resultFileName();
520
521
************************************************/
522
void TestFlacon::testTrackResultFileName_data()
523
{
524
- QTest::addColumn<QString>("cueFile");
525
+ QTest::addColumn<QString>("cue");
526
QTest::addColumn<QString>("pattern");
527
QTest::addColumn<QString>("expected");
528
529
- QString cueFile = mTmpDir + "testTrackResultFileName.cue";
530
531
- {
532
- QStringList cue;
533
- cue << "REM GENRE \"Genre\"";
534
- cue << "REM DATE 2013";
535
- cue << "REM DISCID 123456789";
536
- cue << "REM COMMENT \"ExactAudioCopy v0.99pb4\"";
537
- cue << "PERFORMER \"Artist\"";
538
- cue << "TITLE \"Album\"";
539
- cue << "FILE \"en.wav\" WAVE";
540
- cue << " TRACK 01 AUDIO";
541
- cue << " TITLE \"Song01\"";
542
- cue << " INDEX 01 00:00:00";
543
- cue << " TRACK 02 AUDIO";
544
- cue << " TITLE \"Song02\"";
545
- cue << " INDEX 01 03:39:10";
546
- cue << " TRACK 03 AUDIO";
547
- cue << " TITLE \"Song03\"";
548
- cue << " INDEX 01 07:25:42";
549
- cue << " TRACK 04 AUDIO";
550
- cue << " TITLE \"Song04\"";
551
- cue << " INDEX 01 12:04:72";
552
-
553
- writeTextFile(cueFile, cue);
554
- }
555
-
556
-
557
- QTest::newRow("1")
558
- << cueFile
559
+ QTest::newRow("1.1")
560
+ << "REM GENRE \"Genre\"\n"
561
+ "REM DATE 2013\n"
562
+ "REM DISCID 123456789\n"
563
+ "REM COMMENT \"ExactAudioCopy v0.99pb4\"\n"
564
+ "PERFORMER \"Artist\"\n"
565
+ "TITLE \"Album\"\n"
566
+ "FILE \"en.wav\" WAVE\n"
567
+ " TRACK 01 AUDIO\n"
568
+ " TITLE \"Song01\"\n"
569
+ " INDEX 01 00:00:00\n"
570
+ " TRACK 02 AUDIO\n"
571
+ " TITLE \"Song02\"\n"
572
+ " INDEX 01 03:39:10\n"
573
+ " TRACK 03 AUDIO\n"
574
+ " TITLE \"Song03\"\n"
575
+ " INDEX 01 07:25:42\n"
576
+ " TRACK 04 AUDIO\n"
577
+ " TITLE \"Song04\"\n"
578
+ " INDEX 01 12:04:72\n"
579
<< "%a/%y - %A/%n - %t"
580
<< "Artist/2013 - Album/01 - Song01.wav";
581
582
- QTest::newRow("2")
583
- << cueFile
584
+ QTest::newRow("1.2")
585
+ << "REM GENRE \"Genre\"\n"
586
+ "REM DATE 2013\n"
587
+ "REM DISCID 123456789\n"
588
+ "REM COMMENT \"ExactAudioCopy v0.99pb4\"\n"
589
+ "PERFORMER \"Artist\"\n"
590
+ "TITLE \"Album\"\n"
591
+ "FILE \"en.wav\" WAVE\n"
592
+ " TRACK 01 AUDIO\n"
593
+ " TITLE \"Song01\"\n"
594
+ " INDEX 01 00:00:00\n"
595
+ " TRACK 02 AUDIO\n"
596
+ " TITLE \"Song02\"\n"
597
+ " INDEX 01 03:39:10\n"
598
+ " TRACK 03 AUDIO\n"
599
+ " TITLE \"Song03\"\n"
600
+ " INDEX 01 07:25:42\n"
601
+ " TRACK 04 AUDIO\n"
602
+ " TITLE \"Song04\"\n"
603
+ " INDEX 01 12:04:72\n"
604
+
605
<< "N/n/A/a/t/y/g"
606
<< "N/n/A/a/t/y/g.wav";
607
608
- QTest::newRow("3")
609
- << cueFile
610
+ QTest::newRow("1.3")
611
+ << "REM GENRE \"Genre\"\n"
612
+ "REM DATE 2013\n"
613
+ "REM DISCID 123456789\n"
614
+ "REM COMMENT \"ExactAudioCopy v0.99pb4\"\n"
615
+ "PERFORMER \"Artist\"\n"
616
+ "TITLE \"Album\"\n"
617
+ "FILE \"en.wav\" WAVE\n"
618
+ " TRACK 01 AUDIO\n"
619
+ " TITLE \"Song01\"\n"
620
+ " INDEX 01 00:00:00\n"
621
+ " TRACK 02 AUDIO\n"
622
+ " TITLE \"Song02\"\n"
623
+ " INDEX 01 03:39:10\n"
624
+ " TRACK 03 AUDIO\n"
625
+ " TITLE \"Song03\"\n"
626
+ " INDEX 01 07:25:42\n"
627
+ " TRACK 04 AUDIO\n"
628
+ " TITLE \"Song04\"\n"
629
+ " INDEX 01 12:04:72\n"
630
+
631
<< "N/n/A/a/t/y/g"
632
<< "N/n/A/a/t/y/g.wav";
633
634
- QTest::newRow("4")
635
- << cueFile
636
+ QTest::newRow("1.4")
637
+ << "REM GENRE \"Genre\"\n"
638
+ "REM DATE 2013\n"
639
+ "REM DISCID 123456789\n"
640
+ "REM COMMENT \"ExactAudioCopy v0.99pb4\"\n"
641
+ "PERFORMER \"Artist\"\n"
642
+ "TITLE \"Album\"\n"
643
+ "FILE \"en.wav\" WAVE\n"
644
+ " TRACK 01 AUDIO\n"
645
+ " TITLE \"Song01\"\n"
646
+ " INDEX 01 00:00:00\n"
647
+ " TRACK 02 AUDIO\n"
648
+ " TITLE \"Song02\"\n"
649
+ " INDEX 01 03:39:10\n"
650
+ " TRACK 03 AUDIO\n"
651
+ " TITLE \"Song03\"\n"
652
+ " INDEX 01 07:25:42\n"
653
+ " TRACK 04 AUDIO\n"
654
+ " TITLE \"Song04\"\n"
655
+ " INDEX 01 12:04:72\n"
656
+
657
<< "/%%/%Q/%N/%n/%A/%a/%t/%y/%g/%%"
658
<< "/%/%Q/04/01/Album/Artist/Song01/2013/Genre/%.wav";
659
660
661
- QTest::newRow("5")
662
- << cueFile
663
+ QTest::newRow("1.5")
664
+ << "REM GENRE \"Genre\"\n"
665
+ "REM DATE 2013\n"
666
+ "REM DISCID 123456789\n"
667
+ "REM COMMENT \"ExactAudioCopy v0.99pb4\"\n"
668
+ "PERFORMER \"Artist\"\n"
669
+ "TITLE \"Album\"\n"
670
+ "FILE \"en.wav\" WAVE\n"
671
+ " TRACK 01 AUDIO\n"
672
+ " TITLE \"Song01\"\n"
673
+ " INDEX 01 00:00:00\n"
674
+ " TRACK 02 AUDIO\n"
675
+ " TITLE \"Song02\"\n"
676
+ " INDEX 01 03:39:10\n"
677
+ " TRACK 03 AUDIO\n"
678
+ " TITLE \"Song03\"\n"
679
+ " INDEX 01 07:25:42\n"
680
+ " TRACK 04 AUDIO\n"
681
+ " TITLE \"Song04\"\n"
682
+ " INDEX 01 12:04:72\n"
683
+
684
<< "%%Q/%%N/%%n/%%A/%%a/%%t/%%y/%%g"
685
<< "%Q/%N/%n/%A/%a/%t/%y/%g.wav";
686
687
- QTest::newRow("6")
688
- << cueFile
689
+ QTest::newRow("1.6")
690
+ << "REM GENRE \"Genre\"\n"
691
+ "REM DATE 2013\n"
692
+ "REM DISCID 123456789\n"
693
+ "REM COMMENT \"ExactAudioCopy v0.99pb4\"\n"
694
+ "PERFORMER \"Artist\"\n"
695
+ "TITLE \"Album\"\n"
696
+ "FILE \"en.wav\" WAVE\n"
697
+ " TRACK 01 AUDIO\n"
698
+ " TITLE \"Song01\"\n"
699
+ " INDEX 01 00:00:00\n"
700
+ " TRACK 02 AUDIO\n"
701
+ " TITLE \"Song02\"\n"
702
+ " INDEX 01 03:39:10\n"
703
+ " TRACK 03 AUDIO\n"
704
+ " TITLE \"Song03\"\n"
705
+ " INDEX 01 07:25:42\n"
706
+ " TRACK 04 AUDIO\n"
707
+ " TITLE \"Song04\"\n"
708
+ " INDEX 01 12:04:72\n"
709
+
710
<< "%%%Q/%%%N/%%%n/%%%A/%%%a/%%%t/%%%y/%%%g/%%%"
711
<< "%%Q/%04/%01/%Album/%Artist/%Song01/%2013/%Genre/%%.wav";
712
713
- cueFile = TEST_OUT_DIR "testTrackResultFileName2.cue";
714
- {
715
- QStringList cue;
716
- cue << "REM DATE 2013";
717
- cue << "REM DISCID 123456789";
718
- cue << "REM COMMENT \"ExactAudioCopy v0.99pb4\"";
719
- cue << "PERFORMER \"Artist\"";
720
- cue << "FILE \"en.wav\" WAVE";
721
- cue << " TRACK 01 AUDIO";
722
- cue << " TITLE \"Song01\"";
723
- cue << " INDEX 01 00:00:00";
724
- cue << " TRACK 02 AUDIO";
725
- cue << " TITLE \"Song02\"";
726
- cue << " INDEX 01 03:39:10";
727
- cue << " TRACK 03 AUDIO";
728
- cue << " TITLE \"Song03\"";
729
- cue << " INDEX 01 07:25:42";
730
- cue << " TRACK 04 AUDIO";
731
- cue << " TITLE \"Song04\"";
732
- cue << " INDEX 01 12:04:72";
733
-
734
- writeTextFile(cueFile, cue);
735
- }
736
-
737
+ QTest::newRow("2.1")
738
+ << "REM DATE 2013\n"
739
+ "REM DISCID 123456789\n"
740
+ "REM COMMENT \"ExactAudioCopy v0.99pb4\"\n"
741
+ "PERFORMER \"Artist\"\n"
742
+ "FILE \"en.wav\" WAVE\n"
743
+ " TRACK 01 AUDIO\n"
744
+ " TITLE \"Song01\"\n"
745
+ " INDEX 01 00:00:00\n"
746
+ " TRACK 02 AUDIO\n"
747
+ " TITLE \"Song02\"\n"
748
+ " INDEX 01 03:39:10\n"
749
+ " TRACK 03 AUDIO\n"
750
+ " TITLE \"Song03\"\n"
751
+ " INDEX 01 07:25:42\n"
752
+ " TRACK 04 AUDIO\n"
753
+ " TITLE \"Song04\"\n"
754
+ " INDEX 01 12:04:72\n"
755
756
- QTest::newRow("1")
757
- << cueFile
758
<< "{}/{Text}/{%n}/{%n Text}/{%A}/{%A Text}"
759
<< "{}/{Text}/01/01 Text//.wav";
760
761
762
- QTest::newRow("2")
763
- << cueFile
764
+ QTest::newRow("2.2")
765
+ << "REM DATE 2013\n"
766
+ "REM DISCID 123456789\n"
767
+ "REM COMMENT \"ExactAudioCopy v0.99pb4\"\n"
768
+ "PERFORMER \"Artist\"\n"
769
+ "FILE \"en.wav\" WAVE\n"
770
+ " TRACK 01 AUDIO\n"
771
+ " TITLE \"Song01\"\n"
772
+ " INDEX 01 00:00:00\n"
773
+ " TRACK 02 AUDIO\n"
774
+ " TITLE \"Song02\"\n"
775
+ " INDEX 01 03:39:10\n"
776
+ " TRACK 03 AUDIO\n"
777
+ " TITLE \"Song03\"\n"
778
+ " INDEX 01 07:25:42\n"
779
+ " TRACK 04 AUDIO\n"
780
+ " TITLE \"Song04\"\n"
781
+ " INDEX 01 12:04:72\n"
782
+
783
<< "Test{Text/{%n}/{%n Text}/{%A}/{%A Text}"
784
<< "Test{Text/01/01 Text//.wav";
785
786
787
- QTest::newRow("3")
788
- << cueFile
789
+ QTest::newRow("2.3")
790
+ << "REM DATE 2013\n"
791
+ "REM DISCID 123456789\n"
792
+ "REM COMMENT \"ExactAudioCopy v0.99pb4\"\n"
793
+ "PERFORMER \"Artist\"\n"
794
+ "FILE \"en.wav\" WAVE\n"
795
+ " TRACK 01 AUDIO\n"
796
+ " TITLE \"Song01\"\n"
797
+ " INDEX 01 00:00:00\n"
798
+ " TRACK 02 AUDIO\n"
799
+ " TITLE \"Song02\"\n"
800
+ " INDEX 01 03:39:10\n"
801
+ " TRACK 03 AUDIO\n"
802
+ " TITLE \"Song03\"\n"
803
+ " INDEX 01 07:25:42\n"
804
+ " TRACK 04 AUDIO\n"
805
+ " TITLE \"Song04\"\n"
806
+ " INDEX 01 12:04:72\n"
807
+
808
<< "Text}/{%n}/{%n Text}/{%A}/{%A Text}"
809
<< "Text}/01/01 Text//.wav";
810
811
812
<< "."
813
<< "%a/%y - %A/%n - %t"
814
<< mTmpDir + "/Artist/2013 - Album/01 - Song01.wav"
815
- << mCdAudioFile;
816
+ << mAudio_cd_wav;
817
818
QTest::newRow("6. empty with CdAudioFile")
819
<< ""
820
<< "%a/%y - %A/%n - %t"
821
<< mTmpDir + "/Artist/2013 - Album/01 - Song01.wav"
822
- << mCdAudioFile;
823
+ << mAudio_cd_wav;
824
825
QTest::newRow("7: ~")
826
<< "~"
827
828
QFETCH(QString, codepageBefore);
829
QFETCH(QString, codepageAfter);
830
831
- QString outFilePattern = QString("%1%2.%3.%4")
832
- .arg(TEST_OUT_DIR)
833
- .arg(count, 2, 10, QChar('0'))
834
- .arg(QTest::currentDataTag());
835
-
836
QString testDataDir = TEST_DATA_DIR;
837
838
- QString testCueFile = outFilePattern.arg("cue");
839
- QString expectedFile = outFilePattern.arg("expected");
840
- QString resultFile = outFilePattern.arg("result");
841
+ QString testCueFile = dir() + "/input.cue";
842
+ QString expectedFile = dir() + "/expected.cue";
843
+ QString resultFile = dir() + "/result.cue";
844
845
if (QFileInfo(testCueFile).exists())
846
QFile(testCueFile).remove();
847
848
849
foreach (QString f, audioFiles.split(","))
850
{
851
- QFile(mCdAudioFile).link(dir + f.trimmed());
852
+ QFile(mAudio_cd_wav).link(dir + f.trimmed());
853
}
854
855
856
857
"FileTag(2).wav";
858
}
859
860
-struct TestCueFile {
861
+struct TestCueFile_ {
862
QString name;
863
QString fileTag;
864
QString fileTag2;
865
};
866
-Q_DECLARE_METATYPE(TestCueFile)
867
+Q_DECLARE_METATYPE(TestCueFile_)
868
869
870
struct TestFindCueFileData {
871
- QList<TestCueFile> cueFiles;
872
+ QList<TestCueFile_> cueFiles;
873
QStringList audioFiles;
874
QString chekAudioFile;
875
QString expected;
876
};
877
Q_DECLARE_METATYPE(TestFindCueFileData)
878
879
+
880
/************************************************
881
882
************************************************/
883
884
885
foreach (QString f, test.audioFiles)
886
{
887
- QFile(mCdAudioFile).link(dir + f.trimmed());
888
+ QFile(mAudio_cd_wav).link(dir + f.trimmed());
889
}
890
891
- foreach (TestCueFile cueFile, test.cueFiles)
892
+ foreach (TestCueFile_ cueFile, test.cueFiles)
893
{
894
QStringList cue;
895
cue << "REM DATE 2013";
896
897
898
// -------------------------------------
899
test = TestFindCueFileData();
900
- test.cueFiles.append(TestCueFile());
901
+ test.cueFiles.append(TestCueFile_());
902
test.cueFiles.last().name = "1.cue";
903
test.cueFiles.last().fileTag= "FILE \"1.wav\" WAVE";
904
905
906
907
// -------------------------------------
908
test = TestFindCueFileData();
909
- test.cueFiles.append(TestCueFile());
910
+ test.cueFiles.append(TestCueFile_());
911
test.cueFiles.last().name = "1.cue";
912
test.cueFiles.last().fileTag= "FILE \"1.wav\" WAVE";
913
914
- test.cueFiles.append(TestCueFile());
915
+ test.cueFiles.append(TestCueFile_());
916
test.cueFiles.last().name = "2.cue";
917
test.cueFiles.last().fileTag= "FILE \"2.wav\" WAVE";
918
919
920
921
// -------------------------------------
922
test = TestFindCueFileData();
923
- test.cueFiles.append(TestCueFile());
924
+ test.cueFiles.append(TestCueFile_());
925
test.cueFiles.last().name = "1.cue";
926
test.cueFiles.last().fileTag= "FILE \"1.wav\" WAVE";
927
928
- test.cueFiles.append(TestCueFile());
929
+ test.cueFiles.append(TestCueFile_());
930
test.cueFiles.last().name = "2.cue";
931
test.cueFiles.last().fileTag= "FILE \"2.wav\" WAVE";
932
933
934
935
// -------------------------------------
936
test = TestFindCueFileData();
937
- test.cueFiles.append(TestCueFile());
938
+ test.cueFiles.append(TestCueFile_());
939
test.cueFiles.last().name = "multi.cue";
940
test.cueFiles.last().fileTag = "FILE \"1.wav\" WAVE";
941
test.cueFiles.last().fileTag2= "FILE \"2.wav\" WAVE";
942
943
944
// -------------------------------------
945
test = TestFindCueFileData();
946
- test.cueFiles.append(TestCueFile());
947
+ test.cueFiles.append(TestCueFile_());
948
test.cueFiles.last().name = "multi.cue";
949
test.cueFiles.last().fileTag = "FILE \"1.wav\" WAVE";
950
test.cueFiles.last().fileTag2= "FILE \"2.wav\" WAVE";
951
952
test.expected = "multi.cue";
953
QTest::newRow("multi.cue multi_1.wav multi_2.wav") << test;
954
}
955
+
956
+
957
QTEST_MAIN(TestFlacon)
958
flacon-2.1.1.tar.gz/tests/testflacon.h -> flacon-3.1.1.tar.gz/tests/testflacon.h
Changed
115
1
2
#ifndef TEST_FLACON_H
3
#define TEST_FLACON_H
4
5
+#include <QTest>
6
#include <QObject>
7
#include <QStringList>
8
#include <QMap>
9
10
11
#define SettingsValues QMap<QString, QVariant>
12
13
-class ConverterTester
14
-{
15
-public:
16
- ConverterTester(const QString &cueFile,
17
- const QString &audioFile,
18
- const QString &expectedCue,
19
- const QString &resultFiles);
20
-
21
-
22
- void run(const QString &name);
23
-
24
- Disk *disk() { return mDisk; }
25
-
26
-private:
27
- Disk *mDisk;
28
- QStringList mResultFiles;
29
- QString mExpectedCue;
30
-
31
- ConverterTester(const ConverterTester &other) {}
32
-};
33
-
34
class TestFlacon : public QObject
35
{
36
Q_OBJECT
37
38
39
private slots:
40
void initTestCase();
41
+ void init();
42
+
43
+ void testReadWavHeader();
44
+ void testReadWavHeader_data();
45
+
46
+ void testFormatWavLast();
47
+
48
+ void testFormat();
49
+ void testFormat_data();
50
+
51
+ void testFormatFromFile();
52
+ void testFormatFromFile_data();
53
+
54
+ void testInputAudioFile();
55
+ void testInputAudioFile_data();
56
+
57
+ void testDecoder();
58
+ void testDecoder_data();
59
60
void testByteArraySplit_data();
61
void testByteArraySplit();
62
63
void testFindCueFile_data();
64
void testFindCueFile();
65
66
-
67
void testConvert();
68
+ void testConvert_data();
69
70
private:
71
- void createAudioFile(const QString &program, const QString &fileName, int duration, bool cdQuality);
72
void writeTextFile( const QString &fileName, const QString &content);
73
void writeTextFile( const QString &fileName, const QStringList &content);
74
75
76
void checkFileNotExists(const QString &fileName);
77
78
void applySettings(const SettingsValues &config);
79
+ QString dir();
80
81
Disk *standardDisk();
82
83
- QString mFfmpeg;
84
- QString mCdAudioFile;
85
- QString mHdAudioFile;
86
+ QString mAudio_cd_wav;
87
+ QString mAudio_24x96_wav;
88
+
89
+ QString mAudio_cd_ape;
90
+ QString mAudio_24x96_ape;
91
+
92
+
93
+ QString mAudio_cd_flac;
94
+ QString mAudio_24x96_flac;
95
+
96
+ QString mAudio_cd_wv;
97
+ QString mAudio_24x96_wv;
98
+
99
+ QString mAudio_cd_tta;
100
+ QString mAudio_24x96_tta;
101
+
102
const QString mTmpDir;
103
const QString mDataDir;
104
Disk *mStandardDisk;
105
+
106
+ static int mTestNum;
107
};
108
109
+
110
+
111
QStringList &operator<<(QStringList &list, int value);
112
113
+
114
#endif // TEST_FLACON_H
115
flacon-3.1.1.tar.gz/tests/tools.cpp
Added
357
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#include "tools.h"
29
+
30
+#include <QTest>
31
+#include <QDir>
32
+#include <QFile>
33
+#include <QTextStream>
34
+#include <QProcess>
35
+#include <QCryptographicHash>
36
+#include <QIODevice>
37
+#include <QDebug>
38
+#include "../settings.h"
39
+#include "../cue.h"
40
+#include "../disk.h"
41
+
42
+
43
+/************************************************
44
+ *
45
+ ************************************************/
46
+QString calcAudioHash(const QString &fileName)
47
+{
48
+ QFile f(fileName);
49
+ f.open(QFile::ReadOnly);
50
+ QByteArray ba = f.read(1024);
51
+ int n = ba.indexOf("data");
52
+ f.seek(n + 8);
53
+
54
+ QCryptographicHash hash(QCryptographicHash::Md5);
55
+ while (!f.atEnd())
56
+ {
57
+ ba = f.read(1024 * 1024);
58
+ hash.addData(ba);
59
+ }
60
+
61
+ return hash.result().toHex();
62
+}
63
+
64
+
65
+/************************************************
66
+ *
67
+ ************************************************/
68
+TestCueFile::TestCueFile(const QString &fileName):
69
+ mFileName(fileName)
70
+{
71
+}
72
+
73
+
74
+/************************************************
75
+ *
76
+ ************************************************/
77
+void TestCueFile::setWavFile(const QString &value)
78
+{
79
+ mWavFile = value;
80
+}
81
+
82
+
83
+/************************************************
84
+ *
85
+ ************************************************/
86
+void TestCueFile::addTrack(const QString &index0, const QString &index1)
87
+{
88
+ mTracks << TestCueTrack(index0, index1);
89
+}
90
+
91
+
92
+/************************************************
93
+ *
94
+ ************************************************/
95
+void TestCueFile::addTrack(const QString &index1)
96
+{
97
+ addTrack("", index1);
98
+}
99
+
100
+
101
+/************************************************
102
+ *
103
+ ************************************************/
104
+void TestCueFile::write()
105
+{
106
+ QFile f(mFileName);
107
+ if (!f.open(QFile::WriteOnly | QFile::Truncate))
108
+ QFAIL(QString("Can't create cue file '%1': %2").arg(mFileName).arg(f.errorString()).toLocal8Bit());
109
+
110
+ QTextStream cue(&f);
111
+
112
+ cue << QString("FILE \"%1\" WAVE\n").arg(mWavFile);
113
+ for (int i=0; i < mTracks.count(); ++i)
114
+ {
115
+ TestCueTrack track = mTracks.at(i);
116
+
117
+ cue << QString("\nTRACK %1 AUDIO\n").arg(i + 1);
118
+ if (track.index0 != "")
119
+ cue << QString(" INDEX 00 %1\n").arg(track.index0);
120
+
121
+ if (track.index1 != "")
122
+ cue << QString(" INDEX 01 %1\n").arg(track.index1);
123
+ }
124
+
125
+ f.close();
126
+}
127
+
128
+
129
+/************************************************
130
+ *
131
+ ************************************************/
132
+QStringList shnSplit(const QString &cueFile, const QString &audioFile)
133
+{
134
+ QString dir = QFileInfo(cueFile).absoluteDir().absolutePath();
135
+ foreach (QFileInfo file, QDir(dir).entryInfoList(QStringList() << "*-shntool.wav"))
136
+ {
137
+ QFile::remove(file.absoluteFilePath());
138
+ }
139
+
140
+ QStringList args;
141
+ args << "split";
142
+ args << "-w";
143
+ args << "-q";
144
+ args << "-O" << "always";
145
+ args << "-n" << "%03d";
146
+ args << "-t" << "%n-shntool";
147
+ args << "-d" << dir;
148
+ args << "-f" << QDir::toNativeSeparators(cueFile);
149
+ args << QDir::toNativeSeparators(audioFile);
150
+ //qDebug() << args;
151
+
152
+ QProcess proc;
153
+
154
+ if (proc.execute("shntool", args) != 0)
155
+ {
156
+
157
+ FAIL("snhtool was crashed: " + proc.readAllStandardError());
158
+ }
159
+
160
+ QStringList res;
161
+ foreach (QFileInfo file, QDir(dir).entryInfoList(QStringList() << "*-shntool.wav"))
162
+ {
163
+ if (!file.absoluteFilePath().endsWith("000-shntool.wav"))
164
+ res << file.absoluteFilePath();
165
+ }
166
+
167
+ return res;
168
+}
169
+
170
+
171
+/************************************************
172
+ *
173
+ ************************************************/
174
+void compareAudioHash(const QString &file1, const QString &expected)
175
+{
176
+ if (calcAudioHash(file1) != expected)
177
+ {
178
+ QFAIL(QString("Compared hases are not the same for:\n"
179
+ " [%1] %2\n"
180
+ " [%3] %4\n")
181
+
182
+ .arg(calcAudioHash(file1))
183
+ .arg(file1)
184
+
185
+ .arg(expected)
186
+ .arg("expected")
187
+
188
+ .toLocal8Bit());
189
+ }
190
+ //QCOMPARE(calcAudioHash(file1), calcAudioHash(file2));
191
+}
192
+
193
+
194
+/************************************************
195
+ *
196
+ ************************************************/
197
+void writeHexString(const QString &str, QIODevice *out)
198
+{
199
+ bool ok;
200
+ int i =0;
201
+ while (i<str.length()-1)
202
+ {
203
+ if (str.at(i).isSpace())
204
+ {
205
+ ++i;
206
+ continue;
207
+ }
208
+
209
+ union {
210
+ quint16 n16;
211
+ char b;
212
+ };
213
+ n16 = str.mid(i, 2).toShort(&ok, 16);
214
+
215
+ out->write(&b, 1);
216
+ if (!ok)
217
+ throw QString("Incorrect HEX data at %1:\n%2").arg(i).arg(str);
218
+ i+=2;
219
+ }
220
+}
221
+
222
+/************************************************
223
+ *
224
+ ************************************************/
225
+void createWavFile(const QString &fileName, int duration, StdWavHeader::Quality quality)
226
+{
227
+ if (QFileInfo(fileName).exists())
228
+ return;
229
+
230
+ QFile file(fileName);
231
+ if (!file.open(QFile::WriteOnly | QFile::Truncate))
232
+ QFAIL(QString("Can't create file '%1': %2").arg(fileName, file.errorString()).toLocal8Bit());
233
+
234
+
235
+ int dataSize = StdWavHeader::bytesPerSecond(quality) * duration;
236
+ file.write(StdWavHeader(dataSize, quality).toByteArray());
237
+
238
+ quint32 x=123456789, y=362436069, z=521288629;
239
+ union {
240
+ quint32 t;
241
+ char bytes[4];
242
+ };
243
+
244
+ for (uint i=0; i<(dataSize/ sizeof(quint32)); ++i)
245
+ {
246
+ // xorshf96 ...................
247
+ x ^= x << 16;
248
+ x ^= x >> 5;
249
+ x ^= x << 1;
250
+
251
+ t = x;
252
+ x = y;
253
+ y = z;
254
+ z = t ^ x ^ y;
255
+ // xorshf96 ...................
256
+
257
+ file.write(bytes, 4);
258
+ }
259
+
260
+ file.close();
261
+}
262
+
263
+
264
+/************************************************
265
+ *
266
+ ************************************************/
267
+void encodeAudioFile(const QString &wavFileName, const QString &outFileName)
268
+{
269
+ if (QFileInfo(outFileName).exists())
270
+ return;
271
+
272
+ QString program;
273
+ QStringList args;
274
+
275
+ QString ext = QFileInfo(outFileName).suffix();
276
+
277
+ if(ext == "ape")
278
+ {
279
+ program = "mac";
280
+ args << wavFileName;
281
+ args << outFileName;
282
+ args << "-c2000";
283
+
284
+ }
285
+
286
+ else if(ext == "flac")
287
+ {
288
+ program = "flac";
289
+ args << "--silent";
290
+ args << "--force";
291
+ args << "-o" << outFileName;
292
+ args << wavFileName;
293
+ }
294
+
295
+ else if(ext == "wv")
296
+ {
297
+ program = "wavpack";
298
+ args << wavFileName;
299
+ args << "-y";
300
+ args << "-q";
301
+ args << "-o" << outFileName;
302
+ }
303
+
304
+ else if(ext == "tta")
305
+ {
306
+ program = "ttaenc";
307
+ args << "-o" << outFileName;
308
+ args << "-e";
309
+ args << wavFileName;
310
+ args << "/";
311
+ }
312
+
313
+ else
314
+ {
315
+ QFAIL(QString("Can't create file '%1': unknown file format").arg(outFileName).toLocal8Bit());
316
+ }
317
+
318
+#if 1
319
+ QProcess proc;
320
+ proc.start(program, args);
321
+ proc.waitForFinished(3 * 60 * 10000);
322
+ if (proc.exitStatus() != 0)
323
+ QFAIL(QString("Can't encode to file '%1':").arg(outFileName).toLocal8Bit() + proc.readAllStandardError());
324
+#else
325
+ QProcess proc;
326
+ if (proc.execute(program, args) != 0)
327
+ QFAIL(QString("Can't encode to file '%1':").arg(outFileName).toLocal8Bit() + proc.readAllStandardError());
328
+#endif
329
+
330
+ if (!QFileInfo(outFileName).isFile())
331
+ QFAIL(QString("Can't encode to file '%1' (file don't exists'):").arg(outFileName).toLocal8Bit() + proc.readAllStandardError());
332
+}
333
+
334
+
335
+/************************************************
336
+ *
337
+ ************************************************/
338
+void testFail(const QString &message, const char *file, int line)
339
+{
340
+ QTest::qFail(message.toLocal8Bit().data(), file, line);
341
+}
342
+
343
+
344
+/************************************************
345
+ *
346
+ ************************************************/
347
+Disk *loadFromCue(const QString &cueFile)
348
+{
349
+ CueReader cueReader(cueFile);
350
+ if (!cueReader.isValid())
351
+ FAIL(cueReader.errorString().toLocal8Bit());
352
+
353
+ Disk *res = new Disk();
354
+ res->loadFromCue(cueReader.disk(0));
355
+ return res;
356
+}
357
flacon-3.1.1.tar.gz/tests/tools.h
Added
105
1
2
+/* BEGIN_COMMON_COPYRIGHT_HEADER
3
+ * (c)LGPL2+
4
+ *
5
+ * Flacon - audio File Encoder
6
+ * https://github.com/flacon/flacon
7
+ *
8
+ * Copyright: 2017
9
+ * Alexander Sokoloff <sokoloff.a@gmail.com>
10
+ *
11
+ * This library is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+
16
+ * This library is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ * Lesser General Public License for more details.
20
+
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with this library; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * END_COMMON_COPYRIGHT_HEADER */
26
+
27
+
28
+#ifndef TOOLS_H
29
+#define TOOLS_H
30
+
31
+#include <QString>
32
+#include <QStringList>
33
+#include <QVector>
34
+#include "wavheader.h"
35
+
36
+class QIODevice;
37
+class Disk;
38
+
39
+
40
+class TestCueFile
41
+{
42
+public:
43
+ explicit TestCueFile(const QString &fileName);
44
+
45
+ QString fileName() const { return mFileName; }
46
+
47
+ void setWavFile(const QString &value);
48
+ QString wavFile() const { return mWavFile; }
49
+
50
+ void addTrack(const QString &index0, const QString &index1);
51
+ void addTrack(const QString &index1);
52
+
53
+ void write();
54
+
55
+private:
56
+ struct TestCueTrack {
57
+ QString index0;
58
+ QString index1;
59
+
60
+ TestCueTrack():
61
+ index0(""),
62
+ index1("")
63
+ {
64
+ }
65
+
66
+
67
+ TestCueTrack(const QString &index1):
68
+ index0(""),
69
+ index1(index1)
70
+ {
71
+ }
72
+
73
+
74
+ TestCueTrack(const QString &index0, const QString &index1):
75
+ index0(index0),
76
+ index1(index1)
77
+ {
78
+ }
79
+
80
+
81
+ };
82
+
83
+ QString mFileName;
84
+ QString mWavFile;
85
+ QVector<TestCueTrack> mTracks;
86
+};
87
+
88
+
89
+QStringList shnSplit(const QString &cueFile, const QString &audioFile);
90
+QString calcAudioHash(const QString &fileName);
91
+void compareAudioHash(const QString &file1, const QString &expected);
92
+void writeHexString(const QString &str, QIODevice *out);
93
+void createWavFile(const QString &fileName, int duration, StdWavHeader::Quality quality);
94
+void encodeAudioFile(const QString &wavFileName, const QString &outFileName);
95
+void testFail(const QString &message, const char *file, int line);
96
+
97
+#define FAIL(message) \
98
+do {\
99
+ testFail(message, __FILE__, __LINE__); \
100
+} while (0)
101
+
102
+Disk *loadFromCue(const QString &cueFile);
103
+
104
+#endif // TOOLS_H
105
flacon-2.1.1.tar.gz/tools.cmake -> flacon-3.1.1.tar.gz/tools.cmake
Changed
17
1
2
endif()
3
add_definitions(-D${VAR_NAME}=\"${VAR_VALUE}\")
4
endmacro()
5
+
6
+
7
+macro(addTests TESTS_DIR)
8
+ option(BUILD_TESTS "Build tests." $ENV{BUILD_TESTS})
9
+
10
+ if(BUILD_TESTS)
11
+ add_definitions(-DBUILD_TESTS)
12
+ add_subdirectory(${TESTS_DIR})
13
+ else()
14
+ status_message("For building tests use -DBUILD_TESTS=Yes option.")
15
+ endif()
16
+endmacro()
17
flacon-2.1.1.tar.gz/translations/flacon_cs.ts -> flacon-3.1.1.tar.gz/translations/flacon_cs.ts
Changed
10
1
2
</message>
3
<message>
4
<source>Delete current pattern from history</source>
5
- <translation type="unfinished"/>
6
+ <translation>Smazat nynější vzor z historie</translation>
7
</message>
8
</context>
9
<context>
10
flacon-2.1.1.tar.gz/translations/flacon_de.ts -> flacon-3.1.1.tar.gz/translations/flacon_de.ts
Changed
222
1
2
</message>
3
<message>
4
<source>Extracts individual tracks from one big audio file containing the entire album.</source>
5
- <translation type="unfinished"/>
6
+ <translation>Einzelne Audiodateien aus einer großen Audiodatei extrahieren die ein ganzes Album enthält.</translation>
7
</message>
8
<message>
9
<source>Copyright: %1-%2 %3</source>
10
11
<message>
12
<source>Bug tracker %1</source>
13
<comment>About dialog, About tab</comment>
14
- <translation type="unfinished"/>
15
+ <translation>Bug Tracker %1</translation>
16
</message>
17
<message>
18
<source>Flacon is translated into many languages thanks to the work of the Flacon translation teams on <a href='%1'>Transifex</a>.</source>
19
- <translation type="unfinished"/>
20
+ <translation>Flacon wird dank der Hilfe der Flacon Übersetzer Teams auf <a href='%1'>Transifex</a> in viele Sprachen übersetzt.</translation>
21
</message>
22
</context>
23
<context>
24
25
</message>
26
<message>
27
<source>Per track cue sheet</source>
28
- <translation type="unfinished"/>
29
+ <translation>Cue-Datei pro Stück</translation>
30
</message>
31
<message>
32
<source>Create per track cue sheet</source>
33
- <translation type="unfinished"/>
34
+ <translation>Cue-Datei pro Stück erstellen</translation>
35
</message>
36
</context>
37
<context>
38
39
<p>
40
In CBR mode, it sets the specific output bitrate.
41
</source>
42
- <translation type="unfinished"/>
43
+ <translation>Legt die Ziel Bitrate in kb/s (6-256 pro Audikanal) fest.
44
+<p>
45
+Im VBR Modus bestimmt diese die durchschnittliche Bitrate für eine große und weitläufige Audiosammlung.
46
+<p>
47
+Im CBR Modus bestimmt diese die tatsächliche Bitrate.
48
+</translation>
49
</message>
50
</context>
51
<context>
52
53
</message>
54
<message>
55
<source>The cue file contains information about multiple disks. Which disk you want to use?</source>
56
- <translation type="unfinished"/>
57
+ <translation>Das Cue Sheet enthält Informationen über mehrere Disks. Welche Disk soll verwendet werden?</translation>
58
</message>
59
</context>
60
<context>
61
62
</message>
63
<message>
64
<source>Cue file not set.</source>
65
- <translation type="unfinished"/>
66
+ <translation>Kein Cue Sheet ausgewählt. </translation>
67
</message>
68
<message>
69
<source>Audio file shorter than expected from cue sheet.</source>
70
- <translation type="unfinished"/>
71
+ <translation>Audio Datei ist kürzer als im Cue Sheet angegeben.</translation>
72
</message>
73
</context>
74
<context>
75
76
<message>
77
<source>I can't read %1 file</source>
78
<comment>Encoder error. %1 is a file name.</comment>
79
- <translation type="unfinished"/>
80
+ <translation>Ich kann die Datei %1 nicht lesen</translation>
81
</message>
82
</context>
83
<context>
84
85
<message>
86
<source>Sets compression level, between %1 (fastest) and %2 (highest compression).
87
This only affects the file size. All settings are lossless.</source>
88
- <translation type="unfinished"/>
89
+ <translation>Kompressionsstärke angeben, zwischen %1 (am schnellsten) und %2 (höchste Kompression).
90
+Diese Einstellung wirkt sich nur auf die Dateigröße aus. Alle Einstellungen sind verlustfrei.</translation>
91
</message>
92
<message>
93
<source>Disabled</source>
94
95
96
The analysis can be performed on individual tracks, so that all tracks will be of equal volume on playback.
97
Using the album-gain analysis will preserve the volume differences within an album.</source>
98
- <translation type="unfinished"/>
99
+ <translation>ReplayGain ist ein Standard zur Anpassung der gehörten Lautstärke bei Computer Audioformaten.
100
+
101
+Die Analyse kann bei einzelnen Audiodateien durchgeführt werden, so dass diese anschließend mit gleicher Lautstärke wiedergegeben werden.
102
+Die Album-Gain Analyse behält die Lautstärkeunterschiede innerhalb eines Albums dabei bei.</translation>
103
</message>
104
<message>
105
<source>%1 kbps</source>
106
107
108
If the path is left empty or starts with "." (dot), the result files will be placed in the same directory as the source.</source>
109
<comment>Main form tooltip for "Directory" edit</comment>
110
- <translation type="unfinished"/>
111
+ <translation>Sie können das Zielverzeichnis auswählen. Sie können das Zielverzeichnis auch manuell angeben.
112
+
113
+Wird kein Zielverzeichnis angegeben oder beginnt es mit "." (Punkt), werden die erzeugten Dateien im Quellverzeichnis gespeichert.</translation>
114
</message>
115
<message>
116
<source>Use "%1"</source>
117
118
<message>
119
<source>Select cue file</source>
120
<comment>OpenFile dialog title</comment>
121
- <translation type="unfinished"/>
122
+ <translation>Cue Sheet auswählen</translation>
123
</message>
124
<message>
125
<source>Add cue or audio file</source>
126
<comment>OpenFile dialog title</comment>
127
- <translation type="unfinished"/>
128
+ <translation>Cue- oder Audiodatei hinzufügen</translation>
129
</message>
130
<message>
131
<source>Delete current pattern from history</source>
132
133
<message>
134
<source>%1 program</source>
135
<comment>This is part of filter for 'select program' dialog. %1 is a name of required program. Example: 'shntool program (shntool)'</comment>
136
- <translation type="unfinished"/>
137
+ <translation>%1 Programm</translation>
138
</message>
139
<message>
140
<source>All files</source>
141
<comment>This is part of filter for 'select program' dialog. 'All files (*)'</comment>
142
- <translation type="unfinished"/>
143
+ <translation>Alle Dateien</translation>
144
</message>
145
</context>
146
<context>
147
148
</message>
149
<message>
150
<source>File <b>%1</b> is not a supported audio file. <br><br>Verify that all required programs are installed and in your preferences.</source>
151
- <translation type="unfinished"/>
152
+ <translation>Datei <b>%1</b> ist keine unterstützte Audiodatei. <br><br> überprüfen Sie, dass alle benötigten Programme installiert und konfiguriert sind.</translation>
153
</message>
154
<message>
155
<source> [disk %1]</source>
156
157
</message>
158
<message>
159
<source>I can't write cue file <b>%1</b>:<br>%2</source>
160
- <translation type="unfinished"/>
161
+ <translation>Ich kann die Cue-Datei <b>%1</b>:<br>%2 nicht schreiben</translation>
162
</message>
163
<message>
164
<source>File <b>"%1"</b> does not exist</source>
165
- <translation type="unfinished"/>
166
+ <translation>Datei <b>"%1"</b> ist nicht vorhanden</translation>
167
</message>
168
<message>
169
<source><b>%1</b> is not a valid cue file. Disk %2 has no tags.</source>
170
- <translation type="unfinished"/>
171
+ <translation><b>%1</b> ist keine gültige Cue-Datei. Disk %2 hat keine Tags.</translation>
172
</message>
173
<message>
174
<source>The audio file name is not set</source>
175
- <translation type="unfinished"/>
176
+ <translation>Audiodateiname ist nicht festgelegt</translation>
177
</message>
178
<message>
179
<source>you can't use 'ReplayGain' for files with sample rates above 48kHz. Metaflac doesn't support such files.</source>
180
<comment>This string should begin with a lowercase letter. This is a part of the complex sentence.</comment>
181
- <translation type="unfinished"/>
182
+ <translation>'ReplayGain' kann für Dateien mit einer Samplerate über 48kHz nicht verwendet werden, da Metaflac diese Dateien nicht unterstützt.</translation>
183
</message>
184
<message>
185
<source><b>%1</b> is not a valid cue file. The cue sheet has no FILE tag.</source>
186
- <translation type="unfinished"/>
187
+ <translation><b>%1</b> ist keine gültige Cue-Datei. Die Cue-Datei hat keinen FILE Tag.</translation>
188
</message>
189
<message>
190
<source><b>%1</b> is not a valid cue file. Incorrect track index at %2.</source>
191
<comment>Cue parser error. %2 is file position</comment>
192
- <translation type="unfinished"/>
193
+ <translation><b>%1</b> ist keine gültige Cue-Datei. Falscher Track-Index bei %2.</translation>
194
</message>
195
<message>
196
<source>The audio file <b>"%1"</b> does not exist</source>
197
- <translation type="unfinished"/>
198
+ <translation>Audiodatei <b>"%1"</b> ist nicht vorhanden</translation>
199
</message>
200
</context>
201
<context>
202
203
</message>
204
<message>
205
<source>Select another cue file</source>
206
- <translation type="unfinished"/>
207
+ <translation>Wählen Sie eine andere Cue-Datei aus</translation>
208
</message>
209
</context>
210
<context>
211
212
<message>
213
<source>The conversion is not possible.
214
%1</source>
215
- <translation type="unfinished"/>
216
+ <translation>Die Konvertierung ist nicht möglich.
217
+%1</translation>
218
</message>
219
</context>
220
</TS>
221
\ No newline at end of file
222
flacon-2.1.1.tar.gz/translations/flacon_fr.ts -> flacon-3.1.1.tar.gz/translations/flacon_fr.ts
Changed
24
1
2
</message>
3
<message>
4
<source>Start num:</source>
5
- <translation>Numéro de début :</translation>
6
+ <translation>Premier numéro :</translation>
7
</message>
8
<message>
9
<source>Disc ID:</source>
10
11
</message>
12
<message>
13
<source>Remove album</source>
14
- <translation>Retirer l'album</translation>
15
+ <translation>Enlever l'album</translation>
16
</message>
17
<message>
18
<source>Remove album from project</source>
19
- <translation>Retirer l'album du projet</translation>
20
+ <translation>Enlever l'album du projet</translation>
21
</message>
22
<message>
23
<source>Ctrl+Del</source>
24
flacon-2.1.1.tar.gz/translations/flacon_hu.desktop -> flacon-3.1.1.tar.gz/translations/flacon_hu.desktop
Changed
8
1
2
3
# Translations
4
Icon[hu]=flacon
5
+Comment[hu]=Kibontja egy CD-képfájlból az audio-sávokat különálló sávokra
6
GenericName[hu]=Audio-fájl átalakító
7
Name[hu]=Flacon
8
flacon-2.1.1.tar.gz/translations/flacon_hu.ts -> flacon-3.1.1.tar.gz/translations/flacon_hu.ts
Changed
1345
1
2
<name>AboutDialog</name>
3
<message>
4
<source>About Flacon</source>
5
- <translation type="unfinished"/>
6
+ <translation>Flacon névjegye</translation>
7
</message>
8
<message>
9
<source>About</source>
10
- <translation type="unfinished"/>
11
+ <translation>About</translation>
12
</message>
13
<message>
14
<source>Author</source>
15
- <translation type="unfinished"/>
16
+ <translation>Szerző</translation>
17
</message>
18
<message>
19
<source>Thanks</source>
20
- <translation type="unfinished"/>
21
+ <translation>Köszönet</translation>
22
</message>
23
<message>
24
<source>Translations</source>
25
- <translation type="unfinished"/>
26
+ <translation>Fordítások</translation>
27
</message>
28
<message>
29
<source>External programs</source>
30
- <translation type="unfinished"/>
31
+ <translation>Külső alkalmazások</translation>
32
</message>
33
<message>
34
<source>Homepage: %1</source>
35
- <translation type="unfinished"/>
36
+ <translation>Honlap: %1</translation>
37
</message>
38
<message>
39
<source>License: %1</source>
40
- <translation type="unfinished"/>
41
+ <translation>Licenc: %1</translation>
42
</message>
43
<message>
44
<source>Special thanks to:</source>
45
- <translation type="unfinished"/>
46
+ <translation>Különleges köszönet neki(k):</translation>
47
</message>
48
<message>
49
<source>Flacon uses external programs. Many thanks to their authors!</source>
50
- <translation type="unfinished"/>
51
+ <translation>A Flacon külső programokat használ. Ezer köszönet a szerzőknek!</translation>
52
</message>
53
<message>
54
<source>Extracts individual tracks from one big audio file containing the entire album.</source>
55
56
</message>
57
<message>
58
<source>Copyright: %1-%2 %3</source>
59
- <translation type="unfinished"/>
60
+ <translation>%1 %2 használata - Copyright (C) %3</translation>
61
</message>
62
<message>
63
<source>WavPack support patch</source>
64
- <translation type="unfinished"/>
65
+ <translation>Wavpack támogató patch</translation>
66
</message>
67
<message>
68
<source>Application icon, Packaging</source>
69
- <translation type="unfinished"/>
70
+ <translation>Alkalmazás ikon, Csomagolás</translation>
71
</message>
72
<message>
73
<source>Packaging, testing</source>
74
- <translation type="unfinished"/>
75
+ <translation>Csomagolás, tesztelés</translation>
76
</message>
77
<message>
78
<source>Improvements in the UI</source>
79
- <translation type="unfinished"/>
80
- </message>
81
- <message>
82
- <source>Flacon is translated into many languages thanks to the work of the translation teams all over the world.</source>
83
- <translation type="unfinished"/>
84
+ <translation>Felületi fejlesztések</translation>
85
</message>
86
<message>
87
<source>Flacon account on github.com</source>
88
- <translation type="unfinished"/>
89
+ <translation>Flacon fiók a github.com-on</translation>
90
</message>
91
<message>
92
<source>Bug tracker %1</source>
93
<comment>About dialog, About tab</comment>
94
+ <translation>Hibakövetés %1</translation>
95
+ </message>
96
+ <message>
97
+ <source>Flacon is translated into many languages thanks to the work of the Flacon translation teams on <a href='%1'>Transifex</a>.</source>
98
<translation type="unfinished"/>
99
</message>
100
</context>
101
102
<message>
103
<source>Auto detect</source>
104
<comment>Codepage auto detection</comment>
105
- <translation type="unfinished"/>
106
+ <translation>Automatikus detektálás</translation>
107
</message>
108
<message>
109
<source>Unicode (UTF-8)</source>
110
- <translation type="unfinished"/>
111
+ <translation>Unicode (UTF-8)</translation>
112
</message>
113
<message>
114
<source>Unicode (UTF-16LE)</source>
115
- <translation type="unfinished"/>
116
+ <translation>Unicode (UTF-16LE)</translation>
117
</message>
118
<message>
119
<source>Unicode (UTF-16BE)</source>
120
- <translation type="unfinished"/>
121
+ <translation>Unicode (UTF-16BE)</translation>
122
</message>
123
<message>
124
<source>Cyrillic (Win-1251)</source>
125
- <translation type="unfinished"/>
126
+ <translation>Cyrillic (Win-1251)</translation>
127
</message>
128
<message>
129
<source>Cyrillic (CP-866)</source>
130
- <translation type="unfinished"/>
131
+ <translation>Cyrillic (CP-866)</translation>
132
</message>
133
<message>
134
<source>Latin-1 (ISO-8859-1)</source>
135
- <translation type="unfinished"/>
136
+ <translation>Latin-1 (ISO-8859-1)</translation>
137
</message>
138
<message>
139
<source>Latin-2 (ISO-8859-2)</source>
140
- <translation type="unfinished"/>
141
+ <translation>Latin-2 (ISO-8859-2)</translation>
142
</message>
143
<message>
144
<source>Latin-3 (ISO-8859-3)</source>
145
- <translation type="unfinished"/>
146
+ <translation>Latin-3 (ISO-8859-3)</translation>
147
</message>
148
<message>
149
<source>Latin-4 (ISO-8859-4)</source>
150
- <translation type="unfinished"/>
151
+ <translation>Latin-4 (ISO-8859-4)</translation>
152
</message>
153
<message>
154
<source>Latin-5 (ISO-8859-5)</source>
155
- <translation type="unfinished"/>
156
+ <translation>Latin-5 (ISO-8859-5)</translation>
157
</message>
158
<message>
159
<source>Latin-6 (ISO-8859-6)</source>
160
- <translation type="unfinished"/>
161
+ <translation>Latin-6 (ISO-8859-6)</translation>
162
</message>
163
<message>
164
<source>Latin-7 (ISO-8859-7)</source>
165
- <translation type="unfinished"/>
166
+ <translation>Latin-7 (ISO-8859-7)</translation>
167
</message>
168
<message>
169
<source>Latin-8 (ISO-8859-8)</source>
170
- <translation type="unfinished"/>
171
+ <translation>Latin-8 (ISO-8859-8)</translation>
172
</message>
173
<message>
174
<source>Latin-9 (ISO-8859-9)</source>
175
- <translation type="unfinished"/>
176
+ <translation>Latin-9 (ISO-8859-9)</translation>
177
</message>
178
<message>
179
<source>Latin-10 (ISO-8859-10)</source>
180
- <translation type="unfinished"/>
181
+ <translation>Latin-10 (ISO-8859-10)</translation>
182
</message>
183
<message>
184
<source>Latin-13 (ISO-8859-13)</source>
185
- <translation type="unfinished"/>
186
+ <translation>Latin-13 (ISO-8859-13)</translation>
187
</message>
188
<message>
189
<source>Latin-14 (ISO-8859-14)</source>
190
- <translation type="unfinished"/>
191
+ <translation>Latin-14 (ISO-8859-14)</translation>
192
</message>
193
<message>
194
<source>Latin-15 (ISO-8859-15)</source>
195
- <translation type="unfinished"/>
196
+ <translation>Latin-15 (ISO-8859-15)</translation>
197
</message>
198
<message>
199
<source>Latin-16 (ISO-8859-16)</source>
200
- <translation type="unfinished"/>
201
+ <translation>Latin-16 (ISO-8859-16)</translation>
202
+ </message>
203
+ <message>
204
+ <source>Windows 1250</source>
205
+ <translation>Windows 1250</translation>
206
+ </message>
207
+ <message>
208
+ <source>Windows 1252</source>
209
+ <translation>Windows 1252</translation>
210
+ </message>
211
+ <message>
212
+ <source>Windows 1253</source>
213
+ <translation>Windows 1253</translation>
214
+ </message>
215
+ <message>
216
+ <source>Windows 1254</source>
217
+ <translation>Windows 1254</translation>
218
+ </message>
219
+ <message>
220
+ <source>Windows 1255</source>
221
+ <translation>Windows 1255</translation>
222
+ </message>
223
+ <message>
224
+ <source>Windows 1256</source>
225
+ <translation>Windows 1256</translation>
226
+ </message>
227
+ <message>
228
+ <source>Windows 1257</source>
229
+ <translation>Windows 1257</translation>
230
+ </message>
231
+ <message>
232
+ <source>Windows 1258</source>
233
+ <translation>Windows 1258</translation>
234
</message>
235
</context>
236
<context>
237
<name>ConfigDialog</name>
238
<message>
239
<source>Preferences</source>
240
- <translation type="unfinished"/>
241
+ <translation>Beállítások</translation>
242
</message>
243
<message>
244
<source>General configuration</source>
245
- <translation type="unfinished"/>
246
+ <translation>Általános beállítások</translation>
247
</message>
248
<message>
249
<source>Thread count:</source>
250
- <translation type="unfinished"/>
251
+ <translation>Szálnak száma:</translation>
252
</message>
253
<message>
254
<source>The number of threads in the conversion process.</source>
255
- <translation type="unfinished"/>
256
+ <translation>A szálak száma a konvertálási folyamatban.</translation>
257
</message>
258
<message>
259
<source>Temporary directory:</source>
260
- <translation type="unfinished"/>
261
+ <translation>Ideiglenes könyvtár:</translation>
262
</message>
263
<message>
264
<source>Default codepage:</source>
265
- <translation type="unfinished"/>
266
- </message>
267
- <message>
268
- <source>Per track CUE</source>
269
- <translation type="unfinished"/>
270
- </message>
271
- <message>
272
- <source>Create per track CUE</source>
273
- <translation type="unfinished"/>
274
+ <translation>Alapértelmezett kódlap:</translation>
275
</message>
276
<message>
277
<source>First track pregap:</source>
278
- <translation type="unfinished"/>
279
+ <translation>Első pregap sáv:</translation>
280
</message>
281
<message>
282
<source>Rescan</source>
283
- <translation type="unfinished"/>
284
+ <translation>Frissít</translation>
285
</message>
286
<message>
287
<source>Full path of the external applications</source>
288
- <translation type="unfinished"/>
289
+ <translation>Külső alkalmazások teljes útvonala</translation>
290
</message>
291
<message>
292
<source>Extract to separate file</source>
293
- <translation type="unfinished"/>
294
+ <translation>Kibontás különálló fájlba</translation>
295
</message>
296
<message>
297
<source>Add to first track</source>
298
- <translation type="unfinished"/>
299
+ <translation>Adja az első sávhoz</translation>
300
</message>
301
<message>
302
<source>General</source>
303
- <translation type="unfinished"/>
304
+ <translation>General</translation>
305
</message>
306
<message>
307
<source>Programs</source>
308
- <translation type="unfinished"/>
309
+ <translation>Programok</translation>
310
</message>
311
<message>
312
<source>Select temporary directory</source>
313
+ <translation>Válasszon ideiglenes könyvtárt</translation>
314
+ </message>
315
+ <message>
316
+ <source>Per track cue sheet</source>
317
+ <translation type="unfinished"/>
318
+ </message>
319
+ <message>
320
+ <source>Create per track cue sheet</source>
321
<translation type="unfinished"/>
322
</message>
323
</context>
324
325
<name>ConfigPage_Aac</name>
326
<message>
327
<source>AAC encoding configuration</source>
328
- <translation type="unfinished"/>
329
+ <translation>AAC-átalakító beállítása</translation>
330
</message>
331
<message>
332
<source>Use quality setting (recommended)</source>
333
- <translation type="unfinished"/>
334
+ <translation>Használt minőség beállításai (javasolt)</translation>
335
</message>
336
<message>
337
<source>Use bitrate</source>
338
- <translation type="unfinished"/>
339
+ <translation>Használt bitráta:</translation>
340
</message>
341
<message>
342
<source>Bitrate:</source>
343
- <translation type="unfinished"/>
344
+ <translation>Bitráta:</translation>
345
</message>
346
<message>
347
<source>Sets target bitrate (in kb/s).</source>
348
- <translation type="unfinished"/>
349
+ <translation>Cél bitsebesség (bit/mp-ben)</translation>
350
</message>
351
</context>
352
<context>
353
<name>ConfigPage_Flac</name>
354
<message>
355
<source>Flac encoding configuration</source>
356
- <translation type="unfinished"/>
357
+ <translation>FLAC-átalakító beállítása</translation>
358
</message>
359
<message>
360
<source>Compression:</source>
361
- <translation type="unfinished"/>
362
+ <translation>Tömörítő:</translation>
363
</message>
364
<message>
365
<source>ReplayGain</source>
366
- <translation type="unfinished"/>
367
+ <translation>Visszajátszási erősítés</translation>
368
</message>
369
<message>
370
<source>Calculate gain:</source>
371
- <translation type="unfinished"/>
372
+ <translation>Erősítés számolása:</translation>
373
</message>
374
<message>
375
<source>Disabled</source>
376
- <translation type="unfinished"/>
377
+ <translation>Letiltva</translation>
378
</message>
379
</context>
380
<context>
381
<name>ConfigPage_Mp3</name>
382
<message>
383
<source>MP3 encoding configuration</source>
384
- <translation type="unfinished"/>
385
+ <translation>MP3-átalakító beállítása</translation>
386
</message>
387
<message>
388
<source>Preset:</source>
389
- <translation type="unfinished"/>
390
+ <translation>Bitzosított:</translation>
391
</message>
392
<message>
393
<source><dt>VBR medium</dt>
394
395
</message>
396
<message>
397
<source>Use bitrate</source>
398
- <translation type="unfinished"/>
399
+ <translation>Használt bitráta</translation>
400
</message>
401
<message>
402
<source>Bitrate:</source>
403
- <translation type="unfinished"/>
404
+ <translation>Bitráta:</translation>
405
</message>
406
<message>
407
<source>Sets target bitrate (in kb/s).</source>
408
- <translation type="unfinished"/>
409
+ <translation>Cél bitsebesség (bit/mp-ben)</translation>
410
</message>
411
<message>
412
<source>Use quality</source>
413
- <translation type="unfinished"/>
414
+ <translation>Használt minőség</translation>
415
</message>
416
<message>
417
<source>Quality:</source>
418
- <translation type="unfinished"/>
419
+ <translation>Minőség:</translation>
420
</message>
421
<message>
422
<source>ReplayGain</source>
423
- <translation type="unfinished"/>
424
+ <translation>Visszajátszási erősítés</translation>
425
</message>
426
<message>
427
<source>Calculate gain:</source>
428
- <translation type="unfinished"/>
429
+ <translation>Erősítés számolása:</translation>
430
</message>
431
<message>
432
<source>VBR medium</source>
433
- <translation type="unfinished"/>
434
+ <translation>Közepes VBR</translation>
435
</message>
436
<message>
437
<source>VBR standard</source>
438
- <translation type="unfinished"/>
439
+ <translation>Általános VBR</translation>
440
</message>
441
<message>
442
<source>VBR standard fast</source>
443
- <translation type="unfinished"/>
444
+ <translation>Általános gyors VBR</translation>
445
</message>
446
<message>
447
<source>VBR extreme</source>
448
- <translation type="unfinished"/>
449
+ <translation>Extrém VBR</translation>
450
</message>
451
<message>
452
<source>VBR extreme fast</source>
453
- <translation type="unfinished"/>
454
+ <translation>Extrém gyors VBR</translation>
455
</message>
456
<message>
457
<source>VBR quality</source>
458
- <translation type="unfinished"/>
459
+ <translation>VBR minőség</translation>
460
</message>
461
<message>
462
<source>CBR insane</source>
463
- <translation type="unfinished"/>
464
+ <translation>Őrült CBR</translation>
465
</message>
466
<message>
467
<source>CBR kbps</source>
468
- <translation type="unfinished"/>
469
+ <translation>CBR kbps</translation>
470
</message>
471
<message>
472
<source>ABR kbps</source>
473
- <translation type="unfinished"/>
474
+ <translation>ABR kbps</translation>
475
</message>
476
</context>
477
<context>
478
<name>ConfigPage_Ogg</name>
479
<message>
480
<source>Ogg encoding configuration</source>
481
- <translation type="unfinished"/>
482
+ <translation>Ogg-átalakító beállítása</translation>
483
</message>
484
<message>
485
<source>Use quality setting (recommended)</source>
486
- <translation type="unfinished"/>
487
+ <translation>Használt minőség beállításai (javasolt)</translation>
488
</message>
489
<message>
490
<source>Use bitrate</source>
491
- <translation type="unfinished"/>
492
+ <translation>Használt bitráta</translation>
493
</message>
494
<message>
495
<source>Minimal bitrate:</source>
496
- <translation type="unfinished"/>
497
+ <translation>Minimális bitráta:</translation>
498
</message>
499
<message>
500
<source>Sets minimum bitrate (in kb/s).</source>
501
- <translation type="unfinished"/>
502
+ <translation>Minimális bitsebesség (bit/mp-ben)</translation>
503
</message>
504
<message>
505
<source>Nominal bitrate:</source>
506
- <translation type="unfinished"/>
507
+ <translation>Nominális bitráta</translation>
508
</message>
509
<message>
510
<source>Sets target bitrate (in kb/s).</source>
511
- <translation type="unfinished"/>
512
+ <translation>Cél bitsebesség (bit/mp-ben)</translation>
513
</message>
514
<message>
515
<source>Maximum bitrate:</source>
516
- <translation type="unfinished"/>
517
+ <translation>Maximális bitráta:</translation>
518
</message>
519
<message>
520
<source>Sets maximum bitrate (in kb/s).</source>
521
- <translation type="unfinished"/>
522
+ <translation>Minimális cél bitsebesség (bit/mp-ben)</translation>
523
</message>
524
<message>
525
<source>ReplayGain</source>
526
- <translation type="unfinished"/>
527
+ <translation>Visszajátszási erősítés</translation>
528
</message>
529
<message>
530
<source>Calculate gain:</source>
531
+ <translation>Erősítés számolása:</translation>
532
+ </message>
533
+</context>
534
+<context>
535
+ <name>ConfigPage_Opus</name>
536
+ <message>
537
+ <source>Opus encoding configuration</source>
538
+ <translation>Opus kódoló beállítása</translation>
539
+ </message>
540
+ <message>
541
+ <source>Bitrate type:</source>
542
+ <translation>Bitráta típusa:</translation>
543
+ </message>
544
+ <message>
545
+ <source>Bitrate:</source>
546
+ <translation>Bitráta:</translation>
547
+ </message>
548
+ <message>
549
+ <source>VBR - variable bitrate</source>
550
+ <translation>VBR - változó bitráta</translation>
551
+ </message>
552
+ <message>
553
+ <source>CBR - constrained bitrate</source>
554
+ <translation>CBR - korlátozott bitráta</translation>
555
+ </message>
556
+ <message>
557
+ <source><dt>VBR</dt>
558
+<dd>Use variable bitrate encoding (recommended). In VBR mode, the bitrate may go up and down freely depending on the content ensure quality consistency.</dd>
559
+
560
+<dt>CBR</dt>
561
+<dd>Use constrained variable bitrate encoding. Outputs to a specific bitrate. This mode is analogous to CBR in AAC/MP3 encoders and managed mode in vorbis coders. This delivers less consistent quality than VBR mode but consistent bitrate.</dd></source>
562
+ <translation type="unfinished"/>
563
+ </message>
564
+ <message>
565
+ <source>Sets the target bitrate in kb/s (6-256 per channel).
566
+<p>
567
+In VBR mode, this sets the average rate for a large and diverse collection of audio.
568
+<p>
569
+In CBR mode, it sets the specific output bitrate.
570
+</source>
571
<translation type="unfinished"/>
572
</message>
573
</context>
574
575
<name>ConfigPage_Wv</name>
576
<message>
577
<source>WavPack encoding configuration</source>
578
- <translation type="unfinished"/>
579
+ <translation>WavPack-átalakító beállítása</translation>
580
</message>
581
<message>
582
<source>Compression:</source>
583
- <translation type="unfinished"/>
584
+ <translation>Tömörítő:</translation>
585
</message>
586
<message>
587
<source>ReplayGain</source>
588
- <translation type="unfinished"/>
589
+ <translation>Visszajátszási erősítés</translation>
590
</message>
591
<message>
592
<source>Calculate gain:</source>
593
- <translation type="unfinished"/>
594
+ <translation>Erősítés számolása:</translation>
595
</message>
596
<message>
597
<source>Disabled</source>
598
- <translation type="unfinished"/>
599
+ <translation>Kikapcsolva</translation>
600
</message>
601
</context>
602
<context>
603
<name>Converter</name>
604
<message>
605
<source>I can't create directory "%1".</source>
606
- <translation type="unfinished"/>
607
+ <translation>"%1" könyvtár nem hozható létre.</translation>
608
</message>
609
<message>
610
<source>I can't write to directory "%1".</source>
611
- <translation type="unfinished"/>
612
+ <translation>"%1" könyvtárba nem lehet írni.</translation>
613
</message>
614
<message>
615
<source>Conversion is not possible:</source>
616
- <translation type="unfinished"/>
617
+ <translation>Átalakítása nem lehetséges:</translation>
618
</message>
619
</context>
620
<context>
621
- <name>Disk</name>
622
+ <name>CueDiskSelectDialog</name>
623
<message>
624
- <source>Audio file not set.</source>
625
- <translation type="unfinished"/>
626
+ <source>Select disk</source>
627
+ <translation>Válassza ki a lemezt</translation>
628
</message>
629
<message>
630
- <source>CUE file not set.</source>
631
- <translation type="unfinished"/>
632
+ <source>%1 [ disk %2 ]</source>
633
+ <comment>Cue disk select dialog, string like 'The Wall [disk 1]'</comment>
634
+ <translation>%1 [ lemez %2 ]</translation>
635
</message>
636
<message>
637
- <source>File <b>%1</b> is not a valid CUE file.</source>
638
+ <source>The cue file contains information about multiple disks. Which disk you want to use?</source>
639
<translation type="unfinished"/>
640
</message>
641
+</context>
642
+<context>
643
+ <name>Disk</name>
644
+ <message>
645
+ <source>Audio file not set.</source>
646
+ <translation>Audio-fájl nincs beállítva.</translation>
647
+ </message>
648
<message>
649
- <source>File <b>%1</b> contains several FILE tags.<br>These CUE files are not supported yet.</source>
650
+ <source>Cue file not set.</source>
651
+ <translation>Cue-fájl nincs beállíŧva</translation>
652
+ </message>
653
+ <message>
654
+ <source>Audio file shorter than expected from cue sheet.</source>
655
<translation type="unfinished"/>
656
</message>
657
</context>
658
659
<source>I can't delete file:
660
%1
661
%2</source>
662
- <translation type="unfinished"/>
663
+ <translation>Nem tudtam törölni:
664
+%1
665
+%2</translation>
666
</message>
667
<message>
668
<source>Encoder error:
669
</source>
670
- <translation type="unfinished"/>
671
+ <translation>Átalakító hiba
672
+</translation>
673
</message>
674
<message>
675
<source>I can't read %1 file</source>
676
- <translation type="unfinished"/>
677
+ <comment>Encoder error. %1 is a file name.</comment>
678
+ <translation>Nem tudtam olvasni a %1 fájlt</translation>
679
</message>
680
</context>
681
<context>
682
<name>EncoderConfigPage</name>
683
<message>
684
<source>Sets encoding quality, between %1 (lowest) and %2 (highest).</source>
685
- <translation type="unfinished"/>
686
+ <translation>Átalakítási minőség beállítása %1 (alacsonyabb) és %2 (magasabb) között.</translation>
687
</message>
688
<message>
689
<source>Sets compression level, between %1 (fastest) and %2 (highest compression).
690
This only affects the file size. All settings are lossless.</source>
691
- <translation type="unfinished"/>
692
+ <translation>Tömörítési szint beállítása %1 (gyorsabb) és %2 (nagyobb tömörítés) között.
693
+Ez csak a fájl méretet befolyásolja. Minden beállítás veszteségmentes.</translation>
694
</message>
695
<message>
696
<source>Disabled</source>
697
<comment>ReplayGain type combobox</comment>
698
- <translation type="unfinished"/>
699
+ <translation>Letiltva</translation>
700
</message>
701
<message>
702
<source>Per Track</source>
703
<comment>ReplayGain type combobox</comment>
704
- <translation type="unfinished"/>
705
+ <translation>Sávonként</translation>
706
</message>
707
<message>
708
<source>Per Album</source>
709
<comment>ReplayGain type combobox</comment>
710
- <translation type="unfinished"/>
711
+ <translation>Albumonként</translation>
712
</message>
713
<message>
714
<source>ReplayGain is a standard to normalize the perceived loudness of computer audio formats.
715
716
</message>
717
<message>
718
<source>%1 kbps</source>
719
- <translation type="unfinished"/>
720
+ <translation>%1 kbit/s</translation>
721
</message>
722
<message>
723
<source>Default</source>
724
- <translation type="unfinished"/>
725
+ <translation>Alapértelmezés</translation>
726
</message>
727
</context>
728
<context>
729
730
<source>I can't rename file:
731
%1 to %2
732
%3</source>
733
- <translation type="unfinished"/>
734
+ <translation>Nem tudtam átnevezni:
735
+%1 to %2
736
+%3</translation>
737
</message>
738
</context>
739
<context>
740
741
<message>
742
<source>Gain error:
743
</source>
744
- <translation type="unfinished"/>
745
+ <translation>Erősítés hiba:
746
+</translation>
747
</message>
748
</context>
749
<context>
750
<name>MainWindow</name>
751
<message>
752
<source>Flacon</source>
753
- <translation type="unfinished"/>
754
+ <translation>Flacon</translation>
755
</message>
756
<message>
757
<source>Result Files</source>
758
- <translation type="unfinished"/>
759
+ <translation>Fájleredmények</translation>
760
</message>
761
<message>
762
<source>Directory:</source>
763
- <translation type="unfinished"/>
764
+ <translation>Mappa:</translation>
765
</message>
766
<message>
767
<source>Pattern:</source>
768
- <translation type="unfinished"/>
769
+ <translation>Minta:</translation>
770
</message>
771
<message>
772
<source>Format:</source>
773
- <translation type="unfinished"/>
774
+ <translation>Formátum:</translation>
775
</message>
776
<message>
777
<source>Output format</source>
778
<comment>Main form tooltip for "Format" edit</comment>
779
- <translation type="unfinished"/>
780
+ <translation>Kimeneti formátum</translation>
781
</message>
782
<message>
783
<source>Tags</source>
784
- <translation type="unfinished"/>
785
+ <translation>Címkék</translation>
786
</message>
787
<message>
788
<source>Genre:</source>
789
- <translation type="unfinished"/>
790
+ <translation>Műfaj:</translation>
791
</message>
792
<message>
793
<source>Year:</source>
794
- <translation type="unfinished"/>
795
+ <translation>Év:</translation>
796
</message>
797
<message>
798
<source>Artist:</source>
799
- <translation type="unfinished"/>
800
+ <translation>Művész:</translation>
801
</message>
802
<message>
803
<source>Album:</source>
804
- <translation type="unfinished"/>
805
+ <translation>Album:</translation>
806
</message>
807
<message>
808
<source>Start num:</source>
809
- <translation type="unfinished"/>
810
+ <translation>Kezdőszám:</translation>
811
</message>
812
<message>
813
<source>Disc ID:</source>
814
- <translation type="unfinished"/>
815
+ <translation>Lemezazonosító:</translation>
816
</message>
817
<message>
818
<source>Codepage:</source>
819
- <translation type="unfinished"/>
820
+ <translation>Kódlap:</translation>
821
</message>
822
<message>
823
<source>&File</source>
824
- <translation type="unfinished"/>
825
+ <translation>&Fájl</translation>
826
</message>
827
<message>
828
<source>&Settings</source>
829
- <translation type="unfinished"/>
830
+ <translation>&Beállítások</translation>
831
</message>
832
<message>
833
<source>&Help</source>
834
- <translation type="unfinished"/>
835
+ <translation>&Segítség</translation>
836
</message>
837
<message>
838
<source>Add file</source>
839
- <translation type="unfinished"/>
840
+ <translation>Fájl hozzáadása</translation>
841
</message>
842
<message>
843
<source>Add CUE or audio file</source>
844
- <translation type="unfinished"/>
845
+ <translation>Cue vagy audio-fájl hozzáadása</translation>
846
</message>
847
<message>
848
<source>Ctrl+O</source>
849
- <translation type="unfinished"/>
850
+ <translation>Ctrl+O</translation>
851
</message>
852
<message>
853
<source>Convert</source>
854
- <translation type="unfinished"/>
855
+ <translation>Konvertálás</translation>
856
</message>
857
<message>
858
<source>Start conversion process</source>
859
- <translation type="unfinished"/>
860
+ <translation>A konvertálási folyamat kezdése</translation>
861
</message>
862
<message>
863
<source>Ctrl+W</source>
864
- <translation type="unfinished"/>
865
+ <translation>Ctrl+W</translation>
866
</message>
867
<message>
868
<source>Abort</source>
869
- <translation type="unfinished"/>
870
+ <translation>Megszakítás</translation>
871
</message>
872
<message>
873
<source>Abort conversion process</source>
874
- <translation type="unfinished"/>
875
+ <translation>A konvertálási folyamat megszakítása</translation>
876
</message>
877
<message>
878
<source>Exit</source>
879
- <translation type="unfinished"/>
880
+ <translation>Kilépés</translation>
881
</message>
882
<message>
883
<source>Ctrl+Q</source>
884
- <translation type="unfinished"/>
885
+ <translation>Ctrl+Q</translation>
886
</message>
887
<message>
888
<source>&Preferences</source>
889
- <translation type="unfinished"/>
890
+ <translation>&Beállítások</translation>
891
</message>
892
<message>
893
<source>Program preferences</source>
894
- <translation type="unfinished"/>
895
+ <translation>A program beállításai</translation>
896
</message>
897
<message>
898
<source>&About Flacon</source>
899
- <translation type="unfinished"/>
900
+ <translation>Flacon &névjegye</translation>
901
</message>
902
<message>
903
<source>Remove album</source>
904
- <translation type="unfinished"/>
905
+ <translation>Album eltávolítása</translation>
906
</message>
907
<message>
908
<source>Remove album from project</source>
909
- <translation type="unfinished"/>
910
+ <translation>Album eltávolítása a projektből</translation>
911
</message>
912
<message>
913
<source>Ctrl+Del</source>
914
- <translation type="unfinished"/>
915
+ <translation>Ctrl+Del</translation>
916
</message>
917
<message>
918
<source>Configure encoder</source>
919
- <translation type="unfinished"/>
920
+ <translation>Átalakító beállítása</translation>
921
</message>
922
<message>
923
<source>...</source>
924
- <translation type="unfinished"/>
925
+ <translation>...</translation>
926
</message>
927
<message>
928
<source>Select result directory</source>
929
- <translation type="unfinished"/>
930
+ <translation>Eredmények mappa kiválaszása</translation>
931
</message>
932
<message>
933
<source>Get from CDDB</source>
934
- <translation type="unfinished"/>
935
+ <translation>Megszerzés a CDDB-ből</translation>
936
</message>
937
<message>
938
<source>Get album information from CDDB</source>
939
- <translation type="unfinished"/>
940
+ <translation>Album információk megszerzése a CDDB-ből</translation>
941
</message>
942
<message>
943
<source>Ctrl+I</source>
944
- <translation type="unfinished"/>
945
+ <translation>Ctrl+I</translation>
946
</message>
947
<message>
948
<source>Scan</source>
949
- <translation type="unfinished"/>
950
+ <translation>Keresés</translation>
951
</message>
952
<message>
953
<source>Recursive album search</source>
954
- <translation type="unfinished"/>
955
+ <translation>Rekurzív album keresés</translation>
956
</message>
957
<message>
958
<source>Insert "Track number"</source>
959
- <translation type="unfinished"/>
960
+ <translation>"Sávszám" beszúrása</translation>
961
</message>
962
<message>
963
<source>Insert "Total number of tracks"</source>
964
- <translation type="unfinished"/>
965
+ <translation>"Összesen sávszám" beszúrása</translation>
966
</message>
967
<message>
968
<source>Insert "Artist"</source>
969
- <translation type="unfinished"/>
970
+ <translation>"Előadó" beszúrása</translation>
971
</message>
972
<message>
973
<source>Insert "Album title"</source>
974
- <translation type="unfinished"/>
975
+ <translation>"Albumcím" beszúrása</translation>
976
</message>
977
<message>
978
<source>Insert "Track title"</source>
979
- <translation type="unfinished"/>
980
+ <translation>"Sávcím" beszúrása</translation>
981
</message>
982
<message>
983
<source>Insert "Year"</source>
984
- <translation type="unfinished"/>
985
+ <translation>"Év" beszúrása</translation>
986
</message>
987
<message>
988
<source>Insert "Genre"</source>
989
- <translation type="unfinished"/>
990
- </message>
991
- <message>
992
- <source>Select CUE file</source>
993
- <comment>OpenFile dialog title</comment>
994
- <translation type="unfinished"/>
995
+ <translation>"Műfaj" beszúrása</translation>
996
</message>
997
<message>
998
<source>Some albums will not be converted, they contain errors.
999
Do you want to continue?</source>
1000
- <translation type="unfinished"/>
1001
+ <translation>Több album nem lesz átalakítva mert hibákat tartalmaznak.
1002
+Biztosan folytatni akarod?</translation>
1003
</message>
1004
<message>
1005
<source>%1 files</source>
1006
<comment>OpenFile dialog filter line, like "WAV files"</comment>
1007
- <translation type="unfinished"/>
1008
+ <translation>%1 fájlok</translation>
1009
</message>
1010
<message>
1011
<source>All supported formats</source>
1012
<comment>OpenFile dialog filter line</comment>
1013
- <translation type="unfinished"/>
1014
+ <translation>Minden támogatott formátum</translation>
1015
</message>
1016
<message>
1017
<source>All files</source>
1018
<comment>OpenFile dialog filter line like "All files"</comment>
1019
- <translation type="unfinished"/>
1020
- </message>
1021
- <message>
1022
- <source>Add CUE or audio file</source>
1023
- <comment>OpenFile dialog title</comment>
1024
- <translation type="unfinished"/>
1025
+ <translation>Minden fájl</translation>
1026
</message>
1027
<message>
1028
<source>Select audio file</source>
1029
<comment>OpenFile dialog title</comment>
1030
- <translation type="unfinished"/>
1031
+ <translation>Audio-fájl kiválasztása</translation>
1032
</message>
1033
<message>
1034
<source>Select directory</source>
1035
- <translation type="unfinished"/>
1036
+ <translation>Válassza ki a könyvtárat</translation>
1037
</message>
1038
<message>
1039
<source>Flacon</source>
1040
<comment>Error</comment>
1041
- <translation type="unfinished"/>
1042
+ <translation>Flacon</translation>
1043
</message>
1044
<message>
1045
<source><style type="text/css">
1046
1047
<translation type="unfinished"/>
1048
</message>
1049
<message>
1050
- <source>You can browse to the destination directory. You can also input it manually.
1051
+ <source>You can browse to the destination directory. You can also input it manually.
1052
1053
If the path is left empty or starts with "." (dot), the result files will be placed in the same directory as the source.</source>
1054
<comment>Main form tooltip for "Directory" edit</comment>
1055
<translation type="unfinished"/>
1056
</message>
1057
+ <message>
1058
+ <source>Use "%1"</source>
1059
+ <comment>Predefined out file pattern, string like 'Use "%a/%A/%n - %t"'</comment>
1060
+ <translation>"%1" használata</translation>
1061
+ </message>
1062
+ <message>
1063
+ <source>Select cue file</source>
1064
+ <comment>OpenFile dialog title</comment>
1065
+ <translation>Cue-fájl kiválasztása</translation>
1066
+ </message>
1067
+ <message>
1068
+ <source>Add cue or audio file</source>
1069
+ <comment>OpenFile dialog title</comment>
1070
+ <translation>Cue vagy audio-fájl hozzáadása</translation>
1071
+ </message>
1072
+ <message>
1073
+ <source>Delete current pattern from history</source>
1074
+ <translation type="unfinished"/>
1075
+ </message>
1076
</context>
1077
<context>
1078
<name>MultiValuesComboBox</name>
1079
<message>
1080
<source>Multiple values</source>
1081
- <translation type="unfinished"/>
1082
+ <translation>Többszörös értékek</translation>
1083
</message>
1084
</context>
1085
<context>
1086
<name>MultiValuesLineEdit</name>
1087
<message>
1088
<source>Multiple values</source>
1089
- <translation type="unfinished"/>
1090
+ <translation>Többszörös értékek</translation>
1091
</message>
1092
</context>
1093
<context>
1094
<name>MultiValuesSpinBox</name>
1095
<message>
1096
<source>Multiple values</source>
1097
- <translation type="unfinished"/>
1098
+ <translation>Többszörös értékek</translation>
1099
</message>
1100
</context>
1101
<context>
1102
<name>ProgramEdit</name>
1103
<message>
1104
- <source>%1 program</source>
1105
- <translation type="unfinished"/>
1106
+ <source>Select program file</source>
1107
+ <translation>Programfájl kiválasztása</translation>
1108
</message>
1109
<message>
1110
- <source>All files</source>
1111
- <translation type="unfinished"/>
1112
+ <source>%1 program</source>
1113
+ <comment>This is part of filter for 'select program' dialog. %1 is a name of required program. Example: 'shntool program (shntool)'</comment>
1114
+ <translation>%1 program</translation>
1115
</message>
1116
<message>
1117
- <source>Select program file</source>
1118
- <translation type="unfinished"/>
1119
+ <source>All files</source>
1120
+ <comment>This is part of filter for 'select program' dialog. 'All files (*)'</comment>
1121
+ <translation>Minden fájl</translation>
1122
</message>
1123
</context>
1124
<context>
1125
- <name>Project</name>
1126
+ <name>QObject</name>
1127
+ <message>
1128
+ <source>I can't find program <b>%1</b>.</source>
1129
+ <translation>Nem találtam meg a <b>%1</b> programot.</translation>
1130
+ </message>
1131
+ <message>
1132
+ <source>File <b>%1</b> is not a supported audio file. <br><br>Verify that all required programs are installed and in your preferences.</source>
1133
+ <translation>A <b>%1</b> egy nem támogatott audio-fájl. <br><br>Ellenőrizni kell a szükséges programok telepítését és a beállításokat.</translation>
1134
+ </message>
1135
+ <message>
1136
+ <source> [disk %1]</source>
1137
+ <translation>[lemez %1]</translation>
1138
+ </message>
1139
<message>
1140
<source>Flacon</source>
1141
<comment>Error</comment>
1142
- <translation type="unfinished"/>
1143
+ <translation>Flacon</translation>
1144
</message>
1145
-</context>
1146
-<context>
1147
- <name>QObject</name>
1148
<message>
1149
- <source>I can't write CUE file <b>%1</b>:<br>%2</source>
1150
- <translation type="unfinished"/>
1151
+ <source>I can't write cue file <b>%1</b>:<br>%2</source>
1152
+ <translation>Nem lehetett írni az <b>%1</b>:<br>%2</translation>
1153
</message>
1154
<message>
1155
- <source>I can't find program <b>%1</b>.</source>
1156
- <translation type="unfinished"/>
1157
+ <source>File <b>"%1"</b> does not exist</source>
1158
+ <translation><b>"%1"</b> fájl nem létezik</translation>
1159
</message>
1160
<message>
1161
- <source>File <b>%1</b> is not a supported audio file. <br><br>Verify that all required programs are installed and in your preferences.</source>
1162
- <translation type="unfinished"/>
1163
+ <source><b>%1</b> is not a valid cue file. Disk %2 has no tags.</source>
1164
+ <translation><b>%1</b> nem egy valódi cue-fájl. %2 lemeznek nincs címkéje</translation>
1165
+ </message>
1166
+ <message>
1167
+ <source>The audio file name is not set</source>
1168
+ <translation>Az audio-fájl neve nincs beállíva</translation>
1169
</message>
1170
<message>
1171
<source>you can't use 'ReplayGain' for files with sample rates above 48kHz. Metaflac doesn't support such files.</source>
1172
+ <comment>This string should begin with a lowercase letter. This is a part of the complex sentence.</comment>
1173
<translation type="unfinished"/>
1174
</message>
1175
+ <message>
1176
+ <source><b>%1</b> is not a valid cue file. The cue sheet has no FILE tag.</source>
1177
+ <translation><b>%1</b> nem egy valódi cue-fájl. A cue mező nem tartalmaz FÁJL cimkét.</translation>
1178
+ </message>
1179
+ <message>
1180
+ <source><b>%1</b> is not a valid cue file. Incorrect track index at %2.</source>
1181
+ <comment>Cue parser error. %2 is file position</comment>
1182
+ <translation><b>%1</b> nem egy valódi cue-fájl. Érvénytelen sáv-index ebben: %2</translation>
1183
+ </message>
1184
+ <message>
1185
+ <source>The audio file <b>"%1"</b> does not exist</source>
1186
+ <translation><b>"%1"</b> audio-fájl nem létezik</translation>
1187
+ </message>
1188
</context>
1189
<context>
1190
<name>Splitter</name>
1191
1192
<context>
1193
<name>TrackView</name>
1194
<message>
1195
- <source>Select another CUE file</source>
1196
- <translation type="unfinished"/>
1197
- </message>
1198
- <message>
1199
<source>Get data from CDDB</source>
1200
- <translation type="unfinished"/>
1201
+ <translation>Adatok megszerzése a CDDB-ből</translation>
1202
</message>
1203
<message>
1204
<source>Edit</source>
1205
- <translation type="unfinished"/>
1206
+ <translation>Szerkesztés</translation>
1207
</message>
1208
<message>
1209
<source>Select another audio file</source>
1210
- <translation type="unfinished"/>
1211
+ <translation>Egy másik audio-fájl kiválasztása</translation>
1212
+ </message>
1213
+ <message>
1214
+ <source>Select another cue file</source>
1215
+ <translation>Egy másik cue-fájl kiválasztása</translation>
1216
</message>
1217
</context>
1218
<context>
1219
<name>TrackViewDelegate</name>
1220
<message>
1221
<source>Error</source>
1222
- <translation type="unfinished"/>
1223
+ <translation>Hiba</translation>
1224
</message>
1225
<message>
1226
<source>Aborted</source>
1227
- <translation type="unfinished"/>
1228
+ <translation>Megszakítva</translation>
1229
</message>
1230
<message>
1231
<source>OK</source>
1232
- <translation type="unfinished"/>
1233
+ <translation>RENDBEN</translation>
1234
</message>
1235
<message>
1236
<source>Extracting</source>
1237
- <translation type="unfinished"/>
1238
+ <translation>Kibontás</translation>
1239
</message>
1240
<message>
1241
<source>Encoding</source>
1242
- <translation type="unfinished"/>
1243
+ <translation>Átalakítás</translation>
1244
</message>
1245
<message>
1246
<source>Queued</source>
1247
- <translation type="unfinished"/>
1248
+ <translation>Sorbaállított</translation>
1249
</message>
1250
<message>
1251
<source>Calculate gain</source>
1252
- <translation type="unfinished"/>
1253
+ <translation>Erősítés számítása</translation>
1254
</message>
1255
<message>
1256
<source>Wait gain</source>
1257
- <translation type="unfinished"/>
1258
+ <translation>Késleltetéserősítés</translation>
1259
</message>
1260
<message>
1261
<source>Write gain</source>
1262
- <translation type="unfinished"/>
1263
+ <translation>Íráserősítés</translation>
1264
</message>
1265
<message>
1266
<source>Tracks:</source>
1267
- <translation type="unfinished"/>
1268
+ <translation>Sávok:</translation>
1269
</message>
1270
<message>
1271
<source>Audio:</source>
1272
- <translation type="unfinished"/>
1273
+ <translation>Hang:</translation>
1274
</message>
1275
</context>
1276
<context>
1277
1278
<message>
1279
<source>Track</source>
1280
<comment>Table header.</comment>
1281
- <translation type="unfinished"/>
1282
+ <translation>Sorszám</translation>
1283
</message>
1284
<message>
1285
<source>Title</source>
1286
<comment>Table header.</comment>
1287
- <translation type="unfinished"/>
1288
+ <translation>Cím</translation>
1289
</message>
1290
<message>
1291
<source>Artist</source>
1292
<comment>Table header.</comment>
1293
- <translation type="unfinished"/>
1294
+ <translation>Előadó</translation>
1295
</message>
1296
<message>
1297
<source>Album</source>
1298
<comment>Table header.</comment>
1299
- <translation type="unfinished"/>
1300
+ <translation>Album</translation>
1301
</message>
1302
<message>
1303
<source>Comment</source>
1304
<comment>Table header.</comment>
1305
- <translation type="unfinished"/>
1306
+ <translation>Megjegyzés</translation>
1307
</message>
1308
<message>
1309
<source>File</source>
1310
<comment>Table header.</comment>
1311
- <translation type="unfinished"/>
1312
+ <translation>Fájl</translation>
1313
</message>
1314
<message>
1315
<source>Multiple values</source>
1316
- <translation type="unfinished"/>
1317
+ <translation>Többszörös értékek</translation>
1318
+ </message>
1319
+ <message>
1320
+ <source>Length</source>
1321
+ <comment>Table header.</comment>
1322
+ <translation>Hossz</translation>
1323
</message>
1324
<message>
1325
- <source>Conversion is not possible.
1326
+ <source>%1:%2:%3</source>
1327
+ <comment>Track length, string like '01:02:56'</comment>
1328
+ <translation>%1:%2:%3</translation>
1329
+ </message>
1330
+ <message>
1331
+ <source>%1:%2</source>
1332
+ <comment>Track length, string like '02:56'</comment>
1333
+ <translation>%1:%2</translation>
1334
+ </message>
1335
+ <message>
1336
+ <source>The conversion is not possible.
1337
%1</source>
1338
- <translation type="unfinished"/>
1339
+ <translation>Átalakítása nem lehetséges.
1340
+%1</translation>
1341
</message>
1342
</context>
1343
</TS>
1344
\ No newline at end of file
1345
flacon-2.1.1.tar.gz/translations/flacon_lt.desktop -> flacon-3.1.1.tar.gz/translations/flacon_lt.desktop
Changed
8
1
2
# Translations
3
Icon[lt]=flacon
4
Comment[lt]=Išskleidžia garso takelius iš CD atvaizdžio į atskirus takelius.
5
-GenericName[lt]=Garso Failų Koduotuvas
6
+GenericName[lt]=Garso failų koduotuvas
7
Name[lt]=Flacon
8
flacon-2.1.1.tar.gz/translations/flacon_nb.ts -> flacon-3.1.1.tar.gz/translations/flacon_nb.ts
Changed
10
1
2
</message>
3
<message>
4
<source>Start num:</source>
5
- <translation>Startnum:</translation>
6
+ <translation>Startnummer:</translation>
7
</message>
8
<message>
9
<source>Disc ID:</source>
10
flacon-2.1.1.tar.gz/translations/translators_de.info -> flacon-3.1.1.tar.gz/translations/translators_de.info
Changed
14
1
2
translator_1_nameNative = Ettore Atalan
3
translator_1_contact = atalanttore@gmail.com
4
5
-translator_2_nameEnglish = -
6
-translator_2_nameNative = -
7
-translator_2_contact = -
8
+translator_2_nameEnglish = Andreas Martin Schops
9
+translator_2_nameNative = Andreas Martin Schops
10
+translator_2_contact = ams@mailbox.org
11
12
translator_3_nameEnglish = -
13
translator_3_nameNative = -
14
flacon-3.1.1.tar.gz/translations/translators_hu.info
Added
16
1
2
+_help = Don't translate this text, it is only help. I want to thank you in the "About" dialog. So, please fill the following information about yourself. The number does not matter, all the names will be displayed in alphabetical order.
3
+
4
+
5
+translator_1_nameEnglish = Fordító 1. Charles K Barcza
6
+translator_1_nameNative = Fordító 1. Barcza Károly
7
+translator_1_contact = Fordító 1. www.blackpanther.hu
8
+
9
+translator_2_nameEnglish = Translator 2. Your name in English.
10
+translator_2_nameNative = Translator 2. Your name in the native language.
11
+translator_2_contact = Translator 2. Contact information, email or web site address.
12
+
13
+translator_3_nameEnglish = Translator 3. Your name in English.
14
+translator_3_nameNative = Translator 3. Your name in the native language.
15
+translator_3_contact = Translator 3. Contact information, email or web site address.
16
flacon-2.1.1.tar.gz/translations/translators_nb.info -> flacon-3.1.1.tar.gz/translations/translators_nb.info
Changed
26
1
2
-_help = Don't translate this text, it is only help. I want to thank you in the "About" dialog. So, please fill the following information about yourself. The number does not matter, all the names will be displayed in alphabetical order.
3
+_help =
4
5
6
-translator_1_nameEnglish = Translator 1. Harald H.
7
-translator_1_nameNative = Translator 1. Harald H.
8
-translator_1_contact = Translator 1. haarektrans@gmail.com
9
+translator_1_nameEnglish = Translator 1. Allan Nordhoey
10
+translator_1_nameNative = Translator 1. Allan Nordhøy
11
+translator_1_contact = Translator 1. epost@anotheragency.no
12
13
-translator_2_nameEnglish = Allan Nordhøy
14
-translator_2_nameNative = Allan Nordhøy
15
-translator_2_contact = epost@anotheragency.no
16
+translator_2_nameEnglish = Translator 2. Harald H.
17
+translator_2_nameNative = Translator 2. Harald H.
18
+translator_2_contact = Translator 2. haarektrans@gmail.com
19
20
-translator_3_nameEnglish = Translator 3. Your name in English.
21
-translator_3_nameNative = Translator 3. Your name in the native language.
22
-translator_3_contact = Translator 3. Contact information, email or web site address.
23
+translator_3_nameEnglish =
24
+translator_3_nameNative =
25
+translator_3_contact =
26
Refresh
No build results available
Refresh
No rpmlint results available
Login required, please
login
or
signup
in order to comment