changeset 144:5dfc0e491ad3 trunk

[svn] Null output plugin added; original code by Christian Birchinger <joker -at- gentoo.org>
author kiyoshi
date Mon, 30 Oct 2006 17:40:00 -0800
parents e8f34254bc18
children 7804476ba85a
files ChangeLog configure.ac mk/rules.mk.in src/null/Makefile src/null/null.c
diffstat 5 files changed, 298 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Oct 29 12:29:05 2006 -0800
+++ b/ChangeLog	Mon Oct 30 17:40:00 2006 -0800
@@ -1,3 +1,11 @@
+2006-10-29 20:29:05 +0000  William Pitcock <nenolod@nenolod.net>
+  revision [286]
+  - overflow fixes for modplug (via Stanislav Brabec @ novell/suse).
+  
+  trunk/src/modplug/sndfile.cxx |    3 ++-
+  1 file changed, 2 insertions(+), 1 deletion(-)
+
+
 2006-10-29 09:08:30 +0000  Aaron Sheldon <asheldon@uiuc.edu>
   revision [284]
   Atari XL SAP.  This compiles anything but cleanly, but somehow still 
--- a/configure.ac	Sun Oct 29 12:29:05 2006 -0800
+++ b/configure.ac	Mon Oct 30 17:40:00 2006 -0800
@@ -295,6 +295,22 @@
 	have_coreaudio=no
 fi
 
