From bed87bc89a1258d3b3dc429f3df114c8c2655a6a Mon Sep 17 00:00:00 2001 From: trialuser02 Date: Sat, 25 Oct 2008 20:58:48 +0000 Subject: aac plugin git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@601 90c681e8-e032-0410-971d-27865f9a5e38 --- src/plugins/Input/aac/aac.pro | 39 ++++ src/plugins/Input/aac/aacfile.cpp | 120 ++++++++++ src/plugins/Input/aac/aacfile.h | 46 ++++ src/plugins/Input/aac/decoder_aac.cpp | 328 ++++++++++++++++++++++++++ src/plugins/Input/aac/decoder_aac.h | 78 +++++++ src/plugins/Input/aac/decoderaacfactory.cpp | 121 ++++++++++ src/plugins/Input/aac/decoderaacfactory.h | 54 +++++ src/plugins/Input/aac/detailsdialog.cpp | 115 +++++++++ src/plugins/Input/aac/detailsdialog.h | 49 ++++ src/plugins/Input/aac/detailsdialog.ui | 347 ++++++++++++++++++++++++++++ 10 files changed, 1297 insertions(+) create mode 100644 src/plugins/Input/aac/aac.pro create mode 100644 src/plugins/Input/aac/aacfile.cpp create mode 100644 src/plugins/Input/aac/aacfile.h create mode 100644 src/plugins/Input/aac/decoder_aac.cpp create mode 100644 src/plugins/Input/aac/decoder_aac.h create mode 100644 src/plugins/Input/aac/decoderaacfactory.cpp create mode 100644 src/plugins/Input/aac/decoderaacfactory.h create mode 100644 src/plugins/Input/aac/detailsdialog.cpp create mode 100644 src/plugins/Input/aac/detailsdialog.h create mode 100644 src/plugins/Input/aac/detailsdialog.ui (limited to 'src') diff --git a/src/plugins/Input/aac/aac.pro b/src/plugins/Input/aac/aac.pro new file mode 100644 index 000000000..5bc0cb38a --- /dev/null +++ b/src/plugins/Input/aac/aac.pro @@ -0,0 +1,39 @@ +include(../../plugins.pri) + +FORMS += detailsdialog.ui +HEADERS += decoderaacfactory.h \ + decoder_aac.h \ + detailsdialog.h \ + aacfile.h +SOURCES += decoder_aac.cpp \ + decoderaacfactory.cpp \ + detailsdialog.cpp \ + aacfile.cpp + +TARGET =$$PLUGINS_PREFIX/Input/aac +QMAKE_CLEAN =$$PLUGINS_PREFIX/Input/libaac.so + + +INCLUDEPATH += ../../../ +CONFIG += release \ +warn_on \ +plugin \ +link_pkgconfig +TEMPLATE = lib +QMAKE_LIBDIR += ../../../../lib +LIBS += -lqmmp -lfaad -L/usr/lib -I/usr/include +PKGCONFIG += taglib +#TRANSLATIONS = translations/mpc_plugin_ru.ts +# translations/mpc_plugin_uk_UA.ts +# translations/mpc_plugin_zh_CN.ts +# translations/mpc_plugin_zh_TW.ts +# translations/mpc_plugin_cs.ts +# translations/mpc_plugin_de.ts +#RESOURCES = translations/translations.qrc + +isEmpty(LIB_DIR){ + LIB_DIR = /lib +} + +target.path = $$LIB_DIR/qmmp/Input +INSTALLS += target diff --git a/src/plugins/Input/aac/aacfile.cpp b/src/plugins/Input/aac/aacfile.cpp new file mode 100644 index 000000000..9cf3184d8 --- /dev/null +++ b/src/plugins/Input/aac/aacfile.cpp @@ -0,0 +1,120 @@ +/*************************************************************************** + * Copyright (C) 2008 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 "aacfile.h" + +#define MAX_CHANNELS 6 + +static int adts_sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0}; + +AACFile::AACFile(QIODevice *i) +{ + m_length = 0; + m_bitrate = 0; + m_input = i; + parseADTS(); +} + +AACFile::~AACFile() +{ +} + +qint64 AACFile::length() +{ + return m_length; +} + +quint32 AACFile::bitrate() +{ + return m_bitrate; +} + +void AACFile::parseADTS() +{ + uchar *buf = new uchar[FAAD_MIN_STREAMSIZE*MAX_CHANNELS]; + qint64 buf_at = 0; + int frames, frame_length; + int t_framelength = 0; + int samplerate = 0; + float frames_per_sec, bytes_per_frame; + qint64 pos = m_input->pos(); + + m_input->seek(0); + + buf_at = m_input->read((char *)buf, FAAD_MIN_STREAMSIZE*MAX_CHANNELS); + + for (int i = 0; i < buf_at - 1; i++) + { + if (buf[i] == 0xff && (buf[i+1]&0xf6) == 0xf0) + { + memmove (buf, buf + i, buf_at - i); + buf_at -= i; + break; + } + } + + /* Read all frames to ensure correct time and bitrate */ + for (frames = 0; /* */; frames++) + { + //qDebug("frame header = %d", buf[0]); + buf_at += m_input->read((char *)buf + buf_at, FAAD_MIN_STREAMSIZE*MAX_CHANNELS - buf_at); + + if (buf_at > 7) + { + /* check syncword */ + if (!((buf[0] == 0xFF)&&((buf[1] & 0xF6) == 0xF0))) + break; + + if (frames == 0) + samplerate = adts_sample_rates[(buf[2]&0x3c)>>2]; + + frame_length = ((((unsigned int)buf[3] & 0x3)) << 11) + | (((unsigned int)buf[4]) << 3) | (buf[5] >> 5); + + t_framelength += frame_length; + + if (frame_length > buf_at) + break; + + buf_at -= frame_length; + memmove(buf, buf + frame_length, buf_at); + } + else + { + break; + } + } + m_input->seek(pos); + frames_per_sec = (float)samplerate/1024.0f; + if (frames != 0) + bytes_per_frame = (float)t_framelength/(float)(frames*1000); + else + bytes_per_frame = 0; + m_bitrate = (quint32)(8. * bytes_per_frame * frames_per_sec + 0.5); + + if (frames_per_sec != 0) + m_length = frames/frames_per_sec; + else + m_length = 1; +} diff --git a/src/plugins/Input/aac/aacfile.h b/src/plugins/Input/aac/aacfile.h new file mode 100644 index 000000000..2d2ca1db5 --- /dev/null +++ b/src/plugins/Input/aac/aacfile.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2008 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 AACFILE_H +#define AACFILE_H + +class QIODevice; + +/** + @author Ilya Kotov +*/ +class AACFile +{ +public: + AACFile(QIODevice *i); + + ~AACFile(); + + qint64 length(); + quint32 bitrate(); + +private: + void parseADTS(); + qint64 m_length; + quint32 m_bitrate; + QIODevice *m_input; + +}; + +#endif diff --git a/src/plugins/Input/aac/decoder_aac.cpp b/src/plugins/Input/aac/decoder_aac.cpp new file mode 100644 index 000000000..114c39a18 --- /dev/null +++ b/src/plugins/Input/aac/decoder_aac.cpp @@ -0,0 +1,328 @@ +/*************************************************************************** + * Copyright (C) 2006-2008 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 "decoder_aac.h" +#include "aacfile.h" + +#define AAC_BUFFER_SIZE 4096 + +// Decoder class + +DecoderAAC::DecoderAAC(QObject *parent, DecoderFactory *d, QIODevice *i, Output *o) + : Decoder(parent, d, i, o) +{ + m_inited = FALSE; + m_user_stop = FALSE; + m_output_buf = 0; + m_output_bytes = 0; + m_output_at = 0; + m_bks = 0; + m_done = FALSE; + m_finish = FALSE; + m_len = 0; + m_freq = 0; + m_bitrate = 0; + m_seekTime = -1.0; + m_totalTime = 0.0; + m_chan = 0; + m_output_size = 0; + m_data = 0; + m_input_buf = 0; + m_input_at = 0; +} + + +DecoderAAC::~DecoderAAC() +{ + deinit(); + if (data()) + { + if (data()->handle) + NeAACDecClose (data()->handle); + delete data(); + m_data = 0; + } + if (m_output_buf) + delete [] m_output_buf; + if (m_input_buf) + delete [] m_input_buf; + m_output_buf = 0; + m_input_buf = 0; +} + + +void DecoderAAC::stop() +{ + m_user_stop = TRUE; +} + + +void DecoderAAC::flush(bool final) +{ + ulong min = final ? 0 : m_bks; + + while ((! m_done && ! m_finish) && m_output_bytes > min) + { + output()->recycler()->mutex()->lock (); + + while ((! m_done && ! m_finish) && output()->recycler()->full()) + { + mutex()->unlock(); + + output()->recycler()->cond()->wait(output()->recycler()->mutex()); + + mutex()->lock (); + m_done = m_user_stop; + } + + if (m_user_stop || m_finish) + { + m_inited = FALSE; + m_done = TRUE; + } + else + { + m_output_bytes -= produceSound(m_output_buf, m_output_bytes, m_bitrate, m_chan); + m_output_size += m_bks; + m_output_at = m_output_bytes; + } + + if (output()->recycler()->full()) + { + output()->recycler()->cond()->wakeOne(); + } + + output()->recycler()->mutex()->unlock(); + } +} + + +bool DecoderAAC::initialize() +{ + m_bks = Buffer::size(); + m_inited = m_user_stop = m_done = m_finish = FALSE; + m_len = m_freq = m_bitrate = 0; + //chan = 0; + m_output_size = 0; + m_seekTime = -1.0; + m_totalTime = 0.0; + + + if (!input()) + { + qWarning("DecoderAAC: cannot initialize. No input."); + return FALSE; + } + if (!m_input_buf) + m_input_buf = new char[AAC_BUFFER_SIZE]; + + if (!m_output_buf) + m_output_buf = new char[globalBufferSize]; + m_output_at = 0; + m_output_bytes = 0; + m_input_at = 0; + + if (!input()->isOpen()) + { + if (!input()->open(QIODevice::ReadOnly)) + { + qWarning("DecoderAAC: unable to open input."); + return FALSE; + } + } + + if (!m_data) + m_data = new aac_data; + + data()->handle = NeAACDecOpen(); + + NeAACDecConfigurationPtr conf; + conf = NeAACDecGetCurrentConfiguration(data()->handle); + conf->downMatrix = 1; + conf->defSampleRate = 44100; + conf->dontUpSampleImplicitSBR = 0; + conf->defObjectType = LC; + conf->outputFormat = FAAD_FMT_16BIT; + NeAACDecSetConfiguration(data()->handle, conf); + m_input_at = input()->read((char *)m_input_buf, AAC_BUFFER_SIZE); + for (int i = 0; i < m_input_at - 1; i++) + { + if ((uchar)m_input_buf[i] == 0xff && ((uchar)m_input_buf[i+1]&0xf6) == 0xf0) + { + memmove (m_input_buf, m_input_buf + i, AAC_BUFFER_SIZE - i); + m_input_at -= i; + break; + } + } + AACFile aac_file(input()); + m_totalTime = aac_file.length(); + m_bitrate = aac_file.bitrate(); + + int res = NeAACDecInit (data()->handle, (unsigned char*) m_input_buf, m_input_at, &m_freq, &m_chan); + memmove(m_input_buf, m_input_buf + res, m_input_at - res); + m_input_at -= res; + + configure(m_freq, m_chan, 16); + + m_inited = TRUE; + qDebug("DecoderAAC: initialize succes"); + return TRUE; +} + +qint64 DecoderAAC::aac_decode(void *out) +{ + NeAACDecFrameInfo frame_info; + qint64 size = 0, to_read, read; + out = 0; + bool eof = FALSE; + + while (size <= 0 && !eof) + { + if (m_input_at < AAC_BUFFER_SIZE) + { + to_read = AAC_BUFFER_SIZE - m_input_at; + read = input()->read((char *) (m_input_buf + m_input_at), to_read); + eof = (read != to_read); + m_input_at += read; + } + + out = NeAACDecDecode(data()->handle, &frame_info, (uchar *)m_input_buf, m_input_at); + memmove(m_input_buf, m_input_buf + frame_info.bytesconsumed, m_input_at - frame_info.bytesconsumed); + m_input_at -= frame_info.bytesconsumed; + + if ((size = frame_info.samples * 2) > 0) + memcpy((void *) (m_output_buf + m_output_at), out, size); + } + return size; +} + +qint64 DecoderAAC::lengthInSeconds() +{ + if (!m_inited) + return 0; + + return m_totalTime; +} + + +void DecoderAAC::seek(qint64 pos) +{ + m_seekTime = pos; +} + + +void DecoderAAC::deinit() +{ + m_inited = m_user_stop = m_done = m_finish = FALSE; + m_len = m_freq = m_bitrate = 0; + m_chan = 0; + m_output_size = 0; +} + +void DecoderAAC::run() +{ + m_prebuf_pos = 0; + m_prebuf_size = 0; + mutex()->lock (); + if (!m_inited) + { + mutex()->unlock(); + return; + } + mutex()->unlock(); + + while (!m_done && !m_finish) + { + mutex()->lock (); + // decode + + if (m_seekTime >= 0.0) + { + //mpc_decoder_seek_seconds(&data()->decoder, seekTime); + input()->seek(m_seekTime * input()->size() / m_totalTime); + m_input_at = 0; + m_seekTime = -1.0; + } + + m_prebuf_size = aac_decode(m_prebuf2); + m_len = m_prebuf_size; + + if (m_len > 0) + { + //qDebug("flush"); + //bitrate = vbrUpd * data()->info.sample_freq / 1152; + m_output_at += m_len; + m_output_bytes += m_len; + + if (output()) + flush(); + + } + else if (m_len == 0) + { + flush(TRUE); + + if (output()) + { + output()->recycler()->mutex()->lock (); + // end of stream + while (!output()->recycler()->empty() && !m_user_stop) + { + output()->recycler()->cond()->wakeOne(); + mutex()->unlock(); + output()->recycler()->cond()->wait(output()->recycler()->mutex()); + mutex()->lock (); + } + output()->recycler()->mutex()->unlock(); + } + + m_done = TRUE; + if (!m_user_stop) + { + m_finish = TRUE; + } + } + else + { + // error in read + qWarning("DecoderAAC: Error while decoding stream, file appears to be corrupted"); + m_finish = TRUE; + } + + mutex()->unlock(); + } + mutex()->lock (); + + if (m_finish) + finish(); + + mutex()->unlock(); + deinit(); +} diff --git a/src/plugins/Input/aac/decoder_aac.h b/src/plugins/Input/aac/decoder_aac.h new file mode 100644 index 000000000..5a1d698ea --- /dev/null +++ b/src/plugins/Input/aac/decoder_aac.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2006-2008 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 DECODER_AAC_H +#define DECODER_AAC_H + + +#include + +#include + +struct aac_data +{ + NeAACDecHandle handle; +}; + +class DecoderAAC : public Decoder +{ +public: + DecoderAAC(QObject *, DecoderFactory *, QIODevice *, Output *); + virtual ~DecoderAAC(); + + // Standard Decoder API + bool initialize(); + qint64 lengthInSeconds(); + void seek(qint64); + void stop(); + + struct aac_data *data() + { + return m_data; + } + + +private: + // thread run function + void run(); + struct aac_data *m_data; + // helper functions + void flush(bool = FALSE); + void deinit(); + qint64 aac_decode(void *out); + + bool m_inited, m_user_stop; + + // output buffer + char *m_output_buf, *m_input_buf; + void *m_prebuf2; + qint64 m_output_bytes, m_output_at, m_input_at, m_prebuf_pos, m_prebuf_size; + + unsigned int m_bks; + bool m_done, m_finish; + long unsigned int m_len, m_freq, m_bitrate; + unsigned char m_chan; + unsigned long m_output_size; + double m_frameSize; //frame size in bytes + qint64 m_totalTime, m_seekTime; +}; + + +#endif // __decoder_aac_h diff --git a/src/plugins/Input/aac/decoderaacfactory.cpp b/src/plugins/Input/aac/decoderaacfactory.cpp new file mode 100644 index 000000000..2f5b621ee --- /dev/null +++ b/src/plugins/Input/aac/decoderaacfactory.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** + * Copyright (C) 2008 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 "aacfile.h" +#include "detailsdialog.h" +#include "decoder_aac.h" +#include "decoderaacfactory.h" + + +// DecoderAACFactory + +bool DecoderAACFactory::supports(const QString &source) const +{ + + return (source.right(4).toLower() == ".aac") + || (source.right(4).toLower() == ".m4a"); +} + +bool DecoderAACFactory::canDecode(QIODevice *) const +{ + return FALSE; +} + +const DecoderProperties DecoderAACFactory::properties() const +{ + DecoderProperties properties; + properties.name = tr("AAC Plugin"); + properties.filter = "*.aac"; + properties.description = tr("AAC Files"); + //properties.contentType = ; + properties.hasAbout = TRUE; + properties.hasSettings = FALSE; + return properties; +} + +Decoder *DecoderAACFactory::create(QObject *parent, QIODevice *input, + Output *output, const QString &) +{ + return new DecoderAAC(parent, this, input, output); +} + +QList DecoderAACFactory::createPlayList(const QString &fileName) +{ + FileInfo *info = new FileInfo(fileName); + + /*TagLib::FileRef fileRef(fileName.toLocal8Bit ()); + TagLib::Tag *tag = fileRef.tag(); + 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());*/ + QFile file(fileName); + if(file.open(QIODevice::ReadOnly)) + { + AACFile aac_file(&file); + info->setLength(aac_file.length()); + } + QList list; + list << info; + return list; +} + +QObject* DecoderAACFactory::showDetails(QWidget *parent, const QString &path) +{ + /*DetailsDialog *d = new DetailsDialog(parent, path); + d -> show();*/ + return 0; +} + +void DecoderAACFactory::showSettings(QWidget *) +{} + +void DecoderAACFactory::showAbout(QWidget *parent) +{ + QMessageBox::about (parent, tr("About AAC Audio Plugin"), + tr("Qmmp AAC Audio Plugin")+"\n"+ + tr("Writen by: Ilya Kotov ")); +} + +QTranslator *DecoderAACFactory::createTranslator(QObject *parent) +{ + QTranslator *translator = new QTranslator(parent); + QString locale = QLocale::system().name(); + translator->load(QString(":/aac_plugin_") + locale); + return translator; +} + +Q_EXPORT_PLUGIN(DecoderAACFactory) diff --git a/src/plugins/Input/aac/decoderaacfactory.h b/src/plugins/Input/aac/decoderaacfactory.h new file mode 100644 index 000000000..eb4fb6276 --- /dev/null +++ b/src/plugins/Input/aac/decoderaacfactory.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2006-2008 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 DECODERAACFACTORY_H +#define DECODERAACFACTORY_H + +#include +#include +#include +#include + +#include +#include +#include +#include + + + + +class DecoderAACFactory : public QObject, + DecoderFactory +{ +Q_OBJECT +Q_INTERFACES(DecoderFactory); + +public: + bool supports(const QString &source) const; + bool canDecode(QIODevice *input) const; + const DecoderProperties properties() const; + Decoder *create(QObject *, QIODevice *, Output *, const QString &); + QList createPlayList(const QString &fileName); + QObject* showDetails(QWidget *parent, const QString &path); + void showSettings(QWidget *parent); + void showAbout(QWidget *parent); + QTranslator *createTranslator(QObject *parent); +}; + +#endif diff --git a/src/plugins/Input/aac/detailsdialog.cpp b/src/plugins/Input/aac/detailsdialog.cpp new file mode 100644 index 000000000..472046717 --- /dev/null +++ b/src/plugins/Input/aac/detailsdialog.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + * Copyright (C) 2007 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include +#include +#include + +#include +#include + +#include "detailsdialog.h" + +#define QStringToTString_qt4(s) TagLib::String(s.toUtf8().constData(), TagLib::String::UTF8) + +DetailsDialog::DetailsDialog(QWidget *parent, const QString &path) + : QDialog(parent) +{ + ui.setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + m_path = path; + setWindowTitle (path.section('/',-1)); + path.section('/',-1); + ui.pathLineEdit->setText(m_path); + if(QFile::exists(m_path)) + { + loadMPCInfo(); + loadTag(); + } +} + + +DetailsDialog::~DetailsDialog() +{} + +void DetailsDialog::loadMPCInfo() +{ + TagLib::MPC::File f (m_path.toLocal8Bit()); + QString text; + text = QString("%1").arg(f.audioProperties()->length()/60); + text +=":"+QString("%1").arg(f.audioProperties()->length()%60,2,10,QChar('0')); + ui.lengthLabel->setText(text); + text = QString("%1").arg(f.audioProperties()->sampleRate()); + ui.sampleRateLabel->setText(text+" "+tr("Hz")); + text = QString("%1").arg(f.audioProperties()->channels()); + ui.channelsLabel->setText(text); + text = QString("%1").arg(f.audioProperties()->bitrate()); + ui.bitrateLabel->setText(text+" "+tr("kbps")); + text = QString("%1").arg(f.audioProperties()->mpcVersion()); + ui.versionLabel->setText(text); + text = QString("%1 "+tr("KB")).arg(f.length()/1024); + ui.fileSizeLabel->setText(text); +} + +void DetailsDialog::loadTag() +{ + TagLib::FileRef f (m_path.toLocal8Bit()); + + if (f.tag()) + { //TODO: load codec name from config + + TagLib::String title = f.tag()->title(); + TagLib::String artist = f.tag()->artist(); + TagLib::String album = f.tag()->album(); + TagLib::String comment = f.tag()->comment(); + TagLib::String genre = f.tag()->genre(); + QString string = QString::fromUtf8(title.toCString(TRUE)).trimmed(); + ui.titleLineEdit->setText(string); + string = QString::fromUtf8(artist.toCString(TRUE)).trimmed(); + ui.artistLineEdit->setText(string); + string = QString::fromUtf8(album.toCString(TRUE)).trimmed(); + ui.albumLineEdit->setText(string); + string = QString::fromUtf8(comment.toCString(TRUE)).trimmed(); + ui.commentLineEdit->setText(string); + string = QString("%1").arg(f.tag()->year()); + ui.yearLineEdit->setText(string); + string = QString("%1").arg(f.tag()->track()); + ui.trackLineEdit->setText(string); + string = QString::fromUtf8(genre.toCString(TRUE)).trimmed(); + ui.genreLineEdit->setText(string); + } + QFileInfo info(m_path); + ui.saveButton->setEnabled(info.isWritable()); + connect(ui.saveButton, SIGNAL(clicked()), SLOT(saveTag())); +} + +void DetailsDialog::saveTag() +{ + TagLib::FileRef f (m_path.toLocal8Bit()); + + f.tag()->setTitle(QStringToTString_qt4(ui.titleLineEdit->text())); + f.tag()->setArtist(QStringToTString_qt4(ui.artistLineEdit->text())); + f.tag()->setAlbum(QStringToTString_qt4(ui.albumLineEdit->text())); + f.tag()->setComment(QStringToTString_qt4(ui.commentLineEdit->text())); + f.tag()->setGenre(QStringToTString_qt4(ui.genreLineEdit->text())); + f.tag()->setYear(ui.yearLineEdit->text().toUInt()); + f.tag()->setTrack(ui.trackLineEdit->text().toUInt()); + + f.save(); +} diff --git a/src/plugins/Input/aac/detailsdialog.h b/src/plugins/Input/aac/detailsdialog.h new file mode 100644 index 000000000..70540bda1 --- /dev/null +++ b/src/plugins/Input/aac/detailsdialog.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2007 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DETAILSDIALOG_H +#define DETAILSDIALOG_H + +#include + +#include "ui_detailsdialog.h" + +/** + @author Ilya Kotov +*/ +class DetailsDialog : public QDialog +{ +Q_OBJECT +public: + DetailsDialog(QWidget *parent = 0, const QString &path = 0); + + ~DetailsDialog(); + +private slots: + void saveTag(); + +private: + void loadMPCInfo(); + void loadTag(); + Ui::DetailsDialog ui; + QString m_path; + +}; + +#endif diff --git a/src/plugins/Input/aac/detailsdialog.ui b/src/plugins/Input/aac/detailsdialog.ui new file mode 100644 index 000000000..618300c10 --- /dev/null +++ b/src/plugins/Input/aac/detailsdialog.ui @@ -0,0 +1,347 @@ + + DetailsDialog + + + + 0 + 0 + 545 + 374 + + + + Details + + + + + + File path: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + true + + + + + + + + 0 + 16 + + + + Musepack Info + + + + 8 + + + 8 + + + 8 + + + 8 + + + 6 + + + 6 + + + + + Qt::Vertical + + + + 74 + 151 + + + + + + + + - + + + + + + + Length: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + - + + + + + + + Sample rate: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + - + + + + + + + Qt::LeftToRight + + + Channels: + + + Qt::PlainText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + File size: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Bitrate: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::LeftToRight + + + - + + + + + + + - + + + + + + + Stream version: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + - + + + + + + + + + + + 0 + 0 + + + + APE Tag + + + + + + Title: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + Artist: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + Album: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + Comment: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + Year: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + Track number: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Genre: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + false + + + Save + + + + + + + + + + Qt::Horizontal + + + + 111 + 20 + + + + + + + + Close + + + + + + + + + pushButton_3 + clicked() + DetailsDialog + close() + + + 623 + 353 + + + 539 + 352 + + + + + -- cgit v1.2.3-13-gbd6f