Hi all,

I needed MP3 output encoding, so I whipped up a version of the ices
plugin that supports both.  The waf script has been updated as well,
and it will autodetect when a system has the requisite libs for at
least one encoder and enable one or both as necessary.  I also adjusted
some of the config values, adding a "speed" param that controls lame's
internal quality (useful for low-end systems that may not be able to
handle vorbis encoding), detecting kbps values for the bitrates so that
users don't have to type in 128000 (they still *can*, though), and of
course adding a knob to select between mp3 and ogg encoding.  

Both encoders have been tested, and although there are still a few bits
and pieces lying around in the code, they both work and are stable.  I
intend to put the finishing touches on things soon and hopefully get it
included, but felt it was better to get feedback before going any
further.

Attached is the output of 'git diff'.

HTH,
Steven
diff --git a/src/plugins/ices/encode.c b/src/plugins/ices/encode.c
deleted file mode 100644
index da443e0..0000000
--- a/src/plugins/ices/encode.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/* encode.c
- * - runtime encoding of PCM data.
- *
- * $Id: encode.c,v 1.16 2003/03/22 02:27:55 karl Exp $
- *
- * Copyright (c) 2001 Michael Smith <[EMAIL PROTECTED]>
- *
- * This program is distributed under the terms of the GNU General
- * Public License, version 2. You may use, modify, and redistribute
- * it under the terms of this license. A copy should be included
- * with this source.
- */
-
-/*
- * Modifications for xmms2
- * Copyright (C) 2003-2008 XMMS2 Team
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <glib.h>
-
-#include <ogg/ogg.h>
-#include <vorbis/codec.h>
-#include <vorbis/vorbisenc.h>
-
-#include "encode.h"
-#include "xmms/xmms_log.h"
-#include "xmms/xmms_sample.h"
-
-#define MODULE "encode/"
-
-struct encoder_state {
-	/* General encoder configuration. */
-	int min_br;
-	int nom_br;
-	int max_br;
-	int channels;
-	int rate;
-
-	gboolean encoder_inited;
-
-	/* Ogg state. Remains active for the lifetime of the encoder. */
-	ogg_stream_state os;
-	int serial;
-	gboolean in_header; /* TRUE if the stream is still within a vorbis
-						 * header. */
-	gboolean flushing; /* TRUE if the end of stream is reached and
-						* we're just flushing the ogg data. */
-
-	/* Used for ogg page size management. See xmms_ices_encoder_output
-	 * for details. */
-	int samples_in_current_page;
-	ogg_int64_t previous_granulepos;
-
-	/* Vorbis state. May be recreated if there is a change in
-	 * rate/channels. */
-	vorbis_info vi;
-	vorbis_block vb;
-	vorbis_dsp_state vd;
-};
-
-
-/* Create an ogg stream and vorbis encoder, with the configuration
- * specified in the encoder_state.
- */
-static gboolean
-xmms_ices_encoder_create (encoder_state *s, vorbis_comment *vc)
-{
-	ogg_packet header[3];
-
-	if (s->encoder_inited) {
-		XMMS_DBG ("OOPS: xmms_ices_encoder_create called "
-		          "with s->encoder_inited == TRUE !");
-	}
-
-	XMMS_DBG ("Creating encoder in ABR mode: min/avg/max bitrate %d/%d/%d",
-	          s->min_br, s->nom_br, s->max_br);
-
-	/* Create the Vorbis encoder. */
-	vorbis_info_init (&s->vi);
-	if (vorbis_encode_init (&s->vi, s->channels, s->rate,
-	                        s->max_br, s->nom_br, s->min_br) < 0)
-		return FALSE;
-	vorbis_analysis_init (&s->vd, &s->vi);
-	vorbis_block_init (&s->vd, &s->vb);
-
-	/* Initialize the ogg stream and input the vorbis header
-	 * packets. */
-	ogg_stream_init (&s->os, s->serial++);
-	vorbis_analysis_headerout (&s->vd, vc, &header[0], &header[1], &header[2]);
-	ogg_stream_packetin (&s->os, &header[0]);
-	ogg_stream_packetin (&s->os, &header[1]);
-	ogg_stream_packetin (&s->os, &header[2]);
-
-	s->in_header = TRUE;
-	s->flushing = FALSE;
-	s->samples_in_current_page = 0;
-	s->previous_granulepos = 0;
-	s->encoder_inited = TRUE;
-
-	return TRUE;
-}
-
-/* Free the ogg and vorbis encoder state associated with
- * encoder_state, if the encoder is present.
- */
-static void
-xmms_ices_encoder_free (encoder_state *s)
-{
-	if (s->encoder_inited) {
-		ogg_stream_clear (&s->os);
-		vorbis_block_clear (&s->vb);
-		vorbis_dsp_clear (&s->vd);
-		vorbis_info_clear (&s->vi);
-		s->encoder_inited = FALSE;
-	}
-}
-
-
-encoder_state *
-xmms_ices_encoder_init (int min_br, int nom_br, int max_br)
-{
-	encoder_state *s = g_new0 (encoder_state, 1);
-
-	/* If none of these are set, it's obviously not supposed to be managed */
-	if (nom_br <= 0)
-		return NULL;
-
-	s->min_br = min_br;
-	s->nom_br = nom_br;
-	s->max_br = max_br;
-	s->serial = 0;
-	s->in_header = FALSE;
-	s->encoder_inited = FALSE;
-
-	return s;
-}
-
-void xmms_ices_encoder_fini (encoder_state *s) {
-	xmms_ices_encoder_free (s);
-	g_free (s);
-}
-
-/* Start a new logical ogg stream. */
-gboolean xmms_ices_encoder_stream_change (encoder_state *s, int rate,
-                                          int channels, vorbis_comment *vc)
-{
-	xmms_ices_encoder_free (s);
-	s->rate = rate;
-	s->channels = channels;
-	return xmms_ices_encoder_create (s, vc);
-}
-
-/* Encode the given data into Ogg Vorbis. */
-void xmms_ices_encoder_input (encoder_state *s, xmms_samplefloat_t *buf, int bytes)
-{
-	float **buffer;
-	int i,j;
-	int channels = s->vi.channels;
-	int samples = bytes / (sizeof (xmms_samplefloat_t)*channels);
-
-	buffer = vorbis_analysis_buffer (&s->vd, samples);
-
-	for (i = 0; i < samples; i++)
-		for (j = 0; j < channels; j++)
-			buffer[j][i] = buf[i*channels + j];
-
-	vorbis_analysis_wrote (&s->vd, samples);
-	s->samples_in_current_page += samples;
-}
-
-/* Mark the end of the vorbis encoding, flush the vorbis buffers, and
- * mark the ogg stream as being in the flushing state. */
-void xmms_ices_encoder_finish (encoder_state *s)
-{
-	ogg_packet op;
-
-	vorbis_analysis_wrote (&s->vd, 0);
-
-	while (vorbis_analysis_blockout (&s->vd, &s->vb)==1) {
-		vorbis_analysis (&s->vb, NULL);
-		vorbis_bitrate_addblock (&s->vb);
-		while (vorbis_bitrate_flushpacket (&s->vd, &op))
-			ogg_stream_packetin (&s->os, &op);
-	}
-
-	s->flushing = TRUE;
-}
-
-/* Returns TRUE if an ogg page was output, FALSE if there is nothing
- * left to do.
- */
-gboolean xmms_ices_encoder_output (encoder_state *s, ogg_page *og)
-{
-	ogg_packet op;
-
-	/* As long as we're still in the header, we still have the header
-	 * packets to output. Loop over those before going to the actual
-	 * vorbis data. */
-	if (s->in_header) {
-		if (ogg_stream_flush (&s->os, og))
-			return TRUE;
-		else
-			s->in_header = FALSE;
-	}
-
-	/* If we're flushing the end of the stream, just output. */
-	if (s->flushing) {
-		if (ogg_stream_flush (&s->os, og))
-			return TRUE;
-		else
-			return FALSE;
-	}
-
-	/* Flush the vorbis analysis stream into ogg packets, and add
-	 * those to the ogg packet stream. */
-	while (vorbis_analysis_blockout (&s->vd, &s->vb) == 1) {
-		vorbis_analysis (&s->vb, NULL);
-		vorbis_bitrate_addblock (&s->vb);
-
-		while (vorbis_bitrate_flushpacket (&s->vd, &op))
-			ogg_stream_packetin (&s->os, &op);
-	}
-
-	/* For live encoding, we want to stream pages regularly, rather
-	 * than burst huge pages. Therefore, we periodically manually
-	 * flush the stream. */
-	if (s->samples_in_current_page > s->rate * 2) {
-		if (!ogg_stream_flush (&s->os, og))
-			return FALSE;
-	} else {
-		if (!ogg_stream_pageout (&s->os, og))
-			return FALSE;
-	}
-
-	/* At this point, we have an ogg page in og. Keep bookkeeping
-	 * accurate regarding the number of samples still in the page
-	 * buffer, and return. */
-	s->samples_in_current_page -= (ogg_page_granulepos (og)
-	                               - s->previous_granulepos);
-	s->previous_granulepos = ogg_page_granulepos (og);
-
-	return TRUE;
-}
diff --git a/src/plugins/ices/encode.h b/src/plugins/ices/encode.h
index dc368ed..e20f96a 100644
--- a/src/plugins/ices/encode.h
+++ b/src/plugins/ices/encode.h
@@ -20,20 +20,126 @@
 #define __ENCODE_H
 
 #include <glib.h>
