Phonon + Volume Changes and feedback loops

Colin Guthrie gmane at colin.guthr.ie
Wed Mar 31 13:26:49 BST 2010


'Twas brillig, and Christian Esken at 31/03/10 12:52 did gyre and gimble:
>> I had a quick look at the blockSignals() docs and it seems that after
>> turning it off, I'd need to turn it back on somehow (e.g. there is no
>> "block one setValue signal" capability). With the current solution
>> linked above, I turn the handling back on after ignoring a change but to
>> do that I have to do it in the slot for that change. With blockSignals()
>> I'd have to find a way to unblock them again after one has been thrown
>> away.... I couldn't see a way to do that, but perhaps I missed that?
> 
> Usually you do:
> 
> slider->blockSignals( true );  // block
> slider.setValue( ...) ; // do your GUI change
> slider->blockSignals( false ); // unblock
> 
> Should work for your case, as you can do all of that in the same slot.
> Or I haven't understod the issue fully yet. ;)

This wont work in the current case due to the async nature of the
"setValue" command. In actual fact it's not a GUI element here but the
sound output. i.e. the code is:

output->setVolume(newVolume);

If the setVolume call was synchronous then surrounding it by
blockSignals(true) would work fine, but as the setVolume call with PA is
async, then the signal is not generated when the call itself is made but
some time later.

i.e.

1. Block signals.
2. Call output->setVolume(); Issue change request now, but no signals.
3. Unblock signals.
4. Some time passes.
5. Receive notification from PA of volume change.
6. Generate signals.
7. Lather, rinse, repeat.

Because of the async nature, the signal itself is generated after the
Unblocking of signals and thus it will be handled and the feedback loop
would kick in.

So the solution I went for doesn't block the signals but handles them
gracefully. It says "I want to ignore the next change signal" and then
does just that in the slot handling that signal by making the code a
noop on that run and then resetting the flag that "says ignore the next
change."

And I need two separate flags for the two scenarios of:
 1. Change initiated in the GUI and change needs to be applied to the
stream.
and the opposite:
 2. Change is detected in the stream (e.g. from another mixer app) and
the GUI needs to be updated to reflect that.


Thanks for discussing this as the whole async nature of this is often a
headfuk :p I'm not totally certain it's the perfect solution but it
seems to work OK in practice and the loops I could generate before, I
can no longer trigger.

Col


-- 

Colin Guthrie
gmane(at)colin.guthr.ie
http://colin.guthr.ie/

Day Job:
  Tribalogic Limited [http://www.tribalogic.net/]
Open Source:
  Mandriva Linux Contributor [http://www.mandriva.com/]
  PulseAudio Hacker [http://www.pulseaudio.org/]
  Trac Hacker [http://trac.edgewall.org/]



More information about the kde-multimedia mailing list