Index: src/slimaudio/slimaudio_buffer.c
===================================================================
--- src/slimaudio/slimaudio_buffer.c	(revision 261)
+++ src/slimaudio/slimaudio_buffer.c	(working copy)
@@ -69,10 +69,11 @@
 }
 
 void slimaudio_buffer_open(slimaudio_buffer_t *buf, void *user_data) {
+	struct buffer_stream *stream;
 	assert(buf);	
 	DEBUGF("buffer_open: %p\n", buf);
 	
-	struct buffer_stream *stream = (struct buffer_stream *) malloc(sizeof(struct buffer_stream));
+	stream = (struct buffer_stream *) malloc(sizeof(struct buffer_stream));
 	memset(stream, 0, sizeof(struct buffer_stream));
 	
 	stream->user_data = user_data;
@@ -116,14 +117,14 @@
 }
 
 void slimaudio_buffer_flush(slimaudio_buffer_t *buf) {
+	struct buffer_stream *stream, *next_stream;
+	
 	pthread_mutex_lock(&buf->buffer_mutex);
 
 	assert(buf);
 	
 	DEBUGF("buffer_flush: buf=%p\n", buf);
 	
-	struct buffer_stream *stream, *next_stream;
-	
 	stream = buf->read_stream;
 	while (stream != NULL) {
 		next_stream = stream->next;
@@ -162,7 +163,7 @@
 }
 
 void slimaudio_buffer_write(slimaudio_buffer_t *buf, char *data, int len) {
-	int free;
+	int free, trailing_space, remainder_len;
 
 	pthread_mutex_lock(&buf->buffer_mutex);
 	
@@ -194,7 +195,7 @@
 		free = buf->buffer_size - buf->total_available;
 	}
 
-	int trailing_space = buf->buffer_end - buf->write_ptr;
+	trailing_space = buf->buffer_end - buf->write_ptr;
 	if ( len < trailing_space) {
 		/* sufficient trailing space */
 		memcpy(buf->write_ptr, data, len);
@@ -208,7 +209,7 @@
 		data += trailing_space;
 
 		/* copy remainder to start */
-		int remainder_len = len - trailing_space;
+		remainder_len = len - trailing_space;
 		memcpy(buf->buffer_start, data, remainder_len);
 		buf->write_ptr = buf->buffer_start + remainder_len;
 	}
@@ -224,12 +225,15 @@
 }
 
 slimaudio_buffer_status slimaudio_buffer_read(slimaudio_buffer_t *buf, char *data, int *data_len) {
+	int len, trailing_data, remainder_len;
+	slimaudio_buffer_status status = SLIMAUDIO_BUFFER_STREAM_CONTINUE;
+
 	pthread_mutex_lock(&buf->buffer_mutex);
 	
 	assert(buf);
 	assert(data);
 
-	int len = *data_len;
+	len = *data_len;
 	
 	while (buf->total_available == 0) {
 		if (buf->read_stream == NULL)
@@ -290,7 +294,7 @@
 	buf->total_available -= len;
 	buf->read_stream->available -= len;
 
-	int trailing_data = buf->buffer_end - buf->read_ptr;
+	trailing_data = buf->buffer_end - buf->read_ptr;
 	if (len < trailing_data) {
 		/* sufficient trailing data */
 		memcpy(data, buf->read_ptr, len);
@@ -304,7 +308,7 @@
 		data += trailing_data;
 
 		/* copy remainder from start */		
-		int remainder_len = len - trailing_data;
+		remainder_len = len - trailing_data;
 		memcpy(data, buf->buffer_start, remainder_len);
 		buf->read_ptr = buf->buffer_start + remainder_len;		
 	}
@@ -314,7 +318,6 @@
 		pthread_cond_signal(&buf->read_cond);	
 	}
 	
-	slimaudio_buffer_status status = SLIMAUDIO_BUFFER_STREAM_CONTINUE;
 
 	if (buf->read_stream->read_count == 0) {
 		status = SLIMAUDIO_BUFFER_STREAM_START;		
Index: src/slimaudio/slimaudio_decoder_vorbis.c
===================================================================
--- src/slimaudio/slimaudio_decoder_vorbis.c	(revision 261)
+++ src/slimaudio/slimaudio_decoder_vorbis.c	(working copy)
@@ -25,7 +25,7 @@
 #include <assert.h>
 
 #define OV_EXCLUDE_STATIC_CALLBACKS
-#include <vorbis/vorbisfile.h>
+#include <tremor/ivorbisfile.h>
 
 #include "slimproto/slimproto.h"
 #include "slimaudio/slimaudio.h"
@@ -54,12 +54,16 @@
 
 int slimaudio_decoder_vorbis_process(slimaudio_t *audio) {
 	int err;
+	ov_callbacks callbacks;
+	int bytes_read;
+	int current_bitstream;
+	bool ogg_continue = true;
+	char buffer[AUDIO_CHUNK_SIZE];
 	
 	assert(audio != NULL);
 
 	DEBUGF("slimaudio_decoder_vorbis_process: start\n");
 	
-	ov_callbacks callbacks;
 	callbacks.read_func = vorbis_read_func;
 	callbacks.seek_func = vorbis_seek_func;
 	callbacks.close_func = vorbis_close_func;
@@ -73,10 +77,6 @@
 		return -1;
 	}
 	
-	int bytes_read;
-	int current_bitstream;
-	bool ogg_continue = true;
-	char buffer[AUDIO_CHUNK_SIZE];
 	
 	do {
 #if defined(NO_FPU) /* Use Tremor fixed point vorbis decoder */
@@ -126,7 +126,8 @@
 
 static size_t vorbis_read_func(void *ptr, size_t size, size_t nmemb, void *datasource) {
 	slimaudio_t *audio = (slimaudio_t *) datasource;
-	
+	int data_len;
+	slimaudio_buffer_status ok;
 	pthread_mutex_lock(&audio->decoder_mutex);
 
 	if (audio->decoder_state != STREAM_PLAYING) {
@@ -139,8 +140,8 @@
 	if (audio->decoder_end_of_stream)
 		return 0;
 	
-	int data_len = nmemb;
-	slimaudio_buffer_status ok = slimaudio_buffer_read(audio->decoder_buffer, ptr, &data_len);
+	data_len = nmemb;
+	ok = slimaudio_buffer_read(audio->decoder_buffer, ptr, &data_len);
 	if (ok == SLIMAUDIO_BUFFER_STREAM_END) {
 		audio->decoder_end_of_stream = true;
 	}
Index: src/slimaudio/slimaudio_decoder_flac.c
===================================================================
--- src/slimaudio/slimaudio_decoder_flac.c	(revision 261)
+++ src/slimaudio/slimaudio_decoder_flac.c	(working copy)
@@ -25,11 +25,11 @@
 #include <string.h>
 #include <assert.h>
 
-#include <FLAC/stream_decoder.h>
-
 #include "slimproto/slimproto.h"
 #include "slimaudio/slimaudio.h"
 
+#include <FLAC/stream_decoder.h>
+
 #ifdef SLIMPROTO_DEBUG
   #define DEBUGF(...) if (slimaudio_decoder_debug) fprintf(stderr, __VA_ARGS__)
   #define RDEBUGF(...) if (slimaudio_decoder_debug_r) fprintf(stderr, __VA_ARGS__)
@@ -65,6 +65,13 @@
 }
 
 int slimaudio_decoder_flac_process(slimaudio_t *audio) {
+#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT < 8
+	FLAC__StreamDecoderState s;
+#else
+	FLAC__StreamDecoderInitStatus s;
+#endif
+	FLAC__bool b;
+	
 	assert(audio != NULL);
 
 	DEBUGF("slimaudio_decoder_flac_process: start\n");
@@ -75,9 +82,9 @@
 	FLAC__stream_decoder_set_write_callback(audio->flac_decoder, flac_write_callback);
 	FLAC__stream_decoder_set_metadata_callback(audio->flac_decoder, flac_metadata_callback);
 	FLAC__stream_decoder_set_error_callback(audio->flac_decoder, flac_error_callback);
-	FLAC__StreamDecoderState s = FLAC__stream_decoder_init(audio->flac_decoder);
+	s = FLAC__stream_decoder_init(audio->flac_decoder);
 #else
-	FLAC__StreamDecoderInitStatus s = FLAC__stream_decoder_init_stream(audio->flac_decoder, flac_read_callback, NULL, NULL, NULL, NULL, flac_write_callback, flac_metadata_callback, flac_error_callback, audio);
+	s = FLAC__stream_decoder_init_stream(audio->flac_decoder, flac_read_callback, NULL, NULL, NULL, NULL, flac_write_callback, flac_metadata_callback, flac_error_callback, audio);
 #endif
 	if (s != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) {
 		DEBUGF("slimaudio_decoder_flac_process: init failed %i\n", s);
@@ -88,7 +95,7 @@
 
 	audio->decoder_end_of_stream = false;
 
-	FLAC__bool b = FLAC__stream_decoder_process_until_end_of_stream(audio->flac_decoder);
+	b = FLAC__stream_decoder_process_until_end_of_stream(audio->flac_decoder);
 	FLAC__stream_decoder_finish(audio->flac_decoder);
 
 	DEBUGF("slimaudio_decoder_flac_process: end\n");
@@ -97,6 +104,9 @@
 }
 
 static FLAC__StreamDecoderReadStatus flac_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) {
+	int data_len;
+	slimaudio_buffer_status ok;
+	
 	slimaudio_t *audio = (slimaudio_t *) client_data;
 	
 	pthread_mutex_lock(&audio->decoder_mutex);
@@ -118,8 +128,8 @@
 		return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;		
 	}
 	
-	int data_len = *bytes;
-	slimaudio_buffer_status ok = slimaudio_buffer_read(audio->decoder_buffer, (char*) buffer, &data_len);
+	data_len = *bytes;
+	ok = slimaudio_buffer_read(audio->decoder_buffer, (char*) buffer, &data_len);
 	if (ok == SLIMAUDIO_BUFFER_STREAM_END) {
 		DEBUGF("slimaudio_decoder_flac_process: EOS\n");
 		audio->decoder_end_of_stream = true;
Index: src/slimaudio/slimaudio_http.c
===================================================================
--- src/slimaudio/slimaudio_http.c	(revision 261)
+++ src/slimaudio/slimaudio_http.c	(working copy)
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <pthread.h>
+#include <sched.h>
 
 #ifdef __WIN32__
   #include <winsock.h>
@@ -105,11 +106,12 @@
 #ifdef SLIMPROTO_DEBUG				
 	int last_state = 0;
 #endif
+	/* Lower thread priority to give precedence to the decoder */
+	nice(5);
 
 #ifdef BSD_THREAD_LOCKING
 	pthread_mutex_lock(&audio->http_mutex);
 #endif
-
 	audio->http_state = STREAM_STOPPED;
 	
 	while (true) {
@@ -162,10 +164,15 @@
 
 void slimaudio_http_connect(slimaudio_t *audio, slimproto_msg_t *msg) {
 	int n;
+	struct sockaddr_in serv_addr = audio->proto->serv_addr;
+	const socket_t fd = socket(AF_INET, SOCK_STREAM, 0);
 
+	char http_hdr[HTTP_HEADER_LENGTH];
+	int pos = 0;
+	int crlf = 0;
+
 	slimaudio_http_disconnect(audio);
 	
-	struct sockaddr_in serv_addr = audio->proto->serv_addr;
 	if (msg->strm.server_ip != 0) {
 		serv_addr.sin_addr.s_addr = htonl(msg->strm.server_ip);
 	}
@@ -176,7 +183,6 @@
 	DEBUGF("slimaudio_http_connect: http connect %s:%i\n", 
 	       inet_ntoa(serv_addr.sin_addr), msg->strm.server_port);
 	
-	const socket_t fd = socket(AF_INET, SOCK_STREAM, 0);
 	if (fd < 0) {
 		perror("slimaudio_http_connect: Error opening socket");
 		return;
@@ -210,9 +216,6 @@
 	}
 
 	/* read http header */
-	char http_hdr[HTTP_HEADER_LENGTH];
-	int pos = 0;
-	int crlf = 0;
 	
 	do {
 		n = recv(fd, http_hdr+pos, 1, 0);
@@ -321,6 +324,8 @@
 static void http_recv(slimaudio_t *audio) {
 	char buf[AUDIO_CHUNK_SIZE];
 	struct timeval timeOut; 
+	int n;
+	
 	fd_set fdread;
 	u32_t decode_num_tracks_started;
 	u32_t autostart_threshold;
@@ -336,8 +341,16 @@
 		return;
 	}
 
-	int n = recv(audio->streamfd, buf, AUDIO_CHUNK_SIZE, 0);
+	while (slimaudio_buffer_available(audio->output_buffer) < AUDIO_CHUNK_SIZE * 2 &&
+		slimaudio_buffer_available(audio->decoder_buffer) >= AUDIO_CHUNK_SIZE * 8)
+	{
+		DEBUGF("http_recv: output_buffer %i below AUDIO_CHUNK_SIZE * 2\n", slimaudio_buffer_available(audio->output_buffer));
+		DEBUGF("http_recv: output_decoder_available %i\n", slimaudio_buffer_available(audio->decoder_buffer));
+		sched_yield();
+	}
 
+	n = recv(audio->streamfd, buf, AUDIO_CHUNK_SIZE, 0);
+
 	/* n == 0 http stream closed by server */
 	if (n <= 0)
 	{
Index: src/slimaudio/slimaudio_output.c
===================================================================
--- src/slimaudio/slimaudio_output.c	(revision 261)
+++ src/slimaudio/slimaudio_output.c	(working copy)
@@ -24,6 +24,7 @@
 #include <errno.h>
 #include <string.h>
 #include <limits.h>
+#include <math.h>
 
 #include <portaudio.h>
 #ifdef PA_WASAPI
@@ -288,7 +289,7 @@
 }
 
 static void *output_thread(void *ptr) {
-	int err;
+	int err, num_mixers, nbVolumes, volumeIdx;
 	struct timeval  now;
 	struct timespec timeout;
 	
@@ -302,8 +303,11 @@
                 exit(-1);
         }
 
+	errno = 0;
+	nice(-5); // Increase priority
+        DEBUGF("output_thread: nice errno: %i\n", errno);
         DEBUGF("output_thread: PortAudio initialized\n");
-	
+
 #ifndef PORTAUDIO_DEV
 	err = Pa_OpenStream(	&audio->pa_stream,	// stream
 				paNoDevice,		// input device
@@ -315,7 +319,7 @@
 				paInt16,		// output sample format
 				NULL,			// output driver info
 				44100.0,		// sample rate
-				256,			// frames per buffer
+				1152,			// frames per buffer
 				0,			// number of buffers
 				0,			// stream flags
 				pa_callback,		// callback
@@ -401,7 +405,7 @@
 	}
 
 #ifndef PORTAUDIO_DEV
-	int num_mixers = Px_GetNumMixers(audio->pa_stream);
+	num_mixers = Px_GetNumMixers(audio->pa_stream);
 	while (--num_mixers >= 0) {
 		DEBUGF("Mixer: %s\n", Px_GetMixerName(audio->pa_stream, num_mixers));
 	}
@@ -419,9 +423,8 @@
 		DEBUGF("PCM volume supported: %d.\n", 
 		       Px_SupportsPCMOutputVolume(audio->px_mixer));
 
-		const int nbVolumes = Px_GetNumOutputVolumes(audio->px_mixer);
+		nbVolumes = Px_GetNumOutputVolumes(audio->px_mixer);
 		DEBUGF("Nb volumes supported: %d.\n", nbVolumes);
-		int volumeIdx;
 		for (volumeIdx=0; volumeIdx<nbVolumes; ++volumeIdx) {
 			DEBUGF("Volume %d: %s\n", volumeIdx, 
 				Px_GetOutputVolumeName(audio->px_mixer, volumeIdx));
@@ -512,7 +515,16 @@
 				if (audio->output_STMs)
 				{
 					audio->output_STMs = false;
+					audio->decode_num_tracks_started++;
 
+					audio->replay_gain = audio->start_replay_gain;
+					audio->volume = audio->vol_adjust * audio->replay_gain;
+
+					if ( ( audio->volume == -1.0 ) || ( audio->volume > 1.0 ) )
+						audio->volume = 1.0;
+
+					audio->pa_streamtime_offset = audio->stream_samples;
+
 					DEBUGF("output_thread STMs-PLAYING: %llu\n",audio->pa_streamtime_offset);
 					output_thread_stat(audio, "STMs");
 				}
@@ -650,8 +662,13 @@
 
 #ifndef PORTAUDIO_DEV
 	if (audio->px_mixer != NULL) {
+#ifdef EMPEG
+		Px_SetMasterVolume(audio->px_mixer, (PxVolume)pow(audio->volume, 0.5));
+		DEBUGF("Master volume %f\n", Px_GetMasterVolume(audio->px_mixer));
+#else
 		Px_SetPCMOutputVolume(audio->px_mixer, (PxVolume)audio->volume);
-		DEBUGF("pcm volume %f\n", Px_GetPCMOutputVolume(audio->px_mixer));	
+		DEBUGF("pcm volume %f\n", Px_GetPCMOutputVolume(audio->px_mixer));
+#endif
 	}
 #endif		
 	return 0;
@@ -773,19 +790,20 @@
 	// read 'audio->volume' exactly once (assuming this operation is atomic)
 	// to make sure that volume changes performed while we are here will not
 	// cause any glitches.
-	const float newVolume = audio->volume;
-	float curVolume = audio->prev_volume;
-	audio->prev_volume = newVolume;
-	const float volumeIncr = (newVolume - curVolume) / (float)nbFrames;
-	short* const samples = (short*)outputBuffer;
-	const int nbSamples = nbFrames * 2;
-	int i;
-	for (i = 0; i < nbSamples; i += 2, curVolume += volumeIncr) {
-		samples[i]     = ((float)samples[i])     * curVolume;
-		samples[i + 1] = ((float)samples[i + 1]) * curVolume;
+	{
+		const float newVolume = audio->volume;
+		float curVolume = audio->prev_volume;
+		const float volumeIncr = (newVolume - curVolume) / (float)nbFrames;
+		short* const samples = (short*)outputBuffer;
+		const int nbSamples = nbFrames * 2;
+		int i;
+		audio->prev_volume = newVolume;
+		for (i = 0; i < nbSamples; i += 2, curVolume += volumeIncr) {
+			samples[i]     = ((float)samples[i])     * curVolume;
+			samples[i + 1] = ((float)samples[i + 1]) * curVolume;
+		}
+		VDEBUGF("volume: %f applied\n",newVolume);
 	}
-
-	VDEBUGF("volume: %f applied\n",newVolume);
 }
 
 // Writes pre-delay sample-frames into the output buffer passed in.
@@ -794,11 +812,13 @@
 // samples to turn on.
 static int produce_predelay_frames(slimaudio_t* audio, void* outputBuffer, unsigned int nbBytes)
 {
+	int i;
+	unsigned int predelayBytes;
 	// FIXME: Asuming 2 channels, 16 bit samples (i.e. 2 bytes)
 	const int frameSize = 2 * 2;
 	unsigned int predelayFrames = audio->output_predelay_frames;
 	const unsigned int maxFrames = nbBytes / frameSize;
-	
+		
 	if (predelayFrames > maxFrames) {
 	  	predelayFrames = maxFrames;
 	}
@@ -806,7 +826,7 @@
 	DEBUGF("slimaudio_output: producing %i predelay frames\n",
 	       predelayFrames);
 	
-	const unsigned int predelayBytes = predelayFrames * frameSize;
+	predelayBytes = predelayFrames * frameSize;
 	if (audio->output_predelay_amplitude == 0) {
 		memset((char*)outputBuffer, 0, predelayBytes);
 	}
@@ -825,7 +845,6 @@
 			// calls.
 			val = -val;
 		}
-		int i;
 		for ( i = 0; i < predelayFrames; ++i, val = -val ) {
 			samples[ 2 * i ] = samples[ 2 * i + 1] = val;
 		}
@@ -853,7 +872,7 @@
 	const int frameSize = 2 * 2;
 	const int len = framesPerBuffer * frameSize; 
 	
-	int off = 0;
+	int off = 0, uninitSize, data_len;
 
 	while ( (audio->output_state == PLAYING) && ((len - off) > 0) )
 	{
@@ -862,7 +881,7 @@
 			continue;
 		}
 
-		int data_len = len - off;
+		data_len = len - off;
 
 		if (slimaudio_buffer_available(audio->output_buffer) > 0)
 		{
@@ -872,13 +891,12 @@
 		{
 			ok = SLIMAUDIO_BUFFER_STREAM_UNDERRUN;
 			DEBUGF("pa_callback: SLIMAUDIO_BUFFER_STREAM_UNDERRUN\n");
+			break; // Added so playback would be silent on underrun
 		}
 
 		if (ok == SLIMAUDIO_BUFFER_STREAM_END) {
 			/* stream closed */
 			if (slimaudio_buffer_available(audio->output_buffer) == 0) {
-				pthread_mutex_lock(&audio->output_mutex);
-
 				// Send buffer underrun to Squeezebox Server. During
 				// normal play this indicates the end of the
 				// playlist. During sync this starts the next 
@@ -887,32 +905,18 @@
 
 				DEBUGF("pa_callback: STREAM_END:output_STMu:%i\n",audio->output_STMu);
 
-				pthread_mutex_unlock(&audio->output_mutex);
 				pthread_cond_broadcast(&audio->output_cond);
 			}
 		}
 		else if (ok == SLIMAUDIO_BUFFER_STREAM_START) {
-			pthread_mutex_lock(&audio->output_mutex);
-
 			/* Send track start to Squeezebox Server. During normal play
 			** this advances the playlist.
 			*/
 			audio->output_STMs = true;
 
-			audio->decode_num_tracks_started++;
-
-			audio->replay_gain = audio->start_replay_gain;
-			audio->volume = audio->vol_adjust * audio->replay_gain;
-
-			if ( ( audio->volume == -1.0 ) || ( audio->volume > 1.0 ) )
-				audio->volume = 1.0;
-
-			audio->pa_streamtime_offset = audio->stream_samples;
-
 			DEBUGF("pa_callback: STREAM_START:output_STMs:%i tracks:%i\n",
 				audio->output_STMs, audio->decode_num_tracks_started);
 
-			pthread_mutex_unlock(&audio->output_mutex);
 			pthread_cond_broadcast(&audio->output_cond);
 
 		}
@@ -933,7 +937,7 @@
 
 	}
 
-	const int uninitSize = len - off;
+	uninitSize = len - off;
 	if (uninitSize > 0) {
 	 	DEBUGF("slimaudio_output: pa_callback uninitialized bytes: %i\n", uninitSize);
 		memset((char *)outputBuffer+off, 0, uninitSize);
Index: src/slimaudio/slimaudio.c
===================================================================
--- src/slimaudio/slimaudio.c	(revision 261)
+++ src/slimaudio/slimaudio.c	(working copy)
@@ -230,6 +230,7 @@
 // server to signal the version.
 static int vers_callback(slimproto_t *p, const unsigned char *buf,
 			 int buf_len, void *user_data) {
+	slimproto_msg_t msg;
 
 	slimaudio_t* const audio = (slimaudio_t*)user_data;
 
@@ -240,7 +241,6 @@
 		return 0;
 	}
 
-	slimproto_msg_t msg;
 	slimproto_parse_command(buf, buf_len, &msg);
 	DEBUGF("Server version: %x\n", msg.vers.version);
 
@@ -291,9 +291,9 @@
 }
 
 static int connect_callback(slimproto_t *p, bool isConnected, void *user_data) {
+	slimaudio_t *audio = (slimaudio_t*)user_data;
 	if (!isConnected) {
 		DEBUGF("Stopping audio because of disconnection.\n");
-		slimaudio_t *audio = (slimaudio_t*)user_data;
 		audio_stop(audio);
 	}
 	
Index: src/slimaudio/slimaudio_decoder_pcm.c
===================================================================
--- src/slimaudio/slimaudio_decoder_pcm.c	(revision 261)
+++ src/slimaudio/slimaudio_decoder_pcm.c	(working copy)
@@ -58,6 +58,7 @@
 	while (ok != SLIMAUDIO_BUFFER_STREAM_END)
 	{
 		/* keep partial samples from last iteration */
+		int nsamples;
 		int remainder = data_len;
 		if (remainder > 0)
 		{
@@ -66,7 +67,7 @@
 		
 		data_len = AUDIO_CHUNK_SIZE-remainder;
 		ok = slimaudio_buffer_read(audio->decoder_buffer, (char*)(data+remainder), &data_len);
-		int nsamples = data_len / 2;
+		nsamples = data_len / 2;
 
 		/* convert buffer into samples */
 		ptr = data;
Index: src/slimaudio/slimaudio_decoder.c
===================================================================
--- src/slimaudio/slimaudio_decoder.c	(revision 261)
+++ src/slimaudio/slimaudio_decoder.c	(working copy)
@@ -155,6 +155,9 @@
 
 
 static void *decoder_thread(void *ptr) {
+	bool decoder_failed = false;	
+	unsigned char first_time = 1;
+
 	slimaudio_t *audio = (slimaudio_t *) ptr;
 #ifdef BSD_THREAD_LOCKING
 	pthread_mutex_lock(&audio->decoder_mutex);
@@ -162,9 +165,6 @@
 	
 	audio->decoder_state = STREAM_STOPPED;
 
-	bool decoder_failed = false;	
-	unsigned char first_time = 1;
-
 	while (true) {				
 		switch (audio->decoder_state) {
 			case STREAM_STOPPED:
Index: src/slimaudio/slimaudio.h
===================================================================
--- src/slimaudio/slimaudio.h	(revision 261)
+++ src/slimaudio/slimaudio.h	(working copy)
@@ -33,7 +33,7 @@
 #include <mad.h>
 #include <FLAC/stream_decoder.h>
 #define OV_EXCLUDE_STATIC_CALLBACKS
-#include <vorbis/vorbisfile.h>
+#include <tremor/ivorbisfile.h>
 
 #include "slimproto/slimproto.h"
 #include "slimaudio/slimaudio_buffer.h"
@@ -122,8 +122,8 @@
 	u64_t pa_streamtime_offset;
 	u64_t stream_samples;
 
-	bool output_STMs;
-	bool output_STMu;
+	volatile bool output_STMs;
+	volatile bool output_STMu;
 
 	int keepalive_interval;
 	
Index: src/slimaudio/slimaudio_decoder_mad.c
===================================================================
--- src/slimaudio/slimaudio_decoder_mad.c	(revision 261)
+++ src/slimaudio/slimaudio_decoder_mad.c	(working copy)
@@ -73,7 +73,7 @@
 }
 
 int slimaudio_decoder_mad_process(slimaudio_t *audio) {
-	int retcode = 0;
+	int retcode = 0, result;
 
 	/* configure input, output, and error functions */
     mad_decoder_init(&audio->mad_decoder, audio,
@@ -82,7 +82,7 @@
 
 	/* start decoding */
 	audio->decoder_end_of_stream = false;
-	int result = mad_decoder_run(&audio->mad_decoder, MAD_DECODER_MODE_SYNC);
+	result = mad_decoder_run(&audio->mad_decoder, MAD_DECODER_MODE_SYNC);
 	if (result != 0)
 		retcode = -1;
 
@@ -106,7 +106,8 @@
 		    struct mad_stream *stream)
 {
 	slimaudio_t *audio = (slimaudio_t *) data;
-	int remainder;
+	int remainder, data_len;
+	slimaudio_buffer_status ok;
 
 	pthread_mutex_lock(&audio->decoder_mutex);
 
@@ -130,9 +131,9 @@
 
 	memcpy (audio->decoder_data, stream->this_frame, remainder);
 	
-	int data_len = AUDIO_CHUNK_SIZE-MAD_BUFFER_GUARD-remainder;
+	data_len = AUDIO_CHUNK_SIZE-MAD_BUFFER_GUARD-remainder;
 	VDEBUGF("mad: data_len:%i remainder:%i available:%i\n", data_len, remainder, slimaudio_buffer_available(audio->decoder_buffer));
-	slimaudio_buffer_status ok = slimaudio_buffer_read(audio->decoder_buffer, audio->decoder_data + remainder, &data_len);
+	ok = slimaudio_buffer_read(audio->decoder_buffer, audio->decoder_data + remainder, &data_len);
 	if (ok == SLIMAUDIO_BUFFER_STREAM_END) {
 		DEBUGF("mad: SLIMAUDIO_BUFFER_STREAM_END\n");
 		memset(audio->decoder_data + remainder + data_len, 0, MAD_BUFFER_GUARD);
Index: src/slimproto/slimproto.c
===================================================================
--- src/slimproto/slimproto.c	(revision 256)
+++ src/slimproto/slimproto.c	(working copy)
@@ -24,6 +24,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
+#include <sys/poll.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <ctype.h>
@@ -118,7 +119,8 @@
 
 static void *proto_thread(void *ptr) {
 	int r, i;
-
+	bool disconnected;
+	
 	slimproto_t *p = (slimproto_t *) ptr;
 
 	pthread_mutex_lock(&p->slimproto_mutex);				
@@ -141,7 +143,7 @@
 
 				while (proto_recv(p) >= 0) {
 					pthread_mutex_lock(&p->slimproto_mutex);
-					const bool disconnected = p->state != PROTO_CONNECTED;
+					disconnected = p->state != PROTO_CONNECTED;
 					pthread_mutex_unlock(&p->slimproto_mutex);
 					if (disconnected) {
 						DEBUGF("proto_thread: disconnected state:%i\n", p->state);
@@ -174,9 +176,10 @@
 }
 
 void slimproto_add_command_callback(slimproto_t *p, const char *cmd, slimproto_command_callback_t *callback, void *user_data) {
+	int i;
 	pthread_mutex_lock(&p->slimproto_mutex);				
 
-	int i = p->num_command_callbacks;
+	i = p->num_command_callbacks;
 	p->command_callbacks[i].cmd = strdup(cmd);
 	p->command_callbacks[i].callback = (void *) callback; // FIXME
 	p->command_callbacks[i].user_data = user_data;
@@ -186,9 +189,10 @@
 }
 
 void slimproto_add_connect_callback(slimproto_t *p, slimproto_connect_callback_t *callback, void *user_data) {
+	int i;
 	pthread_mutex_lock(&p->slimproto_mutex);				
 
-	int i = p->num_connect_callbacks;
+	i = p->num_connect_callbacks;
 	p->connect_callbacks[i].callback = (void *) callback; // FIXME
 	p->connect_callbacks[i].user_data = user_data;
 	p->num_connect_callbacks++;
@@ -214,40 +218,81 @@
 		perror("Error setting TCP_NODELAY on socket");
 		retcode = -1;
 	}
-	else
+	else if (slimproto_configure_socket_sigpipe(sockfd) != 0)
 	{
-#ifndef __SUNPRO_C
-	if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout,  sizeof(timeout)))
-	{
-		perror("Error setting receive socket timeout");
-		retcode = -1;
-	}
-       	else
-	{
-	if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (void *)&timeout,  sizeof(timeout)))
-	{
-		perror("Error setting send socket timeout");
-		retcode = -1;
-	}
-	else
-	{
-#endif /* __SUNPRO_C */
-	if (slimproto_configure_socket_sigpipe(sockfd) != 0)
-	{
 		fprintf(stderr, "Couldn't configure socket for SIGPIPE.\n");
 		retcode = -1;
 	}
-#ifndef __SUNPRO_C
-	}
-	}
-#endif /* __SUNPRO_C */
-	}
 
+
 	return (retcode);
 }
 
+#define SLIMPROTO_DISCOVERY "eIPAD\0NAME\0JSON"
+
+int slimproto_discover(char * server_addr, int server_addr_len, int port)
+{
+	int sockfd;
+	int broadcast=1;
+	struct sockaddr_in sendaddr;
+	struct sockaddr_in recvaddr;
+	int try;
+	char buffer[100];
+	socklen_t sockaddr_len = sizeof(sendaddr);
+	struct pollfd pollfd;
+
+        if((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
+                perror("sockfd");
+                return -1;
+        }
+
+	pollfd.fd = sockfd;
+	pollfd.events = POLLIN;
+
+       if((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof broadcast)) == -1) {
+		perror("setsockopt - SO_BROADCAST");
+                return -1;
+        }
+
+        sendaddr.sin_family = AF_INET;
+        sendaddr.sin_port = htons(port);
+        sendaddr.sin_addr.s_addr = INADDR_ANY;
+        memset(sendaddr.sin_zero,'\0',sizeof sendaddr.sin_zero);
+
+        if(bind(sockfd, (struct sockaddr*) &sendaddr, sizeof sendaddr) == -1) {
+            perror("bind");
+            return -1;
+        }
+	recvaddr.sin_family = AF_INET;
+	recvaddr.sin_port = htons(port);
+	recvaddr.sin_addr.s_addr = INADDR_BROADCAST;
+	memset(recvaddr.sin_zero,'\0',sizeof recvaddr.sin_zero);
+
+	for (try = 0; try < 5; try ++) {
+		if (sendto(sockfd, SLIMPROTO_DISCOVERY, sizeof(SLIMPROTO_DISCOVERY), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr)) == -1) {
+			close(sockfd);
+			perror("sendto");
+			return -1;
+		}
+		fprintf(stderr, "Server discovery packet sent.\n");
+		/* Wait up to 1 second for response */
+		while (poll(&pollfd, 1, 1000)) {
+			if (recvfrom(sockfd, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr *)&sendaddr, &sockaddr_len) == -1) continue;
+			if (memcmp(buffer, "ENAME", 5)) continue;
+			buffer[buffer[5] + 6] = 0;
+			inet_ntop(AF_INET, &sendaddr.sin_addr.s_addr, server_addr, server_addr_len);
+			fprintf(stderr, "Server discovered: %s@%s\n", &buffer[6], server_addr);
+			close(sockfd);
+			return strlen(server_addr);
+		}
+	}
+	close(sockfd);
+	return -1;  /* Server not found */
+}
+
 int slimproto_connect(slimproto_t *p, const char *server_addr, int port) {
 	struct hostent *server;
+	int return_value = 0; 
 
 	DEBUGF("slimproto_connect: (%s, %i)\n", server_addr, port);
 
@@ -275,7 +320,6 @@
 	// Wait for confirmation that the connection opens correctly.  This
 	// will fail, for example, if Squeezebox Server is not running when the
 	// connection attempt happens.
-	int return_value = 0; 
 	while (p->state != PROTO_CONNECTED) {
 		pthread_cond_wait(&p->slimproto_cond, &p->slimproto_mutex);
 		if (p->state == PROTO_CLOSED) {
@@ -359,7 +403,7 @@
 static int proto_recv(slimproto_t *p) {
 	short len;
 	unsigned char buf[BUF_LENGTH];
-	int r, n;		
+	int r, n, i;
 
         /* Fix receive error on quiting */
 	if (p->state != PROTO_CONNECTED) return -1;
@@ -402,7 +446,6 @@
 	DEBUGF("proto_recv: cmd=%4.4s len=%i\n", buf+2, len);
 
 	buf[len]=0;
-	int i;
 	for (i=0; i<p->num_command_callbacks; i++) {
 		if (strncmp(p->command_callbacks[i].cmd, (char*)(buf+2), 4) == 0) {
 			int ok = (p->command_callbacks[i].callback)(p, buf, len, p->command_callbacks[i].user_data);
@@ -419,6 +462,9 @@
 }
 
 void slimproto_parse_command(const unsigned char *buf, int buf_len, slimproto_msg_t *msg) {
+	int http_len, val, i;
+	char str[2] = { '\0', '\0' };
+	
 	memset(msg, 0, sizeof(slimproto_msg_t));
 	
 	if (strncmp((char*)(buf+2), "strm", 4) == 0) {
@@ -441,7 +487,7 @@
 		msg->strm.replay_gain = unpackN4(buf, 20);
 		msg->strm.server_port = unpackN2(buf, 24);
 		msg->strm.server_ip = unpackN4(buf, 26);
-		int http_len = msg->strm.length-28;
+		http_len = msg->strm.length-28;
 
 		if (http_len > 0) {
 			assert(http_len+1 < sizeof(msg->strm.http_hdr));
@@ -463,10 +509,9 @@
 		msg->vers.length = unpackN2(buf, 0);
 		memcpy(msg->vers.cmd, buf+2, 4);
 
-		int val =  0;
+		val =  0;
 		// This assumes the version format is a.b.c, where
 		// a, b, c are numbers of at most 2 digits.
-		int i;
 		for( i = 6; i <= buf_len; ++i ) {
 			if(buf[i]=='.' || i == buf_len) {
 				msg->vers.version <<= 8;
@@ -475,7 +520,7 @@
 			}
 			else if (isdigit(buf[i])) {
 				val <<= 4;
-				char str[2] = { buf[i], '\0' };
+				str[0] = buf[i];
 				val += atoi(str);
 			}
 		}
@@ -487,6 +532,7 @@
 }
 
 int slimproto_dsco(slimproto_t *p, int dscoCode) {
+	unsigned char msg[SLIMPROTO_MSG_SIZE];
 
 	pthread_mutex_lock(&p->slimproto_mutex);
 	if (p->state != PROTO_CONNECTED) {
@@ -495,7 +541,6 @@
 	}
 	pthread_mutex_unlock(&p->slimproto_mutex);
 
-	unsigned char msg[SLIMPROTO_MSG_SIZE];
 	memset(&msg, 0, SLIMPROTO_MSG_SIZE);
 
 	packA4(msg, 0, "DSCO");
@@ -510,6 +555,7 @@
  * upgrade = 0x01 -> player is goint out for firmware upgrade
  */
 int slimproto_goodbye(slimproto_t *p, u8_t upgrade) {
+	unsigned char msg[SLIMPROTO_MSG_SIZE];
 
 	pthread_mutex_lock(&p->slimproto_mutex);
 	if (p->state != PROTO_CONNECTED) {
@@ -518,7 +564,6 @@
 	}
 	pthread_mutex_unlock(&p->slimproto_mutex);
 
-	unsigned char msg[SLIMPROTO_MSG_SIZE];
 	memset(&msg, 0, SLIMPROTO_MSG_SIZE);
 
         packA4(msg, 0, "BYE!");
@@ -530,6 +575,7 @@
 
 int slimproto_helo(slimproto_t *p, char device_id, char revision, const char *macaddress, char isGraphics, char isReconnect) {	
 	unsigned char msg[SLIMPROTO_MSG_SIZE];
+	int channelList = 0;
 	memset(&msg, 0, SLIMPROTO_MSG_SIZE);
 
 	packA4(msg, 0, "HELO");
@@ -537,7 +583,6 @@
 	packC(msg, 8, device_id);
 	packC(msg, 9, revision);
 	memcpy(msg+10, macaddress, 6);
-	int channelList = 0;
 	if (isGraphics)
 		channelList |= 0x8000;
 	if (isReconnect)
@@ -561,6 +606,31 @@
 	return slimproto_send(p, msg);
 }
 
+int slimproto_button(slimproto_t *p, int button) {
+	unsigned char msg[SLIMPROTO_MSG_SIZE];
+	memset(&msg, 0, SLIMPROTO_MSG_SIZE);
+
+	packA4(msg, 0, "BUTN");
+	packN4(msg, 4, 8);
+	slimproto_set_jiffies(p, msg, 8);
+	packN4(msg, 12, button);
+	
+	return slimproto_send(p, msg);
+}
+
+int slimproto_knob(slimproto_t *p, long position) {
+	unsigned char msg[SLIMPROTO_MSG_SIZE];
+	memset(&msg, 0, SLIMPROTO_MSG_SIZE);
+
+	packA4(msg, 0, "KNOB");
+	packN4(msg, 4, 9);
+	slimproto_set_jiffies(p, msg, 8);
+	packN4(msg, 12, ((unsigned long)position)); /* Signed relative position */
+	packC(msg, 16, 0);  /* Sync is always 0 */
+	
+	return slimproto_send(p, msg);
+}
+
 int slimproto_stat(slimproto_t *p, const char *code, int decoder_buffer_size, int decoder_buffer_fullness, u64_t bytes_rx, int output_buffer_size, int output_buffer_fullness, u32_t elapsed_milliseconds, u32_t server_timestamp)
 {
 	u32_t client_timestamp;
Index: src/slimproto/slimproto.h
===================================================================
--- src/slimproto/slimproto.h	(revision 256)
+++ src/slimproto/slimproto.h	(working copy)
@@ -135,6 +135,7 @@
 
 void slimproto_add_connect_callback(slimproto_t *p, slimproto_connect_callback_t *callback, void *user_data);
 
+int slimproto_discover(char * server_addr, int server_addr_len, int port);
 
 int slimproto_connect(slimproto_t *p, const char *server_addr, int port);
 
@@ -155,6 +156,10 @@
 
 int slimproto_goodbye(slimproto_t *, u8_t);
 
+int slimproto_button(slimproto_t *p, int button);
+
+int slimproto_knob(slimproto_t *p, long position);
+
 int slimproto_ir(slimproto_t *p, int format, int noBits, int irCode);
 
 int slimproto_stat(slimproto_t *, const char *, int, int, u64_t, int, int, u32_t, u32_t);
Index: src/squeezeslave/squeezeslave.h
===================================================================
--- src/squeezeslave/squeezeslave.h	(revision 261)
+++ src/squeezeslave/squeezeslave.h	(working copy)
@@ -53,9 +53,9 @@
 #include <unistd.h>
 #include <locale.h>
 #include <ctype.h>
-#include <curses.h>
+//#include <curses.h>
 #include <fcntl.h>
-#include <lirc/lirc_client.h>
+//#include <lirc/lirc_client.h>
 #ifndef __WIN32__
 #include <netinet/tcp.h> 
 #endif
@@ -84,12 +84,27 @@
 void daemonize(char *);
 #endif
 
-#ifdef INTERACTIVE
 #define packN4(ptr, off, v) { ptr[off] = (char)(v >> 24) & 0xFF; ptr[off+1] = (v >> 16) & 0xFF; ptr[off+2] = (v >> 8) & 0xFF; ptr[off+3] = v & 0xFF; }
 #define packC(ptr, off, v) { ptr[off] = v & 0xFF; }
 #define packA4(ptr, off, v) { strncpy((char*)(&ptr[off]), v, 4); }
+
+#ifdef EMPEG
+int empeg_getmac(char * mac_addr);
+void empeg_init(void);
+void close_lcd(void);
+void empeg_vfd_pwr(bool state);
+long empeg_getkey(void);
+long empeg_getircode(long key);
+int empeg_idle(void);
+void empeg_poweroff(void);
+void empeg_seteq_fromfile(void);
+void empeg_puteq_tofile(void);
+int empeg_vfd_callback(slimproto_t *, const unsigned char *, int, void *);
+int empeg_vfdbrt_callback(slimproto_t *, const unsigned char *, int, void *);
+#endif
+
+#ifdef INTERACTIVE
 void toggle_handler(int);
-int vfd_callback(slimproto_t *, const unsigned char *, int, void *);
 void receive_display_data(unsigned short *, int);
 bool charisok(unsigned char);
 void show_display_buffer(char *);
@@ -100,13 +115,11 @@
 void exitcurses(void);
 void initcurses(void);
 int read_lirc(void);
-void init_lcd (void);
 void init_lirc(void);
 void send_lcd(char*, int);
 bool read_lcd(void);
 int setNonblocking(int);
 void close_lirc(void);
-void close_lcd(void);
 #ifdef __WIN32__
 int inet_pton (int, const char *, void *);
 #endif
Index: src/squeezeslave/help.c
===================================================================
--- src/squeezeslave/help.c	(revision 261)
+++ src/squeezeslave/help.c	(working copy)
@@ -301,6 +301,9 @@
 #ifdef INTERACTIVE
 	fprintf(stdout, "interactive ");
 #endif
+#ifdef EMPEG
+	fprintf(stdout, "empeg ");
+#endif
 #ifdef DAEMONIZE
 	fprintf(stdout, "daemon ");
 #endif
@@ -392,6 +395,7 @@
 "                            If using LCDd, width is detected.\n"
 #endif
 #endif
+"-F, --discovery             Discover server IP automatically.\n"
 #ifdef DAEMONIZE
 "-M, --daemonize <logfile>   Run squeezeslave as a daemon.\n"
 "                            Messages written to specified file.\n"
@@ -413,6 +417,11 @@
 "                            is useful if the DAC used for output is slow to\n"
 "                            wake-up/lock, causing the first few samples to be\n"
 "                            dropped.\n"
+#ifdef EMPEG
+"-Q, --puteq                 Reads the empeg equalizer from the DSP and writes\n"
+"                            it to eq.dat\n"
+"-q, --geteq                 Reads the eq.dat file and configures the empeg eq\n"
+#endif
 "-R, --retry                 Causes the program to retry connecting to\n"
 "                            Squeezebox Server until it succeeds or is stopped\n"
 "                            using SIGTERM or keyboard entry.\n"
Index: src/squeezeslave/squeezeslave.c
===================================================================
--- src/squeezeslave/squeezeslave.c	(revision 261)
+++ src/squeezeslave/squeezeslave.c	(working copy)
@@ -64,6 +64,10 @@
 bool wasapi_exclusive = true;
 #endif
 
+#ifdef EMPEG
+int linelen = 128;
+#endif
+
 #ifdef INTERACTIVE
 struct lirc_config *lircconfig;
 int linelen = 40;
@@ -139,7 +143,7 @@
 
 // Called by the library when the connection is either established or broken.
 int connect_callback(slimproto_t *p, bool isConnected, void *user_data) {
-#ifdef INTERACTIVE
+#if defined(INTERACTIVE) || defined(EMPEG)
 	unsigned char msg[SLIMPROTO_MSG_SIZE];
 #endif
 
@@ -151,12 +155,16 @@
 #ifdef INTERACTIVE
 	if ( using_curses || using_lirc || use_lcdd_menu )
 	{
+#endif
+#if defined(INTERACTIVE) || defined(EMPEG)
                 memset(&msg, 0, SLIMPROTO_MSG_SIZE);
                 packA4(msg, 0, "SETD");
                 packN4(msg, 4, 2);
                 packC(msg, 8, 0xfe);
                 packC(msg, 9, linelen);
-               	slimproto_send(p, msg);
+                slimproto_send(p, msg);
+#endif
+#ifdef INTERACTIVE
 	}
 #endif
 	}
@@ -172,6 +180,7 @@
 }
 
 int main(int argc, char *argv[]) {
+	int exit_code = 0;
 	slimproto_t slimproto;
 	slimaudio_t slimaudio;
 
@@ -180,9 +189,13 @@
 
 	unsigned int output_predelay = 0;
 	unsigned int output_predelay_amplitude = 0;
-
+#ifdef EMPEG
+	bool power_bypass = false;
+	long key, ir;
+	slimaudio_volume_t volume_control = VOLUME_DRIVER;
+#else
 	slimaudio_volume_t volume_control = VOLUME_SOFTWARE;
-
+#endif
 	unsigned int retry_interval = RETRY_DEFAULT;
 
 	char macaddress[6] = { 0, 0, 0, 0, 0, 1 };
@@ -190,13 +203,14 @@
 	int keepalive_interval = -1;
 
 	bool listdevs = false;
+	bool discover_server = false;
 
 #ifdef DAEMONIZE
 	bool should_daemonize = false;
 	char *logfile = NULL;
 #endif
+	char slimserver_address[INET_ADDRSTRLEN] = "127.0.0.1";
 
-
 #ifdef INTERACTIVE
         fd_set read_fds;
         fd_set write_fds;
@@ -220,9 +234,10 @@
 	strcat(lircrc,"/.lircrc");
 #endif
 
-	char getopt_options[OPTLEN] = "a:d:Y:e:f:hk:Lm:n:o:P:p:Rr:Vv:";
+	char getopt_options[OPTLEN] = "a:d:Y:e:Ff:hk:Lm:n:o:P:p:Rr:Vv:";
 	static struct option long_options[] = {
 		{"predelay_amplitude", required_argument, 0, 'a'},
+		{"discover",           no_argument,       0, 'F'},
 		{"debug",              required_argument, 0, 'd'},
 		{"debuglog",           required_argument, 0, 'Y'},
 		{"help",               no_argument,       0, 'h'},
@@ -235,6 +250,10 @@
 		{"firmware",           required_argument, 0, 'f'},
 		{"port",               required_argument, 0, 'P'},
 		{"predelay",           required_argument, 0, 'p'},
+#ifdef EMPEG
+		{"puteq",              no_argument,       0, 'Q'},
+		{"geteq",              no_argument,       0, 'q'},
+#endif
 		{"retry",              no_argument,       0, 'R'},
 		{"intretry",           required_argument, 0, 'r'},
 		{"version",            no_argument,       0, 'V'},
@@ -260,6 +279,9 @@
 #endif
 		{0, 0, 0, 0}
 	};
+#ifdef EMPEG
+	strcat (getopt_options, "Qq");
+#endif
 #ifdef PORTAUDIO_DEV
 	strcat (getopt_options, "y:");
 #endif	
@@ -275,6 +297,11 @@
 	strcat (getopt_options, "S");
 #endif
 #endif
+
+#ifdef EMPEG
+	empeg_getmac(macaddress);
+#endif
+
 	while (true) {
 		const char shortopt =
 			getopt_long_only(argc, argv, getopt_options, long_options, NULL);
@@ -287,6 +314,9 @@
 		case 'a':
 			output_predelay_amplitude = strtoul(optarg, NULL, 0);
 			break;
+		case 'F':
+			discover_server = true;
+			break;
 		case 'd':
 #ifdef SLIMPROTO_DEBUG
 			if (strcmp(optarg, "all") == 0)
@@ -441,6 +471,15 @@
 			}
 			break;
 			break;
+#ifdef EMPEG
+		case 'Q':
+			empeg_puteq_tofile();
+			exit(0);
+			break;
+		case 'q':
+			empeg_seteq_fromfile();
+			break;
+#endif
 		case 'R':
 			retry_connection = true;
 			break;
@@ -515,6 +554,9 @@
 		exit(0);
 	}
 
+	strcpy(slimserver_address, "127.0.0.1");
+
+
 #ifdef DAEMONIZE
 	if ( should_daemonize ) {
 #ifdef INTERACTIVE
@@ -528,10 +570,8 @@
 			init_daemonize();
 	}
 #endif
-
-	char *slimserver_address = "127.0.0.1";
 	if (optind < argc)
-		slimserver_address = argv[optind];
+		strncpy(slimserver_address, argv[optind], sizeof(slimserver_address));
 
 	signal(SIGTERM, &exit_handler);
 	install_restart_handler();
@@ -556,6 +596,10 @@
 	if ( using_curses || using_lirc || use_lcdd_menu )
 		slimproto_add_command_callback(&slimproto, "vfdc", vfd_callback, macaddress);
 #endif
+#ifdef EMPEG
+	slimproto_add_command_callback(&slimproto, "grfe", empeg_vfd_callback, macaddress);
+	slimproto_add_command_callback(&slimproto, "grfb", empeg_vfdbrt_callback, macaddress);
+#endif
 
 	slimaudio_set_volume_control(&slimaudio, volume_control);
 	slimaudio_set_output_predelay(&slimaudio, output_predelay, output_predelay_amplitude);
@@ -567,13 +611,14 @@
 #ifdef INTERACTIVE
 	init_lcd();
 #endif
+#ifdef EMPEG
+	empeg_init();
+#endif
 
 	if (slimaudio_open(&slimaudio) < 0) {
 		fprintf(stderr, "Failed to open slimaudio\n");
-#ifdef INTERACTIVE
-		close (lcd_fd);
-#endif
-		exit(-1);
+		exit_code = -1;
+		goto exit;
 	}
 
 #ifdef SLIMPROTO_DEBUG
@@ -595,26 +640,30 @@
 	// When retry_connection is true, retry connecting to Squeezebox Server 
 	// until we succeed, unless the signal handler tells us to give up.
 	do {
+		while (discover_server && slimproto_discover(slimserver_address, sizeof(slimserver_address), port) < 0) {
+			fprintf(stderr, "Unable to discover server.\n");
+			if (signal_exit_flag) {
+				exit_code = 0;
+				goto exit;
+			}
+			else if (!retry_connection) {
+				exit_code = -1;
+				goto exit;
+			}
+		}
+
 		while (slimproto_connect(
 			&slimproto, slimserver_address, port) < 0) {
 			if (!retry_connection || signal_exit_flag) {
 				if (signal_exit_flag) {
 					// No message when the exit is triggered
 					// by the user.
-#ifdef INTERACTIVE
-					exitcurses();
-					close_lirc();
-					close_lcd();
-#endif
-					exit(0);
+					exit_code = 0;
+					goto exit;
 				}
-#ifdef INTERACTIVE
-				exitcurses();
-				close_lirc();
-				close_lcd();
-#endif
 				fprintf(stderr, "Connection to Squeezebox Server %s failed.\n", slimserver_address);
-				exit(-1);
+				exit_code = -1;
+				goto exit;
 			}
 #ifdef INTERACTIVE
 			exitcurses();
@@ -627,6 +676,42 @@
 		}
                 signal_restart_flag = false;
                 while (!signal_exit_flag && !signal_restart_flag) {
+#ifdef EMPEG
+		   int rc = empeg_idle();
+		   if (power_bypass)
+		   {
+		      if (rc == 0)
+		         power_bypass = false;
+		   }
+		   else if (rc == -1)
+		   {
+		     fprintf(stderr, "Power loss detected.\n");
+		     empeg_vfd_pwr(false);
+		     slimproto_goodbye(&slimproto, 0x00);
+		     continue;
+		   }
+		   else if (rc == -2)
+		   {
+		     if (empeg_getkey() == -1)
+		        continue;
+		     fprintf(stderr, "Keypress detected, staying on.\n");
+		     empeg_vfd_pwr(true);
+		     power_bypass = true;
+		   }
+		   else if (rc == -3)
+		   {
+		     fprintf(stderr, "Power restored.\n");
+		     empeg_vfd_pwr(true);
+		   }
+		   else if (rc == -4)
+		   {
+		      fprintf(stderr, "Powering down.\n");
+		      Pa_Sleep(400);
+		      empeg_poweroff();
+		      exit_code = 0;
+		      goto exit;
+		   }
+#endif
 #ifdef INTERACTIVE
                    if (using_curses == 1 || use_lcdd_menu || using_lirc) {
                       FD_ZERO(&read_fds);
@@ -688,8 +773,17 @@
                       wait_for_restart_signal();
 		   }
 #else
+#ifdef EMPEG
+                   while ((key = empeg_getkey()) != -1)
+                   {
+                      ir = empeg_getircode(key);
+                      if (ir != 0)
+                         slimproto_ir(&slimproto, 1, 1, ir);
+                   }
+#else
                    wait_for_restart_signal();
 #endif
+#endif
 		}
 #ifdef INTERACTIVE
                 FD_ZERO(&read_fds);
@@ -707,6 +801,7 @@
 		}
         } while (signal_restart_flag && !signal_exit_flag);
 
+exit:
 #ifdef INTERACTIVE
 	close_lirc();
 #endif
@@ -723,6 +818,10 @@
         exitcurses();
         close_lcd();
 #endif
+#ifdef EMPEG
+	close_lcd();
+#endif
+
 #ifdef SLIMPROTO_DEBUG
 	if (debug_logfile)
 	{
@@ -733,6 +832,6 @@
 	slimaudio_destroy(&slimaudio);
 	slimproto_destroy(&slimproto);
 
-	return 0;
+	return exit_code;
 } 
 
Index: src/squeezeslave/empeg.c
===================================================================
--- src/squeezeslave/empeg.c	(revision 0)
+++ src/squeezeslave/empeg.c	(revision 0)
@@ -0,0 +1,362 @@
+/*
+ *   SlimProtoLib Copyright (c) 2004,2006 Richard Titmuss
+ *
+ *   This file is part of SlimProtoLib.
+ *
+ *   SlimProtoLib is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   SlimProtoLib is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with SlimProtoLib; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+
+#ifdef EMPEG
+#include "squeezeslave.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <net/if.h>
+#include <ctype.h>
+#include <fcntl.h>
+
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <sys/ioctl.h>
+#include <asm/arch-sa1100/empeg.h>
+
+#define DISPLAY_DEV "/dev/display"
+#define POWER_DEV "/dev/empeg_power"
+#define IR_DEV "/dev/ir"
+#define MIXER_DEV "/dev/mixer"
+
+/*
+ * Front panel buttons
+ */
+
+#define IR_TOP_BUTTON_PRESSED       0x00000000
+#define IR_TOP_BUTTON_RELEASED      0x00000001
+#define IR_RIGHT_BUTTON_PRESSED     0x00000002
+#define IR_RIGHT_BUTTON_RELEASED    0x00000003
+#define IR_LEFT_BUTTON_PRESSED      0x00000004
+#define IR_LEFT_BUTTON_RELEASED     0x00000005
+#define IR_BOTTOM_BUTTON_PRESSED    0x00000006
+#define IR_BOTTOM_BUTTON_RELEASED   0x00000007
+#define IR_KNOB_BUTTON_PRESSED      0x00000008
+#define IR_KNOB_BUTTON_RELEASED     0x00000009
+#define IR_KNOB_UP                  0x0000000A
+#define IR_KNOB_DOWN                0x0000000B
+
+extern const int linelen;
+
+int vfd_fd, power_fd, mixer_fd, ir_fd;
+caddr_t vfd_map;
+
+struct empeg_eq_section_t empeg_eq_sections[20];
+
+int empeg_getmac(char * mac_addr)
+{
+    int s;
+    struct ifreq buffer;
+
+    s = socket(PF_INET, SOCK_DGRAM, 0);
+
+    memset(&buffer, 0x00, sizeof(buffer));
+
+    strcpy(buffer.ifr_name, "eth0");
+
+    ioctl(s, SIOCGIFHWADDR, &buffer);
+
+    close(s);
+
+    memcpy(mac_addr, buffer.ifr_hwaddr.sa_data, 6);
+
+    return 0;
+}
+
+void empeg_vfd_pwr(bool state)
+{
+   state = state ? 1 : 0;
+   ioctl(vfd_fd, EMPEG_DISPLAY_POWER, state); // turn LCD and amp remote on/off
+}
+
+// Close LCD connection (if open)
+void close_lcd(void)
+{
+   empeg_vfd_pwr(false);
+   munmap(vfd_map, 2048);
+   close (vfd_fd);
+   close (power_fd);
+   close (mixer_fd);
+   close (ir_fd);
+}
+
+void empeg_puteq_tofile(void)
+{
+   int wr_fd, io_fd, rc;
+
+   fprintf(stderr, "Writing current EQ to 'eq.dat'\n");
+   io_fd = open(MIXER_DEV, O_RDWR);
+   wr_fd = open("eq.dat", O_WRONLY | O_CREAT);
+   ioctl(io_fd, EMPEG_MIXER_GET_EQ, empeg_eq_sections);
+   rc = write(wr_fd, empeg_eq_sections, sizeof(empeg_eq_sections));
+   fprintf(stderr, "Bytes written %i\n", rc);
+   close(wr_fd);
+   close(io_fd);
+}
+
+// convert from -6dB(32) - 0dB(64) - +6dB(128) to DSP value
+int eq_gain[13] = {32, 36, 40, 44, 50, 56, 64, 72, 82, 90, 102, 114, 128 };
+
+void empeg_seteq_section(int channel, int band, int cent_freq, int q, int gaindb)
+{
+   int i = channel * 5 + band;
+
+   if (gaindb > 6) gaindb = 6;
+   if (gaindb < -6) gaindb = -6;
+
+   empeg_eq_sections[i].word1 = cent_freq;
+   empeg_eq_sections[i].word2 = q << 7 | (eq_gain[gaindb + 6]);
+}
+
+void empeg_seteq(void)
+{
+   /* Set EQ to 4 channel */
+   ioctl(mixer_fd, EMPEG_MIXER_SET_EQ_FOUR_CHANNEL, (int)1);
+   /* Set all EQ sections */
+   ioctl(mixer_fd, EMPEG_MIXER_SET_EQ, empeg_eq_sections);
+}
+
+void empeg_seteq_fromfile(void)
+{
+   int fd = open("eq.dat", O_RDONLY);
+   memset(&empeg_eq_sections, 0, sizeof(empeg_eq_sections));
+   read(fd, &empeg_eq_sections, sizeof(empeg_eq_sections));
+   close(fd);
+
+   empeg_seteq();
+}
+
+// If it succeeeds configure hardware
+// If it fails, print a message, disable support and continue
+void empeg_init(void)
+{
+   vfd_fd = open(DISPLAY_DEV, O_RDWR);
+   if (vfd_fd <= 0)
+   {
+      fprintf(stderr,"Connect to LCD failed!\n");
+      exit(1);
+   }
+
+   vfd_map = mmap(0,2048, PROT_READ | PROT_WRITE, MAP_SHARED, vfd_fd, 0);
+   if (vfd_map == (caddr_t) -1)
+   {
+      close(vfd_fd);
+      return;
+   }
+   empeg_vfd_pwr(true); // turn VFD and amp remote on
+   memset(vfd_map, 0, 2048); // clear VFD
+   ioctl(vfd_fd, EMPEG_DISPLAY_REFRESH);
+
+   power_fd = open(POWER_DEV, O_RDWR);
+
+   mixer_fd = open(MIXER_DEV, O_RDWR);
+   empeg_seteq_fromfile();
+
+   ir_fd = open(IR_DEV, O_RDONLY/* | O_NDELAY*/);
+
+   fprintf(stderr,"Empeg hardware init complete!\n");
+}
+
+bool power_flag = false;
+unsigned long power_timer = 0;
+
+int empeg_idle(void)
+{
+   unsigned int pwr_state;
+   struct timeval tnow;
+
+   gettimeofday(&tnow, NULL);
+
+   ioctl(power_fd, EMPEG_POWER_READSTATE, &pwr_state);
+   if ((pwr_state & EMPEG_POWER_FLAG_DC) && !(pwr_state & EMPEG_POWER_FLAG_ACCESSORY))
+   {
+      if (!power_flag)
+      {
+         power_flag = true;
+         power_timer = tnow.tv_sec;
+         fprintf(stderr, "Power state:0x%X\n", pwr_state);
+         return -1; // pause return code
+      }
+      else if (power_timer + 300 < tnow.tv_sec)
+         return -4; // power down return code
+      return -2;
+   }
+   else if (power_flag)
+   {
+      power_flag = false;
+      return -3;
+   }
+
+   return 0;
+}
+
+void empeg_poweroff(void)
+{
+   ioctl(power_fd, EMPEG_POWER_TURNOFF, 0); // turn off empeg
+}
+
+struct
+{
+    bool down;
+    unsigned long timer;
+    long downcode;
+    long upcode;
+    long downir;
+    long upir;
+} keys[5] = {
+   {false, 0, IR_TOP_BUTTON_PRESSED, IR_TOP_BUTTON_RELEASED, 0x00010012, 0x00020012 },
+   {false, 0, IR_BOTTOM_BUTTON_PRESSED, IR_BOTTOM_BUTTON_RELEASED, 0x0001000D, 0x0002000D },
+   {false, 0, IR_RIGHT_BUTTON_PRESSED, IR_RIGHT_BUTTON_RELEASED, 0x00010011, 0x00020011 },
+   {false, 0, IR_LEFT_BUTTON_PRESSED, IR_LEFT_BUTTON_RELEASED, 0x00010010, 0x00020010 },
+   {false, 0, IR_KNOB_BUTTON_PRESSED, IR_KNOB_BUTTON_RELEASED, 0x0001000E, 0x0002000E },
+};
+
+#define REPEAT_RATE 30
+
+long empeg_getkey(void)
+{
+   int i;
+   long key = -1;
+   struct pollfd pollfd = { ir_fd, POLLIN, 0 };
+   struct timeval tnow;
+   unsigned long timer;
+
+   gettimeofday(&tnow, NULL);
+   timer = tnow.tv_sec * 1000 + tnow.tv_usec / 1000;
+
+   for (i = 0; i < 5; i ++)
+   {
+      if (keys[i].down && keys[i].timer + (1000 / REPEAT_RATE) < timer)
+      {
+         keys[i].timer = timer;
+         return keys[i].downcode;
+      }
+   }
+
+   if (!poll(&pollfd, 1, (1000 / REPEAT_RATE))) return -1;
+   read(ir_fd, (char *) &key, 4);
+   return key;
+}
+
+long empeg_getircode(long key)
+{
+   int i;
+   struct timeval tnow;
+   unsigned long timer;
+
+   gettimeofday(&tnow, NULL);
+   timer = tnow.tv_sec * 1000 + tnow.tv_usec / 1000;
+
+   if (key == IR_KNOB_UP)
+      return 0x0001005B;
+   else if (key == IR_KNOB_DOWN)
+      return 0x0001005A;
+
+   for (i = 0; i < 5; i ++) 
+   {
+      if (key == keys[i].downcode)
+      {
+         keys[i].down = true;
+         keys[i].timer = timer;
+         return keys[i].downir;
+      }
+      else if (key == keys[i].upcode)
+      {
+         if (!keys[i].down) return 0;
+         keys[i].down = false;
+         return keys[i].upir;
+      }
+   }
+   return 0;
+}
+
+// Called by the library when a vfd command is received.
+int empeg_vfd_callback(slimproto_t *p, const unsigned char * buf, int len , void *user_data) 
+{
+   int i = 10, j, row, clm;
+   char temp;
+//   int offset = buf[10] << 8 | buf[1]; // unpackN2
+//   char transition = buf[12];
+//   int tParam = buf[13];
+//   int width = (len - 14) / 4;
+
+   if (p->state == PROTO_CONNECTED) {
+       /* Translate from row->column 1 bpp to column->row, 4 bpp */
+       for (clm = 0; clm < 128/2; clm ++)
+       {
+          for (row = 0; row < 32; row += 8, i ++)
+          {
+             temp = buf[i];
+             for (j = 0; j < 8; j ++)
+             {
+                vfd_map[((row + j) << 6) + clm] = temp >> 7 ? 0x3 : 0; // Set both bits if pixel on
+                temp <<= 1;
+             }
+          }
+          for (row = 0; row < 32; row += 8, i ++)
+          {
+             temp = buf[i];
+             for (j = 0; j < 8; j ++)
+             {
+                vfd_map[((row + j) << 6) + clm] |= (temp >> 7 ? 0x3 : 0) << 4;
+                temp <<= 1;
+             }
+          }
+       }
+
+       ioctl(vfd_fd, EMPEG_DISPLAY_REFRESH);
+   }
+   return 0;
+}
+
+int empeg_vfdbrt_callback(slimproto_t *p, const unsigned char * buf, int len , void *user_data)
+{
+   char b;
+
+   switch(buf[0] << 8 | buf[1])
+   {
+      case 65535:
+         b = 0;
+         break;
+      case 0:
+         b = 1;
+         break;
+      case 1:
+         b = 2;
+         break;
+      case 3:
+         b = 4;
+         break;
+      case 4:
+         b = 8;
+         break;
+      default:
+         b = 8;
+         break;
+   }
+   return 0;
+}
+#endif
+
Index: contrib/makefile.linux22-empeg
===================================================================
--- contrib/makefile.linux22-empeg	(revision 0)
+++ contrib/makefile.linux22-empeg	(revision 0)
@@ -0,0 +1,134 @@
+# Linux 2.2 OSS armel empeg
+# Uses Tremor fixed point vorbis decoder.
+OS=lnx24
+CC=gcc
+CXX=g++
+TAR=tar
+CP=cp
+SED=sed
+SHELL=/bin/bash
+PATCH=patch
+CFLAGS=-DSLIMPROTO_DEBUG -DDAEMONIZE -DUSE_SIGNALS_FOR_RESTART -DNO_FPU -Wall -O3 -march=armv4 -mtune=strongarm1100 -g
+LDFLAGS=
+
+# Comment out these two lines to remove display support
+#CFLAGS+=-DINTERACTIVE
+#LIBS+=/usr/lib/libncurses.a lib/lirc/$(OS)/lib/liblirc_client.a
+CFLAGS+=-DEMPEG
+# -DINTERACTIVE
+
+INCLUDE=-Ilib/getopt -Ilib/portaudio/pa_common -Ilib/portaudio/pablio -Ilib/portmixer/px_common -Isrc -I/usr/local/armtools-empeg/arm-empeg-linux/include
+
+PORTAUDIOFILES:=lib/portaudio/pa_unix_oss/pa_unix.c lib/portaudio/pa_unix_oss/pa_unix_oss.c  lib/portaudio/pa_common/pa_lib.c lib/portaudio/pa_common/pa_convert.c lib/portaudio/pablio/ringbuffer.c
+
+LIBMAD=libmad-0.15.1b
+LIBOGG=libogg-1.2.2
+LIBVORBIS=tremor-r17503
+LIBFLAC=flac-1.2.1
+#LIBLIRC=lirc-0.8.6
+
+PORTMIXERFILES:=lib/portmixer/px_unix_oss/px_unix_oss.c
+
+GETOPTFILES=lib/getopt/getopt.c lib/getopt/getopt1.c
+
+SLIMPROTOFILES:=src/slimaudio/slimaudio_http.c src/slimaudio/slimaudio_decoder.c src/slimaudio/slimaudio_decoder_flac.c src/slimaudio/slimaudio_decoder_mad.c src/slimaudio/slimaudio_decoder_vorbis.c src/slimaudio/slimaudio_decoder_pcm.c src/slimaudio/slimaudio_output.c src/slimaudio/slimaudio_buffer.c src/slimaudio/slimaudio.c src/slimproto/slimproto.c
+
+SQUEEZESLAVEFILES:=src/squeezeslave/squeezeslave.c src/squeezeslave/help.c src/squeezeslave/daemonize.c src/squeezeslave/empeg.c
+
+LIBPORTAUDIO=lib/libportaudio.a
+
+LIBSLIMPROTO=lib/libslimproto.a
+
+LIBGETOPT=lib/libgetopt.a
+
+SUPPORTLIBS=lib/libportaudio.a lib/libmad.a lib/libvorbisidec.a lib/libogg.a lib/libFLAC.a
+
+SQUEEZESLAVE=bin/squeezeslave
+
+.c.o:
+	$(CC) $(CFLAGS) -c $(INCLUDE) $< -o $*.o
+
+all: $(SUPPORTLIBS) $(SQUEEZESLAVE)
+
+lib/lirc/$(OS)/lib/liblirc_client.a:
+	cd lib/lirc/$(OS)/build && ${TAR} --bzip -xf ../../../../sources/$(LIBLIRC).tar.bz2
+	cd lib/lirc/$(OS)/build && ${PATCH} -p0 -i ../../../../patches/lirc_client.patch
+	cd lib/lirc/$(OS)/build/$(LIBLIRC) && $(SED) -i "s:^#define WEXITSTATUS(w)		(((w) >> 8) & 0xff)::" tools/lirc_client.h
+	cd lib/lirc/$(OS)/build/$(LIBLIRC)/tools && $(CC) $(CFLAGS) -I.. -I. -c -o lirc_client.o lirc_client.c
+	ar cru lib/lirc/$(OS)/lib/liblirc_client.a lib/lirc/$(OS)/build/$(LIBLIRC)/tools/lirc_client.o
+	ranlib lib/lirc/$(OS)/lib/liblirc_client.a
+	cp -p lib/lirc/$(OS)/build/$(LIBLIRC)/tools/lirc_client.h lib/lirc/$(OS)/include/lirc
+
+$(LIBPORTAUDIO): $(PORTAUDIOFILES:.c=.o)
+	ar cru $(LIBPORTAUDIO) $^
+	ranlib $(LIBPORTAUDIO)
+
+lib/libmad/$(OS)/lib/libmad.a:
+	cd lib/libmad/$(OS)/build && ${TAR} --bzip -xf ../../../../sources/$(LIBMAD).tar.bz2
+	cd lib/libmad/$(OS)/build && ${PATCH} -p0 -i ../../../../patches/libmad-forcemem.patch
+	cd lib/libmad/$(OS)/build/$(LIBMAD) && CC="$(CC)" CFLAGS="$(CFLAGS)" CPPFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" ./configure --enable-shared=no --enable-fpm=intel
+	cd lib/libmad/$(OS)/build/$(LIBMAD) && make clean && make
+	${CP} -p lib/libmad/$(OS)/build/$(LIBMAD)/.libs/libmad.a lib/libmad/$(OS)/lib
+	${CP} -p lib/libmad/$(OS)/build/$(LIBMAD)/mad.h lib/libmad/$(OS)/include
+
+lib/vorbis/$(OS)/lib/libogg.a:
+	cd lib/vorbis/$(OS)/build && ${TAR} --bzip -xf ../../../../sources/$(LIBOGG).tar.bz2
+	cd lib/vorbis/$(OS)/build/$(LIBOGG) && CC="$(CC)" CFLAGS="$(CFLAGS)" CPPFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" ./configure --enable-shared=no
+	cd lib/vorbis/$(OS)/build/$(LIBOGG) && make clean && make
+	${CP} -p lib/vorbis/$(OS)/build/$(LIBOGG)/src/.libs/libogg.a lib/vorbis/$(OS)/lib
+	${CP} -p lib/vorbis/$(OS)/build/$(LIBOGG)/include/ogg/{ogg.h,os_types.h,config_types.h} lib/vorbis/$(OS)/include/ogg
+
+lib/vorbis/$(OS)/lib/libvorbisidec.a: lib/vorbis/$(OS)/lib/libogg.a
+	cd lib/vorbis/$(OS)/build && ${TAR} --bzip -xf ../../../../sources/$(LIBVORBIS).tar.bz2
+	cd lib/vorbis/$(OS)/build/$(LIBVORBIS) && CC="$(CC)" CFLAGS="$(CFLAGS)" CPPFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" ./configure --enable-shared=no --with-ogg-includes=`pwd`/../../include --with-ogg-libraries=`pwd`/../../lib
+	cd lib/vorbis/$(OS)/build/$(LIBVORBIS) && make clean && make
+	${CP} -p lib/vorbis/$(OS)/build/$(LIBVORBIS)/.libs/libvorbisidec.a lib/vorbis/$(OS)/lib
+	${CP} -p lib/vorbis/$(OS)/build/$(LIBVORBIS)/{ivorbiscodec.h,ivorbisfile.h,config_types.h} lib/vorbis/$(OS)/include/vorbis
+	cd lib/vorbis/$(OS)/include/vorbis; ln -s ivorbisfile.h vorbisfile.h
+
+lib/flac/$(OS)/lib/libFLAC.a: lib/vorbis/$(OS)/lib/libogg.a
+	cd lib/flac/$(OS)/build && ${TAR} --bzip -xf ../../../../sources/$(LIBFLAC).tar.bz2
+	cd lib/flac/$(OS)/build/$(LIBFLAC) && CC="$(CC)" OGG_CFLAGS=-I`pwd`/../../include OGG_LIBS=`pwd`/../../lib/libogg.a CFLAGS="$(CFLAGS)" CPPFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS) ${OGG_LIBS}" ./configure --enable-shared=no --disable-oggtest --with-ogg-libraries=`pwd`/../../../../vorbis/$(OS)/lib --with-ogg-includes=`pwd`/../../../../vorbis/$(OS)/include
+	cd lib/flac/$(OS)/build/$(LIBFLAC)/src/libFLAC && make clean && make
+	${CP} -p lib/flac/$(OS)/build/$(LIBFLAC)/src/libFLAC/.libs/libFLAC.a lib/flac/$(OS)/lib
+	${CP} -p lib/flac/$(OS)/build/$(LIBFLAC)/include/FLAC/{all.h,export.h,ordinals.h,assert.h,format.h,stream_decoder.h,callback.h,metadata.h,stream_encoder.h} lib/flac/$(OS)/include/FLAC
+
+$(LIBSLIMPROTO): $(SLIMPROTOFILES:.c=.o)
+	ar cru $(LIBSLIMPROTO) $^
+	ranlib $(LIBSLIMPROTO)
+
+$(LIBGETOPT): $(GETOPTFILES:.c=.o)
+	ar cru $(LIBGETOPT) $^
+	ranlib $(LIBGETOPT)
+
+$(SQUEEZESLAVE): $(SQUEEZESLAVEFILES:.c=.o) $(PORTMIXERFILES:.c=.o) $(LIBPORTAUDIO) $(LIBSLIMPROTO) $(LIBGETOPT) $(SUPPORTLIBS)
+	$(CC) $(LDFLAGS) -static -o $(SQUEEZESLAVE) $^ -lpthread -lm $(LIBS) -lrt
+	mv $(SQUEEZESLAVE) $(SQUEEZESLAVE)-static
+	$(CC) $(LDFLAGS) -o $(SQUEEZESLAVE) $^ -lpthread -lm $(LIBS) -lrt
+
+clean:
+	-@rm -f $(PORTAUDIOFILES:.c=.o)
+	-@rm -f $(SLIMPROTOFILES:.c=.o)
+	-@rm -f $(SQUEEZESLAVEFILES:.c=.o)
+	-@rm -f $(PORTMIXERFILES:.c=.o)
+	-@rm -f $(GETOPTFILES:.c=.o)
+	-@rm -f $(LIBPORTAUDIO)
+	-@rm -f $(LIBSLIMPROTO)
+	-@rm -f $(LIBGETOPT)
+	-@rm -f $(SQUEEZESLAVE)-static
+	-@rm -f $(SQUEEZESLAVE)
+
+realclean: clean
+	-@rm -rf lib/libmad/$(OS)/build/$(LIBMAD)
+	-@rm -rf lib/vorbis/$(OS)/build/$(LIBOGG)
+	-@rm -rf lib/vorbis/$(OS)/build/$(LIBVORBIS)
+	-@rm -rf lib/flac/$(OS)/build/$(LIBFLAC)
+	-@rm -rf lib/lirc/$(OS)/build/$(LIBLIRC)
+	-@rm -f lib/libmad/$(OS)/lib/libmad.a lib/libmad/$(OS)/include/mad.h
+	-@rm -f lib/vorbis/$(OS)/lib/libogg.a lib/vorbis/$(OS)/include/ogg/{ogg.h,os_types.h,config_types.h}
+	-@rm -f lib/vorbis/$(OS)/lib/libvorbisidec.a
+	-@rm -f lib/vorbis/$(OS)/include/vorbis/{vorbisfile.h,ivorbiscodec.h,ivorbisfile.h,config_types.h}
+	-@rm -f lib/flac/$(OS)/lib/libFLAC.a
+	-@rm -f lib/flac/$(OS)/include/FLAC/{all.h,export.h,ordinals.h,assert.h,format.h,stream_decoder.h,callback.h,metadata.h,stream_encoder.h}
+	-@rm -f lib/lirc/$(OS)/lib/liblirc_client.a lib/lirc/$(OS)/include/lirc/lirc_client.h
+
Index: lib/portaudio/pa_unix_oss/pa_unix_oss.c
===================================================================
--- lib/portaudio/pa_unix_oss/pa_unix_oss.c	(revision 256)
+++ lib/portaudio/pa_unix_oss/pa_unix_oss.c	(working copy)
@@ -96,69 +96,18 @@
     }
 
     /*  Ask OSS what formats are supported by the hardware. */
-    pad->pad_Info.nativeSampleFormats = 0;
+    pad->pad_Info.nativeSampleFormats = paInt16;
 
-    if (ioctl(tempDevHandle, SNDCTL_DSP_GETFMTS, &format) == -1)
-    {
-        ERR_RPT(("Pa_QueryDevice: could not get format info\n" ));
-        goto error;
-    }
-    if( format & AFMT_U8 )     pad->pad_Info.nativeSampleFormats |= paUInt8;
-    if( format & AFMT_S16_NE ) pad->pad_Info.nativeSampleFormats |= paInt16;
-
     /* Negotiate for the maximum number of channels for this device. PLB20010927
      * Consider up to 16 as the upper number of channels.
      * Variable numChannels should contain the actual upper limit after the call.
      * Thanks to John Lazzaro and Heiko Purnhagen for suggestions.
      */
-    maxNumChannels = 0;
-    for( numChannels = 1; numChannels <= 16; numChannels++ )
-    {
-        int temp = numChannels;
-        DBUG(("Pa_QueryDevice: use SNDCTL_DSP_CHANNELS, numChannels = %d\n", numChannels ))
-        if(ioctl(tempDevHandle, SNDCTL_DSP_CHANNELS, &temp) < 0 )
-        {
-            /* ioctl() failed so bail out if we already have stereo */
-            if( numChannels > 2 ) break;
-        }
-        else
-        {
-            /* ioctl() worked but bail out if it does not support numChannels.
-             * We don't want to leave gaps in the numChannels supported.
-             */
-            if( (numChannels > 2) && (temp != numChannels) ) break;
-            DBUG(("Pa_QueryDevice: temp = %d\n", temp ))
-            if( temp > maxNumChannels ) maxNumChannels = temp; /* Save maximum. */
-        }
-    }
+    maxNumChannels = 2;
 
-    /* The above negotiation may fail for an old driver so try this older technique. */
-    if( maxNumChannels < 1 )
-    {
-        int stereo = 1;
-        if(ioctl(tempDevHandle, SNDCTL_DSP_STEREO, &stereo) < 0)
-        {
-            maxNumChannels = 1;
-        }
-        else
-        {
-            maxNumChannels = (stereo) ? 2 : 1;
-        }
-        DBUG(("Pa_QueryDevice: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", maxNumChannels ))
-    }
-
     pad->pad_Info.maxOutputChannels = maxNumChannels;
     DBUG(("Pa_QueryDevice: maxNumChannels = %d\n", maxNumChannels))
 
-    /* During channel negotiation, the last ioctl() may have failed. This can
-     * also cause sample rate negotiation to fail. Hence the following, to return
-     * to a supported number of channels. SG20011005 */
-    {
-        int temp = maxNumChannels;
-        if( temp > 2 ) temp = 2; /* use most reasonable default value */
-        ioctl(tempDevHandle, SNDCTL_DSP_CHANNELS, &temp);
-    }
-
     /* FIXME - for now, assume maxInputChannels = maxOutputChannels.
      *    Eventually do separate queries for O_WRONLY and O_RDONLY
     */
@@ -172,37 +121,8 @@
      * OSS often supports funky rates such as 44188 instead of 44100!
      */
     numSampleRates = 0;
-    lastRate = 0;
-    numRatesToTry = sizeof(ratesToTry)/sizeof(int);
-    for (i = 0; i < numRatesToTry; i++)
-    {
-        sampleRate = ratesToTry[i];
+    pad->pad_SampleRates[numSampleRates++] = 44100;
 
-        if (ioctl(tempDevHandle, SNDCTL_DSP_SPEED, &sampleRate) >= 0 ) /* PLB20010817 */
-        {
-            /* Use whatever rate OSS tells us. PLB20021018 */
-            if (sampleRate != lastRate)
-            {
-                DBUG(("Pa_QueryDevice: adding sample rate: %d\n", sampleRate))
-                pad->pad_SampleRates[numSampleRates] = (float)sampleRate;
-                numSampleRates++;
-                lastRate = sampleRate;
-            }
-            else
-            {
-                DBUG(("Pa_QueryDevice: dang - got sample rate %d again!\n", sampleRate))
-            }
-        }
-    }
-
-    DBUG(("Pa_QueryDevice: final numSampleRates = %d\n", numSampleRates))
-    if (numSampleRates==0)   /* HP20010922 */
-    {
-        /* Desparate attempt to keep running even though no good rates found! */
-        ERR_RPT(("Pa_QueryDevice: no supported sample rate (or SNDCTL_DSP_SPEED ioctl call failed). Force 44100 Hz\n" ));
-        pad->pad_SampleRates[numSampleRates++] = 44100;
-    }
-
     pad->pad_Info.numSampleRates = numSampleRates;
     pad->pad_Info.sampleRates = pad->pad_SampleRates; /* use pointer to embedded array */
 
@@ -223,56 +143,6 @@
     PaError result = paNoError;
     int     tmp;
 
-    /* Set format, channels, and rate in this order to keep OSS happy. */
-    /* Set data format. FIXME - handle more native formats. */
-    tmp = AFMT_S16_NE;
-    if( ioctl(devHandle,SNDCTL_DSP_SETFMT,&tmp) == -1)
-    {
-        ERR_RPT(("Pa_SetupDeviceFormat: could not SNDCTL_DSP_SETFMT\n" ));
-        return paHostError;
-    }
-    if( tmp != AFMT_S16_NE )
-    {
-        ERR_RPT(("Pa_SetupDeviceFormat: HW does not support AFMT_S16_NE\n" ));
-        return paHostError;
-    }
-
-
-    /* Set number of channels. */
-    tmp = numChannels;
-    if (ioctl(devHandle, SNDCTL_DSP_CHANNELS, &numChannels) == -1)
-    {
-        ERR_RPT(("Pa_SetupDeviceFormat: could not SNDCTL_DSP_CHANNELS\n" ));
-        return paHostError;
-    }
-    if( tmp != numChannels)
-    {
-        ERR_RPT(("Pa_SetupDeviceFormat: HW does not support %d channels\n", numChannels ));
-        return paHostError;
-    }
-
-    /* Set playing frequency. */
-    tmp = sampleRate;
-    if( ioctl(devHandle,SNDCTL_DSP_SPEED,&tmp) == -1)
-    {
-        ERR_RPT(("Pa_SetupDeviceFormat: could not SNDCTL_DSP_SPEED\n" ));
-        return paHostError;
-    }
-    else if( tmp != sampleRate )
-    {
-        int percentError = abs( (100 * (sampleRate - tmp)) / sampleRate );
-        PRINT(("Pa_SetupDeviceFormat: warning - requested sample rate = %d Hz - closest = %d\n",
-            sampleRate, tmp ));
-        /* Allow sample rate within 10% off of requested rate. PLB20021018
-        * Sometimes OSS uses a funky rate like 44188 instead of 44100.
-        */
-        if( percentError > 10 )
-        {
-            ERR_RPT(("Pa_SetupDeviceFormat: HW does not support %d Hz sample rate\n",sampleRate ));
-           return paHostError;
-        }
-    }
-    
     return result;
 }
 
@@ -321,13 +191,6 @@
     /* Encode info into a single int */
     tmp=(numBuffers<<16) + powerOfTwo;
 
-    if(ioctl(devHandle,SNDCTL_DSP_SETFRAGMENT,&tmp) == -1)
-    {
-        ERR_RPT(("Pa_SetLatency: could not SNDCTL_DSP_SETFRAGMENT\n" ));
-        /* Don't return an error. Best to just continue and hope for the best. */
-        ERR_RPT(("Pa_SetLatency: numBuffers = %d, framesPerBuffer = %d, powerOfTwo = %d\n",
-                 numBuffers, framesPerBuffer, powerOfTwo ));
-    }
 }
 
 /***********************************************************************/
@@ -345,15 +208,11 @@
 
     if( pahsc->pahsc_NativeOutputBuffer )
     {
-       ioctl(pahsc->pahsc_OutputHandle, SNDCTL_DSP_GETOPTR, &info);
-       delta = (info.bytes - pahsc->pahsc_LastPosPtr);
-       return (pahsc->pahsc_LastStreamBytes + delta) / (past->past_NumOutputChannels * sizeof(short));
+       return (pahsc->pahsc_LastStreamBytes) / (past->past_NumOutputChannels * sizeof(short));
     }
     else
     {
-       ioctl(pahsc->pahsc_InputHandle, SNDCTL_DSP_GETIPTR, &info);
-       delta = (info.bytes - pahsc->pahsc_LastPosPtr);
-       return (pahsc->pahsc_LastStreamBytes + delta) / (past->past_NumInputChannels * sizeof(short));
+       return (pahsc->pahsc_LastStreamBytes) / (past->past_NumInputChannels * sizeof(short));
     }
 }
 
@@ -364,16 +223,7 @@
 
   /* Update current stream time (using a double so that
      we don't wrap around like info.bytes does) */
-  if( pahsc->pahsc_NativeOutputBuffer )
-  {
-    ioctl(pahsc->pahsc_OutputHandle, SNDCTL_DSP_GETOPTR, &info);
-  }
-  else
-  {
-    ioctl(pahsc->pahsc_InputHandle, SNDCTL_DSP_GETIPTR, &info);
-  }
-  delta = (info.bytes - pahsc->pahsc_LastPosPtr);
-  pahsc->pahsc_LastStreamBytes += delta;
+  pahsc->pahsc_LastStreamBytes += 0;
   pahsc->pahsc_LastPosPtr = info.bytes;
 }
 
Index: lib/portaudio/pa_unix_oss/pa_unix.h
===================================================================
--- lib/portaudio/pa_unix_oss/pa_unix.h	(revision 256)
+++ lib/portaudio/pa_unix_oss/pa_unix.h	(working copy)
@@ -82,11 +82,7 @@
 #define MAX_TIMEOUT_MSEC   (1000)
 
 /************************************************* Definitions ********/
-#ifdef __linux__
- #define DEVICE_NAME_BASE            "/dev/dsp"
-#else
  #define DEVICE_NAME_BASE            "/dev/audio"
-#endif
 
 #define MAX_CHARS_DEVNAME           (32)
 #define MAX_SAMPLE_RATES            (10)
Index: lib/portmixer/px_tests/Makefile
===================================================================
--- lib/portmixer/px_tests/Makefile	(revision 256)
+++ lib/portmixer/px_tests/Makefile	(working copy)
@@ -4,7 +4,7 @@
 
 px_test: px_test.o px_unix_oss.o ../px_common/portmixer.h
 	gcc -g -o px_test px_test.o px_unix_oss.o -lm \
-		-L../../portaudio/pa_unix_oss -lportaudio -lpthread
+		-L../../portaudio/pa_unix_oss ../../libportaudio.a -lpthread
 
 px_test.o: px_test.c ../px_common/portmixer.h
 	gcc $(CFLAGS) -c px_test.c
Index: lib/portmixer/px_unix_oss/px_unix_oss.c
===================================================================
--- lib/portmixer/px_unix_oss/px_unix_oss.c	(revision 256)
+++ lib/portmixer/px_unix_oss/px_unix_oss.c	(working copy)
@@ -1,5 +1,4 @@
-/*
- * PortMixer
+/* PortMixer
  * Unix OSS Implementation
  *
  * Copyright (c) 2002
@@ -136,11 +135,13 @@
    if (ioctl(info->fd, MIXER_READ(SOUND_MIXER_READ_DEVMASK),
              &devmask) == -1)
       goto bad;
-   if (ioctl(info->fd, MIXER_READ(SOUND_MIXER_READ_RECMASK),
-             &recmask) == -1)
-      goto bad;
-   outmask = devmask ^ recmask;
-
+//   if (ioctl(info->fd, MIXER_READ(SOUND_MIXER_READ_RECMASK),
+//             &recmask) == -1)
+//      goto bad;
+//   outmask = devmask ^ recmask;
+   outmask = devmask;
+   recmask = 0;
+   
    info->num_out = 0;
    info->num_rec = 0;
 
