summaryrefslogtreecommitdiffstats
path: root/plugins/alsa-sound/alsa-sound-configuration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/alsa-sound/alsa-sound-configuration.cpp')
-rw-r--r--plugins/alsa-sound/alsa-sound-configuration.cpp353
1 files changed, 353 insertions, 0 deletions
diff --git a/plugins/alsa-sound/alsa-sound-configuration.cpp b/plugins/alsa-sound/alsa-sound-configuration.cpp
new file mode 100644
index 0000000..9a29e43
--- /dev/null
+++ b/plugins/alsa-sound/alsa-sound-configuration.cpp
@@ -0,0 +1,353 @@
+/***************************************************************************
+ alsa-sound-configuration.cpp - description
+ -------------------
+ begin : Thu Sep 30 2004
+ copyright : (C) 2004 by Martin Witte
+ email : witte@kawo1.rwth-aachen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <tqcheckbox.h>
+#include <tqgroupbox.h>
+#include <tqlayout.h>
+#include <tqscrollview.h>
+
+#include <kurlrequester.h>
+#include <knuminput.h>
+#include <klineedit.h>
+#include <kcombobox.h>
+#include <ktabwidget.h>
+#include <tdelocale.h>
+
+#include "alsa-mixer-element.h"
+#include "alsa-sound-configuration.h"
+#include "alsa-sound.h"
+
+
+AlsaSoundConfiguration::AlsaSoundConfiguration (TQWidget *parent, AlsaSoundDevice *dev)
+ : AlsaSoundConfigurationUI(parent),
+ m_SoundDevice (dev),
+ m_groupMixerLayout(NULL),
+ m_groupMixerScrollView(NULL),
+ m_groupMixerSubFrame(NULL),
+ m_dirty(true),
+ m_ignore_updates(false)
+{
+ TQObject::connect(m_comboPlaybackCard, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetDirty()));
+ TQObject::connect(m_comboCaptureCard, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetDirty()));
+ TQObject::connect(m_comboPlaybackDevice, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetDirty()));
+ TQObject::connect(m_comboCaptureDevice, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetDirty()));
+ TQObject::connect(editHWBufferSize, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetDirty()));
+ TQObject::connect(editBufferSize, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetDirty()));
+ TQObject::connect(chkDisablePlayback, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetDirty()));
+ TQObject::connect(chkDisableCapture, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetDirty()));
+
+ TQObject::connect(m_comboPlaybackCard, TQT_SIGNAL(activated(const TQString &)),
+ this, TQT_SLOT(slotPlaybackCardSelected(const TQString &)));
+ TQObject::connect(m_comboCaptureCard, TQT_SIGNAL(activated(const TQString &)),
+ this, TQT_SLOT(slotCaptureCardSelected(const TQString &)));
+
+ m_groupMixer->setColumnLayout(0, Qt::Horizontal );
+
+ TQHBoxLayout *tmp_layout = new TQHBoxLayout( m_groupMixer->layout() );
+
+ m_groupMixerScrollView = new TQScrollView (m_groupMixer);
+ m_groupMixerScrollView->setFrameShape(TQFrame::NoFrame);
+ m_groupMixerScrollView->setFrameShadow(TQFrame::Plain);
+ m_groupMixerScrollView->enableClipper(true);
+ m_groupMixerScrollView->setResizePolicy(TQScrollView::AutoOneFit);
+ //m_groupMixerScrollView->setHScrollBarMode(TQScrollView::AlwaysOn);
+
+ tmp_layout->addWidget(m_groupMixerScrollView);
+
+
+ int card = -1;
+ int ret = 0;
+ int idx_playback = 0;
+ int idx_capture = 0;
+ while ((ret = snd_card_next(&card)) == 0) {
+ char *name = NULL;
+ if (card >= 0 && snd_card_get_longname(card, &name) == 0) {
+ if (name) {
+ m_name2card[name] = card;
+ m_card2name[card] = name;
+ if (listSoundDevices(NULL, NULL, NULL, NULL, card, SND_PCM_STREAM_PLAYBACK)) {
+ m_comboPlaybackCard->insertItem(name);
+ m_playbackCard2idx[card] = idx_playback++;
+ }
+ if (listSoundDevices(NULL, NULL, NULL, NULL, card, SND_PCM_STREAM_CAPTURE)) {
+ m_comboCaptureCard->insertItem(name);
+ m_captureCard2idx[card] = idx_capture++;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+
+ slotCancel();
+}
+
+
+AlsaSoundConfiguration::~AlsaSoundConfiguration ()
+{
+}
+
+
+void AlsaSoundConfiguration::slotPlaybackCardSelected(const TQString &cardname)
+{
+ if (!m_name2card.contains(cardname))
+ return;
+
+ listSoundDevices(m_comboPlaybackDevice, &m_playbackDeviceName2dev, &m_dev2playbackDeviceName, &m_playbackDevice2idx, m_name2card[cardname], SND_PCM_STREAM_PLAYBACK);
+}
+
+
+void AlsaSoundConfiguration::slotCaptureCardSelected(const TQString &cardname)
+{
+ if (!m_name2card.contains(cardname))
+ return;
+
+ saveCaptureMixerSettings();
+
+ listSoundDevices(m_comboCaptureDevice, &m_captureDeviceName2dev, &m_dev2captureDeviceName, &m_captureDevice2idx, m_name2card[cardname], SND_PCM_STREAM_CAPTURE);
+
+ m_currentCaptureCard = m_name2card[cardname];
+
+ TQStringList vol_list, sw_list, all_list;
+ TQMap<TQString, AlsaMixerElement> vol_ch2id, sw_ch2id;
+ AlsaSoundDevice::getCaptureMixerChannels(m_name2card[cardname], NULL, vol_list, vol_ch2id, sw_list, sw_ch2id, &all_list);
+
+ for (TQMapIterator<TQString, QAlsaMixerElement*> it = m_MixerElements.begin(); it != m_MixerElements.end(); ++it) {
+ delete *it;
+ }
+ m_MixerElements.clear();
+
+ if (m_groupMixerSubFrame)
+ delete m_groupMixerSubFrame;
+
+ m_groupMixerSubFrame = new TQFrame(m_groupMixerScrollView->viewport());
+ m_groupMixerSubFrame->setSizePolicy(TQSizePolicy::Maximum, TQSizePolicy::Maximum);
+ m_groupMixerScrollView->addChild(m_groupMixerSubFrame);
+
+ int rows = 1;
+ int cols = (all_list.count()+rows-1)/rows;
+ m_groupMixerLayout = new TQGridLayout( m_groupMixerSubFrame, rows, cols, 0, 0 );
+ m_groupMixerLayout->setAlignment( TQt::AlignBottom );
+
+ int idx = 0;
+ for (TQValueListConstIterator<TQString> it = all_list.begin(); it != all_list.end(); ++it, ++idx) {
+ QAlsaMixerElement *e = new QAlsaMixerElement(m_groupMixerSubFrame, *it,
+ sw_list.contains(*it), vol_list.contains(*it));
+ TQObject::connect(e, TQT_SIGNAL(sigDirty()), this, TQT_SLOT(slotSetDirty()));
+ m_groupMixerLayout->addWidget(e, idx > cols, idx % cols);
+ e->show();
+ m_MixerElements.insert(*it, e);
+ }
+ restoreCaptureMixerSettings();
+ m_groupMixerSubFrame->show();
+}
+
+void AlsaSoundConfiguration::saveCaptureMixerSettings()
+{
+ for (TQMapIterator<TQString, QAlsaMixerElement*> it = m_MixerElements.begin(); it != m_MixerElements.end(); ++it) {
+ const TQString &name = it.key();
+ int card = m_currentCaptureCard;
+ TQString id = AlsaConfigMixerSetting::getIDString(card, name);
+ QAlsaMixerElement *e = *it;
+ float vol = e->getVolume();
+ bool use = e->getOverride();
+ bool active = e->getActive();
+ e->slotResetDirty();
+ m_MixerSettings[id] = AlsaConfigMixerSetting(card,name,use,active,vol);
+ }
+}
+
+void AlsaSoundConfiguration::restoreCaptureMixerSettings()
+{
+ for (TQMapIterator<TQString, QAlsaMixerElement*> it = m_MixerElements.begin(); it != m_MixerElements.end(); ++it) {
+ const TQString &name = it.key();
+ int card = m_currentCaptureCard;
+ TQString id = AlsaConfigMixerSetting::getIDString(card, name);
+ QAlsaMixerElement *e = *it;
+
+ if (m_MixerSettings.contains(id)) {
+ const AlsaConfigMixerSetting &s = m_MixerSettings[id];
+ e->setVolume(s.m_volume);
+ e->setOverride(s.m_use);
+ e->setActive(s.m_active);
+ e->slotResetDirty();
+ } else {
+ if (name == "ADC") {
+ e->setOverride(true);
+ e->setActive(true);
+ e->setVolume(1.0);
+ }
+ else if (name == "Digital") {
+ e->setOverride(true);
+ e->setActive(true);
+ e->setVolume(1.0);
+ }
+ else if (name == "Wave") {
+ e->setOverride(true);
+ e->setActive(false);
+ e->setVolume(0);
+ }
+ else if (name == "Capture") {
+ e->setOverride(true);
+ e->setActive(true);
+ e->setVolume(0.01);
+ }
+ e->slotSetDirty();
+ }
+ }
+}
+
+int AlsaSoundConfiguration::listSoundDevices(KComboBox *combobox, TQMap<TQString, int> *devname2dev, TQMap<int, TQString> *dev2devname, TQMap<int, int> *dev2idx, int card, snd_pcm_stream_t stream)
+{
+ snd_ctl_t *handle = NULL;
+ int dev = -1;
+ snd_ctl_card_info_t *info = NULL;
+ snd_pcm_info_t *pcminfo = NULL;
+
+ snd_ctl_card_info_alloca(&info);
+ snd_pcm_info_alloca (&pcminfo);
+
+ TQString ctlname = "hw:"+TQString::number(card);
+
+ if (combobox)
+ combobox->clear();
+ if (devname2dev)
+ devname2dev->clear();
+ if (dev2devname)
+ dev2devname->clear();
+ if (dev2idx)
+ dev2idx->clear();
+
+ int count = 0;
+
+ if (snd_ctl_open (&handle, ctlname.ascii(), 0) == 0) {
+ if (snd_ctl_card_info(handle, info) == 0) {
+
+ dev = -1;
+ while (1) {
+ if (snd_ctl_pcm_next_device(handle, &dev) < 0) {
+ //logError("snd_ctl_pcm_next_device");
+ }
+ if (dev < 0)
+ break;
+ snd_pcm_info_set_device(pcminfo, dev);
+ snd_pcm_info_set_subdevice(pcminfo, 0);
+ snd_pcm_info_set_stream(pcminfo, stream);
+ int err = 0;
+ if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
+ if (err != -ENOENT) {
+ //logError(TQString("control digital audio info (%1): %2").arg(card).arg(snd_strerror(err)));
+ }
+ continue;
+ }
+ const char *dev_name = snd_pcm_info_get_name(pcminfo);
+ TQString devname = i18n("context-card-plus-device-number", "%1 device %2").arg(dev_name).arg(dev);
+ if (combobox)
+ combobox->insertItem(devname);
+ if (devname2dev)
+ (*devname2dev)[devname] = dev;
+ if (dev2devname)
+ (*dev2devname)[dev] = devname;
+ if (dev2idx)
+ (*dev2idx)[dev] = count;
+ ++count;
+ }
+ }
+ snd_ctl_close(handle);
+ }
+ return count;
+}
+
+void AlsaSoundConfiguration::slotOK()
+{
+ if (!m_dirty)
+ return;
+
+ if (m_SoundDevice) {
+ m_SoundDevice->setHWBufferSize ( editHWBufferSize ->value() * 1024);
+ m_SoundDevice->setBufferSize ( editBufferSize ->value() * 1024);
+ m_SoundDevice->enablePlayback (!chkDisablePlayback->isChecked());
+ m_SoundDevice->enableCapture (!chkDisableCapture ->isChecked());
+
+ int card = m_name2card[m_comboPlaybackCard->currentText()];
+ int device = m_playbackDeviceName2dev[m_comboPlaybackDevice->currentText()];
+ m_SoundDevice->setPlaybackDevice( card, device);
+ card = m_name2card[m_comboCaptureCard->currentText()];
+ device = m_captureDeviceName2dev[m_comboCaptureDevice->currentText()];
+ m_SoundDevice->setCaptureDevice ( card, device);
+
+ saveCaptureMixerSettings();
+ m_SoundDevice->setCaptureMixerSettings(m_MixerSettings);
+ }
+ m_dirty = false;
+}
+
+
+void AlsaSoundConfiguration::slotCancel()
+{
+ if (!m_dirty)
+ return;
+ m_ignore_updates = true;
+
+ int card = m_SoundDevice ? m_SoundDevice->getPlaybackCard() : 0;
+ int dev = m_SoundDevice ? m_SoundDevice->getPlaybackDevice() : 0;
+ m_comboPlaybackCard ->setCurrentItem(m_playbackCard2idx[card]);
+ slotPlaybackCardSelected(m_comboPlaybackCard->currentText());
+ m_comboPlaybackDevice->setCurrentItem(m_playbackDevice2idx[dev]);
+
+ card = m_SoundDevice ? m_SoundDevice->getCaptureCard() : 0;
+ dev = m_SoundDevice ? m_SoundDevice->getCaptureDevice() : 0;
+ m_comboCaptureCard ->setCurrentItem(m_captureCard2idx[card]);
+ slotCaptureCardSelected(m_comboCaptureCard->currentText());
+ m_comboCaptureDevice->setCurrentItem(m_captureDevice2idx[dev]);
+
+ //IErrorLogClient::staticLogDebug(TQString("capture: card = %1(%2), dev = %3").arg(card).arg(m_captureCard2idx[card]).arg(dev));
+
+ editHWBufferSize ->setValue (m_SoundDevice ? m_SoundDevice->getHWBufferSize()/1024 : 4);
+ editBufferSize ->setValue (m_SoundDevice ? m_SoundDevice->getBufferSize()/1024 : 4);
+ chkDisablePlayback->setChecked(m_SoundDevice ? !m_SoundDevice->isPlaybackEnabled() : false);
+ chkDisableCapture ->setChecked(m_SoundDevice ? !m_SoundDevice->isCaptureEnabled() : false);
+
+ //IErrorLogClient::staticLogDebug(TQString("capture: card = %1").arg(m_comboCaptureCard->currentText()));
+
+
+ if (m_SoundDevice)
+ m_MixerSettings = m_SoundDevice->getCaptureMixerSettings();
+ else
+ m_MixerSettings.clear();
+ restoreCaptureMixerSettings();
+
+ m_ignore_updates = false;
+ m_dirty = false;
+}
+
+
+void AlsaSoundConfiguration::slotUpdateConfig()
+{
+ slotSetDirty();
+ slotCancel();
+}
+
+void AlsaSoundConfiguration::slotSetDirty()
+{
+ if (!m_dirty && !m_ignore_updates) {
+ m_dirty = true;
+ //emit sigDirty();
+ }
+}
+
+#include "alsa-sound-configuration.moc"