changeset 1208:c1dcc9d38f98 trunk

Automated merge with ssh://hg.atheme.org//hg/audacious-plugins
author William Pitcock <nenolod@atheme-project.org>
date Wed, 04 Jul 2007 23:27:27 -0500
parents 3094d9c8a935 (current diff) c39a61e6a276 (diff)
children 594909468f53
files src/sexypsf/xmms.c
diffstat 6 files changed, 543 insertions(+), 441 deletions(-) [+]
line wrap: on
line diff
--- a/AUTHORS	Wed Jul 04 23:25:02 2007 -0500
+++ b/AUTHORS	Wed Jul 04 23:27:27 2007 -0500
@@ -4,6 +4,7 @@
 --------------------------------------------
 
 George Averill <nhjm449@gmail.com>
+Michael Färber <0102@gmx.at>
 Giacomo Lozito <james@develia.org>
 William Pitcock <nenolod@nenolod.net>
 Derek Pomery <nemo@m8y.org>
@@ -24,7 +25,7 @@
 Greek              - Kouzinopoulos Haris
                      Stavros Giannouris
                      Stathis Kamperis
-Italian		   - Diego Petteno
+Italian            - Diego Petteno
 Japanese           - Dai
 
 -
@@ -91,7 +92,7 @@
 Japanese             - Takeshi Aihana <aihana@gnome.gr.jp>
 Korean               - DongCheon Park <dcpark@kaist.ac.kr>
 Lithuanian           - Rimas Kudelis <rq@akl.lt>
-Macedonian 	     - Arangel Angov <ufo@linux.net.mk>
+Macedonian           - Arangel Angov <ufo@linux.net.mk>
 Polish               - Jacek Wolszczak <shutdownrunner@o2.pl>
 Romanian             - Liviu Danicel <liviu.danicel@spymac.com>
 Russian              - Pavlo Bohmat <bohm@ukr.net>
--- a/src/lastfm/lastfm.c	Wed Jul 04 23:25:02 2007 -0500
+++ b/src/lastfm/lastfm.c	Wed Jul 04 23:27:27 2007 -0500
@@ -1,131 +1,200 @@
-/*  Audacious
- *  Copyright (c) 2007 Cristi Magherusan
- *
- *  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.
+/* Audacious lastfm transport plugin
+ * Copyright (c) 2007 Cristi Magherusan <majeru@gentoo.ro>
+ * All rights reserved.
  *
- *  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 
+ *       Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ * 
+ *       Redistributions in binary form must reproduce the above copyright notice,
+ *       this list of conditions and the following disclaimer in the documentation
+ *       and/or other materials provided with the distribution.
+ * 
+ *       Neither the name of the author nor the names of its contributors may be
+ *       used to endorse or promote products derived from this software without
+ *       specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <audacious/vfs.h>
 #include <audacious/plugin.h>
 #include <audacious/configdb.h>
-
 #include <libmowgli/mowgli_global_storage.h>
 #include <curl/curl.h>
 #include <glib.h>
 #include "lastfm.h"
 
-#define DEBUG 0
+#define DEBUG 1 
+
+size_t lastfm_store_res(void *ptr, size_t size, size_t nmemb, void *udata)
+{
+        GString *data = (GString *) udata;
+        g_string_append_len(data, ptr, nmemb);
+        return size * nmemb;
+}
 
-LastFM *LastFMGlobalData;
-/*this keeps the login data in a global place since 
- * we cannot login on every fopen call* if anyone 
- * has a better solution to this any hint is welcome */
-
-static size_t lastfm_store_res(void *ptr, size_t size, size_t nmemb, void *udata)
+gint lastfm_get_data_from_uri(gchar *url, GString * result)
 {
-	GString *data = (GString *) udata;
-	g_string_append_len(data, ptr, nmemb);
-	return size * nmemb;
+        CURL *curl = curl_easy_init();
+        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
+        curl_easy_setopt(curl, CURLOPT_USERAGENT, "mplayer");
+        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, lastfm_store_res);
+        curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+        curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, LASTFM_CURL_TIMEOUT);
+        curl_easy_setopt(curl, CURLOPT_URL, url);
+        curl_easy_setopt(curl, CURLOPT_WRITEDATA, result);
+        gint status = curl_easy_perform(curl);
+        curl_easy_cleanup(curl);
+        return status;
 }
 
