KMix: Dynamism in tracing of appearance new audio-controllers

Signed-off-by: Roman Savochenko <roman@home.home>
feat/kmix-dyn
Roman Savochenko 6 months ago
parent 268aed5464
commit 7173de9b1d

@ -4,6 +4,7 @@
* Copyright (C) 2000 Stefan Schimanski <schimmi@kde.org>
* Copyright (C) 2001 Preston Brown <pbrown@kde.org>
* Copyright (C) 2003 Sven Leiber <s.leiber@web.de>
* Copyright (C) 2020 Roman Savochenko <roman@oscada.org>
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
@ -98,12 +99,18 @@ KMixWindow::KMixWindow()
hide();
}
connect( kapp, TQT_SIGNAL( aboutToQuit()), TQT_SLOT( saveSettings()) );
mixersUpdTimer = new TQTimer();
connect(mixersUpdTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(mixersUpdate()));
mixersUpdTimer->start(10000);
}
KMixWindow::~KMixWindow()
{
MixerToolBox::deinitMixer();
delete mixersUpdTimer;
MixerToolBox::deinitMixer(Mixer::mixers());
}
@ -136,6 +143,34 @@ KMixWindow::initActions()
createGUI( "kmixui.rc" );
}
void
KMixWindow::mixersUpdate()
{
//Do not update the mixers at the mixer window and the dock widget visibility
if(!m_dockWidget || isVisible() || (m_dockWidget->_dockAreaPopup && ((TQWidget*)m_dockWidget->_dockAreaPopup)->isVisible())) return;
//Detection the mixers configuration change
else {
TQPtrList<Mixer> tmpMix;
#ifdef WITH_KMIX_EXPERIMENTAL
MixerToolBox::initMixer(tmpMix, KMixSettings::multiDriver(), m_hwInfoString, true);
#else
MixerToolBox::initMixer(tmpMix, false, m_hwInfoString, true);
#endif
bool chMixers = (tmpMix.count() != Mixer::mixers().count());
MixerToolBox::deinitMixer(tmpMix);
if(!chMixers) return;
}
MixerToolBox::deinitMixer(Mixer::mixers());
#ifdef WITH_KMIX_EXPERIMENTAL
MixerToolBox::initMixer(Mixer::mixers(), KMixSettings::multiDriver(), m_hwInfoString);
#else
MixerToolBox::initMixer(Mixer::mixers(), false, m_hwInfoString);
#endif
initMixerWidgets();
updateDocking();
}
void
KMixWindow::initWidgets()
{
@ -271,6 +306,8 @@ void
KMixWindow::initMixerWidgets()
{
m_mixerWidgets.clear();
m_cMixer->clear();
mixerNameLayout->show();
int id=0;
Mixer *mixer;

@ -3,6 +3,7 @@
*
*
* Copyright (C) 2000 Stefan Schimanski <1Stein@gmx.de>
* Copyright (C) 2020 Roman Savochenko <roman@oscada.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -30,6 +31,7 @@
// include files for TQt
#include <tqstring.h>
#include <tqmap.h>
#include <tqtimer.h>
class TQHBox;
class TQWidgetStack;
@ -128,9 +130,11 @@ KMixWindow : public TDEMainWindow, virtual public KMixIface
KMixDockWidget *m_dockWidget;
TQString m_hwInfoString;
TQVBoxLayout *widgetsLayout;
TQTimer *mixersUpdTimer;
private slots:
//void removeMixerWidget( KMixerWidget *mw );
void mixersUpdate();
void slotHWInfo();
void showSelectedMixer( int mixer );
void configureGlobalShortcuts();

@ -4,6 +4,7 @@
*
* Copyright (C) 2000 Stefan Schimanski <schimmi@kde.org>
* Copyright (C) 2004 Christian Esken <esken@kde.org>
* Copyright (C) 2020 Roman Savochenko <roman@oscada.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -226,7 +227,7 @@ KMixApplet::~KMixApplet()
s_instCount--;
if ( s_instCount == 0)
{
MixerToolBox::deinitMixer();
MixerToolBox::deinitMixer(Mixer::mixers());
}
*/
}

@ -2,6 +2,7 @@
* kmixctrl - kmix volume save/restore utility
*
* Copyright (C) 2000 Stefan Schimanski <1Stein@gmx.de>
* Copyright (C) 2020 Roman Savochenko <roman@oscada.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -84,7 +85,7 @@ extern "C" KDE_EXPORT int kdemain(int argc, char *argv[])
mixer->volumeSave( TDEGlobal::config() );
}
MixerToolBox::deinitMixer();
MixerToolBox::deinitMixer(Mixer::mixers());
return 0;
}

