OSDN Git Service

Initial support for cover artwork.
[lamexp/LameXP.git] / src / Model_AudioFile.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2011 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.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 //
19 // http://www.gnu.org/licenses/gpl-2.0.txt
20 ///////////////////////////////////////////////////////////////////////////////
21
22 #include "Model_AudioFile.h"
23
24 #include <QTime>
25 #include <QObject>
26 #include <QMutexLocker>
27 #include <QFile>
28
29 QMutex AudioFileModel::m_mutexCovers;
30 QMap<QString, unsigned int> AudioFileModel::m_counterCovers;
31 QMap<QString, QFile*> AudioFileModel::m_locksCovers;
32
33 ////////////////////////////////////////////////////////////
34 // Constructor & Destructor
35 ////////////////////////////////////////////////////////////
36
37 AudioFileModel::AudioFileModel(const QString &path, const QString &name)
38 {
39         resetAll();
40
41         m_filePath = path;
42         m_fileName = name;
43 }
44
45 AudioFileModel::AudioFileModel(const AudioFileModel &model, bool copyMetaInfo)
46 {
47         resetAll();
48
49         setFilePath(model.m_filePath);
50         setFormatContainerType(model.m_formatContainerType);
51         setFormatContainerProfile(model.m_formatContainerProfile);
52         setFormatAudioType(model.m_formatAudioType);
53         setFormatAudioProfile(model.m_formatAudioProfile);
54         setFormatAudioVersion(model.m_formatAudioVersion);
55         setFormatAudioSamplerate(model.m_formatAudioSamplerate);
56         setFormatAudioChannels(model.m_formatAudioChannels);
57         setFormatAudioBitdepth(model.m_formatAudioBitdepth);
58         setFileDuration(model.m_fileDuration);
59
60         if(copyMetaInfo)
61         {
62                 setFileName(model.m_fileName);
63                 setFileArtist(model.m_fileArtist);
64                 setFileAlbum(model.m_fileAlbum);
65                 setFileGenre(model.m_fileGenre);
66                 setFileComment(model.m_fileComment);
67                 setFileCover(model.m_fileCover);
68                 setFileYear(model.m_fileYear);
69                 setFilePosition(model.m_filePosition);
70         }
71 }
72
73 AudioFileModel &AudioFileModel::operator=(const AudioFileModel &model)
74 {
75         setFilePath(model.m_filePath);
76         setFileName(model.m_fileName);
77         setFileArtist(model.m_fileArtist);
78         setFileAlbum(model.m_fileAlbum);
79         setFileGenre(model.m_fileGenre);
80         setFileComment(model.m_fileComment);
81         setFileCover(model.m_fileCover);
82         setFileYear(model.m_fileYear);
83         setFilePosition(model.m_filePosition);
84         setFileDuration(model.m_fileDuration);
85
86         setFormatContainerType(model.m_formatContainerType);
87         setFormatContainerProfile(model.m_formatContainerProfile);
88         setFormatAudioType(model.m_formatAudioType);
89         setFormatAudioProfile(model.m_formatAudioProfile);
90         setFormatAudioVersion(model.m_formatAudioVersion);
91         setFormatAudioSamplerate(model.m_formatAudioSamplerate);
92         setFormatAudioChannels(model.m_formatAudioChannels);
93         setFormatAudioBitdepth(model.m_formatAudioBitdepth);
94
95         return (*this);
96 }
97
98 AudioFileModel::~AudioFileModel(void)
99 {
100         if(!m_fileCover.isEmpty())
101         {
102                 setFileCover(QString());
103         }
104 }
105
106 ////////////////////////////////////////////////////////////
107 // Private Functions
108 ////////////////////////////////////////////////////////////
109
110 void AudioFileModel::resetAll(void)
111 {
112         m_filePath.clear();
113         m_fileName.clear();
114         m_fileArtist.clear();
115         m_fileAlbum.clear();
116         m_fileGenre.clear();
117         m_fileComment.clear();
118         m_fileCover.clear();
119         
120         m_fileYear = 0;
121         m_filePosition = 0;
122         m_fileDuration = 0;
123
124         m_formatContainerType.clear();
125         m_formatContainerProfile.clear();
126         m_formatAudioType.clear();
127         m_formatAudioProfile.clear();
128         m_formatAudioVersion.clear();
129         
130         m_formatAudioSamplerate = 0;
131         m_formatAudioChannels = 0;
132         m_formatAudioBitdepth = 0;
133 }
134
135 ////////////////////////////////////////////////////////////
136 // Public Functions
137 ////////////////////////////////////////////////////////////
138
139 // ---------------------------------
140 // Getter methods
141 // ---------------------------------
142
143 const QString &AudioFileModel::filePath(void) const
144 {
145         return m_filePath;
146 }
147
148 const QString &AudioFileModel::fileName(void) const
149 {
150         return m_fileName;
151 }
152
153 const QString &AudioFileModel::fileArtist(void) const
154 {
155         return m_fileArtist;
156 }
157
158 const QString &AudioFileModel::fileAlbum(void) const
159 {
160         return m_fileAlbum;
161 }
162
163 const QString &AudioFileModel::fileGenre(void) const
164 {
165         return m_fileGenre;
166 }
167
168 const QString &AudioFileModel::fileComment(void) const
169 {
170         return m_fileComment;
171 }
172
173 const QString &AudioFileModel::fileCover(void) const
174 {
175         return m_fileCover;
176 }
177
178 unsigned int AudioFileModel::fileYear(void) const
179 {
180         return m_fileYear;
181 }
182
183 unsigned int AudioFileModel::filePosition(void) const
184 {
185         return m_filePosition;
186 }
187
188 unsigned int AudioFileModel::fileDuration(void) const
189 {
190         return m_fileDuration;
191 }
192
193 const QString &AudioFileModel::formatContainerType(void) const
194 {
195         return m_formatContainerType;
196 }
197
198 const QString &AudioFileModel::formatContainerProfile(void) const
199 {
200         return m_formatContainerProfile;
201 }
202
203 const QString &AudioFileModel::formatAudioType(void) const
204 {
205         return m_formatAudioType;
206 }
207
208 const QString &AudioFileModel::formatAudioProfile(void) const
209 {
210         return m_formatAudioProfile;
211 }
212
213 const QString &AudioFileModel::formatAudioVersion(void) const
214 {
215         return m_formatAudioVersion;
216 }
217
218 unsigned int AudioFileModel::formatAudioSamplerate(void) const
219 {
220         return m_formatAudioSamplerate;
221 }
222
223 unsigned int AudioFileModel::formatAudioChannels(void) const
224 {
225         return m_formatAudioChannels;
226 }
227
228 unsigned int AudioFileModel::formatAudioBitdepth(void) const
229 {
230         return m_formatAudioBitdepth;
231 }
232
233 const QString AudioFileModel::fileDurationInfo(void) const
234 {
235         if(m_fileDuration)
236         {
237                 QTime time = QTime().addSecs(m_fileDuration);
238                 return time.toString("hh:mm:ss");
239         }
240         else
241         {
242                 return QString();
243         }
244 }
245
246 const QString AudioFileModel::formatContainerInfo(void) const
247 {
248         if(!m_formatContainerType.isEmpty())
249         {
250                 QString info = m_formatContainerType;
251                 if(!m_formatContainerProfile.isEmpty()) info.append(QString(" (%1: %2)").arg(tr("Profile"), m_formatContainerProfile));
252                 return info;
253         }
254         else
255         {
256                 return QString();
257         }
258 }
259
260 const QString AudioFileModel::formatAudioBaseInfo(void) const
261 {
262         if(m_formatAudioSamplerate || m_formatAudioChannels || m_formatAudioBitdepth)
263         {
264                 QString info;
265                 if(m_formatAudioChannels)
266                 {
267                         if(!info.isEmpty()) info.append(", ");
268                         info.append(QString("%1: %2").arg(tr("Channels"), QString::number(m_formatAudioChannels)));
269                 }
270                 if(m_formatAudioSamplerate)
271                 {
272                         if(!info.isEmpty()) info.append(", ");
273                         info.append(QString("%1: %2 Hz").arg(tr("Samplerate"), QString::number(m_formatAudioSamplerate)));
274                 }
275                 if(m_formatAudioBitdepth)
276                 {
277                         if(!info.isEmpty()) info.append(", ");
278                         info.append(QString("%1: %2 Bit").arg(tr("Bitdepth"), QString::number(m_formatAudioBitdepth)));
279                 }
280                 return info;
281         }
282         else
283         {
284                 return QString();
285         }
286 }
287
288 const QString AudioFileModel::formatAudioCompressInfo(void) const
289 {
290         if(!m_formatAudioType.isEmpty())
291         {
292                 QString info;
293                 if(!m_formatAudioProfile.isEmpty() || !m_formatAudioVersion.isEmpty())
294                 {
295                         info.append(QString("%1: ").arg(tr("Type")));
296                 }
297                 info.append(m_formatAudioType);
298                 if(!m_formatAudioProfile.isEmpty())
299                 {
300                         info.append(QString(", %1: %2").arg(tr("Profile"), m_formatAudioProfile));
301                 }
302                 if(!m_formatAudioVersion.isEmpty())
303                 {
304                         info.append(QString(", %1: %2").arg(tr("Version"), m_formatAudioVersion));
305                 }
306                 return info;
307         }
308         else
309         {
310                 return QString();
311         }
312 }
313
314 // ---------------------------------
315 // Setter methods
316 // ---------------------------------
317
318 void AudioFileModel::setFilePath(const QString &path)
319 {
320         m_filePath = path;
321 }
322
323 void AudioFileModel::setFileName(const QString &name)
324 {
325         m_fileName = name;
326 }
327
328 void AudioFileModel::setFileArtist(const QString &artist)
329 {
330         m_fileArtist = artist;
331 }
332
333 void AudioFileModel::setFileAlbum(const QString &album)
334 {
335         m_fileAlbum = album;
336 }
337
338 void AudioFileModel::setFileGenre(const QString &genre)
339 {
340         m_fileGenre = genre;
341 }
342
343 void AudioFileModel::setFileComment(const QString &comment)
344 {
345         m_fileComment = comment;
346 }
347
348 void AudioFileModel::setFileCover(const QString &coverFile)
349 {
350         QMutexLocker lock(&m_mutexCovers);
351         if(m_fileCover.isEmpty() || coverFile.isEmpty() || (m_fileCover.compare(coverFile, Qt::CaseInsensitive) != 0))
352         {
353                 if(!m_fileCover.isEmpty() && m_counterCovers.contains(m_fileCover))
354                 {
355                         if(--m_counterCovers[m_fileCover] < 1)
356                         {
357                                 m_counterCovers.remove(m_fileCover);
358                                 if(m_locksCovers.contains(m_fileCover))
359                                 {
360                                         delete m_locksCovers[m_fileCover];
361                                         m_locksCovers.remove(m_fileCover);
362                                 }
363                                 QFile::remove(m_fileCover);
364                         }
365                 }
366                 if(!coverFile.isEmpty())
367                 {
368                         if(!m_counterCovers.contains(coverFile))
369                         {
370                                 m_counterCovers.insert(coverFile, 0);
371                                 m_locksCovers.insert(coverFile, new QFile(coverFile));
372                                 m_locksCovers[coverFile]->open(QIODevice::ReadOnly);
373                         }
374                         m_counterCovers[coverFile]++;
375                 }
376         }
377
378         m_fileCover = coverFile;
379 }
380
381 void AudioFileModel::setFileYear(unsigned int year)
382 {
383         m_fileYear = year;
384 }
385
386 void AudioFileModel::setFilePosition(unsigned int position)
387 {
388         m_filePosition = position;
389 }
390
391 void AudioFileModel::setFileDuration(unsigned int duration)
392 {
393         m_fileDuration = duration;
394 }
395
396 void AudioFileModel::setFormatContainerType(const QString &type)
397 {
398         m_formatContainerType = type;
399 }
400
401 void AudioFileModel::setFormatContainerProfile(const QString &profile)
402 {
403         m_formatContainerProfile = profile;
404 }
405
406 void AudioFileModel::setFormatAudioType(const QString &type)
407 {
408         m_formatAudioType = type;
409 }
410
411 void AudioFileModel::setFormatAudioProfile(const QString &profile)
412 {
413         m_formatAudioProfile = profile;
414 }
415
416 void AudioFileModel::setFormatAudioVersion(const QString &version)
417 {
418         m_formatAudioVersion = version;
419 }
420
421 void AudioFileModel::setFormatAudioSamplerate(unsigned int samplerate)
422 {
423         m_formatAudioSamplerate = samplerate;
424 }
425
426 void AudioFileModel::setFormatAudioChannels(unsigned int channels)
427 {
428         m_formatAudioChannels = channels;
429 }
430
431 void AudioFileModel::setFormatAudioBitdepth(unsigned int bitdepth)
432 {
433         m_formatAudioBitdepth = bitdepth;
434 }
435
436 void AudioFileModel::updateMetaInfo(const AudioFileModel &model)
437 {
438         if(!model.fileArtist().isEmpty()) setFileArtist(model.fileArtist());
439         if(!model.fileAlbum().isEmpty()) setFileAlbum(model.fileAlbum());
440         if(!model.fileGenre().isEmpty()) setFileGenre(model.fileGenre());
441         if(!model.fileComment().isEmpty()) setFileComment(model.fileComment());
442         if(model.fileYear()) setFileYear(model.fileYear());
443 }