coLinux
Advertisement

(documentation from the ML and tested)

Since Windows already uses your computer sound card, coLinux cannot access the hardware. That being said ...

Applications running on Linux don't use the sound card hardware directly because only the kernel has permission to access it (if you can access hardware, you can change or bypass any security setting in the system).

So, userland applications access a device node in the filesystem (protected by file permissions), usually under /dev, which actually transfers data to a kernel module.

For sound, it's typically /dev/dsp.

The program then has to talk the protocol of the kernel module, which validates the requests and controls the hardware.

Since there are several protocols (ALSA, OSS ...) used by different sound cards drivers, generally another layer is added (GStreamer, JACK, PulseAudio, ESound, aRts, NAS ...).

Several of these layers (PulseAudio, ESound, JACK, NAS ...), in addition to using ALSA or OSS kernel modules as the backend to send audio data, also have the capability to send the audio data over the network, to another computer.

So, to hear sound from an application running on CoLinux, the trick is to use a _sound server_ in Windows that supports receiving audio streams from the network: applications running in coLinux will send audio streams over the network to this sound server, and the server will forward the audio data to your soundcard.

PulseAudio[]

This is the best solution so it comes first.

PulseAudio can be used as a virtual ALSA device and can also act as an ESound server, so it will let you run applications that want to use ALSA, OSS, JACK, GStreamer, ESound ... This means nearly all recent linux applications will work fine.

Compared to ESound, PulseAudio can be seen as its modern successor. It integrates with ALSA by providing a virtual device, while there was no way to do the same with ESound. Moreover, PulseAudio offers a far better (shorter) latency than ESound.

The main site for PulseAudio is: http://pulseaudio.org

Windows side (PulseAudio server)[]

You can download binaries for Windows here: http://www.cendio.com/pulseaudio

In the directory of the binaries, create a text config file named default.pa with the content:

load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16
load-module module-esound-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16
load-module module-detect

If you want the server to dynamically load/unload the device driver, use this instead of load-module module-detect:

add-autoload-sink output module-waveout sink_name=output
set-default-sink output

Once you've created the default.pa config file, start the server process by executing the pulseaudio.exe program.

PulseAudio can also be started automatically by adding the following line to the coLinux configuration file:

exec0=C:\Path\To\PulseAudio\pulseaudio.exe

CoLinux side[]

  • Install the libpulse0 library:
aptitude install libpulse0
  • Edit your /etc/pulse/client.conf to set the address of the Windows host that runs the PulseAudio server:
default-server = 192.168.0.1

where 192.168.0.1 is the IP address of the Windows host.

(If you prefer, you can achieve the same effect by adding "export PULSE_SERVER=192.168.0.1" to your ~/.bashrc --- or the equivalent for your shell of choice.)

ALSA support through the pulse virtual device[]

  • To be able to use ALSA, install the standard ALSA modules, which contain the PulseAudio virtual device:
aptitude install libasound2-plugins

You should then have a file /usr/lib/alsa-lib/libasound_module_pcm_pulse.so

  • Then edit your /etc/asound.conf:
pcm.!default {
    type pulse
}

ctl.!default {
    type pulse
}

pcm.pulse {
    type pulse
}

ctl.pulse {
    type pulse
}
  • Test with an ALSA player:
aplay /usr/share/sounds/alsa/Front_Center.wav

You should hear a voice saying "Front Center".

GStreamer support[]

(GStreamer is a multimedia API used, for example, by GNOME.) If you followed the instructions for ALSA support, then GStreamer should work out-of-the-box. Otherwise, you can add direct support for PulseAudio in Gstreamer:

  • Install the PulseAudio plugin for Gstreamer:
aptitude install libgstreamer-plugins-pulse0.10-0
  • To set it as the default sink (and/or source), start the gstreamer-properties config panel:
gstreamer-properties
  • Select "PulseAudio Sound Server"

Note: You may also use the "Autodetect", but it might pick up "ESD" which has bad latency.

  • Press the "Test" button. You should hear a sine tone.

Cygwin's ESound server[]

The PulseAudio server described above has ESound support and is recommended. However, you can also use Cygwin's ESound server.

If you don't already have cygwin installed get this this stripped-down cygwin package.

If you already have cygwin installed, you will probably already have the ESound server. To check, try starting a cygwin bash prompt and typing:

which esd

(Also, some Windows Media players are reported to support ESD plugins (more info needed on this))

  • start the sound server like this:
esd -tcp -public

important note: Don't use the -public option if you are not behind some firewall. Or you can set up an extra tap with private static IPs on both sides, and use -public with -bind to tell esd to only listen on the private network.

X Window server startup[]

If you use the X Window server on cygwin you should be able to automatically start the ESound deamon as part of the X server init script execution.

Using ESound clients on the CoLinux side[]

  • get some audio players with ESound support (Debian packages in this example):
aptitude install mpg123-esd
aptitude install alsaplayer-esd
...
  • tell these players where to stream the output:
export ESPEAKER=192.168.0.1:16001

where 192.168.0.1 is the IP address of the Windows host. 16001 is the default port the server is listening on, so you can omit it.

  • and finally, play whatever ogg/mp3 file you have at hand:
mpg123-esd demo.mp3

Desktop environment configuration[]

The Enlightened Sound Daemon (ESD) has been the default sound server for the GNOME desktop; you do not need to change any settings to use it.

The KDE desktop can be configured to use ESD, as well. In the Control Center, under "Sound & Multimedia", select the "System Sound" page, and make sure that Enlightend Sound Daemon is selected as the Audio "Device".

Special case for the ESound server that comes with NoMachine NX[]

