diff options
Diffstat (limited to 'src/plugins')
| -rw-r--r-- | src/plugins/General/rgscan/rgscaner.cpp | 29 | ||||
| -rw-r--r-- | src/plugins/Input/mad/decoder_mad.cpp | 140 | ||||
| -rw-r--r-- | src/plugins/Input/mad/decoder_mad.h | 3 |
3 files changed, 113 insertions, 59 deletions
diff --git a/src/plugins/General/rgscan/rgscaner.cpp b/src/plugins/General/rgscan/rgscaner.cpp index 069a4e0da..0fc2e3833 100644 --- a/src/plugins/General/rgscan/rgscaner.cpp +++ b/src/plugins/General/rgscan/rgscaner.cpp @@ -22,6 +22,7 @@ #include <stdint.h> #include <QStringList> #include <QThread> +#include <math.h> #include <qmmp/inputsourcefactory.h> #include <qmmp/decoderfactory.h> #include "rgscaner.h" @@ -143,14 +144,14 @@ void RGScaner::run() const int buf_size = 8192; //samples AudioParameters ap = m_decoder->audioParameters(); //Qmmp::AudioFormat format = ap.format(); - unsigned char output_buf[buf_size]; + float output_buf[buf_size]; qint64 output_at = 0; qint64 total = 0; qint64 len = 0; - qint64 totalSize = m_decoder->totalTime() * ap.sampleRate() * ap.channels() * ap.sampleSize() / 1000; - qint32 max = 0; - double out_left[buf_size/4]; - double out_right[buf_size/4]; + qint64 totalSamples = m_decoder->totalTime() * ap.sampleRate() * ap.channels() / 1000; + float max = 0; + double out_left[buf_size/2]; + double out_right[buf_size/2]; if(m_handle) @@ -164,22 +165,22 @@ void RGScaner::run() forever { // decode - len = m_decoder->read((char *)(output_buf + output_at), buf_size - output_at); + len = m_decoder->read((float *)(output_buf + output_at), buf_size - output_at); if (len > 0) { output_at += len; total += len; - emit progress(100 * total / totalSize); + emit progress(100 * total / totalSamples); - for(int i = 0; i < len/4; ++i) + for(int i = 0; i < len/2; ++i) { - out_left[i] = ((short *) output_buf)[i*2]; - out_right[i] = ((short *) output_buf)[i*2+1]; - max = qMax(abs(out_left[i]), max); - max = qMax(abs(out_right[i]), max); + out_left[i] = output_buf[i*2]*32767.0; + out_right[i] = output_buf[i*2+1]*32767.0; + max = qMax(fabs(out_left[i]), (double)max); + max = qMax(fabs(out_right[i]), (double)max); } - AnalyzeSamples(m_handle, out_left, out_right, len/4, 2); + AnalyzeSamples(m_handle, out_left, out_right, len/2, 2); output_at = 0; } @@ -196,7 +197,7 @@ void RGScaner::run() } m_gain = GetTitleGain(m_handle); - m_peak = max / 32768.0; + m_peak = max/32767.0; qDebug("peak = %f", m_peak); qDebug("RGScaner: thread %ld finished", QThread::currentThreadId()); m_is_running = false; diff --git a/src/plugins/Input/mad/decoder_mad.cpp b/src/plugins/Input/mad/decoder_mad.cpp index 331453362..b4087c06b 100644 --- a/src/plugins/Input/mad/decoder_mad.cpp +++ b/src/plugins/Input/mad/decoder_mad.cpp @@ -340,48 +340,18 @@ int DecoderMAD::bitrate() qint64 DecoderMAD::read(char *data, qint64 size) { - forever - { - if(((m_stream.error == MAD_ERROR_BUFLEN) || !m_stream.buffer) && !m_eof) - { - m_eof = !fillBuffer(); - } - if(mad_frame_decode(&m_frame, &m_stream) < 0) - { - switch((int) m_stream.error) - { - case MAD_ERROR_LOSTSYNC: - { - //skip ID3v2 tag - uint tagSize = findID3v2((uchar *)m_stream.this_frame, - (ulong) (m_stream.bufend - m_stream.this_frame)); - if (tagSize > 0) - { - mad_stream_skip(&m_stream, tagSize); - qDebug("DecoderMAD: %d bytes skipped", tagSize); - } - continue; - } - case MAD_ERROR_BUFLEN: - if(m_eof) - return 0; - continue; - default: - if (!MAD_RECOVERABLE(m_stream.error)) - return 0; - else - continue; - } - } - if(m_skip_frames) - { - m_skip_frames--; - continue; - } - mad_synth_frame(&m_synth, &m_frame); + if(decodeFrame()) return madOutput(data, size); - } + return 0; } + +qint64 DecoderMAD::read(float *data, qint64 samples) +{ + if(decodeFrame()) + return madOutputFloat(data, samples); + return 0; +} + void DecoderMAD::seek(qint64 pos) { if(m_totalTime > 0) @@ -508,12 +478,58 @@ long DecoderMAD::audio_linear_round(unsigned int bits, mad_fixed_t sample) return sample >> (MAD_F_FRACBITS + 1 - bits); } +bool DecoderMAD::decodeFrame() +{ + forever + { + if(((m_stream.error == MAD_ERROR_BUFLEN) || !m_stream.buffer) && !m_eof) + { + m_eof = !fillBuffer(); + } + if(mad_frame_decode(&m_frame, &m_stream) < 0) + { + switch((int) m_stream.error) + { + case MAD_ERROR_LOSTSYNC: + { + //skip ID3v2 tag + uint tagSize = findID3v2((uchar *)m_stream.this_frame, + (ulong) (m_stream.bufend - m_stream.this_frame)); + if (tagSize > 0) + { + mad_stream_skip(&m_stream, tagSize); + qDebug("DecoderMAD: %d bytes skipped", tagSize); + } + continue; + } + case MAD_ERROR_BUFLEN: + if(m_eof) + return false; + continue; + default: + if (!MAD_RECOVERABLE(m_stream.error)) + return false; + else + continue; + } + } + if(m_skip_frames) + { + m_skip_frames--; + continue; + } + mad_synth_frame(&m_synth, &m_frame); + break; + } + return true; +} + qint64 DecoderMAD::madOutput(char *data, qint64 size) { - unsigned int samples, channels; + unsigned int samples_per_channel, channels; mad_fixed_t const *left, *right; - samples = m_synth.pcm.length; + samples_per_channel = m_synth.pcm.length; channels = m_synth.pcm.channels; left = m_synth.pcm.samples[0]; right = m_synth.pcm.samples[1]; @@ -521,13 +537,13 @@ qint64 DecoderMAD::madOutput(char *data, qint64 size) m_output_at = 0; m_output_bytes = 0; - if(samples * channels * 2 > size) + if(samples_per_channel * channels * 2 > size) { qWarning("DecoderMad: input buffer is too small"); - samples = size / channels / 2; + samples_per_channel = size / channels / 2; } - while (samples--) + while (samples_per_channel--) { signed int sample; #ifdef USE_DITHERING @@ -553,3 +569,37 @@ qint64 DecoderMAD::madOutput(char *data, qint64 size) } return m_output_bytes; } + +qint64 DecoderMAD::madOutputFloat(float *data, qint64 samples) +{ + float *data_it = data; + unsigned int samples_per_channel, channels; + mad_fixed_t const *left, *right; + + samples_per_channel = m_synth.pcm.length; + channels = m_synth.pcm.channels; + left = m_synth.pcm.samples[0]; + right = m_synth.pcm.samples[1]; + m_bitrate = m_frame.header.bitrate / 1000; + m_output_at = 0; + m_output_bytes = 0; + qint64 output_samples = 0; + + if(samples_per_channel * channels > samples) + { + qWarning("DecoderMad: input buffer is too small"); + samples_per_channel = samples / channels; + } + + while (samples_per_channel--) + { + *data_it++ = mad_f_todouble(*left++); + output_samples++; + if (channels == 2) + { + *data_it++ = mad_f_todouble(*right++); + output_samples++; + } + } + return output_samples; +} diff --git a/src/plugins/Input/mad/decoder_mad.h b/src/plugins/Input/mad/decoder_mad.h index 002caa53d..d15508848 100644 --- a/src/plugins/Input/mad/decoder_mad.h +++ b/src/plugins/Input/mad/decoder_mad.h @@ -46,11 +46,14 @@ public: qint64 totalTime(); int bitrate(); qint64 read(char *data, qint64 size); + qint64 read(float *data, qint64 samples); void seek(qint64); private: // helper functions + bool decodeFrame(); qint64 madOutput(char *data, qint64 size); + qint64 madOutputFloat(float *data, qint64 samples); bool fillBuffer(); void deinit(); bool findHeader(); |