-#include <ogg/ogg.h>
-#include <vorbis/codec.h>
+#include <shout/shout.h>
 
 #include "xmms/xmms_sample.h"
+#include "xmms_configuration.h"
+
+/* For now, we hack around ogg_page.  Maybe fix later. */
+
+#ifdef HAVE_ogg
+
+#include <ogg/ogg.h>
+
+#else
+
+typedef struct {
+	unsigned char *header;
+	long header_len;
+	unsigned char *body;
+	long body_len;
+} ogg_page;
+
+#endif
+
+
+typedef struct {
+    
+    /* ABR parameters. Note these are in KBPS. */
+    int min_br;
+    int nom_br;
+    int max_br;
+
+	/* lame-only "speed" param (referred to in API as "quality") */
+	int speed;
+
+    int channels;
+    int rate;
+} encoder_config;
 
-typedef struct encoder_state encoder_state;
+/* Two simple types used a couple of times in the code. */
+typedef struct {
+	gchar *key;
+	gchar *val;
+} key_val_pair;
 
-encoder_state *xmms_ices_encoder_init(int min_br, int nom_br, int max_br);
-void xmms_ices_encoder_fini(encoder_state *s);
-gboolean xmms_ices_encoder_stream_change(encoder_state *s, int rate,
-                                         int channels, vorbis_comment *vc);
-void xmms_ices_encoder_input(encoder_state *s, xmms_samplefloat_t *buf, int n_samples);
-void xmms_ices_encoder_finish(encoder_state *s);
-gboolean xmms_ices_encoder_output(encoder_state *s, ogg_page *og);
+typedef struct key_val_ll_t key_val_ll;
 
