aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Output/alsa
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2014-10-06 07:50:56 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2014-10-06 07:50:56 +0000
commit76f436c36cdec74e73c12cea8d81051a7d75ec96 (patch)
tree03fe155b5311f6dccbf0dfb2a9cb0954484a138c /src/plugins/Output/alsa
parent67e825df80708f31daf7a4f4cd6045ecf010efa6 (diff)
downloadqmmp-76f436c36cdec74e73c12cea8d81051a7d75ec96.tar.gz
qmmp-76f436c36cdec74e73c12cea8d81051a7d75ec96.tar.bz2
qmmp-76f436c36cdec74e73c12cea8d81051a7d75ec96.zip
added multichannel support
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@4530 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src/plugins/Output/alsa')
-rw-r--r--src/plugins/Output/alsa/outputalsa.cpp44
-rw-r--r--src/plugins/Output/alsa/outputalsa.h9
2 files changed, 46 insertions, 7 deletions
diff --git a/src/plugins/Output/alsa/outputalsa.cpp b/src/plugins/Output/alsa/outputalsa.cpp
index 5774579f5..f12f02060 100644
--- a/src/plugins/Output/alsa/outputalsa.cpp
+++ b/src/plugins/Output/alsa/outputalsa.cpp
@@ -44,6 +44,18 @@ OutputALSA::OutputALSA() : m_inited(false)
m_prebuf_size = 0;
m_prebuf_fill = 0;
m_can_pause = false;
+
+ m_alsa_channels[SND_CHMAP_NA] = Qmmp::CHAN_NULL;
+ m_alsa_channels[SND_CHMAP_MONO] = Qmmp::CHAN_FRONT_CENTER;
+ m_alsa_channels[SND_CHMAP_FL] = Qmmp::CHAN_FRONT_LEFT;
+ m_alsa_channels[SND_CHMAP_FR] = Qmmp::CHAN_FRONT_RIGHT;
+ m_alsa_channels[SND_CHMAP_RL] = Qmmp::CHAN_REAR_LEFT;
+ m_alsa_channels[SND_CHMAP_RR] = Qmmp::CHAN_REAR_RIGHT;
+ m_alsa_channels[SND_CHMAP_FC] = Qmmp::CHAN_FRONT_CENTER;
+ m_alsa_channels[SND_CHMAP_LFE] = Qmmp::CHAN_LFE;
+ m_alsa_channels[SND_CHMAP_SL] = Qmmp::CHAN_SIDE_LEFT;
+ m_alsa_channels[SND_CHMAP_SR] = Qmmp::CHAN_SIDE_RIGHT;
+ m_alsa_channels[SND_CHMAP_RC] = Qmmp::CHAN_REAR_CENTER;
}
OutputALSA::~OutputALSA()
@@ -52,7 +64,7 @@ OutputALSA::~OutputALSA()
free (pcm_name);
}
-bool OutputALSA::initialize(quint32 freq, int chan, Qmmp::AudioFormat format)
+bool OutputALSA::initialize(quint32 freq, ChannelMap map, Qmmp::AudioFormat format)
{
m_inited = false;
@@ -141,12 +153,17 @@ bool OutputALSA::initialize(quint32 freq, int chan, Qmmp::AudioFormat format)
qWarning("OutputALSA: The rate %d Hz is not supported by your hardware.\n==> Using %d Hz instead.", rate, exact_rate);
rate = exact_rate;
}
- uint c = chan;
+ uint c = map.count();
if ((err = snd_pcm_hw_params_set_channels_near(pcm_handle, hwparams, &c)) < 0)
{
qWarning("OutputALSA: Error setting channels: %s", snd_strerror(err));
return false;
}
+ if (c != (uint)map.count())
+ {
+ qWarning("OutputALSA: The channel number %d is not supported by your hardware", map.count());
+ qWarning("==> Using %d instead.", c);
+ }
if ((err = snd_pcm_hw_params_set_period_time_near(pcm_handle, hwparams, &period_time ,0)) < 0)
{
qWarning("OutputALSA: Error setting period time: %s", snd_strerror(err));
@@ -190,11 +207,30 @@ bool OutputALSA::initialize(quint32 freq, int chan, Qmmp::AudioFormat format)
m_chunk_size = period_size;
m_can_pause = snd_pcm_hw_params_can_pause(hwparams) && use_pause;
qDebug("OutputALSA: can pause: %d", m_can_pause);
- configure(rate, chan, format); //apply configuration
+
+ //channel map configuration
+ snd_pcm_chmap_t *chmap = snd_pcm_get_chmap(pcm_handle);
+ if(!chmap)
+ {
+ qWarning("OutputALSA: Unable to receive current channel map: %s", snd_strerror(err));
+ return false;
+ }
+ char tmp[256];
+ memset(tmp,0,256);
+ snd_pcm_chmap_print(chmap, 256, tmp);
+ qDebug("OutputALSA: received channel map: %s",tmp);
+ ChannelMap out_map;
+ for(uint i = 0; i < chmap->channels; ++i)
+ {
+ if(m_alsa_channels.keys().contains(chmap->pos[i]))
+ out_map.append(m_alsa_channels.value(chmap->pos[i]));
+ else
+ out_map.append(Qmmp::CHAN_NULL);
+ }
+ configure(exact_rate, out_map, format); //apply configuration
//create alsa prebuffer;
m_prebuf_size = 2 * snd_pcm_frames_to_bytes(pcm_handle, m_chunk_size); //buffer for two periods
m_prebuf = (uchar *)malloc(m_prebuf_size);
-
m_inited = true;
return true;
}
diff --git a/src/plugins/Output/alsa/outputalsa.h b/src/plugins/Output/alsa/outputalsa.h
index 1600e3b29..d378b813c 100644
--- a/src/plugins/Output/alsa/outputalsa.h
+++ b/src/plugins/Output/alsa/outputalsa.h
@@ -18,8 +18,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#ifndef OUTPUTALSA_H
-#define OUTPUTALSA_H
+#ifndef OUTPUTALSA_H
+#define OUTPUTALSA_H
class OutputALSA;
@@ -28,6 +28,7 @@ extern "C"
#include <alsa/asoundlib.h>
}
+#include <QHash>
#include <qmmp/output.h>
#include <qmmp/volume.h>
@@ -38,7 +39,7 @@ public:
OutputALSA();
~OutputALSA();
- bool initialize(quint32, int, Qmmp::AudioFormat format);
+ bool initialize(quint32, ChannelMap map, Qmmp::AudioFormat format);
//output api
qint64 latency();
qint64 writeAudio(unsigned char *data, qint64 maxSize);
@@ -63,6 +64,8 @@ private:
qint64 m_prebuf_size;
qint64 m_prebuf_fill;
bool m_can_pause;
+ //channel conversions
+ QHash <quint16, Qmmp::ChannelPosition> m_alsa_channels;
};
class VolumeALSA : public Volume