Fixed detection of alsa channels capabilities. This resolves bug 2994

and issue #16.
The code is partially based on previous work from TCH <tch@protonmail.com>.

Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
pull/18/head
Michele Calgaro 4 years ago
parent 85a278813f
commit 7a39a18686
Signed by: MicheleC
GPG Key ID: 2A75B7CA8ADED5CF

@ -199,9 +199,10 @@ Mixer_ALSA::open()
sid = (snd_mixer_selem_id_t*)malloc(snd_mixer_selem_id_sizeof()); // I believe *we* must malloc it for ourself sid = (snd_mixer_selem_id_t*)malloc(snd_mixer_selem_id_sizeof()); // I believe *we* must malloc it for ourself
snd_mixer_selem_get_id( elem, sid ); snd_mixer_selem_get_id( elem, sid );
bool canRecord = false; bool canPlay = false;
bool canMute = false;
bool canCapture = false; bool canCapture = false;
bool hasPlaySwitch = false;
bool hasCaptureSwitch = false;
long maxVolumePlay= 0, minVolumePlay= 0; long maxVolumePlay= 0, minVolumePlay= 0;
long maxVolumeRec = 0, minVolumeRec = 0; long maxVolumeRec = 0, minVolumeRec = 0;
validDevice = true; validDevice = true;
@ -261,6 +262,7 @@ Mixer_ALSA::open()
? Volume::MLEFT : (Volume::ChannelMask)(Volume::MLEFT | Volume::MRIGHT); ? Volume::MLEFT : (Volume::ChannelMask)(Volume::MLEFT | Volume::MRIGHT);
chn = (Volume::ChannelMask) (chn | chnTmp); chn = (Volume::ChannelMask) (chn | chnTmp);
cc = MixDevice::SLIDER; cc = MixDevice::SLIDER;
canPlay = true;
volPlay = new Volume( chn, maxVolumePlay, minVolumePlay ); volPlay = new Volume( chn, maxVolumePlay, minVolumePlay );
} else { } else {
volPlay = new Volume(); volPlay = new Volume();
@ -283,72 +285,83 @@ Mixer_ALSA::open()
mixer_sid_list.append( sid ); mixer_sid_list.append( sid );
if ( snd_mixer_selem_has_playback_switch ( elem ) ) { if ( snd_mixer_selem_has_playback_switch ( elem ) ) {
//kdDebug(67100) << "has_playback_switch()" << endl; //kdDebug(67100) << "has_playback_switch()" << endl;
canMute = true; hasPlaySwitch = true;
} }
if ( snd_mixer_selem_has_capture_switch ( elem ) ) { if ( snd_mixer_selem_has_capture_switch ( elem ) ) {
//kdDebug(67100) << "has_capture_switch()" << endl; //kdDebug(67100) << "has_capture_switch()" << endl;
canRecord = true; hasCaptureSwitch = true;
} }
if ( snd_mixer_selem_has_common_switch ( elem ) ) { if ( snd_mixer_selem_has_common_switch ( elem ) ) {
//kdDebug(67100) << "has_common_switch()" << endl; //kdDebug(67100) << "has_common_switch()" << endl;
canMute = true; hasPlaySwitch = true;
canRecord = true; hasCaptureSwitch = true;
} }
if ( /*snd_mixer_selem_has_common_switch ( elem ) || */ if (cc == MixDevice::UNDEFINED )
cc == MixDevice::UNDEFINED )
{ {
// Everything unknown is handled as switch // Everything unknown is handled as switch
cc = MixDevice::SWITCH; cc = MixDevice::SWITCH;
} }
} // is ordinary mixer element (NOT an enum) } // is ordinary mixer element (NOT an enum)
if (canPlay || cc == MixDevice::SWITCH || cc == MixDevice::ENUM)
{
MixDevice* md = new MixDevice( mixerIdx, MixDevice* md = new MixDevice( mixerIdx,
canCapture ? *volCapture : *volPlay, *volPlay,
canCapture ? true : canRecord, false,
canMute, hasPlaySwitch,
snd_mixer_selem_id_get_name( sid ), snd_mixer_selem_id_get_name( sid ),
ct, ct,
cc ); cc );
m_mixDevices.append( md );
m_mixDevices.append( md );
if (!masterChosen && ct==MixDevice::VOLUME) { if (!masterChosen && ct==MixDevice::VOLUME) {
// Determine a nicer MasterVolume // Determine a nicer MasterVolume
m_recommendedMaster = md; m_recommendedMaster = md;
masterChosen = true; masterChosen = true;
} }
if ( enumList.count() > 0 ) { if ( enumList.count() > 0 ) {
int maxEnumId= enumList.count(); int maxEnumId= enumList.count();
TQPtrList<TQString>& enumValuesRef = md->enumValues(); // retrieve a ref TQPtrList<TQString>& enumValuesRef = md->enumValues(); // retrieve a ref
for (int i=0; i<maxEnumId; i++ ) { for (int i=0; i<maxEnumId; i++ ) {
// we have an enum. Lets set the names of the enum items in the MixDevice // we have an enum. Lets set the names of the enum items in the MixDevice
// the enum names are assumed to be static! // the enum names are assumed to be static!
enumValuesRef.append(enumList.at(i) ); enumValuesRef.append(enumList.at(i) );
} }
} }
//kdDebug(67100) << "ALSA create MDW, vol= " << *vol << endl; }
delete volPlay; if (canCapture)
delete volCapture;
} // virginOpen
else
{ {
MixDevice* md; MixDevice* md = new MixDevice( mixerIdx,
bool found = false; *volCapture,
for ( md = m_mixDevices.first(); md != 0; md = m_mixDevices.next() ) { true,
if ( md->num() == mixerIdx ) { hasCaptureSwitch,
found = true; snd_mixer_selem_id_get_name( sid ),
writeVolumeToHW( mixerIdx, md->getVolume() ); ct,
} cc );
} m_mixDevices.append( md );
if( !found ) }
{ //kdDebug(67100) << "ALSA create MDW, vol= " << *vol << endl;
return Mixer::ERR_INCOMPATIBLESET; delete volPlay;
} delete volCapture;
} // !virginOpen } // virginOpen
else
{
MixDevice* md;
bool found = false;
for ( md = m_mixDevices.first(); md != 0; md = m_mixDevices.next() ) {
if ( md->num() == mixerIdx ) {
found = true;
writeVolumeToHW( mixerIdx, md->getVolume() );
}
}
if( !found )
{
return Mixer::ERR_INCOMPATIBLESET;
}
} // !virginOpen
} // for all elems } // for all elems
/************************************************************************************** /**************************************************************************************

Loading…
Cancel
Save