+dnl *** Null Audio
+
+AC_ARG_ENABLE(null,
+    [  --disable-null          disable Null Audio output plugin (default=enabled)],
+    [enable_null=$enableval],
+    [enable_null="yes"]
+)
+
+if test "$enable_null" = "yes"; then
+	have_null=yes
+	OUTPUT_PLUGINS="$OUTPUT_PLUGINS null"
+else
+	AC_MSG_RESULT([*** Null Audio output plugin disabled per user request ***])
+	have_null=no
+fi
+
 dnl *** AltiVec
 
 AC_CHECK_HEADERS(altivec.h,
@@ -1110,6 +1126,7 @@
 echo "  BSD/SUN audio output (sun):             $have_sun"
 echo "  PulseAudio sound server (pulse_audio):  $have_pulse"
 echo "  Mac OS X sound support (CoreAudio):     $have_coreaudio"
+echo "  Null Audio output (null):               $have_null"
 echo
 echo "  Input Plugins"
 echo "  -------------"
--- a/mk/rules.mk.in	Sun Oct 29 12:29:05 2006 -0800
+++ b/mk/rules.mk.in	Mon Oct 30 17:40:00 2006 -0800
@@ -157,6 +157,7 @@
 HAVE_GNOME_VFS_TRUE ?= @HAVE_GNOME_VFS_TRUE@
 HAVE_JACK_FALSE ?= @HAVE_JACK_FALSE@
 HAVE_JACK_TRUE ?= @HAVE_JACK_TRUE@
+HAVE_NULL_TRUE ?= @HAVE_NULL_TRUE@
 HAVE_LIBSAMPLERATE_FALSE ?= @HAVE_LIBSAMPLERATE_FALSE@
 HAVE_LIBSAMPLERATE_TRUE ?= @HAVE_LIBSAMPLERATE_TRUE@
 HAVE_LIBSNDFILE_FALSE ?= @HAVE_LIBSNDFILE_FALSE@
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/null/Makefile	Mon Oct 30 17:40:00 2006 -0800
@@ -0,0 +1,15 @@
+include ../../mk/rules.mk
+include ../../mk/init.mk
+
+OBJECTIVE_LIBS = libnull${SHARED_SUFFIX}
+
+LIBDIR = ${plugindir}/${OUTPUT_PLUGIN_DIR}
+
+SOURCES = null.c
+
+OBJECTS = ${SOURCES:.c=.o}
+
+CFLAGS += ${PICFLAGS} \
+	-I../..
+
+include ../../mk/objective.mk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/null/null.c	Mon Oct 30 17:40:00 2006 -0800
@@ -0,0 +1,257 @@
+/*
+ *  Copyright 2006 Christian Birchinger <joker@netswarm.net>
+ *
+ *  Based on the XMMS plugin:
+ *  Copyright 2000 Håvard Kvålen <havardk@sol.no>
+ *
+ *
+ *  This program 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.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <audacious/plugin.h>
+#include <audacious/util.h>
+#include <audacious/configdb.h>
+
+static GTimer *timer;
+static gulong offset_time, written;
+static gint bps;
+static gboolean real_time = TRUE;
+static gboolean paused, started;
+static GtkWidget *configurewin;
+static struct {
+	AFormat format;
+	gint frequency;
+	gint channels;
+} input_format;
+
+#define ELAPSED_TIME (offset_time + g_timer_elapsed(timer, NULL) * 1000)
+
+static void null_init(void)
+{
+	ConfigDb *db;
+	db = bmp_cfg_db_open();
+	bmp_cfg_db_get_bool(db, "null", "real_time", &real_time);
+	bmp_cfg_db_close(db);
+}
+
+static void null_about(void)
+{
+	static GtkWidget *about;
+
+	if (about)
+		return;
+	about = xmms_show_message(_("About Null Output"),
+				  _("Null output plugin " VERSION
+				  " by Christian Birchinger <joker@netswarm.net>\n"
+				  " based on the XMMS plugin by Håvard Kvål <havardk@xmms.org>"),
+				  _("Ok"), FALSE, NULL, NULL);
+
+	g_signal_connect(G_OBJECT(about), "destroy",
+			 G_CALLBACK(gtk_widget_destroyed), &about);
+}
+
+static void null_configure_ok_cb(GtkButton *w, gpointer data)
+{
+	ConfigDb *db;
+
+	db = bmp_cfg_db_open();
+	real_time = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data));
+	bmp_cfg_db_set_bool(db, "null", "real_time", real_time);
+	bmp_cfg_db_close(db);
+	gtk_widget_destroy(configurewin);
+}
+
+
+static void null_configure(void)
+{
+	GtkWidget *rt_btn, *ok_button, *cancel_button, *vbox, *bbox;
+
+	if (configurewin)
+		return;
+	
+	configurewin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+	gtk_window_set_title(GTK_WINDOW(configurewin), "Null output preferences");
+	gtk_window_set_policy(GTK_WINDOW(configurewin), FALSE, FALSE, FALSE);
+	gtk_container_set_border_width(GTK_CONTAINER(configurewin), 10);
+	gtk_signal_connect(GTK_OBJECT(configurewin), "destroy",
+			   GTK_SIGNAL_FUNC(gtk_widget_destroyed), &configurewin);
+
+	vbox = gtk_vbox_new(FALSE, 10);
+	gtk_container_add(GTK_CONTAINER(configurewin), vbox);
+
+	rt_btn = gtk_check_button_new_with_label("Run in real time");
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rt_btn), real_time);
+	gtk_box_pack_start(GTK_BOX(vbox), rt_btn, FALSE, FALSE, 0);
+	bbox = gtk_hbutton_box_new();
+	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+	gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
+	gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
+	ok_button = gtk_button_new_with_label("Ok");
+	cancel_button = gtk_button_new_with_label("Cancel");
+	GTK_WIDGET_SET_FLAGS(ok_button, GTK_CAN_DEFAULT);
+	GTK_WIDGET_SET_FLAGS(cancel_button, GTK_CAN_DEFAULT);
+	gtk_widget_grab_default(ok_button);
+	gtk_signal_connect_object(GTK_OBJECT(cancel_button), "clicked",
+				  GTK_SIGNAL_FUNC(gtk_widget_destroy),
+				  GTK_OBJECT(configurewin));
+	gtk_signal_connect(GTK_OBJECT(ok_button), "clicked",
+			   GTK_SIGNAL_FUNC(null_configure_ok_cb), rt_btn);
+	gtk_box_pack_start_defaults(GTK_BOX(bbox), ok_button);
+	gtk_box_pack_start_defaults(GTK_BOX(bbox), cancel_button);
+
+	gtk_widget_show_all(configurewin);
+}
+
+static int null_open(AFormat fmt, int rate, int nch)
+{
+	offset_time = 0;
+	written = 0;
+	started = FALSE;
+	paused = FALSE;
+	input_format.format = fmt;
+	input_format.frequency = rate;
+	input_format.channels = nch;
+	bps = rate * nch;
+	switch (fmt)
+	{
+		case FMT_U8:
+		case FMT_S8:
+			break;
+		default:
+			bps <<= 1;
+			break;
+	}
+	if (real_time)
+		timer = g_timer_new();
+	return 1;
+}
+
+static void null_write(void *ptr, int length)
+{
+	EffectPlugin *ep;
+	if (timer && !started)
+	{
+		g_timer_start(timer);
+		started = TRUE;
+	}
+
+	if ((ep = get_current_effect_plugin()) != NULL &&
+	    effects_enabled() && ep->mod_samples)
+		ep->mod_samples(&ptr, length, input_format.format,
+				input_format.frequency, input_format.channels);
+	
+	written += length;
+}
+
+static void null_close(void)
+{
+	if (timer)
+		g_timer_destroy(timer);
+	timer = NULL;
+}
+
+static void null_flush(int time)
+{
+	offset_time = time;
+	written = ((double)time * bps) / 1000;
+	if (timer)
+		g_timer_reset(timer);
+}
+
+static void null_pause(short p)
+{
+	paused = p;
+	if (!timer)
+		return;
+	
+	if (paused)
+		g_timer_stop(timer);
+	else
+	{
+		offset_time += g_timer_elapsed(timer, NULL) * 1000;
+		g_timer_start(timer);
+	}
+}
+
+static int null_buffer_free(void)
+{
+	if (timer)
+	{
+		return 10240 - (written - (ELAPSED_TIME * bps) / 1000);
+	}
+	else
+	{
+		if (!paused)
+			return 10000;
+		else
+			return 0;
+	}
+}
+
+static int null_playing(void)
+{
+	if (!timer)
+		return FALSE;
+	
+	if ((gdouble)(written * 1000) / bps > ELAPSED_TIME)
+		return TRUE;
+	return FALSE;
+}
+
+static int null_get_written_time(void)
+{
+	if (!bps)
+		return 0;
+	return ((gint64)written * 1000) / bps;
+}
+
+static int null_get_output_time(void)
+{
+	if (!timer)
+		return null_get_written_time();
+	
+	return ELAPSED_TIME;
+}
+
+OutputPlugin null_op =
+{
+	NULL,
+	NULL,
+	"Null output " VERSION,
+	null_init,
+	NULL,			/* cleanup */ 
+	null_about,
+	null_configure,
+	NULL,			/* Get volume */
+	NULL,			/* Set volume */
+	null_open,
+	null_write,
+	null_close,
+	null_flush,
+	null_pause,
+	null_buffer_free,
+	null_playing,
+	null_get_output_time,
+	null_get_written_time,
+	NULL			/* tell */
+};
+
+OutputPlugin *get_oplugin_info(void)
+{
+	return &null_op;
+}