diff options
Diffstat (limited to 'src/plugins')
| -rw-r--r-- | src/plugins/Effect/Effect.pro | 6 | ||||
| -rw-r--r-- | src/plugins/Effect/srconverter/srconverter.cpp | 8 | ||||
| -rw-r--r-- | src/plugins/Effect/srconverter/srconverter.h | 4 | ||||
| -rw-r--r-- | src/plugins/Input/Input.pro | 28 | ||||
| -rw-r--r-- | src/plugins/Input/flac/decoder_flac.cpp | 77 | ||||
| -rw-r--r-- | src/plugins/Input/flac/decoder_flac.h | 1 | ||||
| -rw-r--r-- | src/plugins/Input/mad/decoder_mad.cpp | 7 | ||||
| -rw-r--r-- | src/plugins/Output/Output.pro | 10 | ||||
| -rw-r--r-- | src/plugins/Output/alsa/outputalsa.cpp | 44 | ||||
| -rw-r--r-- | src/plugins/Output/alsa/outputalsa.h | 9 |
10 files changed, 155 insertions, 39 deletions
diff --git a/src/plugins/Effect/Effect.pro b/src/plugins/Effect/Effect.pro index 336647a4b..b073f08f3 100644 --- a/src/plugins/Effect/Effect.pro +++ b/src/plugins/Effect/Effect.pro @@ -1,15 +1,15 @@ include (../../../qmmp.pri) TEMPLATE = subdirs -SUBDIRS += crossfade stereo +#SUBDIRS += crossfade stereo contains(CONFIG, BS2B_PLUGIN){ -SUBDIRS += bs2b +#SUBDIRS += bs2b } unix { SUBDIRS += srconverter contains(CONFIG, LADSPA_PLUGIN){ - SUBDIRS += ladspa +# SUBDIRS += ladspa } } diff --git a/src/plugins/Effect/srconverter/srconverter.cpp b/src/plugins/Effect/srconverter/srconverter.cpp index fcd77bc04..324dbb051 100644 --- a/src/plugins/Effect/srconverter/srconverter.cpp +++ b/src/plugins/Effect/srconverter/srconverter.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007-2013 by Ilya Kotov * + * Copyright (C) 2007-2014 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -115,12 +115,12 @@ void SRConverter::applyEffect(Buffer *b) } } -void SRConverter::configure(quint32 freq, int chan, Qmmp::AudioFormat format) +void SRConverter::configure(quint32 freq, ChannelMap map, Qmmp::AudioFormat format) { freeSRC(); if(freq != m_overSamplingFs && format != Qmmp::PCM_S8) { - m_src_state = src_new(m_converter_type, chan, &m_srcError); + m_src_state = src_new(m_converter_type, map.count(), &m_srcError); if (m_src_state) { m_src_data.src_ratio = (float)m_overSamplingFs/(float)freq; @@ -129,7 +129,7 @@ void SRConverter::configure(quint32 freq, int chan, Qmmp::AudioFormat format) else qDebug("SRConverter: src_new(): %s", src_strerror(m_srcError)); } - Effect::configure(m_overSamplingFs, chan, format); + Effect::configure(m_overSamplingFs, map, format); m_sz = audioParameters().sampleSize(); } diff --git a/src/plugins/Effect/srconverter/srconverter.h b/src/plugins/Effect/srconverter/srconverter.h index f25ebc491..b214c866f 100644 --- a/src/plugins/Effect/srconverter/srconverter.h +++ b/src/plugins/Effect/srconverter/srconverter.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007-2013 by Ilya Kotov * + * Copyright (C) 2007-2014 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -34,7 +34,7 @@ public: virtual ~SRConverter(); void applyEffect(Buffer *b); - void configure(quint32 freq, int chan, Qmmp::AudioFormat format); + void configure(quint32 freq, ChannelMap map, Qmmp::AudioFormat format); private: void freeSRC(); diff --git a/src/plugins/Input/Input.pro b/src/plugins/Input/Input.pro index 9b00864e6..0149aa949 100644 --- a/src/plugins/Input/Input.pro +++ b/src/plugins/Input/Input.pro @@ -1,53 +1,53 @@ include(../../../qmmp.pri) -SUBDIRS += mad cue vorbis sndfile wavpack TEMPLATE = subdirs +SUBDIRS += mad #cue vorbis sndfile wavpack contains(CONFIG, FLAC_PLUGIN){ SUBDIRS += flac } contains(CONFIG, MUSEPACK_PLUGIN){ - SUBDIRS += mpc +# SUBDIRS += mpc } contains(CONFIG, MODPLUG_PLUGIN){ - SUBDIRS += modplug +# SUBDIRS += modplug } contains(CONFIG, FFMPEG_PLUGIN){ - contains(CONFIG, FFMPEG_LEGACY){ - SUBDIRS += ffmpeg_legacy - }else{ - SUBDIRS += ffmpeg - } +# contains(CONFIG, FFMPEG_LEGACY){ +# SUBDIRS += ffmpeg_legacy +# }else{ +# SUBDIRS += ffmpeg +# } } contains(CONFIG, GME_PLUGIN){ - SUBDIRS += gme +# SUBDIRS += gme } contains(CONFIG, OPUS_PLUGIN){ - SUBDIRS += opus +# SUBDIRS += opus } contains(CONFIG, CDAUDIO_PLUGIN){ - SUBDIRS += cdaudio +# SUBDIRS += cdaudio } contains(CONFIG, SID_PLUGIN){ - SUBDIRS += sid +# SUBDIRS += sid } unix{ contains(CONFIG, AAC_PLUGIN){ - SUBDIRS += aac +# SUBDIRS += aac } contains(CONFIG, WILDMIDI_PLUGIN){ - SUBDIRS += wildmidi +# SUBDIRS += wildmidi } diff --git a/src/plugins/Input/flac/decoder_flac.cpp b/src/plugins/Input/flac/decoder_flac.cpp index acd76f159..4dfca6839 100644 --- a/src/plugins/Input/flac/decoder_flac.cpp +++ b/src/plugins/Input/flac/decoder_flac.cpp @@ -393,17 +393,25 @@ bool DecoderFLAC::initialize() data()->ok = 0; return false; } + ChannelMap channel_map = findChannelMap(data()->channels); + + if(channel_map.isEmpty()) + { + qWarning("DecoderFLAC: unsupported number of channels: %d", data()->channels); + return false; + } + switch(data()->bits_per_sample) { case 8: - configure(data()->sample_rate, data()->channels, Qmmp::PCM_S8); + configure(data()->sample_rate, channel_map, Qmmp::PCM_S8); break; case 16: - configure(data()->sample_rate, data()->channels, Qmmp::PCM_S16LE); + configure(data()->sample_rate, channel_map, Qmmp::PCM_S16LE); break; case 24: case 32: - configure(data()->sample_rate, data()->channels, Qmmp::PCM_S32LE); + configure(data()->sample_rate, channel_map, Qmmp::PCM_S32LE); break; default: return false; @@ -555,3 +563,66 @@ uint DecoderFLAC::findID3v2(char *data, ulong size) //retuns ID3v2 tag size } return 0; } + +ChannelMap DecoderFLAC::findChannelMap(int channels) +{ + ChannelMap map; + switch (channels) + { + case 1: + map << Qmmp::CHAN_FRONT_LEFT; + break; + case 2: + map << Qmmp::CHAN_FRONT_LEFT + << Qmmp::CHAN_FRONT_RIGHT; + break; + case 3: + map << Qmmp::CHAN_FRONT_LEFT + << Qmmp::CHAN_FRONT_RIGHT + << Qmmp::CHAN_FRONT_CENTER; + break; + case 4: + map << Qmmp::CHAN_FRONT_LEFT + << Qmmp::CHAN_FRONT_RIGHT + << Qmmp::CHAN_REAR_LEFT + << Qmmp::CHAN_REAR_RIGHT; + break; + case 5: + map << Qmmp::CHAN_FRONT_LEFT + << Qmmp::CHAN_FRONT_RIGHT + << Qmmp::CHAN_FRONT_CENTER + << Qmmp::CHAN_REAR_LEFT + << Qmmp::CHAN_REAR_RIGHT; + break; + case 6: + map << Qmmp::CHAN_FRONT_LEFT + << Qmmp::CHAN_FRONT_RIGHT + << Qmmp::CHAN_FRONT_CENTER + << Qmmp::CHAN_LFE + << Qmmp::CHAN_REAR_LEFT + << Qmmp::CHAN_REAR_RIGHT; + break; + case 7: + map << Qmmp::CHAN_FRONT_LEFT + << Qmmp::CHAN_FRONT_RIGHT + << Qmmp::CHAN_FRONT_CENTER + << Qmmp::CHAN_LFE + << Qmmp::CHAN_REAR_CENTER + << Qmmp::CHAN_SIDE_LEFT + << Qmmp::CHAN_SIDE_RIGHT; + break; + case 8: + map << Qmmp::CHAN_FRONT_LEFT + << Qmmp::CHAN_FRONT_RIGHT + << Qmmp::CHAN_FRONT_CENTER + << Qmmp::CHAN_LFE + << Qmmp::CHAN_REAR_LEFT + << Qmmp::CHAN_REAR_RIGHT + << Qmmp::CHAN_SIDE_LEFT + << Qmmp::CHAN_SIDE_RIGHT; + break; + default: + ; + } + return map; +} diff --git a/src/plugins/Input/flac/decoder_flac.h b/src/plugins/Input/flac/decoder_flac.h index e64e376eb..4b4a2f668 100644 --- a/src/plugins/Input/flac/decoder_flac.h +++ b/src/plugins/Input/flac/decoder_flac.h @@ -82,6 +82,7 @@ private: // helper functions void deinit(); uint findID3v2(char *data, ulong size); //retuns ID3v2 tag size + ChannelMap findChannelMap(int channels); struct flac_data *m_data; qint64 length_in_bytes; diff --git a/src/plugins/Input/mad/decoder_mad.cpp b/src/plugins/Input/mad/decoder_mad.cpp index b4087c06b..08b2486fb 100644 --- a/src/plugins/Input/mad/decoder_mad.cpp +++ b/src/plugins/Input/mad/decoder_mad.cpp @@ -120,7 +120,12 @@ bool DecoderMAD::initialize() mad_frame_mute (&m_frame); m_stream.next_frame = 0; m_stream.sync = 0; - configure(m_freq, m_channels, Qmmp::PCM_S16LE); + ChannelMap map; + if(m_channels == 1) + map << Qmmp::CHAN_FRONT_LEFT; + else + map << Qmmp::CHAN_FRONT_LEFT << Qmmp::CHAN_FRONT_RIGHT; + configure(m_freq, map, Qmmp::PCM_S16LE); m_inited = true; return true; } diff --git a/src/plugins/Output/Output.pro b/src/plugins/Output/Output.pro index d07513257..7dc1f0ddb 100644 --- a/src/plugins/Output/Output.pro +++ b/src/plugins/Output/Output.pro @@ -4,20 +4,20 @@ TEMPLATE = subdirs win32:SUBDIRS += waveout win32:SUBDIRS += directsound -SUBDIRS += null +#SUBDIRS += null unix{ contains(CONFIG, JACK_PLUGIN){ - SUBDIRS += jack +# SUBDIRS += jack } contains(CONFIG, OSS_PLUGIN){ - SUBDIRS += oss +# SUBDIRS += oss } contains(CONFIG, PULSE_AUDIO_PLUGIN){ - SUBDIRS += pulseaudio +# SUBDIRS += pulseaudio } contains(CONFIG, ALSA_PLUGIN){ @@ -25,7 +25,7 @@ contains(CONFIG, ALSA_PLUGIN){ } contains(CONFIG, OSS4_PLUGIN){ - SUBDIRS += oss4 +# SUBDIRS += oss4 } } 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 |
