diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2014-10-06 07:50:56 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2014-10-06 07:50:56 +0000 |
| commit | 76f436c36cdec74e73c12cea8d81051a7d75ec96 (patch) | |
| tree | 03fe155b5311f6dccbf0dfb2a9cb0954484a138c /src/plugins/Output/alsa | |
| parent | 67e825df80708f31daf7a4f4cd6045ecf010efa6 (diff) | |
| download | qmmp-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.cpp | 44 | ||||
| -rw-r--r-- | src/plugins/Output/alsa/outputalsa.h | 9 |
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 |