@ -4,6 +4,7 @@
*
* Copyright (C) 1996-2004 Christian Esken - esken@kde.org
* 2002 Helio Chissini de Castro - helio@conectiva.com.br
* Copyright (C) 2017,2020 Roman Savochenko <roman@oscada.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -108,6 +109,7 @@ Mixer::~Mixer() {
// Close the mixer. This might also free memory, depending on the called backend method
close();
delete _pollingTimer;
delete _mixerBackend;
}
void Mixer::volumeSave( TDEConfig *config )

@ -6,6 +6,7 @@
* 1996-2000 Christian Esken <esken@kde.org>
* Sven Fischer <herpes@kawo2.rwth-aachen.de>
* 2002 - Helio Chissini de Castro <helio@conectiva.com.br>
* Copyright (C) 2017 Roman Savochenko <roman@oscada.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public

@ -6,6 +6,7 @@
*
* Copyright (C) 2002 Helio Chissini de Castro <helio@conectiva.com.br>
* 2004 Christian Esken <esken@kde.org>
* Copyright (C) 2020 Roman Savochenko <roman@oscada.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -107,11 +108,7 @@ Mixer_ALSA::open()
snd_ctl_t *ctl_handle;
snd_ctl_card_info_t *hw_info;
snd_ctl_card_info_alloca(&hw_info);
snd_mixer_elem_t *elem;
snd_mixer_selem_id_t *sid;
snd_mixer_selem_id_alloca( &sid );
snd_ctl_card_info_malloc(&hw_info);
// Card information
if ((unsigned)m_devnum > 31) m_devnum = -1;
@ -126,6 +123,7 @@ Mixer_ALSA::open()
{
kdDebug(67100) << probeMessage << "not found: snd_ctl_open err=" << snd_strerror(err) << endl;
//_stateMessage = errorText( Mixer::ERR_NODEV );
snd_ctl_card_info_free(hw_info);
return Mixer::ERR_OPEN;
}
@ -134,6 +132,7 @@ Mixer_ALSA::open()
kdDebug(67100) << probeMessage << "not found: snd_ctl_card_info err=" << snd_strerror(err) << endl;
//_stateMessage = errorText( Mixer::ERR_READ );
snd_ctl_close( ctl_handle );
snd_ctl_card_info_free(hw_info);
return Mixer::ERR_READ;
}
@ -155,6 +154,7 @@ Mixer_ALSA::open()
kdDebug(67100) << probeMessage << "not found: snd_mixer_open err=" << snd_strerror(err) << endl;
//errormsg( Mixer::ERR_NODEV );
_handle = 0;
snd_ctl_card_info_free(hw_info);
return Mixer::ERR_NODEV; // if we cannot open the mixer, we have no devices
}
//kdDebug(67100) << "OUT Mixer_ALSA snd_mixer_open()" << endl;
@ -163,6 +163,8 @@ Mixer_ALSA::open()
{
kdDebug(67100) << probeMessage << "not found: snd_mixer_attach err=" << snd_strerror(err) << endl;
//errormsg( Mixer::ERR_PERM );
close();
snd_ctl_card_info_free(hw_info);
return Mixer::ERR_OPEN;
}
@ -170,6 +172,8 @@ Mixer_ALSA::open()
{
kdDebug(67100) << probeMessage << "not found: snd_mixer_selem_register err=" << snd_strerror(err) << endl;
//errormsg( Mixer::ERR_READ );
close();
snd_ctl_card_info_free(hw_info);
return Mixer::ERR_READ;
}
@ -178,11 +182,15 @@ Mixer_ALSA::open()
kdDebug(67100) << probeMessage << "not found: snd_mixer_load err=" << snd_strerror(err) << endl;
//errormsg( Mixer::ERR_READ );
close();
snd_ctl_card_info_free(hw_info);
return Mixer::ERR_READ;
}
kdDebug(67100) << probeMessage << "found" << endl;
snd_mixer_elem_t *elem;
snd_mixer_selem_id_t *sid;
unsigned int mixerIdx = 0;
for ( elem = snd_mixer_first_elem( _handle ); elem; elem = snd_mixer_elem_next( elem ), mixerIdx++ )
{
@ -195,8 +203,7 @@ Mixer_ALSA::open()
continue;
}
sid = (snd_mixer_selem_id_t*)malloc(snd_mixer_selem_id_sizeof()); // I believe *we* must malloc it for ourself
snd_mixer_selem_id_malloc( &sid );
snd_mixer_selem_get_id( elem, sid );
bool canPlay = false;
@ -359,6 +366,8 @@ Mixer_ALSA::open()
}
if( !found )
{
close();
snd_ctl_card_info_free(hw_info);
return Mixer::ERR_INCOMPATIBLESET;
}
} // !virginOpen
@ -372,6 +381,8 @@ Mixer_ALSA::open()
***************************************************************************************/
if ( !validDevice )
{
close();
snd_ctl_card_info_free(hw_info);
return Mixer::ERR_NODEV;
}
@ -385,6 +396,8 @@ Mixer_ALSA::open()
/* setup for select on stdin and the mixer fd */
if ((m_count = snd_mixer_poll_descriptors_count(_handle)) < 0) {
kdDebug(67100) << "Mixer_ALSA::poll() , snd_mixer_poll_descriptors_count() err=" << m_count << "\n";
close();
snd_ctl_card_info_free(hw_info);
return Mixer::ERR_OPEN;
}
@ -393,19 +406,27 @@ Mixer_ALSA::open()
m_fds = (struct pollfd*)calloc(m_count, sizeof(struct pollfd));
if (m_fds == NULL) {
kdDebug(67100) << "Mixer_ALSA::poll() , calloc() = null" << "\n";
close();
snd_ctl_card_info_free(hw_info);
return Mixer::ERR_OPEN;
}
m_fds->events = POLLIN;
if ((err = snd_mixer_poll_descriptors(_handle, m_fds, m_count)) < 0) {
kdDebug(67100) << "Mixer_ALSA::poll() , snd_mixer_poll_descriptors_count() err=" << err << "\n";
close();
snd_ctl_card_info_free(hw_info);
return Mixer::ERR_OPEN;
}
if (err != m_count) {
kdDebug(67100) << "Mixer_ALSA::poll() , snd_mixer_poll_descriptors_count() err=" << err << " m_count=" << m_count << "\n";
close();
snd_ctl_card_info_free(hw_info);
return Mixer::ERR_OPEN;
}
snd_ctl_card_info_free(hw_info);
return 0;
}
@ -462,6 +483,10 @@ Mixer_ALSA::close()
}
for(int iMS = 0; iMS < mixer_sid_list.count(); iMS++)
if(mixer_sid_list[iMS])
snd_mixer_selem_id_free(mixer_sid_list[iMS]);
mixer_elem_list.clear();
mixer_sid_list.clear();
m_mixDevices.clear();

