kc0arf 68 Posting Virtuoso Team Colleague

Intro

This guide is for building a Linux audio server using RedHat Linux and Icecast / Ices combination. I write this guide with no expressed warrenty or liability for it's accuracy or completion. You may use at your own risk.

This is simply how I was able to get my linux box to receive external audio through the soundcard, and stream it on the internet.

Icecast is very powerful; different computers may be used to stream and digitize the audio. My setup here is for a simple setup of digitizing a single source-- the website icecast.org has instructions on how to make a more complex installation. If you do decide to have one computer host the mountpoints (be the place where your users will find the sounds) and another computer digitize the sounds (play the CD, or handle the microphone), then you should consider 2 network cards in the hosting computer, so that the NIC is not trying to stream input and output at the same time.


Setting up the computer

First, I created a new RedHat 9 installation, and installed most of the components. You will need to bring along the development tools, as some of the programs down the road will require you to compile them in order to use them. It is easier to set them up at installation time. Also, I had the soundcard and the ethernet card in the computer, so that the installer would configure them right away.

After I completed the installation, I also downloaded and installed pine and sndconfig. With pine, you receive a nice text editor called pico that may be used to edit text files, and sndconfig features a nice shell audio tool. You might also need to install lynx, the text-based web browser.

Next, boot the computer, and wire your sound source to the mic or line-in on the soundcard, and hook up headphones to the speaker jack. Use sndconfig to ensure the card is configured and loaded properly. You should hear your source coming through the headphones. Make sure your source audio has some "volume" to it, but do not put the volume all the way up.

Next, use aumix to adjust the sliders into the middle of the fields. Use the spacebar to select the proper input jack. Sometimes the field will not adjust to the proper setting. In my case, that turned out ok.

Next, as root, go to the file /etc/services, and add at the bottom of the file:

icecast <tab> 8000/udp
icecast <tab> 8000/tcp

replacing the <tab> with a tab key. Save the file.

Download more software

Once the sound is configured, make a directory somewhere to download your files, and keep the source together. Some people like /usr/src, others like to put them in a home directory. Next, launch lynx, and go to www.icecast.org, and obtain IceCast, Libshout, and Ices. Download these files to that directory you created.

Compile and install the software

Once the files are on your local system, use gzip and tar to untar the files. Then, build the binaries by executing "./configure" then "make", and then "make install". Be sure to read the associated README files in each directory. You will need to build Libshout before you build Ices.

IceCast Configuration

The part that was unclear to me in all of this was that IceCast behaves like Apache... it is the web interface to the audio stream. Once I built that relationship in my mind, I understood how and why things work the way they do.

Icecast installed the exe in /usr/local/bin/icecast
Icecast config is: /usr/local/etc/icecast.xml
icecast is launched by: icecast -c /location/where/config/is.xml

Here is my sample IceCast text:

[root@soundman etc]# cat icecast.xml
<icecast>
    <limits>
        <clients>100</clients>
        <sources>5</sources>
        <threadpool>5</threadpool>
        <queue-size>102400</queue-size>
        <client-timeout>30</client-timeout>
        <header-timeout>15</header-timeout>
        <source-timeout>10</source-timeout>
    </limits>

    <authentication>
        <!-- Sources log in with username 'source' -->
        <source-password>REPLACE</source-password>
        <!-- Relays log in username 'relay' -->
        <relay-password>closed</relay-password>

        <!-- Admin logs in with the username given below -->
        <admin-user>admin</admin-user>
        <admin-password>REPLACE</admin-password>
    </authentication>

    <hostname>127.0.0.1</hostname>

    <!-- You may have multiple <listener> elements -->
    <listen-socket>
        <port>8000</port>
    </listen-socket>

<!--
    <mount>
        <mount-name>/REPLACE.ogg</mount-name>
        <max-listeners>10</max-listeners>
        <dump-file>/tmp/dump-example1.ogg</dump-file>
        <fallback-mount>/irlp2.ogg</fallback-mount>
    </mount>