+struct key_val_ll_t {
+	gchar *key;
+	gchar *val;
+	key_val_ll *next;
+};
+
+typedef void* (*init_func)     ();
+typedef void  (*finish_func)   (void *s);
+typedef void  (*destroy_func)  (void *s);
+typedef void  (*input_func)    (void *s, xmms_samplefloat_t *buf, int bytes);
+typedef gboolean (*output_func)        (void *s, ogg_page *og);
+typedef gboolean (*stream_change_func) (void *s, const encoder_config *c,
+                                        key_val_ll *metadata);
+
+typedef struct {
+	int                shout_format;
+	init_func          init;
+	finish_func        finish;
+	destroy_func       destroy;
+	input_func         input;
+	output_func        output;
+	stream_change_func stream_change;
+} encoder_t;
+
+#ifdef HAVE_vorbisenc
+
+typedef struct encoder_ogg_state_t encoder_ogg_state;
+void*    xmms_ices_encoder_ogg_init ();
+void     xmms_ices_encoder_ogg_finish (encoder_ogg_state *s);
+void     xmms_ices_encoder_ogg_destroy (encoder_ogg_state *s);
+void     xmms_ices_encoder_ogg_input (encoder_ogg_state *s, 
+                                      xmms_samplefloat_t *buf,
+									  int bytes);
+gboolean xmms_ices_encoder_ogg_output (encoder_ogg_state *s, ogg_page *og);
+gboolean xmms_ices_encoder_ogg_stream_change (encoder_ogg_state *s, 
+                                              const encoder_config *c,
+                                              key_val_ll *metadata);
+
+
+static const encoder_t xmms_ices_encoder_ogg = {
+	SHOUT_FORMAT_OGG,
+	(init_func)          xmms_ices_encoder_ogg_init,
+	(finish_func)        xmms_ices_encoder_ogg_finish,
+	(destroy_func)       xmms_ices_encoder_ogg_destroy,
+	(input_func)         xmms_ices_encoder_ogg_input,
+	(output_func)        xmms_ices_encoder_ogg_output,
+	(stream_change_func) xmms_ices_encoder_ogg_stream_change
+};
 #endif
 
