OSDN Git Service

Updated IPC handler threads for latest MUtilities changes.
[lamexp/LameXP.git] / src / Model_AudioFile.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2015 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version, but always including the *additional*
9 // restrictions defined in the "License.txt" file.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // http://www.gnu.org/licenses/gpl-2.0.txt
21 ///////////////////////////////////////////////////////////////////////////////
22
23 #include "Model_AudioFile.h"
24
25 //Internal
26 #include "Global.h"
27
28 //MUtils
29 #include <MUtils/Global.h>
30
31 //Qt
32 #include <QTime>
33 #include <QObject>
34 #include <QMutexLocker>
35 #include <QFile>
36
37 //CRT
38 #include <limits.h>
39
40 const unsigned int AudioFileModel::BITDEPTH_IEEE_FLOAT32 = UINT_MAX-1;
41
42 #define PRINT_S(VAR) do \
43 { \
44         if((VAR).isEmpty()) qDebug(#VAR " = N/A"); else qDebug(#VAR " = \"%s\"", MUTILS_UTF8((VAR))); \
45 } \
46 while(0)
47
48 #define PRINT_U(VAR) do \
49 { \
50         if((VAR) < 1) qDebug(#VAR " = N/A"); else qDebug(#VAR " = %u", (VAR)); \
51 } \
52 while(0)
53
54 //if((!(OTHER.NAME.isEmpty())) && ((FORCE) || (this.NAME.isEmpty()))) /*this.NAME = OTHER.NAME;*/ \
55
56 #define UPDATE_STR(OTHER, FORCE, NAME) do \
57 { \
58         if(!(((OTHER).NAME).isEmpty())) \
59         { \
60                 if((FORCE) || ((this->NAME).isEmpty())) (this->NAME) = ((OTHER).NAME); \
61         } \
62 } \
63 while(0)
64
65 #define UPDATE_INT(OTHER, FORCE, NAME) do \
66 { \
67         if(((OTHER).NAME) > 0) \
68         { \
69                 if((FORCE) || ((this->NAME) == 0)) (this->NAME) = ((OTHER).NAME); \
70         } \
71 } \
72 while(0)
73
74 #define ASSIGN_VAL(OTHER, NAME)  do \
75 { \
76         (this->NAME) = ((OTHER).NAME); \
77 } \
78 while(0)
79
80 ///////////////////////////////////////////////////////////////////////////////
81 // Audio File - Meta Info
82 ///////////////////////////////////////////////////////////////////////////////
83
84 AudioFileModel_MetaInfo::AudioFileModel_MetaInfo(void)
85 {
86         reset();
87 }
88
89 AudioFileModel_MetaInfo::AudioFileModel_MetaInfo(const AudioFileModel_MetaInfo &model)
90 {
91         ASSIGN_VAL(model, m_titel);
92         ASSIGN_VAL(model, m_artist);
93         ASSIGN_VAL(model, m_album);
94         ASSIGN_VAL(model, m_genre);
95         ASSIGN_VAL(model, m_comment);
96         ASSIGN_VAL(model, m_cover);
97         ASSIGN_VAL(model, m_year);
98         ASSIGN_VAL(model, m_position);
99 }
100
101 AudioFileModel_MetaInfo &AudioFileModel_MetaInfo::operator=(const AudioFileModel_MetaInfo &model)
102 {
103         ASSIGN_VAL(model, m_titel);
104         ASSIGN_VAL(model, m_artist);
105         ASSIGN_VAL(model, m_album);
106         ASSIGN_VAL(model, m_genre);
107         ASSIGN_VAL(model, m_comment);
108         ASSIGN_VAL(model, m_cover);
109         ASSIGN_VAL(model, m_year);
110         ASSIGN_VAL(model, m_position);
111
112         return (*this);
113 }
114
115 #define IS_EMPTY(X) ((X).isEmpty() ? "YES" : "NO")
116
117 void AudioFileModel_MetaInfo::update(const AudioFileModel_MetaInfo &model, const bool replace)
118 {
119         UPDATE_STR(model, replace, m_titel);
120         UPDATE_STR(model, replace, m_artist);
121         UPDATE_STR(model, replace, m_album);
122         UPDATE_STR(model, replace, m_genre);
123         UPDATE_STR(model, replace, m_comment);
124         UPDATE_STR(model, replace, m_cover);
125         UPDATE_INT(model, replace, m_year);
126         UPDATE_INT(model, replace, m_position);
127 }
128
129 AudioFileModel_MetaInfo::~AudioFileModel_MetaInfo(void)
130 {
131         /*nothing to do*/
132 }
133
134 void AudioFileModel_MetaInfo::reset(void)
135 {
136         m_titel.clear();
137         m_artist.clear();
138         m_album.clear();
139         m_genre.clear();
140         m_comment.clear();
141         m_cover.clear();
142         m_year = 0;
143         m_position = 0;
144 }
145
146 void AudioFileModel_MetaInfo::print(void) const
147 {
148         PRINT_S(m_titel);
149         PRINT_S(m_artist);
150         PRINT_S(m_album);
151         PRINT_S(m_genre);
152         PRINT_S(m_comment);
153         PRINT_S(m_cover.filePath());
154         PRINT_U(m_year);
155         PRINT_U(m_position);
156 }
157
158 ///////////////////////////////////////////////////////////////////////////////
159 // Audio File - Technical Info
160 ///////////////////////////////////////////////////////////////////////////////
161
162 AudioFileModel_TechInfo::AudioFileModel_TechInfo(void)
163 {
164         reset();
165 }
166
167 AudioFileModel_TechInfo::AudioFileModel_TechInfo(const AudioFileModel_TechInfo &model)
168 {
169         ASSIGN_VAL(model, m_containerType);
170         ASSIGN_VAL(model, m_containerProfile);
171         ASSIGN_VAL(model, m_audioType);
172         ASSIGN_VAL(model, m_audioProfile);
173         ASSIGN_VAL(model, m_audioVersion);
174         ASSIGN_VAL(model, m_audioEncodeLib);
175         ASSIGN_VAL(model, m_audioSamplerate);
176         ASSIGN_VAL(model, m_audioChannels);
177         ASSIGN_VAL(model, m_audioBitdepth);
178         ASSIGN_VAL(model, m_audioBitrate);
179         ASSIGN_VAL(model, m_audioBitrateMode);
180         ASSIGN_VAL(model, m_duration);
181 }
182
183 AudioFileModel_TechInfo &AudioFileModel_TechInfo::operator=(const AudioFileModel_TechInfo &model)
184 {
185         ASSIGN_VAL(model, m_containerType);
186         ASSIGN_VAL(model, m_containerProfile);
187         ASSIGN_VAL(model, m_audioType);
188         ASSIGN_VAL(model, m_audioProfile);
189         ASSIGN_VAL(model, m_audioVersion);
190         ASSIGN_VAL(model, m_audioEncodeLib);
191         ASSIGN_VAL(model, m_audioSamplerate);
192         ASSIGN_VAL(model, m_audioChannels);
193         ASSIGN_VAL(model, m_audioBitdepth);
194         ASSIGN_VAL(model, m_audioBitrate);
195         ASSIGN_VAL(model, m_audioBitrateMode);
196         ASSIGN_VAL(model, m_duration);
197
198         return (*this);
199 }
200
201 AudioFileModel_TechInfo::~AudioFileModel_TechInfo(void)
202 {
203         /*nothing to do*/
204 }
205
206 void AudioFileModel_TechInfo::reset(void)
207 {
208         m_containerType.clear();
209         m_containerProfile.clear();
210         m_audioType.clear();
211         m_audioProfile.clear();
212         m_audioVersion.clear();
213         m_audioEncodeLib.clear();
214         m_audioSamplerate = 0;
215         m_audioChannels = 0;
216         m_audioBitdepth = 0;
217         m_audioBitrate = 0;
218         m_audioBitrateMode = 0;
219         m_duration = 0;
220 }
221
222 ////////////////////////////////////////////////////////////
223 // Audio File Model
224 ////////////////////////////////////////////////////////////
225
226 AudioFileModel::AudioFileModel(const QString &path)
227 :
228         m_filePath(path)
229 {
230         m_metaInfo.reset();
231         m_techInfo.reset();
232 }
233
234 AudioFileModel::AudioFileModel(const AudioFileModel &model)
235 {
236         ASSIGN_VAL(model, m_filePath);
237         ASSIGN_VAL(model, m_metaInfo);
238         ASSIGN_VAL(model, m_techInfo);
239 }
240
241 AudioFileModel &AudioFileModel::operator=(const AudioFileModel &model)
242 {
243         ASSIGN_VAL(model, m_filePath);
244         ASSIGN_VAL(model, m_metaInfo);
245         ASSIGN_VAL(model, m_techInfo);
246
247         return (*this);
248 }
249
250 AudioFileModel::~AudioFileModel(void)
251 {
252         /*nothing to do*/
253 }
254
255
256 void AudioFileModel::reset(void)
257 {
258         m_filePath.clear();
259         m_metaInfo.reset();
260         m_techInfo.reset();
261 }
262
263 /*------------------------------------*/
264 /* Helper functions
265 /*------------------------------------*/
266
267 const QString AudioFileModel::durationInfo(void) const
268 {
269         if(m_techInfo.duration())
270         {
271                 QTime time = QTime().addSecs(m_techInfo.duration());
272                 return time.toString("hh:mm:ss");
273         }
274         else
275         {
276                 return QString();
277         }
278 }
279
280 const QString AudioFileModel::containerInfo(void) const
281 {
282         if(!m_techInfo.containerType().isEmpty())
283         {
284                 QString info = m_techInfo.containerType();
285                 if(!m_techInfo.containerProfile().isEmpty()) info.append(QString(" (%1: %2)").arg(tr("Profile"), m_techInfo.containerProfile()));
286                 return info;
287         }
288         else
289         {
290                 return QString();
291         }
292 }
293
294 const QString AudioFileModel::audioBaseInfo(void) const
295 {
296         if(m_techInfo.audioSamplerate() || m_techInfo.audioChannels() || m_techInfo.audioBitdepth())
297         {
298                 QString info;
299                 if(m_techInfo.audioChannels())
300                 {
301                         if(!info.isEmpty()) info.append(", ");
302                         info.append(QString("%1: %2").arg(tr("Channels"), QString::number(m_techInfo.audioChannels())));
303                 }
304                 if(m_techInfo.audioSamplerate())
305                 {
306                         if(!info.isEmpty()) info.append(", ");
307                         info.append(QString("%1: %2 Hz").arg(tr("Samplerate"), QString::number(m_techInfo.audioSamplerate())));
308                 }
309                 if(m_techInfo.audioBitdepth())
310                 {
311                         if(!info.isEmpty()) info.append(", ");
312                         if(m_techInfo.audioBitdepth() == BITDEPTH_IEEE_FLOAT32)
313                         {
314                                 info.append(QString("%1: %2 Bit (IEEE Float)").arg(tr("Bitdepth"), QString::number(32)));
315                         }
316                         else
317                         {
318                                 info.append(QString("%1: %2 Bit").arg(tr("Bitdepth"), QString::number(m_techInfo.audioBitdepth())));
319                         }
320                 }
321                 return info;
322         }
323         else
324         {
325                 return QString();
326         }
327 }
328
329 const QString AudioFileModel::audioCompressInfo(void) const
330 {
331         if(!m_techInfo.audioType().isEmpty())
332         {
333                 QString info;
334                 if(!m_techInfo.audioProfile().isEmpty() || !m_techInfo.audioVersion().isEmpty())
335                 {
336                         info.append(QString("%1: ").arg(tr("Type")));
337                 }
338                 info.append(m_techInfo.audioType());
339                 if(!m_techInfo.audioProfile().isEmpty())
340                 {
341                         info.append(QString(", %1: %2").arg(tr("Profile"), m_techInfo.audioProfile()));
342                 }
343                 if(!m_techInfo.audioVersion().isEmpty())
344                 {
345                         info.append(QString(", %1: %2").arg(tr("Version"), m_techInfo.audioVersion()));
346                 }
347                 if(m_techInfo.audioBitrate() > 0)
348                 {
349                         switch(m_techInfo.audioBitrateMode())
350                         {
351                         case BitrateModeConstant:
352                                 info.append(QString(", %1: %2 kbps (%3)").arg(tr("Bitrate"), QString::number(m_techInfo.audioBitrate()), tr("Constant")));
353                                 break;
354                         case BitrateModeVariable:
355                                 info.append(MUTILS_QSTR(L", %1: \u2248%2 kbps (%3)").arg(tr("Bitrate"), QString::number(m_techInfo.audioBitrate()), tr("Variable")));
356                                 break;
357                         default:
358                                 info.append(QString(", %1: %2 kbps").arg(tr("Bitrate"), QString::number(m_techInfo.audioBitrate())));
359                                 break;
360                         }
361                 }
362                 if(!m_techInfo.audioEncodeLib().isEmpty())
363                 {
364                         info.append(QString(", %1: %2").arg(tr("Encoder"), m_techInfo.audioEncodeLib()));
365                 }
366                 return info;
367         }
368         else
369         {
370                 return QString();
371         }
372 }