-->

    <fileserve>1</fileserve>

    <paths>
        <!-- basedir is only used if chroot is enabled -->
        <basedir>/usr/local/share/icecast</basedir>

        <!-- Note that if <chroot> is turned on below, these paths must both
             be relative to the new root, not the original root -->
        <logdir>/home/icecast</logdir>
        <webroot>/usr/local/share/icecast/web</webroot>
        <adminroot>/usr/local/share/icecast/admin</adminroot>
    </paths>

    <logging>
        <accesslog>access.log</accesslog>
        <errorlog>error.log</errorlog>
        <loglevel>4</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error -->
    </logging>

    <security>
        <chroot>0</chroot>

        <changeowner>
            <user>icecast</user>
            <group>icecast</group>
        </changeowner>

    </security>
</icecast>

Above, you will need to make note of the passwords (look at REPLACE), along with the mount point (REPLACE.ogg). I also added a user on my system called icecast, so that the software doesn't run with root privs, and I place all of the logs in that /home/icecast directory.


Setting up Libshout

Libshout places everything where it needs to be, so there is no needed special configuration.


Setting up Ices

Ices is the program that goes to the soundcard and grabs the audio for processing. Ices can also be used to grab audio from a CD-ROM or from the hard disk. My setup here uses the soundcard... other instructions are available on the website, or in the config folder.

