From ba91edcc600a84fb3d3fc00f68454d2b0fc5063f Mon Sep 17 00:00:00 2001
From: tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>
Date: Thu, 25 Mar 2010 17:53:28 +0000
Subject: Add support for ALSA plugins to kmix Patch courtesy of
 ledest@gmail.com and Michael Shigorin

git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1107453 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
---
 kmix/kmix-platforms.cpp | 18 ++++++++++--------
 kmix/mixer.cpp          |  5 +++++
 kmix/mixer.h            |  1 +
 kmix/mixer_alsa.h       |  7 +++++++
 kmix/mixer_alsa9.cpp    | 30 ++++++++++++++++++++++++------
 kmix/mixer_backend.cpp  | 25 +++++++++++++++++++++++++
 kmix/mixer_backend.h    | 12 ++++++++++++
 kmix/mixer_oss.cpp      |  2 +-
 kmix/mixertoolbox.cpp   | 16 +++++++++++++++-
 9 files changed, 100 insertions(+), 16 deletions(-)

diff --git a/kmix/kmix-platforms.cpp b/kmix/kmix-platforms.cpp
index d7d57334..222119eb 100644
--- a/kmix/kmix-platforms.cpp
+++ b/kmix/kmix-platforms.cpp
@@ -108,42 +108,44 @@
 
 typedef Mixer_Backend *getMixerFunc( int device );
 typedef QString getDriverNameFunc( );
+typedef DevIterator* getDevIteratorFunc( );
 
 struct MixerFactory {
     getMixerFunc *getMixer;
     getDriverNameFunc *getDriverName;
+    getDevIteratorFunc *getDevIterator;
 };
 
 MixerFactory g_mixerFactories[] = {
 
 #if defined(NAS_MIXER)
-    { NAS_getMixer, 0 },
+    { NAS_getMixer, NULL, NULL },
 #endif
 
 #if defined(SUN_MIXER)
-    { SUN_getMixer, SUN_getDriverName },
+    { SUN_getMixer, SUN_getDriverName, NULL },
 #endif
 
 #if defined(IRIX_MIXER)
-    { IRIX_getMixer, IRIX_getDriverName },
+    { IRIX_getMixer, IRIX_getDriverName, NULL },
 #endif
 
 #if defined(ALSA_MIXER)
-    { ALSA_getMixer, ALSA_getDriverName },
+    { ALSA_getMixer, ALSA_getDriverName, ALSA_getDevIterator },
 #endif
 
 #if defined(OSS4_MIXER)
-    { OSS4_getMixer, OSS4_getDriverName },
+    { OSS4_getMixer, OSS4_getDriverName, NULL },
 #endif
 
 #if defined(OSS_MIXER)
-    { OSS_getMixer, OSS_getDriverName },
+    { OSS_getMixer, OSS_getDriverName, NULL },
 #endif
 
 #if defined(HPUX_MIXER)
-    { HPUX_getMixer, HPUX_getDriverName },
+    { HPUX_getMixer, HPUX_getDriverName, NULL },
 #endif
 
-    { 0, 0 }
+    { NULL, NULL, NULL }
 };
 
diff --git a/kmix/mixer.cpp b/kmix/mixer.cpp
index 84d078f2..116e6c23 100644
--- a/kmix/mixer.cpp
+++ b/kmix/mixer.cpp
@@ -347,6 +347,11 @@ QString Mixer::mixerName()
   return _mixerBackend->m_mixerName;
 }
 
+int Mixer::devnum()
+{
+  return _mixerBackend->m_devnum;
+}
+
 QString Mixer::driverName( int driver )
 {
     getDriverNameFunc *f = g_mixerFactories[driver].getDriverName;
diff --git a/kmix/mixer.h b/kmix/mixer.h
index bf8fdda0..1a94dba6 100644
--- a/kmix/mixer.h
+++ b/kmix/mixer.h
@@ -82,6 +82,7 @@ class Mixer : public QObject, virtual public MixerIface
       QString& stateMessage() const;
 
       virtual QString mixerName();
+      virtual int devnum();
 
       // Returns the name of the driver, e.g. "OSS" or "ALSA0.9"
       static QString driverName(int num);
diff --git a/kmix/mixer_alsa.h b/kmix/mixer_alsa.h
index da04e372..0d73dc77 100644
--- a/kmix/mixer_alsa.h
+++ b/kmix/mixer_alsa.h
@@ -50,4 +50,11 @@ class Mixer_ALSA : public Mixer_Backend
 
 };
 
+class ALSA_DevIterator : public DevIterator
+{
+	public:
+		ALSA_DevIterator();
+		virtual void next();
+};
+
 #endif
diff --git a/kmix/mixer_alsa9.cpp b/kmix/mixer_alsa9.cpp
index d778510b..751d5f9e 100644
--- a/kmix/mixer_alsa9.cpp
+++ b/kmix/mixer_alsa9.cpp
@@ -114,12 +114,8 @@ Mixer_ALSA::open()
     snd_mixer_selem_id_alloca( &sid );
 
     // Card information