-gint get_data_from_url(gchar buf[4096], GString * res)
+gchar* lastfm_get_login_uri()
 {
-	CURL *curl = curl_easy_init();
-	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
-	curl_easy_setopt(curl, CURLOPT_USERAGENT, "Audacious");
-	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, lastfm_store_res);
-	curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
-	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
-	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, LASTFM_CURL_TIMEOUT);
-	curl_easy_setopt(curl, CURLOPT_URL, buf);
-	curl_easy_setopt(curl, CURLOPT_WRITEDATA, res);
-	gint status = curl_easy_perform(curl);
-	curl_easy_cleanup(curl);
-	return status;
+#if DEBUG
+        g_print("Getting login data from config\n");
+#endif
+
+        ConfigDb *cfgfile = NULL;
+        gchar   *buf=NULL,
+                *username = NULL, 
+                *password = NULL;
+        if ((cfgfile = bmp_cfg_db_open()) != NULL)
+        {
+                bmp_cfg_db_get_string(cfgfile, "audioscrobbler","username",
+                                &username);
+                bmp_cfg_db_get_string(cfgfile, "audioscrobbler","password",
+                                &password);
+                g_free(cfgfile);
+        }
+        if (username != NULL && password != NULL)
+        {
+#if DEBUG
+        g_print("Creating the login URI\n");
+#endif
+
+                buf=g_strdup_printf(LASTFM_HANDSHAKE_URL, username, password);
+                g_free(password);
+                g_free(username);
+#if DEBUG
+                g_print("Succesfully created the login uri\n");
+#endif
+                return buf;
+        }
+        else {
+#if DEBUG
+                g_print("Couldn't find the login data. Use the scrobbler plugin to set it up.\n");
+#endif
+
+        return NULL;
+        }
+}
+
+void lastfm_store(gchar *var_name,gchar* var){
+if (mowgli_global_storage_get(var_name))
+                mowgli_global_storage_free(var_name);
+
+        mowgli_global_storage_put(var_name,var);
+#if DEBUG
+        g_print("Storing into '%s' the value '%s'\n",var_name,var);
+#endif
 }
 
-static gboolean lastfm_login(void)
+int lastfm_login(void)
 {
-	/*gets the session ID in lastfm_session_id and returns the URL to be played
-	 * read http://gabistapler.de/blog/index.php?/archives/268-Play-last.fm-streams-without-the-player.html for more info
-	 */
-	gint status, i;
-	gchar buf[4096], **split = NULL;
-	GString *res = g_string_new(NULL);
-	ConfigDb *cfgfile = NULL;
-	char *username = NULL, *password = NULL;
-	if ((cfgfile = bmp_cfg_db_open()) != NULL)
-	{
-		bmp_cfg_db_get_string(cfgfile, "audioscrobbler", "username", &username);
-		bmp_cfg_db_get_string(cfgfile, "audioscrobbler", "password", &password);
-		g_free(cfgfile);
-	}
-	if (username != NULL && password != NULL)
-	{
-		snprintf(buf, sizeof(buf), LASTFM_HANDSHAKE_URL, username, password);
-		g_free(password);
-		g_free(username);
-	}
-	else
-		return FALSE;
+        /*gets the session ID in the URL to be played and stores them using 
+         * mowgli_global_storage
+         * read http://gabistapler.de/blog/index.php?/archives/268-Play-last.fm-streams-without-the-player.html for more info
+         */
+      
+        gint status, i;
+        gchar   *lastfm_session_id=NULL, 
+                *lastfm_stream_uri=NULL,
+                *login_uri=NULL,
+                **split = NULL;
+        GString *res = g_string_new(NULL);
+g_print("Logging in\n");
+        login_uri=lastfm_get_login_uri();
+        if(login_uri==NULL){
+                g_free(login_uri);
+                return LASTFM_MISSING_LOGIN_DATA;
+                }
+        status = lastfm_get_data_from_uri(login_uri, res);
+#if DEBUG
+        g_print("Opened login URI: '%s'\n", login_uri);
+        g_print("Got following data: '%s'\n", res->str);
+#endif
 
-	status = get_data_from_url(buf, res);
+        if (status == CURLE_OK)
+        {
+                split = g_strsplit(res->str, "\n", 7);
 
-#ifdef DEBUG
-	g_print("URL:%s\n", buf);
-	g_print("Downloaded data:%s\n", res->str);
+                for (i = 0; split && split[i]; i++)
+                {
+                        if (g_str_has_prefix(split[i], "session="))
+                        {
+                                lastfm_session_id = g_strndup(split[i] + 8, 32);
+#if DEBUG
+                                g_print("Got session ID:'%s'\n",lastfm_session_id);
 #endif
-	if (status == CURLE_OK)
-	{
-		split = g_strsplit(res->str, "\n", 7);
+                        }
+                        else if (g_str_has_prefix(split[i], "stream_url="))
+                                lastfm_stream_uri = g_strdup(split[i] + 11);
+                }
+        }
+        else
+                {
+                g_strfreev(split);
+                g_string_erase(res, 0, -1);
+                g_free(lastfm_session_id);
+                g_free(lastfm_stream_uri);
+                g_free(login_uri);
+                return LASTFM_LOGIN_ERROR;
+                }
+        lastfm_store("lastfm_session_id",lastfm_session_id);
+        lastfm_store("lastfm_stream_uri",lastfm_stream_uri);
 
-		for (i = 0; split && split[i]; i++)
-		{
-			if (g_str_has_prefix(split[i], "session="))
-				LastFMGlobalData->lastfm_session_id = g_strndup(split[i] + 8, 32);
-			else if (g_str_has_prefix(split[i], "stream_url="))
-				LastFMGlobalData->lastfm_mp3_stream_url = g_strdup(split[i] + 11);
-		}
-	}
-	else
-		return FALSE;
-
-	g_strfreev(split);
-	g_string_erase(res, 0, -1);
-
-	if (mowgli_global_storage_get("lastfm_session_id"))
-		mowgli_global_storage_free("lastfm_session_id");
-
-	mowgli_global_storage_put("lastfm_session_id", LastFMGlobalData->lastfm_session_id);
-
-	return (gboolean) TRUE;
+#if DEBUG
+        g_print("Login finished succesfully\n");
+#endif
+        g_strfreev(split);
+        g_string_erase(res, 0, -1);
+        g_free(login_uri);
+ return LASTFM_LOGIN_OK ;
 }
 
