kmix: improve detection of mixers (invalid mixers are no longer created and destroyed) and fix memory leak in case of detection of mixers that were already existing.

Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
feat/kmix/mixer-detection
Michele Calgaro 4 years ago
parent ed09d89f42
commit 337b217e99
Signed by: MicheleC
GPG Key ID: 2A75B7CA8ADED5CF

@ -72,6 +72,19 @@ TQPtrList<Mixer>& Mixer::mixers()
return s_mixers;
}
bool Mixer::isValid(int driver, int device)
{
getMixerFunc *mf = g_mixerFactories[driver].getMixer;
if (mf)
{
Mixer_Backend *mb = mf(device);
if (mb)
{
return mb->isValid();
}
}
return false;
}
Mixer::Mixer( int driver, int device ) : DCOPObject( "Mixer" )
{
@ -101,7 +114,6 @@ Mixer::Mixer( int driver, int device ) : DCOPObject( "Mixer" )
#endif
objid.prepend("Mixer");
DCOPObject::setObjId( objid );
}
Mixer::~Mixer() {

@ -55,6 +55,9 @@ class Mixer : public TQObject, virtual public MixerIface
static int numDrivers();
// check if a given driver/device is a valid mixer
static bool isValid(int driver, int device);
MixDevice* find(TQString& devPK);
void volumeSave( TDEConfig *config );
@ -166,9 +169,10 @@ class Mixer : public TQObject, virtual public MixerIface
private:
Mixer_Backend *_mixerBackend;
mutable bool _readSetFromHWforceUpdate;
static int _dcopID;
TQString _id;
TQString _masterDevicePK;
static int _dcopID;
static TQString _masterCard;
static TQString _masterCardDevice;
};

@ -56,7 +56,7 @@ extern MixerFactory g_mixerFactories[];
/**
* Scan for Mixers in the System. This is the method that implicitely fills the
* list of Mixer's, which is accesible via the static Mixer::mixer() method.
* list of Mixer's, which is accessible via the static Mixer::mixer() method.
* @par mixers The list where to add the found Mixers. This parameter is superfluous
* nowadays, as it is now really trivial to get it - just call the static
* Mixer::mixer() method.
@ -115,58 +115,58 @@ void MixerToolBox::initMixer(TQPtrList<Mixer> &mixers, bool multiDriverMode, TQS
// approach doesn't work for the one or other user.
int devNumMax = 19;
getDevIteratorFunc* f = g_mixerFactories[drv].getDevIterator;
for( DevIterator* I = f ? f() : new DevIterator(); !I->end(); I->next())
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
// be referenced (especially for config file access, so it is meant to be persistent!).
mixerNums[mixer->mixerName()]++;
// Create a useful PK
/* As we use "::" and ":" as separators, the parts %1,%2 and %3 may not
* contain it.
* %1, the driver name is from the KMix backends, it does not contain colons.
* %2, the mixer name, is typically coming from an OS driver. It could contain colons.
* %3, the mixer number, is a number: it does not contain colons.
*/
TQString mixerName = mixer->mixerName();
mixerName.replace(":","_");
TQString primaryKeyOfMixer = TQString("%1::%2:%3")
.arg(driverName)
.arg(mixerName)
.arg(mixerNums[mixer->mixerName()]);
// The following 3 replaces are for not messing up the config file
primaryKeyOfMixer.replace("]","_");
primaryKeyOfMixer.replace("[","_"); // not strictly neccesary, but lets play safe
primaryKeyOfMixer.replace(" ","_");
primaryKeyOfMixer.replace("=","_");
mixer->setID(primaryKeyOfMixer);
} // valid
else
// Check with backend if mixer is invalid
if (!Mixer::isValid(drv, dev))
{
continue;
}
// Check if mixer already exists
Mixer *mixer = new Mixer(drv, dev);
Mixer *m;
for (m = mixers.first(); m; m = mixers.next())
{
delete mixer;
mixer = 0;
} // invalid
if (mixer->devnum() == m->devnum())
{
break;
}
}
if (m)
{
delete mixer;
mixer = 0;
continue;
}
// New mixer found
mixer->open();
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
// be referenced (especially for config file access, so it is meant to be persistent!).
mixerNums[mixer->mixerName()]++;
// Create a useful PK
/* As we use "::" and ":" as separators, the parts %1,%2 and %3 may not
* contain it.
* %1, the driver name is from the KMix backends, it does not contain colons.
* %2, the mixer name, is typically coming from an OS driver. It could contain colons.
* %3, the mixer number, is a number: it does not contain colons.
*/
TQString mixerName = mixer->mixerName();
mixerName.replace(":","_");
TQString primaryKeyOfMixer = TQString("%1::%2:%3")
.arg(driverName)
.arg(mixerName)
.arg(mixerNums[mixer->mixerName()]);
// The following 3 replaces are for not messing up the config file
primaryKeyOfMixer.replace("]","_");
primaryKeyOfMixer.replace("[","_"); // not strictly necessary, but let's play safe
primaryKeyOfMixer.replace(" ","_");
primaryKeyOfMixer.replace("=","_");
mixer->setID(primaryKeyOfMixer);
/* Lets decide if we the autoprobing shall continue: */
// Lets decide if we the autoprobing shall continue
if ( multiDriverMode ) {
// trivial case: In multiDriverMode, we scan ALL 20 devs of ALL drivers
// so we have to do "nothing" in this case
@ -174,7 +174,7 @@ void MixerToolBox::initMixer(TQPtrList<Mixer> &mixers, bool multiDriverMode, TQS
else {
// In No-multiDriver-mode we only need to check after we reached devNumMax
if ( dev == devNumMax ) {
if ( Mixer::mixers().count() != 0 ) {
if ( mixers.count() != 0 ) {
// highest device number of driver and a Mixer => finished
autodetectionFinished = true;
}
@ -218,9 +218,9 @@ void MixerToolBox::initMixer(TQPtrList<Mixer> &mixers, bool multiDriverMode, TQS
// We have no master card yet. This actually only happens when there was
// not one defined in the kmixrc.
// So lets just set the first card as master card.
if (Mixer::mixers().count() > 0)
if (mixers.count() > 0)
{
Mixer *mixer = Mixer::mixers().first();
Mixer *mixer = mixers.first();
Mixer::setMasterCard(mixer->id());
MixSet ms = mixer->getMixSet();
for (MixDevice *md = ms.first(); md != 0; md = ms.next())
@ -243,7 +243,7 @@ void MixerToolBox::initMixer(TQPtrList<Mixer> &mixers, bool multiDriverMode, TQS
ref_hwInfoString += "\nExperimental multiple-Driver mode activated";
}
kdDebug(67100) << ref_hwInfoString << endl << "Total number of detected Mixers: " << Mixer::mixers().count() << endl;
kdDebug(67100) << ref_hwInfoString << endl << "Total number of detected Mixers: " << mixers.count() << endl;
//kdDebug(67100) << "OUT MixerToolBox::initMixer()"<<endl;
}

Loading…
Cancel
Save