aboutsummaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/General/rgscan/rgscaner.cpp29
-rw-r--r--src/plugins/Input/mad/decoder_mad.cpp140
-rw-r--r--src/plugins/Input/mad/decoder_mad.h3
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();