[Screencast] KMix QML Applet, the real one


When I started writing my last blog post, exactly two weeks ago, I never imagined that I would receive so many positive feedbacks and responses1 for a project that, as I’ve always restated, was just an proof of concept and nothing more.

Anyways that experiment (and the act of sharing it with the community) leaded, besides the comments, to an awesome consequence: the developer in charge to improve KMix DBus interface and provide the Plasma applet replacement, Igor Poboiko2, sent me an email the same day I wrote the aforementioned post.

Long story short: he was busy (like me) with College duties so, after refactoring the DBus interface, he was forced to stop his work. But theΒ  amazing news was an other: he even wrote a Plasma DataEngine, and a Plasma Service for KMix πŸ˜€

So we joined our forces,Β  I advised him to publish his work on reviewboard (he did a huge work, kudos!) to receive more feedbacks about his doings and I started coding, on my spare time, to a new KMix applet replacement. Since I had at my disposal this new “mixer” Plasma DataEngine, I started wondering why not making a QML applet, instead of a regular C++ plasmoid.

No sooner said than done, and this is the result (still incomplete) of my work:

[HQ Version]

The applet has all the basic functionalities required for a mixer, you can modify the volume level/state for each control (in my past experiment, I was only able to act on the Master) but still, there is a lot of room for improvements.

I was really impressed about the power of QML and Plasma technology combined (plus some Javascript flavors),Β  I think I’m in love with them πŸ™‚

As soon as Igor’s work will be published, also mine will land on reviewboard and, hopefully, will be part of the kdemultimedia module πŸ™‚

Stay tuned for updates, cheers!

_______________________________________________________________

1: I even scored the busiest day on my blog, and my previous record was half of the visit I received that day O.o↑
2: Unfortunately, he doesn’t have a blog; I’ve found his sourceforge and twitter page, if you are interested↑