-    if( m_devnum == -1 )
-        m_devnum = 0;
-    if ( (unsigned)m_devnum > 31 )
-	devName = "default";
-    else
-	devName = QString( "hw:%1" ).arg( m_devnum );
+    if ((unsigned)m_devnum > 31) m_devnum = -1;
+    devName = m_devnum == -1 ? "default" : QString("hw:%1").arg(m_devnum);
 
     QString probeMessage;
 
@@ -146,6 +142,8 @@ Mixer_ALSA::open()
     //mixer_device_name = snd_ctl_card_info_get_mixername( hw_info );
     // Copy the name of kmix mixer from card name (mixername is rumoured to be not that good)
     m_mixerName = mixer_card_name;
+    if (m_devnum == -1) m_devnum = snd_card_get_index(snd_ctl_card_info_get_id(hw_info));
+    if (m_devnum < 0) m_devnum = -1;
 
     snd_ctl_close( ctl_handle );
 
@@ -826,3 +824,23 @@ ALSA_getDriverName()
 }
 
 
+ALSA_DevIterator::ALSA_DevIterator()
+{
+	N = -1;
+	NMax = 31;
+}
+
+void ALSA_DevIterator::next()
+{
+#if 0
+	int rc = snd_card_next(&N);
+	if (rc || (N == -1)) N = NMax + 1;
+#else
+	if ((snd_card_next(&N) != 0) || (N == -1)) N = NMax + 1;
+#endif
+}
+
+DevIterator* ALSA_getDevIterator()
+{
+	return new ALSA_DevIterator();
+}
diff --git a/kmix/mixer_backend.cpp b/kmix/mixer_backend.cpp
index bc213fc4..0ad262b7 100644
--- a/kmix/mixer_backend.cpp
+++ b/kmix/mixer_backend.cpp
@@ -145,3 +145,28 @@ QString Mixer_Backend::errorText(int mixer_error)
   return l_s_errmsg;
 }
 
+
+DevIterator::DevIterator()
+{
+  N = 0;
+  NMax = 19;
+}
+
+void DevIterator::next()
+{
+  N++;
+}
+
+int DevIterator::getdev()
+{
+  return N;
+}
+
+bool DevIterator::end()
+{
+  return N > NMax;
+}
+
+DevIterator::~DevIterator()
+{
+}
diff --git a/kmix/mixer_backend.h b/kmix/mixer_backend.h
index 7023ac46..f9823a78 100644
--- a/kmix/mixer_backend.h
+++ b/kmix/mixer_backend.h
@@ -101,4 +101,16 @@ protected:
   MixDevice* m_recommendedMaster;
 };
 
+class DevIterator
+{
+public:
+    DevIterator();
+    virtual ~DevIterator();
+    virtual void next();
+    virtual int getdev();
+    virtual bool end();
+protected:
+    int N, NMax;
+};
+
 #endif
diff --git a/kmix/mixer_oss.cpp b/kmix/mixer_oss.cpp
index 299b5464..c39c05b1 100644
--- a/kmix/mixer_oss.cpp
+++ b/kmix/mixer_oss.cpp
@@ -133,7 +133,7 @@ int Mixer_OSS::open()
                   readVolumeFromHW( idx, vol );
                   MixDevice* md =
                     new MixDevice( idx, vol, recmask & ( 1 << idx ), true,
-                                   i18n(MixerDevNames[idx]),
+                                   MixerDevNames[idx],
                                    MixerChannelTypes[idx]);
                   md->setRecSource( isRecsrcHW( idx ) );
                   m_mixDevices.append( md );
diff --git a/kmix/mixertoolbox.cpp b/kmix/mixertoolbox.cpp
index 0480955b..38b404ac 100644
--- a/kmix/mixertoolbox.cpp
+++ b/kmix/mixertoolbox.cpp
@@ -99,11 +99,25 @@ void MixerToolBox::initMixer(QPtrList<Mixer> &mixers, bool multiDriverMode, QStr
 	    // New: We don't try be that clever anymore. We now blindly scan 20 cards, as the clever
 	    // approach doesn't work for the one or other user.
 	    int devNumMax = 19;
-	    for( int dev=0; dev<=devNumMax; dev++ )
+	    getDevIteratorFunc* f = g_mixerFactories[drv].getDevIterator;
+	    for( DevIterator* I = f ? f() : new DevIterator(); !I->end(); I->next())
 	    {
+		int dev = I->getdev();
 		Mixer *mixer = new Mixer( drv, dev );
 		if ( mixer->isValid() ) {
 			mixer->open();
+			Mixer* m;
+			if (dev >= 0) {
+				for (m = mixers.first(); m; m = mixers.next())
+#if 0
+					if ((mixer->devnum() == m->devnum()) &&
+					    m->id().startsWith(mixer->driverName(drv) + "::", true))
+#else
+					if (mixer->devnum() == m->devnum())
+#endif
+						break;
+				if (m) continue;
+			}
 			mixers.append( mixer );
 			// Count mixer nums for every mixer name to identify mixers with equal names.
 			// This is for creating persistent (reusable) primary keys, which can safely
-- 
cgit v1.2.3