NX software (http://www.nomachine.com/) includes a ESound server among other things (X server, ssh client).

NX (even the nxfree server) assigns a port in the 7000-7999 range for the X Window server (DISPLAY env var), and a corresponding port between 8000-8999 for the ESound server (ESPEAKER env var).

When the NX client establishes the connection with the NX server, the DISPLAY environment is set to "unix:XXXX.Y", where XXXX is the display number within the range the NX server is set to use, and Y is the display number (which will be 0 unless you've changed you setup).

As detailed at in the NX Server System Administrator's Guide (http://www.nomachine.com/documentation/html/admin-guide.html), when multimedia forwarding is enabled, multimedia is streamed on the TCP port XXXX+7000. In order for the NX client to receive this audio stream, applications running on the server must write their audio to this port.

The ESPEAKER env var can hence be deduced from the DISPLAY env var.

Environment setup on the CoLinux side[]

Environment setup for standard POSIX/Korn/Bourne/Bash shells[]

 if test -n "$NX_VERSION"
 then
 	# Setup the NX multimedia port (Esound)
 	nx_multimedia_port=$(echo $DISPLAY | sed -nre 's/unix:([0-9]+)(\.[0-9]*)?/\1/p')
 	if test -n "$PORT"
 	then
 		export ESPEAKER=localhost:$(($nx_multimedia_port + 7000))
 	fi
 	unset nx_multimedia_port
 fi

Environment setup for TCSh[]

This is a perl script to set the ESPEAKER env var correctly to output to NX's ESound server.

In .tcsh.config (this is the WRONG place, somebody please someone tell where to "load" it for X) to detect a NX connection:

if (${?NX_VERSION}) setenv ESPEAKER=`~/nxespeaker.pl`

~/nxespeaker.pl contains:

#! /usr/bin/env perl
use strict;
use warnings;
use strict 'subs';

$_ = $ENV{'DISPLAY'};
if (/:(\d+)$/) {
        print "localhost:" . (7000+$1);
}

The problem with this is that it only works for applications started from within shells (think konsole or gnome-terminal), but not for applications started directly from the kde/gnome menu.

Where to place the code that sets up the env var?[]

It is difficult to find the best place to set this variable. If you place it in your ~/.bashrc, you'll found that when it is executed, the DISPLAY variable is not yet set, making it impossible to determine the correct port for ESound.

A solution is to write a wrapper script to start a NX session. To do so, place the following into /usr/bin/nxsession:

#! /bin/sh

# Setup the NX multimedia port (Esound)
nx_multimedia_port=$(echo $DISPLAY | sed -nre 's/unix:([0-9]+)(\.[0-9]*)?/\1/p')
if test -n "$PORT"
then
        export ESPEAKER=localhost:$(($nx_multimedia_port + 7000))
fi
unset nx_multimedia_port

# Run the specified command
"$@"

This script will parse the DISPLAY env variable as set by NX, and export the appropriate ESPEAKER before executing whatever was passed as a parameter. Thus, it can safely wrap any command.

Then change your node.conf file, updating the COMMAND_START_KDE, COMMAND_START_GNOME, COMMAND_START_CDE, and COMMAND_XTERM entries to use this wrapper, i.g. COMMAND_START_KDE="nxsession startkde". This allows the wrapper script to be used even when directly selecting a session type using the NX client. Additionally, the wrapper script can be used with any other command executed with a Custom session type, in a similar manner.

NX Client configuration[]

The only other step is to ensure that "Enable Multimedia Support" is selected on Services tab of the connection settings in the NX client. Once done, this will forward all output from the ESound server to the NX client.

Shoutcast / Icecast streaming[]

Named either (Nullsoft) Shoutcast or icecast, it's quite popular to stream songs to Winamp and other players, you can also use this technique to stream audio data from colinux to your physical sound card.

For Debian, the packages are liveice, icecast-server, and icecast-streamer.

(to be continued)

KDE-Specific tweaks[]

The KDE can be configured to use an Esound server like GNOME. In the Control Center, under "Sound & Multimedia", select the "System Sound" page, and make sure that Enlightend Sound Daemon is selected as the Audio "Device".

KNotify has a "External Player" button. If you set this to esdplay you get all the desktop sounds. Probably don't need to set up ARTS for that. - Al Williams

To get artsd to work, install arts with esd support.

Optimising the network usage[]

Streaming CD-quality audio data means transfering 1.3Mb/s.

You should use a dedicated/exclusive network connection between Windows and CoLinux, separate from the connection to rest of the network: for example, use TAP exclusively for transmissions between Windows and CoLinux and give CoLinux LAN/Internet connectivity with WinPCap.

If you do not route the audio stream properly, you will likely hurt your main Internet connection to your ISP (Usual symptoms include connections to IRC servers being lost until you stop streaming data).

You can also put a limit to the bandwith being used by reducing the sound quality.

Without the network?[]

Isn't there a possibility to make a sound driver that uses coLinux primitives to discuss with windows and on windows to have a daemon which streams the sound to the sound card through DirectX or something like that? Leo

This will be especially important if people are using multiple channels on their soundcards. You are talking about streaming an awful lot of data over the local computer's network devices. The same applies to video devices. While it will probably not be feasable to allow the various linuxes to detect what hardware one has, there could be a special sound device that one might need to install in linux that knows about a colinux device that can deal directly with directshow (formerly Direct Sound) for audio and video. Perhaps this is only feasable for some colinux video device that will send its video to an outside app. This could be useful for, e.g. openGL games, which would be transparent to the user for full-screen games.

At a bare minimum, there should be one recommended and well-tested method of getting sound via the network, if that is the route employed. While many users might not expect to run graphic intensive games on colinux, it will always seem fundamentally incomplete without sound. Hope you guys can get a dent in it one day soon. -J

Advertisement