+#ifdef HAVE_lame
+
+typedef struct encoder_mp3_state_t encoder_mp3_state;
+void*    xmms_ices_encoder_mp3_init ();
+void     xmms_ices_encoder_mp3_finish (encoder_mp3_state *s);
+void     xmms_ices_encoder_mp3_destroy (encoder_mp3_state *s);
+void     xmms_ices_encoder_mp3_input (encoder_mp3_state *s, 
+                                      xmms_samplefloat_t *buf,
+									  int bytes);
+gboolean xmms_ices_encoder_mp3_output (encoder_mp3_state *s, ogg_page *og);
+gboolean xmms_ices_encoder_mp3_stream_change (encoder_mp3_state *s, 
+                                              const encoder_config *c,
+                                              key_val_ll *metadata);
+
+static const encoder_t xmms_ices_encoder_mp3 = {
+	SHOUT_FORMAT_MP3,
+	(init_func)          xmms_ices_encoder_mp3_init,
+	(finish_func)        xmms_ices_encoder_mp3_finish,
+	(destroy_func)       xmms_ices_encoder_mp3_destroy,
+	(input_func)         xmms_ices_encoder_mp3_input,
+	(output_func)        xmms_ices_encoder_mp3_output,
+	(stream_change_func) xmms_ices_encoder_mp3_stream_change
+};
+#endif
+
+
+
+#endif
diff --git a/src/plugins/ices/ices.c b/src/plugins/ices/ices.c
index b7932f4..43c6598 100644
--- a/src/plugins/ices/ices.c
+++ b/src/plugins/ices/ices.c
@@ -21,18 +21,19 @@
 #include <math.h>
 #include <glib.h>
 #include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
 
 #include <shout/shout.h>
 
-#include <ogg/ogg.h>
-#include <vorbis/codec.h>
-
 #include "encode.h"
 
 typedef struct xmms_ices_data_St {
-	shout_t *shout;
-	vorbis_comment vc;
-	encoder_state *encoder;
+	encoder_config  enc_cfg;
+	void            *enc_st;
+	const encoder_t *enc;
+	char*           *enc_name;
+	shout_t         *shout;
 } xmms_ices_data_t;
 
 /*
@@ -55,21 +56,22 @@ static void xmms_ices_write (xmms_output_t *output, gpointer buffer,
 static void
 xmms_ices_send_shout (xmms_ices_data_t *data, xmms_error_t *err)
 {
+	/* TODO: drop ogg_page from this code */
 	ogg_page og;
 
-	while (xmms_ices_encoder_output (data->encoder, &og) == TRUE) {
+	while (data->enc->output (data->enc_st, &og)) {
 		if (shout_send (data->shout, og.header, og.header_len) < 0) {
 			if (err)
 				xmms_error_set (err, XMMS_ERROR_GENERIC,
 				                "Disconnected or something.");
 			return;
-		} else if (shout_send (data->shout, og.body, og.body_len) < 0) {
+		} else if (og.body_len > 0 && shout_send (data->shout, og.body, 
+		                                          og.body_len) < 0) {
 			if (err)
 				xmms_error_set (err, XMMS_ERROR_GENERIC,
 				                "Error when sending data to icecast server");
 			return;
 		}
-
 		shout_sync (data->shout);
 	}
 }
@@ -77,7 +79,7 @@ xmms_ices_send_shout (xmms_ices_data_t *data, xmms_error_t *err)
 static void
 xmms_ices_flush_internal (xmms_ices_data_t *data)
 {
-	xmms_ices_encoder_finish (data->encoder);
+	data->enc->finish (data->enc_st);
 
 	xmms_ices_send_shout (data, NULL);
 }