-static gboolean lastfm_adjust(const gchar * url)
+gint lastfm_adjust(const gchar * uri)
 {
-	int status, i;
-	gchar tmp[4096], **split = NULL;
-	gboolean ret = FALSE;
-	GString *res = g_string_new(NULL);
+        int status, i;
+        gchar tmp[4096], **split = NULL;
+        gboolean ret = FALSE;
+        GString *res = g_string_new(NULL);
+        gchar* session_id=mowgli_global_storage_get("lastfm_session_id");
+
 
-	if (LastFMGlobalData->lastfm_session_id == NULL)
-		return FALSE;
-	snprintf(tmp, sizeof(tmp), LASTFM_ADJUST_URL, LastFMGlobalData->lastfm_session_id, url);
+        if (!session_id)
+		return LASTFM_SESSION_MISSING;
+#if DEBUG
+        g_print("Session ID: '%s'\n",session_id);
+#endif
 
-	status = get_data_from_url(tmp, res);
+        snprintf(tmp, sizeof(tmp), LASTFM_ADJUST_URL, session_id, uri);
 
-#ifdef DEBUG
+	status = lastfm_get_data_from_uri(tmp, res);
+
+#if DEBUG
 	g_print("Adjust received data:%s\n", res->str);
 #endif
 	if (status == CURLE_OK)
@@ -135,54 +204,67 @@
 		for (i = 0; split && split[i]; i++)
 		{
 			if (g_str_has_prefix(split[i], "response=OK"))
-				ret = TRUE;
+				ret = LASTFM_ADJUST_OK;
 			if (g_str_has_prefix(split[i], "stationname="))
 			{
-				LastFMGlobalData->lastfm_station_name = g_strdup(split[i] + 12);
-#ifdef DEBUG
-				g_print("StationnName:%s\n", LastFMGlobalData->lastfm_station_name);
+				mowgli_global_storage_put("lastfm_station_name", g_strdup(split[i] + 12));
+#if DEBUG
+				g_print ("Setting station name: '%s'\n", 
+                                        (gchar*)mowgli_global_storage_get("lastfm_station_name"));
 #endif
 			}
 		}
 		g_strfreev(split);
 	}
 	g_string_erase(res, 0, -1);
-
+       
 	return ret;
 }
 
