Older blog entries for ensonic (starting at number 117)

buzztard & gstreamer

In the begining of the month I finished the new treeview models. There were a couple of corner cases I did not handled yet. I did some thinking about the remaining model, but did not yet write any code for it. Instead I did some code review of the whole project leading to numerous small cleanups and fixes. I also got rid of some holes in the api docs.

Otherwise I worked more on GStreamer and gtk-doc. In GStreamer I mostly hacked on a baseclass for audio-visualizers which is now in gst-plugins-bad (together with 4 elements using it).

There are some other reasons for not having so much time to hack on, of which I will shortly speak about :)

32 files changed, 1848 insertions(+), 444 deletions(-)
buzztard

After last month spectrum analyzer work, I also looked at the volume meters again. Handling the updates is a bit tricky as I need to sync them to the audio playback. Now I have optimizations in place to skip updates when the meter is zero or maxed and has not changed. This is actually quite often the case.

I also fixed a small UI glitch; song-io plugins did not tell so far whether they support saving and/or loading. Thus one could end up selecting a format and then getting an error. Now one will see only the formats that plugins can handle.

Finally I got around catching up on the docs too. Now all dialogs have some docs including screenshots.

One refactoring I was actually considering to push for after the next release was getting rid of the GtkListStores and use real GtkTreeModels instead. The disadvantage of a ListStore is that it is static, if the underlying object is dynamic one needs to manually synchronize it. This enlarges the code and also the duplicated data storage uses memory. Writing own models was in the end not so difficult, it is quite some boilerplate code though. The first one I wrote is a object-list-model. It allows to bind object-properties to model columns. If e.g. a field changes, the model notifies and the view updates. The whole thing could become more generic if we would have an iterator interfaces and the collection types (list, array, ..) would be gobjects implementing the iface. Well, I am not the first to notice that :). Next I made 2 specialized models and started to take them into use. As a bonus e.g. the machine model provides a nice logical sorting. One more model to implement and switch to.

72 files changed, 6268 insertions(+), 1250 deletions(-)

best birthday gift ever

I got totally awesome birthday gifts today - Gnome 3 and Banshee 2 - thanks everybody :). When I asked on the irc what people will then release on my next anniversary - "well, like gnome 3.6 ;)" was the answer.

My personal birthday gift was this one. It is going to be fun.

buzztard

I have been refactoring GStreamer's spectrum analyzer. It is now working faster and also allows to get per-channel results. For testing I updated buzztard to check if one has the new version and if so show per channel graphs. While hacking on the analyzer graphs I have also refactored the code, so that now it is possible to probe the final output as well.

I spend the bigger part of the month on the tests again. I had an unref too much somewhere. Even after all the work in refdbg this is still difficult to track down. Eventually I found it and now all tests are green.

43 files changed, 796 insertions(+), 100 deletions(-)

buzztard I was testing buzztard a lot on my MeeGo netbook this month. As screen space is more precious on netbooks I was running it often in fullscreen mode and noticed that some windows seem to not open. When leaving full screen the windows appeared. Somehow they opened behind the main window. I looked over all child windows and dialogs and cleaned up the handling with a helper method doing:
  gtk_window_set_transient_for(window, main_window);
  gtk_window_set_destroy_with_parent(window, TRUE);
On my desktop it works fine on the netbook the problem still happens :/ No idea right now. As a good side effect I ensured that all dialogs have a properly set default response.

I was also running the performance tests and did some oprofiling. I knew already that my data-fixup code for buzzmachines caused quite some overhead. It is handling denormals and marking full zero buffers as empty. I now added code that sets the FPU on x86 machines to DAZ|FZ mode from the application and disable the fixup code. On my netbook my 11 min benchmark song renders in about 1 min instead of 1:20 min before. On my desktop most of the change are hard to measure as it already only takes 5 seconds :). Anyway the oprofile runs confirm the speedup. The code disappeared from the top 20.

The pattern editor widget becomes slow when getting large. Some text drawing operations look expensive. For a start I ported the whole widget to use cairo, but that does not take care of the slowness. After more measurements it becomes clear that I need to rework this more. I need to render it offscreen and reply to expose events by copying pixels.

