changeset 155:2746c4cadd07 trunk

[svn] Add sndfile version of the wav plugin. Not integrated into buildsystem yet.
author chainsaw
date Sat, 12 Nov 2005 15:39:26 -0800
parents 6dc4483b4c4c
children 23726a5a74bc
files Plugins/Input/wav/wav-sndfile.c Plugins/Input/wav/wav-sndfile.h
diffstat 2 files changed, 315 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/wav/wav-sndfile.c	Sat Nov 12 15:39:26 2005 -0800
@@ -0,0 +1,271 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005 Audacious development team.
+ *
+ *  Based on the xmms_sndfile input plugin:
+ *  Copyright (C) 2000, 2002 Erik de Castro Lopo
+ *
+ *  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 <string.h>
+#include <math.h>
+#include <stdio.h>
+
+#include <libaudacious/util.h>
+#include <libaudacious/titlestring.h>
+#include "audacious/output.h"
+#include "wav-sndfile.h"
+
+#include <sndfile.h>
+
+static	SNDFILE *sndfile = NULL;
+static	SF_INFO sfinfo;
+
+static	int 	song_length;
+static	int 	bit_rate = 0;
+static	int 	decoding;
+static	int 	seek_time = -1;
+
+static	GThread *decode_thread;
+
+
+InputPlugin wav_ip = {
+    NULL,
+    NULL,
+    NULL,
+    plugin_init,
+    wav_about,
+    NULL,
+    is_our_file,
+    NULL,
+    play_start,
+    play_stop,
+    NULL,			/* Could call do_pause here, but it will cause auto-stop anyway */
+    file_seek,
+    NULL,
+    get_time,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    get_song_info,
+    NULL,
+    NULL
+};
+
+int
+get_song_length (char *filename)
+{	SNDFILE	*tmp_sndfile;
+	SF_INFO tmp_sfinfo;
+
+	if (! (tmp_sndfile = sf_open (filename, SFM_READ, &tmp_sfinfo)))
+		return 0;
+
+	sf_close (tmp_sndfile);
+	tmp_sndfile = NULL;
+
+	if (tmp_sfinfo.samplerate <= 0)
+		return 0;
+
+	return (int) ceil (1000.0 * tmp_sfinfo.frames / tmp_sfinfo.samplerate);
+} /* get_song_length */
+
+static gchar *get_title(char *filename)
+{
+	gchar *title;
+	title = g_path_get_basename(filename);
+	return title;
+}
+
+static void
+plugin_init (void)
+{
+	decoding = FALSE;
+	seek_time = -1;
+} /* plugin_int */
+
+static int
+is_our_file (char *filename)
+{	SNDFILE	*tmp_sndfile;
+	SF_INFO tmp_sfinfo;
+
+	/* Have to open the file to see if libsndfile can handle it. */
+	if (! (tmp_sndfile = sf_open (filename, SFM_READ, &tmp_sfinfo)))
+		return FALSE;
+
+	/* It can so close file and return TRUE. */
+	sf_close (tmp_sndfile);
+	tmp_sndfile = NULL;
+
+	return TRUE;
+} /* is_our_file */
+
+static void*
+play_loop (void *arg)
+{	static short buffer [BUFFER_SIZE];
+	int samples;
+
+	decoding = TRUE;
+	while (decoding)
+	{
+		/* sf_read_short will return 0 for all reads at EOF. */
+		samples = sf_read_short (sndfile, buffer, BUFFER_SIZE);
+
+		if (samples > 0 && decoding)
+		{	wav_ip.add_vis_pcm (wav_ip.output->written_time (), HOST_SIGNED_SHORT, sfinfo.channels, samples * sizeof (short), buffer);
+
+			while ((wav_ip.output->buffer_free () < (samples * sizeof (short))) && decoding)
+				xmms_usleep (80000);
+			
+			wav_ip.output->write_audio (buffer, samples * sizeof (short));
+   			}
+		else
+			xmms_usleep (80000);
+
+		/* Do seek if seek_time is valid. */
+		if (seek_time > 0)
+		{	sf_seek (sndfile, seek_time * sfinfo.samplerate, SEEK_SET);
+			wav_ip.output->flush (seek_time * 1000);
+			seek_time = -1;
+   			};
+
+  		}; /* while (decoding) */
+
+	g_thread_exit (NULL);
+	return NULL;
+} /* play_loop */
+
+static void
+play_start (char *filename)
+{
+	int pcmbitwidth;
+	gchar *song_title;
+
+	if (sndfile)
+		return;
+
+	pcmbitwidth = 32;
+
+	song_title = get_title(filename);
+
+	if (! (sndfile = sf_open (filename, SFM_READ, &sfinfo)))
+		return;
+
+	bit_rate = sfinfo.samplerate * pcmbitwidth * sfinfo.channels;
+
+	if (sfinfo.samplerate > 0)
+		song_length = (int) ceil (1000.0 * sfinfo.frames / sfinfo.samplerate);
+	else
+		song_length = 0;
+
+	if (! wav_ip.output->open_audio (HOST_SIGNED_SHORT, sfinfo.samplerate, sfinfo.channels))
+	{	sf_close (sndfile);
+		sndfile = NULL;
+		return;
+		};
+
+	wav_ip.set_info (song_title, song_length, bit_rate, sfinfo.samplerate, sfinfo.channels);
+	g_free (song_title);
+
+	decode_thread = g_thread_create ((GThreadFunc)play_loop, NULL, TRUE, NULL);
+
+	while (decoding == FALSE)
+	    xmms_usleep (80000);
+} /* play_start */
+
+static void
+play_stop (void)
+{
+	if (decode_thread == NULL)
+		return;
+
+	decoding = FALSE;
+
+	g_thread_join (decode_thread);
+	wav_ip.output->close_audio ();
+
+	sf_close (sndfile);
+	sndfile = NULL;
+	decode_thread = NULL;
+
+	seek_time = -1;
+} /* play_stop */
+
+static void
+file_seek (int time)
+{
+	if (! sfinfo.seekable)
+		return;
+
+	seek_time = time;
+
+	while (seek_time != -1)
+		xmms_usleep (80000);
+} /* file_seek */
+
+static int
+get_time (void)
+{
+	if ( ! (wav_ip.output->buffer_playing () && decoding))
+		return -1;
+
+	return wav_ip.output->output_time ();
+} /* get_time */
+
+static void
+get_song_info (char *filename, char **title, int *length)
+{
+	(*length) = get_song_length(filename);
+	(*title) = get_title(filename);
+} /* get_song_info */
+
+static void wav_about(void)
+{
+        static GtkWidget *box;
+        box = xmms_show_message(
+                _("About sndfile WAV support"),
+                _("Adapted for audacious usage by Tony Vroon <chainsaw@gentoo.org>\n"
+                  "from the xmms_sndfile plugin which is:\n"
+		  "Copyright (C) 2000, 2002 Erik de Castro Lopo\n\n"
+		  "This program is free software ; you can redistribute it and/or modify \n"
+	          "it under the terms of the GNU General Public License as published by \n"
+ 	          "the Free Software Foundation ; either version 2 of the License, or \n"
+	          "(at your option) any later version. \n \n"
+	          "This program is distributed in the hope that it will be useful, \n"
+	          "but WITHOUT ANY WARRANTY ; without even the implied warranty of \n"
+	          "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  \n"
+	          "See the GNU General Public License for more details. \n\n"
+	          "You should have received a copy of the GNU General Public \n"
+	          "License along with this program ; if not, write to \n"
+	          "the Free Software Foundation, Inc., \n"
+	          "59 Temple Place, Suite 330, \n"
+	          "Boston, MA  02111-1307  USA"),
+                _("Ok"), FALSE, NULL, NULL);
+        gtk_signal_connect(GTK_OBJECT(box), "destroy",
+                           gtk_widget_destroyed, &box);
+}
+
+
+InputPlugin *get_iplugin_info(void)
+{
+        wav_ip.description = g_strdup_printf(_("sndfile WAV plugin"));
+        return &wav_ip;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/wav/wav-sndfile.h	Sat Nov 12 15:39:26 2005 -0800
@@ -0,0 +1,44 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005 Audacious development team.
+ *
+ *  Based on the xmms_sndfile input plugin:
+ *  Copyright (C) 2000, 2002 Erik de Castro Lopo
+ *
+ *  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.
+ */
+
+#ifndef WAV_SNDFILE_H
+#define WAV_SNDFILE_H
+
+#define BUFFER_SIZE 			8192
+#define	TITLE_LEN			64
+
+#ifdef WORDS_BIGENDIAN
+# define	HOST_SIGNED_SHORT	FMT_S16_BE
+#else
+# define	HOST_SIGNED_SHORT	FMT_S16_LE
+#endif
+
+static	void 	plugin_init (void);
+static	int	is_our_file (char *filename);
+static	void 	play_start (char *filename);
+static	void 	play_stop (void);
+static	void 	do_pause (short pause);
+static	void 	file_seek (int time);
+static	int	get_time (void);
+static	void 	get_song_info (char *filename, char **title, int *length);
+static  void    wav_about (void);
+
+#endif