May 16, 2012

Musings on the linux audio stack

Trever Fischer

I spent some free time today getting caught up on the large backlog of phonon-gstreamer bugs. Towards the end, I started to have delusions of grandeur: Imagine a phonon-gstreamer codebase that doesn’t require supporting a zillion different audio frameworks, and instead belays that task to something that I don’t have to maintain.

My question here, is how many people would throw a fit if phonon-gstreamer dropped support for ALSA and OSS, and forced everyone to use pulseaudio by way of GStreamer’s excellent pulseaudio support?

Hold on, lower your pitchforks for a minute. Let us consider the audio framework landscape in the modern world:

  • Pulseaudio is the One True Way for audio playback in Gnome
  • For 90% of the support questions we handle in #kde-multimedia, the solution is “use pulseaudio”.
  • Pulseaudio can handle using OSS, ALSA, Bluetooth, or whatever your audio output is, through one consistent entry point
  • It is a total headache to figure out any bugs in your audio when music goes from Amarok->Phonon->Phonon-GStreamer->(ALSA, OSS, Pulseaudio, god knows what)->Speakers->Earholes

Additionally, I really don’t feel like testing phonon-gstreamer on all those different kernel-level interfaces with exotic setups every time I fix a bug and am afraid I’d introduce another twelve. The PulseAudio folks seem to do a fantastic job at that already. Phonon isn’t meant for real-time playback or production studio quality audio. Thats what Jack is meant for.

I can’t think of a good reason why we shouldn’t stand on the shoulders of giants by making PulseAudio handle all the hard stuff on Unix involving massaging PCM formats, equalizers, matching playback category with output device, enumerating outputs both real and virtual, volume control, etc.

If you can, leave a comment on this post. I’m not making an official statement saying that I’m definitely removing ALSA and OSS support from phonon-gstreamer, I’m merely asking for feedback to see what can be done to fix things at all levels in the audio stack.

flattr this!

by Trever at May 16, 2012 07:51 PM

Continuing with my previous post about the Zeitgeist team’s improvements with regards to speed, there’s a nifty tool in the sources I wrote yesterday that uses a genetic algorithm to find the slowest queries you can throw at the engine.

If you’re not familiar with genetic algorithms, here’s a brief review of how they work:

  • Start off with an array of numbers, with each index corresponding to a particular attribute of the problem.
  • Evaluate the fitness of that genome
  • Simulate evolution of the successful genomes by crossing, mutations, etc, just as you would with real DNA chromosomes

In the case of this Zeitgeist tool, the chromosome refers to a query, and each allele (index of the array) refers to an attribute of the query. Here’s a relevant comment from the sources:

# Chromosome to data mapping:
# 0, 1 - Timerange begin and end. If both are zero, we use timerange.always()
# 2 - The search type. Anything over 30 is a dead individual.
# 3-5 - Specify template properties. Anything besides 0 and 1 is dead.
# 3 - Specify a subject interpretation
# 4 - Specify a subject manifestation
# 5 - Specify an event actor

Using the super cool pyevolve library, implementing a genetic algorithm is super easy:

def eval_func(chromosome):
  query = buildQuery(chromosome)
  if query is None:
    return 0

  start = time.time()
  results = engine.find_events(*query)
  overall = (time.time() - start)
  return (results["find_events"]*2+results["find_event_ids"]*4+results["get_events"])*1000

genome = G1DList.G1DList(6)
genome.evaluator.set(eval_func)
ga = GSimpleGA.GSimpleGA(genome)
ga.evolve(freq_stats = 1)
query = buildQuery(ga.bestIndividual())
assert query is not None
print query, len(engine.find_events(*query))

Let it run for a long while on a big database, and you end up with a query that takes forever. Due to how evolution works, it isn’t the longest running query, but it is certainly one that takes a long time.

flattr this!

by Trever at May 16, 2012 04:43 PM

May 12, 2012

PulseAudio 2.0: Twice The Goodness!

Arun Raghavan

That’s right, it’s finally out! Thanks go out to all our contributors for the great work (there’s too many — see the shortlog!). The highlights of the release follow. Head over to the announcement or release notes for more details.

  • Dynamic sample rate switching by Pierre-Louis Bossart: This makes PulseAudio even more power efficient.

  • Jack detection by David Henningsson: Separate volumes for your laptop speakers and headphones, and more stuff coming soon.

  • Major echo canceller improvements by me: Based on the WebRTC.org audio processing library, we now do better echo cancellation, remove the need to fiddle with the mic volume knob and have fixed AEC between laptop speakers and a USB webcam mic.

  • A virtual surround module by Niels Ole Salscheider: Try it out for some virtual surround sound shininess!

  • Support for Xen guests by Giorgos Boutsiouki: Should make audio virtualisation in guests more efficient.

