To content | To menu | To search

Sunday, July 6 2014

Pulse Audio, Airplay device and XBMC

Here is my little howto explaining how I configured my Linux box to select the audio device (so I can choose between my monitor, or my hifi setup for audio)

1. Pulse Audio

Pulse Audio currently only support Airplay devices through TCP protocol. For devices using UDP, like mine, you need to patch Pulse Audio to add UDP support. Patches are available on http://hfujita.github.io/pulseaudio-raop2/

Run PulseAudio paprefs program, go to 'Network Access' tab, and verify that option 'Make discoverable Apple AirTunes sound devices available locally' is enabled.

Run PulseAudio manager program, go to 'Devices' tab, and note the name of the various sinks devices. Your Airplay device should be listed there, if discovered. Here is mine for example:

Sinks
 alsa_output.pci-0000_05_00.1.hdmi_stereo (video card HDMI output)
 alsa_output.pci-0000_00_1b.0.analog_stereo (PC jack output)
 raop_output.XC-HM71.local (Airplay device)

2. XBMC audio device switching script

Download xbmc-audio-switch.py here (it's a script I downloaded elsewhere, don't remember the original author though :( ).

You need to modify it to match your sinks listed above, at the start of the script:

def main():
    target_name = "alsa_output.pci-0000_00_1b.0.analog-stereo"
    target_vol = 100
    if sys.argv[1] == "2":
        target_name = "raop_output.XC-HM71.local"
        target_vol = 25
    if sys.argv[1] == "3":
        target_name = "alsa_output.pci-0000_05_00.1.hdmi-stereo"
        target_vol = 100

The target_vol option is used to force volume change when changing device, as many HiFi setups will not like volume being set to 100% as default (and neither you :) ). Of course you can add more devices, when ready, copy it to /usr/local/bin directory.

3. Configure XBMC hotkeys

Configure XBMC to use Pulse Audio for audio output. Now we need to configure hotkeys to use, to select the needed audio device. The file is $HOME/.xbmc/userdata/keymaps/keyboard.xml :

<keymap>
  <global>
    <keyboard>
      <f1>RunScript(/usr/local/bin/xbmc-audio-switch.py,1)</f1>
      <f2>RunScript(/usr/local/bin/xbmc-audio-switch.py,2)</f2>
      <f3>RunScript(/usr/local/bin/xbmc-audio-switch.py,3)</f3>
    </keyboard>
  </global>
</keymap>

Then pressing F1, F2 or F3 will call the script with parameter 1,2 or 3, which will then tells PulseAudio to change the current audio output device.

Thursday, December 11 2008

Incompatibility between FPU and non-FPU code

While trying to compile an FPU application, I came through a problem, as I used a library that did not have a FPU version, and was using a function that was returning a float value (a double value could also cause the problem).

Current ABI for non-FPU code is to have return value in d0; of course, FPU code expects return value in fp0 register.

Now, if your application, compiled for -m68020-60 (or -m68030 -m68881) is linked against a library, and calls a function returning a float or double value, which does not have a m68020-60 build, it will be linked against the m68020 or m68000 version of said library, which returns the value in d0, and your application behaves strangely, or does not work at all, and you wonder why for hours :).

To make it short:

- FPU application + FPU library = OK

- FPU application + non-FPU library = OK only for functions not returning float/double values, bugs for the ones that return value of said type, in register fp0.

- non-FPU application + FPU library = same problem as above, in reverse direction. If your system does not have a FPU, you'll trigger an exception as soon as you try to execute FPU code. If you have an FPU, the library will return the value in fp0, but the non-FPU application expects result in d0.

- non-FPU application + non-FPU library = OK.

What should be done?

Do not mix non-FPU code with FPU-code, it means when using -m68020-60 to compile an application, gcc/ld should never use m68020 or m68000 version of libraries. The reverse is of course not possible due to gcc/ld multilib settings. When you compile your application for m68000 or m68020, it never links to libraries in m68020-60. But I did not check what happens when you compile your code with -m68881.

Problem with multilib feature of gcc

I am using gcc 3.3 and binutils 2.13.2.1 (cross-compiler versions). I create a dummy library, with a single function, and tried linking a dummy program with different parameters:

gcc myprog.c -t -lmylib : default linking directory .
gcc myprog.c -t -m68020 -lmylib : default linking directory ./m68020
gcc myprog.c -t -m68020-60 -lmylib : default linking directory ./m68020-60

So everything is ok, now if I move mylib to a different directory, and use -L to link against it:

gcc myprog.c -t -Lmylib -lmylib : default linking directory . and mylib directory added for linking my library.
gcc myprog.c -t -m68020 -Lmylib -lmylib : default linking directory ./m68020 and mylib added to link my library.
gcc myprog.c -t -m68020-60 -Lmylib -lmylib : default linking directory ./m68020-60 and mylib directory added to link my library.

So everything is also ok in this case. The problem arises when the directory given as -L parameter is one of the default path used to search for libraries (/usr/lib, usr/local/lib):

If I install mylib in /usr/lib:

gcc monprog.c -t -L/usr/lib -lmylib : only /usr/lib used
gcc monprog.c -t -m68020 -L/usr/lib -lmylib : only /usr/lib used
gcc monprog.c -t -m68020-60 -L/usr/lib -lmylib : only /usr/lib used

So it appears -L disable multilib path generation, for the given directory. I suppose gcc also removes paths that appear several times. The problem in this case, is that paths for multilib are not used at all.

For example, the file libgcc.a which resides in a specific directory of gcc installation is not impacted by this (the libgcc.a is still the one from ., m68020 or m68020-60), but I think it could also happens if you add -L/path/to/libgcca

I did not try for gcc 4.3 and binutils 2.18.

This is a huge problem, because when you use extra libraries for your application, and linking parameters are given through the result of a mylib-config script output, or even pkg-config.

On my cross-compiler setup, all libraries are stored in the same directory, the ones that come from sparemint (with . m68020 and m68020-60) and the ones I compile, for example SDL, that have a pkg-config, and also a sdl-config that gives the path to libSDL.a using the -L parameter.

In my case, it means all applications I compiled for 68020 or 68020-60 and that use SDL, are linked against the 68000 version of the libraries. I suppose it is the same for people that use config script for libraries.

Monday, August 18 2008

Brainstorm's DSP JPEG decoder documentation

Official documentation from Brainstorm to use the DSP JPEG decoder. Thanks to Olivier Landemarre for original scanned document.

Continue reading...

Metados BOS driver doc

Small text describing how make a BOS driver for Metados.

Continue reading...

Videl Inside 2 doc

Small text describing how to program with Videl Inside 2.

Continue reading...

Screen Blaster 3 doc

Small text describing how to program with ScreenBlaster 3.

Continue reading...

Screen Blaster 2 doc

Small text describing how to program with ScreenBlaster 2.

Continue reading...

BlowUp doc

Small text describing how to program with BlowUp.

Continue reading...