@@ -97,13 +99,13 @@ static gboolean
 xmms_ices_plugin_setup (xmms_output_plugin_t *plugin)
 {
 	xmms_output_methods_t methods;
-	static const struct {
-		char *name;
-		char *val;
-	} *pptr, ices_properties[] = {
-		{ "encodingnombr", "96000" },
+
+	key_val_pair *pptr, ices_properties[] = {
+		{ "encodingnombr", "96" },
 		{ "encodingminbr", "-1" },
 		{ "encodingmaxbr", "-1" },
+		{ "encodingspeed", "7"}, // Only for lame
+		{ "encodingformat", "ogg"},
 		{ "host", "localhost" },
 		{ "port", "8000" },
 		{ "user", "source" },
@@ -130,13 +132,14 @@ xmms_ices_plugin_setup (xmms_output_plugin_t *plugin)
 
 	xmms_output_plugin_methods_set (plugin, &methods);
 
-	for (pptr = ices_properties; pptr->name != NULL; pptr++)
-		xmms_output_plugin_config_property_register (plugin, pptr->name,
+	
+	for (pptr = ices_properties; pptr->key != NULL; pptr++)
+		xmms_output_plugin_config_property_register (plugin, pptr->key,
 		                                             pptr->val,
 		                                             NULL, NULL);
 
 	return TRUE;
-}
+}	
 
 static gboolean
 xmms_ices_new (xmms_output_t *output)
@@ -144,12 +147,50 @@ xmms_ices_new (xmms_output_t *output)
 	xmms_ices_data_t *data;
 	xmms_config_property_t *val;
 
-	shout_init ();
-
 	data = g_new0 (xmms_ices_data_t, 1);
+
+	val = xmms_output_config_lookup (output, "encodingminbr");
+	data->enc_cfg.min_br = xmms_config_property_get_int (val);
+
+	val = xmms_output_config_lookup (output, "encodingnombr");
+	data->enc_cfg.nom_br = xmms_config_property_get_int (val);
+
+	val = xmms_output_config_lookup (output, "encodingmaxbr");
+	data->enc_cfg.max_br = xmms_config_property_get_int (val);
+
+	val = xmms_output_config_lookup (output, "encodingspeed");
+	data->enc_cfg.speed = xmms_config_property_get_int (val);
+
+	/* Deal with legacy settings using full-range bps */
+	if (data->enc_cfg.min_br > 2000) 
+		data->enc_cfg.min_br = data->enc_cfg.min_br / 1000;
+	if (data->enc_cfg.max_br > 2000) 
+		data->enc_cfg.max_br = data->enc_cfg.max_br / 1000;
+	if (data->enc_cfg.nom_br > 2000) 
+		data->enc_cfg.nom_br = data->enc_cfg.nom_br / 1000;
+
+
+	/* This is gross, but it works.  If we have lame AND vorbisenc,
+	 * then we check encodingformat, defaulting to ogg.  Otherwise,
+	 * we use whichever was compiled in. */
+
+#ifdef HAVE_vorbisenc
+	data->enc = &xmms_ices_encoder_ogg;
+#endif
+
+#ifdef HAVE_lame
+#ifdef HAVE_vorbisenc
+	val = xmms_output_config_lookup (output, "encodingformat");
+	if (! strcmp (xmms_config_property_get_string (val), "mp3"))
+#endif
+		data->enc = &xmms_ices_encoder_mp3;
+#endif
+
+
+	shout_init();
 	data->shout = shout_new ();
 
-	shout_set_format (data->shout, SHOUT_FORMAT_VORBIS);
+	shout_set_format (data->shout, data->enc->shout_format);
 	shout_set_protocol (data->shout, SHOUT_PROTOCOL_HTTP);
 
 	val = xmms_output_config_lookup (output, "host");
@@ -184,6 +225,7 @@ xmms_ices_new (xmms_output_t *output)
 	val = xmms_output_config_lookup (output, "streamurl");
 	shout_set_url (data->shout, xmms_config_property_get_string (val));
 
+
 	xmms_output_private_data_set (output, data);
 	xmms_output_format_add (output, XMMS_SAMPLE_FORMAT_FLOAT, 2, 44100);
 
@@ -198,10 +240,8 @@ xmms_ices_destroy (xmms_output_t *output)
 	data = xmms_output_private_data_get (output);
 	g_return_if_fail (data);
 
-	if (data->encoder)
-		xmms_ices_encoder_fini (data->encoder);
-
-	vorbis_comment_clear (&data->vc);
+	if (data->enc)
+		data->enc->destroy (data->enc_st);
 
 	shout_close (data->shout);
 	shout_free (data->shout);
@@ -240,7 +280,7 @@ xmms_ices_close (xmms_output_t *output)
 	data = xmms_output_private_data_get (output);
 	g_return_if_fail (data);
 
-	if (!data->encoder) {
+	if (! data->enc_st) {
 		shout_close (data->shout);
 		return;
 	}
@@ -248,9 +288,9 @@ xmms_ices_close (xmms_output_t *output)
 	xmms_ices_flush_internal (data);
 
 	shout_close (data->shout);
-
-	xmms_ices_encoder_fini (data->encoder);
-	data->encoder = NULL;
+	
+	data->enc->destroy (data->enc_st);
+	data->enc_st = NULL;
 }
 
 static void
@@ -262,16 +302,12 @@ static gboolean
 xmms_ices_format_set (xmms_output_t *output, const xmms_stream_type_t *format)
 {
 	xmms_ices_data_t *data;
-	xmms_config_property_t *val;
-	gint rate;
-	gint channels;
 	xmms_medialib_entry_t entry;
 	xmms_medialib_session_t *session;
+	key_val_ll *head = NULL;
+	
 
-	static const struct {
-		gchar *prop;
-		gchar *key;
-	} *pptr, props[] = {
+	key_val_pair *pptr, props[] = {
 		{XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE, "title"},
 		{XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST, "artist"},
 		{XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM, "album"},
@@ -282,49 +318,59 @@ xmms_ices_format_set (xmms_output_t *output, const xmms_stream_type_t *format)
 	data = xmms_output_private_data_get (output);
 	g_return_val_if_fail (data, FALSE);
 
-	if (data->encoder)
+	if (data->enc_st)
 		xmms_ices_flush_internal (data);
 
-	/* Reset the Vorbis comment with the new track metadata. */
-	vorbis_comment_clear (&data->vc);
-	vorbis_comment_init (&data->vc);
-
 	entry = xmms_output_current_id (output, NULL);
 	session = xmms_medialib_begin ();
 
-	for (pptr = props; pptr && pptr->prop; pptr++) {
-		const gchar *tmp;
-
-		tmp = xmms_medialib_entry_property_get_str (session, entry, pptr->prop);
-		if (tmp) {
-			vorbis_comment_add_tag (&data->vc,
-			                        pptr->key, (gchar *) tmp);
+	/* Unfortunately, MP3 metadata must be dealt with here.  This code does not
+	 * depend on lame. */
+	if (data->enc->shout_format == SHOUT_FORMAT_MP3 ) {
+		shout_metadata_t *sm = shout_metadata_new();
+		gchar *tmp;
+
+		for (pptr = props; pptr && pptr->key; pptr++) {
+			tmp = xmms_medialib_entry_property_get_str (session,
+			                                            entry, pptr->key);
+			if (tmp) {
+				shout_metadata_add(sm, pptr->val, tmp);
+				free (tmp);
+			}
+		}
+		shout_set_metadata (data->shout, sm);
+		shout_metadata_free (sm);
+	} else {
+		key_val_ll *cur = NULL;
+		gchar *tmp;
+
+		for (pptr = props; pptr && pptr->key; pptr++) {
+			tmp = xmms_medialib_entry_property_get_str (session, 
+			                                            entry, pptr->key);
+			if (tmp) {
+				if (cur == NULL)
+					head = cur = g_new0 (key_val_ll, 1);
+				else
+					cur = cur->next = g_new0 (key_val_ll, 1);
+				cur->key = strdup (pptr->val);
+				cur->val = tmp;
+			}
 		}
 	}
 
 	xmms_medialib_end (session);
 
 	/* If there is no encoder around, we need to build one. */
-	if (!data->encoder) {
-		int minbr, nombr, maxbr;
-
-		val = xmms_output_config_lookup (output, "encodingnombr");
-		nombr = xmms_config_property_get_int (val);
-		val = xmms_output_config_lookup (output, "encodingminbr");
-		minbr = xmms_config_property_get_int (val);
-		val = xmms_output_config_lookup (output, "encodingmaxbr");
-		maxbr = xmms_config_property_get_int (val);
-
-		data->encoder = xmms_ices_encoder_init (minbr, nombr, maxbr);
-		if (!data->encoder)
-			return FALSE;
-	}
+	if (!data->enc_st) 
+		g_return_val_if_fail ((data->enc_st = data->enc->init ()), FALSE);
 
 	/* Get this stream's data and fire up the encoder. */
-	rate = xmms_stream_type_get_int (format, XMMS_STREAM_TYPE_FMT_SAMPLERATE);
-	channels = xmms_stream_type_get_int (format, XMMS_STREAM_TYPE_FMT_CHANNELS);
-
-	xmms_ices_encoder_stream_change (data->encoder, rate, channels, &data->vc);
+	data->enc_cfg.rate = xmms_stream_type_get_int (format, 
+	                          XMMS_STREAM_TYPE_FMT_SAMPLERATE);
+	data->enc_cfg.channels = xmms_stream_type_get_int (format, 
+	                          XMMS_STREAM_TYPE_FMT_CHANNELS);
+	
+	data->enc->stream_change (data->enc_st, &data->enc_cfg, head);
 
 	return TRUE;
 }
@@ -338,12 +384,12 @@ xmms_ices_write (xmms_output_t *output, gpointer buffer,
 	data = xmms_output_private_data_get (output);
 	g_return_if_fail (data);
 
-	if (!data->encoder) {
+	if (!data->enc_st) {
 		xmms_error_set (err, XMMS_ERROR_GENERIC, "encoding is not initialized");
 		return;
 	}
 
-	xmms_ices_encoder_input (data->encoder, buffer, len);
+	data->enc->input (data->enc_st, buffer, len);
 
 	xmms_ices_send_shout (data, err);
 }
diff --git a/src/plugins/ices/wscript b/src/plugins/ices/wscript
index eefe95c..d7f45ae 100644
--- a/src/plugins/ices/wscript
+++ b/src/plugins/ices/wscript
@@ -1,11 +1,30 @@
 from waftools.plugin import plugin
+from wafadmin.Environment import Environment
+
 
 def plugin_configure(conf):
-    return (conf.check_pkg('shout', destvar='shout') and
-            conf.check_pkg('ogg', destvar='ogg') and
-            conf.check_pkg('vorbisenc', destvar='vorbisenc'))
+	# Require at least one encoder lib
+	env = conf.retrieve('default')
+	env['ices_have_vorbisenc'] = (conf.check_pkg('ogg', destvar='ogg') and 
+		                          conf.check_pkg('vorbisenc', destvar='vorbisenc'))
+	lame_lc = conf.create_library_configurator()
+	lame_lc.name = 'mp3lame'
+	lame_lc.uselib = 'lame'
+	env['ices_have_lame'] =  lame_lc.run()
+	return (conf.check_pkg('shout', destvar='shout') and
+	        (env['ices_have_vorbisenc'] or env['ices_have_lame']))
+
+def plugin_build(bld, obj):
+	env = bld.env()
+	if env['ices_have_vorbisenc']:
+		obj.source.append('encode_vorbis.c')
+		obj.uselib += ' vorbisenc ogg'
+	if env['ices_have_lame']:
+		obj.source.append('encode_mp3.c')
+		obj.uselib += ' lame'
+	
 
 configure, build = plugin('ices', configure=plugin_configure,
-                          source=['ices.c', 'encode.c'],
-                          extra_libs=['shout', 'vorbisenc', 'ogg', 'socket'],
+                          build=plugin_build, source=['ices.c'],
+                          extra_libs=['shout', 'socket'],
                           output_prio=0)

Attachment: signature.asc
Description: PGP signature

--
_______________________________________________
Xmms2-devel mailing list
Xmms2-devel@lists.xmms.se
http://lists.xmms.se/cgi-bin/mailman/listinfo/xmms2-devel

Reply via email to