28 responses to “[Screencast] KMix QML Applet, the real one

  1. What’s about performance? QML manual states that’s it’s better to limit javascript usage to bare minimum.

    Like

    • In my code, about 10% is Javascript, and the performances are good. The problem in this specific applet is that, when showing all the controls (18 in my case), I have 18 dataengines connected remotely to KMix via DBus, and sometimes left/right flicking the applet to show all the controls is a little jerky; perhaps increasing the cacheBuffer will reduce this behavior with little overhead.

      Like

      • Dataengines? Plural? Shouldn’t it be one dataengine and 18 sources (or at least 2 dataengines, for input and output, and those 18 sources distributed accordingly)? …

        And what do kmix and d-bus have with it? AFAIK, you’re supposed to connect your plasmoid to a dataengine/service and that’s it (that’s, for a not so close example, what now playing does — http://techbase.kde.org/Development/Tutorials/Plasma/JavaScript/NowPlaying http://techbase.kde.org/Development/Tutorials/Plasma )! Ain’t the dataengine and service providing all data and control you need? If Im’ not wrong, they must to, so that doesn’t happen.

        And don’t take this wrong, I’m trying to help here: maybe it’s flicking ’cause you’re trying to push to much into it, stuff really unneeded.

        And, BTW, kudos on the effort! Sadly, I couldn’t see the screencast yet, it doesn’t make through here at work. But, as someone said up here, it’s possibly the only (or at least the most) outdated thing at the notif.area. I’ve even myself redesigned it a few times (ended up with something combining kmix’s main channel window and the channels full list’s window*) but have no technical knowlege yet for the dataengine/service. Thank you for your time and work!

        * If you don’t have that yet and care for the suggestion, think of networkmanager’s plasmoid, with the “Advanced” button (maybe “More” sounds better in this case) showing all channels (possibly grouped in categories tabs as kmix does) and allowing not only to control each but also to set which shows up in that main/simplier/not-advanced/first view (maybe through checkboxes for that to each). What’s the use for that? I want not only to control the main volume but also inputs like a mic (boy, I miss this!). I can make some mockups, if you like such a feature.

        Like

      • Hey dont’ worry, I always appreciate constructive comments πŸ˜‰
        About the “mixer” dataengine(s) thing, you need to know how it provides its data first. In fact, it provides three types of data sources:

        1. * “Mixers”, the most generic, which simply returns the name(s) of the mixer(s) on your machine (mixerID) ;
        2. * “mixerID”, where mixerID comes from the previous data source, and returns all the names of _all_ the controls (controlID) in the given mixer device;
        3. * “mixerID/controlID”, which returns the specific values of volume and mute state of the control specified by its controlID, on the mixerID device.

        This is the reason why I need to create a dataengine for each control πŸ™‚
        Of course if the dataengine was implemented in a different way (for example putting everything about all the controls in one big datasource), instead of connecting to more datasources, I would have connected to just one. But the price of this alternate implementation would be a _lot_ of javascript code to detect which control has been modified, and find the correspondig UI element, and modify it (and inside QML word, this should be avoided).

        About the KMix and DBus mention: I was just describing how the dataengine works internally πŸ™‚

        The reason why the flick action is jerky is because the I don’t set the cacheBuffer to the number of controls in the mixer device so, when flicking, the invisible controls are dynamically created (instead of being created upon the listview initialization) and, since creating them means retrieving volume and mute state -> ergo dataengine call -> ergo an internal dbus call to kmix, the DBus call takes “a little bit” for being processed, thus the jerkiness πŸ™‚

        Of course I care of those details too, that’s why I stated there is a lot of room for improvements πŸ™‚

        Like

      • “But the price of this alternate implementation would be a _lot_ of javascript code to detect which control has been modified, and find the correspondig UI element, and modify it (and inside QML word, this should be avoided).”

        That depends … I’ve only played with Javascript and Python (and a little C++) plasmoids and know nothing yet about QML ones but, assuming dataengines/services work the same way for all of them, dataUpdated() wouldn’t give you exactly this? And associating the widget to a service wouldn’t modify it automaticly ( http://aseigo.blogspot.com/2009/01/basic-javascript-engine-go-forward.html )? (That I don’t know if is javascript specific but I really hope not as it makes it waaay easier and would be a such a shame if not available to all prog. languages. It’s worth big time looking for something alike.)

        Like

      • In QML thigs are slightly different, however I’m using a onDataChanged signal to perform my computation, and this is very similar to the dataUpdated() approach we usually do with JS/Python/Ruby.
        Associating the slider widget to a service directly is a very bad thingβ„’ in this case: if you modify the slider by hand, causing a valueChanged() being fired, you automatically fire the associated service too, which causes a volume level change. This, in turn, causes an update of the dataEngine, so the onDataChanged signal is fired (or, equivalently, the dataUpdate() slot is executed) and here we update of course the label and the slider value with the new value coming from the dataUpdated() data. Since the slider value and that new value are the same, because we changed the slider by hand in the first place, there is no further valueChanged() emission, and we are done. But, we live in the real world, and setting the volume to 75% is not guaranteed to have the same effect on the audio card, this will actually trigger a new valueChanged() signal, and now we just entered a funny loop, until the volume decreases till 0 πŸ™‚
        So I can’t do this association, because I need to insert some code to detect this unwanted behavior, and stop it πŸ˜‰

        Like

  2. This looks great. Thank you for porting KMix. It seems so out-of-date in the Plasma system tray. One question though: Pulseaudio finally works really well with KDE and is used by a large number of distributions. How will this plasmoid handle Pulse? Will it show several controls, as Veromix does?

    Like

    • I’ve never tried Veromix, however my plasmoid doesn’t care about Pulseaudio. It simply connects to a dataengine which provides all the mixer infos needed so, strictly speaking, the way those infos are exposed(through pulseaudio) is just an implementation detail. If you meant if this plasmoid will show specific infos about the “application X” using pulseaudio, as veromix seems does, the answer is: the dataengine I’m using doesn’t provide this feature, so no. This could be improved, tho πŸ™‚

      Like

  3. Are there any animations between slider positions when the mixer levels are changed by dbus signals? They don’t come out on the screencast. If not, animating transitions would make the jump between levels appear more natural, hiding the low number of signals.

    Like

    • There are no transitions between slider positions, and this is not easy to achieve because this would require whether tweaking the Plasma::Slider code or creating a fake QML Slider component in order to address the issue.

      Like

  4. Wow, awesome. I hope it’ll be ready for SC 4.7.
    One thing, though: When more than slider is displayed, scrolling seems currently to happen solely through kinetic scrolling. That’s fine for touch devices but for mouse driven devices displaying a scroll bar is better.

    Like

  5. Pingback: KMix, Veromix, QML and other stories… | Padoca Virtual

    • It does, but not directly. In fact the dataEngine I’m querying to get the infos about the audio devices, is connected to (via a DBus interface) to the KMix application (that implements that interface). However KMix can run in the background (simply disable the tray icon option, and then close its main window), and there is even a daemon, so don’t worry: when everything will be completed, you won’t see the old tray icon application anymore πŸ™‚

      Like

      • Thanks, but will the gui of kmix be on ram or it will be only the service?, I guess I don’t need the ui og kmix loaded in the ram.

        Like

      • I don’t know the internals of KMix however, since its main UI is accessed just a couple of times (apart from those screencasts I made lately, I rarely had the need to use it), so I suppose it’s loaded on demand, and destroyed when closed.

        Like

    • Oh well back in march, when I started this experiment, QML wasn’t complete and functional as now.
      Now things are changed for good, qml has been improved a lot, we have complete plasma declarative components, but now I’m busy with my thesis and my last exam (and an other “secret” project), and there are still some issues whithin qml and scripted plasmoids to solve (i.e.: the plasmoid config page can’t be modified from the plasmoid code, so we can’t show all the channels in a combobox and let the user choose which one he wants to control).
      Hopefully I’ll start coding it back in January and the good news is that, since it’s a scripted plasmoid, we can publish it on opendesktop.org if the release schedule won’t allow us to include it in kdemultimedia πŸ™‚

      Like

      • If it isn’t in now then it won’t make it for KDE 4.8 since that is at RC at the moment..

        Could you just put your code in a git branch somewhere? I think i will pick it up and play with it if you do.

        Kind regards and happy new year πŸ™‚

        Like

      • First of all, I want to apologize for replying sooo late, I’m really sorry for that 😦
        About the code, I’ve rewrote it using the new plasmacomponents (yay) and now looks really nice. It’s really basic by the way, you can’t select which channel will be the Master one (but you can do that from the usual KMix gui, and the plasmoid will automatically recognize any change), neither change its orientation (due to a lot of issues in the bindings side that drove me really crazy). I’ve submitted it to the rewievboard so, if you want, you could grab the diffs here https://svn.reviewboard.kde.org/r/6928/ or download the plasmoid package from here.
        Sorry again, have a nice day!

        Like

  6. Pingback: Merry Christmas, and a PlasMate surprise for you :) [screencast] « [Po]lentino's blog

  7. Any chance you could provide the source for this?
    I’m planing on implementing something similar to ubuntu’s sound-menu, and this would be of great help.

    Like

Leave a comment