aboutsummaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/Input/CMakeLists.txt6
-rw-r--r--src/plugins/Input/Input.pro3
-rw-r--r--src/plugins/Input/opus/decoder_opus.cpp159
-rw-r--r--src/plugins/Input/opus/decoder_opus.h54
-rw-r--r--src/plugins/Input/opus/decoderopusfactory.cpp136
-rw-r--r--src/plugins/Input/opus/decoderopusfactory.h54
-rw-r--r--src/plugins/Input/opus/opus.pro61
-rw-r--r--src/plugins/Input/opus/opusfile.cpp137
-rw-r--r--src/plugins/Input/opus/opusfile.h122
-rw-r--r--src/plugins/Input/opus/opusmetadatamodel.cpp213
-rw-r--r--src/plugins/Input/opus/opusmetadatamodel.h59
-rw-r--r--src/plugins/Input/opus/opusproperties.cpp161
-rw-r--r--src/plugins/Input/opus/opusproperties.h96
-rw-r--r--src/plugins/Input/opus/replaygainreader.cpp61
-rw-r--r--src/plugins/Input/opus/replaygainreader.h44
-rw-r--r--src/plugins/Input/opus/tdebug.cpp55
-rw-r--r--src/plugins/Input/opus/tdebug.h71
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_cs.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_de.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_es.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_fr.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_he.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_hu.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_it.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_ja.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_kk.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_lt.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_nl.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_pl.ts80
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_pl_PL.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_pt_BR.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_ru.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_sk.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_tr.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_uk_UA.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_zh_CN.ts75
-rw-r--r--src/plugins/Input/opus/translations/opus_plugin_zh_TW.ts75
-rw-r--r--src/plugins/Input/opus/translations/translations.qrc24
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_cs.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_de.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_es.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_fr.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_he.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_hu.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_it.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_ja.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_kk.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_lt.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_nl.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_pl_PL.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_pt_BR.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_ru.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_sk.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_tr.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_uk_UA.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_zh_CN.ts4
-rw-r--r--src/plugins/Ui/skinned/translations/skinned_plugin_zh_TW.ts4
57 files changed, 3058 insertions, 39 deletions
diff --git a/src/plugins/Input/CMakeLists.txt b/src/plugins/Input/CMakeLists.txt
index ba943f1ff..1eb17ac9c 100644
--- a/src/plugins/Input/CMakeLists.txt
+++ b/src/plugins/Input/CMakeLists.txt
@@ -1,4 +1,3 @@
-
SET(USE_MAD TRUE CACHE BOOL "enable/disable mad plugin")
SET(USE_FLAC TRUE CACHE BOOL "enable/disable flac plugin")
SET(USE_VORBIS TRUE CACHE BOOL "enable/disable ogg vorbis plugin")
@@ -13,6 +12,7 @@ SET(USE_CUE TRUE CACHE BOOL "enable/disable cue plugin")
SET(USE_CDA TRUE CACHE BOOL "enable/disable cd audio support")
SET(USE_MIDI TRUE CACHE BOOL "enable/disable midi support")
SET(USE_GME TRUE CACHE BOOL "enable/disable game music plugin")
+SET(USE_OPUS TRUE CACHE BOOL "enable/disable opus plugin")
IF(USE_MAD AND TAGLIB_FOUND)
@@ -70,3 +70,7 @@ ENDIF(USE_MIDI)
IF(USE_GME)
add_subdirectory(gme)
ENDIF(USE_GME)
+
+IF(USE_OPUS AND TAGLIB_FOUND)
+add_subdirectory(opus)
+ENDIF(USE_OPUS AND TAGLIB_FOUND)
diff --git a/src/plugins/Input/Input.pro b/src/plugins/Input/Input.pro
index 00fabe618..29bd6351d 100644
--- a/src/plugins/Input/Input.pro
+++ b/src/plugins/Input/Input.pro
@@ -41,4 +41,7 @@ contains(CONFIG, GME_PLUGIN){
SUBDIRS += gme
}
+contains(CONFIG, OPUS_PLUGIN){
+ SUBDIRS += opus
+}
}
diff --git a/src/plugins/Input/opus/decoder_opus.cpp b/src/plugins/Input/opus/decoder_opus.cpp
new file mode 100644
index 000000000..b8fda17fb
--- /dev/null
+++ b/src/plugins/Input/opus/decoder_opus.cpp
@@ -0,0 +1,159 @@
+/***************************************************************************
+ * Copyright (C) 2013 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <QObject>
+#include <QIODevice>
+#include <qmmp/buffer.h>
+#include <qmmp/output.h>
+#include <qmmp/fileinfo.h>
+#include "decoder_opus.h"
+
+// ic functions for libopusfile
+static int opusread (void *src, unsigned char *buf,int size)
+{
+ DecoderOpus *d = (DecoderOpus *) src;
+ return d->input()->read((char *) buf, size);
+}
+
+static int opusseek(void *src, opus_int64 offset, int whence)
+{
+ DecoderOpus *d = (DecoderOpus *) src;
+ if (d->input()->isSequential())
+ return -1;
+ long start = 0;
+ switch (whence)
+ {
+ case SEEK_END:
+ start = d->input()->size();
+ break;
+
+ case SEEK_CUR:
+ start = d->input()->pos();
+ break;
+
+ case SEEK_SET:
+ default:
+ start = 0;
+ }
+
+ if (d->input()->seek(start + offset))
+ return 0;
+ return -1;
+}
+
+static opus_int64 opustell(void *src)
+{
+ DecoderOpus *dogg = (DecoderOpus *) src;
+ return (long) dogg->input()->pos();
+}
+
+// Decoder class
+DecoderOpus::DecoderOpus(const QString &url, QIODevice *i) : Decoder(i)
+{
+ m_totalTime = 0;
+ m_opusfile = 0;
+ m_chan = 0;
+ m_bitrate = 0;
+ m_url = url;
+}
+
+DecoderOpus::~DecoderOpus()
+{
+ if (m_opusfile)
+ op_free(m_opusfile);
+ m_opusfile = 0;
+}
+
+bool DecoderOpus::initialize()
+{
+ qDebug("DecoderOpus: initialize");
+ quint32 freq = 0;
+ m_chan = 0;
+ m_totalTime = 0;
+
+ if (!input())
+ {
+ qDebug("DecoderOpus: cannot initialize. No input");
+ return false;
+ }
+
+ if (!input()->isOpen())
+ {
+ if (!input()->open(QIODevice::ReadOnly))
+ {
+ qWarning("DecoderOpus: unable to open input. Error: %s",qPrintable(input()->errorString()));
+ return false;
+ }
+ }
+
+ OpusFileCallbacks opuscb =
+ {
+ opusread,
+ opusseek,
+ opustell,
+ 0,
+ };
+ m_opusfile = op_open_callbacks(this, &opuscb, 0, 0, 0);
+
+ if (!m_opusfile)
+ {
+ qWarning("DecoderOpus: cannot open stream");
+ return false;
+ }
+
+ m_bitrate = op_bitrate(m_opusfile, -1) / 1000;
+
+ if((m_totalTime = op_pcm_total(m_opusfile, -1) / 48) < 0)
+ m_totalTime = 0;
+
+ const OpusHead *head = op_head(m_opusfile, -1);
+ if (head)
+ {
+ freq = head->input_sample_rate;
+ m_chan = head->channel_count;
+ }
+ configure(freq, m_chan, Qmmp::PCM_S16LE);
+ return true;
+}
+
+qint64 DecoderOpus::totalTime()
+{
+ if (!m_opusfile)
+ return 0;
+ return m_totalTime;
+}
+
+int DecoderOpus::bitrate()
+{
+ return m_bitrate;
+}
+
+void DecoderOpus::seek(qint64 time)
+{
+ op_pcm_seek(m_opusfile, time*48);
+}
+
+qint64 DecoderOpus::read(char *data, qint64 maxSize)
+{
+ int samples = maxSize / 2 / m_chan;
+ samples = op_read(m_opusfile, (opus_int16 *)data, samples, 0);
+ m_bitrate = op_bitrate_instant(m_opusfile) / 1000;
+ return samples * m_chan * 2;
+}
diff --git a/src/plugins/Input/opus/decoder_opus.h b/src/plugins/Input/opus/decoder_opus.h
new file mode 100644
index 000000000..987c1b3b9
--- /dev/null
+++ b/src/plugins/Input/opus/decoder_opus.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * Copyright (C) 2013 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef DECODER_OPUS_H
+#define DECODER_OPUS_H
+
+#include <qmmp/decoder.h>
+#include <opus/opusfile.h>
+
+/**
+ @author Ilya Kotov <forkotov02@hotmail.ru>
+*/
+class DecoderOpus : public Decoder
+{
+public:
+ DecoderOpus(const QString &url, QIODevice *i);
+ virtual ~DecoderOpus();
+
+ // Standard Decoder API
+ bool initialize();
+ qint64 totalTime();
+ int bitrate();
+
+private:
+ virtual qint64 read(char *data, qint64 maxSize);
+ virtual void seek(qint64 time);
+
+ // helper functions
+ OggOpusFile *m_opusfile;
+ qint64 m_totalTime;
+ int m_bitrate;
+ int m_chan;
+ QString m_url;
+};
+
+
+#endif // DECODER_OPUS_H
diff --git a/src/plugins/Input/opus/decoderopusfactory.cpp b/src/plugins/Input/opus/decoderopusfactory.cpp
new file mode 100644
index 000000000..f8d0f7d3d
--- /dev/null
+++ b/src/plugins/Input/opus/decoderopusfactory.cpp
@@ -0,0 +1,136 @@
+/***************************************************************************
+ * Copyright (C) 2013 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include <QtGui>
+#include <taglib/tag.h>
+#include <taglib/fileref.h>
+#include "opusfile.h"
+#include "replaygainreader.h"
+#include "decoder_opus.h"
+#include "opusmetadatamodel.h"
+#include "decoderopusfactory.h"
+
+
+// DecoderOpusFactory
+bool DecoderOpusFactory::supports(const QString &source) const
+{
+ return source.right(5).toLower() == ".opus";
+}
+
+bool DecoderOpusFactory::canDecode(QIODevice *input) const
+{
+ char buf[36];
+ if (input->peek(buf, 36) == 36 && !memcmp(buf, "OggS", 4)
+ && !memcmp(buf + 28, "OpusHead", 8))
+ return true;
+ return false;
+}
+
+const DecoderProperties DecoderOpusFactory::properties() const
+{
+ DecoderProperties properties;
+ properties.name = tr("Opus Plugin");
+ properties.shortName = "opus";
+ properties.filters << "*.opus";
+ properties.description = tr("Ogg Opus Files");
+ properties.contentTypes << "audio/opus";
+ properties.hasAbout = true;
+ properties.hasSettings = false;
+ properties.noInput = false;
+ return properties;
+}
+
+Decoder *DecoderOpusFactory::create(const QString &url, QIODevice *input)
+{
+ Decoder *d = new DecoderOpus(url, input);
+ if(!url.contains("://")) //local file
+ {
+ ReplayGainReader rg(url);
+ d->setReplayGainInfo(rg.replayGainInfo());
+ }
+ return d;
+}
+
+MetaDataModel* DecoderOpusFactory::createMetaDataModel(const QString &path, QObject *parent)
+{
+ return new OpusMetaDataModel(path, parent);
+}
+
+QList<FileInfo *> DecoderOpusFactory::createPlayList(const QString &fileName, bool useMetaData)
+{
+ FileInfo *info = new FileInfo(fileName);
+
+ TagLib::Ogg::Opus::File fileRef(fileName.toLocal8Bit().constData());
+ TagLib::Ogg::XiphComment *tag = useMetaData ? fileRef.tag() : 0;
+
+ 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());
+ //additional metadata
+ if(tag)
+ {
+ TagLib::StringList fld;
+ if(!(fld = tag->fieldListMap()["COMPOSER"]).isEmpty())
+ info->setMetaData(Qmmp::COMPOSER,
+ QString::fromUtf8(fld.toString().toCString(true)).trimmed());
+ if(!(fld = tag->fieldListMap()["DISCNUMBER"]).isEmpty())
+ info->setMetaData(Qmmp::DISCNUMBER,
+ QString::fromUtf8(fld.toString().toCString(true)).trimmed());
+ }
+
+ QList <FileInfo*> list;
+ list << info;
+ return list;
+}
+
+void DecoderOpusFactory::showSettings(QWidget *)
+{}
+
+void DecoderOpusFactory::showAbout(QWidget *parent)
+{
+ QMessageBox::about (parent, tr("About Opus Audio Plugin"),
+ tr("Qmmp Opus Audio Plugin")+"\n"+
+ tr("Written by: Ilya Kotov <forkotov02@hotmail.ru>")
+ );
+}
+
+QTranslator *DecoderOpusFactory::createTranslator(QObject *parent)
+{
+ QTranslator *translator = new QTranslator(parent);
+ QString locale = Qmmp::systemLanguageID();
+ translator->load(QString(":/opus_plugin_") + locale);
+ return translator;
+}
+
+Q_EXPORT_PLUGIN2(opus,DecoderOpusFactory)
diff --git a/src/plugins/Input/opus/decoderopusfactory.h b/src/plugins/Input/opus/decoderopusfactory.h
new file mode 100644
index 000000000..34bbd66d7
--- /dev/null
+++ b/src/plugins/Input/opus/decoderopusfactory.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * Copyright (C) 2013 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef DECODEROPUSFACTORY_H
+#define DECODEROPUSFACTORY_H
+
+#include <QObject>
+#include <QString>
+#include <QIODevice>
+#include <QWidget>
+#include <qmmp/decoder.h>
+#include <qmmp/output.h>
+#include <qmmp/decoderfactory.h>
+#include <qmmp/fileinfo.h>
+#include <qmmp/metadatamodel.h>
+
+/**
+ @author Ilya Kotov <forkotov02@hotmail.ru>
+*/
+class DecoderOpusFactory : 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(const QString &path, QIODevice *input);
+ MetaDataModel* createMetaDataModel(const QString &path, QObject *parent = 0);
+ QList<FileInfo *> createPlayList(const QString &fileName, bool useMetaData);
+ QObject* showDetails(QWidget *parent, const QString &path);
+ void showSettings(QWidget *parent);
+ void showAbout(QWidget *parent);
+ QTranslator *createTranslator(QObject *parent);
+};
+
+#endif //DECODEROPUSFACTORY_H
diff --git a/src/plugins/Input/opus/opus.pro b/src/plugins/Input/opus/opus.pro
new file mode 100644
index 000000000..be6c4f38f
--- /dev/null
+++ b/src/plugins/Input/opus/opus.pro
@@ -0,0 +1,61 @@
+include(../../plugins.pri)
+FORMS +=
+HEADERS += decoderopusfactory.h \
+ decoder_opus.h \
+ opusmetadatamodel.h \
+ replaygainreader.h \
+ opusproperties.h \
+ opusfile.h \
+ tdebug.h
+SOURCES += decoder_opus.cpp \
+ decoderopusfactory.cpp \
+ opusmetadatamodel.cpp \
+ replaygainreader.cpp \
+ opusproperties.cpp \
+ opusfile.cpp \
+ tdebug.cpp
+TARGET = $$PLUGINS_PREFIX/Input/opus
+
+INCLUDEPATH += ../../../
+CONFIG += release \
+ warn_on \
+ plugin \
+ link_pkgconfig
+TEMPLATE = lib
+QMAKE_LIBDIR += ../../../../lib
+
+
+TRANSLATIONS = translations/opus_plugin_ru.ts \
+ translations/opus_plugin_uk_UA.ts \
+ translations/opus_plugin_zh_CN.ts \
+ translations/opus_plugin_zh_TW.ts \
+ translations/opus_plugin_cs.ts \
+ translations/opus_plugin_pl.ts \
+ translations/opus_plugin_de.ts \
+ translations/opus_plugin_it.ts \
+ translations/opus_plugin_tr.ts \
+ translations/opus_plugin_lt.ts \
+ translations/opus_plugin_nl.ts \
+ translations/opus_plugin_ja.ts \
+ translations/opus_plugin_es.ts
+
+RESOURCES = translations/translations.qrc
+
+
+unix {
+ isEmpty (LIB_DIR):LIB_DIR = /lib
+ target.path = $$LIB_DIR/qmmp/Input
+ INSTALLS += target
+
+ PKGCONFIG += taglib opus opusfile
+ LIBS += -lqmmp
+ QMAKE_CLEAN = $$PLUGINS_PREFIX/Input/libopus.so
+}
+
+win32 {
+ HEADERS += ../../../../src/qmmp/metadatamodel.h \
+ ../../../../src/qmmp/decoderfactory.h
+ QMAKE_LIBDIR += ../../../../bin
+ LIBS += -lqmmp0 -lopusfile -lopus -ltag.dll -lm
+ LD_FLAGS += -no-undefined
+}
diff --git a/src/plugins/Input/opus/opusfile.cpp b/src/plugins/Input/opus/opusfile.cpp
new file mode 100644
index 000000000..b3c43e54b
--- /dev/null
+++ b/src/plugins/Input/opus/opusfile.cpp
@@ -0,0 +1,137 @@
+/***************************************************************************
+ copyright : (C) 2012 by Lukáš Lalinský
+ email : lalinsky@gmail.com
+
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ (original Vorbis implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
+ * 02110-1301 USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include <bitset>
+
+#include <taglib/tstring.h>
+#include "tdebug.h"
+#include <taglib/tpropertymap.h>
+
+#include "opusfile.h"
+
+using namespace TagLib;
+using namespace TagLib::Ogg;
+
+class Opus::File::FilePrivate
+{
+public:
+ FilePrivate() :
+ comment(0),
+ properties(0) {}
+
+ ~FilePrivate()
+ {
+ delete comment;
+ delete properties;
+ }
+
+ Ogg::XiphComment *comment;
+ Properties *properties;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+Opus::File::File(FileName file, bool readProperties,
+ Properties::ReadStyle propertiesStyle) : Ogg::File(file)
+{
+ d = new FilePrivate;
+ read(readProperties, propertiesStyle);
+}
+
+Opus::File::File(IOStream *stream, bool readProperties,
+ Properties::ReadStyle propertiesStyle) : Ogg::File(stream)
+{
+ d = new FilePrivate;
+ read(readProperties, propertiesStyle);
+}
+
+Opus::File::~File()
+{
+ delete d;
+}
+
+Ogg::XiphComment *Opus::File::tag() const
+{
+ return d->comment;
+}
+
+PropertyMap Opus::File::properties() const
+{
+ return d->comment->properties();
+}
+
+PropertyMap Opus::File::setProperties(const PropertyMap &properties)
+{
+ return d->comment->setProperties(properties);
+}
+
+Opus::Properties *Opus::File::audioProperties() const
+{
+ return d->properties;
+}
+
+bool Opus::File::save()
+{
+ if(!d->comment)
+ d->comment = new Ogg::XiphComment;
+
+ setPacket(1, ByteVector("OpusTags", 8) + d->comment->render(false));
+
+ return Ogg::File::save();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+void Opus::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
+{
+ ByteVector opusHeaderData = packet(0);
+
+ if(!opusHeaderData.startsWith("OpusHead")) {
+ setValid(false);
+ debug("Opus::File::read() -- invalid Opus identification header");
+ return;
+ }
+
+ ByteVector commentHeaderData = packet(1);
+
+ if(!commentHeaderData.startsWith("OpusTags")) {
+ setValid(false);
+ debug("Opus::File::read() -- invalid Opus tags header");
+ return;
+ }
+
+ d->comment = new Ogg::XiphComment(commentHeaderData.mid(8));
+
+ if(readProperties)
+ d->properties = new Properties(this, propertiesStyle);
+}
diff --git a/src/plugins/Input/opus/opusfile.h b/src/plugins/Input/opus/opusfile.h
new file mode 100644
index 000000000..208f33bc5
--- /dev/null
+++ b/src/plugins/Input/opus/opusfile.h
@@ -0,0 +1,122 @@
+/***************************************************************************
+ copyright : (C) 2012 by Lukáš Lalinský
+ email : lalinsky@gmail.com
+
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ (original Vorbis implementation)
+***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
+ * 02110-1301 USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_OPUSFILE_H
+#define TAGLIB_OPUSFILE_H
+
+#include <taglib/oggfile.h>
+#include <taglib/xiphcomment.h>
+
+#include "opusproperties.h"
+
+namespace TagLib {
+
+ namespace Ogg {
+
+ //! A namespace containing classes for Opus metadata
+
+ namespace Opus {
+
+ //! An implementation of Ogg::File with Opus specific methods
+
+ /*!
+ * This is the central class in the Ogg Opus metadata processing collection
+ * of classes. It's built upon Ogg::File which handles processing of the Ogg
+ * logical bitstream and breaking it down into pages which are handled by
+ * the codec implementations, in this case Opus specifically.
+ */
+
+ class TAGLIB_EXPORT File : public Ogg::File
+ {
+ public:
+ /*!
+ * Contructs a Opus file from \a file. If \a readProperties is true the
+ * file's audio properties will also be read using \a propertiesStyle. If
+ * false, \a propertiesStyle is ignored.
+ */
+ File(FileName file, bool readProperties = true,
+ Properties::ReadStyle propertiesStyle = Properties::Average);
+
+ /*!
+ * Contructs a Opus file from \a file. If \a readProperties is true the
+ * file's audio properties will also be read using \a propertiesStyle. If
+ * false, \a propertiesStyle is ignored.
+ *
+ * \note TagLib will *not* take ownership of the stream, the caller is
+ * responsible for deleting it after the File object.
+ */
+ File(IOStream *stream, bool readProperties = true,
+ Properties::ReadStyle propertiesStyle = Properties::Average);
+
+ /*!
+ * Destroys this instance of the File.
+ */
+ virtual ~File();
+
+ /*!
+ * Returns the XiphComment for this file. XiphComment implements the tag
+ * interface, so this serves as the reimplementation of
+ * TagLib::File::tag().
+ */
+ virtual Ogg::XiphComment *tag() const;
+
+ /*!
+ * Implements the unified property interface -- export function.
+ * This forwards directly to XiphComment::properties().
+ */
+ PropertyMap properties() const;
+
+ /*!
+ * Implements the unified tag dictionary interface -- import function.
+ * Like properties(), this is a forwarder to the file's XiphComment.
+ */
+ PropertyMap setProperties(const PropertyMap &);
+
+ /*!
+ * Returns the Opus::Properties for this file. If no audio properties
+ * were read then this will return a null pointer.
+ */
+ virtual Properties *audioProperties() const;
+
+ virtual bool save();
+
+ private:
+ File(const File &);
+ File &operator=(const File &);
+
+ void read(bool readProperties, Properties::ReadStyle propertiesStyle);
+
+ class FilePrivate;
+ FilePrivate *d;
+ };
+ }
+ }
+}
+
+#endif
diff --git a/src/plugins/Input/opus/opusmetadatamodel.cpp b/src/plugins/Input/opus/opusmetadatamodel.cpp
new file mode 100644
index 000000000..254abb582
--- /dev/null
+++ b/src/plugins/Input/opus/opusmetadatamodel.cpp
@@ -0,0 +1,213 @@
+/***************************************************************************
+ * Copyright (C) 2013 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <taglib/tag.h>
+#include <taglib/fileref.h>
+#include "opusfile.h"
+#include <taglib/xiphcomment.h>
+#include <taglib/tmap.h>
+#include "opusmetadatamodel.h"
+
+#define QStringToTString_qt4(s) TagLib::String(s.toUtf8().constData(), TagLib::String::UTF8)
+#define TStringToQString_qt4(s) QString::fromUtf8(s.toCString(true)).trimmed()
+
+OpusMetaDataModel::OpusMetaDataModel(const QString &path, QObject *parent) : MetaDataModel(parent)
+{
+ m_path = path;
+ m_tags << new VorbisCommentModel(path);
+}
+
+OpusMetaDataModel::~OpusMetaDataModel()
+{
+ while(!m_tags.isEmpty())
+ delete m_tags.takeFirst();
+}
+
+QHash<QString, QString> OpusMetaDataModel::audioProperties()
+{
+ QHash<QString, QString> ap;
+ TagLib::Ogg::Opus::File f (m_path.toLocal8Bit().constData());
+ if(f.audioProperties())
+ {
+ QString text = QString("%1").arg(f.audioProperties()->length()/60);
+ text +=":"+QString("%1").arg(f.audioProperties()->length()%60,2,10,QChar('0'));
+ ap.insert(tr("Length"), text);
+ ap.insert(tr("Sample rate"), QString("%1 " + tr("Hz")).arg(f.audioProperties()->sampleRate()));
+ ap.insert(tr("Channels"), QString("%1").arg(f.audioProperties()->channels()));
+ ap.insert(tr("Bitrate"), QString("%1 " + tr("kbps")).arg(f.audioProperties()->bitrate()));
+ ap.insert(tr("File size"), QString("%1 "+tr("KB")).arg(f.length()/1024));
+ }
+ return ap;
+}
+
+QList<TagModel* > OpusMetaDataModel::tags()
+{
+ return m_tags;
+}
+
+QPixmap OpusMetaDataModel::cover()
+{
+ TagLib::Ogg::Opus::File file(m_path.toLocal8Bit().constData());
+ TagLib::Ogg::XiphComment *tag = file.tag();
+ if(!tag)
+ return QPixmap();
+ TagLib::StringList list = tag->fieldListMap()["METADATA_BLOCK_PICTURE"];
+ if(list.isEmpty())
+ return QPixmap();
+ for(uint i = 0; i < list.size(); ++i)
+ {
+ TagLib::String value = list[i];
+ QByteArray block = QByteArray::fromBase64(TStringToQString_qt4(value).toAscii());
+ if(block.size() < 32)
+ continue;
+ qint64 pos = 0;
+ if(readPictureBlockField(block, pos) != 3) //picture type, use front cover only
+ continue;
+ pos += 4;
+ int mimeLength = readPictureBlockField(block, pos); //mime type length
+ pos += 4;
+ pos += mimeLength; //skip mime type
+ int descLength = readPictureBlockField(block, pos); //description length
+ pos += 4;
+ pos += descLength; //skip description
+ pos += 4; //width
+ pos += 4; //height
+ pos += 4; //color depth
+ pos += 4; //the number of colors used
+ int length = readPictureBlockField(block, pos); //picture size
+ pos += 4;
+ QPixmap cover;
+ cover.loadFromData(block.mid(pos, length)); //read binary picture data
+ return cover;
+ }
+ return QPixmap();
+}
+
+ulong OpusMetaDataModel::readPictureBlockField(QByteArray data, int offset)
+{
+ return (((uchar)data.data()[offset] & 0xff) << 24) |
+ (((uchar)data.data()[offset+1] & 0xff) << 16) |
+ (((uchar)data.data()[offset+2] & 0xff) << 16) |
+ ((uchar)data.data()[offset+3] & 0xff);
+
+}
+
+VorbisCommentModel::VorbisCommentModel(const QString &path) : TagModel(TagModel::Save)
+{
+ m_file = new TagLib::Ogg::Opus::File (path.toLocal8Bit().constData());
+ m_tag = m_file->tag();
+}
+
+VorbisCommentModel::~VorbisCommentModel()
+{
+ delete m_file;
+}
+
+const QString VorbisCommentModel::name()
+{
+ return "Vorbis Comment";
+}
+
+const QString VorbisCommentModel::value(Qmmp::MetaData key)
+{
+ if(!m_tag)
+ return QString();
+ switch((int) key)
+ {
+ case Qmmp::TITLE:
+ return TStringToQString_qt4(m_tag->title());
+ case Qmmp::ARTIST:
+ return TStringToQString_qt4(m_tag->artist());
+ case Qmmp::ALBUM:
+ return TStringToQString_qt4(m_tag->album());
+ case Qmmp::COMMENT:
+ return TStringToQString_qt4(m_tag->comment());
+ case Qmmp::GENRE:
+ return TStringToQString_qt4(m_tag->genre());
+ case Qmmp::COMPOSER:
+ if(m_tag->fieldListMap()["COMPOSER"].isEmpty())
+ return QString();
+ else
+ return TStringToQString_qt4(m_tag->fieldListMap()["COMPOSER"].front());
+ case Qmmp::YEAR:
+ return QString::number(m_tag->year());
+ case Qmmp::TRACK:
+ return QString::number(m_tag->track());
+ case Qmmp::DISCNUMBER:
+ if(m_tag->fieldListMap()["DISCNUMBER"].isEmpty())
+ return QString();
+ else
+ return TStringToQString_qt4(m_tag->fieldListMap()["DISCNUMBER"].front());
+ }
+ return QString();
+}
+
+void VorbisCommentModel::setValue(Qmmp::MetaData key, const QString &value)
+{
+ if(!m_tag)
+ return;
+
+ TagLib::String str = QStringToTString_qt4(value);
+
+ switch((int) key)
+ {
+ case Qmmp::TITLE:
+ m_tag->setTitle(str);
+ return;
+ case Qmmp::ARTIST:
+ m_tag->setArtist(str);
+ return;
+ case Qmmp::ALBUM:
+ m_tag->setAlbum(str);
+ return;
+ case Qmmp::COMMENT:
+ m_tag->setComment(str);
+ return;
+ case Qmmp::GENRE:
+ m_tag->setGenre(str);
+ return;
+ case Qmmp::COMPOSER:
+ value.isEmpty() ?
+ m_tag->removeField("COMPOSER"):
+ m_tag->addField("COMPOSER", str, true);
+ return;
+ case Qmmp::TRACK:
+ m_tag->setTrack(value.toInt());
+ return;
+ case Qmmp::YEAR:
+ m_tag->setYear(value.toInt());
+ return;
+ case Qmmp::DISCNUMBER:
+ value == "0" ?
+ m_tag->removeField("DISCNUMBER"):
+ m_tag->addField("DISCNUMBER", str, true);
+ }
+}
+
+void VorbisCommentModel::save()
+{
+ if(m_tag)
+ m_file->save();
+ //taglib bug workarround
+ QString path = QString::fromLocal8Bit(m_file->name());
+ delete m_file;
+ m_file = new TagLib::Ogg::Opus::File(path.toLocal8Bit().constData());
+ m_tag = m_file->tag();
+}
diff --git a/src/plugins/Input/opus/opusmetadatamodel.h b/src/plugins/Input/opus/opusmetadatamodel.h
new file mode 100644
index 000000000..e6253122f
--- /dev/null
+++ b/src/plugins/Input/opus/opusmetadatamodel.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * Copyright (C) 2013 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef OPUSMETADATAMODEL_H
+#define OPUSMETADATAMODEL_H
+
+#include "opusfile.h"
+#include <taglib/xiphcomment.h>
+#include <qmmp/metadatamodel.h>
+
+class OpusMetaDataModel : public MetaDataModel
+{
+Q_OBJECT
+public:
+ OpusMetaDataModel(const QString &path, QObject *parent);
+ ~OpusMetaDataModel();
+ QHash<QString, QString> audioProperties();
+ QList<TagModel* > tags();
+ QPixmap cover();
+
+private:
+ QString m_path;
+ QList<TagModel* > m_tags;
+ ulong readPictureBlockField(QByteArray data, int offset);
+};
+
+class VorbisCommentModel : public TagModel
+{
+public:
+ VorbisCommentModel(const QString &path);
+ ~VorbisCommentModel();
+ const QString name();
+ const QString value(Qmmp::MetaData key);
+ void setValue(Qmmp::MetaData key, const QString &value);
+ void save();
+
+private:
+ TagLib::Ogg::Opus::File *m_file;
+ TagLib::Ogg::XiphComment *m_tag;
+};
+
+#endif // OPUSMETADATAMODEL_H
diff --git a/src/plugins/Input/opus/opusproperties.cpp b/src/plugins/Input/opus/opusproperties.cpp
new file mode 100644
index 000000000..89ede973d
--- /dev/null
+++ b/src/plugins/Input/opus/opusproperties.cpp
@@ -0,0 +1,161 @@
+/***************************************************************************
+ copyright : (C) 2012 by Lukáš Lalinský
+ email : lalinsky@gmail.com
+
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ (original Vorbis implementation)
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
+ * 02110-1301 USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include <taglib/tstring.h>
+#include "tdebug.h"
+
+#include <taglib/oggpageheader.h>
+
+#include "opusproperties.h"
+#include "opusfile.h"
+
+using namespace TagLib;
+using namespace TagLib::Ogg;
+
+class Opus::Properties::PropertiesPrivate
+{
+public:
+ PropertiesPrivate(File *f, ReadStyle s) :
+ file(f),
+ style(s),
+ length(0),
+ inputSampleRate(0),
+ channels(0),
+ opusVersion(0) {}
+
+ File *file;
+ ReadStyle style;
+ int length;
+ int inputSampleRate;
+ int channels;
+ int opusVersion;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+Opus::Properties::Properties(File *file, ReadStyle style) : AudioProperties(style)
+{
+ d = new PropertiesPrivate(file, style);
+ read();
+}
+
+Opus::Properties::~Properties()
+{
+ delete d;
+}
+
+int Opus::Properties::length() const
+{
+ return d->length;
+}
+
+int Opus::Properties::bitrate() const
+{
+ return 0;
+}
+
+int Opus::Properties::sampleRate() const
+{
+ // Opus can decode any stream at a sample rate of 8, 12, 16, 24, or 48 kHz,
+ // so there is no single sample rate. Let's assume it's the highest
+ // possible.
+ return 48000;
+}
+
+int Opus::Properties::channels() const
+{
+ return d->channels;
+}
+
+int Opus::Properties::inputSampleRate() const
+{
+ return d->inputSampleRate;
+}
+
+int Opus::Properties::opusVersion() const
+{
+ return d->opusVersion;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+void Opus::Properties::read()
+{
+ // Get the identification header from the Ogg implementation.
+
+ // http://tools.ietf.org/html/draft-terriberry-oggopus-01#section-5.1
+
+ ByteVector data = d->file->packet(0);
+
+ // *Magic Signature*
+ int pos = 8;
+
+ // *Version* (8 bits, unsigned)
+ d->opusVersion = uchar(data.at(pos));
+ pos += 1;
+
+ // *Output Channel Count* 'C' (8 bits, unsigned)
+ d->channels = uchar(data.at(pos));
+ pos += 1;
+
+ // *Pre-skip* (16 bits, unsigned, little endian)
+ ushort preSkip = data.mid(pos, 2).toUShort(false);
+ pos += 2;
+
+ // *Input Sample Rate* (32 bits, unsigned, little endian)
+ d->inputSampleRate = data.mid(pos, 4).toUInt(false);
+ pos += 4;
+
+ // *Output Gain* (16 bits, signed, little endian)
+ pos += 2;
+
+ // *Channel Mapping Family* (8 bits, unsigned)
+ pos += 1;
+
+ const Ogg::PageHeader *first = d->file->firstPageHeader();
+ const Ogg::PageHeader *last = d->file->lastPageHeader();
+
+ if(first && last) {
+ long long start = first->absoluteGranularPosition();
+ long long end = last->absoluteGranularPosition();
+
+ if(start >= 0 && end >= 0)
+ d->length = (int) ((end - start - preSkip) / 48000);
+ else {
+ debug("Opus::Properties::read() -- The PCM values for the start or "
+ "end of this file was incorrect.");
+ }
+ }
+ else
+ debug("Opus::Properties::read() -- Could not find valid first and last Ogg pages.");
+}
diff --git a/src/plugins/Input/opus/opusproperties.h b/src/plugins/Input/opus/opusproperties.h
new file mode 100644
index 000000000..27984534c
--- /dev/null
+++ b/src/plugins/Input/opus/opusproperties.h
@@ -0,0 +1,96 @@
+/***************************************************************************
+ copyright : (C) 2012 by Lukáš Lalinský
+ email : lalinsky@gmail.com
+
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ (original Vorbis implementation)
+***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
+ * 02110-1301 USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_OPUSPROPERTIES_H
+#define TAGLIB_OPUSPROPERTIES_H
+
+#include <taglib/audioproperties.h>
+
+namespace TagLib {
+
+ namespace Ogg {
+
+ namespace Opus {
+
+ class File;
+
+ //! An implementation of audio property reading for Ogg Opus
+
+ /*!
+ * This reads the data from an Ogg Opus stream found in the AudioProperties
+ * API.
+ */
+
+ class TAGLIB_EXPORT Properties : public AudioProperties
+ {
+ public:
+ /*!
+ * Create an instance of Opus::Properties with the data read from the
+ * Opus::File \a file.
+ */
+ Properties(File *file, ReadStyle style = Average);
+
+ /*!
+ * Destroys this Opus::Properties instance.
+ */
+ virtual ~Properties();
+
+ // Reimplementations.
+
+ virtual int length() const;
+ virtual int bitrate() const;
+ virtual int sampleRate() const;
+ virtual int channels() const;
+
+ /*!
+ * The Opus codec supports decoding at multiple sample rates, there is no
+ * single sample rate of the encoded stream. This returns the sample rate
+ * of the original audio stream.
+ */
+ int inputSampleRate() const;
+
+ /*!
+ * Returns the Opus version, currently "0" (as specified by the spec).
+ */
+ int opusVersion() const;
+
+ private:
+ Properties(const Properties &);
+ Properties &operator=(const Properties &);
+
+ void read();
+
+ class PropertiesPrivate;
+ PropertiesPrivate *d;
+ };
+ }
+ }
+}
+
+#endif
diff --git a/src/plugins/Input/opus/replaygainreader.cpp b/src/plugins/Input/opus/replaygainreader.cpp
new file mode 100644
index 000000000..fad3afa57
--- /dev/null
+++ b/src/plugins/Input/opus/replaygainreader.cpp
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * Copyright (C) 2013 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <QtGlobal>
+#include <taglib/tag.h>
+#include <taglib/fileref.h>
+#include "opusfile.h"
+#include "replaygainreader.h"
+
+ReplayGainReader::ReplayGainReader(const QString &path)
+{
+ TagLib::Ogg::Opus::File fileRef(path.toLocal8Bit ().constData());
+ if(fileRef.tag())
+ readVorbisComment(fileRef.tag());
+}
+
+QMap <Qmmp::ReplayGainKey, double> ReplayGainReader::replayGainInfo() const
+{
+ return m_values;
+}
+
+void ReplayGainReader::readVorbisComment(TagLib::Ogg::XiphComment *comment)
+{
+ TagLib::Ogg::FieldListMap items = comment->fieldListMap();
+ if (items.contains("REPLAYGAIN_TRACK_GAIN"))
+ setValue(Qmmp::REPLAYGAIN_TRACK_GAIN,TStringToQString(items["REPLAYGAIN_TRACK_GAIN"].front()));
+ if (items.contains("REPLAYGAIN_TRACK_PEAK"))
+ setValue(Qmmp::REPLAYGAIN_TRACK_PEAK,TStringToQString(items["REPLAYGAIN_TRACK_PEAK"].front()));
+ if (items.contains("REPLAYGAIN_ALBUM_GAIN"))
+ setValue(Qmmp::REPLAYGAIN_ALBUM_GAIN,TStringToQString(items["REPLAYGAIN_ALBUM_GAIN"].front()));
+ if (items.contains("REPLAYGAIN_ALBUM_PEAK"))
+ setValue(Qmmp::REPLAYGAIN_ALBUM_PEAK,TStringToQString(items["REPLAYGAIN_ALBUM_PEAK"].front()));
+}
+
+void ReplayGainReader::setValue(Qmmp::ReplayGainKey key, QString value)
+{
+ value.remove(" dB");
+ if(value.isEmpty())
+ return;
+ bool ok;
+ double v = value.toDouble(&ok);
+ if(ok)
+ m_values[key] = v;
+}
diff --git a/src/plugins/Input/opus/replaygainreader.h b/src/plugins/Input/opus/replaygainreader.h
new file mode 100644
index 000000000..b2c5e8070
--- /dev/null
+++ b/src/plugins/Input/opus/replaygainreader.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * Copyright (C) 2013 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef REPLAYGAINREADER_H
+#define REPLAYGAINREADER_H
+
+#include <QMap>
+#include <QString>
+#include <taglib/xiphcomment.h>
+#include <qmmp/qmmp.h>
+
+/**
+ @author Ilya Kotov <forkotov02@hotmail.ru>
+*/
+class ReplayGainReader
+{
+public:
+ ReplayGainReader(const QString &path);
+ QMap <Qmmp::ReplayGainKey, double> replayGainInfo() const;
+
+private:
+ void readVorbisComment(TagLib::Ogg::XiphComment *comment);
+ void setValue(Qmmp::ReplayGainKey key, QString value);
+ QMap <Qmmp::ReplayGainKey, double> m_values;
+};
+
+#endif // REPLAYGAINREADER_H
diff --git a/src/plugins/Input/opus/tdebug.cpp b/src/plugins/Input/opus/tdebug.cpp
new file mode 100644
index 000000000..5a7be431d
--- /dev/null
+++ b/src/plugins/Input/opus/tdebug.cpp
@@ -0,0 +1,55 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
+ * 02110-1301 USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef NDEBUG
+#include <iostream>
+#include <bitset>
+
+#include "tdebug.h"
+#include <taglib/tstring.h>
+
+using namespace TagLib;
+
+void TagLib::debug(const String &s)
+{
+ std::cerr << "TagLib: " << s << std::endl;
+}
+
+void TagLib::debugData(const ByteVector &v)
+{
+ for(uint i = 0; i < v.size(); i++) {
+
+ std::cout << "*** [" << i << "] - '" << char(v[i]) << "' - int " << int(v[i])
+ << std::endl;
+
+ std::bitset<8> b(v[i]);
+
+ for(int j = 0; j < 8; j++)
+ std::cout << i << ":" << j << " " << b.test(j) << std::endl;
+
+ std::cout << std::endl;
+ }
+}
+#endif
diff --git a/src/plugins/Input/opus/tdebug.h b/src/plugins/Input/opus/tdebug.h
new file mode 100644
index 000000000..5204fe707
--- /dev/null
+++ b/src/plugins/Input/opus/tdebug.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
+ * 02110-1301 USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_DEBUG_H
+#define TAGLIB_DEBUG_H
+
+namespace TagLib {
+
+ class String;
+ class ByteVector;
+
+#ifndef DO_NOT_DOCUMENT
+#ifndef NDEBUG
+
+ /*!
+ * A simple function that prints debugging output to cerr if debugging is
+ * not disabled.
+ *
+ * \warning Do not use this outside of TagLib, it could lead to undefined
+ * symbols in your build if TagLib is built with NDEBUG defined and your
+ * application is not.
+ *
+ * \internal
+ */
+ void debug(const String &s);
+
+ /*!
+ * For debugging binary data.
+ *
+ * \warning Do not use this outside of TagLib, it could lead to undefined
+ * symbols in your build if TagLib is built with NDEBUG defined and your
+ * application is not.
+ *
+ * \internal
+ */
+ void debugData(const ByteVector &v);
+
+#else
+
+ // Define these to an empty statement if debugging is disabled.
+
+#define debug(x)
+#define debugData(x)
+
+#endif
+#endif
+}
+
+#endif
diff --git a/src/plugins/Input/opus/translations/opus_plugin_cs.ts b/src/plugins/Input/opus/translations/opus_plugin_cs.ts
new file mode 100644
index 000000000..31b208182
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_cs.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="cs">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">Autor: Ilja Kotov &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">Délka</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">Vzorkovací frekvence</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished">Hz</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">Počet kanálů</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">Datový tok</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished">kbps</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">Velikost souboru</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished">KiB</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_de.ts b/src/plugins/Input/opus/translations/opus_plugin_de.ts
new file mode 100644
index 000000000..183d65ef6
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_de.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="de_DE">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">Autor: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">Länge</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">Abtastrate</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished">Hz</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">Kanäle</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">Bitrate</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished">kbps</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">Dateigröße</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished">KB</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_es.ts b/src/plugins/Input/opus/translations/opus_plugin_es.ts
new file mode 100644
index 000000000..c369935d1
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_es.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="es">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">Escrito por: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">Duración</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">Frecuencia</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished">Hz</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">Canales</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">Tasa de bits</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished">kbps</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">Tamaño del archivo</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished">KB</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_fr.ts b/src/plugins/Input/opus/translations/opus_plugin_fr.ts
new file mode 100644
index 000000000..fdce467cb
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_fr.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr_FR">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_he.ts b/src/plugins/Input/opus/translations/opus_plugin_he.ts
new file mode 100644
index 000000000..6df6cc745
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_he.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="he_IL">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">חוברה על ידי: Ilya Kotov ‫&lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">אריכות</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">שיעור דגימה</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished">הרץ</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">ערוצים</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">שיעור סיביות</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">גודל קובץ</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished">ק״ב</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_hu.ts b/src/plugins/Input/opus/translations/opus_plugin_hu.ts
new file mode 100644
index 000000000..d3c3202b4
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_hu.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="hu_HU">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_it.ts b/src/plugins/Input/opus/translations/opus_plugin_it.ts
new file mode 100644
index 000000000..834563503
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_it.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="de">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">Autore: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">Durata</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">Campionamento</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished">Hz</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">Canali</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">bit al secondo</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished">kbps</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">Dimensione file</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished">KB</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_ja.ts b/src/plugins/Input/opus/translations/opus_plugin_ja.ts
new file mode 100644
index 000000000..97eeb1089
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_ja.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="ja_JP">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">制作: Илья Котов (Ilya Kotov) &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">長さ</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">サンプルレート</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished">Hz</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">チャンネル</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">ビットレート</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished">キロビット毎秒</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">ファイルの大きさ</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished">KiB</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_kk.ts b/src/plugins/Input/opus/translations/opus_plugin_kk.ts
new file mode 100644
index 000000000..bb729f853
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_kk.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="kk_KZ">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_lt.ts b/src/plugins/Input/opus/translations/opus_plugin_lt.ts
new file mode 100644
index 000000000..688d9a1fa
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_lt.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="lt">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">Sukūrė: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">Trukmė</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">Dažnis</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished">Hz</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">Kanalai</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">Kokybė</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished">kbps</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">Bylos dydis</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished">KB</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_nl.ts b/src/plugins/Input/opus/translations/opus_plugin_nl.ts
new file mode 100644
index 000000000..bfaeabdf1
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_nl.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="nl">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">Auteur: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">Duur</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">Sample frequentie</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">Kanalen</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">Bitsnelheid</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">Bestandsnaam</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_pl.ts b/src/plugins/Input/opus/translations/opus_plugin_pl.ts
new file mode 100644
index 000000000..a7d51c5b4
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_pl.ts
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="pl">
+<context>
+ <name>DecoderVorbisFactory</name>
+ <message>
+ <location filename="../decodervorbisfactory.cpp" line="50"/>
+ <source>Ogg Vorbis Plugin</source>
+ <translation>Wtyczka Ogg Vorbis</translation>
+ </message>
+ <message>
+ <location filename="../decodervorbisfactory.cpp" line="53"/>
+ <source>Ogg Vorbis Files</source>
+ <translation>Pliki Ogg Vorbis</translation>
+ </message>
+ <message>
+ <location filename="../decodervorbisfactory.cpp" line="124"/>
+ <source>About Ogg Vorbis Audio Plugin</source>
+ <translation>O wtyczce Ogg Vorbis Audio</translation>
+ </message>
+ <message>
+ <location filename="../decodervorbisfactory.cpp" line="125"/>
+ <source>Qmmp Ogg Vorbis Audio Plugin</source>
+ <translation>Wtyczka Ogg Vorbis dla Qmmp</translation>
+ </message>
+ <message>
+ <location filename="../decodervorbisfactory.cpp" line="126"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation>Autor: Ilja Kotov &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+ <message>
+ <location filename="../decodervorbisfactory.cpp" line="127"/>
+ <source>Source code based on mq3 project</source>
+ <translation>Kod źródłowy oparty jest na projekcie mq3</translation>
+ </message>
+</context>
+<context>
+ <name>VorbisMetaDataModel</name>
+ <message>
+ <location filename="../vorbismetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation>Długość</translation>
+ </message>
+ <message>
+ <location filename="../vorbismetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation>Próbkowanie</translation>
+ </message>
+ <message>
+ <location filename="../vorbismetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../vorbismetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation>Kanały</translation>
+ </message>
+ <message>
+ <location filename="../vorbismetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation>Szybkość transmisji</translation>
+ </message>
+ <message>
+ <location filename="../vorbismetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../vorbismetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation>Wielkość pliku</translation>
+ </message>
+ <message>
+ <location filename="../vorbismetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation></translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_pl_PL.ts b/src/plugins/Input/opus/translations/opus_plugin_pl_PL.ts
new file mode 100644
index 000000000..cadc65139
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_pl_PL.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="pl">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">Autor: Ilja Kotov &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">Długość</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">Próbkowanie</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">Kanały</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">Szybkość transmisji</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">Wielkość pliku</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_pt_BR.ts b/src/plugins/Input/opus/translations/opus_plugin_pt_BR.ts
new file mode 100644
index 000000000..e096dcf33
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_pt_BR.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="pt_BR">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_ru.ts b/src/plugins/Input/opus/translations/opus_plugin_ru.ts
new file mode 100644
index 000000000..0346ba092
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_ru.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="ru">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">Разработчик: Илья Котов &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">Длительность</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">Дискретизация</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished">Гц</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">Каналов</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">Битовая частота</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished">Кб/с</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">Размер файла</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished">КБ</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_sk.ts b/src/plugins/Input/opus/translations/opus_plugin_sk.ts
new file mode 100644
index 000000000..f313e9615
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_sk.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="sk_SK">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_tr.ts b/src/plugins/Input/opus/translations/opus_plugin_tr.ts
new file mode 100644
index 000000000..110b3ccb6
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_tr.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="tr_TR">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">Yazan: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished">Hz</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished">kbps</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished">KB</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_uk_UA.ts b/src/plugins/Input/opus/translations/opus_plugin_uk_UA.ts
new file mode 100644
index 000000000..b14a85465
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_uk_UA.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="uk">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">Розробник: Ілля Котов &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">Тривалість</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">Частота</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished">Гц</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">Канали</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">Бітрейт</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished">Кб/с</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">Розмір файлу</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished">Кб</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_zh_CN.ts b/src/plugins/Input/opus/translations/opus_plugin_zh_CN.ts
new file mode 100644
index 000000000..d29ac0273
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_zh_CN.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="zh_CN">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">作者:Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">长度</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">取样率</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">声音通道</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">比特率</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">文件大小</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/opus_plugin_zh_TW.ts b/src/plugins/Input/opus/translations/opus_plugin_zh_TW.ts
new file mode 100644
index 000000000..f42a9046b
--- /dev/null
+++ b/src/plugins/Input/opus/translations/opus_plugin_zh_TW.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="zh_TW">
+<context>
+ <name>DecoderOpusFactory</name>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="48"/>
+ <source>Opus Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="51"/>
+ <source>Ogg Opus Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="122"/>
+ <source>About Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="123"/>
+ <source>Qmmp Opus Audio Plugin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../decoderopusfactory.cpp" line="124"/>
+ <source>Written by: Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</source>
+ <translation type="unfinished">作者:Ilya Kotov &lt;forkotov02@hotmail.ru&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>OpusMetaDataModel</name>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="51"/>
+ <source>Length</source>
+ <translation type="unfinished">長度</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Sample rate</source>
+ <translation type="unfinished">取樣率</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="52"/>
+ <source>Hz</source>
+ <translation type="unfinished">Hz</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="53"/>
+ <source>Channels</source>
+ <translation type="unfinished">聲音通道</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>Bitrate</source>
+ <translation type="unfinished">比特率</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="54"/>
+ <source>kbps</source>
+ <translation type="unfinished">kbps</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>File size</source>
+ <translation type="unfinished">文件大小</translation>
+ </message>
+ <message>
+ <location filename="../opusmetadatamodel.cpp" line="55"/>
+ <source>KB</source>
+ <translation type="unfinished">KB</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/plugins/Input/opus/translations/translations.qrc b/src/plugins/Input/opus/translations/translations.qrc
new file mode 100644
index 000000000..f2f256263
--- /dev/null
+++ b/src/plugins/Input/opus/translations/translations.qrc
@@ -0,0 +1,24 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource>
+ <file>opus_plugin_ru.qm</file>
+ <file>opus_plugin_uk_UA.qm</file>
+ <file>opus_plugin_zh_CN.qm</file>
+ <file>opus_plugin_zh_TW.qm</file>
+ <file>opus_plugin_tr.qm</file>
+ <file>opus_plugin_cs.qm</file>
+ <file>opus_plugin_pt_BR.qm</file>
+ <file>opus_plugin_de.qm</file>
+ <file>opus_plugin_pl_PL.qm</file>
+ <file>opus_plugin_fr.qm</file>
+ <file>opus_plugin_it.qm</file>
+ <file>opus_plugin_kk.qm</file>
+ <file>opus_plugin_lt.qm</file>
+ <file>opus_plugin_hu.qm</file>
+ <file>opus_plugin_nl.qm</file>
+ <file>opus_plugin_ja.qm</file>
+ <file>opus_plugin_sk.qm</file>
+ <file>opus_plugin_es.qm</file>
+ <file>opus_plugin_he.qm</file>
+ </qresource>
+</RCC>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_cs.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_cs.ts
index 1dc6b097b..8161e5188 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_cs.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_cs.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>Odstranit</translation>
</message>
@@ -842,7 +842,7 @@
<translation>...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>Přejmenovat</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_de.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_de.ts
index 85c176c60..c1dc4fcb2 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_de.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_de.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>Löschen</translation>
</message>
@@ -842,7 +842,7 @@
<translation>…</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>Umbenennen</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_es.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_es.ts
index e0a9d6656..0070f2f44 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_es.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_es.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>Borrar</translation>
</message>
@@ -842,7 +842,7 @@
<translation>...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>Renombrar</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_fr.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_fr.ts
index d79ff71c6..4440ae1d4 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_fr.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_fr.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation type="unfinished">Supprimer</translation>
</message>
@@ -842,7 +842,7 @@
<translation type="unfinished">...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation type="unfinished"></translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_he.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_he.ts
index 0e1abf0e7..afd4b5831 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_he.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_he.ts
@@ -834,7 +834,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>מחק</translation>
</message>
@@ -845,7 +845,7 @@
<translation></translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>שנה שם</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_hu.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_hu.ts
index e31ebade1..143f5373a 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_hu.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_hu.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>Törlés</translation>
</message>
@@ -842,7 +842,7 @@
<translation>...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>Átnevez</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_it.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_it.ts
index 8806cfc5b..8f9c25a0d 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_it.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_it.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>Elimina</translation>
</message>
@@ -842,7 +842,7 @@
<translation>...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>Rinomina</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_ja.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_ja.ts
index 607915e0e..af895441a 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_ja.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_ja.ts
@@ -832,7 +832,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>削除</translation>
</message>
@@ -843,7 +843,7 @@
<translation>...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>名前を変更</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_kk.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_kk.ts
index 3740012f5..5f0e98098 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_kk.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_kk.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation type="unfinished">Өшіру</translation>
</message>
@@ -842,7 +842,7 @@
<translation type="unfinished">...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation type="unfinished"></translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_lt.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_lt.ts
index bafdfce46..d9eed6a17 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_lt.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_lt.ts
@@ -832,7 +832,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>Ištrinti</translation>
</message>
@@ -843,7 +843,7 @@
<translation>...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>Pervadinti</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_nl.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_nl.ts
index 8d418036b..e3aaedf80 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_nl.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_nl.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>Verwijder</translation>
</message>
@@ -842,7 +842,7 @@
<translation></translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>Hernoem</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_pl_PL.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_pl_PL.ts
index 7a0d53d65..ee00d4d80 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_pl_PL.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_pl_PL.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>Usuń</translation>
</message>
@@ -842,7 +842,7 @@
<translation>...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>Zmień nazwę</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_pt_BR.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_pt_BR.ts
index f28963d91..fcdbf36fd 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_pt_BR.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_pt_BR.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation type="unfinished">Remover</translation>
</message>
@@ -842,7 +842,7 @@
<translation type="unfinished">...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation type="unfinished"></translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_ru.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_ru.ts
index 53f544a80..375bae2c9 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_ru.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_ru.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>Удалить</translation>
</message>
@@ -842,7 +842,7 @@
<translation>...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>Переименовать</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_sk.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_sk.ts
index 8ab867b45..682fc27e6 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_sk.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_sk.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>Vymazať</translation>
</message>
@@ -842,7 +842,7 @@
<translation>...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>Premenovať</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_tr.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_tr.ts
index 3855db1ca..768d211da 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_tr.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_tr.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation type="unfinished">Sil</translation>
</message>
@@ -842,7 +842,7 @@
<translation type="unfinished">...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation type="unfinished"></translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_uk_UA.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_uk_UA.ts
index 7f258e759..c7331b9ff 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_uk_UA.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_uk_UA.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation>Видалити</translation>
</message>
@@ -842,7 +842,7 @@
<translation>...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation>Переіменувати</translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_zh_CN.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_zh_CN.ts
index 4a4e00c6b..ed3619a67 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_zh_CN.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_zh_CN.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation type="unfinished">删除</translation>
</message>
@@ -842,7 +842,7 @@
<translation type="unfinished">...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation type="unfinished"></translation>
</message>
diff --git a/src/plugins/Ui/skinned/translations/skinned_plugin_zh_TW.ts b/src/plugins/Ui/skinned/translations/skinned_plugin_zh_TW.ts
index 0a3bfd62f..d626a54c6 100644
--- a/src/plugins/Ui/skinned/translations/skinned_plugin_zh_TW.ts
+++ b/src/plugins/Ui/skinned/translations/skinned_plugin_zh_TW.ts
@@ -831,7 +831,7 @@
</message>
<message>
<location filename="../forms/playlistbrowser.ui" line="52"/>
- <location filename="../playlistbrowser.cpp" line="39"/>
+ <location filename="../playlistbrowser.cpp" line="40"/>
<source>Delete</source>
<translation type="unfinished">移除</translation>
</message>
@@ -842,7 +842,7 @@
<translation type="unfinished">...</translation>
</message>
<message>
- <location filename="../playlistbrowser.cpp" line="38"/>
+ <location filename="../playlistbrowser.cpp" line="39"/>
<source>Rename</source>
<translation type="unfinished"></translation>
</message>