diff options
Diffstat (limited to 'src/plugins/Input/modplug/decoder_modplug.cpp')
| -rw-r--r-- | src/plugins/Input/modplug/decoder_modplug.cpp | 257 |
1 files changed, 50 insertions, 207 deletions
diff --git a/src/plugins/Input/modplug/decoder_modplug.cpp b/src/plugins/Input/modplug/decoder_modplug.cpp index adb11daed..c33716f28 100644 --- a/src/plugins/Input/modplug/decoder_modplug.cpp +++ b/src/plugins/Input/modplug/decoder_modplug.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008 by Ilya Kotov * + * Copyright (C) 2008-2009 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -33,7 +33,6 @@ #include <libmodplug/it_defs.h> #include <libmodplug/sndfile.h> -#include <qmmp/constants.h> #include <qmmp/buffer.h> #include <qmmp/output.h> #include <qmmp/recycler.h> @@ -51,21 +50,10 @@ DecoderModPlug::DecoderModPlug(QObject *parent, DecoderFactory *d, Output *o, co : Decoder(parent, d, o) { m_path = path; - m_inited = FALSE; - m_user_stop = FALSE; - m_output_buf = 0; - m_output_bytes = 0; - m_output_at = 0; - m_bks = 0; - m_done = FALSE; - m_finish = FALSE; m_freq = 0; m_bitrate = 0; - m_seekTime = -1.0; - m_totalTime = 0.0; + m_totalTime = 0; m_chan = 0; - m_output_size = 0; - //m_modFile = 0; m_soundFile = 0; m_sampleSize = 0; m_instance = this; @@ -74,71 +62,15 @@ DecoderModPlug::DecoderModPlug(QObject *parent, DecoderFactory *d, Output *o, co DecoderModPlug::~DecoderModPlug() { deinit(); - if (m_output_buf) - delete [] m_output_buf; - m_output_buf = 0; m_instance = 0; } -void DecoderModPlug::stop() -{ - m_user_stop = TRUE; -} - -void DecoderModPlug::flush(bool final) -{ - ulong min = final ? 0 : m_bks; - - while ((! m_done && ! m_finish) && m_output_bytes > min) - { - output()->recycler()->mutex()->lock (); - - while ((! m_done && ! m_finish) && output()->recycler()->full()) - { - mutex()->unlock(); - - output()->recycler()->cond()->wait(output()->recycler()->mutex()); - - mutex()->lock (); - m_done = m_user_stop; - } - - if (m_user_stop || m_finish) - { - m_inited = FALSE; - m_done = TRUE; - } - else - { - m_output_bytes -= produceSound(m_output_buf, m_output_bytes, m_bitrate, m_chan); - m_output_size += m_bks; - m_output_at = m_output_bytes; - } - - if (output()->recycler()->full()) - { - output()->recycler()->cond()->wakeOne(); - } - - output()->recycler()->mutex()->unlock(); - } -} - bool DecoderModPlug::initialize() { - m_bks = Buffer::size(); - m_inited = m_user_stop = m_done = m_finish = FALSE; m_freq = m_bitrate = 0; m_chan = 0; - m_output_size = 0; - m_seekTime = -1.0; m_totalTime = 0.0; - if (! m_output_buf) - m_output_buf = new char[globalBufferSize]; - m_output_at = 0; - m_output_bytes = 0; - ArchiveReader reader(this); if (reader.isSupported(m_path)) m_input_buf = reader.unpack(m_path); @@ -163,171 +95,82 @@ bool DecoderModPlug::initialize() m_sampleSize = m_bps / 8 * m_chan; m_soundFile->Create((uchar*) m_input_buf.data(), m_input_buf.size()); m_bitrate = m_soundFile->GetNumChannels(); - /*if(!m_modFile) - { - qWarning("DecoderModPlug: error reading moplug file"); - return FALSE; - }*/ - m_totalTime = (qint64) m_soundFile->GetSongTime() * 1000; configure(m_freq, m_chan, m_bps); - m_inited = TRUE; return TRUE; } qint64 DecoderModPlug::totalTime() { - if (! m_inited) - return 0; - return m_totalTime; } - -void DecoderModPlug::seek(qint64 pos) -{ - m_seekTime = pos; -} - -void DecoderModPlug::deinit() +int DecoderModPlug::bitrate() { - m_inited = m_user_stop = m_done = m_finish = FALSE; - m_freq = m_bitrate = 0; - m_chan = 0; - m_output_size = 0; - if (m_soundFile) - { - m_soundFile->Destroy(); - delete m_soundFile; - m_soundFile = 0; - } - m_input_buf.clear(); + return m_bitrate; } -void DecoderModPlug::run() +qint64 DecoderModPlug::readAudio(char *audio, qint64 maxSize) { - mutex()->lock (); - - ulong len = 0; - if (!m_inited) + long len = m_soundFile->Read (audio, qMin((qint64)Buffer::size(), maxSize)) * m_sampleSize; + if (m_usePreamp) { - mutex()->unlock(); - return; - } - mutex()->unlock(); - - char *prebuf = new char[m_bks]; - - while (!m_done && !m_finish) - { - mutex()->lock (); - - //seeking - - if (m_seekTime >= 0) - { - quint32 lMax; - quint32 lMaxtime; - double lPostime; - - if (m_seekTime > (lMaxtime = m_soundFile->GetSongTime()) * 1000) - m_seekTime = lMaxtime * 1000; - lMax = m_soundFile->GetMaxPosition(); - lPostime = float(lMax) / lMaxtime; - m_soundFile->SetCurrentPos(int(m_seekTime * lPostime / 1000)); - m_seekTime = -1.0; - } - - // decode - len = m_bks > (globalBufferSize - m_output_at) ? globalBufferSize - m_output_at : m_bks; - len = m_soundFile->Read (prebuf, len) * m_sampleSize; - - //preamp - if (m_usePreamp) { + //apply preamp + if (m_bps == 16) { - //apply preamp - if (m_bps == 16) + long n = len >> 1; + for (long i = 0; i < n; i++) { - uint n = len >> 1; - for (uint i = 0; i < n; i++) - { - short old = ((short*)prebuf)[i]; - ((short*)prebuf)[i] *= m_preampFactor; - // detect overflow and clip! - if ((old & 0x8000) != - (((short*)prebuf)[i] & 0x8000)) - ((short*)prebuf)[i] = old | 0x7FFF; - - } - } - else - { - for (uint i = 0; i < len; i++) - { - uchar old = ((uchar*)prebuf)[i]; - ((uchar*)prebuf)[i] *= m_preampFactor; - // detect overflow and clip! - if ((old & 0x80) != - (((uchar*)prebuf)[i] & 0x80)) - ((uchar*)prebuf)[i] = old | 0x7F; - } + short old = ((short*)audio)[i]; + ((short*)audio)[i] *= m_preampFactor; + // detect overflow and clip! + if ((old & 0x8000) != + (((short*)audio)[i] & 0x8000)) + ((short*)audio)[i] = old | 0x7FFF; } } - } - - memmove(m_output_buf + m_output_at, prebuf, len); - - if (len > 0) - { - m_output_at += len; - m_output_bytes += len; - - if (output()) - flush(); - - } - else if (len == 0) - { - flush(TRUE); - - if (output()) + else { - output()->recycler()->mutex()->lock (); - // end of stream - while (! output()->recycler()->empty() && ! m_user_stop) + for (long i = 0; i < len; i++) { - output()->recycler()->cond()->wakeOne(); - mutex()->unlock(); - output()->recycler()->cond()->wait(output()->recycler()->mutex()); - mutex()->lock (); + uchar old = ((uchar*)audio)[i]; + ((uchar*)audio)[i] *= m_preampFactor; + // detect overflow and clip! + if ((old & 0x80) != + (((uchar*)audio)[i] & 0x80)) + ((uchar*)audio)[i] = old | 0x7F; } - output()->recycler()->mutex()->unlock(); - } - - m_done = TRUE; - if (! m_user_stop) - { - m_finish = TRUE; } } - else - { - // error while read - qWarning("DecoderModPlug: Error while decoding stream, File appears to be corrupted"); - m_finish = TRUE; - } - mutex()->unlock(); } + return len; +} - mutex()->lock (); - - if (m_finish) - finish(); +void DecoderModPlug::seekAudio(qint64 pos) +{ + quint32 lMax; + quint32 lMaxtime; + double lPostime; + + if (pos > (lMaxtime = m_soundFile->GetSongTime()) * 1000) + pos = lMaxtime * 1000; + lMax = m_soundFile->GetMaxPosition(); + lPostime = float(lMax) / lMaxtime; + m_soundFile->SetCurrentPos(int(pos * lPostime / 1000)); +} - mutex()->unlock(); - delete prebuf; - deinit(); +void DecoderModPlug::deinit() +{ + m_freq = m_bitrate = 0; + m_chan = 0; + if (m_soundFile) + { + m_soundFile->Destroy(); + delete m_soundFile; + m_soundFile = 0; + } + m_input_buf.clear(); } void DecoderModPlug::readSettings() |