I also worked a bit more on the interaction-controller library. udev/hal code is refactored into extra objects (saves me a lot of #ifdefs). It also has some tests now. I still have a mysterious issue with udev. Run this stand alone example as told in the header - for me valgrind complains about uninitialized data access. It only seems to happen when you have a /dev/input/mice which all my computers have. I have a workaround, but believe more testing from other would be great.

44 files changed, 1087 insertions(+), 317 deletions(-)

As there was no project news over x-mas, I have a slightly longer one this time. Before I dive into the usual code changes, something else - tadaa - we have a new webpage. The previous page was a mediawiki with a few customizations. Now we use a combo of wordpress-3 and mediawiki. Both use a similar theme (based on the arch linux one). Wordpres gives as news, forum, social-network features and much more. The first days I was suffering a lot from wordpress account creation spam. Luckily this seems to be under control now. The concept and a lot of the work was done by Joe Pea. We both have quite a few more things on the todo list. One of the next items is single sign in for wordpress and mediawiki. Stay tuned.

In the last two month I improved the song-recovery workflow. The recovery is now giving better feedback to the user and we're properly cleaning up afterwards. The machine machine and pattern view do now have almost full undo/redo.

Quite several times already I had to deal with a dialog containing a treeview showing a list of items. The latest example is the song-recovery dialog. Giving such a dialog a nice good initial size is tricky. The treeview usually goes into a scrolled window. By default one can see the headers and maybe one line. Of course one can resize the dialog a bit, but as the line height is not easy to figure it is still not easy. One approach I came up with is to grow the dialog to show all lines until it would exceed a certain limit. The limit would be e.g. half of screen or window height. The code for that is quite simple:

  list=gtk_tree_view_new();
  g_signal_connect(list,"size-request",G_CALLBACK(on_list_size_request),NULL);
  ...
  static void
  on_list_size_request(GtkWidget *widget,GtkRequisition *requisition,gpointer user_data)
  {
    gint max_height=gdk_screen_get_height(gdk_screen_get_default())/2;
    gint height=2+MIN(requisition->height,max_height);


/* make sure the dialog resize without showing a scrollbar until it would * reach half screen height */ gtk_widget_set_size_request(gtk_widget_get_parent(widget),-1,height); }

Another thing in gtk that I wonder if it has a better solution is the disposal of popup-menus. The problem is that gtk_menu_popup is not taking ownership of the menu, but there seems to be now event when the menu is done, so that one can unref it. The only solution I can see is the pre- create the menu and ref-sink it. When the entity that owns it is disposed it can destroy and unref it.

As we're quite gtk related in this time anyway one more discovery. Listening for key-press-event instead of key- release-event and widgets makes key-repeat work. Have added that to the gtk api docs.

Beside all the things above a couple of bug-fixes went in (make preferences in machines work (e.g. choosing fluidsynth instruments). I did some refactoring on midi controller handling; one can use the pitchwheel now and continuous controllers work better. Finally the dialogs warning about unsaved changes are more user-friendly; they now show the time passed since last saved/created in addition to the timestamp.

50 files changed, 2402 insertions(+), 1183 deletions(-)

GObject reference counting

Last month I made good progress on the undo/redo. I am now running the undo/redo in sync with the object lifecycle. The downside of this is that undo/redo fails when you have ref-count leaks. This now makes them more apparent. When trying to debug them I noticed that refdbg is not working anymore since quite a while. I was googling what other people use for such problems. Well, apparently everybody hates ref-count issues. Also most of the info you find is how to get traces for refcount activity. That is what refdbg does also. As this did not work for me anymore I've tried systemtap. Unfortunately right now its not useful for user-space work on most distros (except fedora) - bugs filed. Next step: gdb scripting. I managed to get a gdb script running. Now even for simple cases you quickly end up with a log of 150 backtraces. That is a lot to manually review. I went one step further and wrote a script to filter the traces. Over time I got the trace-log down to 20 entries. This is practical. Unfortunately the gdb script only work for tracing the lifecycle of one particular object. If I extend it to work for all refcounting activity I hit a gdb limitation to not allow nested commands :/. Back to refdbg :) I finally figured why it does not work and have started to fix it up. Lets see how far I get next month.

Buzztard

Naturally this used most of my hacking time. Still I managed to make some progress there as well. The buzztard irc channel was much more active this month. People reported small things here and there and most of it got fixed right away. The manual got some more love too to help people to get started and improve the description of several concepts. Finally all the refcount-debugging leads to a lot of code reviews. I found several areas with lots of needless refcount activity - fixes are in the repository.

81 files changed, 2682 insertions(+), 817 deletions(-)

gstreamer projects

In October I had not much time for buzztard. I went to the GStreamer conference and the CELF Europe. There I gave a talk about the "MeeGo multimedia stack". I also hacked on two GStreamer tool projects; gst-tracelib and gst-mediainfo. In tracelib I worked on a UI to monitor gstreamer pipelines on the fly. My approach to use libgvc (graphviz) for the layout seems to challenge it a bit though - I get very mysterious failures. At some point realloc is failing to e.g. allocate 96 bytes and the lib calls abort(). mallinfo() from libc is telling that the process uses 200 mb and valgind has nothing serious to complain about. That's weired as I was suspecting a corrupted memory list. I have to put that aside for a while until I get some new ideas for tackling it.

gst-mediainfo is the UI for the new discoverer API in GStreamer. I'll make a first release when the current gstreamer core and base is out as it depends on them.

In buzztard I mostly worked a bit on the crash recovery and did some bug fixing. Hopefully will have more time in November.

14 files changed, 325 insertions(+), 166 deletions(-)

buzztard

After all the initial work for journaling of edit events in the editor, I wanted to get a first proof of concept that everything fits together. And that I just got. The pattern editor implements a change-logger interfaces. It grabs the changelog singleton instance and logs all changes together with the undo action. The redo-action gets serialized and written to the changelog. The ui can undo/redo activities by using the change-logger interface. Upon startup the ui checks for leftover change logs, auto-cleans a few of them and offers a dialog for deleting/replaying them. I can now load a song, make changes in the pattern editor, ctrl-c/kill the app and replay the log when starting it again. There are a couple of details that need to be cleanup and some things need a bit more thinking: Next I will implement this in larger scale also.

As a continuation from last month I changed the whole editor UI to use G_DEFINE_TYPE and co. Boring work, but good to have it done now.

I had some strange crashes in the test suite - all pointing to gconf and only happening with the commandline client. After adding lots of extra logging there I still could see nothing wrong. Then I remember the hack I added to get a eventloop into the app - I run it as a new thread. By doing that I was doing gconf bits from different threads too and it does not seem to like it. I have now done the mainloop stuff more properly and get no more crashers. While looking into this problem, I cleaned the settings classes and the gconf backend a bit. It now does more stuff only as needed, improving the startup time of buzztard app a little further.

In GStreamer next core release will have extra metadata on element factories. This mechanism allows me to kill the one-property help interface. I rewrote all the code to use that conditionally and will remove it in a year or so.

As a last bigger task I migrated from deprecated HAL to GUdev. I have still conditional support for both, but will kill the HAL code once everything works nicely. I was using hal to discover input devices (joysticks, wiimotes,..) and midi-devices that can be used to control effects. Most of the conversion was straight forward. I spent a bit more time on getting nice names of the found devices for the UI and to classify midi-devices. For the midi-device classification I copied the matching rules from HAL - after all they seemed to do the trick there. For the ui names HAL was actually grepping through various files (e.g. /proc/asound/cards) for soundcard names. That I did not really wanted to copy. I got some great help from the udev people and learned that udev devices have properties like ID_VENDOR. One just needs to walk the device tree to get to the root device and grab the names there.

119 files changed, 3377 insertions(+), 1953 deletions(-)

tracking down udev hangs

I still face some problems on my new computer system. One of them iswas that udev was hanging in 8/10 cases at bootup. Thanks to great support from the udev folks I learned how to track it down. I previously tried to add options to /etc/udev/udev.conf (e.g. to raise the log level), but one can actually just add them to the kernel options. This has the great advantage that they don't persist. Things you want to add to debug are:

udev.log-priority=info udev.children-max=1 udev.exec-delay=1

This logs a lot of things (the boot can go from 30 second to minutes, so be patient). The option children-max is turning parallel event execution off and exec-delay is delaying run actions. With those I saw that the system hangs when loading the cdrom.ko kernel module. As I had some problems with the drive as well I swapped it and now bootup is fine.

108 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!