aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Input/vorbis
diff options
context:
space:
mode:
authorvovanec <vovanec@90c681e8-e032-0410-971d-27865f9a5e38>2008-02-07 13:36:34 +0000
committervovanec <vovanec@90c681e8-e032-0410-971d-27865f9a5e38>2008-02-07 13:36:34 +0000
commit06d1877811fa6aa97dddc0e03bcde4e766928c87 (patch)
treec25462d0e58c3d58c728664440412bf4f16a49ec /src/plugins/Input/vorbis
parent3f6b60f23c44a8ba8dd97ca6f41a16e2af7ef2f7 (diff)
downloadqmmp-06d1877811fa6aa97dddc0e03bcde4e766928c87.tar.gz
qmmp-06d1877811fa6aa97dddc0e03bcde4e766928c87.tar.bz2
qmmp-06d1877811fa6aa97dddc0e03bcde4e766928c87.zip
new directory structure
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@232 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src/plugins/Input/vorbis')
-rw-r--r--src/plugins/Input/vorbis/CMakeLists.txt96
-rw-r--r--src/plugins/Input/vorbis/decoder_vorbis.cpp425
-rw-r--r--src/plugins/Input/vorbis/decoder_vorbis.h63
-rw-r--r--src/plugins/Input/vorbis/decodervorbisfactory.cpp105
-rw-r--r--src/plugins/Input/vorbis/decodervorbisfactory.h54
-rw-r--r--src/plugins/Input/vorbis/detailsdialog.cpp120
-rw-r--r--src/plugins/Input/vorbis/detailsdialog.h49
-rw-r--r--src/plugins/Input/vorbis/detailsdialog.ui384
-rw-r--r--src/plugins/Input/vorbis/translations/translations.qrc6
-rw-r--r--src/plugins/Input/vorbis/translations/vorbis_plugin_ru.qmbin0 -> 2569 bytes
-rw-r--r--src/plugins/Input/vorbis/translations/vorbis_plugin_ru.ts164
-rw-r--r--src/plugins/Input/vorbis/vorbis.pro35
12 files changed, 1501 insertions, 0 deletions
diff --git a/src/plugins/Input/vorbis/CMakeLists.txt b/src/plugins/Input/vorbis/CMakeLists.txt
new file mode 100644
index 000000000..baf5bad8c
--- /dev/null
+++ b/src/plugins/Input/vorbis/CMakeLists.txt
@@ -0,0 +1,96 @@
+project(libvorbis)
+
+cmake_minimum_required(VERSION 2.4.0)
+
+
+INCLUDE(UsePkgConfig)
+INCLUDE(FindQt4)
+
+find_package(Qt4 REQUIRED) # find and setup Qt4 for this project
+include(${QT_USE_FILE})
+
+# qt plugin
+ADD_DEFINITIONS( -Wall )
+ADD_DEFINITIONS(${QT_DEFINITIONS})
+ADD_DEFINITIONS(-DQT_PLUGIN)
+ADD_DEFINITIONS(-DQT_NO_DEBUG)
+ADD_DEFINITIONS(-DQT_SHARED)
+ADD_DEFINITIONS(-DQT_THREAD)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+SET(QT_INCLUDES
+ ${QT_INCLUDES}
+ ${CMAKE_CURRENT_BINARY_DIR}/../../../
+)
+
+# libqmmp
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../)
+link_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../)
+
+# libvorbis and taglib
+PKGCONFIG(ogg OGG_INCLUDE_DIR OGG_LINK_DIR OGG_LINK_FLAGS OGG_CFLAGS)
+PKGCONFIG(vorbis VORBIS_INCLUDE_DIR VORBIS_LINK_DIR VORBIS_LINK_FLAGS VORBIS_CFLAGS)
+PKGCONFIG(vorbisfile VORBISFILE_INCLUDE_DIR VORBISFILE_LINK_DIR VORBISFILE_LINK_FLAGS VORBISFILE_CFLAGS)
+
+PKGCONFIG(taglib TAGLIB_INCLUDE_DIR TAGLIB_LINK_DIR TAGLIB_LINK_FLAGS TAGLIB_CFLAGS)
+
+IF(NOT OGG_LINK_FLAGS)
+ SET(OGG_LINK_FLAGS -logg)
+ENDIF(NOT OGG_LINK_FLAGS)
+
+IF(NOT VORBIS_LINK_FLAGS)
+ SET(VORBIS_LINK_FLAGS -lvorbis)
+ENDIF(NOT VORBIS_LINK_FLAGS)
+
+IF(NOT VORBISFILE_LINK_FLAGS)
+ SET(VORBISFILE_LINK_FLAGS -lvorbisfile)
+ENDIF(NOT VORBISFILE_LINK_FLAGS)
+
+IF(NOT TAGLIB_LINK_FLAGS)
+ SET(TAGLIB_LINK_FLAGS -ltag)
+ SET(TAGLIB_INCLUDE_DIR /usr/include/taglib)
+ SET(TAGLIB_CFLAGS -I/usr/include/taglib)
+ENDIF(NOT TAGLIB_LINK_FLAGS)
+
+include_directories(${VORBIS_INCLUDE_DIR} ${TAGLIB_INCLUDE_DIR})
+link_directories(${VORBIS_LINK_DIR} ${TAGLIB_LINK_DIR})
+
+#ADD_DEFINITIONS(${VORBIS_CFLAGS})
+ADD_DEFINITIONS(${TAGLIB_CFLAGS})
+
+
+SET(libvorbis_SRCS
+ decoder_vorbis.cpp
+ decodervorbisfactory.cpp
+ detailsdialog.cpp
+)
+
+SET(libvorbis_MOC_HDRS
+ decodervorbisfactory.h
+ decoder_vorbis.h
+ detailsdialog.h
+)
+
+SET(libvorbis_RCCS translations/translations.qrc)
+
+QT4_ADD_RESOURCES(libvorbis_RCC_SRCS ${libvorbis_RCCS})
+
+QT4_WRAP_CPP(libvorbis_MOC_SRCS ${libvorbis_MOC_HDRS})
+
+# user interface
+
+
+SET(libvorbis_UIS
+ detailsdialog.ui
+)
+
+QT4_WRAP_UI(libvorbis_UIS_H ${libvorbis_UIS})
+# Don't forget to include output directory, otherwise
+# the UI file won't be wrapped!
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+ADD_LIBRARY(vorbis SHARED ${libvorbis_SRCS} ${libvorbis_MOC_SRCS} ${libvorbis_UIS_H}
+ ${libvorbis_RCC_SRCS})
+target_link_libraries(vorbis ${QT_LIBRARIES} -lqmmp ${VORBIS_LINK_FLAGS} ${VORBISFILE_LINK_FLAGS} ${OGG_LINK_FLAGS} ${TAGLIB_LINK_FLAGS} ${TAGLIB_CFLAGS})
+install(TARGETS vorbis DESTINATION ${LIB_DIR}/qmmp/Input PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ)
diff --git a/src/plugins/Input/vorbis/decoder_vorbis.cpp b/src/plugins/Input/vorbis/decoder_vorbis.cpp
new file mode 100644
index 000000000..31fb99c6f
--- /dev/null
+++ b/src/plugins/Input/vorbis/decoder_vorbis.cpp
@@ -0,0 +1,425 @@
+// Copyright (c) 2000-2001 Brad Hughes <bhughes@trolltech.com>
+//
+// Use, modification and distribution is allowed without limitation,
+// warranty, or liability of any kind.
+//
+
+#include "decoder_vorbis.h"
+#include "constants.h"
+#include "buffer.h"
+#include "output.h"
+#include "recycler.h"
+#include "filetag.h"
+
+#include <QObject>
+#include <QIODevice>
+
+
+// ic functions for OggVorbis
+
+static size_t oggread (void *buf, size_t size, size_t nmemb, void *src)
+{
+ if (! src) return 0;
+
+ DecoderVorbis *dogg = (DecoderVorbis *) src;
+ int len = dogg->input()->read((char *) buf, (size * nmemb));
+ return len / size;
+}
+
+
+static int oggseek(void *src, int64_t offset, int whence)
+{
+ DecoderVorbis *dogg = (DecoderVorbis *) src;
+
+ if ( dogg->input()->isSequential ())
+ return -1;
+
+ long start = 0;
+ switch (whence)
+ {
+ case SEEK_END:
+ start = dogg->input()->size();
+ break;
+
+ case SEEK_CUR:
+ start = dogg->input()->pos();
+ break;
+
+ case SEEK_SET:
+ default:
+ start = 0;
+ }
+
+ if (dogg->input()->seek(start + offset))
+ return 0;
+ return -1;
+}
+
+
+static int oggclose(void *src)
+{
+ DecoderVorbis *dogg = (DecoderVorbis *) src;
+ dogg->input()->close();
+ return 0;
+}
+
+
+static long oggtell(void *src)
+{
+ DecoderVorbis *dogg = (DecoderVorbis *) src;
+ long t = dogg->input()->pos();
+ return t;
+}
+
+
+// Decoder class
+
+DecoderVorbis::DecoderVorbis(QObject *parent, DecoderFactory *d, QIODevice *i, Output *o)
+ : Decoder(parent, d, i, o)
+{
+ inited = FALSE;
+ user_stop = FALSE;
+ stat = 0;
+ output_buf = 0;
+ output_bytes = 0;
+ output_at = 0;
+ bks = 0;
+ done = FALSE;
+ finish = FALSE;
+ len = 0;
+ freq = 0;
+ bitrate = 0;
+ seekTime = -1.0;
+ totalTime = 0.0;
+ chan = 0;
+ output_size = 0;
+}
+
+
+DecoderVorbis::~DecoderVorbis()
+{
+ deinit();
+
+ if (output_buf)
+ delete [] output_buf;
+ output_buf = 0;
+}
+
+
+void DecoderVorbis::stop()
+{
+ user_stop = TRUE;
+}
+
+
+void DecoderVorbis::flush(bool final)
+{
+ ulong min = final ? 0 : bks;
+
+ while ((! done && ! finish) && output_bytes > min)
+ {
+ output()->recycler()->mutex()->lock ();
+
+ while ((! done && ! finish) && output()->recycler()->full())
+ {
+ mutex()->unlock();
+
+ output()->recycler()->cond()->wait(output()->recycler()->mutex());
+
+ mutex()->lock ();
+ done = user_stop;
+ }
+
+ if (user_stop || finish)
+ {
+ inited = FALSE;
+ done = TRUE;
+ }
+ else
+ {
+ /*ulong sz = output_bytes < bks ? output_bytes : bks;
+ Buffer *b = output()->recycler()->get();
+
+ memcpy(b->data, output_buf, sz);
+ if (sz != bks) memset(b->data + sz, 0, bks - sz);
+
+ b->nbytes = bks;
+ b->rate = bitrate;
+ output_size += b->nbytes;
+ output()->recycler()->add();
+
+ output_bytes -= sz;
+ memmove(output_buf, output_buf + sz, output_bytes);*/
+ output_bytes -= produceSound(output_buf, output_bytes, bitrate, chan);
+ output_size += bks;
+ output_at = output_bytes;
+ }
+
+ if (output()->recycler()->full())
+ {
+ output()->recycler()->cond()->wakeOne();
+ }
+
+ output()->recycler()->mutex()->unlock();
+ }
+}
+
+
+bool DecoderVorbis::initialize()
+{
+ qDebug("DecoderVorbis: initialize");
+ bks = blockSize();
+
+ inited = user_stop = done = finish = FALSE;
+ len = freq = bitrate = 0;
+ stat = chan = 0;
+ output_size = 0;
+ seekTime = -1.0;
+ totalTime = 0.0;
+ if (! input())
+ {
+ qDebug("DecoderVorbis: cannot initialize. No input");
+
+ return FALSE;
+ }
+
+ if (! output_buf)
+ output_buf = new char[globalBufferSize];
+ output_at = 0;
+ output_bytes = 0;
+
+ if (! input()->isOpen())
+ {
+ if (! input()->open(QIODevice::ReadOnly))
+ {
+ qWarning(qPrintable("DecoderVorbis: failed to open input. " +
+ input()->errorString () + "."));
+ return FALSE;
+ }
+ }
+
+ ov_callbacks oggcb =
+ {
+ oggread,
+ oggseek,
+ oggclose,
+ oggtell
+ };
+ if (ov_open_callbacks(this, &oggfile, NULL, 0, oggcb) < 0)
+ {
+ qWarning("DecoderVorbis: cannot open stream");
+
+ return FALSE;
+ }
+
+ freq = 0;
+ bitrate = ov_bitrate(&oggfile, -1) / 1000;
+ chan = 0;
+
+ totalTime = long(ov_time_total(&oggfile, 0));
+ totalTime = totalTime < 0 ? 0 : totalTime;
+
+ vorbis_info *ogginfo = ov_info(&oggfile, -1);
+ if (ogginfo)
+ {
+ freq = ogginfo->rate;
+ chan = ogginfo->channels;
+ }
+
+ configure(freq, chan, 16, bitrate);
+
+ inited = TRUE;
+ return TRUE;
+}
+
+
+double DecoderVorbis::lengthInSeconds()
+{
+ if (! inited)
+ return 0;
+
+ return totalTime;
+}
+
+
+void DecoderVorbis::seek(double pos)
+{
+ seekTime = pos;
+}
+
+
+void DecoderVorbis::deinit()
+{
+ if (inited)
+ ov_clear(&oggfile);
+ inited = user_stop = done = finish = FALSE;
+ len = freq = bitrate = 0;
+ stat = chan = 0;
+ output_size = 0;
+}
+
+void DecoderVorbis::updateTags()
+{
+ int i;
+ vorbis_comment *comments;
+
+ FileTag tag;
+ 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::ARTIST,
+ 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],
+ "comment=", strlen ("comment=")))
+ tag.setValue(FileTag::COMMENT,
+ QString::fromUtf8(comments->user_comments[i]
+ + strlen ("comment=")));
+ else if (!strncasecmp(comments->user_comments[i],
+ "genre=", strlen ("genre=")))
+ tag.setValue(FileTag::GENRE, QString::fromUtf8 (comments->user_comments[i]
+ + strlen ("genre=")));
+ 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=")));
+ else if (!strncasecmp(comments->user_comments[i],
+ "date=", strlen ("date=")))
+ tag.setValue(FileTag::YEAR, atoi (comments->user_comments[i]
+ + strlen ("date=")));
+
+ }
+ tag.setValue(FileTag::LENGTH, uint(totalTime));
+ dispatch(tag);
+}
+
+void DecoderVorbis::run()
+{
+ mutex()->lock ();
+
+ if (! inited)
+ {
+ mutex()->unlock();
+
+ return;
+ }
+
+ //stat = DecoderEvent::Decoding;
+ stat = DecoderState::Decoding;
+ mutex()->unlock();
+
+ {
+ //DecoderEvent e((DecoderEvent::Type) stat);
+ //dispatch(e);
+ //DecoderStatus st ((DecoderStatus::Type) stat);
+ dispatch(DecoderState ((DecoderState::Type) stat));
+
+ //emit statusChanged(stat);
+ }
+
+ int section = 0;
+ int last_section = -1;
+
+ while (! done && ! finish)
+ {
+ mutex()->lock ();
+ // decode
+
+ if (seekTime >= 0.0)
+ {
+ ov_time_seek(&oggfile, double(seekTime));
+ seekTime = -1.0;
+
+ output_size = long(ov_time_tell(&oggfile)) * long(freq * chan * 2);
+ }
+ len = -1;
+ while (len < 0)
+ {
+ len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 0, 2, 1,
+ &section);
+ }
+ if (section != last_section)
+ updateTags();
+ last_section = section;
+
+ if (len > 0)
+ {
+ bitrate = ov_bitrate_instant(&oggfile) / 1000;
+
+ output_at += len;
+ output_bytes += len;
+
+ if (output())
+ flush();
+ }
+ else if (len == 0)
+ {
+ flush(TRUE);
+
+ if (output())
+ {
+ output()->recycler()->mutex()->lock ();
+ // end of stream
+ while (! output()->recycler()->empty() && ! user_stop)
+ {
+ output()->recycler()->cond()->wakeOne();
+ mutex()->unlock();
+ output()->recycler()->cond()->wait(output()->recycler()->mutex());
+ mutex()->lock ();
+ }
+ output()->recycler()->mutex()->unlock();
+ }
+
+ done = TRUE;
+ if (! user_stop)
+ {
+ finish = TRUE;
+ }
+ }
+ else
+ {
+ // error in read
+ error("DecoderVorbis: Error while decoding stream, File appears to be "
+ "corrupted");
+
+ finish = TRUE;
+ }
+
+ mutex()->unlock();
+ }
+
+ mutex()->lock ();
+
+ if (finish)
+ stat = DecoderState::Finished;
+ else if (user_stop)
+ stat = DecoderState::Stopped;
+
+ mutex()->unlock();
+
+ {
+ /*DecoderEvent e((DecoderEvent::Type) stat);
+ dispatch(e);*/
+ //DecoderStatus st ((DecoderStatus::Type) stat);
+ //emit statusChanged(st);
+ dispatch(DecoderState ((DecoderState::Type) stat));
+ }
+
+ deinit();
+}
diff --git a/src/plugins/Input/vorbis/decoder_vorbis.h b/src/plugins/Input/vorbis/decoder_vorbis.h
new file mode 100644
index 000000000..091d856ff
--- /dev/null
+++ b/src/plugins/Input/vorbis/decoder_vorbis.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2000-2001 Brad Hughes <bhughes@trolltech.com>
+//
+// Use, modification and distribution is allowed without limitation,
+// warranty, or liability of any kind.
+//
+
+#ifndef __decoder_vorbis_h
+#define __decoder_vorbis_h
+
+#include "decoder.h"
+
+#include <vorbis/vorbisfile.h>
+
+
+class DecoderVorbis : public Decoder
+{
+public:
+ DecoderVorbis(QObject *, DecoderFactory *, QIODevice *, Output *);
+ virtual ~DecoderVorbis();
+
+ // Standard Decoder API
+ bool initialize();
+ double lengthInSeconds();
+ void seek(double);
+ void stop();
+
+ // Equalizer
+ bool isEQSupported() const { return FALSE; }
+ void setEQEnabled(bool) { ; }
+ void setEQGain(int) { ; }
+ void setEQBands(int[10]) { ; }
+
+
+private:
+ // thread run function
+ void run();
+
+ // helper functions
+ void flush(bool = FALSE);
+ void deinit();
+
+ void updateTags();
+
+ bool inited, user_stop;
+ int stat;
+
+ // output buffer
+ char *output_buf;
+ ulong output_bytes, output_at;
+
+ // OggVorbis Decoder
+ OggVorbis_File oggfile;
+
+ unsigned int bks;
+ bool done, finish;
+ long len, freq, bitrate;
+ int chan;
+ unsigned long output_size;
+ double totalTime, seekTime;
+};
+
+
+#endif // __decoder_vorbis_h
diff --git a/src/plugins/Input/vorbis/decodervorbisfactory.cpp b/src/plugins/Input/vorbis/decodervorbisfactory.cpp
new file mode 100644
index 000000000..c3b31ec52
--- /dev/null
+++ b/src/plugins/Input/vorbis/decodervorbisfactory.cpp
@@ -0,0 +1,105 @@
+#include <QtGui>
+#include <taglib/tag.h>
+#include <taglib/fileref.h>
+#include <tag.h>
+
+#include "detailsdialog.h"
+#include "decoder_vorbis.h"
+#include "decodervorbisfactory.h"
+
+
+// DecoderOggFactory
+
+bool DecoderVorbisFactory::supports(const QString &source) const
+{
+ return source.right(4).toLower() == ".ogg";
+}
+
+bool DecoderVorbisFactory::canDecode(QIODevice *input) const
+{
+ char buf[36];
+ if (input->peek(buf, 36) == 36 && !memcmp(buf, "OggS", 4)
+ && !memcmp(buf + 29, "vorbis", 6))
+ return TRUE;
+
+ return FALSE;
+}
+
+const DecoderProperties DecoderVorbisFactory::properties() const
+{
+ DecoderProperties properties;
+ properties.name = tr("Ogg Vorbis Plugin");
+ properties.filter = "*.ogg";
+ properties.description = tr("Ogg Vorbis Files");
+ properties.contentType = "application/ogg;audio/x-vorbis+ogg";
+ properties.hasAbout = TRUE;
+ properties.hasSettings = FALSE;
+ return properties;
+}
+
+Decoder *DecoderVorbisFactory::create(QObject *parent, QIODevice *input,
+ Output *output)
+{
+ return new DecoderVorbis(parent, this, input, output);
+}
+
+FileTag *DecoderVorbisFactory::createTag(const QString &source)
+{
+ 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());
+ ftag->setValue(FileTag::YEAR, tag->year());
+ ftag->setValue(FileTag::TRACK, tag->track());
+ }
+
+ if (fileRef.audioProperties())
+ ftag->setValue(FileTag::LENGTH, fileRef.audioProperties()->length());
+
+ return ftag;
+}
+
+QObject* DecoderVorbisFactory::showDetails(QWidget *parent, const QString &path)
+{
+ DetailsDialog *d = new DetailsDialog(parent, path);
+ d -> show();
+ return d;
+}
+
+void DecoderVorbisFactory::showSettings(QWidget *)
+{
+ /*SettingsDialog *s = new SettingsDialog(parent);
+ s -> show();*/
+}
+
+void DecoderVorbisFactory::showAbout(QWidget *parent)
+{
+ QMessageBox::about (parent, tr("About Ogg Vorbis Audio Plugin"),
+ tr("Qmmp Ogg Vorbis Audio Plugin")+"\n"+
+ tr("Writen by: Ilya Kotov <forkotov02@hotmail.ru>")+"\n"+
+ tr("Source code based on mq3 progect")
+ );
+}
+
+QTranslator *DecoderVorbisFactory::createTranslator(QObject *parent)
+{
+ QTranslator *translator = new QTranslator(parent);
+ QString locale = QLocale::system().name();
+ translator->load(QString(":/vorbis_plugin_") + locale);
+ return translator;
+}
+
+Q_EXPORT_PLUGIN(DecoderVorbisFactory)
diff --git a/src/plugins/Input/vorbis/decodervorbisfactory.h b/src/plugins/Input/vorbis/decodervorbisfactory.h
new file mode 100644
index 000000000..6830fc102
--- /dev/null
+++ b/src/plugins/Input/vorbis/decodervorbisfactory.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * 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 DECODERVORBISFACTORY_H
+#define DECODERVORBISFACTORY_H
+
+#include <QObject>
+#include <QString>
+#include <QIODevice>
+#include <QWidget>
+
+#include <decoder.h>
+#include <output.h>
+#include <decoderfactory.h>
+#include <filetag.h>
+
+
+
+
+class DecoderVorbisFactory : public QObject,
+ DecoderFactory
+{
+Q_OBJECT
+Q_INTERFACES(DecoderFactory);
+
+public:
+ bool supports(const QString &source) const;
+ bool canDecode(QIODevice *input) const;
+ const DecoderProperties properties() const;
+ Decoder *create(QObject *, QIODevice *, Output *);
+ FileTag *createTag(const QString &source);
+ QObject* showDetails(QWidget *parent, const QString &path);
+ void showSettings(QWidget *parent);
+ void showAbout(QWidget *parent);
+ QTranslator *createTranslator(QObject *parent);
+};
+
+#endif
diff --git a/src/plugins/Input/vorbis/detailsdialog.cpp b/src/plugins/Input/vorbis/detailsdialog.cpp
new file mode 100644
index 000000000..bbe441703
--- /dev/null
+++ b/src/plugins/Input/vorbis/detailsdialog.cpp
@@ -0,0 +1,120 @@
+/***************************************************************************
+ * Copyright (C) 2007 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 <taglib/tag.h>
+#include <taglib/fileref.h>
+#include <taglib/vorbisfile.h>
+
+#include <QFile>
+#include <QFileInfo>
+
+#include "detailsdialog.h"
+
+#define QStringToTString_qt4(s) TagLib::String(s.toUtf8().constData(), TagLib::String::UTF8)
+
+DetailsDialog::DetailsDialog(QWidget *parent, const QString &path)
+ : QDialog(parent)
+{
+ ui.setupUi(this);
+ setAttribute(Qt::WA_DeleteOnClose);
+ m_path = path;
+ setWindowTitle (path.section('/',-1));
+ path.section('/',-1);
+ ui.pathLineEdit->setText(m_path);
+ if(QFile::exists(m_path))
+ {
+ loadVorbisInfo();
+ loadTag();
+ }
+}
+
+
+DetailsDialog::~DetailsDialog()
+{}
+
+void DetailsDialog::loadVorbisInfo()
+{
+ TagLib::Ogg::Vorbis::File f (m_path.toLocal8Bit());
+ //l.label
+ //ui. f.audioProperties()->level();
+ QString text;
+ text = QString("%1").arg(f.audioProperties()->length()/60);
+ text +=":"+QString("%1").arg(f.audioProperties()->length()%60,2,10,QChar('0'));
+ ui.lengthLabel->setText(text);
+ text = QString("%1").arg(f.audioProperties()->sampleRate());
+ ui.sampleRateLabel->setText(text+" "+tr("Hz"));
+ text = QString("%1").arg(f.audioProperties()->channels());
+ ui.channelsLabel->setText(text);
+ text = QString("%1").arg(f.audioProperties()->bitrateNominal());
+ ui.nominalLabel->setText(text+" "+tr("kbps"));
+ text = QString("%1").arg(f.audioProperties()->bitrateMaximum());
+ ui.maximumLabel->setText(text+" "+tr("kbps"));
+ text = QString("%1").arg(f.audioProperties()->bitrateMinimum());
+ ui.minimumLabel->setText(text+" "+tr("kbps"));
+ text = QString("%1 "+tr("KB")).arg(f.length()/1024);
+ ui.fileSizeLabel->setText(text);
+
+}
+
+void DetailsDialog::loadTag()
+{
+ TagLib::FileRef f (m_path.toLocal8Bit());
+
+ if (f.tag())
+ { //TODO: load codec name from config
+
+ TagLib::String title = f.tag()->title();
+ TagLib::String artist = f.tag()->artist();
+ TagLib::String album = f.tag()->album();
+ TagLib::String comment = f.tag()->comment();
+ TagLib::String genre = f.tag()->genre();
+ QString string = QString::fromUtf8(title.toCString(TRUE)).trimmed();
+ ui.titleLineEdit->setText(string);
+ string = QString::fromUtf8(artist.toCString(TRUE)).trimmed();
+ ui.artistLineEdit->setText(string);
+ string = QString::fromUtf8(album.toCString(TRUE)).trimmed();
+ ui.albumLineEdit->setText(string);
+ string = QString::fromUtf8(comment.toCString(TRUE)).trimmed();
+ ui.commentLineEdit->setText(string);
+ string = QString("%1").arg(f.tag()->year());
+ ui.yearLineEdit->setText(string);
+ string = QString("%1").arg(f.tag()->track());
+ ui.trackLineEdit->setText(string);
+ string = QString::fromUtf8(genre.toCString(TRUE)).trimmed();
+ ui.genreLineEdit->setText(string);
+ }
+ QFileInfo info(m_path);
+ ui.saveButton->setEnabled(info.isWritable());
+ connect(ui.saveButton, SIGNAL(clicked()), SLOT(saveTag()));
+}
+
+void DetailsDialog::saveTag()
+{
+ TagLib::FileRef f (m_path.toLocal8Bit());
+
+ f.tag()->setTitle(QStringToTString_qt4(ui.titleLineEdit->text()));
+ f.tag()->setArtist(QStringToTString_qt4(ui.artistLineEdit->text()));
+ f.tag()->setAlbum(QStringToTString_qt4(ui.albumLineEdit->text()));
+ f.tag()->setComment(QStringToTString_qt4(ui.commentLineEdit->text()));
+ f.tag()->setGenre(QStringToTString_qt4(ui.genreLineEdit->text()));
+ f.tag()->setYear(ui.yearLineEdit->text().toUInt());
+ f.tag()->setTrack(ui.trackLineEdit->text().toUInt());
+
+ f.save();
+}
diff --git a/src/plugins/Input/vorbis/detailsdialog.h b/src/plugins/Input/vorbis/detailsdialog.h
new file mode 100644
index 000000000..94d4243b8
--- /dev/null
+++ b/src/plugins/Input/vorbis/detailsdialog.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * Copyright (C) 2007 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 DETAILSDIALOG_H
+#define DETAILSDIALOG_H
+
+#include <QDialog>
+
+#include "ui_detailsdialog.h"
+
+/**
+ @author Ilya Kotov <forkotov02@hotmail.ru>
+*/
+class DetailsDialog : public QDialog
+{
+Q_OBJECT
+public:
+ DetailsDialog(QWidget *parent = 0, const QString &path = 0);
+
+ ~DetailsDialog();
+
+private slots:
+ void saveTag();
+
+private:
+ void loadVorbisInfo();
+ void loadTag();
+ Ui::DetailsDialog ui;
+ QString m_path;
+
+};
+
+#endif
diff --git a/src/plugins/Input/vorbis/detailsdialog.ui b/src/plugins/Input/vorbis/detailsdialog.ui
new file mode 100644
index 000000000..1804ab268
--- /dev/null
+++ b/src/plugins/Input/vorbis/detailsdialog.ui
@@ -0,0 +1,384 @@
+<ui version="4.0" >
+ <class>DetailsDialog</class>
+ <widget class="QDialog" name="DetailsDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>536</width>
+ <height>375</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Details</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>8</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item rowspan="2" row="1" column="0" colspan="2" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="minimumSize" >
+ <size>
+ <width>220</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="title" >
+ <string>Ogg Vorbis Info</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>8</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="2" column="1" >
+ <widget class="QLabel" name="fileSizeLabel" >
+ <property name="text" >
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QLabel" name="channelsLabel" >
+ <property name="layoutDirection" >
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text" >
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Length:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="lengthLabel" >
+ <property name="text" >
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Sample rate:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLabel" name="sampleRateLabel" >
+ <property name="text" >
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_10" >
+ <property name="layoutDirection" >
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text" >
+ <string>Channels:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="0" colspan="2" >
+ <widget class="QGroupBox" name="groupBox_3" >
+ <property name="title" >
+ <string>Bit Rate</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignHCenter</set>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>8</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="1" column="1" >
+ <widget class="QLabel" name="maximumLabel" >
+ <property name="text" >
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QLabel" name="minimumLabel" >
+ <property name="text" >
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_9" >
+ <property name="layoutDirection" >
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text" >
+ <string>Minimum:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="nominalLabel" >
+ <property name="text" >
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_8" >
+ <property name="text" >
+ <string>Maximum:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_7" >
+ <property name="text" >
+ <string>Nominal:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>File size:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="3" >
+ <widget class="QLineEdit" name="pathLineEdit" >
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_28" >
+ <property name="text" >
+ <string>File path:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3" >
+ <widget class="QPushButton" name="pushButton_3" >
+ <property name="text" >
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>111</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="2" colspan="2" >
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Ogg Vorbis Tag</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>8</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="6" column="1" colspan="2" >
+ <widget class="QPushButton" name="saveButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Save</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3" >
+ <widget class="QLineEdit" name="trackLineEdit" />
+ </item>
+ <item row="4" column="2" >
+ <widget class="QLabel" name="label_26" >
+ <property name="text" >
+ <string>Track number:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QLineEdit" name="yearLineEdit" />
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="label_25" >
+ <property name="text" >
+ <string>Year:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" >
+ <widget class="QLabel" name="label_27" >
+ <property name="text" >
+ <string>Genre:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_24" >
+ <property name="text" >
+ <string>Comment:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_23" >
+ <property name="text" >
+ <string>Album:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_22" >
+ <property name="text" >
+ <string>Artist:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_21" >
+ <property name="text" >
+ <string>Title:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="3" >
+ <widget class="QLineEdit" name="titleLineEdit" />
+ </item>
+ <item row="1" column="1" colspan="3" >
+ <widget class="QLineEdit" name="artistLineEdit" />
+ </item>
+ <item row="2" column="1" colspan="3" >
+ <widget class="QLineEdit" name="albumLineEdit" />
+ </item>
+ <item row="3" column="1" colspan="3" >
+ <widget class="QLineEdit" name="commentLineEdit" />
+ </item>
+ <item row="5" column="1" colspan="2" >
+ <widget class="QLineEdit" name="genreLineEdit" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>pushButton_3</sender>
+ <signal>clicked()</signal>
+ <receiver>DetailsDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>623</x>
+ <y>353</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>539</x>
+ <y>352</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/plugins/Input/vorbis/translations/translations.qrc b/src/plugins/Input/vorbis/translations/translations.qrc
new file mode 100644
index 000000000..c5cacdfb0
--- /dev/null
+++ b/src/plugins/Input/vorbis/translations/translations.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource>
+ <file>vorbis_plugin_ru.qm</file>
+ </qresource>
+</RCC>
diff --git a/src/plugins/Input/vorbis/translations/vorbis_plugin_ru.qm b/src/plugins/Input/vorbis/translations/vorbis_plugin_ru.qm
new file mode 100644
index 000000000..a6a3a77b7
--- /dev/null
+++ b/src/plugins/Input/vorbis/translations/vorbis_plugin_ru.qm
Binary files differ
diff --git a/src/plugins/Input/vorbis/translations/vorbis_plugin_ru.ts b/src/plugins/Input/vorbis/translations/vorbis_plugin_ru.ts
new file mode 100644
index 000000000..16cf81ea3
--- /dev/null
+++ b/src/plugins/Input/vorbis/translations/vorbis_plugin_ru.ts
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1" language="ru">
+<context>
+ <name>DecoderVorbisFactory</name>
+ <message>
+ <location filename="../decodervorbisfactory.cpp" line="21"/>
+ <source>Ogg Vorbis Plugin</source>
+ <translation>Модуль Ogg Vorbis</translation>
+ </message>
+ <message>
+ <location filename="../decodervorbisfactory.cpp" line="34"/>
+ <source>Ogg Vorbis Files</source>
+ <translation>Файлы Ogg Vorbis</translation>
+ </message>
+ <message>
+ <location filename="../decodervorbisfactory.cpp" line="64"/>
+ <source>About Ogg Vorbis Audio Plugin</source>
+ <translation>Об аудио-модуле Ogg Vorbis</translation>
+ </message>
+ <message>
+ <location filename="../decodervorbisfactory.cpp" line="65"/>
+ <source>Qmmp Ogg Vorbis Audio Plugin</source>
+ <translation>Аудио-модуль Ogg Vorbis для Qmmp</translation>
+ </message>
+ <message>
+ <location filename="../decodervorbisfactory.cpp" line="66"/>
+ <source>Writen by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation>Разработчик: Илья Котов &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+ <message>
+ <location filename="../decodervorbisfactory.cpp" line="68"/>
+ <source>Source code based on mq3 progect</source>
+ <translation>Исходный код основан на проекте mq3</translation>
+ </message>
+</context>
+<context>
+ <name>DetailsDialog</name>
+ <message>
+ <location filename="../detailsdialog.cpp" line="54"/>
+ <source>Hz</source>
+ <translation>Гц</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="265"/>
+ <source>Save</source>
+ <translation>Сохранить</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="275"/>
+ <source>Track number:</source>
+ <translation>Номер трека:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="288"/>
+ <source>Year:</source>
+ <translation>Год:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="298"/>
+ <source>Genre:</source>
+ <translation>Жанр:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="308"/>
+ <source>Comment:</source>
+ <translation>Комментарий:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="318"/>
+ <source>Album:</source>
+ <translation>Альбом:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="328"/>
+ <source>Artist:</source>
+ <translation>Исполнитель:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="338"/>
+ <source>Title:</source>
+ <translation>Название:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="222"/>
+ <source>Close</source>
+ <translation>Закрыть</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="162"/>
+ <source>-</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="192"/>
+ <source>File size:</source>
+ <translation>Размер файла:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="77"/>
+ <source>Sample rate:</source>
+ <translation>Дискретизация:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="212"/>
+ <source>File path:</source>
+ <translation>Путь к файлу:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="31"/>
+ <source>Ogg Vorbis Info</source>
+ <translation>Информация Ogg Vorbis</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="60"/>
+ <source>Length:</source>
+ <translation>Длительность:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="97"/>
+ <source>Channels:</source>
+ <translation>Каналов:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="120"/>
+ <source>Bit Rate</source>
+ <translation>Битовая частота</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="152"/>
+ <source>Minimum:</source>
+ <translation>Минимальная:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="169"/>
+ <source>Maximum:</source>
+ <translation>Максимальная:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="179"/>
+ <source>Nominal:</source>
+ <translation>Номинальная:</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="250"/>
+ <source>Ogg Vorbis Tag</source>
+ <translation>Оgg Vorbis-тег</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.cpp" line="62"/>
+ <source>kbps</source>
+ <translation>Кб/с</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.cpp" line="63"/>
+ <source>KB</source>
+ <translation>Кб</translation>
+ </message>
+ <message>
+ <location filename="../detailsdialog.ui" line="13"/>
+ <source>Details</source>
+ <translation>Информация</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/vorbis/vorbis.pro b/src/plugins/Input/vorbis/vorbis.pro
new file mode 100644
index 000000000..afd7b6510
--- /dev/null
+++ b/src/plugins/Input/vorbis/vorbis.pro
@@ -0,0 +1,35 @@
+# ???? ?????? ? KDevelop ?????????? qmake.
+# -------------------------------------------
+# ?????????? ???????????? ???????? ???????? ???????: ./Plugins/Input/ogg
+# ???? - ??????????:
+
+include(../../plugins.pri)
+
+FORMS += detailsdialog.ui
+HEADERS += decodervorbisfactory.h \
+ decoder_vorbis.h \
+ detailsdialog.h
+SOURCES += decoder_vorbis.cpp \
+ decodervorbisfactory.cpp \
+ detailsdialog.cpp
+
+TARGET=$$PLUGINS_PREFIX/Input/vorbis
+QMAKE_CLEAN =$$PLUGINS_PREFIX/Input/libvorbis.so
+
+INCLUDEPATH += ../../../qmmp
+CONFIG += release \
+warn_on \
+plugin \
+link_pkgconfig
+TEMPLATE = lib
+QMAKE_LIBDIR += ../../../../lib
+LIBS += -lqmmp -L/usr/lib
+PKGCONFIG += taglib ogg vorbisfile vorbis
+#TRANSLATIONS = translations/vorbis_plugin_ru.ts
+#RESOURCES = translations/translations.qrc
+
+isEmpty (LIB_DIR){
+LIB_DIR = /lib
+}
+target.path = $$LIB_DIR/qmmp/Input
+INSTALLS += target