Ices executable: /usr/local/bin/ices
Ices configuration: /usr/local/share/ices/*.xml (might be called ices.conf... you will have choices ices-live.xml and ices-playlist.xml I took ices-live.xml and copied it to ices.xml for my simplicity)
ices launched by: ices /directory/name/of/config.xml/file

[root@soundman ices]# cat ices.xml
<?xml version="1.0"?>
<ices>

    <!-- run in background  -->
    <background>0</background>
    <!-- where logs go. -->
    <logpath>SPECIFY A LOGPATH I USED /home/icecast</logpath>
    <logfile>ices.log</logfile>
    <logsize>2048</logsize>
    <!-- 1=error, 2=warn, 3=infoa ,4=debug -->
    <loglevel>4</loglevel>
    <!-- logfile is ignored if this is set to 1 -->
    <consolelog>0</consolelog>

    <!-- optional filename to write process id to -->
    <!-- <pidfile>/home/ices/ices.pid</pidfile> -->

    <stream>
        <!-- metadata used for stream listing -->
        <metadata>
            <name>NAME OF STREAM (TEXT)</name>
            <genre>NAME OF GENRE</genre>
            <description>NICE DESC</description>
            <url>URL FOR PUBLIC TO SEE</url>
        </metadata>

        <!--    Input module.

            This example uses the 'oss' module. It takes input from the
            OSS audio device (e.g. line-in), and processes it for live
            encoding.  -->
        <input>
            <module>oss</module>
            <param name="rate">44100</param>
            <param name="channels">2</param>
            <param name="device">/dev/dsp</param>
            <!-- Read metadata (from stdin by default, or -->
            <!-- filename defined below (if the latter, only on SIGUSR1) -->
            <param name="metadata">1</param>
            <param name="metadatafilename">FILEWITHDESC</param>
        </input>

        <!--    Stream instance.

            You may have one or more instances here.  This allows you to
            send the same input data to one or more servers (or to different
            mountpoints on the same server). Each of them can have different
            parameters. This is primarily useful for a) relaying to multiple
            independent servers, and b) encoding/reencoding to multiple
            bitrates.

            If one instance fails (for example, the associated server goes
            down, etc), the others will continue to function correctly.
            This example defines a single instance doing live encoding at
            low bitrate.  -->

        <instance>
            <!--    Server details.

                You define hostname and port for the server here, along
                with the source password and mountpoint.  -->

            <hostname>127.0.0.1</hostname>
            <port>8000</port>
            <password>REPLACE</password>
            <mount>/stream.ogg</mount>
            <yp>0</yp>   

            <!--    Live encoding/reencoding:

                channels and samplerate currently MUST match the channels
                and samplerate given in the parameters to the oss input
                module above or the remsaple/downmix section below.  -->

            <encode>  
                <quality>2</quality>
                <samplerate>11127</samplerate>
                <channels>1</channels>
            </encode>

            <!-- stereo->mono downmixing, enabled by setting this to 1 -->
            <downmix>1</downmix>

            <!-- resampling.
            
                Set to the frequency (in Hz) you wish to resample to, -->
             
            <resample>
                <in-rate>44100</in-rate>
                <out-rate>11127</out-rate>
            </resample>
        </instance>

    </stream>
</ices>

There are a couple things to note here:

First, look in the code where I have CAPS. Those need to be changed for your setup.
Also, make sure that your input module (look for module oss) is configured properly. Most ports will be at 44100 rate, and 2 channels (stereo). Also note the metadatafilename... this is a two-line file with text identifying author and groups. This file should be in the same directory that the ices.xml file is in.

In the next section, make sure your hostname information is correct. This should be the IP number of the ICECAST server, and the password that you defined in the ICECAST section. The mount is going to start with a / and be what the user types in in order to access your stream, so do not make it overly complicated.

The encoding section is tricky. Here we define if the Ices audioprocessor will downmix (downgrade) your audio sample. If you are using music, you don't want to tweak it much... a samplerate of 44100 and 2 channels would be nearly perfect, but no one with a modem would be able to hear it, due to bandwidth. Music at 22050 sample, and 2 channels sound fine in computer speakers. Since I am doing talking, I went further with 11127 kHz, and 1 channel, for a talk-radio mono transmission.
In the Re-sample section, the in-rate has to match your sample defined earlier in the input section, and the out-rate has to match your encode value. My settings are to take a 44100 stereo signal from the soundcard, and downmix it to a mono 11127 mono signal to the internet.

Time to Test it

In order to get this to work for me, I stayed out of X-windows, and opened three terminal shells in linux (use the ALT-F1 F2 F3) to access shell 1,2,3 respectively. I first turned on my audio source, and verified that the sound was coming through the headphones. I also typed in "aumix -L" to load my soundcard settings. In the first shell, I launched ICECAST. In the second shell, I launched ICES. In the third shell, I went to /home/icecast, and looked at all three logfiles to look for debug problems.

You should also do a "netstat -an | more" and make sure you see an entry for port 8000 on it.

You can also do a http://ipnumber:8000/admin/stats.xsl and see the information from icecast.

If for some reason, you need to kill the programs, a control-c should do it. Ices on my system locked it up cold, and I had to reboot. If you see an ices [defunct] in your "ps aux", then reboot the computer.

On another computer, you need to open a player for the .ogg file, and direct it tothe audio source. I used a program called VLC on my Mac to access my stream: http://192.168.1.75:8000/irlp2.ogg (that will not work for you... 192 is a private IP, so no, you cannot hit that and test it on my computer sorry!) My Mac came back screaming at me, and I realized that I need to adjust the input volume on my audio source (a radio), and the sliders in aumix (be sure to save then aumix -S) to make the audio level understandable (I was overdriving the soundcard -- too much sound will make it screech!).

Conclusion

The hardest part for me was to realize that ICECAST and ICES work together to make the stream possible. I did not know that I needed both pieces, and the word "mountpoint" threw me for a loop. But now, I have voice streaming in my home network. Very cool. I also found out that I can have three different computers playing the streams, and each will have their unique place in the broadcast -- they do not say the same words at the same time.

These instructions are a product of my notes setting up the system here at home. I have replicated the setup, but may have missed something in the typing. If anyone notices any gaps/corrections, please post them below.

I hope this can help someone else!

Christian