From 9638e8ae7f37000caa171018777d445cf1748dd7 Mon Sep 17 00:00:00 2001 From: trialuser02 Date: Fri, 30 Sep 2011 18:36:36 +0000 Subject: prepare for converter plugin implementation git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@2362 90c681e8-e032-0410-971d-27865f9a5e38 --- src/plugins/General/converter/converter.cpp | 182 +++++++++++++++++++++ src/plugins/General/converter/converter.h | 51 ++++++ src/plugins/General/converter/converter.pro | 50 ++++++ src/plugins/General/converter/converterdialog.cpp | 50 ++++++ src/plugins/General/converter/converterdialog.h | 45 +++++ src/plugins/General/converter/converterdialog.ui | 135 +++++++++++++++ src/plugins/General/converter/converterfactory.cpp | 63 +++++++ src/plugins/General/converter/converterfactory.h | 44 +++++ src/plugins/General/converter/converterhelper.cpp | 70 ++++++++ src/plugins/General/converter/converterhelper.h | 54 ++++++ 10 files changed, 744 insertions(+) create mode 100644 src/plugins/General/converter/converter.cpp create mode 100644 src/plugins/General/converter/converter.h create mode 100644 src/plugins/General/converter/converter.pro create mode 100644 src/plugins/General/converter/converterdialog.cpp create mode 100644 src/plugins/General/converter/converterdialog.h create mode 100644 src/plugins/General/converter/converterdialog.ui create mode 100644 src/plugins/General/converter/converterfactory.cpp create mode 100644 src/plugins/General/converter/converterfactory.h create mode 100644 src/plugins/General/converter/converterhelper.cpp create mode 100644 src/plugins/General/converter/converterhelper.h (limited to 'src/plugins/General') diff --git a/src/plugins/General/converter/converter.cpp b/src/plugins/General/converter/converter.cpp new file mode 100644 index 000000000..23ce7599f --- /dev/null +++ b/src/plugins/General/converter/converter.cpp @@ -0,0 +1,182 @@ +/*************************************************************************** + * Copyright (C) 2011 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "converter.h" + +Converter::Converter(QObject *parent) : QThread(parent) +{} + +void Converter::add(const QStringList &urls) +{ + foreach(QString url, urls) + add(url); + +} + +void Converter::add(const QString &url) +{ + InputSource *source = InputSource::create(url, this); + if(!source->initialize()) + { + delete source; + qWarning("Converter: Invalid url"); + return; + } + + if(source->ioDevice()) + { + source->ioDevice()->open(QIODevice::ReadOnly); + } + + DecoderFactory *factory = 0; + + if(!source->url().contains("://")) + factory = Decoder::findByPath(source->url()); + if(!factory) + factory = Decoder::findByMime(source->contentType()); + if(!factory && source->ioDevice() && source->url().contains("://")) //ignore content of local files + factory = Decoder::findByContent(source->ioDevice()); + if(!factory && source->url().contains("://")) + factory = Decoder::findByProtocol(source->url().section("://",0,0)); + if(!factory) + { + qWarning("Converter: unsupported file format"); + return; + } + qDebug("Converter: selected decoder: %s",qPrintable(factory->properties().shortName)); + if(factory->properties().noInput && source->ioDevice()) + source->ioDevice()->close(); + Decoder *decoder = factory->create(source->url(), source->ioDevice()); + if(!decoder->initialize()) + { + qWarning("Converter: invalid file format"); + delete decoder; + return; + } + m_decoders.enqueue(decoder); + m_inputs.insert(decoder, source); + if(!decoder->totalTime()) + source->setOffset(-1); + source->setParent(this); +} + +void Converter::run() +{ + while(!m_decoders.isEmpty()) + { + Decoder *decoder = m_decoders.dequeue(); + AudioParameters ap = decoder->audioParameters(); + + char wave_header[] = { 0x52, 0x49, 0x46, 0x46, //"RIFF" + 0x00, 0x00, 0x00, 0x00, //(file size) - 8 + 0x57, 0x41, 0x56, 0x45, //WAVE + 0x66, 0x6d, 0x74, 0x20, //"fmt " + 0x10, 0x00, 0x00, 0x00, //16 + extra format bytes + 0x01, 0x00, 0x02, 0x00, //PCM/uncompressed, channels + 0x00, 0x00, 0x00, 0x00, //sample rate + 0x00, 0x00, 0x00, 0x00, //average bytes per second + 0x04, 0x00, 0x10, 0x00, //block align, significant bits per sample + 0x64, 0x61, 0x74, 0x61, //"data" + 0x00, 0x00, 0x00, 0x00 }; //chunk size*/ + + quint32 sample_rate = qToLittleEndian(ap.sampleRate()); + quint16 channels = qToLittleEndian((quint16)ap.channels()); + quint16 block_align = qToLittleEndian((quint16)ap.sampleSize() * ap.channels()); + quint16 bps = qToLittleEndian((quint16)ap.sampleSize() * 8); + quint32 size = decoder->totalTime() * ap.sampleRate() * ap.channels() * ap.sampleSize() / 1000; + size = qToLittleEndian(size); + + memcpy(&wave_header[22], &channels, 2); + memcpy(&wave_header[24], &sample_rate, 4); + memcpy(&wave_header[32], &block_align, 2); + memcpy(&wave_header[34], &bps, 2); + memcpy(&wave_header[40], &size, 4); + + //FILE *enc_pipe = fopen("/mnt/win_e/out.wav", "w"); + FILE *enc_pipe = popen("oggenc -q 1 -o \"/mnt/win_e/out 55.ogg\" -", "w"); + if(!enc_pipe) + { + qWarning("Converter: unable to open pipe"); + delete decoder; + continue; + + } + size_t to_write = sizeof(wave_header); + if(to_write != fwrite(&wave_header, 1, to_write, enc_pipe)) + { + delete decoder; + pclose(enc_pipe); + continue; + } + + convert(decoder, enc_pipe); + pclose(enc_pipe); + //fclose(enc_pipe); + delete decoder; + } +} + +bool Converter::convert(Decoder *decoder, FILE *file) +{ + const int buf_size = 8192; + unsigned char output_buf[buf_size]; + qint64 output_at = 0; + qint64 total = 0; + quint64 len = 0; + AudioParameters ap = decoder->audioParameters(); + qint64 size = decoder->totalTime() * ap.sampleRate() * ap.channels() * ap.sampleSize() / 1000; + forever + { + // decode + len = decoder->read((char *)(output_buf + output_at), buf_size - output_at); + + if (len > 0) + { + output_at += len; + total += len; + while(output_at > 0) + { + len = fwrite(output_buf, 1, output_at, file); + if(len == 0) + { + qWarning("Converter: error"); + return false; + } + output_at -= len; + memmove(output_buf, output_buf + len, output_at); + } + emit progress(floor(100*total/size)); + } + else if (len <= 0) + { + qDebug("Converter: total written: %lld bytes", total); + qDebug("finished!"); + return true; + } + } + return false; +} + diff --git a/src/plugins/General/converter/converter.h b/src/plugins/General/converter/converter.h new file mode 100644 index 000000000..06ac844de --- /dev/null +++ b/src/plugins/General/converter/converter.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2011 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef CONVERTER_H +#define CONVERTER_H + +#include +#include +#include +#include +#include +#include + +class Converter : public QThread +{ + Q_OBJECT +public: + explicit Converter(QObject *parent = 0); + + void add(const QStringList &urls); + void add(const QString &url); + +signals: + void progress(int percent); + +private: + void run(); + bool convert(Decoder *decoder, FILE *file); + QQueue m_decoders; + QHash m_inputs; + +}; + +#endif // CONVERTER_H diff --git a/src/plugins/General/converter/converter.pro b/src/plugins/General/converter/converter.pro new file mode 100644 index 000000000..24fcf00ce --- /dev/null +++ b/src/plugins/General/converter/converter.pro @@ -0,0 +1,50 @@ +include(../../plugins.pri) + +INCLUDEPATH += ../../../../src +CONFIG += release \ +warn_on \ +plugin + +TARGET =$$PLUGINS_PREFIX/General/converter +unix:QMAKE_CLEAN = $$PLUGINS_PREFIX/General/libconverter.so + + +TEMPLATE = lib +unix:QMAKE_LIBDIR += ../../../../lib +unix:LIBS += -lqmmpui -lqmmp + +win32:QMAKE_LIBDIR += ../../../../bin +win32:LIBS += -lqmmpui0 -lqmmp0 + +#TRANSLATIONS = translations/converter_plugin_cs.ts \ +# translations/converter_plugin_de.ts \ +# translations/converter_plugin_zh_CN.ts \ +# translations/converter_plugin_zh_TW.ts \ +# translations/converter_plugin_ru.ts \ +# translations/converter_plugin_pl.ts \ +# translations/converter_plugin_uk_UA.ts \ +# translations/converter_plugin_it.ts \ +# translations/converter_plugin_tr.ts \ +# translations/converter_plugin_lt.ts \ +# translations/converter_plugin_nl.ts \ +# translations/converter_plugin_ja.ts \ +# translations/converter_plugin_es.ts +#RESOURCES = translations/translations.qrc +unix{ +isEmpty(LIB_DIR){ + LIB_DIR = /lib +} +target.path = $$LIB_DIR/qmmp/General +INSTALLS += target +} +HEADERS += converterfactory.h \ + converterhelper.h \ + converterdialog.h \ + converter.h +win32:HEADERS += ../../../../src/qmmpui/general.h +SOURCES += converterfactory.cpp \ + converterhelper.cpp \ + converterdialog.cpp \ + converter.cpp + +FORMS += converterdialog.ui diff --git a/src/plugins/General/converter/converterdialog.cpp b/src/plugins/General/converter/converterdialog.cpp new file mode 100644 index 000000000..501d92ead --- /dev/null +++ b/src/plugins/General/converter/converterdialog.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2011 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include "converterdialog.h" + +ConverterDialog::ConverterDialog(QList items, QWidget *parent) : QDialog(parent) +{ + ui.setupUi(this); + + MetaDataFormatter formatter("%p%if(%p&%t, - ,)%t - %l"); + + foreach(PlayListItem *item , items) + { + QString text = formatter.parse(item); + QListWidgetItem *listItem = new QListWidgetItem(text); + listItem->setData(Qt::UserRole, item->url()); + listItem->setCheckState(Qt::Checked); + ui.itemsListWidget->addItem(listItem); + } +} + +QStringList ConverterDialog::selectedUrls() const +{ + QStringList out; + for(int i = 0; i < ui.itemsListWidget->count(); i++) + { + if(ui.itemsListWidget->item(i)->checkState() == Qt::Checked) + out << ui.itemsListWidget->item(i)->data(Qt::UserRole).toString(); + } + return out; +} diff --git a/src/plugins/General/converter/converterdialog.h b/src/plugins/General/converter/converterdialog.h new file mode 100644 index 000000000..154357176 --- /dev/null +++ b/src/plugins/General/converter/converterdialog.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2011 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef CONVERTERDIALOG_H +#define CONVERTERDIALOG_H + +#include +#include +#include "ui_converterdialog.h" + +class PlayListItem; + +/** + @author Ilya Kotov +*/ +class ConverterDialog : public QDialog +{ + Q_OBJECT +public: + explicit ConverterDialog(QList items, QWidget *parent = 0); + QStringList selectedUrls() const; + +private: + Ui::ConverterDialog ui; + +}; + +#endif // CONVERTERDIALOG_H diff --git a/src/plugins/General/converter/converterdialog.ui b/src/plugins/General/converter/converterdialog.ui new file mode 100644 index 000000000..b93390499 --- /dev/null +++ b/src/plugins/General/converter/converterdialog.ui @@ -0,0 +1,135 @@ + + + ConverterDialog + + + + 0 + 0 + 433 + 428 + + + + Dialog + + + + 6 + + + 6 + + + 6 + + + + + Select files to convert: + + + + + + + true + + + + + + + Output file directory: + + + + + + + + + + Output file name: + + + + + + + + + + Preseed: + + + + + + + + + + CheckBox + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + ... + + + + + + + ... + + + + + + + + + buttonBox + accepted() + ConverterDialog + accept() + + + 330 + 408 + + + 112 + 425 + + + + + buttonBox + rejected() + ConverterDialog + reject() + + + 393 + 407 + + + 383 + 425 + + + + + diff --git a/src/plugins/General/converter/converterfactory.cpp b/src/plugins/General/converter/converterfactory.cpp new file mode 100644 index 000000000..a452d32b9 --- /dev/null +++ b/src/plugins/General/converter/converterfactory.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2011 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include "converterhelper.h" +#include "converterfactory.h" + +const GeneralProperties ConverterFactory::properties() const +{ + GeneralProperties properties; + properties.name = tr("Converter Plugin"); + properties.shortName = "converter"; + properties.hasAbout = true; + properties.hasSettings = false; + properties.visibilityControl = false; + return properties; +} + +QObject *ConverterFactory::create(QObject *parent) +{ + return new ConverterHelper(parent); +} + +QDialog *ConverterFactory::createConfigDialog(QWidget *parent) +{ + Q_UNUSED(parent); + return 0; +} + +void ConverterFactory::showAbout(QWidget *parent) +{ + /*QMessageBox::about (parent, tr("About Converter Plugin"), + tr("Qmmp Converter Plugin")+"\n"+ + tr("")+"\n"+ + tr("Written by: Ilya Kotov "));*/ +} + +QTranslator *ConverterFactory::createTranslator(QObject *parent) +{ + QTranslator *translator = new QTranslator(parent); + QString locale = Qmmp::systemLanguageID(); + translator->load(QString(":/converter_plugin_") + locale); + return translator; +} + +Q_EXPORT_PLUGIN2(converter, ConverterFactory) diff --git a/src/plugins/General/converter/converterfactory.h b/src/plugins/General/converter/converterfactory.h new file mode 100644 index 000000000..33949664f --- /dev/null +++ b/src/plugins/General/converter/converterfactory.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2011 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef CONVERTERFACTORY_H +#define CONVERTERFACTORY_H + +/** + @author Ilya Kotov +*/ +#include +#include +#include +#include +#include + +class ConverterFactory : public QObject, public GeneralFactory +{ +Q_OBJECT +Q_INTERFACES(GeneralFactory) +public: + const GeneralProperties properties() const; + QObject *create(QObject *parent); + QDialog *createConfigDialog(QWidget *parent); + void showAbout(QWidget *parent); + QTranslator *createTranslator(QObject *parent); +}; + +#endif diff --git a/src/plugins/General/converter/converterhelper.cpp b/src/plugins/General/converter/converterhelper.cpp new file mode 100644 index 000000000..df5d61eb3 --- /dev/null +++ b/src/plugins/General/converter/converterhelper.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2011 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "converter.h" +#include "converterdialog.h" +#include "converterhelper.h" + +ConverterHelper::ConverterHelper(QObject *parent) : QObject(parent) +{ + m_action = new QAction(tr("Convert"), this); + m_action->setShortcut(tr("Meta+C")); + UiHelper::instance()->addAction(m_action, UiHelper::PLAYLIST_MENU); + connect (m_action, SIGNAL(triggered ()), SLOT(openConverter())); + m_converter = new Converter(this); + m_progress = new QProgressDialog(qApp->activeWindow()); + m_progress->setRange(0,100); + m_progress->setWindowTitle(tr("Converting...")); + m_progress->setCancelButtonText(tr("Cancel")); + connect(m_converter,SIGNAL(progress(int)),m_progress,SLOT(setValue(int))); + connect(m_converter, SIGNAL(finished()), m_progress, SLOT(reset())); +} + +ConverterHelper::~ConverterHelper() +{ + m_progress->deleteLater(); +} + +void ConverterHelper::openConverter() +{ + PlayListManager *pl_manager = MediaPlayer::instance()->playListManager(); + QList items = pl_manager->selectedPlayList()->selectedItems(); + if (items.isEmpty()) + return; + + ConverterDialog *d = new ConverterDialog(items, qApp->activeWindow ()); + if(QDialog::Accepted == d->exec()) + { + QStringList urls = d->selectedUrls(); + m_converter->add(urls); + if(!m_converter->isRunning()) + m_converter->start(); + + } + d->deleteLater(); +} diff --git a/src/plugins/General/converter/converterhelper.h b/src/plugins/General/converter/converterhelper.h new file mode 100644 index 000000000..312326680 --- /dev/null +++ b/src/plugins/General/converter/converterhelper.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2011 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef CONVERTERHELPER_H +#define CONVERTERHELPER_H + +#include + +#include +#include + +class QAction; +class QProgressDialog; +class Converter; + +/** + @author Ilya Kotov +*/ + +class ConverterHelper : public QObject +{ +Q_OBJECT +public: + ConverterHelper(QObject *parent = 0); + + ~ConverterHelper(); + +private slots: + void openConverter(); + +private: + QAction *m_action; + Converter *m_converter; + QProgressDialog *m_progress; + +}; + +#endif -- cgit v1.2.3-13-gbd6f