aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2008-10-30 21:01:26 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2008-10-30 21:01:26 +0000
commit311224cda472f8d308884353960cab6231bb769d (patch)
tree2407b572357a1a4cc10e184493da528fe69109c4
parent304dc519d9d68b3861af998a997c5f2a97c9235d (diff)
downloadqmmp-311224cda472f8d308884353960cab6231bb769d.tar.gz
qmmp-311224cda472f8d308884353960cab6231bb769d.tar.bz2
qmmp-311224cda472f8d308884353960cab6231bb769d.zip
AAC plugin: fixed seeking; id3v2 tags support
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@606 90c681e8-e032-0410-971d-27865f9a5e38
-rw-r--r--src/plugins/Input/CMakeLists.txt4
-rw-r--r--src/plugins/Input/aac/CMakeLists.txt2
-rw-r--r--src/plugins/Input/aac/aac.pro6
-rw-r--r--src/plugins/Input/aac/aacfile.cpp9
-rw-r--r--src/plugins/Input/aac/aacfile.h10
-rw-r--r--src/plugins/Input/aac/decoder_aac.cpp7
-rw-r--r--src/plugins/Input/aac/decoderaacfactory.cpp22
-rw-r--r--src/plugins/Input/aac/tagextractor.cpp115
-rw-r--r--src/plugins/Input/aac/tagextractor.h68
9 files changed, 218 insertions, 25 deletions
diff --git a/src/plugins/Input/CMakeLists.txt b/src/plugins/Input/CMakeLists.txt
index 1164598c0..c5c82edef 100644
--- a/src/plugins/Input/CMakeLists.txt
+++ b/src/plugins/Input/CMakeLists.txt
@@ -50,6 +50,6 @@ IF(USE_AAC)
add_subdirectory(aac)
ENDIF(USE_AAC)
-IF(USE_CUE)
+IF(USE_CUE AND TAGLIB_FOUND)
add_subdirectory(cue)
-ENDIF(USE_CUE)
+ENDIF(USE_CUE AND TAGLIB_FOUND)
diff --git a/src/plugins/Input/aac/CMakeLists.txt b/src/plugins/Input/aac/CMakeLists.txt
index 1da0221c8..ae9d22b32 100644
--- a/src/plugins/Input/aac/CMakeLists.txt
+++ b/src/plugins/Input/aac/CMakeLists.txt
@@ -39,6 +39,7 @@ SET(libaac_SRCS
decoderaacfactory.cpp
detailsdialog.cpp
aacfile.cpp
+ tagextractor.cpp
)
SET(libaac_MOC_HDRS
@@ -46,6 +47,7 @@ SET(libaac_MOC_HDRS
decoder_aac.h
detailsdialog.h
aacfile.h
+ tagextractor.h
)
#SET(libaac_RCCS translations/translations.qrc)
diff --git a/src/plugins/Input/aac/aac.pro b/src/plugins/Input/aac/aac.pro
index 5bc0cb38a..01e2bbff0 100644
--- a/src/plugins/Input/aac/aac.pro
+++ b/src/plugins/Input/aac/aac.pro
@@ -4,11 +4,13 @@ FORMS += detailsdialog.ui
HEADERS += decoderaacfactory.h \
decoder_aac.h \
detailsdialog.h \
- aacfile.h
+ aacfile.h \
+ tagextractor.h
SOURCES += decoder_aac.cpp \
decoderaacfactory.cpp \
detailsdialog.cpp \
- aacfile.cpp
+ aacfile.cpp \
+ tagextractor.cpp
TARGET =$$PLUGINS_PREFIX/Input/aac
QMAKE_CLEAN =$$PLUGINS_PREFIX/Input/libaac.so
diff --git a/src/plugins/Input/aac/aacfile.cpp b/src/plugins/Input/aac/aacfile.cpp
index f25c31202..8df0592f5 100644
--- a/src/plugins/Input/aac/aacfile.cpp
+++ b/src/plugins/Input/aac/aacfile.cpp
@@ -22,6 +22,7 @@
#include <neaacdec.h>
+#include "tagextractor.h"
#include "aacfile.h"
#define MAX_CHANNELS 6
@@ -34,6 +35,7 @@ AACFile::AACFile(QIODevice *i)
m_isValid = FALSE;
m_length = 0;
m_bitrate = 0;
+ m_ext = 0;
m_input = i;
uchar buf[AAC_BUFFER_SIZE];
qint64 buf_at = i->peek((char *) buf, AAC_BUFFER_SIZE);
@@ -52,6 +54,8 @@ AACFile::AACFile(QIODevice *i)
return;
}
memmove (buf, buf + tag_size, buf_at - tag_size);
+
+ m_ext = new TagExtractor(i);
}
//try to determenate header type;
if (buf[0] == 0xff && ((buf[1] & 0xf6) == 0xf0))
@@ -165,3 +169,8 @@ bool AACFile::isValid()
{
return m_isValid;
}
+
+const QMap<Qmmp::MetaData, QString> AACFile::metaData()
+{
+ return m_ext ? m_ext->id3v2tag() : QMap<Qmmp::MetaData, QString>();
+}
diff --git a/src/plugins/Input/aac/aacfile.h b/src/plugins/Input/aac/aacfile.h
index 4199a3c05..3c9c2bf48 100644
--- a/src/plugins/Input/aac/aacfile.h
+++ b/src/plugins/Input/aac/aacfile.h
@@ -20,7 +20,14 @@
#ifndef AACFILE_H
#define AACFILE_H
+
+#include <QMap>
+#include <QString>
+
+#include <qmmp/qmmp.h>
+
class QIODevice;
+class TagExtractor;
/**
@author Ilya Kotov <forkotov02@hotmail.ru>
@@ -35,6 +42,7 @@ public:
qint64 length();
quint32 bitrate();
bool isValid();
+ const QMap<Qmmp::MetaData, QString> metaData();
private:
void parseADTS();
@@ -42,6 +50,8 @@ private:
quint32 m_bitrate;
QIODevice *m_input;
bool m_isValid;
+ QMap<Qmmp::MetaData, QString> m_metaData;
+ TagExtractor *m_ext;
};
#endif
diff --git a/src/plugins/Input/aac/decoder_aac.cpp b/src/plugins/Input/aac/decoder_aac.cpp
index 65d91e4ed..6953a686c 100644
--- a/src/plugins/Input/aac/decoder_aac.cpp
+++ b/src/plugins/Input/aac/decoder_aac.cpp
@@ -240,6 +240,11 @@ qint64 DecoderAAC::aac_decode(void *out)
if ((size = frame_info.samples * 2) > 0)
memcpy((void *) (m_output_buf + m_output_at), out, size);
+ if (frame_info.error > 0)
+ {
+ m_input_at = 0;
+ qDebug("DecoderAAC: %s", NeAACDecGetErrorMessage(frame_info.error));
+ }
}
return size;
}
@@ -285,7 +290,7 @@ void DecoderAAC::run()
if (m_seekTime >= 0 && m_totalTime)
{
input()->seek(m_seekTime * input()->size() / m_totalTime);
- NeAACDecPostSeekReset (data()->handle, -1);
+ NeAACDecPostSeekReset (data()->handle, 0);
m_input_at = 0;
m_seekTime = -1.0;
}
diff --git a/src/plugins/Input/aac/decoderaacfactory.cpp b/src/plugins/Input/aac/decoderaacfactory.cpp
index 2f5b621ee..9b91f1d45 100644
--- a/src/plugins/Input/aac/decoderaacfactory.cpp
+++ b/src/plugins/Input/aac/decoderaacfactory.cpp
@@ -63,29 +63,11 @@ QList<FileInfo *> DecoderAACFactory::createPlayList(const QString &fileName)
{
FileInfo *info = new FileInfo(fileName);
- /*TagLib::FileRef fileRef(fileName.toLocal8Bit ());
- TagLib::Tag *tag = fileRef.tag();
- if (tag && !tag->isEmpty())
- {
- info->setMetaData(Qmmp::ALBUM,
- QString::fromUtf8(tag->album().toCString(TRUE)).trimmed());
- info->setMetaData(Qmmp::ARTIST,
- QString::fromUtf8(tag->artist().toCString(TRUE)).trimmed());
- info->setMetaData(Qmmp::COMMENT,
- QString::fromUtf8(tag->comment().toCString(TRUE)).trimmed());
- info->setMetaData(Qmmp::GENRE,
- QString::fromUtf8(tag->genre().toCString(TRUE)).trimmed());
- info->setMetaData(Qmmp::TITLE,
- QString::fromUtf8(tag->title().toCString(TRUE)).trimmed());
- info->setMetaData(Qmmp::YEAR, tag->year());
- info->setMetaData(Qmmp::TRACK, tag->track());
- }
- if (fileRef.audioProperties())
- info->setLength(fileRef.audioProperties()->length());*/
QFile file(fileName);
- if(file.open(QIODevice::ReadOnly))
+ if (file.open(QIODevice::ReadOnly))
{
AACFile aac_file(&file);
+ info->setMetaData(aac_file.metaData());
info->setLength(aac_file.length());
}
QList <FileInfo*> list;
diff --git a/src/plugins/Input/aac/tagextractor.cpp b/src/plugins/Input/aac/tagextractor.cpp
new file mode 100644
index 000000000..1385c8a85
--- /dev/null
+++ b/src/plugins/Input/aac/tagextractor.cpp
@@ -0,0 +1,115 @@
+/***************************************************************************
+ * Copyright (C) 2008 by Ilya Kotov *
+ * forkotov02@hotmail.ru *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <QIODevice>
+#include <QSettings>
+#include <QByteArray>
+#include <QBuffer>
+#include <QTextCodec>
+#include <QSettings>
+#include <QDir>
+#include <stdlib.h>
+
+#include "tagextractor.h"
+
+TagExtractor::TagExtractor(QIODevice *d)
+{
+ m_d = d;
+}
+
+
+TagExtractor::~TagExtractor()
+{
+}
+
+const QMap<Qmmp::MetaData, QString> TagExtractor::id3v2tag()
+{
+ QByteArray array = m_d->peek(2048);
+ int offset = array.indexOf("ID3");
+ if (offset < 0)
+ return m_tag;
+ ID3v2Tag taglib_tag(&array, offset);
+ if (taglib_tag.isEmpty())
+ return m_tag;
+
+ TagLib::String album = taglib_tag.album();
+ TagLib::String artist = taglib_tag.artist();
+ TagLib::String comment = taglib_tag.comment();
+ TagLib::String genre = taglib_tag.genre();
+ TagLib::String title = taglib_tag.title();
+
+ QSettings settings(QDir::homePath()+"/.qmmp/qmmprc", QSettings::IniFormat);
+ settings.beginGroup("MAD");
+ QByteArray name = settings.value("ID3v2_encoding","UTF-8").toByteArray ();
+ bool utf = FALSE;
+ QTextCodec *codec = 0;
+ if (name.contains("UTF"))
+ {
+ codec = QTextCodec::codecForName ("UTF-8");
+ utf = TRUE;
+ }
+ else
+ codec = QTextCodec::codecForName(name);
+ settings.endGroup();
+
+ if (!codec)
+ codec = QTextCodec::codecForName ("UTF-8");
+
+ m_tag.insert(Qmmp::ALBUM,
+ codec->toUnicode(album.toCString(utf)).trimmed());
+ m_tag.insert(Qmmp::ARTIST,
+ codec->toUnicode(artist.toCString(utf)).trimmed());
+ m_tag.insert(Qmmp::COMMENT,
+ codec->toUnicode(comment.toCString(utf)).trimmed());
+ m_tag.insert(Qmmp::GENRE,
+ codec->toUnicode(genre.toCString(utf)).trimmed());
+ m_tag.insert(Qmmp::TITLE,
+ codec->toUnicode(title.toCString(utf)).trimmed());
+ m_tag.insert(Qmmp::YEAR,
+ QString::number(taglib_tag.year()));
+ m_tag.insert(Qmmp::TRACK,
+ QString::number(taglib_tag.track()));
+
+ return m_tag;
+
+}
+
+ID3v2Tag::ID3v2Tag(QByteArray *array, long offset) : TagLib::ID3v2::Tag()
+{
+ m_buf = new QBuffer(array);
+ m_buf->open(QIODevice::ReadOnly);
+ m_offset = offset;
+ read();
+}
+
+void ID3v2Tag::read ()
+{
+ m_buf->seek(m_offset);
+ uint to_read = TagLib::ID3v2::Header::size();
+ if (to_read > 2048 - uint(m_offset))
+ return;
+ header()->setData(TagLib::ByteVector(m_buf->read(to_read).data(), to_read));
+ to_read = header()->tagSize();
+ if (!to_read || 2048 < m_offset + TagLib::ID3v2::Header::size())
+ return;
+ QByteArray array = m_buf->read(to_read);
+ TagLib::ByteVector v(array.data(), array.size());
+ parse(v);
+}
diff --git a/src/plugins/Input/aac/tagextractor.h b/src/plugins/Input/aac/tagextractor.h
new file mode 100644
index 000000000..707719535
--- /dev/null
+++ b/src/plugins/Input/aac/tagextractor.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ * Copyright (C) 2008 by Ilya Kotov *
+ * forkotov02@hotmail.ru *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef TAGEXTRACTOR_H
+#define TAGEXTRACTOR_H
+
+#include <QMap>
+
+#include <taglib/tag.h>
+#include <taglib/fileref.h>
+#include <taglib/id3v1tag.h>
+#include <taglib/id3v2tag.h>
+#include <taglib/id3v2header.h>
+
+#include <qmmp/qmmp.h>
+
+class QIODevice;
+class QBuffer;
+class QByteArray;
+
+/**
+ @author Ilya Kotov <forkotov02@hotmail.ru>
+*/
+class TagExtractor
+{
+public:
+ TagExtractor(QIODevice *d);
+
+ ~TagExtractor();
+
+ const QMap<Qmmp::MetaData, QString> id3v2tag();
+
+private:
+ QMap<Qmmp::MetaData, QString> m_tag;
+ QIODevice *m_d;
+
+};
+
+class ID3v2Tag : public TagLib::ID3v2::Tag
+{
+public:
+ ID3v2Tag(QByteArray *array, long offset);
+
+protected:
+ void read ();
+
+private:
+ QBuffer *m_buf;
+ long m_offset;
+};
+
+#endif