@ -3,6 +3,7 @@
*
*
* Copyright (C) 2004 Christian Esken <esken@kde.org>
* Copyright (C) 2017,2020 Roman Savochenko <roman@oscada.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -64,7 +65,7 @@ extern MixerFactory g_mixerFactories[];
* 'true' means to scan all backends. 'false' means: After scanning the
* current backend the next backend is only scanned if no Mixers were found yet.
*/
void MixerToolBox::initMixer(TQPtrList<Mixer> &mixers, bool multiDriverMode, TQString& ref_hwInfoString)
void MixerToolBox::initMixer(TQPtrList<Mixer> &mixers, bool multiDriverMode, TQString& ref_hwInfoString, bool isLight)
{
//kdDebug(67100) << "IN MixerToolBox::initMixer()"<<endl;
@ -115,12 +116,13 @@ 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())
DevIterator *I = f ? f() : new DevIterator();
for( ; !I->end(); I->next())
{
int dev = I->getdev();
Mixer *mixer = new Mixer( drv, dev );
if ( mixer->isValid() ) {
mixer->open();
if(!isLight) mixer->open();
Mixer* m;
if (dev >= 0) {
for (m = mixers.first(); m; m = mixers.next())
@ -131,7 +133,7 @@ void MixerToolBox::initMixer(TQPtrList<Mixer> &mixers, bool multiDriverMode, TQS
if (mixer->devnum() == m->devnum())
#endif
break;
if (m) continue;
if (m) { delete mixer; continue; }
}
mixers.append( mixer );
// Count mixer nums for every mixer name to identify mixers with equal names.
@ -145,6 +147,7 @@ void MixerToolBox::initMixer(TQPtrList<Mixer> &mixers, bool multiDriverMode, TQS
* %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.
*/
if(!isLight) {
TQString mixerName = mixer->mixerName();
mixerName.replace(":","_");
TQString primaryKeyOfMixer = TQString("%1::%2:%3")
@ -158,6 +161,7 @@ void MixerToolBox::initMixer(TQPtrList<Mixer> &mixers, bool multiDriverMode, TQS
primaryKeyOfMixer.replace("=","_");
mixer->setID(primaryKeyOfMixer);
}
} // valid
else
@ -174,7 +178,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;
}
@ -182,7 +186,7 @@ void MixerToolBox::initMixer(TQPtrList<Mixer> &mixers, bool multiDriverMode, TQS
} // !multiDriver
// append driverName (used drivers)
if ( !drvInfoAppended )
if ( !drvInfoAppended && !isLight )
{
drvInfoAppended = true;
TQString driverName = Mixer::driverName(drv);
@ -211,9 +215,10 @@ void MixerToolBox::initMixer(TQPtrList<Mixer> &mixers, bool multiDriverMode, TQS
} // !multipleDriversActive
} // loop over sound card devices of current driver
delete I;
} // loop over soundcard drivers
if (Mixer::masterCard() == 0)
if (Mixer::masterCard() == 0 && !isLight)
{
// We have no master card yet. This actually only happens when there was
// not one defined in the kmixrc.
@ -252,15 +257,15 @@ void MixerToolBox::initMixer(TQPtrList<Mixer> &mixers, bool multiDriverMode, TQS
/*
* Clean up and free all ressources of all found Mixers, which were found in the initMixer() call
*/
void MixerToolBox::deinitMixer()
void MixerToolBox::deinitMixer(TQPtrList<Mixer> &mixers)
{
//kdDebug(67100) << "IN MixerToolBox::deinitMixer()"<<endl;
Mixer *mixer;
while ( (mixer=Mixer::mixers().first()) != 0)
while ( (mixer=mixers.first()) != 0)
{
//kdDebug(67100) << "MixerToolBox::deinitMixer() Remove Mixer" << endl;
mixer->close();
Mixer::mixers().remove(mixer);
mixers.remove(mixer);
delete mixer;
}
// kdDebug(67100) << "OUT MixerToolBox::deinitMixer()"<<endl;

@ -1,3 +1,25 @@
/*
* KMix -- KDE's full featured mini mixer
*
*
* Copyright (C) 2004 Christian Esken <esken@kde.org>
* Copyright (C) 2020 Roman Savochenko <roman@oscada.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef MIXERTOOLBOX_H
#define MIXERTOOLBOX_H
@ -14,8 +36,8 @@ class Mixer;
*/
class MixerToolBox {
public:
static void initMixer(TQPtrList<Mixer>&, bool, TQString&);
static void deinitMixer();
static void initMixer(TQPtrList<Mixer>&, bool, TQString&, bool isLight = false);
static void deinitMixer(TQPtrList<Mixer>&);
};

Loading…
Cancel
Save