+void parse( gchar **split , gchar* field, gchar* data){
 
-static void parse_metadata(LastFM * handle,GString * res)
+
+}
+
+void parse_metadata(LastFM * handle,GString * metadata)
 {
-        gchar **split = g_strsplit(res->str, "\n", 20);
+        gchar **split = g_strsplit(metadata->str, "\n", 20);
         int i;
+        handle->lastfm_duration=0;
+        
         for (i = 0; split && split[i]; i++)
         {
                 if (g_str_has_prefix(split[i], "artist="))
                 {
-                        if (handle->lastfm_artist) g_free(handle->lastfm_artist);
+                        if (handle->lastfm_artist) 
+                                g_free(handle->lastfm_artist);
+
                         handle->lastfm_artist = g_strdup(split[i] + 7);
-#ifdef DEBUG
+#if DEBUG
                         g_print("Artist: %s\n", handle->lastfm_artist);
 #endif
                 }
                 if (g_str_has_prefix(split[i], "track="))
                 {
-                        if (handle->lastfm_title) g_free(handle->lastfm_title);
+                        if (handle->lastfm_title) 
+                                g_free(handle->lastfm_title);
+
                         handle->lastfm_title = g_strdup(split[i] + 6);
-#ifdef DEBUG
+#if DEBUG
                         g_print("Title: %s\n", handle->lastfm_title);
 #endif
                 }
 
                 if (g_str_has_prefix(split[i], "album="))
                         handle->lastfm_album = g_strdup(split[i] + 6);
+
                 if (g_str_has_prefix(split[i], "albumcover_medium="))
                         handle->lastfm_cover = g_strdup(split[i] + 18);
+
                 if (g_str_has_prefix(split[i], "trackduration="))
                 {
                         handle->lastfm_duration = g_ascii_strtoull(g_strdup(split[i] + 14), NULL, 10);
-#ifdef DEBUG
+#if DEBUG
                         g_print("Duration:%d\n", handle->lastfm_duration);
 #endif
                 }
@@ -192,7 +274,7 @@
                 if (g_str_has_prefix(split[i], "station="))
                 {
                         handle->lastfm_station_name = g_strdup(split[i] + 8);
-#ifdef DEBUG
+#if DEBUG
                         g_print("Station Name: %s\n", handle->lastfm_station_name);
 #endif
                 }
@@ -203,22 +285,31 @@
 }
 
 
-static gpointer lastfm_get_metadata(gpointer arg)
-{
-        int err=0,delay=-2;
-
-        int sleep_duration,count=0;
-        gint status;
-        gchar tmp[4096];
+gpointer lastfm_get_metadata(gpointer arg)
+{     
+        gint    err=0,
+                delay=-2,
+                sleep_duration=1,
+                count=0,
+                status;
+        gchar uri[4096];
         GString *res = g_string_new(NULL);
         gboolean track_end=FALSE;
         LastFM *handle = (LastFM *)arg;
+        handle->lastfm_session_id =g_strdup(mowgli_global_storage_get("lastfm_session_id"));
+#if DEBUG
+                        g_print("Session ID: %s\n", handle->lastfm_session_id);
+#endif
 
         if (handle->lastfm_session_id == NULL)
                 return NULL;
-        snprintf(tmp, sizeof(tmp), LASTFM_METADATA_URL, handle->lastfm_session_id);
+        snprintf(uri, sizeof(uri), LASTFM_METADATA_URL, handle->lastfm_session_id);
+#if DEBUG
+                        g_print("Download URI: %s\n", uri);
+#endif
 
-        while ( (handle!= NULL) && (handle->metadata_thread == g_thread_self ()) && (err<5))
+
+        while ( (handle!= NULL)  && (err<5))
                 //exit after 5 failed retries or after metadata_thread changes
         {       
                 count++;
@@ -226,14 +317,12 @@
                 {
                         handle->lastfm_duration = 0;
                         handle->lastfm_progress = 0;
-                        status = get_data_from_url(tmp, res);
-#if 0
-                        g_print("Received metadata:%s\n", res->str);
-#endif
+                        status = lastfm_get_data_from_uri(uri, res);
                         if (status == CURLE_OK)
                         {
-#ifdef DEBUG
-                                g_print("Got Metadata\n");
+#if DEBUG
+                                g_print("Successfully got Metadata\n");
+                                g_print("Received metadata:'%s'\nParsing...", res->str);
 #endif
                                 parse_metadata( handle,res);
                         }
@@ -263,14 +352,14 @@
                                                 //when calculating sleep_time
                         }
 
-#ifdef DEBUG
+#if DEBUG
 		g_print("Sleeping for %d seconds\n", sleep_duration);
 #endif
 	        }
                 sleep(1);
         }
 
-#ifdef DEBUG
+#if DEBUG
         g_print("Exiting thread, ID = %p\n", (void *)g_thread_self());
 #endif
         handle->metadata_thread = NULL;
@@ -284,29 +373,32 @@
 	LastFM *handle;
 	file = g_new0(VFSFile, 1);
 	handle = g_new0(LastFM, 1);
-        while ((LastFMGlobalData->lastfm_mp3_stream_url == NULL) && (LastFMGlobalData->login_count <= 3))
+        int login_count = 0;
+        while( ! mowgli_global_storage_get("lastfm_stream_uri")&&(login_count <= 3))
 	{
-		printf("Login try count: %d\n", LastFMGlobalData->login_count++);
+		printf("Login try count: %d\n", login_count++);
 		lastfm_login();
-		if (LastFMGlobalData->lastfm_mp3_stream_url == NULL)
+		if (!mowgli_global_storage_get("lastfm_stream_uri"))
 			sleep(5);
 	}
 
-	if (LastFMGlobalData->lastfm_mp3_stream_url == NULL)
+        if (!mowgli_global_storage_get("lastfm_stream_uri"))
 		return NULL;
 
-
-	if (LastFMGlobalData->lastfm_station_name==NULL)
+	handle->lastfm_session_id = g_strdup(mowgli_global_storage_get("lastfm_session_id"));
+	handle->lastfm_mp3_stream_url = g_strdup(mowgli_global_storage_get("lastfm_stream_uri"));
+	
+        if (!mowgli_global_storage_get("lastfm_station_name"))
                 {
-                        if(lastfm_adjust(path))
+                        if(lastfm_adjust(path)==LASTFM_ADJUST_OK)
                         {	                                
-#ifdef DEBUG
+#if DEBUG
         		g_print("Tuning was successfully completed into the channel\n");
 #endif
 		        }
                         else
                         {
-#ifdef DEBUG            
+#if DEBUG            
         		g_print("Cannot tune to given channel\n");
 #endif
                         }
@@ -314,21 +406,18 @@
         
         if ((handle->metadata_thread = g_thread_create(lastfm_get_metadata, handle, FALSE, NULL)) == NULL)
 		            {
-#ifdef DEBUG
-			            g_print("Error creating metadata thread!!!\n");
+#if DEBUG
+                                        g_print("Error creating metadata thread!!!\n");
 #endif
 			             return NULL;
 		            }
 		        else
                             {
-#ifdef DEBUG
-                                g_print("A metadata thread has just been created, ID = %p \n", (void *)handle->metadata_thread);
+#if DEBUG
+                                        g_print("A metadata thread has just been created, ID = %p \n", (void *)handle->metadata_thread);
 #endif
                             }
 
-	handle->lastfm_mp3_stream_url = g_strdup(LastFMGlobalData->lastfm_mp3_stream_url);
-	handle->lastfm_session_id = g_strdup(LastFMGlobalData->lastfm_session_id);
-	handle->lastfm_station_name = g_strdup(LastFMGlobalData->lastfm_station_name);
         handle->proxy_fd = vfs_fopen(handle->lastfm_mp3_stream_url, mode);
 	file->handle = handle;
 
@@ -459,13 +548,17 @@
 
 static void init(void)
 {       
-	LastFMGlobalData = g_new0(LastFM, 1);
 	vfs_register_transport(&lastfm_const);
 }
 
 static void cleanup(void)
 {
-	g_free(LastFMGlobalData);
+
+mowgli_global_storage_free("lastfm_session_id");
+mowgli_global_storage_free("lastfm_stream_uri");
+#if DEBUG
+g_print ("Cleanup finished\n");
+#endif
 }
 
 DECLARE_PLUGIN(lastfm, init, cleanup, NULL, NULL, NULL, NULL, NULL)
--- a/src/lastfm/lastfm.h	Wed Jul 04 23:25:02 2007 -0500
+++ b/src/lastfm/lastfm.h	Wed Jul 04 23:27:27 2007 -0500
@@ -5,6 +5,13 @@
 #define LASTFM_CURL_TIMEOUT 10
 
 
+#define LASTFM_LOGIN_OK                 0
+#define LASTFM_LOGIN_ERROR              1
+#define LASTFM_MISSING_LOGIN_DATA       2
+#define LASTFM_SESSION_MISSING          4
+#define LASTFM_ADJUST_OK                0
+
+
 typedef struct
 {
 	VFSFile *proxy_fd;
--- a/src/sexypsf/Makefile	Wed Jul 04 23:25:02 2007 -0500
+++ b/src/sexypsf/Makefile	Wed Jul 04 23:27:27 2007 -0500
@@ -18,7 +18,7 @@
 	PsxInterpreter.c \
 	PsxHLE.c \
 	spu/spu.c \
-	xmms.c
+	plugin.c
 
 LIBADD = -lz
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sexypsf/plugin.c	Wed Jul 04 23:27:27 2007 -0500
@@ -0,0 +1,292 @@
+/*  sexyPSF - PSF1 player
+ *  Copyright (C) 2002-2004 xodnizel
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "audacious/output.h"
+#include "audacious/plugin.h"
+#include "audacious/titlestring.h"
+#include "audacious/util.h"
+#include "audacious/vfs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "driver.h"
+
+static volatile int seek = 0;
+static volatile gboolean playing = FALSE;
+static volatile gboolean paused = FALSE;
+static volatile gboolean stop = FALSE;
+static volatile gboolean nextsong = FALSE;
+
+extern InputPlugin sexypsf_ip;
+static gboolean audio_error = FALSE;
+
+static PSFINFO *PSFInfo = NULL;
+static gchar *fnsave = NULL;
+static GThread *dethread = NULL;
+static InputPlayback *playback = NULL;
+
+static gchar *get_title_psf(gchar *fn);
+
+static int is_our_fd(gchar *filename, VFSFile *file) {
+    gchar magic[4];
+    vfs_fread(magic, 1, 4, file);
+
+    // only allow PSF1 for now
+    if (!memcmp(magic, "PSF\x01", 4))
+        return 1;
+    return 0;
+}
+
+
+void sexypsf_update(unsigned char *buffer, long count)
+{
+    const int mask = ~((((16 / 8) * 2)) - 1);
+
+    while (count > 0)
+    {
+        int t = playback->output->buffer_free() & mask;
+        if (t > count)     
+            produce_audio(playback->output->written_time(),
+                          FMT_S16_NE, 2, count, buffer, NULL);
+        else
+        {
+            if (t)
+                produce_audio(playback->output->written_time(),
+                              FMT_S16_NE, 2, t, buffer, NULL);
+            g_usleep((count-t)*1000*5/441/2);
+        }
+        count -= t;
+        buffer += t;
+    }
+    if (seek)
+    {
+        if(sexypsf_seek(seek))
+        {
+            playback->output->flush(seek);
+            seek = 0;
+        }
+        else  // negative time - must make a C time machine
+        {
+            sexypsf_stop();
+            return;
+        }
+    }
+    if (stop)
+        sexypsf_stop();
+}
+
+static gpointer sexypsf_playloop(gpointer arg)
+{
+    while (TRUE)
+    {
+        sexypsf_execute();
+
+        /* we have reached the end of the song or a command was issued */
+
+        playback->output->buffer_free();
+        playback->output->buffer_free();
+
+        if (stop)
+            break;
+
+        if (seek)
+        {
+            playback->output->flush(seek);
+            if(!(PSFInfo = sexypsf_load(fnsave)))
+                break;
+            sexypsf_seek(seek); 
+            seek = 0;
+            continue;
+        }
+
+        // timeout at the end of a file
+        sleep(4);
+        break;
+    }
+
+    playback->output->close_audio();
+    if (!(stop)) nextsong = TRUE;
+    g_thread_exit(NULL);
+    return NULL;
+}
+
+static void sexypsf_xmms_play(InputPlayback *data)
+{
+    if (playing)
+        return;
+
+    playback = data;
+    nextsong = FALSE;
+    paused = FALSE;
+
+    if (!playback->output->open_audio(FMT_S16_NE, 44100, 2))
+    {
+        audio_error = TRUE;
+        return;
+    }
+
+    fnsave = malloc(strlen(data->filename)+1);
+    strcpy(fnsave, data->filename);
+    if(!(PSFInfo=sexypsf_load(data->filename)))
+    {
+        playback->output->close_audio();
+        nextsong = 1;
+    }
+    else
+    {
+        stop = seek = 0;
+
+        gchar *name = get_title_psf(data->filename);
+        sexypsf_ip.set_info(name, PSFInfo->length, 44100*2*2*8, 44100, 2);
+        g_free(name);
+
+        playing = 1;
+        dethread = g_thread_create((GThreadFunc)sexypsf_playloop,
+                                   NULL, TRUE, NULL);
+    }
+}
+
+static void sexypsf_xmms_stop(InputPlayback * playback)
+{
+    if (!playing) return;
+
+    if (paused)
+        playback->output->pause(0);
+    paused = FALSE;
+
+    stop = TRUE;
+    g_thread_join(dethread);
+    playing = FALSE;
+
+    if (fnsave)
+    {
+        free(fnsave);
+        fnsave = NULL;
+    } 
+    sexypsf_freepsfinfo(PSFInfo);
+    PSFInfo = NULL;
+}
+
+static void sexypsf_xmms_pause(InputPlayback *playback, short p)
+{
+    if (!playing) return;
+    playback->output->pause(p);
+    paused = p;
+}
+
+static void sexypsf_xmms_seek(InputPlayback * data, int time)
+{
+    if (!playing) return;
+    seek = time * 1000;
+}
+
+static int sexypsf_xmms_gettime(InputPlayback *playback)
+{
+    if (audio_error)
+        return -2;
+    if (nextsong)
+        return -1;
+    if (!playing)
+        return 0;
+
+    return playback->output->output_time();
+}
+
+static void sexypsf_xmms_getsonginfo(char *fn, char **title, int *length)
+{
+    PSFINFO *tmp;
+
+    if((tmp = sexypsf_getpsfinfo(fn))) {
+        *length = tmp->length;
+        *title = get_title_psf(fn);
+        sexypsf_freepsfinfo(tmp);
+    }
+}
+
+static TitleInput *get_tuple_psf(gchar *fn) {
+    TitleInput *tuple = NULL;
+    PSFINFO *tmp = sexypsf_getpsfinfo(fn);
+
+    if (tmp->length) {
+        tuple = bmp_title_input_new();
+        tuple->length = tmp->length;
+        tuple->performer = g_strdup(tmp->artist);
+        tuple->album_name = g_strdup(tmp->game);
+        tuple->track_name = g_strdup(tmp->title);
+        tuple->file_name = g_path_get_basename(fn);
+        tuple->file_path = g_path_get_dirname(fn);
+        sexypsf_freepsfinfo(tmp);
+    }
+
+    return tuple;
+}   
+
+static gchar *get_title_psf(gchar *fn) {
+    gchar *title = NULL;
+    TitleInput *tinput = get_tuple_psf(fn);
+
+    if (tinput != NULL) {
+        title = xmms_get_titlestring(xmms_get_gentitle_format(),
+                                     tinput);
+        bmp_title_input_free(tinput);
+    }
+    else
+        title = g_path_get_basename(fn);
+
+    return title;
+}
+
+gchar *sexypsf_fmts[] = { "psf", "minipsf", NULL };
+
+InputPlugin sexypsf_ip =
+{
+    NULL,
+    NULL,
+    "PSF Audio Plugin",
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    sexypsf_xmms_play,
+    sexypsf_xmms_stop,
+    sexypsf_xmms_pause,
+    sexypsf_xmms_seek,
+    NULL,
+    sexypsf_xmms_gettime,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    sexypsf_xmms_getsonginfo,
+    NULL,
+    NULL,
+    get_tuple_psf,
+    NULL,
+    NULL,
+    is_our_fd,
+    sexypsf_fmts,
+};
+
+InputPlugin *sexypsf_iplist[] = { &sexypsf_ip, NULL };
+
+DECLARE_PLUGIN(sexypsf, NULL, NULL, sexypsf_iplist, NULL, NULL, NULL, NULL);
--- a/src/sexypsf/xmms.c	Wed Jul 04 23:25:02 2007 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,291 +0,0 @@
-/*  sexyPSF - PSF1 player
- *  Copyright (C) 2002-2004 xodnizel
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library 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
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-#include "audacious/output.h"
-#include "audacious/plugin.h"
-#include "audacious/titlestring.h"
-#include "audacious/util.h"
-#include "audacious/vfs.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "driver.h"
-
-#define CMD_SEEK	0x80000000
-#define CMD_STOP	0x40000000
-
-#define uint32 u32
-#define int16 short
-
-static volatile uint32 command;
-static volatile int playing=0;
-static volatile int nextsong=0;
-
-extern InputPlugin sexypsf_ip;
-static char *fnsave=NULL;
-
-static gchar *get_title_psf(gchar *fn);
-static int paused;
-static GThread *dethread;
-static PSFINFO *PSFInfo=NULL;
-
-static int is_our_fd(gchar *filename, VFSFile *file) {
-	gchar magic[4], *tmps;
-	// Filter out psflib [we use them, but we can't play them]
-	static const gchar *teststr = "psflib";
-	if (strlen(teststr) < strlen(filename)) {
-		tmps = filename + strlen(filename);
-		tmps -= strlen(teststr);
-		if (!strcasecmp(tmps, teststr))
-			return 0;
-	}
-	vfs_fread(magic,1,4,file);
-	//Only allow PSF1 for now.
-	if (!memcmp(magic,"PSF\x01",4))
-		return 1;
-	return 0;
-}
-
-static void SI(gchar *filename)
-{
-	gchar *name = get_title_psf(filename);
-	sexypsf_ip.set_info(name,PSFInfo->length,44100*2*2*8,44100,2);
-	g_free(name);
-}
-
-static InputPlayback *playback;
-
-void sexypsf_update(unsigned char *Buffer, long count)
-{
-	int mask = ~((((16 / 8) * 2)) - 1);
-
-	while(count>0)
-	{
-		int t=playback->output->buffer_free() & mask;
-		if(t>count)		
-			produce_audio(playback->output->written_time(), FMT_S16_NE, 2, count, Buffer, NULL);
-		else
-		{
-			if(t)
-				produce_audio(playback->output->written_time(), FMT_S16_NE, 2, t, Buffer, NULL);
-			g_usleep((count-t)*1000*5/441/2);
-		}
-		count-=t;
-		Buffer+=t;
-	}
-	if(command&CMD_SEEK)
-	{
-		int t=(command&~(CMD_SEEK|CMD_STOP))*1000;
-
-		if(sexypsf_seek(t))
-			playback->output->flush(t);
-		else	// Negative time!  Must make a C time machine.
-		{
-			sexypsf_stop();
-			return;
-		}
-		command&=~CMD_SEEK;
-	}
-	if(command&CMD_STOP)
-		sexypsf_stop();
-}
-
-static void *sexypsf_playloop(void *arg)
-{
-dofunky:
-
-	sexypsf_execute();
-
-	/* We have reached the end of the song. Now what... */
-	playback->output->buffer_free();
-	playback->output->buffer_free();
-
-	while(!(command&CMD_STOP)) 
-	{
-		if(command&CMD_SEEK)
-			{
-			int t=(command&~(CMD_SEEK|CMD_STOP))*1000;
-			playback->output->flush(t);
-			if(!(PSFInfo=sexypsf_load(fnsave)))
-				break;
-			sexypsf_seek(t); 
-			command&=~CMD_SEEK;
-			goto dofunky;
-			}
-		if(!playback->output->buffer_playing()) break;
-			usleep(2000);
-	}
-	playback->output->close_audio();
-	if(!(command&CMD_STOP)) nextsong=1;
-	g_thread_exit(NULL);
-	return(NULL);
-}
-
-static void sexypsf_xmms_play(InputPlayback *data)
-{
-        char *fn = data->filename;
-	if(playing)
-		return;
-	playback = data;
-	nextsong=0;
-	paused = 0;
-	if(!playback->output->open_audio(FMT_S16_NE, 44100, 2))
-	{
-		puts("Error opening audio.");
-		return;
-	}
-	fnsave=malloc(strlen(fn)+1);
-	strcpy(fnsave,fn);
-	if(!(PSFInfo=sexypsf_load(fn)))
-	{
-		playback->output->close_audio();
-		nextsong=1;
-	}
- 	else
-	{
-		command=0;
-		SI(fn);
-		playing=1;
-		dethread = g_thread_create((GThreadFunc)sexypsf_playloop,NULL,TRUE,NULL);
-	}
-}
-
-static void sexypsf_xmms_stop(InputPlayback * playback)
-{
-	if(!playing) return;
-
-	if(paused)
-		playback->output->pause(0);
-	paused = 0;
-
-	command=CMD_STOP;
-	g_thread_join(dethread);
-	playing = 0;
-
-	if(fnsave)
-	{
-		free(fnsave);
-		fnsave=NULL;
-	} 
-	sexypsf_freepsfinfo(PSFInfo);
-	PSFInfo=NULL;
-}
-
-static void sexypsf_xmms_pause(InputPlayback * playback, short p)
-{
-	if(!playing) return;
-	playback->output->pause(p);
-	paused = p;
-}
-
-static void sexypsf_xmms_seek(InputPlayback * data, int time)
-{
-	if(!playing) return;
-	command=CMD_SEEK|time;
-}
-
-static int sexypsf_xmms_gettime(InputPlayback *playback)
-{
-	if(nextsong)
-		return(-1);
-	if(!playing) return(0);
-		return playback->output->output_time();
-}
-
-static void sexypsf_xmms_getsonginfo(char *fn, char **title, int *length)
-{
-	PSFINFO *tmp;
-
-	if((tmp=sexypsf_getpsfinfo(fn))) {
-		*length = tmp->length;
-		*title = get_title_psf(fn);
-		sexypsf_freepsfinfo(tmp);
-	}
-}
-
-static TitleInput *get_tuple_psf(gchar *fn) {
-	TitleInput *tuple = NULL;
-	PSFINFO *tmp = sexypsf_getpsfinfo(fn);
-
-	if (tmp->length) {
-		tuple = bmp_title_input_new();
-		tuple->length = tmp->length;
-		tuple->performer = g_strdup(tmp->artist);
-		tuple->album_name = g_strdup(tmp->game);
-		tuple->track_name = g_strdup(tmp->title);
-		tuple->file_name = g_path_get_basename(fn);
-		tuple->file_path = g_path_get_dirname(fn);
-	}
-
-	return tuple;
-}	
-
-static gchar *get_title_psf(gchar *fn) {
-	gchar *title;
-	TitleInput *tinput = get_tuple_psf(fn);
-
-	if (tinput != NULL) {
-		title = xmms_get_titlestring(xmms_get_gentitle_format(),
-				tinput);
-		bmp_title_input_free(tinput);
-	}
-	else
-		title = g_path_get_basename(fn);
-	
-	return title;
-}
-
-gchar *sexypsf_fmts[] = { "psf", "minipsf", NULL };
-
-InputPlugin sexypsf_ip =
-{
-	NULL,
-	NULL,
-	"PSF Audio Plugin",
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	sexypsf_xmms_play,
-	sexypsf_xmms_stop,
-	sexypsf_xmms_pause,
-	sexypsf_xmms_seek,
-	NULL,
-	sexypsf_xmms_gettime,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	sexypsf_xmms_getsonginfo,
-	NULL,
-	NULL,
-	get_tuple_psf,
-	NULL,
-	NULL,
-	is_our_fd,
-	sexypsf_fmts,
-};
-
-InputPlugin *sexypsf_iplist[] = { &sexypsf_ip, NULL };
-
-DECLARE_PLUGIN(sexypsf, NULL, NULL, sexypsf_iplist, NULL, NULL, NULL, NULL);