From 2d622fd9bcb8da9dd3f3206e296cd6a701fc9d12 Mon Sep 17 00:00:00 2001 From: vovanec Date: Sat, 23 Jun 2007 16:48:01 +0000 Subject: moved into qmmp dir git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@12 90c681e8-e032-0410-971d-27865f9a5e38 --- lib/decoder.cpp | 270 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 lib/decoder.cpp (limited to 'lib/decoder.cpp') diff --git a/lib/decoder.cpp b/lib/decoder.cpp new file mode 100644 index 000000000..b77b780b4 --- /dev/null +++ b/lib/decoder.cpp @@ -0,0 +1,270 @@ +// Copyright (c) 2000-2001 Brad Hughes +// +// Use, modification and distribution is allowed without limitation, +// warranty, or liability of any kind. +// +#include +#include +#include +#include +#include + + +#include "constants.h" +#include "buffer.h" +#include "output.h" +#include "visualization.h" +#include "decoderfactory.h" +extern "C"{ +#include "equ/iir.h" +} +#include "decoder.h" + + +Decoder::Decoder(QObject *parent, DecoderFactory *d, QIODevice *i, Output *o) + : QThread(parent), fctry(d), in(i), out(o), blksize(0),m_eqInited(FALSE), + m_useEQ(FALSE) +{ + out->recycler()->clear(); + int b[] = {0,0,0,0,0,0,0,0,0,0}; + setEQ(b, 0); + qRegisterMetaType("DecoderState"); +} + +Decoder::~Decoder() +{ + fctry = 0; + in = 0; + out = 0; + blksize = 0; +} + +// static methods + +static QList *factories = 0; +static QStringList files; +static QStringList blacklist; + +static void checkFactories() +{ + QSettings settings ( QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat ); + blacklist = settings.value("Decoder/disabled_plugins").toStringList (); + if (! factories) + { + files.clear(); + factories = new QList; + + QDir pluginsDir (qApp->applicationDirPath()); + pluginsDir.cdUp(); + pluginsDir.cd("lib/qmmp/Input"); + foreach (QString fileName, pluginsDir.entryList(QDir::Files)) + { + QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); + QObject *plugin = loader.instance(); + if (loader.isLoaded()) + { + qDebug("Decoder: plugin loaded - %s", qPrintable(fileName)); + } + DecoderFactory *factory = 0; + if (plugin) + factory = qobject_cast(plugin); + + if (factory) + { + factories->append(factory); + files << pluginsDir.absoluteFilePath(fileName); + } + } + //remove physically deleted plugins from blacklist + QStringList names; + foreach (QString filePath, files) + { + names.append(filePath.section('/',-1)); + } + int i = 0; + while (i < blacklist.size()) + { + if (!names.contains(blacklist.at(i))) + blacklist.removeAt(i); + else + i++; + } + settings.setValue("Decoder/disabled_plugins",blacklist); + } +} + + +QStringList Decoder::all() +{ + checkFactories(); + + QStringList l; + DecoderFactory *fact; + foreach(fact, *factories) + { + l << fact->description(); + } + return l; +} + +QStringList Decoder::decoderFiles() +{ + checkFactories(); + return files; +} + + +bool Decoder::supports(const QString &source) +{ + checkFactories(); + + for (int i=0; isize(); ++i) + { + if (factories->at(i)->supports(source) && + !blacklist.contains(files.at(i).section('/',-1))) + { + return TRUE; + } + } + return FALSE; +} + +Decoder *Decoder::create(QObject *parent, const QString &source, + QIODevice *input, + Output *output) +{ + Decoder *decoder = 0; + + DecoderFactory *fact = Decoder::findFactory(source); + if (fact) + { + decoder = fact->create(parent, input, output); + } + return decoder; +} + +DecoderFactory *Decoder::findFactory(const QString& source) +{ + checkFactories(); + + for (int i=0; isize(); ++i) + { + if (factories->at(i)->supports(source) && + !blacklist.contains(files.at(i).section('/',-1))) + { + return factories->at(i); + } + } + qDebug("Decoder: unable to find factory"); + return 0; +} + +FileTag *Decoder::createTag(const QString& source) +{ + DecoderFactory *fact = Decoder::findFactory(source); + if (fact) + { + return fact->createTag(source); + } + return 0; +} + +QString Decoder::filter() +{ + QString allflt(tr("All Supported Bitstreams (")); + QString flt; + + checkFactories(); + DecoderFactory *fact; + for (int i = 0; isize(); ++i) + { + if (!blacklist.contains(files.at(i).section('/',-1))) + { + fact = (*factories)[i]; + allflt +=fact->filter().toLower() +" "; + flt += fact->description() + " (" + fact->filter().toLower() + ")"; + flt += ";;"; + } + } + if (!flt.isEmpty ()) + flt = flt.left(flt.size ()-2); + + allflt += ");;"; + + return allflt + flt; +} + +QStringList Decoder::nameFilters() +{ + checkFactories(); + QStringList filters; + for (int i=0; isize(); ++i) + { + if (!blacklist.contains(files.at(i).section('/',-1))) + filters << factories->at(i)->filter().split(" ", QString::SkipEmptyParts); + } + return filters; +} + +QList *Decoder::decoderFactories() +{ + checkFactories(); + return factories; +} + +void Decoder::dispatch(const DecoderState &st) +{ + emit stateChanged(st); +} + +void Decoder::dispatch(DecoderState::Type st) +{ + emit stateChanged(DecoderState(st)); +} + +void Decoder::error(const QString &e) +{ + emit stateChanged(DecoderState(e)); +} + +ulong Decoder::produceSound(char *data, ulong output_bytes, ulong bitrate, int nch) +{ + ulong sz = output_bytes < blksize ? output_bytes : blksize; + Buffer *b = output()->recycler()->get(); + + if (!m_eqInited) + { + init_iir(); + m_eqInited = TRUE; + } + if (m_useEQ) + { + iir((void*) data,sz,nch); + } + memcpy(b->data, data, sz); + + if (sz != blksize) + memset(b->data + sz, 0, blksize - sz); + + b->nbytes = blksize; + b->rate = bitrate; + + output()->recycler()->add(); + + output_bytes -= sz; + memmove(data, data + sz, output_bytes); + return sz; +} + +void Decoder::setEQ(int bands[10], int preamp) +{ + set_preamp(0, 1.0 + 0.0932471 *preamp + 0.00279033 * preamp * preamp); + set_preamp(1, 1.0 + 0.0932471 *preamp + 0.00279033 * preamp * preamp); + for (int i=0; i<10; ++i) + { + int value = bands[i]; + set_gain(i,0, 0.03*value+0.000999999*value*value); + set_gain(i,1, 0.03*value+0.000999999*value*value); + } +} + -- cgit v1.2.3-13-gbd6f