aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qmmp/audioconverter.cpp43
-rw-r--r--src/qmmp/audioconverter_p.h12
-rw-r--r--src/qmmp/audioparameters.cpp9
-rw-r--r--src/qmmp/audioparameters.h1
-rw-r--r--src/qmmp/outputwriter.cpp23
-rw-r--r--src/qmmp/outputwriter_p.h3
-rw-r--r--src/qmmp/qmmpaudioengine.cpp37
-rw-r--r--src/qmmp/qmmpaudioengine_p.h4
8 files changed, 60 insertions, 72 deletions
diff --git a/src/qmmp/audioconverter.cpp b/src/qmmp/audioconverter.cpp
index 5316539a4..b4eb27753 100644
--- a/src/qmmp/audioconverter.cpp
+++ b/src/qmmp/audioconverter.cpp
@@ -19,10 +19,11 @@
***************************************************************************/
#include <math.h>
+#include <QtGlobal>
#include "audioconverter_p.h"
//static functions
-static inline void s8_to_s16(qint8 *in, qint16 *out, qint64 samples)
+/*static inline void s8_to_s16(qint8 *in, qint16 *out, qint64 samples)
{
for(qint64 i = 0; i < samples; ++i)
out[i] = in[i] << 8;
@@ -41,7 +42,7 @@ static inline void s32_to_s16(qint32 *in, qint16 *out, qint64 samples)
for(qint64 i = 0; i < samples; ++i)
out[i] = in[i] >> 16;
return;
-}
+}*/
#define INT_TO_FLOAT(TYPE,in,out,samples,offset,max) \
{ \
@@ -64,46 +65,12 @@ static inline void s32_to_s16(qint32 *in, qint16 *out, qint64 samples)
AudioConverter::AudioConverter()
{
m_format = Qmmp::PCM_UNKNOWM;
- m_channels = 0;
m_swap = false;
}
-void AudioConverter::configure(quint32 srate, ChannelMap map, Qmmp::AudioFormat f)
-{
- m_format = f;
- Effect::configure(srate, map, Qmmp::PCM_S16LE);
-}
-
-void AudioConverter::applyEffect(Buffer *b)
-{
- switch(m_format)
- {
- case Qmmp::PCM_S8:
- {
- unsigned char *out = new unsigned char[b->nbytes*2];
- s8_to_s16((qint8 *)b->data, (qint16 *) out, b->nbytes);
- delete [] b->data;
- b->data = out;
- b->nbytes <<= 1;
- break;
- }
- case Qmmp::PCM_S24LE:
- s24_to_s16((qint32 *)b->data, (qint16 *)b->data, b->nbytes >> 2);
- b->nbytes >>= 1;
- break;
- case Qmmp::PCM_S32LE:
- s32_to_s16((qint32 *)b->data, (qint16 *)b->data, b->nbytes >> 2);
- b->nbytes >>= 1;
- break;
- default:
- ;
- }
-}
-
-void AudioConverter::configure(quint8 chan, Qmmp::AudioFormat f)
+void AudioConverter::configure(Qmmp::AudioFormat f)
{
m_format = f;
- m_channels = chan;
switch (f)
{
@@ -181,7 +148,7 @@ void AudioConverter::toFloat(const unsigned char *in, float *out, size_t samples
}
}
-void AudioConverter::fromFloat(const float *in, const unsigned *out, size_t samples)
+void AudioConverter::fromFloat(const float *in, const unsigned char *out, size_t samples)
{
switch (m_format)
{
diff --git a/src/qmmp/audioconverter_p.h b/src/qmmp/audioconverter_p.h
index 3591dd13b..2cb017355 100644
--- a/src/qmmp/audioconverter_p.h
+++ b/src/qmmp/audioconverter_p.h
@@ -22,27 +22,23 @@
#define AUDIOCONVERTER_P_H
#include <stddef.h>
-#include "effect.h"
+#include "qmmp.h"
/*! @internal
* @author Ilya Kotov <forkotov02@hotmail.ru>
*/
-class AudioConverter : public Effect
+class AudioConverter
{
public:
AudioConverter();
- void configure(quint32 srate, ChannelMap map, Qmmp::AudioFormat f = Qmmp::PCM_S16LE);
- void applyEffect(Buffer *b);
-
- void configure(quint8 chan, Qmmp::AudioFormat f);
+ void configure(Qmmp::AudioFormat f);
void toFloat(const unsigned char *in, float *out, size_t samples);
- void fromFloat(const float *in, const unsigned *out, size_t samples);
+ void fromFloat(const float *in, const unsigned char *out, size_t samples);
private:
Qmmp::AudioFormat m_format;
- quint8 m_channels;
bool m_swap;
};
diff --git a/src/qmmp/audioparameters.cpp b/src/qmmp/audioparameters.cpp
index 3082a8dcf..d634cb4f4 100644
--- a/src/qmmp/audioparameters.cpp
+++ b/src/qmmp/audioparameters.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2009-2014 by Ilya Kotov *
+ * Copyright (C) 2009-2015 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -24,6 +24,7 @@ AudioParameters::AudioParameters()
{
m_srate = 0;
m_format = Qmmp::PCM_S16LE;
+ m_sz = 2;
}
AudioParameters::AudioParameters(const AudioParameters &other)
@@ -31,13 +32,15 @@ AudioParameters::AudioParameters(const AudioParameters &other)
m_srate = other.sampleRate();
m_chan_map = other.channelMap();
m_format = other.format();
+ m_sz = other.sampleSize();
}
-AudioParameters::AudioParameters(quint32 srate, const ChannelMap &map, Qmmp::AudioFormat format)
+AudioParameters::AudioParameters(quint32 srate, const ChannelMap &map, Qmmp::AudioFormat format)
{
m_srate = srate;
m_chan_map = map;
m_format = format;
+ m_sz = sampleSize(format);
}
void AudioParameters::operator=(const AudioParameters &p)
@@ -79,7 +82,7 @@ Qmmp::AudioFormat AudioParameters::format() const
int AudioParameters::sampleSize() const
{
- return sampleSize(m_format);
+ return m_sz;
}
int AudioParameters::sampleSize(Qmmp::AudioFormat format)
diff --git a/src/qmmp/audioparameters.h b/src/qmmp/audioparameters.h
index ac229af6b..b38d32994 100644
--- a/src/qmmp/audioparameters.h
+++ b/src/qmmp/audioparameters.h
@@ -87,6 +87,7 @@ private:
quint32 m_srate;
ChannelMap m_chan_map;
Qmmp::AudioFormat m_format;
+ int m_sz;
};
#endif // AUDIOPARAMETERS_H
diff --git a/src/qmmp/outputwriter.cpp b/src/qmmp/outputwriter.cpp
index 184d433ca..47d7b10ba 100644
--- a/src/qmmp/outputwriter.cpp
+++ b/src/qmmp/outputwriter.cpp
@@ -74,6 +74,7 @@ OutputWriter::OutputWriter (QObject* parent) : QThread (parent)
m_useEq = false;
m_muted = false;
m_settings = QmmpSettings::instance();
+ m_converter = new AudioConverter();
}
OutputWriter::~OutputWriter()
@@ -88,6 +89,7 @@ OutputWriter::~OutputWriter()
delete[] m_visBuffer;
m_visBuffer = 0;
}
+ delete m_converter;
}
bool OutputWriter::initialize(quint32 freq, ChannelMap map, Qmmp::AudioFormat format)
@@ -146,7 +148,7 @@ bool OutputWriter::initialize(quint32 freq, ChannelMap map, Qmmp::AudioFormat fo
}
m_bytesPerMillisecond = m_frequency * m_channels * AudioParameters::sampleSize(format) / 1000;
- m_recycler.configure(m_frequency, m_channels, m_format); //calculate output buffer size
+ m_recycler.configure(m_frequency, m_channels, Qmmp::PCM_FLOAT); //calculate output buffer size
//visual buffer
if(m_visBuffer)
delete [] m_visBuffer;
@@ -291,7 +293,8 @@ void OutputWriter::clearVisuals()
bool OutputWriter::prepareConverters()
{
- qDeleteAll(m_converters);
+ m_converter->configure(m_output->audioParameters().format());
+ /*qDeleteAll(m_converters);
m_converters.clear();
AudioParameters ap = m_output->audioParameters();
@@ -321,7 +324,7 @@ bool OutputWriter::prepareConverters()
{
m_converters << new ChannelConverter(ap.channelMap());
m_converters.last()->configure(sampleRate(), channelMap(), ap.format());
- }
+ }*/
return true;
}
@@ -404,7 +407,7 @@ void OutputWriter::run()
if (b)
{
mutex()->lock();
- if (m_useEq)
+ /*if (m_useEq)
{
switch(m_format)
{
@@ -420,7 +423,7 @@ void OutputWriter::run()
default:
;
}
- }
+ }*/
mutex()->unlock();
dispatchVisual(b);
if (SoftwareVolume::instance())
@@ -430,7 +433,13 @@ void OutputWriter::run()
applyConverters(b);
l = 0;
m = 0;
- while (l < b->nbytes && !m_pause && !m_prev_pause)
+
+ size_t samples = b->nbytes / sizeof(float);
+ unsigned char buf[samples * 2];
+ m_converter->fromFloat((float*)b->data, buf, samples);
+
+
+ while (l < samples * 2 && !m_pause && !m_prev_pause)
{
mutex()->lock();
if(m_skip)
@@ -441,7 +450,7 @@ void OutputWriter::run()
break;
}
mutex()->unlock();
- m = m_output->writeAudio(b->data + l, b->nbytes - l);
+ m = m_output->writeAudio(buf + l, samples * 2 - l);
if(m >= 0)
{
m_totalWritten += m;
diff --git a/src/qmmp/outputwriter_p.h b/src/qmmp/outputwriter_p.h
index b0f6ca0a6..5d2e36947 100644
--- a/src/qmmp/outputwriter_p.h
+++ b/src/qmmp/outputwriter_p.h
@@ -32,6 +32,7 @@ class QmmpSettings;
class StateHandler;
class Output;
class Effect;
+class AudioConverter;
/** @internal
@brief Output thread.
@@ -140,7 +141,7 @@ private:
Output *m_output;
bool m_muted;
QList<Effect *> m_converters;
-
+ AudioConverter *m_converter;
};
#endif // OUTPUTWRITER_P_H
diff --git a/src/qmmp/qmmpaudioengine.cpp b/src/qmmp/qmmpaudioengine.cpp
index dc8d45801..f8305576a 100644
--- a/src/qmmp/qmmpaudioengine.cpp
+++ b/src/qmmp/qmmpaudioengine.cpp
@@ -47,6 +47,7 @@ QmmpAudioEngine::QmmpAudioEngine(QObject *parent)
m_output = 0;
m_muted = false;
m_replayGain = new ReplayGain;
+ m_converter = new AudioConverter;
m_settings = QmmpSettings::instance();
connect(m_settings,SIGNAL(replayGainSettingsChanged()), SLOT(updateReplayGainSettings()));
connect(m_settings, SIGNAL(eqSettingsChanged()), SLOT(updateEqSettings()));
@@ -65,6 +66,7 @@ QmmpAudioEngine::~QmmpAudioEngine()
qDeleteAll(m_effects);
m_instance = 0;
delete m_replayGain;
+ delete m_converter;
}
void QmmpAudioEngine::reset()
@@ -292,22 +294,28 @@ void QmmpAudioEngine::stop()
delete m_effects.takeFirst();
}
-qint64 QmmpAudioEngine::produceSound(char *data, qint64 size, quint32 brate)
+qint64 QmmpAudioEngine::produceSound(unsigned char *data, qint64 size, quint32 brate)
{
Buffer *b = m_output->recycler()->get();
- uint sz = size < m_bks ? size : m_bks;
+ //uint sz = size < m_bks ? size : m_bks;
+ size_t samples = qMin(m_bks / sizeof(float), (uint)size / m_ap.sampleSize());
+ size_t in_size = samples * m_ap.sampleSize();
+
+ m_converter->toFloat(data, (float*)(b->data), samples);
+
+
//m_replayGain->applyReplayGain(data, sz);
- memcpy(b->data, data, sz);
- b->nbytes = sz;
+ //memcpy(b->data, data, sz);
+ b->nbytes = samples * sizeof(float);
b->rate = brate;
- foreach(Effect* effect, m_effects)
+ /*foreach(Effect* effect, m_effects)
{
effect->applyEffect(b);
- }
- size -= sz;
- memmove(data, data + sz, size);
+ }*/
+ size -= in_size;
+ memmove(data, data + in_size, size);
m_output->recycler()->add();
- return sz;
+ return in_size;
}
void QmmpAudioEngine::finish()
@@ -403,8 +411,8 @@ void QmmpAudioEngine::run()
{
delay = 0;
// decode
- len = m_replayGain->read(m_decoder, (m_output_buf + m_output_at), m_output_size - m_output_at);
- //len = m_decoder->read((char *)(m_output_buf + m_output_at), m_output_size - m_output_at);
+ //len = m_replayGain->read(m_decoder, (m_output_buf + m_output_at), m_output_size - m_output_at);
+ len = m_decoder->read((m_output_buf + m_output_at), m_output_size - m_output_at);
}
if (len > 0)
@@ -543,7 +551,7 @@ void QmmpAudioEngine::flush(bool final)
m_done = true;
else
{
- m_output_at -= produceSound((char*)m_output_buf, m_output_at, m_bitrate);
+ m_output_at -= produceSound(m_output_buf, m_output_at, m_bitrate);
}
if (!m_output->recycler()->empty())
@@ -604,10 +612,11 @@ OutputWriter *QmmpAudioEngine::createOutput()
void QmmpAudioEngine::prepareEffects(Decoder *d)
{
m_ap = d->audioParameters();
+ m_converter->configure(m_ap.format());
//m_ap = AudioParameters(44100, 2, Qmmp::PCM_S24LE);
- m_replayGain->configure(m_ap);
+ /*m_replayGain->configure(m_ap);
foreach(Effect *e, m_effects) //remove disabled and external effects
{
@@ -661,7 +670,7 @@ void QmmpAudioEngine::prepareEffects(Decoder *d)
}
m_effects << effect;
tmp_effects.removeAll(effect);
- }
+ }*/
}
//static members
diff --git a/src/qmmp/qmmpaudioengine_p.h b/src/qmmp/qmmpaudioengine_p.h
index fc205ed6d..b045ddc5b 100644
--- a/src/qmmp/qmmpaudioengine_p.h
+++ b/src/qmmp/qmmpaudioengine_p.h
@@ -36,6 +36,7 @@ class InputSource;
class EffectFactory;
class ReplayGain;
class QmmpSettings;
+class AudioConverter;
/*! @internal
* @author Ilya Kotov <forkotov02@hotmail.ru>
@@ -69,7 +70,7 @@ private:
void clearDecoders();
void flush(bool = false);
void addOffset();
- qint64 produceSound(char *data, qint64 size, quint32 brate);
+ qint64 produceSound(unsigned char *data, qint64 size, quint32 brate);
void sendMetaData();
OutputWriter *createOutput();
void prepareEffects(Decoder *d);
@@ -94,6 +95,7 @@ private:
static QmmpAudioEngine *m_instance;
ReplayGain *m_replayGain;
QmmpSettings *m_settings;
+ AudioConverter *m_converter;
};
#endif // QMMPAUDIOENGINE_P_H