diff options
| -rw-r--r-- | lib/decoder.cpp | 6 | ||||
| -rw-r--r-- | lib/decoder.h | 46 | ||||
| -rw-r--r-- | lib/filetag.cpp (renamed from lib/qmmp/Input/vorbis/tag.cpp) | 93 | ||||
| -rw-r--r-- | lib/filetag.h | 54 | ||||
| -rw-r--r-- | lib/lib.pro | 3 | ||||
| -rw-r--r-- | lib/qmmp/Input/vorbis/decoder_vorbis.cpp | 51 | ||||
| -rw-r--r-- | lib/qmmp/Input/vorbis/decoder_vorbis.h | 2 | ||||
| -rw-r--r-- | lib/qmmp/Input/vorbis/decodervorbisfactory.cpp | 31 | ||||
| -rw-r--r-- | lib/qmmp/Input/vorbis/tag.h | 61 | ||||
| -rw-r--r-- | lib/qmmp/Input/vorbis/vorbis.pro | 6 |
10 files changed, 209 insertions, 144 deletions
diff --git a/lib/decoder.cpp b/lib/decoder.cpp index e1223c0c8..02983d78b 100644 --- a/lib/decoder.cpp +++ b/lib/decoder.cpp @@ -277,6 +277,11 @@ void Decoder::dispatch(DecoderState::Type st) emit stateChanged(DecoderState(st)); } +void Decoder::dispatch(const FileTag &tag) +{ + emit stateChanged(DecoderState(tag)); +} + void Decoder::error(const QString &e) { emit stateChanged(DecoderState(e)); @@ -322,4 +327,3 @@ void Decoder::setEQ(int bands[10], int preamp) set_gain(i,1, 0.03*value+0.000999999*value*value); } } - diff --git a/lib/decoder.h b/lib/decoder.h index 2246b706f..0aa1f7a5d 100644 --- a/lib/decoder.h +++ b/lib/decoder.h @@ -32,26 +32,45 @@ class Visualization; class DecoderState { public: - enum Type { Decoding, Stopped, Finished, Error }; + enum Type { Decoding, Stopped, Finished, Info, Error }; + + DecoderState(const DecoderState &st) + : m_error_msg(0), m_tag(0) + { + m_type = st.type(); + if (m_type == Info) + m_tag = new FileTag(*st.tag()); + if (m_type == Error) + m_error_msg = new QString(*st.errorMessage()); + } + DecoderState(Type t) - : m_type(t), m_error_msg(0) + : m_type(t), m_error_msg(0), m_tag(0) {} DecoderState(const QString &e) - : m_type(Error) + : m_type(Error), m_tag(0) { m_error_msg = new QString(e); } DecoderState() - : m_type(Stopped), m_error_msg(0) + : m_type(Stopped), m_error_msg(0), m_tag(0) {} + DecoderState(const FileTag &tag) + : m_type(Info), m_error_msg(0), m_tag(0) + { + m_tag = new FileTag(tag); + } + ~DecoderState() { if (m_error_msg) - delete m_error_msg; + delete m_error_msg; + if (m_tag) + delete m_tag; } const QString *errorMessage() const @@ -62,20 +81,25 @@ public: { return m_type; } + const FileTag *tag() const + { + return m_tag; + } private: Type m_type; const QString *m_error_msg; + FileTag *m_tag; }; class Decoder : public QThread { -Q_OBJECT + Q_OBJECT public: - Decoder(QObject *parent, DecoderFactory *d, - QIODevice *i, Output *o); + Decoder(QObject *parent, DecoderFactory *d, + QIODevice *i, Output *o); virtual ~Decoder(); // Standard Decoder API @@ -118,7 +142,10 @@ public: } ulong produceSound(char *data, ulong output_bytes, ulong bitrate, int nch); void setEQ(int bands[10], int preamp); - void setEQEnabled(bool on) { m_useEQ = on; }; + void setEQEnabled(bool on) + { + m_useEQ = on; + }; // static methods static QStringList all(); @@ -140,6 +167,7 @@ signals: protected: void dispatch(DecoderState::Type); void dispatch(const DecoderState&); + void dispatch(const FileTag&); void error(const QString&); private: diff --git a/lib/qmmp/Input/vorbis/tag.cpp b/lib/filetag.cpp index 8f7e28caa..3ce3b505a 100644 --- a/lib/qmmp/Input/vorbis/tag.cpp +++ b/lib/filetag.cpp @@ -17,81 +17,84 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#include "tag.h" +#include "filetag.h" -Tag::Tag(const QString &source) - : FileTag() -{ - m_length = 0; - m_year = 0; - m_track = 0; - m_empty = TRUE; - TagLib::FileRef fileRef(source.toLocal8Bit ()); +FileTag::FileTag() +{} - m_tag = fileRef.tag(); - if(m_tag && !m_tag->isEmpty()) - { - m_album = QString::fromUtf8(m_tag->album().toCString(TRUE)).trimmed(); - m_artist = QString::fromUtf8(m_tag->artist().toCString(TRUE)).trimmed(); - m_comment = QString::fromUtf8(m_tag->comment().toCString(TRUE)).trimmed(); - m_genre = QString::fromUtf8(m_tag->genre().toCString(TRUE)).trimmed(); - m_title = QString::fromUtf8(m_tag->title().toCString(TRUE)).trimmed(); - m_year = 0; - m_track = 0; - m_empty = FALSE; - } - else - m_tag = 0; - if(fileRef.audioProperties()) - m_length = fileRef.audioProperties()->length(); +FileTag::FileTag(const FileTag &other) +{ + *this = other; } - -Tag::~Tag() +FileTag::~FileTag() {} +void FileTag::operator=(const FileTag &tag) +{ + setValue(TITLE,tag.title ()); + setValue(ARTIST,tag.artist ()); + setValue(ALBUM,tag.album ()); + setValue(COMMENT,tag.comment ()); + setValue(GENRE,tag.genre ()); + setValue(YEAR,tag.year ()); + setValue(TRACK,tag.track ()); + setValue(LENGTH,tag.length ()); +} + +void FileTag::setValue(uint name, const QString &value) +{ + if (!value.isEmpty()) + m_strValues.insert (name, value); +} + +void FileTag::setValue(uint name, const uint &value) +{ + if (value > 0) + m_numValues.insert (name, value); +} -bool Tag::isEmpty() +const QString FileTag::title () const { - return m_empty; + return m_strValues[TITLE]; } -QString Tag::album() +const QString FileTag::artist () const { - return m_album; + return m_strValues[ARTIST]; } -QString Tag::artist() +const QString FileTag::album () const { - return m_artist; + return m_strValues[ALBUM]; } -QString Tag::comment() +const QString FileTag::comment () const { - return m_comment; + return m_strValues[COMMENT]; } -QString Tag::genre() +const QString FileTag::genre () const { - return m_genre; + return m_strValues[GENRE]; } -QString Tag::title() +const uint FileTag::year () const { - return m_title; + return m_numValues[YEAR]; } -uint Tag::length() +const uint FileTag::track () const { - return m_length; + return m_numValues[TRACK]; } -uint Tag::track() +const uint FileTag::length () const { - return m_track; + return m_numValues[LENGTH]; } -uint Tag::year() +const bool FileTag::isEmpty () const { - return m_year; + return m_strValues.isEmpty(); } diff --git a/lib/filetag.h b/lib/filetag.h index 80383c2ab..c2d36a842 100644 --- a/lib/filetag.h +++ b/lib/filetag.h @@ -1,6 +1,6 @@ /*************************************************************************** - * Copyright (C) 2006 by Ilya Kotov * - * forkotov02@hotmail.ru * + * Copyright (C) 2006 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 * @@ -20,24 +20,48 @@ #ifndef FILETAG_H #define FILETAG_H - #include <QString> +#include <QMap> +/** + @author Ilya Kotov <forkotov02@hotmail.ru> +*/ class FileTag { public: - FileTag() {}; - - virtual ~FileTag() {}; - virtual QString title () = 0; - virtual QString artist () = 0; - virtual QString album () = 0; - virtual QString comment () = 0 ; - virtual QString genre () = 0; - virtual uint year () = 0; - virtual uint track () = 0; - virtual uint length () = 0; - virtual bool isEmpty () = 0; + FileTag(); + FileTag(const FileTag &other); + + ~FileTag(); + + enum Type + { + TITLE = 0, + ARTIST, + ALBUM, + COMMENT, + GENRE, + YEAR, + TRACK, + LENGTH + }; + + void operator=(const FileTag &tag); + void setValue(uint name, const QString &value); + void setValue(uint name, const uint &value); + const QString title () const; + const QString artist () const; + const QString album () const; + const QString comment () const; + const QString genre () const; + const uint year () const; + const uint track () const; + const uint length () const; + const bool isEmpty () const; + +private: + QMap <uint, QString> m_strValues; + QMap <uint, uint> m_numValues; }; diff --git a/lib/lib.pro b/lib/lib.pro index 3ae6892c1..152c548e6 100644 --- a/lib/lib.pro +++ b/lib/lib.pro @@ -26,7 +26,8 @@ SOURCES += recycler.cpp \ equ\iir_fpu.c \ soundcore.cpp \ streamreader.cpp \ - downloader.cpp + downloader.cpp \ + filetag.cpp TARGET = qmmp CONFIG += release \ diff --git a/lib/qmmp/Input/vorbis/decoder_vorbis.cpp b/lib/qmmp/Input/vorbis/decoder_vorbis.cpp index 5f795d59b..7e421f2fe 100644 --- a/lib/qmmp/Input/vorbis/decoder_vorbis.cpp +++ b/lib/qmmp/Input/vorbis/decoder_vorbis.cpp @@ -9,6 +9,7 @@ #include "buffer.h" #include "output.h" #include "recycler.h" +#include "filetag.h" #include <QObject> #include <QIODevice> @@ -192,7 +193,7 @@ bool DecoderVorbis::initialize() if (! input()->open(QIODevice::ReadOnly)) { qWarning(qPrintable("DecoderVorbis: failed to open input. " + - input()->errorString () + ".")); + input()->errorString () + ".")); return FALSE; } } @@ -250,7 +251,7 @@ void DecoderVorbis::seek(double pos) void DecoderVorbis::deinit() { - if(inited) + if (inited) ov_clear(&oggfile); inited = user_stop = done = finish = FALSE; len = freq = bitrate = 0; @@ -258,6 +259,43 @@ void DecoderVorbis::deinit() output_size = 0; } +void DecoderVorbis::updateTags() +{ + int i; + vorbis_comment *comments; + + FileTag tag; + //TODO add all tags + comments = ov_comment (&oggfile, -1); + for (i = 0; i < comments->comments; i++) + { + if (!strncasecmp(comments->user_comments[i], "title=", + strlen ("title="))) + tag.setValue(FileTag::TITLE, QString::fromUtf8(comments->user_comments[i] + + strlen ("title="))); + else if (!strncasecmp(comments->user_comments[i], + "artist=", strlen ("artist="))) + tag.setValue(FileTag::TITLE, + QString::fromUtf8(comments->user_comments[i] + + strlen ("artist="))); + else if (!strncasecmp(comments->user_comments[i], + "album=", strlen ("album="))) + tag.setValue(FileTag::ALBUM, + QString::fromUtf8(comments->user_comments[i] + + strlen ("album="))); + else if (!strncasecmp(comments->user_comments[i], + "tracknumber=", + strlen ("tracknumber="))) + tag.setValue(FileTag::TRACK, atoi (comments->user_comments[i] + + strlen ("tracknumber="))); + else if (!strncasecmp(comments->user_comments[i], + "track=", strlen ("track="))) + tag.setValue(FileTag::TRACK, atoi (comments->user_comments[i] + + strlen ("track="))); + } + dispatch(tag); +} + void DecoderVorbis::run() { mutex()->lock (); @@ -283,6 +321,7 @@ void DecoderVorbis::run() } int section = 0; + int last_section = -1; while (! done && ! finish) { @@ -297,11 +336,15 @@ void DecoderVorbis::run() output_size = long(ov_time_tell(&oggfile)) * long(freq * chan * 2); } len = -1; - while(len < 0) + while (len < 0) { len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 0, 2, 1, - §ion); + §ion); } + if (section != last_section) + updateTags(); + last_section = section; + if (len > 0) { bitrate = ov_bitrate_instant(&oggfile) / 1000; diff --git a/lib/qmmp/Input/vorbis/decoder_vorbis.h b/lib/qmmp/Input/vorbis/decoder_vorbis.h index 12a5de118..091d856ff 100644 --- a/lib/qmmp/Input/vorbis/decoder_vorbis.h +++ b/lib/qmmp/Input/vorbis/decoder_vorbis.h @@ -39,6 +39,8 @@ private: void flush(bool = FALSE); void deinit(); + void updateTags(); + bool inited, user_stop; int stat; diff --git a/lib/qmmp/Input/vorbis/decodervorbisfactory.cpp b/lib/qmmp/Input/vorbis/decodervorbisfactory.cpp index 8f4458845..53f173631 100644 --- a/lib/qmmp/Input/vorbis/decodervorbisfactory.cpp +++ b/lib/qmmp/Input/vorbis/decodervorbisfactory.cpp @@ -1,10 +1,10 @@ #include <QtGui> #include <taglib/tag.h> #include <taglib/fileref.h> +#include <tag.h> #include "detailsdialog.h" #include "decoder_vorbis.h" -#include "tag.h" #include "decodervorbisfactory.h" @@ -38,15 +38,38 @@ const DecoderProperties DecoderVorbisFactory::properties() const } Decoder *DecoderVorbisFactory::create(QObject *parent, QIODevice *input, - Output *output) + Output *output) { return new DecoderVorbis(parent, this, input, output); } FileTag *DecoderVorbisFactory::createTag(const QString &source) { - FileTag *tag = new Tag(source); - return tag; + FileTag *ftag = new FileTag(); + + TagLib::FileRef fileRef(source.toLocal8Bit ()); + TagLib::Tag *tag = fileRef.tag(); + + if (tag && !tag->isEmpty()) + { + ftag->setValue(FileTag::ALBUM, + QString::fromUtf8(tag->album().toCString(TRUE)).trimmed()); + ftag->setValue(FileTag::ARTIST, + QString::fromUtf8(tag->artist().toCString(TRUE)).trimmed()); + ftag->setValue(FileTag::COMMENT, + QString::fromUtf8(tag->comment().toCString(TRUE)).trimmed()); + ftag->setValue(FileTag::GENRE, + QString::fromUtf8(tag->genre().toCString(TRUE)).trimmed()); + ftag->setValue(FileTag::TITLE, + QString::fromUtf8(tag->title().toCString(TRUE)).trimmed()); + //year - ?; + //track - ?; + } + + if (fileRef.audioProperties()) + ftag->setValue(FileTag::LENGTH, fileRef.audioProperties()->length()); + + return ftag; } void DecoderVorbisFactory::showDetails(QWidget *parent, const QString &path) diff --git a/lib/qmmp/Input/vorbis/tag.h b/lib/qmmp/Input/vorbis/tag.h deleted file mode 100644 index ece3b7d2c..000000000 --- a/lib/qmmp/Input/vorbis/tag.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 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 XIPHCOMMENT_H -#define XIPHCOMMENT_H - -#include <taglib/tag.h> -#include <taglib/fileref.h> - -#include <filetag.h> - -/** - @author Ilya Kotov <forkotov02@hotmail.ru> -*/ -class Tag : public FileTag -{ -public: - Tag(const QString &source); - - ~Tag(); - - virtual QString album(); - virtual QString artist(); - virtual QString comment(); - virtual QString genre(); - virtual QString title(); - virtual uint length(); - virtual uint track(); - virtual uint year(); - virtual bool isEmpty(); - -private: - TagLib::Tag *m_tag; - QString m_album; - QString m_artist; - QString m_comment; - QString m_genre; - QString m_title; - uint m_length; - uint m_year; - uint m_track; - bool m_empty; -}; - -#endif diff --git a/lib/qmmp/Input/vorbis/vorbis.pro b/lib/qmmp/Input/vorbis/vorbis.pro index ce3ee72a6..ada5a9ecb 100644 --- a/lib/qmmp/Input/vorbis/vorbis.pro +++ b/lib/qmmp/Input/vorbis/vorbis.pro @@ -6,12 +6,10 @@ FORMS += detailsdialog.ui HEADERS += decodervorbisfactory.h \ decoder_vorbis.h \ - detailsdialog.h \ - tag.h + detailsdialog.h SOURCES += decoder_vorbis.cpp \ decodervorbisfactory.cpp \ - detailsdialog.cpp \ - tag.cpp + detailsdialog.cpp DESTDIR = ../ QMAKE_CLEAN += ../libvorbis.so INCLUDEPATH += ../../../ |
