Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Multimedia
KMix
Commits
4f7ac8db
Commit
4f7ac8db
authored
Nov 12, 2012
by
Christian Esken
Browse files
Fix volume switch for controls with a virtual/simulated mute switch.
CCBUGS: 309334
parent
8fb06fa8
Changes
5
Hide whitespace changes
Inline
Side-by-side
backends/mixer_alsa9.cpp
View file @
4f7ac8db
...
...
@@ -717,7 +717,17 @@ Mixer_ALSA::readVolumeFromHW( const QString& id, shared_ptr<MixDevice> md )
vol
=
Volume
::
MNONE
;
// --- playback volume
if
(
snd_mixer_selem_has_playback_volume
(
elem
)
)
{
if
(
snd_mixer_selem_has_playback_volume
(
elem
)
)
{
if
(
md
->
isVirtuallyMuted
()
)
{
// Special code path for controls w/o physical mute switch. Doing it in all backends is not perfect,
// but it saves a lot of code and removes a lot of complexity in the Volume and MixDevice classes.
// Don't feed back the actual 0 volume back from the device to KMix. Just do nothing!
}
else
{
foreach
(
VolumeChannel
vc
,
volumePlayback
.
getVolumes
()
)
{
int
ret
=
0
;
...
...
@@ -739,6 +749,7 @@ Mixer_ALSA::readVolumeFromHW( const QString& id, shared_ptr<MixDevice> md )
volumePlayback
.
setVolume
(
vc
.
chid
,
vol
);
//if (id== "Master:0" || id== "PCM:0" ) { kDebug() << "volumePlayback control=" << id << ", chid=" << i << ", vol=" << vol; }
}
}
}
// has playback volume
// --- playback switch
...
...
@@ -811,9 +822,32 @@ Mixer_ALSA::writeVolumeToHW( const QString& id, shared_ptr<MixDevice> md )
return
0
;
}
// --- playback switch
bool
hasPlaybackSwitch
=
snd_mixer_selem_has_playback_switch
(
elem
)
||
snd_mixer_selem_has_common_switch
(
elem
);
if
(
hasPlaybackSwitch
)
{
int
sw
=
0
;
if
(
!
md
->
isMuted
())
sw
=
!
sw
;
// invert all bits
snd_mixer_selem_set_playback_switch_all
(
elem
,
sw
);
}
// --- playback volume
if
(
snd_mixer_selem_has_playback_volume
(
elem
)
)
{
kDebug
()
<<
"phys="
<<
md
->
hasPhysicalMuteSwitch
()
<<
", muted="
<<
md
->
isMuted
();
if
(
md
->
isVirtuallyMuted
()
)
{
// Special code path for controls w/o physical mute switch. Doing it in all backends is not perfect,
// but it saves a lot of code and removes a lot of complexity in the Volume and MixDevice classes.
int
ret
=
snd_mixer_selem_set_playback_volume_all
(
elem
,
(
long
)
0
);
if
(
ret
!=
0
)
kDebug
()
<<
"writeVolumeToHW("
<<
devnum
<<
") [set_playback_volume] failed, errno="
<<
ret
;
}
else
{
foreach
(
VolumeChannel
vc
,
volumePlayback
.
getVolumes
()
)
{
int
ret
=
0
;
...
...
@@ -830,20 +864,13 @@ Mixer_ALSA::writeVolumeToHW( const QString& id, shared_ptr<MixDevice> md )
case
Volume
::
REARSIDERIGHT
:
ret
=
snd_mixer_selem_set_playback_volume
(
elem
,
SND_MIXER_SCHN_SIDE_RIGHT
,
vc
.
volume
);
break
;
default:
kDebug
()
<<
"FATAL: Unknown channel type for playback << "
<<
vc
.
chid
<<
" ... please report this"
;
break
;
}
if
(
ret
!=
0
)
kDebug
()
<<
"writeVolumeToHW("
<<
devnum
<<
") [set_playback_volume] failed, errno="
<<
ret
;
if
(
ret
!=
0
)
kDebug
()
<<
"writeVolumeToHW("
<<
devnum
<<
") [set_playback_volume] failed, errno="
<<
ret
;
//if (id== "Master:0" || id== "PCM:0" ) { kDebug() << "volumePlayback control=" << id << ", chid=" << vc.chid << ", vol=" << vc.volume; }
}
}
}
// has playback volume
// --- playback switch
if
(
snd_mixer_selem_has_playback_switch
(
elem
)
||
snd_mixer_selem_has_common_switch
(
elem
)
)
{
int
sw
=
0
;
if
(
!
md
->
isMuted
()
)
sw
=
!
sw
;
// invert all bits
snd_mixer_selem_set_playback_switch_all
(
elem
,
sw
);
}
// --- capture volume
...
...
core/mixdevice.cpp
View file @
4f7ac8db
...
...
@@ -240,6 +240,13 @@ const QString MixDevice::dbusPath() {
bool
MixDevice
::
isMuted
()
{
return
!
_playbackVolume
.
isSwitchActivated
();
}
/**
* Returns whether this MixDevice is virtually muted. Only MixDevice objects w/o a physical switch can be muted virtually.
*/
bool
MixDevice
::
isVirtuallyMuted
()
{
return
!
hasPhysicalMuteSwitch
()
&&
isMuted
();
}
void
MixDevice
::
setMuted
(
bool
mute
)
{
_playbackVolume
.
setSwitch
(
!
mute
);
}
void
MixDevice
::
toggleMute
()
{
setMuted
(
!
_playbackVolume
.
isSwitchActivated
());
}
bool
MixDevice
::
hasMuteSwitch
()
{
return
playbackVolume
().
hasVolume
()
||
playbackVolume
().
hasSwitch
();
}
...
...
core/mixdevice.h
View file @
4f7ac8db
...
...
@@ -163,6 +163,7 @@ public:
// is an abstract concept. It places no interpretation on the meaning of the switch (e.g. does "switch set" mean
// "mute on", or does it mean "playback on", or "Capture active", or ...
virtual
bool
isMuted
();
virtual
bool
isVirtuallyMuted
();
virtual
void
setMuted
(
bool
value
);
virtual
bool
hasMuteSwitch
();
virtual
void
toggleMute
();
...
...
core/volume.cpp
View file @
4f7ac8db
...
...
@@ -107,7 +107,10 @@ void Volume::init( ChannelMask chmask, long maxVolume, long minVolume, bool hasS
_hasSwitch
=
hasSwitch
;
_isCapture
=
isCapture
;
//_muted = false;
_switchActivated
=
false
;
// Presume that the switch is active. This will always work:
// a) Physical switches will be updated after start from the hardware.
// b) Emulated virtual/switches will not receive updates from the hardware, so they shouldn't disable the channels.
_switchActivated
=
true
;
disallowSwitchDisallowRead
=
false
;
}
...
...
core/volume.h
View file @
4f7ac8db
...
...
@@ -115,26 +115,18 @@ friend class MixDevice;
bool
hasSwitch
()
const
{
if
(
isCapture
())
{
return
_hasSwitch
;
}
else
{
if
(
disallowSwitchDisallowRead
)
{
kError
()
<<
"hasSwitch() must only be called for capture volumes. I will crash now to retreieve a stacktrace!!!"
;
QObject
*
obj
=
0
;
obj
->
blockSignals
(
true
);
return
_hasSwitch
;
}
else
kDebug
()
<<
"Allow playback switch read once"
;
}
return
_hasSwitch
;
return
_hasSwitch
;
};
bool
hasVolume
()
const
{
return
(
_maxVolume
!=
_minVolume
);
}
bool
isCapture
()
const
{
return
_isCapture
;
}
// -<- Query thsi, to find out whether this is a capture or a playback volume
/**
* Returns whether this is a playback or capture volume.
*
* @return true, if it is a capture volume
*/
bool
isCapture
()
const
{
return
_isCapture
;
}
// Some playback switches control playback, and some are special.
// ALSA doesn't differentiate between playback, OnOff and special, so users can add this information in the profile.
...
...
@@ -167,24 +159,7 @@ protected:
bool
isSwitchActivated
()
const
// TODO rename to isActive()
{
return
_switchActivated
;
if
(
isCapture
())
{
return
_switchActivated
&&
hasSwitch
();
}
else
{
if
(
disallowSwitchDisallowRead
)
{
kError
()
<<
"isSwitchActivated() must only be called for capture volumes. I will crash now to retreieve a stacktrace!!!"
;
QObject
*
obj
=
0
;
obj
->
blockSignals
(
true
);
return
_switchActivated
&&
hasSwitch
();
}
}
return
_switchActivated
&&
hasSwitch
();
};
};
private:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment