From 0e860ae0ba0c6ed9f14b9d01a28b44ae64d91532 Mon Sep 17 00:00:00 2001 From: trialuser02 Date: Tue, 9 Sep 2008 19:45:15 +0000 Subject: new libqmmp api, a lot of features has been temporary disabled git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@546 90c681e8-e032-0410-971d-27865f9a5e38 --- src/plugins/Input/CMakeLists.txt | 14 +- src/plugins/Input/Input.pro | 10 +- src/plugins/Input/mad/decoder_mad.cpp | 51 ++-- src/plugins/Input/mad/decoder_mad.h | 4 +- src/plugins/Output/CMakeLists.txt | 6 +- src/plugins/Output/Output.pro | 6 +- src/plugins/Output/alsa/outputalsa.cpp | 20 +- src/plugins/Output/alsa/outputalsa.h | 6 +- src/qmmp/CMakeLists.txt | 6 + src/qmmp/decoder.cpp | 191 +++++++------ src/qmmp/decoder.h | 143 ++-------- src/qmmp/effect.cpp | 7 +- src/qmmp/effect.h | 10 +- src/qmmp/output.cpp | 275 ++++++++++--------- src/qmmp/output.h | 171 ++---------- src/qmmp/qmmp.cpp | 23 ++ src/qmmp/qmmp.h | 33 +++ src/qmmp/qmmp.pro | 24 +- src/qmmp/soundcore.cpp | 219 +++++++-------- src/qmmp/soundcore.h | 173 ++++++------ src/qmmp/statehandler.cpp | 162 +++++++++++ src/qmmp/statehandler.h | 86 ++++++ src/ui/builtincommandlineoption.cpp | 4 +- src/ui/display.cpp | 69 ++++- src/ui/display.h | 18 +- src/ui/eqwidget.cpp | 4 +- src/ui/eqwidget.h | 2 +- src/ui/mainwindow.cpp | 98 +++++-- src/ui/mainwindow.h | 5 +- src/ui/monostereo.h | 1 + src/ui/playlist.cpp | 478 +++++++++++++++++---------------- src/ui/playlist.h | 5 +- src/ui/pluginitem.cpp | 4 +- src/ui/positionbar.cpp | 23 +- src/ui/symboldisplay.h | 9 +- src/ui/titlebar.cpp | 41 +-- src/ui/titlebar.h | 5 +- 37 files changed, 1332 insertions(+), 1074 deletions(-) create mode 100644 src/qmmp/qmmp.cpp create mode 100644 src/qmmp/qmmp.h create mode 100644 src/qmmp/statehandler.cpp create mode 100644 src/qmmp/statehandler.h (limited to 'src') diff --git a/src/plugins/Input/CMakeLists.txt b/src/plugins/Input/CMakeLists.txt index a1f91866d..57df47d99 100644 --- a/src/plugins/Input/CMakeLists.txt +++ b/src/plugins/Input/CMakeLists.txt @@ -17,29 +17,29 @@ add_subdirectory(mad) ENDIF(USE_MAD AND TAGLIB_FOUND) IF(USE_FLAC AND TAGLIB_FOUND) -add_subdirectory(flac) +#add_subdirectory(flac) ENDIF(USE_FLAC AND TAGLIB_FOUND) IF(USE_VORBIS AND TAGLIB_FOUND) -add_subdirectory(vorbis) +#add_subdirectory(vorbis) ENDIF(USE_VORBIS AND TAGLIB_FOUND) IF(USE_FFMPEG) -add_subdirectory(ffmpeg) +#add_subdirectory(ffmpeg) ENDIF(USE_FFMPEG) IF(USE_MPC AND TAGLIB_FOUND) -add_subdirectory(mpc) +#add_subdirectory(mpc) ENDIF(USE_MPC AND TAGLIB_FOUND) IF(USE_SNDFILE) -add_subdirectory(sndfile) +#add_subdirectory(sndfile) ENDIF(USE_SNDFILE) IF(USE_WAVPACK) -add_subdirectory(wavpack) +#add_subdirectory(wavpack) ENDIF(USE_WAVPACK) IF(USE_MODPLUG) -add_subdirectory(modplug) +#add_subdirectory(modplug) ENDIF(USE_MODPLUG) diff --git a/src/plugins/Input/Input.pro b/src/plugins/Input/Input.pro index 2b75906fb..6dff07146 100644 --- a/src/plugins/Input/Input.pro +++ b/src/plugins/Input/Input.pro @@ -1,31 +1,31 @@ include(../../../qmmp.pri) -SUBDIRS += mad vorbis sndfile wavpack +SUBDIRS += mad# vorbis sndfile wavpack TEMPLATE = subdirs contains(CONFIG, MODPLUG_PLUGIN){ - SUBDIRS += modplug +# SUBDIRS += modplug message(***************************) message(* Modplug plugin enabled *) message(***************************) } contains(CONFIG, MUSEPACK_PLUGIN){ - SUBDIRS += mpc +# SUBDIRS += mpc message(***************************) message(* Musepack plugin enabled *) message(***************************) } contains(CONFIG, FLAC_PLUGIN){ - SUBDIRS += flac +# SUBDIRS += flac message(***********************) message(* FLAC plugin enabled *) message(***********************) } contains(CONFIG, FFMPEG_PLUGIN){ - SUBDIRS += ffmpeg +# SUBDIRS += ffmpeg message(*************************) message(* FFMPEG plugin enabled *) message(*************************) diff --git a/src/plugins/Input/mad/decoder_mad.cpp b/src/plugins/Input/mad/decoder_mad.cpp index 7c8cc8f1b..98e437075 100644 --- a/src/plugins/Input/mad/decoder_mad.cpp +++ b/src/plugins/Input/mad/decoder_mad.cpp @@ -25,7 +25,7 @@ DecoderMAD::DecoderMAD(QObject *parent, DecoderFactory *d, QIODevice *i, Output inited = false; user_stop = false; done = false; - finish = false; + m_finish = false; derror = false; eof = false; useeq = false; @@ -72,7 +72,7 @@ bool DecoderMAD::initialize() inited = false; user_stop = false; done = false; - finish = false; + m_finish = false; derror = false; eof = false; totalTime = 0.; @@ -88,7 +88,7 @@ bool DecoderMAD::initialize() if (! input()) { - error("DecoderMAD: cannot initialize. No input."); + qWarning("DecoderMAD: cannot initialize. No input."); return FALSE; } @@ -102,8 +102,8 @@ bool DecoderMAD::initialize() { if (! input()->open(QIODevice::ReadOnly)) { - error("DecoderMAD: Failed to open input. Error " + - QString::number(input()->isOpen()) + "."); + /*qWarning("DecoderMAD: Failed to open input. Error " + + QString::number(input()->isOpen()) + ".");*/ return FALSE; } } @@ -112,8 +112,8 @@ bool DecoderMAD::initialize() { TagExtractor extractor(input()); FileTag tag = extractor.id3v2tag(); - if (!tag.isEmpty()) - dispatch(extractor.id3v2tag()); + // if (!tag.isEmpty()) +// dispatch(extractor.id3v2tag()); } mad_stream_init(&stream); @@ -131,7 +131,7 @@ bool DecoderMAD::initialize() mad_frame_mute (&frame); stream.next_frame = NULL; stream.sync = 0; - configure(freq, channels, 16, bitrate); + configure(freq, channels, 16); inited = TRUE; return TRUE; @@ -150,7 +150,7 @@ void DecoderMAD::deinit() inited = false; user_stop = false; done = false; - finish = false; + m_finish = false; derror = false; eof = false; useeq = false; @@ -339,7 +339,7 @@ bool DecoderMAD::findHeader() return TRUE; } -double DecoderMAD::lengthInSeconds() +qint64 DecoderMAD::lengthInSeconds() { if (! inited) return 0.; @@ -360,11 +360,11 @@ void DecoderMAD::flush(bool final) { ulong min = final ? 0 : bks; - while ((! done && ! finish) && output_bytes > min) + while ((! done && ! m_finish) && output_bytes > min) { output()->recycler()->mutex()->lock(); - while ((! done && ! finish) && output()->recycler()->full()) + while ((! done && ! m_finish) && output()->recycler()->full()) { mutex()->unlock(); output()->recycler()->cond()->wait(output()->recycler()->mutex()); @@ -373,7 +373,7 @@ void DecoderMAD::flush(bool final) done = user_stop; } - if (user_stop || finish) + if (user_stop || m_finish) { inited = FALSE; done = TRUE; @@ -406,13 +406,13 @@ void DecoderMAD::run() } - DecoderState::Type stat = DecoderState::Decoding; + //DecoderState::Type stat = DecoderState::Decoding; mutex()->unlock(); - dispatch(stat); + //dispatch(stat); - while (! done && ! finish && ! derror) + while (! done && ! m_finish && ! derror) { mutex()->lock(); @@ -433,7 +433,7 @@ void DecoderMAD::run() eof = false; } - finish = eof; + m_finish = eof; if (! eof) { @@ -469,7 +469,7 @@ void DecoderMAD::run() mutex()->unlock(); // decode - while (! done && ! finish && ! derror) + while (! done && ! m_finish && ! derror) { if (mad_frame_decode(&frame, &stream) == -1) { @@ -530,17 +530,18 @@ void DecoderMAD::run() done = TRUE; if (! user_stop) - finish = TRUE; + m_finish = TRUE; } - if (finish) - stat = DecoderState::Finished; - else if (user_stop) - stat = DecoderState::Stopped; + if (m_finish) + finish(); +// stat = DecoderState::Finished; + //else if (user_stop) + // stat = DecoderState::Stopped; mutex()->unlock(); - dispatch(stat); + //dispatch(stat); if (input()) input()->close(); @@ -617,7 +618,7 @@ enum mad_flow DecoderMAD::madOutput() } } - if (done || finish) + if (done || m_finish) { return MAD_FLOW_STOP; } diff --git a/src/plugins/Input/mad/decoder_mad.h b/src/plugins/Input/mad/decoder_mad.h index f37016657..55c662737 100644 --- a/src/plugins/Input/mad/decoder_mad.h +++ b/src/plugins/Input/mad/decoder_mad.h @@ -27,7 +27,7 @@ public: // standard decoder API bool initialize(); - double lengthInSeconds(); + qint64 lengthInSeconds(); void seek(double); void stop(); @@ -43,7 +43,7 @@ private: void deinit(); bool findHeader(); bool findXingHeader(struct mad_bitptr, unsigned int); - bool inited, user_stop, done, finish, derror, eof, useeq; + bool inited, user_stop, done, m_finish, derror, eof, useeq; double totalTime, seekTime; int channels; unsigned long bitrate; diff --git a/src/plugins/Output/CMakeLists.txt b/src/plugins/Output/CMakeLists.txt index 9bd11aea8..eabd34ae3 100644 --- a/src/plugins/Output/CMakeLists.txt +++ b/src/plugins/Output/CMakeLists.txt @@ -8,13 +8,13 @@ add_subdirectory(alsa) ENDIF(USE_ALSA) IF(USE_JACK) -add_subdirectory(jack) +#add_subdirectory(jack) ENDIF(USE_JACK) IF(USE_OSS) -add_subdirectory(oss) +#add_subdirectory(oss) ENDIF(USE_OSS) IF(USE_PULSE) -add_subdirectory(pulseaudio) +#add_subdirectory(pulseaudio) ENDIF(USE_PULSE) diff --git a/src/plugins/Output/Output.pro b/src/plugins/Output/Output.pro index 19a20bcd3..b7a8c6cf8 100644 --- a/src/plugins/Output/Output.pro +++ b/src/plugins/Output/Output.pro @@ -4,21 +4,21 @@ CONFIG += release warn_on TEMPLATE = subdirs contains(CONFIG, JACK_PLUGIN){ - SUBDIRS += jack +# SUBDIRS += jack message(***********************) message(* JACK plugin enabled *) message(***********************) } contains(CONFIG, OSS_PLUGIN){ - SUBDIRS += oss +# SUBDIRS += oss message(**********************) message(* OSS plugin enabled *) message(**********************) } contains(CONFIG, PULSE_AUDIO_PLUGIN){ - SUBDIRS += pulseaudio +# SUBDIRS += pulseaudio message(******************************) message(* PULSE AUDIO plugin enabled *) message(******************************) diff --git a/src/plugins/Output/alsa/outputalsa.cpp b/src/plugins/Output/alsa/outputalsa.cpp index 51f3a6189..35e37b301 100644 --- a/src/plugins/Output/alsa/outputalsa.cpp +++ b/src/plugins/Output/alsa/outputalsa.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include "outputalsa.h" OutputALSA::OutputALSA(QObject * parent, bool useVolume) @@ -84,7 +85,7 @@ void OutputALSA::status() } } -long OutputALSA::written() +qint64 OutputALSA::written() { return m_totalWritten; } @@ -95,7 +96,7 @@ void OutputALSA::seek(long pos) m_currentSeconds = -1; } -void OutputALSA::configure(long freq, int chan, int prec, int brate) +void OutputALSA::configure(qint64 freq, int chan, int prec) { // we need to configure if (freq != m_frequency || chan != m_channels || prec != m_precision) @@ -166,8 +167,7 @@ void OutputALSA::configure(long freq, int chan, int prec, int brate) return; } exact_rate = rate;// = 11000; - qDebug("OutputALSA: frequency=%d, channels=%d, bitrate=%d", - rate, chan, brate); + qDebug("OutputALSA: frequency=%d, channels=%d", rate, chan); if ((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &exact_rate, 0)) < 0) { @@ -248,8 +248,8 @@ void OutputALSA::pause() { if (!m_play) return; - m_pause = (m_pause) ? FALSE : TRUE; - OutputState::Type state = m_pause ? OutputState::Paused: OutputState::Playing; + m_pause = !m_pause; + Qmmp::State state = m_pause ? Qmmp::Paused: Qmmp::Playing; dispatch(state); } @@ -273,7 +273,7 @@ bool OutputALSA::initialize() } -long OutputALSA::latency() +qint64 OutputALSA::latency() { long used = 0; @@ -310,7 +310,7 @@ void OutputALSA::run() unsigned char *prebuffer = (unsigned uchar *)malloc(prebuffer_size); ulong prebuffer_fill = 0; - dispatch(OutputState::Playing); + dispatch(Qmmp::Playing); while (!done) { @@ -400,7 +400,7 @@ void OutputALSA::run() } } m_play = FALSE; - dispatch(OutputState::Stopped); + dispatch(Qmmp::Stopped); free(prebuffer); prebuffer = 0; mutex()->unlock(); @@ -483,7 +483,7 @@ void OutputALSA::uninitialize() snd_pcm_close(pcm_handle); pcm_handle = 0; } - dispatch(OutputState::Stopped); + dispatch(Qmmp::Stopped); } /* ****** MIXER ******* */ diff --git a/src/plugins/Output/alsa/outputalsa.h b/src/plugins/Output/alsa/outputalsa.h index 432e31043..333600b1d 100644 --- a/src/plugins/Output/alsa/outputalsa.h +++ b/src/plugins/Output/alsa/outputalsa.h @@ -42,11 +42,11 @@ public: bool initialize(); bool isInitialized() const { return m_inited; } void uninitialize(); - void configure(long, int, int, int); + void configure(qint64, int, int); void stop(); void pause(); - long written(); - long latency(); + qint64 written(); + qint64 latency(); void seek(long); void setVolume(int l, int r); void volume(int *l, int *r); diff --git a/src/qmmp/CMakeLists.txt b/src/qmmp/CMakeLists.txt index abebfb785..996069f61 100644 --- a/src/qmmp/CMakeLists.txt +++ b/src/qmmp/CMakeLists.txt @@ -42,6 +42,8 @@ SET(libqmmp_SRCS streamreader.cpp downloader.cpp effect.cpp + qmmp.cpp + statehandler.cpp ) SET(libqmmp_MOC_HDRS @@ -62,6 +64,8 @@ SET(libqmmp_MOC_HDRS downloader.h effectfactory.h effect.h + qmmp.h + statehandler.h ) SET(libqmmp_DEVEL_HDRS @@ -79,6 +83,8 @@ SET(libqmmp_DEVEL_HDRS downloader.h effectfactory.h effect.h + qmmp.h + statehandler.h ) diff --git a/src/qmmp/decoder.cpp b/src/qmmp/decoder.cpp index e31c85eb1..525d33e0c 100644 --- a/src/qmmp/decoder.cpp +++ b/src/qmmp/decoder.cpp @@ -28,30 +28,107 @@ extern "C" Decoder::Decoder(QObject *parent, DecoderFactory *d, QIODevice *i, Output *o) - : QThread(parent), fctry(d), in(i), m_output(o),m_eqInited(FALSE), + : QThread(parent), m_factory(d), m_input(i), m_output(o),m_eqInited(FALSE), m_useEQ(FALSE) { m_output->recycler()->clear(); int b[] = {0,0,0,0,0,0,0,0,0,0}; setEQ(b, 0); - qRegisterMetaType("DecoderState"); + //qRegisterMetaType("DecoderState"); + qRegisterMetaType("Qmmp::State"); blksize = Buffer::size(); - m_effects = Effect::create(this); + //m_effects = Effect::create(this); QSettings settings(QDir::homePath()+"/.qmmp/qmmprc", QSettings::IniFormat); m_useVolume = settings.value("Volume/software_volume", FALSE).toBool(); m_volL = settings.value("Volume/left", 80).toInt(); m_volR = settings.value("Volume/right", 80).toInt(); - setVolume(m_volL, m_volR); + //setVolume(m_volL, m_volR); + m_handler = new StateHandler(this); } Decoder::~Decoder() { - fctry = 0; - in = 0; + m_factory = 0; + m_input = 0; m_output = 0; blksize = 0; } +DecoderFactory *Decoder::factory() const +{ + return m_factory; +} + +QIODevice *Decoder::input() +{ + return m_input; +} + +Output *Decoder::output() +{ + return m_output; +} + +QMutex *Decoder::mutex() +{ + return &m_mutex; +} + +QWaitCondition *Decoder::cond() +{ + return &m_waitCondition; +} + +StateHandler *Decoder::stateHandler() +{ + return m_handler; +} + +void Decoder::setBlockSize(unsigned int sz) +{ + blksize = sz; +} + +unsigned int Decoder::blockSize() const +{ + return blksize; +} + +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); + } +} + +void Decoder::setEQEnabled(bool on) +{ + m_useEQ = on; +} + +void Decoder::setVolume(int l, int r) +{ + m_mutex.lock(); + m_volL = l; + m_volR = r; + m_volLF = pow( 10, (l - 100)/40.0 ) * 256; + m_volRF = pow( 10, (r - 100)/40.0 ) * 256; + m_mutex.lock(); +} + +void Decoder::volume(int *l, int *r) +{ + m_mutex.lock(); + *l = m_volL; + *r = m_volR; + m_mutex.unlock(); +} + // static methods static QList *factories = 0; @@ -148,7 +225,6 @@ Decoder *Decoder::create(QObject *parent, const QString &source, { Decoder *decoder = 0; DecoderFactory *fact = 0; - if (!input->open(QIODevice::ReadOnly)) { qDebug("Decoder: cannot open input"); @@ -163,14 +239,14 @@ Decoder *Decoder::create(QObject *parent, const QString &source, } else fact = Decoder::findByPath(source); - if (fact) { decoder = fact->create(parent, input, output); } if (!decoder) input->close(); - + else + output->setStateHandler(decoder->stateHandler()); return decoder; } @@ -292,29 +368,23 @@ QList *Decoder::decoderFactories() return factories; } -void Decoder::dispatch(const DecoderState &st) -{ - emit stateChanged(st); -} - -void Decoder::dispatch(DecoderState::Type st) -{ - emit stateChanged(DecoderState(st)); -} - -void Decoder::dispatch(const FileTag &tag) -{ - emit stateChanged(DecoderState(tag)); -} - -void Decoder::error(const QString &e) +void Decoder::configure(qint64 srate, int chan, int bps) { - emit stateChanged(DecoderState(e)); + Effect* effect = 0; + foreach(effect, m_effects) + { + effect->configure(srate, chan, bps); + srate = effect->sampleRate(); + chan = effect->channels(); + bps = effect->bitsPerSample(); + } + if (m_output) + m_output->configure(srate, chan, bps); } -ulong Decoder::produceSound(char *data, ulong output_bytes, ulong bitrate, int nch) +qint64 Decoder::produceSound(char *data, qint64 size, qint64 brate, int chan) { - ulong sz = output_bytes < blksize ? output_bytes : blksize; + ulong sz = size < blksize ? size : blksize; if (m_useEQ) { @@ -323,15 +393,15 @@ ulong Decoder::produceSound(char *data, ulong output_bytes, ulong bitrate, int n init_iir(); m_eqInited = TRUE; } - iir((void*) data,sz,nch); + iir((void*) data,size,chan); } if (m_useVolume) { - changeVolume(data, sz, nch); + changeVolume(data, sz, chan); } char *out_data = data; char *prev_data = data; - ulong w = sz; + qint64 w = sz; Effect* effect = 0; foreach(effect, m_effects) { @@ -360,45 +430,25 @@ ulong Decoder::produceSound(char *data, ulong output_bytes, ulong bitrate, int n memset(b->data + w, 0, blksize + b->exceeding - w); b->nbytes = w;// blksize; - b->rate = bitrate; + b->rate = brate; output()->recycler()->add(); - output_bytes -= sz; - memmove(data, data + sz, output_bytes); + size -= sz; + memmove(data, data + sz, size); return sz; } -void Decoder::configure(long freq, int channels, int prec, int bitrate) +void Decoder::finish() { - Effect* effect = 0; - foreach(effect, m_effects) - { - effect->configure(freq, channels, prec); - freq = m_effects.at(0)->frequency(); - channels = effect->channels(); - prec = effect->resolution(); - } - if (m_output) - m_output->configure(freq, channels, prec, bitrate); + //output()->wait(); + emit finished(); } -void Decoder::setEQ(int bands[10], int preamp) +void Decoder::changeVolume(char *data, qint64 size, int chan) { - 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); - } -} - -void Decoder::changeVolume(char *data, ulong sz, int channels) -{ - if (channels > 1) - for (ulong i = 0; i < sz/2; i+=2) + if (chan > 1) + for (qint64 i = 0; i < size/2; i+=2) { ((short*)data)[i]*= m_volLF/256.0; ((short*)data)[i+1]*= m_volRF/256.0; @@ -406,26 +456,7 @@ void Decoder::changeVolume(char *data, ulong sz, int channels) else { int l = qMax(m_volLF,m_volRF); - for (ulong i = 0; i < sz/2; i++) + for (qint64 i = 0; i < size/2; i++) ((short*)data)[i]*= l/256.0; } } - -void Decoder::setVolume(int l, int r) -{ - mtx.lock(); - m_volL = l; - m_volR = r; - m_volLF = pow( 10, (l - 100)/40.0 ) * 256; - m_volRF = pow( 10, (r - 100)/40.0 ) * 256; - mtx.unlock(); -} - -void Decoder::volume(int *l, int *r) -{ - mtx.lock(); - *l = m_volL; - *r = m_volR; - mtx.unlock(); -} - diff --git a/src/qmmp/decoder.h b/src/qmmp/decoder.h index 389eaa075..1e0a32d82 100644 --- a/src/qmmp/decoder.h +++ b/src/qmmp/decoder.h @@ -26,72 +26,7 @@ class Recycler; class Output; class Visualization; class Effect; - - - -class DecoderState -{ -public: - enum Type { Decoding, Stopped, Finished, Info, Error }; - - DecoderState(const DecoderState &st) - : m_error_msg(0), m_tag(0) - { - m_type = st.type(); - if (m_type == Info) - m_tag = new FileTag(*st.tag()); - else if (m_type == Error) - m_error_msg = new QString(*st.errorMessage()); - } - - - DecoderState(Type t) - : m_type(t), m_error_msg(0), m_tag(0) -{} - - DecoderState(const QString &e) - : m_type(Error), m_tag(0) - { - m_error_msg = new QString(e); - } - - DecoderState() - : m_type(Stopped), m_error_msg(0), m_tag(0) - {} - - DecoderState(const FileTag &tag) - : m_type(Info), m_error_msg(0), m_tag(0) - { - m_tag = new FileTag(tag); - } - - ~DecoderState() - { - if (m_error_msg) - delete m_error_msg; - if (m_tag) - delete m_tag; - } - - const QString *errorMessage() const - { - return m_error_msg; - } - const Type &type() const - { - return m_type; - } - const FileTag *tag() const - { - return m_tag; - } - -private: - Type m_type; - const QString *m_error_msg; - FileTag *m_tag; -}; - +class StateHandler; class Decoder : public QThread @@ -104,50 +39,26 @@ public: // Standard Decoder API virtual bool initialize() = 0; - virtual double lengthInSeconds() = 0; + virtual qint64 lengthInSeconds() = 0; virtual void seek(double) = 0; virtual void stop() = 0; + //virtual void pause() = 0; + //virtual void stop() = 0; + + DecoderFactory *factory() const; + QIODevice *input(); + Output *output(); + QMutex *mutex(); + QWaitCondition *cond(); + StateHandler *stateHandler(); + + void setBlockSize(unsigned int sz); + unsigned int blockSize() const; - DecoderFactory *factory() const - { - return fctry; - } - - QIODevice *input() - { - return in; - } - Output *output() - { - return m_output; - } - - QMutex *mutex() - { - return &mtx; - } - QWaitCondition *cond() - { - return &cnd; - } - - void setBlockSize(unsigned int sz) - { - blksize = sz; - } - - unsigned int blockSize() const - { - return blksize; - } - ulong produceSound(char *data, ulong output_bytes, ulong bitrate, int nch); void setEQ(int bands[10], int preamp); - void setEQEnabled(bool on) - { - m_useEQ = on; - }; - void setVolume(int, int); + void setEQEnabled(bool on); + void setVolume(int, int); void volume(int*, int*); // static methods @@ -166,31 +77,31 @@ public: static bool isEnabled(DecoderFactory* factory); signals: - void stateChanged(const DecoderState&); + void finished(); + //void stateChanged(const DecoderState&); protected: - void configure(long freq, int channels, int prec, int bitrate); - void dispatch(DecoderState::Type); - void dispatch(const DecoderState&); - void dispatch(const FileTag&); - void error(const QString&); + void configure(qint64 srate, int chan, int bps); + qint64 produceSound(char *data, qint64 size, qint64 brate, int chan); + void finish(); private: - DecoderFactory *fctry; - void changeVolume(char *data, ulong sz, int channels); + void changeVolume(char *data, qint64 size, int chan); + DecoderFactory *m_factory; QList m_effects; - QIODevice *in; + QIODevice *m_input; Output *m_output; - QMutex mtx; - QWaitCondition cnd; + QMutex m_mutex; + QWaitCondition m_waitCondition; uint blksize; bool m_eqInited; bool m_useEQ; bool m_useVolume; int m_volL, m_volR, m_volLF, m_volRF; + StateHandler *m_handler; }; diff --git a/src/qmmp/effect.cpp b/src/qmmp/effect.cpp index 0d61a4905..5b498d4d6 100644 --- a/src/qmmp/effect.cpp +++ b/src/qmmp/effect.cpp @@ -33,15 +33,14 @@ Effect::Effect(QObject *parent) Effect::~Effect() {} -void Effect::configure(ulong freq, int chan, int res) +void Effect::configure(qint64 freq, int chan, int res) { m_freq = freq; m_chan = chan; m_res = res; - } -const ulong Effect::frequency() +const qint64 Effect::sampleRate() { return m_freq; } @@ -51,7 +50,7 @@ const int Effect::channels() return m_chan; } -const int Effect::resolution() +const int Effect::bitsPerSample() { return m_res; } diff --git a/src/qmmp/effect.h b/src/qmmp/effect.h index 654c1c2b6..8eaabdd94 100644 --- a/src/qmmp/effect.h +++ b/src/qmmp/effect.h @@ -51,13 +51,13 @@ public: //virtual bool process(char *in_data, char *out_data, const ulong maxsize, ulong &rbytes, ulong &wbytes) = 0; - virtual void configure(ulong freq, int chan, int res); + virtual void configure(qint64 freq, int chan, int res); /*! - * Returns frequency. + * Returns samplerate. * This function should be reimplemented if subclass changes default samplerate. */ - virtual const ulong frequency(); + virtual const qint64 sampleRate(); /*! * Returns channel number. @@ -66,10 +66,10 @@ public: virtual const int channels(); /*! - * Returns resolution. + * Returns bit depth. * This function should be reimplemented if subclass changes default resolution. */ - virtual const int resolution(); + virtual const int bitsPerSample(); static QList create(QObject *parent); diff --git a/src/qmmp/output.cpp b/src/qmmp/output.cpp index f5e30c02a..8e4f579f5 100644 --- a/src/qmmp/output.cpp +++ b/src/qmmp/output.cpp @@ -15,127 +15,29 @@ #include -// static methods - -static QList *factories = 0; -static QStringList files; -static QTimer *timer = 0; - -static void checkFactories() -{ - if ( ! factories ) - { - files.clear(); - factories = new QList; - - QDir pluginsDir ( qApp->applicationDirPath() ); - pluginsDir.cdUp(); - pluginsDir.cd ( "./"LIB_DIR"/qmmp/Output" ); - foreach ( QString fileName, pluginsDir.entryList ( QDir::Files ) ) - { - QPluginLoader loader ( pluginsDir.absoluteFilePath ( fileName ) ); - QObject *plugin = loader.instance(); - if ( loader.isLoaded() ) - qDebug ( "Output: plugin loaded - %s", qPrintable ( fileName ) ); - else - qWarning("Output: %s", qPrintable(loader.errorString ())); - - OutputFactory *factory = 0; - if ( plugin ) - factory = qobject_cast ( plugin ); - - if ( factory ) - { - Output::registerFactory ( factory ); - files << pluginsDir.absoluteFilePath(fileName); - } - } - } -} - -void Output::registerFactory ( OutputFactory *fact ) -{ - factories->append ( fact ); -} - -Output *Output::create (QObject *parent) -{ - Output *output = 0; - - checkFactories(); - if (factories->isEmpty ()) - { - qDebug("Output: unable to find output plugins"); - return output; - } - OutputFactory *fact = 0; - foreach(fact, *factories) - { - if (isEnabled(fact)) - break; - else - fact = factories->at(0); - } - QSettings settings (QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat); - bool useVolume = !settings.value("Volume/software_volume", FALSE).toBool(); - if (fact) - { - output = fact->create (parent, useVolume); - if (useVolume) - { - timer = new QTimer(output); - connect(timer, SIGNAL(timeout()), output, SLOT(checkVolume())); - timer->start(125); - } - else - { - QTimer::singleShot(125, output, SLOT(checkSoftwareVolume())); - } - } - return output; -} - -QList *Output::outputFactories() +Output::Output (QObject* parent) : QThread (parent), m_recycler (stackSize()) { - checkFactories(); - return factories; -} - -QStringList Output::outputFiles() -{ - checkFactories(); - return files; + //qRegisterMetaType("OutputState"); + m_bl = -1; + m_br = -1; + m_handler = 0; } -void Output::setEnabled(OutputFactory* factory) +Recycler *Output::recycler() { - checkFactories(); - if (!factories->contains(factory)) - return; - - QString name = files.at(factories->indexOf(factory)).section('/',-1); - QSettings settings (QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat); - settings.setValue ("Output/plugin_file", name); + return &m_recycler; } -bool Output::isEnabled(OutputFactory* factory) +QMutex *Output::mutex() { - checkFactories(); - if (!factories->contains(factory)) - return FALSE; - QString name = files.at(factories->indexOf(factory)).section('/',-1); - QSettings settings (QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat); - return name == settings.value("Output/plugin_file", "libalsa.so").toString(); + return &m_mutex; } -Output::Output (QObject* parent) : QThread (parent), r (stackSize()) +void Output::setStateHandler(StateHandler *handler) { - qRegisterMetaType("OutputState"); - m_bl = -1; - m_br = -1; + m_handler = handler; } - Output::~Output() { foreach(Visual *visual, m_vis_map.values ()) @@ -149,11 +51,6 @@ Output::~Output() } } -void Output::error ( const QString &e ) -{ - emit stateChanged ( OutputState ( e ) ); -} - void Output::addVisual ( Visual *v ) { if (visuals.indexOf (v) == -1) @@ -183,7 +80,7 @@ void Output::processCloseEvent(Visual *v, QCloseEvent *event) VisualFactory *factory = m_vis_map.key(v); m_vis_map.remove(factory); Visual::setEnabled(factory, FALSE); - dispatch(OutputState::VisualRemoved); + //dispatch(OutputState::VisualRemoved); } } @@ -252,19 +149,19 @@ void Output::clearVisuals() } } -void Output::dispatch(OutputState::Type st) +/*void Output::dispatch(OutputState::Type st) { if (st == OutputState::Stopped) clearVisuals(); emit stateChanged ( OutputState(st) ); -} +}*/ -void Output::dispatch(long s, unsigned long w, int b, int f, int p, int c) +/*void Output::dispatch(long s, unsigned long w, int b, int f, int p, int c) { emit stateChanged ( OutputState(s, w, b, f, p, c) ); -} +}*/ -void Output::dispatch ( const OutputState &st ) +/*void Output::dispatch ( const OutputState &st ) { if (st.type() == OutputState::Stopped) clearVisuals(); @@ -274,7 +171,7 @@ void Output::dispatch ( const OutputState &st ) void Output::dispatchVolume(int L, int R) { emit stateChanged ( OutputState(L, R) ); -} +}*/ void Output::checkVolume() { @@ -288,7 +185,7 @@ void Output::checkVolume() { m_bl = ll; m_br = lr; - dispatchVolume(ll,lr); + //dispatchVolume(ll,lr); } } @@ -297,6 +194,138 @@ void Output::checkSoftwareVolume() QSettings settings(QDir::homePath()+"/.qmmp/qmmprc", QSettings::IniFormat); int L = settings.value("Volume/left", 80).toInt(); int R = settings.value("Volume/right", 80).toInt(); - dispatchVolume(L, R); + //dispatchVolume(L, R); +} + +void Output::dispatch(qint64 elapsed, + qint64 totalTime, + int bitrate, + int frequency, + int precision, + int channels) +{ + if (m_handler) + m_handler->dispatch(elapsed, totalTime, bitrate, frequency, precision, channels); +} + +void Output::dispatch(const Qmmp::State &state) +{ + if (m_handler) + m_handler->dispatch(state); +} + + + +// static methods + +static QList *factories = 0; +static QStringList files; +static QTimer *timer = 0; + +static void checkFactories() +{ + if ( ! factories ) + { + files.clear(); + factories = new QList; + + QDir pluginsDir ( qApp->applicationDirPath() ); + pluginsDir.cdUp(); + pluginsDir.cd ( "./"LIB_DIR"/qmmp/Output" ); + foreach ( QString fileName, pluginsDir.entryList ( QDir::Files ) ) + { + QPluginLoader loader ( pluginsDir.absoluteFilePath ( fileName ) ); + QObject *plugin = loader.instance(); + if ( loader.isLoaded() ) + qDebug ( "Output: plugin loaded - %s", qPrintable ( fileName ) ); + else + qWarning("Output: %s", qPrintable(loader.errorString ())); + + OutputFactory *factory = 0; + if ( plugin ) + factory = qobject_cast ( plugin ); + + if ( factory ) + { + Output::registerFactory ( factory ); + files << pluginsDir.absoluteFilePath(fileName); + } + } + } +} + +void Output::registerFactory ( OutputFactory *fact ) +{ + factories->append ( fact ); +} + +Output *Output::create (QObject *parent) +{ + Output *output = 0; + + checkFactories(); + if (factories->isEmpty ()) + { + qDebug("Output: unable to find output plugins"); + return output; + } + OutputFactory *fact = 0; + foreach(fact, *factories) + { + if (isEnabled(fact)) + break; + else + fact = factories->at(0); + } + QSettings settings (QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat); + bool useVolume = !settings.value("Volume/software_volume", FALSE).toBool(); + if (fact) + { + output = fact->create (parent, useVolume); + if (useVolume) + { + timer = new QTimer(output); + connect(timer, SIGNAL(timeout()), output, SLOT(checkVolume())); + timer->start(125); + } + else + { + QTimer::singleShot(125, output, SLOT(checkSoftwareVolume())); + } + } + return output; +} + +QList *Output::outputFactories() +{ + checkFactories(); + return factories; +} + +QStringList Output::outputFiles() +{ + checkFactories(); + return files; +} + +void Output::setEnabled(OutputFactory* factory) +{ + checkFactories(); + if (!factories->contains(factory)) + return; + + QString name = files.at(factories->indexOf(factory)).section('/',-1); + QSettings settings (QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat); + settings.setValue ("Output/plugin_file", name); +} + +bool Output::isEnabled(OutputFactory* factory) +{ + checkFactories(); + if (!factories->contains(factory)) + return FALSE; + QString name = files.at(factories->indexOf(factory)).section('/',-1); + QSettings settings (QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat); + return name == settings.value("Output/plugin_file", "libalsa.so").toString(); } diff --git a/src/qmmp/output.h b/src/qmmp/output.h index 6bc3487b3..31057c05c 100644 --- a/src/qmmp/output.h +++ b/src/qmmp/output.h @@ -18,126 +18,13 @@ class Output; #include "visual.h" #include "outputfactory.h" #include "visualfactory.h" +#include "statehandler.h" #include "recycler.h" class QTimer; -class OutputState -{ -public: - - enum Type { Playing, Buffering, Info, Paused, Stopped, Volume, Error, VisualRemoved }; - - OutputState() - : m_type(Stopped), m_error_msg(0), m_elasped_seconds(0), - m_written_bytes(0), m_brate(0), m_freq(0), m_prec(0), m_chan(0), - m_left(0), m_right(0) - {} - OutputState(const OutputState &st) - : m_type(Stopped), m_error_msg(0), m_elasped_seconds(0), - m_written_bytes(0), m_brate(0), m_freq(0), m_prec(0), m_chan(0), - m_left(0), m_right(0) - { - m_type = st.type(); - if (m_type == Info) - { - m_elasped_seconds = st.elapsedSeconds(); - m_written_bytes = st.writtenBytes(); - m_brate = st.bitrate(); - m_freq = st.frequency(); - m_prec = st.precision(); - m_chan = st.channels(); - m_left = st.leftVolume(); - m_right = st.rightVolume(); - } - else if (m_type == Error) - m_error_msg = new QString(*st.errorMessage()); - } - - OutputState(Type t) - : m_type(t), m_error_msg(0), m_elasped_seconds(0), - m_written_bytes(0), m_brate(0), m_freq(0), m_prec(0), m_chan(0), - m_left(0), m_right(0) -{} - OutputState(long s, unsigned long w, int b, int f, int p, int c) - : m_type(Info), m_error_msg(0), m_elasped_seconds(s), - m_written_bytes(w), m_brate(b), m_freq(f), m_prec(p), m_chan(c), - m_left(0), m_right(0) - {} - OutputState(int L, int R) - : m_type(Volume), m_error_msg(0), m_elasped_seconds(0), - m_written_bytes(0), m_brate(0), m_freq(0), m_prec(0), m_chan(0), - m_left(L), m_right(R) - {} - OutputState(const QString &e) - : m_type(Error), m_elasped_seconds(0), m_written_bytes(0), - m_brate(0), m_freq(0), m_prec(0), m_chan(0), - m_left(0), m_right(0) - { - m_error_msg = new QString(e); - } - ~OutputState() - { - if (m_error_msg) - delete m_error_msg; - } - - const QString *errorMessage() const - { - return m_error_msg; - } - - const long &elapsedSeconds() const - { - return m_elasped_seconds; - } - const unsigned long &writtenBytes() const - { - return m_written_bytes; - } - const int &bitrate() const - { - return m_brate; - } - const int &frequency() const - { - return m_freq; - } - const int &precision() const - { - return m_prec; - } - const int &channels() const - { - return m_chan; - } - const Type &type() const - { - return m_type; - } - const int leftVolume() const - { - return m_left; - } - const int rightVolume() const - { - return m_right; - } - -private: - Type m_type; - QString *m_error_msg; - long m_elasped_seconds; - unsigned long m_written_bytes; - int m_brate, m_freq, m_prec, m_chan; - int m_left, m_right; //volume -}; - - - - class Output : public QThread { Q_OBJECT @@ -146,15 +33,23 @@ public: Output(QObject * parent = 0); ~Output(); - Recycler *recycler() - { - return &r; - } + // abstract + virtual bool isInitialized() const = 0; + virtual bool initialize() = 0; + virtual void uninitialize() = 0; + virtual void configure(qint64, int, int) = 0; + virtual void pause() = 0; + virtual void stop() = 0; + virtual qint64 written() = 0; + virtual qint64 latency() = 0; + virtual void seek(long) = 0; + virtual void setVolume(int, int){}; + virtual void volume(int *, int *){}; + + Recycler *recycler(); + QMutex *mutex(); - QMutex *mutex() - { - return &mtx; - } + void setStateHandler(StateHandler *handler); //visualization void addVisual(Visual*); @@ -163,18 +58,6 @@ public: void removeVisual(VisualFactory *factory); void processCloseEvent(Visual *v, QCloseEvent *event); - // abstract - virtual bool isInitialized() const = 0; - virtual bool initialize() = 0; - virtual void uninitialize() = 0; - virtual void configure(long, int, int, int) = 0; - virtual void pause() = 0; - virtual void stop() = 0; - virtual long written() = 0; - virtual long latency() = 0; - virtual void seek(long) = 0; - virtual void setVolume(int, int){}; - virtual void volume(int *, int *){}; static void registerFactory(OutputFactory *); static Output *create(QObject *); @@ -187,24 +70,24 @@ public slots: void checkVolume(); void checkSoftwareVolume(); -signals: - void stateChanged(const OutputState&); - protected: - void dispatch(OutputState::Type); - void dispatch(long s, unsigned long w, int b, int f, int p, int c); - void dispatch(const OutputState&); - void dispatchVolume(int L, int R); - void error(const QString &e); + void dispatch(qint64 elapsed, + qint64 totalTime, + int bitrate, + int frequency, + int precision, + int channels); + void dispatch(const Qmmp::State &state); void dispatchVisual(Buffer *, unsigned long, int, int); void clearVisuals(); private: - QMutex mtx; - Recycler r; + QMutex m_mutex; + Recycler m_recycler; QList visuals; //external visualization QMap m_vis_map; //internal visualization int m_bl, m_br; + StateHandler *m_handler; }; diff --git a/src/qmmp/qmmp.cpp b/src/qmmp/qmmp.cpp new file mode 100644 index 000000000..1dca9c96b --- /dev/null +++ b/src/qmmp/qmmp.cpp @@ -0,0 +1,23 @@ +/*************************************************************************** + * 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 "qmmp.h" + + + diff --git a/src/qmmp/qmmp.h b/src/qmmp/qmmp.h new file mode 100644 index 000000000..1c52ae0dd --- /dev/null +++ b/src/qmmp/qmmp.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * 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 QMMP_H +#define QMMP_H + +/** + @author Ilya Kotov +*/ +class Qmmp +{ +public: + enum State {Playing = 0, Paused, Stopped, Buffering, NormalError, FatalError }; + +}; + +#endif diff --git a/src/qmmp/qmmp.pro b/src/qmmp/qmmp.pro index 1f95fc743..e123bd48f 100644 --- a/src/qmmp/qmmp.pro +++ b/src/qmmp/qmmp.pro @@ -17,7 +17,9 @@ HEADERS += recycler.h \ visual.h \ visualfactory.h \ effect.h \ - effectfactory.h + effectfactory.h \ + statehandler.h \ + qmmp.h SOURCES += recycler.cpp \ decoder.cpp \ output.cpp \ @@ -29,7 +31,9 @@ SOURCES += recycler.cpp \ downloader.cpp \ filetag.cpp \ visual.cpp \ - effect.cpp + effect.cpp \ + statehandler.cpp \ + qmmp.cpp TARGET = ../../lib/qmmp CONFIG += release \ @@ -42,16 +46,16 @@ TEMPLATE = lib VERSION = $$QMMP_VERSION PKGCONFIG += libcurl -unix:isEmpty(LIB_DIR){ - LIB_DIR = /lib -} +unix : isEmpty(LIB_DIR){ + LIB_DIR = /lib + } -unix:DEFINES += LIB_DIR=\\\"$$LIB_DIR\\\" +unix : DEFINES += LIB_DIR=\\\"$$LIB_DIR\\\" DEFINES += QMMP_VERSION=$$QMMP_VERSION -contains(CONFIG, SVN_VERSION) { -DEFINES += QMMP_STR_VERSION=\\\"$$QMMP_VERSION-svn\\\" -} else { -DEFINES += QMMP_STR_VERSION=\\\"$$QMMP_VERSION\\\" +contains(CONFIG, SVN_VERSION){ + DEFINES += QMMP_STR_VERSION=\\\"$$QMMP_VERSION-svn\\\" +}else { + DEFINES += QMMP_STR_VERSION=\\\"$$QMMP_VERSION\\\" } target.path = $$LIB_DIR diff --git a/src/qmmp/soundcore.cpp b/src/qmmp/soundcore.cpp index e282f13d8..cef20696c 100644 --- a/src/qmmp/soundcore.cpp +++ b/src/qmmp/soundcore.cpp @@ -28,6 +28,7 @@ #include "constants.h" #include "streamreader.h" #include "effect.h" +#include "statehandler.h" #include "soundcore.h" @@ -48,27 +49,9 @@ SoundCore::SoundCore(QObject *parent) m_preamp = 0; m_vis = 0; m_parentWidget = 0; + m_state = Qmmp::Stopped; for (int i = 1; i < 10; ++i) m_bands[i] = 0; - m_error = NoError; - m_output = Output::create(this); - if (!m_output) - { - m_error = DecoderError; - qWarning("SoundCore: unable to create output"); - } - connect(m_output, SIGNAL(stateChanged(const OutputState&)), - SIGNAL(outputStateChanged(const OutputState&))); - - QList *outputFactories = Output::outputFactories(); - foreach(OutputFactory* of, *outputFactories) - qApp->installTranslator(of->createTranslator(this)); - - QList *decoderFactories = Decoder::decoderFactories(); - foreach(DecoderFactory* df, *decoderFactories) - qApp->installTranslator(df->createTranslator(this)); - - Effect::effectFactories(); } @@ -78,74 +61,58 @@ SoundCore::~SoundCore() bool SoundCore::play(const QString &source) { stop(); - if (source.isEmpty()) + if (m_state != Qmmp::Stopped) //clear error state + setState(Qmmp::Stopped); + m_input = new QFile(source); + m_output = Output::create(this); + if (!m_output) { - m_error = DecoderError; + qWarning("SoundCore: unable to create output"); + setState(Qmmp::FatalError); return FALSE; } - if (source.left(4) == "http") - { - m_input = new StreamReader(source, this); - connect(m_input, SIGNAL(bufferingProgress(int)), SIGNAL(bufferingProgress(int))); - connect(m_input, SIGNAL(titleChanged(const QString&)), - SIGNAL(titleChanged(const QString&))); - connect(m_input, SIGNAL(readyRead()),SLOT(decode())); - } - else - m_input = new QFile(source); + if (!m_output->initialize()) + return FALSE; - m_error = OutputError; - if (!m_output) + m_decoder = Decoder::create(this, source, m_input, m_output); + if (!m_decoder) { - m_output = Output::create(this); - if (!m_output) - { - qWarning("SoundCore: unable to create output"); - return FALSE; - } - connect(m_output, SIGNAL(stateChanged(const OutputState&)), - SIGNAL(outputStateChanged(const OutputState&))); - connect(m_input, SIGNAL(readyRead()),SLOT(read())); - } - if (! m_output->initialize()) + qWarning("SoundCore: unsupported fileformat"); + m_block = FALSE; + stop(); + setState(Qmmp::NormalError); return FALSE; + } + qDebug ("ok"); + m_decoder->setBlockSize(globalBlockSize); //TODO remove + StateHandler *handler = m_decoder->stateHandler(); + connect(handler, SIGNAL(elapsedChanged(qint64)), SIGNAL(elapsedChanged(qint64))); + connect(handler, SIGNAL(bitrateChanged(int)), SIGNAL(bitrateChanged(int))); + connect(handler, SIGNAL(frequencyChanged(int)), SIGNAL(frequencyChanged(int))); + connect(handler, SIGNAL(precisionChanged(int)), SIGNAL(precisionChanged(int))); + connect(handler, SIGNAL(channelsChanged(int)), SIGNAL(channelsChanged(int))); + connect(handler, SIGNAL(metaDataChanged ()), SIGNAL(metaDataChanged ())); + connect(handler, SIGNAL(stateChanged (Qmmp::State)), SLOT(setState(Qmmp::State))); + connect(m_decoder, SIGNAL(finished()), SIGNAL(finished())); - m_error = DecoderError; - - Visual *visual = 0; - foreach(visual, m_visuals) - m_output->addVisual(visual); - - VisualFactory* factory; - foreach(factory, *Visual::visualFactories()) + if (m_decoder->initialize()) { - if (Visual::isEnabled(factory)) - m_output->addVisual(factory, m_parentWidget); + m_output->start(); + m_decoder->start(); + return TRUE; } - - m_source = source; - if (source.left(4) != "http") - return decode(); - else - qobject_cast(m_input)->downloadFile(); - return TRUE; -} - -uint SoundCore::error() -{ - return m_error; + stop(); + return FALSE; } void SoundCore::stop() { - if (m_block) - return; - m_paused = FALSE; if (m_decoder && m_decoder->isRunning()) { m_decoder->mutex()->lock (); m_decoder->stop(); m_decoder->mutex()->unlock(); + m_decoder->stateHandler()->dispatch(Qmmp::Stopped); } if (m_output) { @@ -171,42 +138,22 @@ void SoundCore::stop() m_decoder->wait(); if (m_output) m_output->wait(); - if (m_output && m_output->isInitialized()) + + if (m_output) { - m_output->uninitialize(); + m_output->deleteLater(); + m_output = 0; } - - //display->setTime(0); if (m_decoder) { - delete m_decoder; + m_decoder->deleteLater(); m_decoder = 0; } if (m_input) { - delete m_input; + m_input->deleteLater(); m_input = 0; } - // recreate output - if (m_update && m_output) - { - delete m_output; - m_output = 0; - m_update = FALSE; - m_output = Output::create(this); - if (!m_output) - { - qWarning("SoundCore: unable to create output"); - } - VisualFactory* factory; - foreach(factory, *Visual::visualFactories()) - { - if (Visual::isEnabled(factory)) - m_output->addVisual(factory, m_parentWidget); - } - connect(m_output, SIGNAL(stateChanged(const OutputState&)), - SIGNAL(outputStateChanged(const OutputState&))); - } } void SoundCore::pause() @@ -235,13 +182,10 @@ void SoundCore::pause() } } -void SoundCore::seek(int pos) +void SoundCore::seek(qint64 pos) { if (m_output && m_output->isRunning()) { - /*m_output->recycler()->mutex()->lock (); - m_output->recycler()->clear (); - m_output->recycler()->mutex()->unlock ();*/ m_output->mutex()->lock (); m_output->seek(pos); m_output->mutex()->unlock(); @@ -254,23 +198,9 @@ void SoundCore::seek(int pos) } } -int SoundCore::length() -{ - if (m_decoder) - return int(m_decoder->lengthInSeconds()); - return 0; -} - -bool SoundCore::isInitialized() +qint64 SoundCore::length() const { - if (m_decoder) - return TRUE; - return FALSE; -} - -bool SoundCore::isPaused() -{ - return m_paused; + return (m_decoder) ? m_decoder->lengthInSeconds() : 0; } void SoundCore::setEQ(int bands[10], const int &preamp) @@ -336,13 +266,50 @@ void SoundCore::volume(int *left, int *right) void SoundCore::updateConfig() { - m_update = TRUE; - if (isInitialized()) + //m_update = TRUE; + /*if (isInitialized()) return; - stop(); + stop();*/ +} + +qint64 SoundCore::elapsed() +{ + return (m_decoder) ? m_decoder->stateHandler()->elapsed() : 0; +} + +int SoundCore::bitrate() +{ + return (m_decoder) ? m_decoder->stateHandler()->bitrate() : 0; +} + +int SoundCore::frequency() +{ + return (m_decoder) ? m_decoder->stateHandler()->frequency() : 0; +} + +int SoundCore::precision() //TODO rename +{ + return (m_decoder) ? m_decoder->stateHandler()->precision() : 0; +} + +int SoundCore::channels() +{ + return (m_decoder) ? m_decoder->stateHandler()->channels() : 0; +} + +Qmmp::State SoundCore::state() const +{ + return (m_decoder) ? m_decoder->stateHandler()->state() : m_state; } -void SoundCore::addVisualization(Visual *visual) +void SoundCore::setState(Qmmp::State state) +{ + qDebug("new state = %d",state); + m_state = state; + emit stateChanged (state); +} + +/*void SoundCore::addVisualization(Visual *visual) { if (m_visuals.indexOf (visual) == -1) { @@ -350,9 +317,9 @@ void SoundCore::addVisualization(Visual *visual) if (m_output) m_output->addVisual(visual); } -} +}*/ -bool SoundCore::decode() +/*bool SoundCore::decode() { if (! m_decoder) { @@ -365,7 +332,7 @@ bool SoundCore::decode() qWarning("SoundCore: unsupported fileformat"); m_block = FALSE; stop(); - emit decoderStateChanged(DecoderState(DecoderState::Error)); + //emit decoderStateChanged(DecoderState(DecoderState::Error)); return FALSE; } qDebug ("ok"); @@ -381,16 +348,16 @@ bool SoundCore::decode() { m_output->start(); m_decoder->start(); - m_error = NoError; + //m_error = NoError; m_block = FALSE; return TRUE; } stop(); m_block = FALSE; return FALSE; -} +}*/ -void SoundCore::showVisualization(QWidget *parent) +/*void SoundCore::showVisualization(QWidget *parent) { if (!m_parentWidget) { @@ -430,7 +397,7 @@ void SoundCore::removeVisual(Visual *visual) if (m_output) m_output->removeVisual(visual); } -} +}*/ SoundCore* SoundCore::instance() { diff --git a/src/qmmp/soundcore.h b/src/qmmp/soundcore.h index 37e939a12..d585d9e53 100644 --- a/src/qmmp/soundcore.h +++ b/src/qmmp/soundcore.h @@ -1,6 +1,6 @@ /*************************************************************************** - * Copyright (C) 2006-2208 by Ilya Kotov * - * forkotov02@hotmail.ru * + * 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 * @@ -27,9 +27,10 @@ #include "decoder.h" #include "output.h" #include "visual.h" +#include "qmmp.h" /** - @author Ilya Kotov + \author Ilya Kotov */ class QIODevice; @@ -38,147 +39,119 @@ class SoundCore : public QObject { Q_OBJECT public: - - /*! This enum describes the errors that may be returned by the error() function. - * Available values is: - * \b SoundCore:NoError - no error occurred, - * \b SoundCore:DecoderError - an error occurred when creating decoder, - * \b SoundCore:OutputError - an error occurred when creating output. - */ - enum ErrorType { NoError = 0, DecoderError, OutputError }; - SoundCore(QObject *parent = 0); ~SoundCore(); - // properties - /*! - * Returns the playback error status. - * For example, if play() returns false, this function can be called to find out - * the reason why the operation failed. - */ - uint error(); + * Returns the current state. + * + * \return the state of the object. + */ - /*! - * Returns length in seconds - */ - int length(); + Qmmp::State state() const; /*! - * Returns \b TRUE if \b play() called successful, otherwise \b FALSE. - */ - bool isReady(); + * Returns length in seconds + */ + qint64 length() const; /*! - * Returns \b TRUE if \b play() called successful, otherwise \b FALSE. - * Also this function returns \b FALSE if \b stop() called before - */ - bool isInitialized(); + * Sets equalizer settings. Each item of \p bands[] and \p reamp should be + * \b -100..100 + */ + void setEQ(int bands[10], const int &preamp); /*! - * Returns \b TRUE if plugins in pause mode, otherwise \b FALSE. - */ - bool isPaused(); + * Enables equalizer if \p on is \b TRUE or disables it if \p on is \b FALSE + */ + void setEQEnabled(bool on); - //equalizer + /*! + * adds visualization \p visual + */ + //void addVisualization(Visual *visual); /*! - * Sets equalizer settings. Each item of \b bands[] and \b reamp should be - * \b -100..100 - */ - void setEQ(int bands[10], const int &preamp); + * shows enabled visualization with the parent widget \p parent + */ + //void showVisualization(QWidget *parent); /*! - * Enables equalizer if on is \b TRUE or disables it if on is \b FALSE - */ - void setEQEnabled(bool on); + * adds visualization by factory \p factory + */ + //void addVisual(VisualFactory *factory, QWidget *parent); - //volume + /*! + * removes visualization by factory \p factory + */ + //void removeVisual(VisualFactory *factory); - void volume(int*, int*); + /*! + * removes visualization \p visual + */ + //void removeVisual(Visual *visual); - //config + /*! + * reads current volume. + * \p left contains volume of the left channel. + * \p right contains volume of the right channel. + */ + void volume(int *left, int *right); /*! * updates configuration */ void updateConfig(); - //visualization - /*! - * adds visualization \b visual - */ - void addVisualization(Visual *visual); - /*! - * shows enabled visualization with parent widget \b parent - */ - void showVisualization(QWidget *parent); + qint64 elapsed(); + int bitrate(); + int frequency(); + int precision(); + int channels(); - /*! - * adds visualization by factory \b factory - */ - void addVisual(VisualFactory *factory, QWidget *parent); /*! - * removes visualization by factory \b factory - */ - void removeVisual(VisualFactory *factory); - - /*! - * removes visualization \b visual - */ - void removeVisual(Visual *visual); - + * Returns a pointer to the SoundCore instance. + */ static SoundCore* instance(); public slots: /*! - * Sets volume. \b L - volume of left channel. \b R - volume of right channel. - * \b L and \b R should be 0..100 - */ - void setVolume(int L, int R); - - //control + * Sets volume. + * \p left - volume of the left channel. + * \p right - volume of the right channel. + * \b left and \b right should be \b 0..100. + */ + void setVolume(int left, int right); /*! - * This function plays file with given path, returns \b TRUE if all is OK, otherwise \b FALSE - */ + * This function plays file with the given path \p source. + * + * \return \b TRUE if playback started successful or source is not a local file. + * \return \b FALSE otherwise. + */ bool play(const QString &source); - /*! - * Stops playing - */ + * Stops playback + */ void stop(); /*! - * Pauses/resumes playing - */ + * Pauses/resumes playback + */ void pause(); /*! - *This function sets the current play position to \b pos + *This function sets the current play position to \p pos. */ - void seek(int pos); - + void seek(qint64 pos); signals: - /*! - * This signal is emited when the state of the decoder changes. - * The argument \b state is the new state of the decoder - */ - void decoderStateChanged(const DecoderState& state); - - /*! - * This signal is emited when the state of the output changes. - * The argument \b state is the new state of the output - */ - void outputStateChanged(const OutputState& state); - /*! * This signal is emited when the title of the stream changes. * The argument \b title is the new title of the stream. @@ -193,9 +166,18 @@ signals: */ void bufferingProgress(int progress); + void elapsedChanged(qint64 time); + void bitrateChanged(int bitrate); + void frequencyChanged(int frequency); + void precisionChanged(int precision); + void channelsChanged(int channels); + void metaDataChanged (); + void stateChanged (Qmmp::State newState); + void finished(); private slots: - bool decode(); + //bool decode(); + void setState(Qmmp::State); private: Decoder* m_decoder; @@ -213,6 +195,7 @@ private: QString m_source; QWidget *m_parentWidget; static SoundCore* m_instance; + Qmmp::State m_state; }; #endif diff --git a/src/qmmp/statehandler.cpp b/src/qmmp/statehandler.cpp new file mode 100644 index 000000000..1bb1fb235 --- /dev/null +++ b/src/qmmp/statehandler.cpp @@ -0,0 +1,162 @@ +/*************************************************************************** + * 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 "statehandler.h" + + +StateHandler* StateHandler::m_instance = 0; + +StateHandler::StateHandler(QObject *parent) + : QObject(parent) +{ + m_instance = this; + m_elapsed = -1; + m_totalTime = 0; + m_bitrate = 0; + m_frequency = 0; + m_precision = 0; + m_channels = 0; + m_state = Qmmp::Stopped; +} + + +StateHandler::~StateHandler() +{ + m_instance = 0; +} + + +void StateHandler::dispatch(qint64 elapsed, + qint64 totalTime, + int bitrate, + int frequency, + int precision, + int channels) +{ + m_mutex.lock(); + if (m_elapsed != elapsed) + { + m_elapsed = elapsed; + emit (elapsedChanged(elapsed)); + } + /*if (m_totalTime != totalTime) + { + m_totalTime = totalTime; + emit (totalTimeChanged(totalTime)); + }*/ + if (m_bitrate != bitrate) + { + m_bitrate = bitrate; + emit (bitrateChanged(bitrate)); + } + if (m_frequency != frequency) + { + m_frequency = frequency; + emit (frequencyChanged(frequency)); + } + if (m_precision != precision) + { + m_precision = precision; + emit (precisionChanged(precision)); + } + if (m_channels != channels) + { + m_channels = channels; + emit (channelsChanged(channels)); + } + m_mutex.unlock(); +} + +void StateHandler::dispatch(QMap metaData) +{ + m_mutex.lock(); + if (m_metaData != metaData) + { + m_metaData = metaData; + emit metaDataChanged (); + } + m_mutex.unlock(); +} + +void StateHandler::dispatch(const Qmmp::State &state) +{ + m_mutex.lock(); + if (m_state != state) + { + m_state = state; + emit stateChanged(state); + } + m_mutex.unlock(); +} + +/*void StateHandler::dispatchTotalTime(qint64 totalTime) +{ + m_mutex.lock(); + if (m_totalTime != totalTime) + { + m_totalTime = totalTime; + emit (totalTimeChanged(totalTime)); + } + m_mutex.unlock(); +}*/ + +qint64 StateHandler::elapsed() +{ + return m_elapsed; +} + +qint64 StateHandler::totalTime() +{ + return m_totalTime; +} + +int StateHandler::bitrate() +{ + return m_bitrate; +} + +int StateHandler::frequency() +{ + return m_frequency; +} + +int StateHandler::precision() +{ + return m_precision; +} + +int StateHandler::channels() +{ + return m_channels; +} + +Qmmp::State StateHandler::state() +{ + return m_state; +} + +QMap StateHandler::metaData() +{ + return m_metaData; +} + +StateHandler *StateHandler::instance() +{ + return m_instance; +} diff --git a/src/qmmp/statehandler.h b/src/qmmp/statehandler.h new file mode 100644 index 000000000..b800f2d4d --- /dev/null +++ b/src/qmmp/statehandler.h @@ -0,0 +1,86 @@ +/*************************************************************************** + * 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 STATEHANDLER_H +#define STATEHANDLER_H + +#include +#include +#include + +#include "qmmp.h" + +/** + @author Ilya Kotov +*/ +class StateHandler : public QObject +{ + Q_OBJECT +public: + StateHandler(QObject *parent = 0); + + ~StateHandler(); + + void dispatch(qint64 elapsed, + qint64 totalTime, + int bitrate, + int frequency, + int precision, + int channels); + + void dispatch(QMap metaData); + + void dispatch(const Qmmp::State &state); + + qint64 elapsed(); + qint64 totalTime(); + int bitrate(); + int frequency(); + int precision(); + int channels(); + Qmmp::State state(); + QMap metaData(); + + /*! + * Returns a pointer to the StateHandler instance. + */ + static StateHandler* instance(); + +signals: + void elapsedChanged(qint64 time); + //void totalTimeChanged(qint64 time); + void bitrateChanged(int bitrate); + void frequencyChanged(int frequency); + void precisionChanged(int precision); + void channelsChanged(int channels); + void metaDataChanged (); + void stateChanged (Qmmp::State newState); + void finished(); + +private: + qint64 m_elapsed, m_totalTime; + int m_bitrate, m_frequency, m_precision, m_channels; + static StateHandler* m_instance; + QMap m_metaData; + Qmmp::State m_state; + QMutex m_mutex; + +}; + +#endif diff --git a/src/ui/builtincommandlineoption.cpp b/src/ui/builtincommandlineoption.cpp index e35914f34..32e22fb96 100644 --- a/src/ui/builtincommandlineoption.cpp +++ b/src/ui/builtincommandlineoption.cpp @@ -92,13 +92,13 @@ void BuiltinCommandLineOption::executeCommand(const QString & option_string, Mai else if (option_string == "--next") { mw->next(); - if (!mw->soundCore()->isInitialized()) + if (mw->soundCore()->state() == Qmmp::Stopped) mw->play(); } else if (option_string == "--previous") { mw->previous(); - if (!mw->soundCore()->isInitialized()) + if (mw->soundCore()->state() == Qmmp::Stopped) mw->play(); } else if (option_string == "--play-pause") diff --git a/src/ui/display.cpp b/src/ui/display.cpp index 7c7b7e961..c338050bb 100644 --- a/src/ui/display.cpp +++ b/src/ui/display.cpp @@ -25,6 +25,7 @@ #include #include +#include #include "skin.h" #include "mainvisual.h" #include "button.h" @@ -82,23 +83,23 @@ MainDisplay::MainDisplay (QWidget *parent) vis->show(); m_eqButton = new ToggleButton (this,Skin::BT_EQ_ON_N,Skin::BT_EQ_ON_P, - Skin::BT_EQ_OFF_N,Skin::BT_EQ_OFF_P); + Skin::BT_EQ_OFF_N,Skin::BT_EQ_OFF_P); m_eqButton->move (219,58); m_eqButton->show(); m_plButton = new ToggleButton (this,Skin::BT_PL_ON_N,Skin::BT_PL_ON_P, - Skin::BT_PL_OFF_N,Skin::BT_PL_OFF_P); + Skin::BT_PL_OFF_N,Skin::BT_PL_OFF_P); m_plButton->move (241,58); m_plButton->show(); m_repeatButton = new ToggleButton (this,Skin::REPEAT_ON_N,Skin::REPEAT_ON_P, - Skin::REPEAT_OFF_N,Skin::REPEAT_OFF_P); + Skin::REPEAT_OFF_N,Skin::REPEAT_OFF_P); connect(m_repeatButton,SIGNAL(clicked(bool)),this,SIGNAL(repeatableToggled(bool))); m_repeatButton->move (210,89); m_repeatButton->show(); m_shuffleButton = new ToggleButton (this,Skin::SHUFFLE_ON_N,Skin::SHUFFLE_ON_P, - Skin::SHUFFLE_OFF_N,Skin::SHUFFLE_OFF_P); + Skin::SHUFFLE_OFF_N,Skin::SHUFFLE_OFF_P); connect(m_shuffleButton,SIGNAL(clicked(bool)),this,SIGNAL(shuffleToggled(bool))); m_shuffleButton->move (164,89); m_shuffleButton->show(); @@ -147,23 +148,60 @@ MainDisplay::~MainDisplay() settings.setValue ("Equalizer/visible",m_eqButton->isChecked()); } -void MainDisplay::setTime (int t) +void MainDisplay::setTime (qint64 t) { - posbar->setValue (t); + posbar->setValue (t); //TODO use qint64 m_timeIndicator->setTime(t); } -void MainDisplay::setMaxTime (long mt) // TODO: should be removed +void MainDisplay::setDuration(qint64 t) { - posbar->setMax (mt); - m_timeIndicator->setSongDuration(mt); + posbar->setMax (t); + m_timeIndicator->setSongDuration(t); } +void MainDisplay::setState(Qmmp::State state) +{ + switch ((int) state) + { + case Qmmp::Playing: + { + m_playstatus->setStatus(PlayStatus::PLAY); + m_timeIndicator->setNeedToShowTime(TRUE); + setDuration(m_core->length()); + break; + } + /*case OutputState::Buffering: + { + //ui.label->setText("Buffering"); + break; + }*/ + case Qmmp::Paused: + { + m_playstatus->setStatus(PlayStatus::PAUSE); + break; + } + case Qmmp::Stopped: + { + m_playstatus->setStatus(PlayStatus::STOP); + m_monoster->setChannels (0); + m_timeIndicator->setNeedToShowTime(FALSE); + posbar->setValue (0); + posbar->setMax (0); + break; + } + } +} void MainDisplay::updateSkin() { setPixmap (m_skin->getMain()); } +void MainDisplay::setSampleRate(int rate) +{ + m_freq->display(rate/1000); +} + void MainDisplay::setEQ (QWidget* w) { m_equlizer = w; @@ -180,7 +218,7 @@ void MainDisplay::setPL (QWidget* w) connect (m_playlist, SIGNAL (closed ()), m_plButton, SLOT (click())); } -void MainDisplay::setInfo(const OutputState &st) +/*void MainDisplay::setInfo(const OutputState &st) { @@ -229,6 +267,17 @@ void MainDisplay::setInfo(const OutputState &st) break; } +}*/ + +void MainDisplay::setSoundCore(SoundCore *core) +{ + m_core = core; + connect(core, SIGNAL(elapsedChanged(qint64)), SLOT(setTime(qint64))); + //connect(core, SIGNAL(totalTimeChanged(qint64 time) + connect(core, SIGNAL(bitrateChanged(int)), m_kbps, SLOT(display(int))); + connect(core, SIGNAL(frequencyChanged(int)), SLOT(setSampleRate(int))); + connect(core, SIGNAL(channelsChanged(int)), m_monoster, SLOT(setChannels(int))); + connect(core, SIGNAL(stateChanged(Qmmp::State)), SLOT(setState(Qmmp::State))); } bool MainDisplay::isPlaylistVisible() const diff --git a/src/ui/display.h b/src/ui/display.h index 15e0111d6..4e7623f2f 100644 --- a/src/ui/display.h +++ b/src/ui/display.h @@ -22,9 +22,7 @@ #include -class TimeIndicator; - - +#include #include "pixmapwidget.h" /** @@ -33,6 +31,7 @@ class TimeIndicator; class QPushButton; class QLabel; +class TimeIndicator; class TitleBar; class PositionBar; class Number; @@ -46,6 +45,7 @@ class PlayStatus; class VolumeBar; class BalanceBar; class MainWindow; +class SoundCore; class MainDisplay : public PixmapWidget { @@ -55,10 +55,10 @@ public: ~MainDisplay(); - void setMaxTime(long); void setEQ(QWidget*); void setPL(QWidget*); - void setInfo(const OutputState &st); + //void setInfo(const OutputState &st); + void setSoundCore(SoundCore *core); bool isEqualizerVisible()const; bool isPlaylistVisible()const; bool isRepeatable()const; @@ -67,11 +67,13 @@ public: void setIsShuffle(bool); public slots: - void setTime(int); void hideTimeDisplay(); + void setDuration(qint64); + signals: void repeatableToggled(bool); void shuffleToggled(bool); + protected: void wheelEvent(QWheelEvent *); void mousePressEvent(QMouseEvent*); @@ -79,6 +81,9 @@ protected: private slots: void updateSkin(); void updateVolume(); + void setSampleRate(int rate); + void setTime(qint64); + void setState(Qmmp::State state); private: QWidget* m_equlizer; @@ -101,6 +106,7 @@ private: BalanceBar* m_balanceBar; MainWindow* m_mw; TimeIndicator* m_timeIndicator; + SoundCore *m_core; }; #endif diff --git a/src/ui/eqwidget.cpp b/src/ui/eqwidget.cpp index 3f6e1c781..b9c5ede33 100644 --- a/src/ui/eqwidget.cpp +++ b/src/ui/eqwidget.cpp @@ -364,14 +364,14 @@ void EqWidget::loadPreset(const QString &name) } } -void EqWidget::setInfo(const OutputState &st) +/*void EqWidget::setInfo(const OutputState &st) { if (st.type() == OutputState::Volume) { m_titleBar->setVolume(st.leftVolume(),st.rightVolume()); } -} +}*/ EQPreset *EqWidget::findPreset(const QString &name) { diff --git a/src/ui/eqwidget.h b/src/ui/eqwidget.h index b6bf77ebf..7b3680a45 100644 --- a/src/ui/eqwidget.h +++ b/src/ui/eqwidget.h @@ -56,7 +56,7 @@ public: /*! * shows output volume and balance. Necessare for the shaded mode */ - void setInfo(const OutputState &st); + //void setInfo(const OutputState &st); signals: void valueChanged(); diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index cdb369040..d63237df7 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -123,20 +123,30 @@ MainWindow::MainWindow(const QStringList& args, BuiltinCommandLineOption* option display->setEQ(m_equalizer); display->setPL(m_playlist); + display->setSoundCore(m_core); m_vis = MainVisual::getPointer(); - m_core->addVisualization(m_vis); - m_core->showVisualization(this); + //m_core->addVisualization(m_vis); + //m_core->showVisualization(this); - connect(m_core, SIGNAL(outputStateChanged(const OutputState&)), + /*connect(m_core, SIGNAL(outputStateChanged(const OutputState&)), SLOT(showOutputState(const OutputState&))); connect(m_core, SIGNAL(decoderStateChanged(const DecoderState&)), SLOT(showDecoderState(const DecoderState&))); connect(m_core, SIGNAL(titleChanged(const QString&)), SLOT(changeTitle(const QString&))); connect(m_core, SIGNAL(bufferingProgress(int)), TextScroller::getPointer(), - SLOT(setProgress(int))); + SLOT(setProgress(int)));*/ + + + + connect(m_core, SIGNAL(finished()), SLOT(next())); + connect(m_core, SIGNAL(stateChanged(Qmmp::State)), SLOT(showState(Qmmp::State))); + connect(m_core, SIGNAL(elapsedChanged(qint64)),m_playlist, SLOT(setTime(qint64))); + connect(m_core, SIGNAL(elapsedChanged(qint64)),m_titlebar, SLOT(setTime(qint64))); + + updateEQ(); @@ -171,12 +181,12 @@ void MainWindow::play() disconnect(m_playListModel, SIGNAL(firstAdded()), this, SLOT(play())); m_playListModel->doCurrentVisibleRequest(); - if (m_core->isPaused()) + if (m_core->state() == Qmmp::Paused) { pause(); return; } - stop(); + //stop(); if (m_playListModel->count() == 0) return; @@ -188,21 +198,22 @@ void MainWindow::play() return; if (m_core->play(s)) { - display->setTime(0); + //display->setTime(0); + qDebug("play"); m_generalHandler->setTime(0); - display->setMaxTime(m_core->length()); + //display->setDuration(m_core->totalTime()); } else { //find out the reason why the playback failed - switch ((int) m_core->error()) + switch ((int) m_core->state()) { - case SoundCore::OutputError: + case Qmmp::FatalError: { stop(); return; //unrecovable error in output, so abort playing } - case SoundCore::DecoderError: + case Qmmp::NormalError: { //error in decoder, so we should try to play next song qApp->processEvents(); @@ -239,12 +250,12 @@ void MainWindow::seek(int pos) void MainWindow::forward() { - seek(m_elapsed + KEY_OFFSET); + seek(m_core->elapsed() + KEY_OFFSET); } void MainWindow::backward() { - seek(qMax(0,m_elapsed - KEY_OFFSET)); + seek(qMax(qint64(0), m_core->elapsed() - KEY_OFFSET)); } void MainWindow::setVolume(int volume, int balance) @@ -260,7 +271,7 @@ void MainWindow::pause(void) void MainWindow::stop() { - display->setTime(0); + //display->setTime(0); m_core->stop(); } void MainWindow::next() @@ -276,7 +287,7 @@ void MainWindow::next() return; } m_playlist->update(); - if (m_core->isInitialized()) + if (m_core->state() != Qmmp::Stopped) { stop(); m_elapsed = 0; @@ -294,7 +305,7 @@ void MainWindow::previous() } m_playlist->update(); - if (m_core->isInitialized()) + if (m_core->state() != Qmmp::Stopped) { stop(); play(); @@ -312,17 +323,50 @@ void MainWindow::updateEQ() m_core->setEQEnabled(m_equalizer->isEQEnabled()); } -void MainWindow::showOutputState(const OutputState &st) +void MainWindow::showState(Qmmp::State state) +{ + switch ((int) state) + { + case Qmmp::Playing: + { + m_generalHandler->setState(General::Playing); + if (m_playListModel->currentItem()) + { + SongInfo info = *m_playListModel->currentItem(); + if (info.isEmpty()) + info.setValue(SongInfo::TITLE, m_playlist->currentItem()->text()); + m_generalHandler->setSongInfo(info); + } + if (m_playlist->listWidget()) + m_playlist->listWidget()->updateList(); //removes progress message from TextScroller + break; + } + case Qmmp::Paused: + { + m_generalHandler->setState(General::Paused); + break; + } + case Qmmp::Stopped: + { + m_generalHandler->setState(General::Stopped); + m_playlist->setTime(-1); + m_titlebar->setTime(-1); + break; + } + } +} + +/*void MainWindow::showOutputState(const OutputState &st) { if (seeking) return; - display->setInfo(st); - m_playlist->setInfo(st, m_core->length(), m_playListModel->totalLength()); - m_titlebar->setInfo(st); - m_equalizer->setInfo(st); - switch ((int) st.type()) + //display->setInfo(st); + //m_playlist->setInfo(st, m_core->length(), m_playListModel->totalLength()); + //m_titlebar->setInfo(st); + // m_equalizer->setInfo(st); + /*switch ((int) st.type()) { case OutputState::Playing: { @@ -361,9 +405,9 @@ void MainWindow::showOutputState(const OutputState &st) { m_visMenu->updateActions(); } - } -} -void MainWindow::showDecoderState(const DecoderState &st) + }*/ +//} +/*void MainWindow::showDecoderState(const DecoderState &st) { switch ((int) st.type()) { @@ -407,7 +451,7 @@ void MainWindow::showDecoderState(const DecoderState &st) break; } } -} +}*/ void MainWindow::changeTitle(const QString &title) { @@ -677,7 +721,7 @@ void MainWindow::setFileList(const QStringList & l) void MainWindow::playPause() { - if (m_core->isInitialized()) + if (m_core->state() == Qmmp::Playing) pause(); else play(); diff --git a/src/ui/mainwindow.h b/src/ui/mainwindow.h index b0d535b04..3a2a7a52f 100644 --- a/src/ui/mainwindow.h +++ b/src/ui/mainwindow.h @@ -93,8 +93,9 @@ protected: virtual void keyPressEvent ( QKeyEvent* ); private slots: - void showOutputState(const OutputState&); - void showDecoderState(const DecoderState&); + //void showOutputState(const OutputState&); + //void showDecoderState(const DecoderState&); + void showState(Qmmp::State state); void changeTitle(const QString&); void clear(); void startSeek(); diff --git a/src/ui/monostereo.h b/src/ui/monostereo.h index be1419c5c..936cf0607 100644 --- a/src/ui/monostereo.h +++ b/src/ui/monostereo.h @@ -35,6 +35,7 @@ public: ~MonoStereo(); +public slots: void setChannels(int); private slots: diff --git a/src/ui/playlist.cpp b/src/ui/playlist.cpp index de79e3dcf..f4490fbec 100644 --- a/src/ui/playlist.cpp +++ b/src/ui/playlist.cpp @@ -40,12 +40,13 @@ #include "symboldisplay.h" #include "playlistcontrol.h" #include "keyboardmanager.h" -#include -PlayList::PlayList ( QWidget *parent ) - : QWidget ( parent ) +#include + +PlayList::PlayList (QWidget *parent) + : QWidget (parent) { - setWindowFlags ( Qt::Dialog | Qt::FramelessWindowHint ); + setWindowFlags (Qt::Dialog | Qt::FramelessWindowHint); m_update = FALSE; m_resize = FALSE; @@ -54,62 +55,62 @@ PlayList::PlayList ( QWidget *parent ) createMenus(); - resize ( 275,116 ); - setMinimumSize ( 275,116 ); - setBaseSize ( 275,116 ); - m_listWidget = new ListWidget ( this ); + resize (275,116); + setMinimumSize (275,116); + setBaseSize (275,116); + m_listWidget = new ListWidget (this); m_listWidget->show(); - m_listWidget->setGeometry ( 12,20,243,58 ); + m_listWidget->setGeometry (12,20,243,58); - m_plslider = new PlayListSlider ( this ); + m_plslider = new PlayListSlider (this); m_plslider->show(); - setSizeIncrement ( 25,29 ); + setSizeIncrement (25,29); m_skin = Skin::getPointer(); - m_buttonAdd = new Button ( this,Skin::PL_BT_ADD,Skin::PL_BT_ADD ); - m_buttonAdd->move ( 11,86 ); - m_buttonSub = new Button ( this,Skin::PL_BT_SUB,Skin::PL_BT_SUB ); - m_buttonSub->move ( 40,86 ); - m_selectButton = new Button ( this,Skin::PL_BT_SEL,Skin::PL_BT_SEL ); - m_selectButton->move ( 70,86 ); - m_sortButton= new Button ( this,Skin::PL_BT_SORT,Skin::PL_BT_SORT ); - m_sortButton->move ( 99,86 ); - m_playlistButton = new Button ( this,Skin::PL_BT_LST,Skin::PL_BT_LST ); - - m_pl_control = new PlaylistControl ( this ); - m_pl_control->move ( 0,0 ); + m_buttonAdd = new Button (this,Skin::PL_BT_ADD,Skin::PL_BT_ADD); + m_buttonAdd->move (11,86); + m_buttonSub = new Button (this,Skin::PL_BT_SUB,Skin::PL_BT_SUB); + m_buttonSub->move (40,86); + m_selectButton = new Button (this,Skin::PL_BT_SEL,Skin::PL_BT_SEL); + m_selectButton->move (70,86); + m_sortButton= new Button (this,Skin::PL_BT_SORT,Skin::PL_BT_SORT); + m_sortButton->move (99,86); + m_playlistButton = new Button (this,Skin::PL_BT_LST,Skin::PL_BT_LST); + + m_pl_control = new PlaylistControl (this); + m_pl_control->move (0,0); m_pl_control->show(); - m_length_totalLength = new SymbolDisplay ( this,14 ); - m_length_totalLength->setAlignment ( Qt::AlignLeft ); + m_length_totalLength = new SymbolDisplay (this,14); + m_length_totalLength->setAlignment (Qt::AlignLeft); m_length_totalLength -> show(); - m_current_time = new SymbolDisplay ( this,6 ); + m_current_time = new SymbolDisplay (this,6); m_current_time->show(); - m_keyboardManager = new KeyboardManager ( this ); - - connect ( m_listWidget, SIGNAL ( selectionChanged() ), parent, SLOT ( replay() ) ); - - connect ( m_plslider, SIGNAL ( sliderMoved ( int ) ), m_listWidget, SLOT ( scroll ( int ) ) ); - connect ( m_listWidget, SIGNAL ( positionChanged ( int, int ) ), m_plslider, - SLOT ( setPos ( int, int ) ) ); - connect ( m_skin, SIGNAL ( skinChanged() ), this, SLOT ( update() ) ); - connect ( m_buttonAdd, SIGNAL ( clicked() ), SLOT ( showAddMenu() ) ); - connect ( m_buttonSub, SIGNAL ( clicked() ), SLOT ( showSubMenu() ) ); - connect ( m_selectButton, SIGNAL ( clicked() ), SLOT ( showSelectMenu() ) ); - connect ( m_sortButton, SIGNAL ( clicked() ), SLOT ( showSortMenu() ) ); - connect ( m_playlistButton, SIGNAL ( clicked() ), SLOT ( showPlaylistMenu() ) ); - - connect ( m_pl_control, SIGNAL ( nextClicked() ), SIGNAL ( next() ) ); - connect ( m_pl_control, SIGNAL ( previousClicked() ), SIGNAL ( prev() ) ); - connect ( m_pl_control, SIGNAL ( playClicked() ), SIGNAL ( play() ) ); - connect ( m_pl_control, SIGNAL ( pauseClicked() ), SIGNAL ( pause() ) ); - connect ( m_pl_control, SIGNAL ( stopClicked() ), SIGNAL ( stop() ) ); - connect ( m_pl_control, SIGNAL ( ejectClicked() ), SIGNAL ( eject() ) ); - m_titleBar = new PlayListTitleBar ( this ); - m_titleBar->move ( 0,0 ); + m_keyboardManager = new KeyboardManager (this); + + connect (m_listWidget, SIGNAL (selectionChanged()), parent, SLOT (replay())); + + connect (m_plslider, SIGNAL (sliderMoved (int)), m_listWidget, SLOT (scroll (int))); + connect (m_listWidget, SIGNAL (positionChanged (int, int)), m_plslider, + SLOT (setPos (int, int))); + connect (m_skin, SIGNAL (skinChanged()), this, SLOT (update())); + connect (m_buttonAdd, SIGNAL (clicked()), SLOT (showAddMenu())); + connect (m_buttonSub, SIGNAL (clicked()), SLOT (showSubMenu())); + connect (m_selectButton, SIGNAL (clicked()), SLOT (showSelectMenu())); + connect (m_sortButton, SIGNAL (clicked()), SLOT (showSortMenu())); + connect (m_playlistButton, SIGNAL (clicked()), SLOT (showPlaylistMenu())); + + connect (m_pl_control, SIGNAL (nextClicked()), SIGNAL (next())); + connect (m_pl_control, SIGNAL (previousClicked()), SIGNAL (prev())); + connect (m_pl_control, SIGNAL (playClicked()), SIGNAL (play())); + connect (m_pl_control, SIGNAL (pauseClicked()), SIGNAL (pause())); + connect (m_pl_control, SIGNAL (stopClicked()), SIGNAL (stop())); + connect (m_pl_control, SIGNAL (ejectClicked()), SIGNAL (eject())); + m_titleBar = new PlayListTitleBar (this); + m_titleBar->move (0,0); readSettings(); } @@ -119,120 +120,121 @@ PlayList::~PlayList() void PlayList::createMenus() { - m_addMenu = new QMenu ( this ); - m_subMenu = new QMenu ( this ); - m_selectMenu = new QMenu ( this ); - m_sortMenu = new QMenu ( this ); - m_playlistMenu = new QMenu ( this ); + m_addMenu = new QMenu (this); + m_subMenu = new QMenu (this); + m_selectMenu = new QMenu (this); + m_sortMenu = new QMenu (this); + m_playlistMenu = new QMenu (this); } void PlayList::createActions() -{ //add menu - QAction *addFileAct = new QAction ( tr ( "&Add File" ),this ); - addFileAct->setShortcut ( tr ( "F" ) ); - m_addMenu->addAction ( addFileAct ); - connect ( addFileAct, SIGNAL ( triggered() ), parent(), SLOT ( addFile () ) ); +{ + //add menu + QAction *addFileAct = new QAction (tr ("&Add File"),this); + addFileAct->setShortcut (tr ("F")); + m_addMenu->addAction (addFileAct); + connect (addFileAct, SIGNAL (triggered()), parent(), SLOT (addFile ())); m_actions << addFileAct; - QAction *addDirAct = new QAction ( tr ( "&Add Directory" ),this ); - addDirAct->setShortcut ( tr ( "D" ) ); - m_addMenu->addAction ( addDirAct ); - connect ( addDirAct, SIGNAL ( triggered() ), parent(), SLOT ( addDir () ) ); + QAction *addDirAct = new QAction (tr ("&Add Directory"),this); + addDirAct->setShortcut (tr ("D")); + m_addMenu->addAction (addDirAct); + connect (addDirAct, SIGNAL (triggered()), parent(), SLOT (addDir ())); m_actions << addDirAct; - QAction *addUrlAct = new QAction ( tr ( "&Add Url" ),this ); - addUrlAct->setShortcut ( tr ( "U" ) ); - m_addMenu->addAction ( addUrlAct ); - connect ( addUrlAct, SIGNAL ( triggered() ), parent(), SLOT ( addUrl () ) ); + QAction *addUrlAct = new QAction (tr ("&Add Url"),this); + addUrlAct->setShortcut (tr ("U")); + m_addMenu->addAction (addUrlAct); + connect (addUrlAct, SIGNAL (triggered()), parent(), SLOT (addUrl ())); m_actions << addUrlAct; //remove menu - QAction *remSelAct = new QAction ( tr ( "&Remove Selected" ),this ); - remSelAct->setShortcut ( tr ( "Del" ) ); - m_subMenu->addAction ( remSelAct ); - connect ( remSelAct, SIGNAL ( triggered() ), - m_playListModel, SLOT ( removeSelected () ) ); - this->addAction ( remSelAct ); - - QAction *remAllAct = new QAction ( tr ( "&Remove All" ),this ); + QAction *remSelAct = new QAction (tr ("&Remove Selected"),this); + remSelAct->setShortcut (tr ("Del")); + m_subMenu->addAction (remSelAct); + connect (remSelAct, SIGNAL (triggered()), + m_playListModel, SLOT (removeSelected ())); + this->addAction (remSelAct); + + QAction *remAllAct = new QAction (tr ("&Remove All"),this); //remAllAct->setShortcut(tr("D")); FIXME: add correct shortcat - m_subMenu->addAction ( remAllAct ); - connect ( remAllAct, SIGNAL ( triggered() ), m_playListModel, SLOT ( clear () ) ); + m_subMenu->addAction (remAllAct); + connect (remAllAct, SIGNAL (triggered()), m_playListModel, SLOT (clear ())); m_actions << remAllAct; - QAction *remUnselAct = new QAction ( tr ( "&Remove Unselected" ),this ); - m_subMenu->addAction ( remUnselAct ); - connect ( remUnselAct, SIGNAL ( triggered() ), - m_playListModel, SLOT ( removeUnselected () ) ); + QAction *remUnselAct = new QAction (tr ("&Remove Unselected"),this); + m_subMenu->addAction (remUnselAct); + connect (remUnselAct, SIGNAL (triggered()), + m_playListModel, SLOT (removeUnselected ())); //listwidget menu - QAction *detailsAct = new QAction ( tr ( "&View Track Details" ),this ); - detailsAct->setShortcut ( tr ( "Alt+I" ) ); - m_listWidget->menu()->addAction ( detailsAct ); - connect ( detailsAct, SIGNAL ( triggered() ), m_playListModel, SLOT ( showDetails () ) ); + QAction *detailsAct = new QAction (tr ("&View Track Details"),this); + detailsAct->setShortcut (tr ("Alt+I")); + m_listWidget->menu()->addAction (detailsAct); + connect (detailsAct, SIGNAL (triggered()), m_playListModel, SLOT (showDetails ())); // sort menu - m_sortMenu->addAction ( detailsAct ); + m_sortMenu->addAction (detailsAct); m_sortMenu->addSeparator(); - QMenu* sort_mode_menu = new QMenu ( tr ( "Sort List" ),m_sortMenu ); + QMenu* sort_mode_menu = new QMenu (tr ("Sort List"),m_sortMenu); - QSignalMapper* signalMapper = new QSignalMapper ( this ); - QAction* titleAct = sort_mode_menu->addAction ( tr ( "By Title" ) ); - connect ( titleAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); - signalMapper->setMapping ( titleAct, PlayListModel::TITLE ); + QSignalMapper* signalMapper = new QSignalMapper (this); + QAction* titleAct = sort_mode_menu->addAction (tr ("By Title")); + connect (titleAct, SIGNAL (triggered (bool)), signalMapper, SLOT (map())); + signalMapper->setMapping (titleAct, PlayListModel::TITLE); - QAction* nameAct = sort_mode_menu->addAction ( tr ( "By Filename" ) ); - connect ( nameAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); - signalMapper->setMapping ( nameAct, PlayListModel::FILENAME ); + QAction* nameAct = sort_mode_menu->addAction (tr ("By Filename")); + connect (nameAct, SIGNAL (triggered (bool)), signalMapper, SLOT (map())); + signalMapper->setMapping (nameAct, PlayListModel::FILENAME); - QAction* pathnameAct = sort_mode_menu->addAction ( tr ( "By Path + Filename" ) ); - connect ( pathnameAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); - signalMapper->setMapping ( pathnameAct, PlayListModel::PATH_AND_FILENAME ); + QAction* pathnameAct = sort_mode_menu->addAction (tr ("By Path + Filename")); + connect (pathnameAct, SIGNAL (triggered (bool)), signalMapper, SLOT (map())); + signalMapper->setMapping (pathnameAct, PlayListModel::PATH_AND_FILENAME); - QAction* dateAct = sort_mode_menu->addAction ( tr ( "By Date" ) ); - connect ( dateAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); - signalMapper->setMapping ( dateAct, PlayListModel::DATE ); + QAction* dateAct = sort_mode_menu->addAction (tr ("By Date")); + connect (dateAct, SIGNAL (triggered (bool)), signalMapper, SLOT (map())); + signalMapper->setMapping (dateAct, PlayListModel::DATE); - QAction* trackAct = sort_mode_menu->addAction ( tr ( "By Track Number" ) ); - connect ( trackAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); - signalMapper->setMapping ( trackAct, PlayListModel::TRACK ); + QAction* trackAct = sort_mode_menu->addAction (tr ("By Track Number")); + connect (trackAct, SIGNAL (triggered (bool)), signalMapper, SLOT (map())); + signalMapper->setMapping (trackAct, PlayListModel::TRACK); - connect ( signalMapper, SIGNAL ( mapped ( int ) ), - m_playListModel, SLOT ( sort ( int ) ) ); + connect (signalMapper, SIGNAL (mapped (int)), + m_playListModel, SLOT (sort (int))); - m_sortMenu->addMenu ( sort_mode_menu ); + m_sortMenu->addMenu (sort_mode_menu); - sort_mode_menu = new QMenu ( tr ( "Sort Selection" ),m_sortMenu ); - signalMapper = new QSignalMapper ( this ); - titleAct = sort_mode_menu->addAction ( tr ( "By Title" ) ); - connect ( titleAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); - signalMapper->setMapping ( titleAct, PlayListModel::TITLE ); + sort_mode_menu = new QMenu (tr ("Sort Selection"),m_sortMenu); + signalMapper = new QSignalMapper (this); + titleAct = sort_mode_menu->addAction (tr ("By Title")); + connect (titleAct, SIGNAL (triggered (bool)), signalMapper, SLOT (map())); + signalMapper->setMapping (titleAct, PlayListModel::TITLE); - nameAct = sort_mode_menu->addAction ( tr ( "By Filename" ) ); - connect ( nameAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); - signalMapper->setMapping ( nameAct, PlayListModel::FILENAME ); + nameAct = sort_mode_menu->addAction (tr ("By Filename")); + connect (nameAct, SIGNAL (triggered (bool)), signalMapper, SLOT (map())); + signalMapper->setMapping (nameAct, PlayListModel::FILENAME); - pathnameAct = sort_mode_menu->addAction ( tr ( "By Path + Filename" ) ); - connect ( pathnameAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); - signalMapper->setMapping ( pathnameAct, PlayListModel::PATH_AND_FILENAME ); + pathnameAct = sort_mode_menu->addAction (tr ("By Path + Filename")); + connect (pathnameAct, SIGNAL (triggered (bool)), signalMapper, SLOT (map())); + signalMapper->setMapping (pathnameAct, PlayListModel::PATH_AND_FILENAME); - dateAct = sort_mode_menu->addAction ( tr ( "By Date" ) ); - connect ( dateAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); - signalMapper->setMapping ( dateAct, PlayListModel::DATE ); + dateAct = sort_mode_menu->addAction (tr ("By Date")); + connect (dateAct, SIGNAL (triggered (bool)), signalMapper, SLOT (map())); + signalMapper->setMapping (dateAct, PlayListModel::DATE); - trackAct = sort_mode_menu->addAction ( tr ( "By Track Number" ) ); - connect ( trackAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); - signalMapper->setMapping ( trackAct, PlayListModel::TRACK ); + trackAct = sort_mode_menu->addAction (tr ("By Track Number")); + connect (trackAct, SIGNAL (triggered (bool)), signalMapper, SLOT (map())); + signalMapper->setMapping (trackAct, PlayListModel::TRACK); - connect ( signalMapper, SIGNAL ( mapped ( int ) ), - m_playListModel, SLOT ( sortSelection ( int ) ) ); + connect (signalMapper, SIGNAL (mapped (int)), + m_playListModel, SLOT (sortSelection (int))); - m_sortMenu->addMenu ( sort_mode_menu ); + m_sortMenu->addMenu (sort_mode_menu); m_sortMenu->addSeparator(); - m_sortMenu->addAction ( tr ( "Randomize List" ),m_playListModel,SLOT ( randomizeList() ) ); - m_sortMenu->addAction ( tr ( "Reverse List" ),m_playListModel,SLOT ( reverseList() ) ); + m_sortMenu->addAction (tr ("Randomize List"),m_playListModel,SLOT (randomizeList())); + m_sortMenu->addAction (tr ("Reverse List"),m_playListModel,SLOT (reverseList())); m_listWidget->menu()->addSeparator(); m_listWidget->menu()->addActions (m_subMenu->actions()); @@ -241,136 +243,136 @@ void PlayList::createActions() m_actions << m_listWidget->menu()->actions(); //select menu - QAction *invSelAct = new QAction ( tr ( "Invert Selection" ),this ); - m_selectMenu->addAction ( invSelAct ); - connect ( invSelAct, SIGNAL ( triggered() ), - m_playListModel, SLOT ( invertSelection () ) ); + QAction *invSelAct = new QAction (tr ("Invert Selection"),this); + m_selectMenu->addAction (invSelAct); + connect (invSelAct, SIGNAL (triggered()), + m_playListModel, SLOT (invertSelection ())); m_selectMenu->addSeparator(); - QAction *selNoneAct = new QAction ( tr ( "&Select None" ),this ); + QAction *selNoneAct = new QAction (tr ("&Select None"),this); //selNoneAct->setShortcut(tr("Ctrl+Shift+A")); - m_selectMenu->addAction ( selNoneAct ); - connect ( selNoneAct, SIGNAL ( triggered() ), - m_playListModel, SLOT ( clearSelection () ) ); - this->addAction ( selNoneAct ); - - QAction *selAllAct = new QAction ( tr ( "&Select All" ),this ); - selAllAct->setShortcut ( tr ( "Ctrl+A" ) ); - m_selectMenu->addAction ( selAllAct ); - connect ( selAllAct, SIGNAL ( triggered() ), - m_playListModel, SLOT ( selectAll () ) ); - this->addAction ( selAllAct ); + m_selectMenu->addAction (selNoneAct); + connect (selNoneAct, SIGNAL (triggered()), + m_playListModel, SLOT (clearSelection ())); + this->addAction (selNoneAct); + + QAction *selAllAct = new QAction (tr ("&Select All"),this); + selAllAct->setShortcut (tr ("Ctrl+A")); + m_selectMenu->addAction (selAllAct); + connect (selAllAct, SIGNAL (triggered()), + m_playListModel, SLOT (selectAll ())); + this->addAction (selAllAct); // Playlist Menu - QAction *newListAct = new QAction ( tr ( "&New List" ),this ); - newListAct->setShortcut ( tr ( "Shift+N" ) ); + QAction *newListAct = new QAction (tr ("&New List"),this); + newListAct->setShortcut (tr ("Shift+N")); m_actions << newListAct; - m_playlistMenu->addAction ( newListAct ); - connect ( newListAct, SIGNAL ( triggered() ), this, SIGNAL ( newPlaylist() ) ); + m_playlistMenu->addAction (newListAct); + connect (newListAct, SIGNAL (triggered()), this, SIGNAL (newPlaylist())); m_playlistMenu->addSeparator(); - QAction *loadListAct = new QAction ( tr ( "&Load List" ),this ); - loadListAct->setShortcut ( tr ( "O" ) ); - m_playlistMenu->addAction ( loadListAct ); - connect ( loadListAct, SIGNAL ( triggered() ), this, SIGNAL ( loadPlaylist() ) ); + QAction *loadListAct = new QAction (tr ("&Load List"),this); + loadListAct->setShortcut (tr ("O")); + m_playlistMenu->addAction (loadListAct); + connect (loadListAct, SIGNAL (triggered()), this, SIGNAL (loadPlaylist())); - QAction *saveListAct = new QAction ( tr ( "&Save List" ),this ); - saveListAct->setShortcut ( tr ( "Shift+S" ) ); - m_playlistMenu->addAction ( saveListAct ); - connect ( saveListAct, SIGNAL ( triggered() ), this, SIGNAL ( savePlaylist() ) ); - this->addActions ( m_playlistMenu->actions() ); + QAction *saveListAct = new QAction (tr ("&Save List"),this); + saveListAct->setShortcut (tr ("Shift+S")); + m_playlistMenu->addAction (saveListAct); + connect (saveListAct, SIGNAL (triggered()), this, SIGNAL (savePlaylist())); + this->addActions (m_playlistMenu->actions()); - Dock::getPointer()->addActions ( m_actions ); + Dock::getPointer()->addActions (m_actions); } void PlayList::closeEvent (QCloseEvent *e) { - if(e->spontaneous ()) + if (e->spontaneous ()) emit closed(); writeSettings(); } -void PlayList::paintEvent ( QPaintEvent * ) +void PlayList::paintEvent (QPaintEvent *) { - int m_sx = ( width()-275 ) /25; - int m_sy = ( height()-116 ) /29; - drawPixmap ( m_sx, m_sy ); + int m_sx = (width()-275) /25; + int m_sy = (height()-116) /29; + drawPixmap (m_sx, m_sy); } -void PlayList::drawPixmap ( int sx, int sy ) +void PlayList::drawPixmap (int sx, int sy) { QPainter paint; - paint.begin ( this ); - paint.drawPixmap ( 0,20,m_skin->getPlPart ( Skin::PL_LFILL ) ); - for ( int i = 1; igetPlPart (Skin::PL_LFILL)); + for (int i = 1; igetPlPart ( Skin::PL_LFILL ) ); + paint.drawPixmap (0,20+29*i,m_skin->getPlPart (Skin::PL_LFILL)); } - paint.drawPixmap ( 0,78+29*sy,m_skin->getPlPart ( Skin::PL_LSBAR ) ); - for ( int i = 0; igetPlPart (Skin::PL_LSBAR)); + for (int i = 0; igetPlPart ( Skin::PL_SFILL1 ) ); + paint.drawPixmap (125+i*25,78+sy*29,m_skin->getPlPart (Skin::PL_SFILL1)); } - paint.drawPixmap ( 125+sx*25,78+sy*29,m_skin->getPlPart ( Skin::PL_RSBAR ) ); + paint.drawPixmap (125+sx*25,78+sy*29,m_skin->getPlPart (Skin::PL_RSBAR)); paint.end(); } -void PlayList::resizeEvent ( QResizeEvent *e ) +void PlayList::resizeEvent (QResizeEvent *e) { - int sx = ( e->size().width()-275 ) /25; - int sy = ( e->size().height()-116 ) /29; + int sx = (e->size().width()-275) /25; + int sy = (e->size().height()-116) /29; if (sx < 0 || sy < 0) return; - m_titleBar->resize ( 275+25*sx,20 ); - m_plslider->resize ( 20,58+sy*29 ); + m_titleBar->resize (275+25*sx,20); + m_plslider->resize (20,58+sy*29); - m_listWidget->resize ( 243+25*sx,58+29*sy ); + m_listWidget->resize (243+25*sx,58+29*sy); - m_buttonAdd->move ( 11,86+29*sy ); - m_buttonSub->move ( 40,86+29*sy ); - m_selectButton->move ( 70,86+29*sy ); - m_sortButton->move ( 99,86+29*sy ); + m_buttonAdd->move (11,86+29*sy); + m_buttonSub->move (40,86+29*sy); + m_selectButton->move (70,86+29*sy); + m_sortButton->move (99,86+29*sy); - m_pl_control->move ( 128+sx*25,100+29*sy ); - m_playlistButton->move ( 228+sx*25,86+29*sy ); + m_pl_control->move (128+sx*25,100+29*sy); + m_playlistButton->move (228+sx*25,86+29*sy); - m_length_totalLength -> move ( 131+sx*25,88+29*sy ); - m_current_time->move ( 190+sx*25,101+29*sy ); + m_length_totalLength -> move (131+sx*25,88+29*sy); + m_current_time->move (190+sx*25,101+29*sy); - m_plslider->move ( 255+sx*25,20 ); + m_plslider->move (255+sx*25,20); } -void PlayList::mousePressEvent ( QMouseEvent *e ) +void PlayList::mousePressEvent (QMouseEvent *e) { m_pos = e->pos (); - if ( ( m_pos.x() > width()-25 ) && ( m_pos.y() > height()-25 ) ) + if ((m_pos.x() > width()-25) && (m_pos.y() > height()-25)) { m_resize = TRUE; - setCursor ( Qt::SizeFDiagCursor ); + setCursor (Qt::SizeFDiagCursor); } else m_resize = FALSE; } -void PlayList::mouseMoveEvent ( QMouseEvent *e ) +void PlayList::mouseMoveEvent (QMouseEvent *e) { - if ( m_resize ) + if (m_resize) { - resize ( e->x() +25, e->y() +25 ); + resize (e->x() +25, e->y() +25); //usleep(32000); } } -void PlayList::mouseReleaseEvent ( QMouseEvent * ) +void PlayList::mouseReleaseEvent (QMouseEvent *) { - setCursor ( Qt::ArrowCursor ); + setCursor (Qt::ArrowCursor); /*if (m_resize) m_listWidget->updateList();*/ m_resize = FALSE; Dock::getPointer()->updateDock(); } -void PlayList::setModel ( PlayListModel *model ) +void PlayList::setModel (PlayListModel *model) { m_playListModel = model; m_listWidget->setModel (model); @@ -379,17 +381,17 @@ void PlayList::setModel ( PlayListModel *model ) createActions(); } -void PlayList::changeEvent ( QEvent * event ) +void PlayList::changeEvent (QEvent * event) { - if ( event->type() == QEvent::ActivationChange ) + if (event->type() == QEvent::ActivationChange) { - m_titleBar->setActive ( isActiveWindow() ); + m_titleBar->setActive (isActiveWindow()); } } void PlayList::readSettings() { - if ( m_update ) + if (m_update) { m_listWidget->readSettings(); m_titleBar->readSettings(); @@ -397,9 +399,9 @@ void PlayList::readSettings() else { QSettings settings (QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat); - settings.beginGroup ( "PlayList" ); + settings.beginGroup ("PlayList"); //position - move ( settings.value ("pos", QPoint ( 100, 332 ) ).toPoint()); + move (settings.value ("pos", QPoint (100, 332)).toPoint()); settings.endGroup(); m_update = TRUE; } @@ -408,69 +410,85 @@ void PlayList::readSettings() void PlayList::writeSettings() { - QSettings settings ( QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat ); - settings.beginGroup ( "PlayList" ); + QSettings settings (QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat); + settings.beginGroup ("PlayList"); //position - settings.setValue ( "pos", this->pos() ); + settings.setValue ("pos", this->pos()); settings.endGroup(); } void PlayList::showAddMenu() { - m_addMenu->exec ( m_buttonAdd->mapToGlobal ( QPoint ( 0,0 ) ) ); + m_addMenu->exec (m_buttonAdd->mapToGlobal (QPoint (0,0))); } void PlayList::showSubMenu() { - m_subMenu->exec ( m_buttonSub->mapToGlobal ( QPoint ( 0,0 ) ) ); + m_subMenu->exec (m_buttonSub->mapToGlobal (QPoint (0,0))); } void PlayList::showSelectMenu() { - m_selectMenu->exec ( m_selectButton->mapToGlobal ( QPoint ( 0,0 ) ) ); + m_selectMenu->exec (m_selectButton->mapToGlobal (QPoint (0,0))); } void PlayList::showSortMenu() { - m_sortMenu->exec ( m_sortButton->mapToGlobal ( QPoint ( 0,0 ) ) ); + m_sortMenu->exec (m_sortButton->mapToGlobal (QPoint (0,0))); } - - -QString PlayList::formatTime ( int sec ) +QString PlayList::formatTime (int sec) { int minutes = sec / 60; int seconds = sec % 60; - QString str_minutes = QString::number ( minutes ); - QString str_seconds = QString::number ( seconds ); + QString str_minutes = QString::number (minutes); + QString str_seconds = QString::number (seconds); - if ( minutes < 10 ) str_minutes.prepend ( "0" ); - if ( seconds < 10 ) str_seconds.prepend ( "0" ); + if (minutes < 10) str_minutes.prepend ("0"); + if (seconds < 10) str_seconds.prepend ("0"); return str_minutes + ":" + str_seconds; } -void PlayList::setInfo (const OutputState &st,int length_current, int length_total) +void PlayList::setTime(qint64 time) { - if (st.type() == OutputState::Info) - { - m_current_time->display ( formatTime ( st.elapsedSeconds() ) ); - m_current_time->update(); + if (time < 0) + m_current_time->display ("--:--"); + else + m_current_time->display (formatTime (time)); + m_current_time->update(); - QString str_length = formatTime ( length_current ) + "/" + formatTime ( length_total ); - m_length_totalLength->display ( str_length ); - m_length_totalLength->update(); - } - else if (st.type() == OutputState::Playing) + if (m_playListModel && SoundCore::instance()) { - m_listWidget->updateList(); //removes progress message from TextScroller + m_playListModel->totalLength(); + QString str_length = formatTime (m_playListModel->totalLength()) + + "/" + formatTime (SoundCore::instance()->length()); + m_length_totalLength->display (str_length); + m_length_totalLength->update(); + } } +//void PlayList::setInfo (const OutputState &st,int length_current, int length_total) +//{ +/*if (st.type() == OutputState::Info) +{ + m_current_time->display (formatTime (st.elapsedSeconds())); + m_current_time->update(); + + QString str_length = formatTime (length_current) + "/" + formatTime (length_total); + m_length_totalLength->display (str_length); + m_length_totalLength->update(); +} +else if (st.type() == OutputState::Playing) +{ + m_listWidget->updateList(); //removes progress message from TextScroller +}*/ +//} PlayListItem *PlayList::currentItem() { - if ( m_playListModel ) + if (m_playListModel) return m_playListModel->currentItem(); else return 0; @@ -478,11 +496,11 @@ PlayListItem *PlayList::currentItem() void PlayList::showPlaylistMenu() { - m_playlistMenu->exec ( m_playlistButton->mapToGlobal ( QPoint ( 0,0 ) ) ); + m_playlistMenu->exec (m_playlistButton->mapToGlobal (QPoint (0,0))); } -void PlayList::keyPressEvent ( QKeyEvent *ke ) +void PlayList::keyPressEvent (QKeyEvent *ke) { - if ( m_keyboardManager->handleKeyPress ( ke ) ) + if (m_keyboardManager->handleKeyPress (ke)) update(); } diff --git a/src/ui/playlist.h b/src/ui/playlist.h index 0dd4016f4..a34f4e7b3 100644 --- a/src/ui/playlist.h +++ b/src/ui/playlist.h @@ -53,7 +53,7 @@ class PlayList : public QWidget void load ( PlayListItem * ); void setModel ( PlayListModel * ); void readSettings(); - void setInfo ( const OutputState &,int,int ); + //void setInfo ( const OutputState &,int,int ); PlayListItem *currentItem(); ListWidget* listWidget() const{return m_listWidget;} @@ -69,6 +69,9 @@ class PlayList : public QWidget void newPlaylist(); void closed(); + public slots: + void setTime(qint64 time); + private slots: void showAddMenu(); void showSubMenu(); diff --git a/src/ui/pluginitem.cpp b/src/ui/pluginitem.cpp index 490c46b0d..f606a7223 100644 --- a/src/ui/pluginitem.cpp +++ b/src/ui/pluginitem.cpp @@ -95,10 +95,10 @@ VisualPluginItem::~VisualPluginItem() void VisualPluginItem::select(bool on) { - if(on) + /*if(on) SoundCore::instance()->addVisual(m_factory, 0); else - SoundCore::instance()->removeVisual(m_factory); + SoundCore::instance()->removeVisual(m_factory);*/ } bool VisualPluginItem::isSelected() diff --git a/src/ui/positionbar.cpp b/src/ui/positionbar.cpp index 5431fd4f3..08a612fcb 100644 --- a/src/ui/positionbar.cpp +++ b/src/ui/positionbar.cpp @@ -38,7 +38,7 @@ PositionBar::PositionBar(QWidget *parent) mw = qobject_cast(window()); m_moving = FALSE; m_min = 0; - m_max = 50; + m_max = 0; m_old = m_value = 0; draw(FALSE); } @@ -52,7 +52,7 @@ void PositionBar::mousePressEvent(QMouseEvent *e) m_moving = TRUE; press_pos = e->x(); - if(m_posx() && e->x()x() && e->x()x()-m_pos; } @@ -71,12 +71,12 @@ void PositionBar::mousePressEvent(QMouseEvent *e) void PositionBar::mouseMoveEvent (QMouseEvent *e) { - if(m_moving) + if (m_moving) { int po = e->x(); po = po - press_pos; - if(0<=po && po<=width()-30) + if (0<=po && po<=width()-30) { m_value = convert(po); draw(); @@ -122,12 +122,15 @@ void PositionBar::draw(bool pressed) { int p=int(ceil(double(m_value-m_min)*(width()-30)/(m_max-m_min))); m_pixmap = m_skin->getPosBar(); - QPainter paint(&m_pixmap); - if(pressed) - paint.drawPixmap(p,0,m_skin->getButton(Skin::BT_POSBAR_P)); - else - paint.drawPixmap(p,0,m_skin->getButton(Skin::BT_POSBAR_N)); - setPixmap(m_pixmap); + if (m_max > 0) + { + QPainter paint(&m_pixmap); + if (pressed) + paint.drawPixmap(p,0,m_skin->getButton(Skin::BT_POSBAR_P)); + else + paint.drawPixmap(p,0,m_skin->getButton(Skin::BT_POSBAR_N)); + } + setPixmap(m_pixmap); m_pos = p; } diff --git a/src/ui/symboldisplay.h b/src/ui/symboldisplay.h index 065579b7a..720bad315 100644 --- a/src/ui/symboldisplay.h +++ b/src/ui/symboldisplay.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2006 by Ilya Kotov * + * Copyright (C) 2006-2008 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -37,8 +37,7 @@ public: SymbolDisplay(QWidget *parent = 0, int digits = 3); ~SymbolDisplay(); - void display(const QString&); - void display(int); + void setAlignment(Qt::Alignment a) { m_alignment = a; @@ -48,6 +47,10 @@ public: return m_alignment; } +public slots: + void display(const QString&); + void display(int); + private slots: void draw(); diff --git a/src/ui/titlebar.cpp b/src/ui/titlebar.cpp index 4f22f7069..400c9c2ec 100644 --- a/src/ui/titlebar.cpp +++ b/src/ui/titlebar.cpp @@ -24,7 +24,6 @@ #include #include -#include #include "symboldisplay.h" #include "skin.h" #include "button.h" @@ -174,7 +173,7 @@ void TitleBar::shade() connect (m_control, SIGNAL (stopClicked()), parent(), SLOT (stop())); connect (m_control, SIGNAL (ejectClicked()), parent(), SLOT (addFile())); m_visual = new ShadedVisual(this); - SoundCore::instance()->addVisualization(m_visual); + //SoundCore::instance()->addVisualization(m_visual); m_visual->show(); m_visual->move(79,5); } @@ -185,7 +184,7 @@ void TitleBar::shade() m_shade2->deleteLater(); m_currentTime->deleteLater(); m_control->deleteLater(); - SoundCore::instance()->removeVisual(m_visual); + //SoundCore::instance()->removeVisual(m_visual); m_visual->deleteLater(); m_shade2 = 0; m_currentTime = 0; @@ -210,23 +209,33 @@ QString TitleBar::formatTime ( int sec ) return str_minutes + ":" + str_seconds; } -void TitleBar::setInfo(const OutputState &st) +//void TitleBar::setInfo(const OutputState &st) +//{ +/*if (!m_currentTime) + return;*/ +/*switch ( ( int ) st.type() ) +{ +case OutputState::Info: +{ + m_currentTime->display(formatTime(st.elapsedSeconds())); + break; +} +case OutputState::Stopped: +{ + m_currentTime->display("--:--"); + break; +} +}*/ +//} + +void TitleBar::setTime(qint64 time) { if (!m_currentTime) return; - switch ( ( int ) st.type() ) - { - case OutputState::Info: - { - m_currentTime->display(formatTime(st.elapsedSeconds())); - break; - } - case OutputState::Stopped: - { + if (time < 0) m_currentTime->display("--:--"); - break; - } - } + else + m_currentTime->display(formatTime(time)); } void TitleBar::updateMask() diff --git a/src/ui/titlebar.h b/src/ui/titlebar.h index 4c15aeeff..d7c1f5fca 100644 --- a/src/ui/titlebar.h +++ b/src/ui/titlebar.h @@ -48,7 +48,10 @@ public: ~TitleBar(); void setActive(bool); - void setInfo(const OutputState &st); + //void setInfo(const OutputState &st); + +public slots: + void setTime(qint64 time); private slots: void updateSkin(); -- cgit v1.2.3-13-gbd6f