We don't always make a release, but when we do, it's awesome

Special thanks from me to Collabora for giving me some time for upstream work.

Packages are available on Gentoo, Arch, and probably soon on other distributions if they’re not already there.

by Arun at May 12, 2012 10:50 AM

May 01, 2012

Androidifying your autotools build the easy way

Arun Raghavan

Derek Foreman has finally written up a nice blog post about his Androgenizer tool, which we’ve used for porting PulseAudio, GStreamer, Wayland, Telepathy and most of their dependencies to Android.

If you’ve got an autotools-based project that you’d like to build on Android, whether on the NDK or system-wide this is really useful.

by Arun at May 01, 2012 07:48 PM

April 27, 2012

Did you know g_clear_object/pointer() ?

Xavier Claessens

g_clear_object() has been in glib since 2.28, and now g_clear_pointer() has landed in glib master (see bug #674634).
Their typical usage is to implement GObject::dispose, or “goto out” pattern, previously you would write:

void my_dispose (GObject *obj)
{
  MyObject *self = (MyObject *) obj;
  if (self->priv->object != NULL)
    {
      g_object_unref (self->priv->object);
      self->priv->object = NULL;
    }
  if (self->priv->hash != NULL)
    {
      g_hash_table_unref (self->priv->hash);
      self->priv->my_hash = NULL;
    }
  etc...
}

or:

void some_func ()
{
  GHashTable *tmp = NULL;

  ...
  if (error)
    goto out;

  tmp = g_hash_table_new();
  ...

out:
  if (tmp != NULL)
    g_hash_table_unref (tmp);
}

But now those becomes:

void my_dispose (GObject *obj)
{
  MyObject *self = (MyObject *) obj;

  g_clear_object (&self->priv->object);
  g_clear_pointer (&self->priv->hash, g_hash_table_unref);
  etc...
}

or:

void some_func ()
{
  GHashTable *tmp = NULL;

  ...
  if (error)
    goto out;

  tmp = g_hash_table_new();
  ...

out:
  g_clear_pointer (&tmp, g_hash_table_unref);
}

As extra bonus, g_clear_object() and g_clear_pointer() are thread-safe. That means that 2 threads can clear the same pointer at the same time and it will be freed only once. I’ve heard some code needs thread-safe dispose…

Thanks to Simon McVittie for the original idea in telepathy-glib where we had tp_clear_object/pointer for years.

by xclaesse at April 27, 2012 09:03 AM

Better notification support

Marco Barisione

Yesterday I released a new version of my message notification extension for gnome-shell (3.2 and 3.4), to install it or to update it just visit its page on extensions.gnome.org.

The main feature in the new version is that it just handles notifications coming from well-known applications: Empathy, XChat, XChat-GNOME, Pidgin and notify-send. Handling the Empathy notifications is easy because they are well integrated with the shell, but the other notifications required some hack because all the applications handle notifications in different ways. I did my best to make the notifications as useful as possible, similar to the Empathy ones, but there are some small limitations.
Some of the handled applications require plugins to show notification bubbles:

  • Pidgin: Click on the “Tools” menu and then “Plug-ins”. Make sure that the “Libnotify Popups” plugin is enabled. If the plugin is not in the list it means you need to install it. On Debian the package is called “pidgin-libnotify”, other distros should have a package with a similar name.
  • XChat-GNOME: Click on the “Edit” menu and then “Preferences”. In the “Scripts and Plugins” tab make sure that “On-screen display” is enabled.
  • XChat: Click on the “Settings” menu and then “Preferences”. In the “Alerts” tab make sure that “Show tray baloons” is enabled for both “Private Message” and “Highlighted Message”. If the notifications pile up in the bottom right corner of your screen and clicking on them does nothing, it means that XChat is using notify-send because it cannot find libnotify. I don’t know how to fix this issue on different distros, but I found a Red Hat bug explaining the problem.

Message notification
Notifications coming from Empathy and XChat-GNOME

Is there any other common application that you would like to be handled by my plugin? The only prerequisite is that they somehow use standard notification bubbles (and this means I cannot implement it for Skype).

If you are looking for the source code, it’s in this git repository.

by barisione at April 27, 2012 08:11 AM

Last updated:
May 17, 2012 07:45 AM
All times are UTC.

Subscriptions