diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2010-10-08 18:06:38 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2010-10-08 18:06:38 +0000 |
| commit | c4749f20a5ad31ed8c68c11547120a0d1da45a8f (patch) | |
| tree | 805248511deeea91f7da2d2881f9afefe9f21b1a | |
| parent | 767150cfe9403eb432ea82377664abda214d6e04 (diff) | |
| download | qmmp-c4749f20a5ad31ed8c68c11547120a0d1da45a8f.tar.gz qmmp-c4749f20a5ad31ed8c68c11547120a0d1da45a8f.tar.bz2 qmmp-c4749f20a5ad31ed8c68c11547120a0d1da45a8f.zip | |
dynamic buffer size
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@1928 90c681e8-e032-0410-971d-27865f9a5e38
27 files changed, 321 insertions, 593 deletions
diff --git a/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp b/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp index 25e2ab04c..988d534d4 100644 --- a/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp +++ b/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp @@ -169,7 +169,7 @@ bool DecoderFFmpeg::initialize() } m_totalTime = input()->isSequential() ? 0 : ic->duration * 1000 / AV_TIME_BASE; - m_output_buf = (uint8_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3 / 2 + QMMP_BUFFER_SIZE); + m_output_buf = (uint8_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3 / 2/* + QMMP_BUFFER_SIZE*/); #if (LIBAVCODEC_VERSION_INT >= ((52<<16)+(20<<8)+0)) if(c->codec_id == CODEC_ID_SHORTEN) //ffmpeg bug workaround diff --git a/src/plugins/Input/modplug/decoder_modplug.cpp b/src/plugins/Input/modplug/decoder_modplug.cpp index fe92d90f4..969731bdc 100644 --- a/src/plugins/Input/modplug/decoder_modplug.cpp +++ b/src/plugins/Input/modplug/decoder_modplug.cpp @@ -111,7 +111,7 @@ int DecoderModPlug::bitrate() qint64 DecoderModPlug::read(char *audio, qint64 maxSize) { - long len = m_soundFile->Read (audio, qMin((qint64)QMMP_BLOCK_SIZE, maxSize)) * m_sampleSize; + long len = m_soundFile->Read (audio, maxSize) * m_sampleSize; if (m_usePreamp) { { diff --git a/src/plugins/Input/wavpack/decoder_wavpack.cpp b/src/plugins/Input/wavpack/decoder_wavpack.cpp index 75b09dff0..071b18004 100644 --- a/src/plugins/Input/wavpack/decoder_wavpack.cpp +++ b/src/plugins/Input/wavpack/decoder_wavpack.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008-2009 by Ilya Kotov * + * Copyright (C) 2008-2010 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -24,12 +24,9 @@ #include <QFile> #include <math.h> #include <stdint.h> - #include <qmmp/buffer.h> #include <qmmp/output.h> #include <qmmp/recycler.h> -#include "QtDebug" - #include "decoder_wavpack.h" #include "cueparser.h" @@ -107,7 +104,7 @@ bool DecoderWavPack::initialize() m_freq = WavpackGetSampleRate (m_context); m_bps = WavpackGetBitsPerSample (m_context); if (!m_output_buf) - m_output_buf = new int32_t[QMMP_BUFFER_SIZE/4]; + m_output_buf = new int32_t[QMMP_BLOCK_FRAMES * m_chan]; switch(m_bps) { case 8: @@ -249,7 +246,8 @@ void DecoderWavPack::next() qint64 DecoderWavPack::wavpack_decode(char *data, qint64 size) { - ulong len = WavpackUnpackSamples (m_context, m_output_buf, size / m_chan / 4); + ulong len = qMin(QMMP_BLOCK_FRAMES, (int)size / m_chan / 4); + len = WavpackUnpackSamples (m_context, m_output_buf, len); //convert 32 to 16 qint8 *data8 = (qint8 *)data; qint16 *data16 = (qint16 *)data; diff --git a/src/plugins/Input/wavpack/decoder_wavpack.h b/src/plugins/Input/wavpack/decoder_wavpack.h index 1f2e034ea..a44ca090f 100644 --- a/src/plugins/Input/wavpack/decoder_wavpack.h +++ b/src/plugins/Input/wavpack/decoder_wavpack.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008-2009 by Ilya Kotov * + * Copyright (C) 2008-2010 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * diff --git a/src/plugins/Output/alsa/outputalsa.cpp b/src/plugins/Output/alsa/outputalsa.cpp index 9ae4d5db2..905d58a20 100644 --- a/src/plugins/Output/alsa/outputalsa.cpp +++ b/src/plugins/Output/alsa/outputalsa.cpp @@ -185,7 +185,7 @@ void OutputALSA::configure(quint32 freq, int chan, Qmmp::AudioFormat format) qDebug("OutputALSA: can pause: %d", m_can_pause); Output::configure(freq, chan, format); //apply configuration //create alsa prebuffer; - m_prebuf_size = QMMP_BUFFER_SIZE + m_bits_per_frame * m_chunk_size / 8; + m_prebuf_size = /*QMMP_BUFFER_SIZE + */m_bits_per_frame * m_chunk_size / 8; m_prebuf = (uchar *)malloc(m_prebuf_size); } diff --git a/src/plugins/Visual/analyzer/analyzer.cpp b/src/plugins/Visual/analyzer/analyzer.cpp index c071b12f2..22941892f 100644 --- a/src/plugins/Visual/analyzer/analyzer.cpp +++ b/src/plugins/Visual/analyzer/analyzer.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007 by Ilya Kotov * + * Copyright (C) 2007-2010 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -32,6 +32,8 @@ #include "inlines.h" #include "analyzer.h" +#define VISUAL_NODE_SIZE 512 //samples +#define VISUAL_BUFFER_SIZE (5*VISUAL_NODE_SIZE) Analyzer::Analyzer (QWidget *parent) : Visual (parent), m_fps (20) @@ -42,8 +44,9 @@ Analyzer::Analyzer (QWidget *parent) m_pixmap = QPixmap (75,20); m_timer = new QTimer (this); connect(m_timer, SIGNAL (timeout()), this, SLOT (timeout())); - m_nodes.clear(); - + m_left_buffer = new short[VISUAL_BUFFER_SIZE]; + m_right_buffer = new short[VISUAL_BUFFER_SIZE]; + m_buffer_at = 0; clear(); setWindowTitle (tr("Qmmp Analyzer")); @@ -66,14 +69,13 @@ Analyzer::Analyzer (QWidget *parent) Analyzer::~Analyzer() { - while (!m_nodes.isEmpty()) - m_nodes.removeFirst(); + delete [] m_left_buffer; + delete [] m_right_buffer; } void Analyzer::clear() { - while (!m_nodes.isEmpty()) - m_nodes.removeFirst(); + m_buffer_at = 0; for (int i = 0; i< 75; ++i) { m_intern_vis_data[i] = 0; @@ -87,50 +89,44 @@ void Analyzer::add (unsigned char *data, qint64 size, int chan) if (!m_timer->isActive ()) return; - short *l = 0, *r = 0; - qint64 samples = size/chan >> 1; - int frames = samples/512; - for (int i = 0; i < frames; ++i) + if(VISUAL_BUFFER_SIZE == m_buffer_at) { - l = new short[512]; - r = 0; - if (chan == 2) - { - r = new short[512]; - stereo16_from_stereopcm16 (l, r, (short *) (data + i*4*512), 512); - } - else if (chan == 1) - mono16_from_monopcm16 (l, (short *) (data + i*2*512), 512); - else - { - r = new short[512]; - stereo16_from_multichannel(l, r, (short *) (data + i*2*chan*512), 512, chan); - } - m_nodes.append (new VisualNode (l, r, 512)); + m_buffer_at -= VISUAL_NODE_SIZE; + memmove(m_left_buffer, m_left_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1); + memmove(m_right_buffer, m_right_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1); + return; } -} -void Analyzer::timeout() -{ - VisualNode *node = 0; - mutex()->lock (); + int frames = qMin((int)size/chan >> 1, VISUAL_BUFFER_SIZE - m_buffer_at); - while(m_nodes.size() > 5) + if (chan >= 2) { - delete m_nodes.takeFirst(); + stereo16_from_multichannel(m_left_buffer + m_buffer_at, + m_right_buffer + m_buffer_at,(short *) data, frames, chan); + } + else + { + memcpy(m_left_buffer + m_buffer_at, (short *) data, frames << 1); + memcpy(m_right_buffer + m_buffer_at, (short *) data, frames << 1); } - if(!m_nodes.isEmpty()) - node = m_nodes.takeFirst(); - - mutex()->unlock(); + m_buffer_at += frames; +} - if (node) +void Analyzer::timeout() +{ + mutex()->lock (); + if(m_buffer_at < VISUAL_NODE_SIZE) { - process (node); - delete node; - update(); + mutex()->unlock (); + return; } + + process (m_left_buffer, m_right_buffer); + m_buffer_at -= VISUAL_NODE_SIZE; + memmove(m_left_buffer, m_left_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1); + memmove(m_right_buffer, m_right_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1); + mutex()->unlock (); update(); } @@ -159,7 +155,7 @@ void Analyzer::closeEvent (QCloseEvent *event) Visual::closeEvent(event); //removes visualization before class deleting } -bool Analyzer::process (VisualNode *node) +void Analyzer::process (short *left, short *right) { static fft_state *state = 0; if (!state) @@ -174,15 +170,9 @@ bool Analyzer::process (VisualNode *node) 36, 47, 62, 82, 107, 141, 184, 255 }; - if (node) - { - //i = node->length; - calc_freq (dest_l, node->left); - if (node->right) - calc_freq (dest_r, node->right); - } - else - return false; + calc_freq (dest_l, left); + calc_freq (dest_r, right); + const double y_scale = 3.60673760222; /* 20.0 / log(256) */ int yl,yr, j; @@ -194,16 +184,14 @@ bool Analyzer::process (VisualNode *node) { if (dest_l[j] > yl) yl = dest_l[j]; - if (dest_r[j] > yr && node->right) + if (dest_r[j] > yr) yr = dest_r[j]; } yl >>= 7; + yr >>= 7; int magnitude_l = 0; int magnitude_r = 0; - if (node->right) - { - yr >>= 7; - } + if (yl) { magnitude_l = int(log (yl) * y_scale); @@ -212,7 +200,7 @@ bool Analyzer::process (VisualNode *node) if (magnitude_l < 0) magnitude_l = 0; } - if (yr && node->right) + if (yr) { magnitude_r = int(log (yr) * y_scale); if (magnitude_r > 15) @@ -224,27 +212,20 @@ bool Analyzer::process (VisualNode *node) m_intern_vis_data[i] -= m_analyzer_falloff; m_intern_vis_data[i] = magnitude_l > m_intern_vis_data[i] ? magnitude_l : m_intern_vis_data[i]; - if (node->right) - { - m_intern_vis_data[37-i] -= m_analyzer_falloff; - m_intern_vis_data[37-i] = magnitude_r > m_intern_vis_data[37-i] - ? magnitude_r : m_intern_vis_data[37-i]; - } + + m_intern_vis_data[37-i] -= m_analyzer_falloff; + m_intern_vis_data[37-i] = magnitude_r > m_intern_vis_data[37-i] + ? magnitude_r : m_intern_vis_data[37-i]; if (m_show_peaks) { m_peaks[i] -= m_peaks_falloff; - m_peaks[i] = magnitude_l > m_peaks[i] - ? magnitude_l : m_peaks[i]; - if (node->right) - { - m_peaks[37-i] -= m_peaks_falloff; - m_peaks[37-i] = magnitude_r > m_peaks[37-i] - ? magnitude_r : m_peaks[37-i]; - } + m_peaks[i] = magnitude_l > m_peaks[i] ? magnitude_l : m_peaks[i]; + + m_peaks[37-i] -= m_peaks_falloff; + m_peaks[37-i] = magnitude_r > m_peaks[37-i] ? magnitude_r : m_peaks[37-i]; } } - return true; } void Analyzer::draw (QPainter *p) diff --git a/src/plugins/Visual/analyzer/analyzer.h b/src/plugins/Visual/analyzer/analyzer.h index 1c0e8974e..d2ff0469a 100644 --- a/src/plugins/Visual/analyzer/analyzer.h +++ b/src/plugins/Visual/analyzer/analyzer.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007 by Ilya Kotov * + * Copyright (C) 2007-2010 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -23,35 +23,11 @@ #include <QWidget> #include <QResizeEvent> #include <qmmp/visual.h> -#include <QDir> -class QSettings; class QTimer; class QMenu; class QActionGroup; -class Buffer; - - -class VisualNode -{ -public: - VisualNode(short *l, short *r, unsigned long n) - : left(l), right(r), length(n) - { - // left and right are allocated and then passed to this class - // the code that allocated left and right should give up all ownership - } - - ~VisualNode() - { - delete [] left; - delete [] right; - } - - short *left, *right; - long length; -}; class Analyzer : public Visual { @@ -74,11 +50,10 @@ public slots: void timeout(); private: - bool process(VisualNode *node); + void process(short *l, short *r); void draw(QPainter *p); QPixmap m_pixmap; QPixmap m_bg; - QList <VisualNode*> m_nodes; QTimer *m_timer; int m_fps; double m_intern_vis_data[75]; @@ -86,6 +61,9 @@ private: double m_peaks_falloff; double m_analyzer_falloff; bool m_show_peaks; + short *m_left_buffer; + short *m_right_buffer; + int m_buffer_at; //colors QColor m_color1; QColor m_color2; diff --git a/src/plugins/Visual/analyzer/inlines.h b/src/plugins/Visual/analyzer/inlines.h index e2c48d019..39b81bd57 100644 --- a/src/plugins/Visual/analyzer/inlines.h +++ b/src/plugins/Visual/analyzer/inlines.h @@ -10,8 +10,7 @@ #include "fft.h" // *fast* convenience functions -static inline void -calc_freq(short* dest, short *src) +static inline void calc_freq(short* dest, short *src) { static fft_state *state = NULL; float tmp_out[257]; @@ -26,27 +25,6 @@ calc_freq(short* dest, short *src) dest[i] = ((int) sqrt(tmp_out[i + 1])) >> 8; } -static inline void -calc_mono_freq(short dest[2][256], short src[2][512], int nch) -{ - int i; - short *d, *sl, *sr, tmp[512]; - - if (nch == 1) - calc_freq(dest[0], src[0]); - else - { - d = tmp; - sl = src[0]; - sr = src[1]; - for (i = 0; i < 512; i++) - { - *(d++) = (*(sl++) + *(sr++)) >> 1; - } - calc_freq(dest[0], tmp); - } -} - static inline void stereo16_from_multichannel(register short *l, register short *r, register short *s, @@ -63,71 +41,16 @@ static inline void stereo16_from_multichannel(register short *l, } } - -static inline void stereo16_from_stereopcm16(register short *l, - register short *r, - register short *s, - long cnt) -{ - while (cnt >= 4l) - { - l[0] = s[0]; - r[0] = s[1]; - l[1] = s[2]; - r[1] = s[3]; - l[2] = s[4]; - r[2] = s[5]; - l[3] = s[6]; - r[3] = s[7]; - l += 4; - r += 4; - s += 8; - cnt -= 4l; - } - - if (cnt > 0l) - { - l[0] = s[0]; - r[0] = s[1]; - if (cnt > 1l) - { - l[1] = s[2]; - r[1] = s[3]; - if (cnt > 2l) - { - l[2] = s[4]; - r[2] = s[5]; - } - } - } -} - -static inline void mono16_from_monopcm16(register short *l, - register short *s, - long cnt) +static inline void mono16_from_multichannel(register short *l, + register short *s, + long cnt, int chan) { - while (cnt >= 4l) - { - l[0] = s[0]; - l[1] = s[1]; - l[2] = s[2]; - l[3] = s[3]; - l += 4; - s += 4; - cnt -= 4l; - } - - if (cnt > 0l) + while (cnt > 0) { l[0] = s[0]; - if (cnt > 1l) - { - l[1] = s[1]; - if (cnt > 2l) - { - l[2] = s[2]; - } - } + s += chan; + l++; + cnt--; } } diff --git a/src/qmmp/buffer.h b/src/qmmp/buffer.h index 910615f1f..161af5692 100644 --- a/src/qmmp/buffer.h +++ b/src/qmmp/buffer.h @@ -7,8 +7,7 @@ #ifndef __buffer_h #define __buffer_h -#define QMMP_BLOCK_SIZE (2048*6) //512*4*6 -#define QMMP_BUFFER_SIZE (QMMP_BLOCK_SIZE*32) +#define QMMP_BLOCK_FRAMES 512 /*! @brief Audio buffer class. * @author Brad Hughes <bhughes@trolltech.com> @@ -18,13 +17,14 @@ class Buffer public: /*! * Constructs an empty buffer object. + * @param sz Size in bytes; */ - Buffer() + Buffer(unsigned long sz) { - data = new unsigned char[QMMP_BLOCK_SIZE]; + data = new unsigned char[sz]; nbytes = 0; rate = 0; - size = QMMP_BLOCK_SIZE; + size = sz; } /*! * Destructor. diff --git a/src/qmmp/output.cpp b/src/qmmp/output.cpp index b81f2d708..c8b4f3758 100644 --- a/src/qmmp/output.cpp +++ b/src/qmmp/output.cpp @@ -39,7 +39,7 @@ static inline void s32_to_s16(qint32 *in, qint16 *out, qint64 samples) return; } -Output::Output (QObject* parent) : QThread (parent), m_recycler (QMMP_BUFFER_SIZE) +Output::Output (QObject* parent) : QThread (parent) { m_handler = StateHandler::instance(); m_frequency = 0; @@ -68,25 +68,15 @@ void Output::configure(quint32 freq, int chan, Qmmp::AudioFormat format) formatNames.insert(Qmmp::PCM_S16LE, "s16le"); formatNames.insert(Qmmp::PCM_S24LE, "s24le"); formatNames.insert(Qmmp::PCM_S32LE, "s32le"); - qDebug("Output: %d Hz, %d ch, %s", freq, chan, qPrintable(formatNames.value(format))); + qDebug("Output: [%s] %d Hz, %d ch, %s", qPrintable(Output::currentFactory()->properties().shortName), + freq, chan, qPrintable(formatNames.value(format))); m_bytesPerMillisecond = freq * chan * AudioParameters::sampleSize(format) / 1000; + m_recycler.configure(freq, chan, format); //calculate output buffer size //visual buffer if(m_visBuffer) - { delete [] m_visBuffer; - m_visBuffer = 0; - m_visBufferSize = 0; - } - if(format == Qmmp::PCM_S8) - { - m_visBufferSize = QMMP_BLOCK_SIZE * 2; - m_visBuffer = new unsigned char [m_visBufferSize]; - } - else if(format == Qmmp::PCM_S24LE || format == Qmmp::PCM_S32LE) - { - m_visBufferSize = QMMP_BLOCK_SIZE / 2; - m_visBuffer = new unsigned char [m_visBufferSize]; - } + m_visBufferSize = QMMP_BLOCK_FRAMES * 2 * chan; //16-bit samples + m_visBuffer = new unsigned char [m_visBufferSize]; } void Output::pause() @@ -160,6 +150,11 @@ int Output::sampleSize() const return AudioParameters::sampleSize(m_format); } +qint64 Output::bufferSize() const +{ + return m_recycler.size(); +} + void Output::suspend() {} diff --git a/src/qmmp/output.h b/src/qmmp/output.h index 088de8779..4947b0d5b 100644 --- a/src/qmmp/output.h +++ b/src/qmmp/output.h @@ -115,6 +115,10 @@ public: */ int sampleSize() const; /*! + * Returns buffer size in bytes. + */ + qint64 bufferSize() const; + /*! * Creates selected output. * @param parent Parent object. * @return Output subclass object. diff --git a/src/qmmp/qmmpaudioengine.cpp b/src/qmmp/qmmpaudioengine.cpp index 03baaed0c..25f872951 100644 --- a/src/qmmp/qmmpaudioengine.cpp +++ b/src/qmmp/qmmpaudioengine.cpp @@ -42,9 +42,10 @@ QmmpAudioEngine::QmmpAudioEngine(QObject *parent) : AbstractEngine(parent), m_factory(0), m_output(0), m_useEq(false), m_eqEnabled(false) { - m_output_buf = new unsigned char[QMMP_BUFFER_SIZE]; qRegisterMetaType<Qmmp::State>("Qmmp::State"); - m_bks = QMMP_BLOCK_SIZE; + m_output_buf = 0; + m_output_size = 0; + m_bks = 0; m_decoder = 0; m_output = 0; m_replayGain = new ReplayGain; @@ -289,9 +290,9 @@ void QmmpAudioEngine::stop() qint64 QmmpAudioEngine::produceSound(char *data, qint64 size, quint32 brate, int chan) { + Buffer *b = m_output->recycler()->get(); uint sz = size < m_bks ? size : m_bks; m_replayGain->applyReplayGain(data, sz); - Buffer *b = m_output->recycler()->get(); memcpy(b->data, data, sz); b->nbytes = sz; b->rate = brate; @@ -380,8 +381,7 @@ void QmmpAudioEngine::run() m_output_at = 0; } - len = m_decoder->read((char *)(m_output_buf + m_output_at), - QMMP_BUFFER_SIZE - m_output_at); + len = m_decoder->read((char *)(m_output_buf + m_output_at), m_output_size - m_output_at); if (len > 0) { @@ -442,7 +442,7 @@ void QmmpAudioEngine::run() delete m_output; m_output = createOutput(); if(m_output) - { + { m_output->start(); sendMetaData(); addOffset(); //offset @@ -570,6 +570,11 @@ Output *QmmpAudioEngine::createOutput() return false; } output->configure(m_ap.sampleRate(), m_ap.channels(), m_ap.format()); + if(m_output_buf) + delete [] m_output_buf; + m_bks = QMMP_BLOCK_FRAMES * m_ap.channels() * m_ap.sampleSize(); + m_output_size = m_bks * 4; + m_output_buf = new unsigned char[m_output_size]; return output; } diff --git a/src/qmmp/qmmpaudioengine.h b/src/qmmp/qmmpaudioengine.h index bf924e5fa..537c7dc5e 100644 --- a/src/qmmp/qmmpaudioengine.h +++ b/src/qmmp/qmmpaudioengine.h @@ -83,7 +83,7 @@ private: bool m_done, m_finish, m_user_stop; uint m_bks; qint64 m_totalTime, m_seekTime; - qint64 m_output_at; + qint64 m_output_at, m_output_size; int m_bitrate, m_chan, m_bps; unsigned char *m_output_buf; Decoder *m_decoder; diff --git a/src/qmmp/qmmpsettings.cpp b/src/qmmp/qmmpsettings.cpp index 7c4c3c6dc..170f75df8 100644 --- a/src/qmmp/qmmpsettings.cpp +++ b/src/qmmp/qmmpsettings.cpp @@ -56,6 +56,7 @@ QmmpSettings::QmmpSettings(QObject *parent) : QObject(parent) m_eq_settings.setGain(i, settings.value("Equalizer/band_"+ QString("%1").arg(i), 0).toDouble()); m_eq_settings.setPreamp(settings.value("Equalizer/preamp", 0).toDouble()); m_eq_settings.setEnabled(settings.value("Equalizer/enabled", true).toBool()); + m_buffer_size = settings.value("Output/buffer_size", 500).toInt(); } QmmpSettings::~QmmpSettings() @@ -169,6 +170,16 @@ void QmmpSettings::setEqSettings(const EqSettings &settings) emit eqSettingsChanged(); } +int QmmpSettings:: bufferSize() const +{ + return m_buffer_size; +} + +void QmmpSettings::setBufferSize(int msec) +{ + m_buffer_size = msec; +} + void QmmpSettings::sync() { QSettings settings (Qmmp::configFile(), QSettings::IniFormat); @@ -198,6 +209,8 @@ void QmmpSettings::sync() settings.setValue("Equalizer/band_"+ QString("%1").arg(i), m_eq_settings.gain(i)); settings.setValue("Equalizer/preamp", m_eq_settings.preamp()); settings.setValue("Equalizer/enabled", m_eq_settings.isEnabled()); + //buffer size + settings.setValue("Output/buffer_size", m_buffer_size); } QmmpSettings* QmmpSettings::instance() diff --git a/src/qmmp/qmmpsettings.h b/src/qmmp/qmmpsettings.h index 7dac60da7..8b77bfb1f 100644 --- a/src/qmmp/qmmpsettings.h +++ b/src/qmmp/qmmpsettings.h @@ -132,11 +132,24 @@ public: * @param proxy Proxy url. */ void setNetworkSettings(bool use_proxy, bool auth, const QUrl &proxy); - - + /*! + * Returns equalizer settings. + */ EqSettings eqSettings() const; + /*! + * Changes equalizer settings to \b settings + */ void setEqSettings(const EqSettings &settings); /*! + * Returns buffer size in milliseconds + */ + int bufferSize() const; + /*! + * Sets buffer size + * @param msec Buffer size in milliseconds + */ + void setBufferSize(int msec); + /*! * Returns a pointer to the QmmpSettings instance. */ static QmmpSettings* instance(); @@ -186,6 +199,8 @@ private: QUrl m_proxy_url; //equalizer settings EqSettings m_eq_settings; + //buffer size + int m_buffer_size; static QmmpSettings* m_instance; diff --git a/src/qmmp/recycler.cpp b/src/qmmp/recycler.cpp index 9ac95d774..6c91be5e7 100644 --- a/src/qmmp/recycler.cpp +++ b/src/qmmp/recycler.cpp @@ -5,62 +5,91 @@ // #include "recycler.h" +#include "qmmpsettings.h" +#include "audioparameters.h" #include "buffer.h" -Recycler::Recycler (unsigned int sz) - : add_index (0), done_index (0), current_count (0) +Recycler::Recycler () { - buffer_count = sz / QMMP_BLOCK_SIZE; - if (buffer_count < 4) - buffer_count = 4; - - buffers = new Buffer*[buffer_count]; + m_add_index = 0; + m_done_index = 0; + m_current_count = 0; + m_buffer_count = 0; + m_blocked = 0; + m_block_size = 0; + m_buffers = 0; +} - for (unsigned int i = 0; i < buffer_count; i++) +Recycler::~Recycler() +{ + for (unsigned int i = 0; i < m_buffer_count; i++) { - buffers[i] = new Buffer; + delete m_buffers[i]; + m_buffers[i] = 0; } + if(m_buffer_count) + delete [] m_buffers; m_blocked = 0; } - -Recycler::~Recycler() +void Recycler::configure(quint32 freq, int chan, Qmmp::AudioFormat format) { - for (unsigned int i = 0; i < buffer_count; i++) + unsigned long block_size = AudioParameters::sampleSize(format) * chan * QMMP_BLOCK_FRAMES; + unsigned int buffer_count = freq * QmmpSettings::instance()->bufferSize() / 1000 / QMMP_BLOCK_FRAMES; + if(block_size == m_block_size && buffer_count == m_buffer_count) + return; + + for (unsigned int i = 0; i < m_buffer_count; i++) { - delete buffers[i]; - buffers[i] = 0; + delete m_buffers[i]; + m_buffers[i] = 0; } - delete [] buffers; + if(m_buffer_count) + delete [] m_buffers; + m_add_index = 0; + m_done_index = 0; + m_current_count = 0; m_blocked = 0; -} + m_block_size = block_size; + m_buffer_count = buffer_count; + + + if (m_buffer_count < 4) + m_buffer_count = 4; + + m_buffers = new Buffer*[m_buffer_count]; + for (unsigned int i = 0; i < m_buffer_count; i++) + { + m_buffers[i] = new Buffer(m_block_size); + } +} bool Recycler::full() const { - return current_count == buffer_count; + return m_current_count == m_buffer_count; } bool Recycler::blocked() { - return buffers[add_index] == m_blocked; + return m_buffers[m_add_index] == m_blocked; } bool Recycler::empty() const { - return current_count == 0; + return m_current_count == 0; } int Recycler::available() const { - return buffer_count - current_count; + return m_buffer_count - m_current_count; } int Recycler::used() const { - return current_count; + return m_current_count; } @@ -68,24 +97,23 @@ Buffer *Recycler::get() { if (full()) return 0; - return buffers[add_index]; + return m_buffers[m_add_index]; } - void Recycler::add() { - if(buffers[add_index]->nbytes) + if(m_buffers[m_add_index]->nbytes) { - add_index = (add_index + 1) % buffer_count; - current_count++; + m_add_index = (m_add_index + 1) % m_buffer_count; + m_current_count++; } } Buffer *Recycler::next() { - if(current_count) + if(m_current_count) { - m_blocked = buffers[done_index]; + m_blocked = m_buffers[m_done_index]; return m_blocked; } return 0; @@ -94,21 +122,21 @@ Buffer *Recycler::next() void Recycler::done() { m_blocked = 0; - if (current_count) + if (m_current_count) { - current_count--; - done_index = (done_index + 1) % buffer_count; + m_current_count--; + m_done_index = (m_done_index + 1) % m_buffer_count; } } void Recycler::clear() { - current_count = 0; - add_index = 0; - done_index = 0; + m_current_count = 0; + m_add_index = 0; + m_done_index = 0; } -unsigned int Recycler::size() const +unsigned long Recycler::size() const { - return buffer_count * QMMP_BLOCK_SIZE; + return m_buffer_count * m_block_size; } diff --git a/src/qmmp/recycler.h b/src/qmmp/recycler.h index a52e37143..fc143779d 100644 --- a/src/qmmp/recycler.h +++ b/src/qmmp/recycler.h @@ -9,6 +9,7 @@ #include <QMutex> #include <QWaitCondition> +#include "qmmp.h" class Buffer; @@ -20,14 +21,20 @@ class Recycler public: /*! * Constructor. - * @param sz Preferd total size of the all buffers in bytes. */ - Recycler(unsigned int sz); + Recycler(); /*! * Destructor. */ ~Recycler(); /*! + * Setups audio parameters of output interface. + * @param freq Sample rate. + * @param chan Number of channels. + * @param format Audio format + */ + void configure(quint32 freq, int chan, Qmmp::AudioFormat format); + /*! * Returns \b true if queue if full, otherwise returns \b false */ bool full() const; @@ -66,20 +73,20 @@ public: /*! * Returns size of all buffers in bytes. */ - unsigned int size() const; // size in bytes + unsigned long size() const; // size in bytes /*! * Returns mutex pointer. */ QMutex *mutex() { - return &mtx; + return &m_mtx; } /*! * Returns wait condition pointer. */ QWaitCondition *cond() { - return &cnd; + return &m_cnd; } /*! * Returns \b true if the next buffer is used by output. Otherwise returns \b false. @@ -87,10 +94,11 @@ public: bool blocked(); private: - unsigned int buffer_count, add_index, done_index, current_count; - Buffer **buffers; - QMutex mtx; - QWaitCondition cnd; + unsigned int m_buffer_count, m_add_index, m_done_index, m_current_count; + unsigned long m_block_size; + Buffer **m_buffers; + QMutex m_mtx; + QWaitCondition m_cnd; Buffer *m_blocked; }; diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 5275ad98f..9f9a31774 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -50,7 +50,6 @@ SET(ui_SRCS jumptotrackdialog.cpp keyboardmanager.cpp listwidget.cpp - logscale.cpp mainvisual.cpp mainwindow.cpp monostereo.cpp @@ -107,7 +106,6 @@ SET(ui_MOC_HDRS jumptotrackdialog.h keyboardmanager.h listwidget.h - logscale.h mainvisual.h mainwindow.h monostereo.h diff --git a/src/ui/inlines.h b/src/ui/inlines.h index e2c48d019..39b81bd57 100644 --- a/src/ui/inlines.h +++ b/src/ui/inlines.h @@ -10,8 +10,7 @@ #include "fft.h" // *fast* convenience functions -static inline void -calc_freq(short* dest, short *src) +static inline void calc_freq(short* dest, short *src) { static fft_state *state = NULL; float tmp_out[257]; @@ -26,27 +25,6 @@ calc_freq(short* dest, short *src) dest[i] = ((int) sqrt(tmp_out[i + 1])) >> 8; } -static inline void -calc_mono_freq(short dest[2][256], short src[2][512], int nch) -{ - int i; - short *d, *sl, *sr, tmp[512]; - - if (nch == 1) - calc_freq(dest[0], src[0]); - else - { - d = tmp; - sl = src[0]; - sr = src[1]; - for (i = 0; i < 512; i++) - { - *(d++) = (*(sl++) + *(sr++)) >> 1; - } - calc_freq(dest[0], tmp); - } -} - static inline void stereo16_from_multichannel(register short *l, register short *r, register short *s, @@ -63,71 +41,16 @@ static inline void stereo16_from_multichannel(register short *l, } } - -static inline void stereo16_from_stereopcm16(register short *l, - register short *r, - register short *s, - long cnt) -{ - while (cnt >= 4l) - { - l[0] = s[0]; - r[0] = s[1]; - l[1] = s[2]; - r[1] = s[3]; - l[2] = s[4]; - r[2] = s[5]; - l[3] = s[6]; - r[3] = s[7]; - l += 4; - r += 4; - s += 8; - cnt -= 4l; - } - - if (cnt > 0l) - { - l[0] = s[0]; - r[0] = s[1]; - if (cnt > 1l) - { - l[1] = s[2]; - r[1] = s[3]; - if (cnt > 2l) - { - l[2] = s[4]; - r[2] = s[5]; - } - } - } -} - -static inline void mono16_from_monopcm16(register short *l, - register short *s, - long cnt) +static inline void mono16_from_multichannel(register short *l, + register short *s, + long cnt, int chan) { - while (cnt >= 4l) - { - l[0] = s[0]; - l[1] = s[1]; - l[2] = s[2]; - l[3] = s[3]; - l += 4; - s += 4; - cnt -= 4l; - } - - if (cnt > 0l) + while (cnt > 0) { l[0] = s[0]; - if (cnt > 1l) - { - l[1] = s[1]; - if (cnt > 2l) - { - l[2] = s[2]; - } - } + s += chan; + l++; + cnt--; } } diff --git a/src/ui/logscale.cpp b/src/ui/logscale.cpp deleted file mode 100644 index 921004fd9..000000000 --- a/src/ui/logscale.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2000-2001 Brad Hughes <bhughes@trolltech.com> -// -// Use, modification and distribution is allowed without limitation, -// warranty, or liability of any kind. -// - -#include "logscale.h" - -#include <math.h> -#include <stdio.h> - - -LogScale::LogScale(int maxscale, int maxrange) - : indices(0), s(0), r(0) -{ - setMax(maxscale, maxrange); -} - - -LogScale::~LogScale() -{ - if (indices) - delete [] indices; -} - - -void LogScale::setMax(int maxscale, int maxrange) -{ - if (maxscale == 0 || maxrange == 0) - return; - - s = maxscale; - r = maxrange; - - if (indices) - delete [] indices; - - double alpha; - int i, scaled; - double domain = double(maxscale), - range = double(maxrange), - x = 1.0, - dx = 1.0, - y = 0.0, - yy = 0.0, - t = 0.0, - e4 = double(1.0E-8); - - indices = new int[maxrange]; - for (i = 0; i < maxrange; i++) - indices[i] = 0; - - // initialize log scale - while (fabs(dx) > e4) { - t = log((domain + x) / x); - y = (x * t) - range; - yy = t - (domain / (x + domain)); - dx = y / yy; - x -= dx; - } - - alpha = x; - for (i = 1; i < (int) domain; i++) { - scaled = (int) floor(0.5 + (alpha * log((double(i) + alpha) / alpha))); - if (indices[scaled - 1] < i) - indices[scaled - 1] = i; - } -} - - -int LogScale::operator[](int index) -{ - return indices[index]; -} diff --git a/src/ui/logscale.h b/src/ui/logscale.h deleted file mode 100644 index d74d25207..000000000 --- a/src/ui/logscale.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2000-2001 Brad Hughes <bhughes@trolltech.com> -// -// Use, modification and distribution is allowed without limitation, -// warranty, or liability of any kind. -// - -#ifndef __logscale_h -#define __logscale_h - - -class LogScale -{ -public: - LogScale(int = 0, int = 0); - ~LogScale(); - - int scale() const { return s; } - int range() const { return r; } - - void setMax(int, int); - - int operator[](int); - - -private: - int *indices; - int s, r; -}; - - -#endif // __logscale_h diff --git a/src/ui/mainvisual.cpp b/src/ui/mainvisual.cpp index fdf7076e7..222878e36 100644 --- a/src/ui/mainvisual.cpp +++ b/src/ui/mainvisual.cpp @@ -31,6 +31,9 @@ #include "inlines.h" #include "mainvisual.h" +#define VISUAL_NODE_SIZE 512 //samples +#define VISUAL_BUFFER_SIZE (5*VISUAL_NODE_SIZE) + MainVisual *MainVisual::m_instance = 0; @@ -49,9 +52,10 @@ MainVisual::MainVisual (QWidget *parent) connect(m_skin, SIGNAL(skinChanged()), this, SLOT(updateSettings())); m_timer = new QTimer (this); connect(m_timer, SIGNAL (timeout()), this, SLOT (timeout())); - m_nodes.clear(); createMenu(); readSettings(); + m_left_buffer = new short[VISUAL_BUFFER_SIZE]; + m_buffer_at = 0; m_instance = this; } @@ -67,8 +71,7 @@ MainVisual::~MainVisual() else settings.setValue("Visualization/type", "None"); settings.setValue("Visualization/rate", 1000/m_timer->interval()); - while (!m_nodes.isEmpty()) - delete m_nodes.takeFirst(); + delete [] m_left_buffer; m_instance = 0; } @@ -89,8 +92,7 @@ void MainVisual::setVisual (VisualBase *newvis) void MainVisual::clear() { - while (!m_nodes.isEmpty()) - delete m_nodes.takeFirst(); + m_buffer_at = 0; if (m_vis) m_vis->clear(); m_pixmap = m_bg; @@ -102,52 +104,47 @@ void MainVisual::add (unsigned char *data, qint64 size, int chan) if (!m_timer->isActive () || !m_vis) return; - short *l = 0, *r = 0; - qint64 samples = size/chan >> 1; - int frames = samples/512; - for (int i = 0; i < frames; ++i) + if(VISUAL_BUFFER_SIZE == m_buffer_at) { - l = new short[512]; - r = 0; - if (chan == 2) - { - r = new short[512]; - stereo16_from_stereopcm16 (l, r, (short *) (data + i*4*512), 512); - } - else if (chan == 1) - mono16_from_monopcm16 (l, (short *) (data + i*2*512), 512); - else - { - r = new short[512]; - stereo16_from_multichannel(l, r, (short *) (data + i*2*chan*512), 512, chan); - } - m_nodes.append (new VisualNode (l, r, 512)); + m_buffer_at -= VISUAL_NODE_SIZE; + memmove(m_left_buffer, m_left_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1); + return; + } + + int frames = qMin((int)size/chan >> 1, VISUAL_BUFFER_SIZE - m_buffer_at); + + if (chan >= 2) + { + mono16_from_multichannel(m_left_buffer + m_buffer_at, (short *) data, frames, chan); + } + else + { + memcpy(m_left_buffer + m_buffer_at, (short *) data, frames << 1); } + + m_buffer_at += frames; } void MainVisual::timeout() { - VisualNode *node = 0; mutex()->lock (); - while(m_nodes.size() > 5) + if(m_buffer_at < VISUAL_NODE_SIZE) { - delete m_nodes.takeFirst(); + mutex()->unlock (); + return; } - if(!m_nodes.isEmpty()) - node = m_nodes.takeFirst(); - - mutex()->unlock(); - - if (m_vis && node) + if (m_vis) { - m_vis->process (node); + m_vis->process (m_left_buffer); + m_buffer_at -= VISUAL_NODE_SIZE; + memmove(m_left_buffer, m_left_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1); m_pixmap = m_bg; QPainter p(&m_pixmap); m_vis->draw (&p); - delete node; } + mutex()->unlock (); update(); } @@ -447,14 +444,14 @@ void Analyzer::clear() } } -bool Analyzer::process (VisualNode *node) +bool Analyzer::process (short *l) { static fft_state *state = 0; if (!state) state = fft_init(); short dest[256]; - const int xscale_long[] = + static const int xscale_long[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, @@ -463,19 +460,14 @@ bool Analyzer::process (VisualNode *node) 114, 122, 131, 140, 150, 161, 172, 184, 255 }; - const int xscale_short[] = + static const int xscale_short[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 15, 20, 27, 36, 47, 62, 82, 107, 141, 184, 255 }; - if (node) - { - //i = node->length; - calc_freq (dest, node->left); - } - else - return false; + calc_freq (dest, l); + const double y_scale = 3.60673760222; /* 20.0 / log(256) */ int max = m_lines ? 75 : 19, y, j; @@ -587,18 +579,15 @@ void Scope::clear() Scope::~Scope() {} -bool Scope::process(VisualNode *node) +bool Scope::process(short *l) { - if (!node) - return false; - - int step = (node->length << 8)/76; + int step = (VISUAL_NODE_SIZE << 8)/76; int pos = 0; for (int i = 0; i < 76; ++i) { pos += step; - m_intern_vis_data[i] = (node->left[pos >> 8] >> 12); + m_intern_vis_data[i] = (l[pos >> 8] >> 12); if (m_intern_vis_data[i] > 4) m_intern_vis_data[i] = 4; diff --git a/src/ui/mainvisual.h b/src/ui/mainvisual.h index dbd3cd9c0..9807483d7 100644 --- a/src/ui/mainvisual.h +++ b/src/ui/mainvisual.h @@ -23,40 +23,17 @@ #include <QWidget> #include <QResizeEvent> #include <qmmp/visual.h> -#include "logscale.h" -class QSettings; class QTimer; class QMenu; class QActionGroup; -class Buffer; - -class VisualNode -{ -public: - VisualNode(short *l, short *r, unsigned long n) - : left(l), right(r), length(n) - { - // left and right are allocated and then passed to this class - // the code that allocated left and right should give up all ownership - } - - ~VisualNode() - { - delete [] left; - delete [] right; - } - - short *left, *right; - long length; -}; class VisualBase { public: virtual ~VisualBase(){} virtual void clear() = 0; - virtual bool process(VisualNode *node) = 0; + virtual bool process(short *l) = 0; virtual void draw(QPainter *) = 0; virtual const QString name() = 0; }; @@ -96,7 +73,6 @@ private: VisualBase *m_vis; QPixmap m_pixmap; QPixmap m_bg; - QList <VisualNode*> m_nodes; QTimer *m_timer; bool m_playing; Skin *m_skin; @@ -112,6 +88,9 @@ private: QAction *m_peaksAction; QAction *m_transparentAction; int m_ratio; + short *m_left_buffer; + short *m_right_buffer; + int m_buffer_at; }; namespace mainvisual @@ -123,7 +102,7 @@ public: virtual ~Analyzer(); void clear(); - bool process(VisualNode *node); + bool process(short *l); void draw(QPainter *p); const QString name() { @@ -149,7 +128,7 @@ public: Scope(); virtual ~Scope(); void clear(); - bool process(VisualNode *node); + bool process(short *l); void draw(QPainter *p); const QString name() { diff --git a/src/ui/mp3player.cpp b/src/ui/mp3player.cpp index 1d20377e7..b42b52632 100644 --- a/src/ui/mp3player.cpp +++ b/src/ui/mp3player.cpp @@ -38,13 +38,14 @@ int main(int argc, char *argv[]) { QApplication a (argc, argv ); a.setApplicationName("qmmp"); + + LXDESupport::load(); //load lxde icons + QTranslator translator; QString locale = Qmmp::systemLanguageID(); translator.load(QString(":/qmmp_") + locale); a.installTranslator(&translator); - LXDESupport::load(); //lxde icons - QTranslator qt_translator; qt_translator.load(QLibraryInfo::location (QLibraryInfo::TranslationsPath) + "/qt_" + locale); a.installTranslator(&qt_translator); diff --git a/src/ui/shadedvisual.cpp b/src/ui/shadedvisual.cpp index fdc487c7c..e249752ca 100644 --- a/src/ui/shadedvisual.cpp +++ b/src/ui/shadedvisual.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007-2009 by Ilya Kotov * + * Copyright (C) 2007-2010 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -25,6 +25,9 @@ #include "inlines.h" #include "shadedvisual.h" +#define VISUAL_NODE_SIZE 512 //samples +#define VISUAL_BUFFER_SIZE (5*VISUAL_NODE_SIZE) + ShadedVisual::ShadedVisual(QWidget *parent) : Visual(parent) { m_skin = Skin::instance(); @@ -34,49 +37,52 @@ ShadedVisual::ShadedVisual(QWidget *parent) : Visual(parent) m_timer = new QTimer(this); connect(m_timer, SIGNAL (timeout()), this, SLOT (timeout())); connect(m_skin, SIGNAL(skinChanged()), this, SLOT(updateSkin())); + m_left_buffer = new short[VISUAL_BUFFER_SIZE]; + m_right_buffer = new short[VISUAL_BUFFER_SIZE]; + m_buffer_at = 0; m_timer->setInterval(50); m_timer->start(); clear(); } ShadedVisual::~ShadedVisual() -{} +{ + delete [] m_left_buffer; + delete [] m_right_buffer; +} void ShadedVisual::add(unsigned char *data, qint64 size, int chan) { if (!m_timer->isActive ()) return; - long len = size, cnt; - short *l = 0, *r = 0; - - len /= chan; - len /= 2; - if ( len > 512 ) - len = 512; - cnt = len; - if (chan == 2) + if(VISUAL_BUFFER_SIZE == m_buffer_at) { - l = new short[len]; - r = new short[len]; - stereo16_from_stereopcm16 ( l, r, (short *) data, cnt); + m_buffer_at -= VISUAL_NODE_SIZE; + memmove(m_left_buffer, m_left_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1); + memmove(m_right_buffer, m_right_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1); + return; } - else if (chan == 1) + + int frames = qMin((int)size/chan >> 1, VISUAL_BUFFER_SIZE - m_buffer_at); + + if (chan >= 2) { - l = new short[len]; - mono16_from_monopcm16 (l, (short *) data, cnt); + stereo16_from_multichannel(m_left_buffer + m_buffer_at, + m_right_buffer + m_buffer_at,(short *) data, frames, chan); } else - len = 0; + { + memcpy(m_left_buffer + m_buffer_at, (short *) data, frames << 1); + memcpy(m_right_buffer + m_buffer_at, (short *) data, frames << 1); + } - if (len) - m_nodes.append (new VisualNode (l, r, len)); + m_buffer_at += frames; } void ShadedVisual::clear() { - while (!m_nodes.isEmpty()) - m_nodes.removeFirst(); + m_buffer_at = 0; m_l = 0; m_r = 0; m_pixmap.fill(m_skin->getVisColor(0)); @@ -85,39 +91,28 @@ void ShadedVisual::clear() void ShadedVisual::timeout() { - VisualNode *node = 0; m_pixmap.fill(m_skin->getVisColor(0)); mutex()->lock (); - VisualNode *prev = 0; - while ((!m_nodes.isEmpty())) + if(m_buffer_at < VISUAL_NODE_SIZE) { - node = m_nodes.takeFirst(); - /*if ( node->offset > synctime ) - break;*/ - - if (prev) - delete prev; - prev = node; + mutex()->unlock (); + return; } - mutex()->unlock(); - node = prev; - if (!node) - return; - process (node); - delete node; + process (m_left_buffer, m_right_buffer); + m_buffer_at -= VISUAL_NODE_SIZE; + memmove(m_left_buffer, m_left_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1); + memmove(m_right_buffer, m_right_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1); QPainter p(&m_pixmap); draw (&p); + mutex()->unlock (); update(); } -void ShadedVisual::process (VisualNode *node) +void ShadedVisual::process (short *left, short *right) { - if (!node) - return; - - int step = (node->length << 8)/74; + int step = (VISUAL_NODE_SIZE << 8)/74; int pos = 0; int l = 0; int r = 0; @@ -127,17 +122,17 @@ void ShadedVisual::process (VisualNode *node) { pos += step; - if (node->left) + if (left) { - j_l = abs((node->left[pos >> 8] >> 12)); + j_l = abs((left[pos >> 8] >> 12)); if (j_l > 15) j_l = 15; l = qMax(l, j_l); } - if (node->right) + if (right) { - j_r = abs((node->right[pos >> 8] >> 12)); + j_r = abs((right[pos >> 8] >> 12)); if (j_r > 15) j_r = 15; r = qMax(r, j_r); diff --git a/src/ui/shadedvisual.h b/src/ui/shadedvisual.h index e276b8b24..0592ec78f 100644 --- a/src/ui/shadedvisual.h +++ b/src/ui/shadedvisual.h @@ -27,7 +27,7 @@ class QTimer; class QPixmap; class Skin; -class VisualNode; +//class VisualNode; /** @author Ilya Kotov <forkotov02@hotmail.ru> @@ -54,12 +54,14 @@ private slots: void updateSkin(); private: - void process (VisualNode *node); + void process (short *l, short *r); void draw (QPainter *); Skin *m_skin; QTimer *m_timer; QPixmap m_pixmap; - QList <VisualNode*> m_nodes; + short *m_left_buffer; + short *m_right_buffer; + int m_buffer_at; double m_l, m_r; int m_ratio; diff --git a/src/ui/ui.pro b/src/ui/ui.pro index c4c0ee861..3cabae11e 100644 --- a/src/ui/ui.pro +++ b/src/ui/ui.pro @@ -28,7 +28,6 @@ HEADERS += mainwindow.h \ mainvisual.h \ inlines.h \ fft.h \ - logscale.h \ textscroller.h \ monostereo.h \ playstatus.h \ @@ -81,7 +80,6 @@ SOURCES += mainwindow.cpp \ eqgraph.cpp \ mainvisual.cpp \ fft.c \ - logscale.cpp \ textscroller.cpp \ monostereo.cpp \ playstatus.cpp \ |
