changeset 1454:f57f3af1f722

merge
author Cristi Magherusan <majeru@atheme-project.org>
date Fri, 10 Aug 2007 18:17:01 +0300
parents 572db023e7a6 (current diff) 78de16e6989c (diff)
children 68c9906e0ac4
files
diffstat 18 files changed, 196 insertions(+), 187 deletions(-) [+]
line wrap: on
line diff
--- a/src/filewriter/filewriter.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/filewriter/filewriter.c	Fri Aug 10 18:17:01 2007 +0300
@@ -215,7 +215,7 @@
 
     if (filenamefromtags)
     {
-        gchar *utf8 = xmms_get_titlestring(xmms_get_gentitle_format(), tuple);
+        gchar *utf8 = tuple_formatter_process_string(tuple, cfg.gentitle_format);
 
         g_strchomp(utf8); //chop trailing ^J --yaz
 
@@ -226,7 +226,7 @@
     }
     if (filename == NULL)
     {
-        filename = g_strdup(tuple->file_name);
+        filename = g_strdup(tuple_get_string(tuple, "file-name"));
         if (!use_suffix)
             if ((temp = strrchr(filename, '.')) != NULL)
                 *temp = '\0';
@@ -238,8 +238,8 @@
     if (prependnumber)
     {
         gint number;
-        if (tuple && tuple->track_number)
-            number = tuple->track_number;
+        if (tuple && tuple_get_int(tuple, "track-number"))
+            number = tuple_get_int(tuple, "track-number");
         else
             number = pos + 1;
 
@@ -250,7 +250,7 @@
 
     gchar *directory;
     if (save_original)
-        directory = g_strdup(tuple->file_path);
+        directory = g_strdup(tuple_get_string(tuple, "file-path"));
     else
         directory = g_strdup(file_path);
 
@@ -665,4 +665,4 @@
 VFSFile *output_file = NULL;
 guint64 written = 0;
 guint64 offset = 0;
-TitleInput *tuple = NULL;
+Tuple *tuple = NULL;
--- a/src/filewriter/filewriter.h	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/filewriter/filewriter.h	Fri Aug 10 18:17:01 2007 +0300
@@ -29,6 +29,7 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <audacious/main.h>
 #include <audacious/plugin.h>
 #include <audacious/playlist.h>
 #include <audacious/configdb.h>
@@ -45,7 +46,7 @@
 extern VFSFile *output_file;
 extern guint64 written;
 extern guint64 offset;
-extern TitleInput *tuple;
+extern Tuple *tuple;
 
 typedef struct _FileWriter FileWriter;
 
--- a/src/filewriter/flac.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/filewriter/flac.c	Fri Aug 10 18:17:01 2007 +0300
@@ -107,14 +107,14 @@
 
         meta = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
 
-        INSERT_VORBIS_COMMENT(tuple->track_name, "title=%s");
-        INSERT_VORBIS_COMMENT(tuple->performer, "artist=%s");
-        INSERT_VORBIS_COMMENT(tuple->album_name, "album=%s");
-        INSERT_VORBIS_COMMENT(tuple->genre, "genre=%s");
-        INSERT_VORBIS_COMMENT(tuple->comment, "comment=%s");
-        INSERT_VORBIS_COMMENT(tuple->date, "date=%s");
-        INSERT_VORBIS_COMMENT(tuple->year, "year=%d");
-        INSERT_VORBIS_COMMENT(tuple->track_number, "tracknumber=%d");
+        INSERT_VORBIS_COMMENT(tuple_get_string(tuple, "title"), "title=%s");
+        INSERT_VORBIS_COMMENT(tuple_get_string(tuple, "artist"), "artist=%s");
+        INSERT_VORBIS_COMMENT(tuple_get_string(tuple, "album"), "album=%s");
+        INSERT_VORBIS_COMMENT(tuple_get_string(tuple, "genre"), "genre=%s");
+        INSERT_VORBIS_COMMENT(tuple_get_string(tuple, "comment"), "comment=%s");
+        INSERT_VORBIS_COMMENT(tuple_get_string(tuple, "date"), "date=%s");
+        INSERT_VORBIS_COMMENT(tuple_get_int(tuple, "year"), "year=%d");
+        INSERT_VORBIS_COMMENT(tuple_get_int(tuple, "track-number"), "tracknumber=%d");
 
         FLAC__stream_encoder_set_metadata(flac_encoder, &meta, 1);
     }
--- a/src/filewriter/mp3.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/filewriter/mp3.c	Fri Aug 10 18:17:01 2007 +0300
@@ -201,24 +201,24 @@
     if (tuple) {
         /* XXX write UTF-8 even though libmp3lame does id3v2.3. --yaz */
 #ifdef DEBUG
-        g_print("track_name = %s\n", tuple->track_name);
+        g_print("track_name = %s\n", tuple_get_string(tuple, "title"));
 #endif
-        lameid3.track_name = g_strdup(tuple->track_name);
+        lameid3.track_name = g_strdup(tuple_get_string(tuple, "title"));
         id3tag_set_title(gfp, lameid3.track_name);
 
-        lameid3.performer = g_strdup(tuple->performer);
+        lameid3.performer = g_strdup(tuple_get_string(tuple, "artist"));
         id3tag_set_artist(gfp, lameid3.performer);
 
-        lameid3.album_name = g_strdup(tuple->album_name);
+        lameid3.album_name = g_strdup(tuple_get_string(tuple, "album"));
         id3tag_set_album(gfp, lameid3.album_name);
 
-        lameid3.genre = g_strdup(tuple->genre);
+        lameid3.genre = g_strdup(tuple_get_string(tuple, "genre"));
         id3tag_set_genre(gfp, lameid3.genre);
 
-        lameid3.year = g_strdup_printf("%d", tuple->year);
+        lameid3.year = g_strdup_printf("%d", tuple_get_int(tuple, "year"));
         id3tag_set_year(gfp, lameid3.year);
 
-        lameid3.track_number = g_strdup_printf("%d", tuple->track_number);
+        lameid3.track_number = g_strdup_printf("%d", tuple_get_int(tuple, "track-number"));
         id3tag_set_track(gfp, lameid3.track_number);
 
         //        id3tag_write_v1(gfp);
--- a/src/filewriter/vorbis.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/filewriter/vorbis.c	Fri Aug 10 18:17:01 2007 +0300
@@ -84,33 +84,33 @@
 
     if (tuple)
     {
-        gchar *scratch;
+        const gchar *scratch;
 
-        if (tuple->track_name)
-            vorbis_comment_add_tag(&vc, "title", tuple->track_name);
-        if (tuple->performer)
-            vorbis_comment_add_tag(&vc, "artist", tuple->performer);
-        if (tuple->album_name)
-            vorbis_comment_add_tag(&vc, "album", tuple->album_name);
-        if (tuple->genre)
-            vorbis_comment_add_tag(&vc, "genre", tuple->genre);
-        if (tuple->date)
-            vorbis_comment_add_tag(&vc, "date", tuple->date);
-        if (tuple->comment)
-            vorbis_comment_add_tag(&vc, "comment", tuple->comment);
+        if ((scratch = tuple_get_string(tuple, "title")))
+            vorbis_comment_add_tag(&vc, "title", (gchar *) scratch);
+        if ((scratch = tuple_get_string(tuple, "artist")))
+            vorbis_comment_add_tag(&vc, "artist", (gchar *) scratch);
+        if ((scratch = tuple_get_string(tuple, "album")))
+            vorbis_comment_add_tag(&vc, "album", (gchar *) scratch);
+        if ((scratch = tuple_get_string(tuple, "genre")))
+            vorbis_comment_add_tag(&vc, "genre", (gchar *) scratch);
+        if ((scratch = tuple_get_string(tuple, "date")))
+            vorbis_comment_add_tag(&vc, "date", (gchar *) scratch);
+        if ((scratch = tuple_get_string(tuple, "comment")))
+            vorbis_comment_add_tag(&vc, "comment", (gchar *) scratch);
 
-        if (tuple->track_number)
+        if (tuple_get_int(tuple, "track-number"))
         {
-            scratch = g_strdup_printf("%d", tuple->track_number);
-            vorbis_comment_add_tag(&vc, "tracknumber", scratch);
-            g_free(scratch);
+            gchar *tmp = g_strdup_printf("%d", tuple_get_int(tuple, "track-number"));
+            vorbis_comment_add_tag(&vc, "tracknumber", tmp);
+            g_free(tmp);
         }
 
-        if (tuple->year)
+        if (tuple_get_int(tuple, "year"))
         {
-            scratch = g_strdup_printf("%d", tuple->year);
-            vorbis_comment_add_tag(&vc, "year", scratch);
-            g_free(scratch);
+            gchar *tmp = g_strdup_printf("%d", tuple_get_int(tuple, "year"));
+            vorbis_comment_add_tag(&vc, "year", tmp);
+            g_free(tmp);
         }
     }
 
--- a/src/scrobbler/fmt.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/scrobbler/fmt.c	Fri Aug 10 18:17:01 2007 +0300
@@ -7,7 +7,7 @@
 #include "fmt.h"
 #include <curl/curl.h>
 
-char *fmt_escape(char *str)
+char *fmt_escape(const char *str)
 {
 	return curl_escape(str, 0);
 }
--- a/src/scrobbler/fmt.h	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/scrobbler/fmt.h	Fri Aug 10 18:17:01 2007 +0300
@@ -4,7 +4,7 @@
 
 #include <time.h>
 
-char *fmt_escape(char *);
+char *fmt_escape(const char *);
 char *fmt_unescape(char *);
 char *fmt_timestr(time_t, int);
 char *fmt_vastr(char *, ...);
--- a/src/scrobbler/gerpok.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/scrobbler/gerpok.c	Fri Aug 10 18:17:01 2007 +0300
@@ -13,7 +13,7 @@
 #include "config.h"
 #include <glib.h>
 
-#include <audacious/titlestring.h>
+#include <audacious/tuple.h>
 #include <audacious/util.h>
 
 #define SCROBBLER_HS_URL "http://post.gerpok.com"
@@ -85,14 +85,15 @@
 	free(item);
 }
 
-static void q_put(TitleInput *tuple, int len)
+static void q_put(Tuple *tuple, int len)
 {
 	item_t *item;
+	const gchar *album;
 
 	item = malloc(sizeof(item_t));
 
-	item->artist = fmt_escape(tuple->performer);
-	item->title = fmt_escape(tuple->track_name);
+	item->artist = fmt_escape(tuple_get_string(tuple, "artist"));
+	item->title = fmt_escape(tuple_get_string(tuple, "title"));
 	item->utctime = fmt_escape(fmt_timestr(time(NULL), 1));
 	snprintf(item->len, sizeof(item->len), "%d", len);
 
@@ -105,10 +106,10 @@
 		item->mb = fmt_escape((char*)tuple->mb);
 #endif
 
-	if(tuple->album_name == NULL)
+	if((album = tuple_get_string(tuple, "album")))
 		item->album = fmt_escape("");
 	else
-		item->album = fmt_escape((char*)tuple->album_name);
+		item->album = fmt_escape((char*) album);
 
 	q_nitems++;
 
@@ -926,7 +927,7 @@
 	pdebug("scrobbler starting up", DEBUG);
 }
 
-void gerpok_sc_addentry(GMutex *mutex, TitleInput *tuple, int len)
+void gerpok_sc_addentry(GMutex *mutex, Tuple *tuple, int len)
 {
 	g_mutex_lock(mutex);
 	q_put(tuple, len);
--- a/src/scrobbler/gerpok.h	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/scrobbler/gerpok.h	Fri Aug 10 18:17:01 2007 +0300
@@ -1,11 +1,11 @@
 #ifndef G_NET_H
 #define G_NET_H 1
 
-#include "audacious/titlestring.h"
+#include <audacious/tuple.h>
 
 int gerpok_sc_idle(GMutex *);
 void gerpok_sc_init(char *, char *);
-void gerpok_sc_addentry(GMutex *, TitleInput *, int);
+void gerpok_sc_addentry(GMutex *, Tuple *, int);
 void gerpok_sc_cleaner(void);
 int gerpok_sc_catch_error(void);
 char *gerpok_sc_fetch_error(void);
--- a/src/scrobbler/plugin.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/scrobbler/plugin.c	Fri Aug 10 18:17:01 2007 +0300
@@ -215,7 +215,7 @@
 	int run = 1;
 
 	while (run) {
-		TitleInput *tuple;
+		Tuple *tuple;
 		GTimeVal sleeptime;
 
 		/* Error catching */
@@ -243,16 +243,16 @@
 			if (tuple == NULL)
 				continue;
 
-			if (ishttp(tuple->file_name))
+			if (ishttp(tuple_get_string(tuple, "file-name")))
 				continue;
 
-			if(tuple->performer != NULL && tuple->track_name != NULL)
+			if(tuple_get_string(tuple, "artist") != NULL && tuple_get_string(tuple, "title") != NULL)
 			{
 				pdebug(fmt_vastr(
 					"submitting artist: %s, title: %s",
-					tuple->performer, tuple->track_name), DEBUG);
-				sc_addentry(m_scrobbler, tuple, tuple->length / 1000);
-				gerpok_sc_addentry(m_scrobbler, tuple, tuple->length / 1000);
+					tuple_get_string(tuple, "artist"), tuple_get_string(tuple, "title")), DEBUG);
+				sc_addentry(m_scrobbler, tuple, tuple_get_int(tuple, "length") / 1000);
+				gerpok_sc_addentry(m_scrobbler, tuple, tuple_get_int(tuple, "length") / 1000);
 			}
 			else
 				pdebug("tuple does not contain an artist or a title, not submitting.", DEBUG);
--- a/src/scrobbler/scrobbler.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/scrobbler/scrobbler.c	Fri Aug 10 18:17:01 2007 +0300
@@ -12,7 +12,7 @@
 #include "settings.h"
 #include <glib.h>
 
-#include <audacious/titlestring.h>
+#include <audacious/tuple.h>
 #include <audacious/util.h>
 
 #define SCROBBLER_HS_URL "http://post.audioscrobbler.com"
@@ -124,17 +124,18 @@
 	free(item);
 }
 
-static item_t *q_put(TitleInput *tuple, int len)
+static item_t *q_put(Tuple *tuple, int len)
 {
 	item_t *item;
+	const gchar *album;
 
 	item = malloc(sizeof(item_t));
 
-	item->artist = fmt_escape(tuple->performer);
-	item->title = fmt_escape(tuple->track_name);
+	item->artist = fmt_escape(tuple_get_string(tuple, "artist"));
+	item->title = fmt_escape(tuple_get_string(tuple, "title"));
 	snprintf(item->utctime, sizeof(item->utctime), "%ld", time(NULL));
 	snprintf(item->len, sizeof(item->len), "%d", len);
-	snprintf(item->track, sizeof(item->track), "%d", tuple->track_number);
+	snprintf(item->track, sizeof(item->track), "%d", tuple_get_int(tuple, "track-number"));
 
 #ifdef NOTYET
 	if(tuple->mb == NULL)
@@ -145,10 +146,10 @@
 		item->mb = fmt_escape((char*)tuple->mb);
 #endif
 
-	if(tuple->album_name == NULL)
+	if((album = tuple_get_string(tuple, "album")))
 		item->album = fmt_escape("");
 	else
-		item->album = fmt_escape((char*)tuple->album_name);
+		item->album = fmt_escape((char*) album);
 
 	q_nitems++;
 
@@ -655,7 +656,7 @@
 	return i;
 }
 
-static int sc_submit_np(TitleInput *tuple)
+static int sc_submit_np(Tuple *tuple)
 {
 	CURL *curl;
 	/* struct HttpPost *post = NULL , *last = NULL; */
@@ -672,8 +673,10 @@
 	/*cfa(&post, &last, "debug", "failed");*/
 
 	entry = g_strdup_printf("s=%s&a=%s&t=%s&b=%s&l=%d&n=%d&m=", sc_session_id,
-		tuple->performer, tuple->track_name, tuple->album_name ? tuple->album_name : "",
-		tuple->length / 1000, tuple->track_number);
+		tuple_get_string(tuple, "artist"),
+		tuple_get_string(tuple, "title"),
+		tuple_get_string(tuple, "album") ? tuple_get_string(tuple, "album") : "",
+		tuple_get_int(tuple, "length") / 1000, tuple_get_int(tuple, "track-number"));
 
 	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (char *) entry);
 	memset(sc_curl_errbuf, 0, sizeof(sc_curl_errbuf));
@@ -878,15 +881,15 @@
 		ptr1 = ptr2 + 1;
 
 		{
-			TitleInput *tuple = bmp_title_input_new();
+			Tuple *tuple = tuple_new();
 
-			tuple->performer = g_strdup(xmms_urldecode_plain(artist));
-			tuple->track_name = g_strdup(xmms_urldecode_plain(title));
-			tuple->album_name = g_strdup(xmms_urldecode_plain(album));
+			tuple_associate_string(tuple, "artist", xmms_urldecode_plain(artist));
+			tuple_associate_string(tuple, "title", xmms_urldecode_plain(title));
+			tuple_associate_string(tuple, "album", xmms_urldecode_plain(album));
 
 			item = q_put(tuple, atoi(len));
 
-			bmp_title_input_free(tuple);
+			mowgli_object_unref(tuple);
 		}
 
 		pdebug(fmt_vastr("a[%d]=%s t[%d]=%s l[%d]=%s i[%d]=%s m[%d]=%s b[%d]=%s",
@@ -1018,7 +1021,7 @@
 	pdebug("scrobbler starting up", DEBUG);
 }
 
-void sc_addentry(GMutex *mutex, TitleInput *tuple, int len)
+void sc_addentry(GMutex *mutex, Tuple *tuple, int len)
 {
 	g_mutex_lock(mutex);
 
--- a/src/scrobbler/scrobbler.h	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/scrobbler/scrobbler.h	Fri Aug 10 18:17:01 2007 +0300
@@ -1,13 +1,13 @@
 #ifndef NET_H
 #define NET_H 1
 
-#include "audacious/titlestring.h"
+#include <audacious/tuple.h>
 
 #define SC_CURL_TIMEOUT 5
 
 int sc_idle(GMutex *);
 void sc_init(char *, char *);
-void sc_addentry(GMutex *, TitleInput *, int);
+void sc_addentry(GMutex *, Tuple *, int);
 void sc_cleaner(void);
 int sc_catch_error(void);
 char *sc_fetch_error(void);
--- a/src/statusicon/si_ui.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/statusicon/si_ui.c	Fri Aug 10 18:17:01 2007 +0300
@@ -25,7 +25,7 @@
 #include "gtktrayicon.h"
 #include "si.xpm"
 #include <audacious/playlist.h>
-#include <audacious/titlestring.h>
+#include <audacious/main.h>
 #include <audacious/ui_fileinfopopup.h>
 #include <audacious/util.h>
 #include <audacious/i18n.h>
@@ -144,13 +144,13 @@
 {
   if ( GPOINTER_TO_INT(g_object_get_data( G_OBJECT(evbox) , "timer_active" )) == 1 )
   {
-    TitleInput *tuple;
+    Tuple *tuple;
     Playlist *pl_active = playlist_get_active();
     gint pos = playlist_get_position(pl_active);
     GtkWidget *popup = g_object_get_data( G_OBJECT(evbox) , "popup" );
 
     tuple = playlist_get_tuple( pl_active , pos );
-    if ( ( tuple == NULL ) || ( tuple->length < 1 ) )
+    if ( ( tuple == NULL ) || ( tuple_get_int(tuple, "length") < 1 ) )
     {
       gchar *title = playlist_get_songtitle( pl_active , pos );
       audacious_fileinfopopup_show_from_title( popup , title );
--- a/src/timidity/src/xmms-timidity.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/timidity/src/xmms-timidity.c	Fri Aug 10 18:17:01 2007 +0300
@@ -23,7 +23,7 @@
 
 #include "audacious/util.h"
 #include "audacious/configdb.h"
-#include "audacious/titlestring.h"
+#include "audacious/main.h"
 #include "audacious/vfs.h"
 #include <glib.h>
 #include <gtk/gtk.h>
@@ -305,31 +305,16 @@
 }
 
 static gchar *xmmstimid_get_title(gchar *filename) {
-	TitleInput *input;
-	gchar *temp, *ext, *title, *path, *temp2;
+	Tuple *input;
+	gchar *title;
 
-	input = bmp_title_input_new();
+	input = tuple_new_from_filename(filename);
 
-	path = g_strdup(filename);
-	temp = g_strdup(filename);
-	ext = strrchr(temp, '.');
-	if (ext)
-		*ext = '\0';
-	temp2 = strrchr(path, '/');
-	if (temp2)
-		*temp2 = '\0';
+	title = tuple_formatter_process_string(input, cfg.gentitle_format);
+	if (title == NULL || *title == '\0')
+		title = g_strdup(tuple_get_string(input, "file-name"));
 
-	input->file_name = g_path_get_basename(filename);
-	input->file_ext = ext ? ext+1 : NULL;
-	input->file_path = g_strdup_printf("%s/", path);
-
-	title = xmms_get_titlestring(xmms_get_gentitle_format(), input);
-	if (title == NULL)
-		title = g_strdup(input->file_name);
-
-	g_free(temp);
-	g_free(path);
-	g_free(input);
+	mowgli_object_unref(input);
 
 	return title;
 }
--- a/src/tta/libtta.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/tta/libtta.c	Fri Aug 10 18:17:01 2007 +0300
@@ -43,7 +43,7 @@
 
 #include <audacious/util.h>
 #include <audacious/plugin.h>
-#include <audacious/titlestring.h>
+#include <audacious/main.h>
 #include <audacious/vfs.h>
 #include <audacious/output.h>
 #include <audacious/strings.h>
@@ -71,7 +71,7 @@
 static void get_song_info (char *filename, char **title, int *length);
 static void file_info (char *filename);
 static void about ();
-static TitleInput *get_song_tuple(char *filename);
+static Tuple *get_song_tuple(char *filename);
 static gchar *extname(const char *filename);
 
 static GThread *decode_thread = NULL;
@@ -175,25 +175,25 @@
 }
 
 static gchar *
-get_song_title(TitleInput *tuple)
+get_song_title(Tuple *tuple)
 {
-	return xmms_get_titlestring(xmms_get_gentitle_format(), tuple);
+	return tuple_formatter_process_string(tuple, cfg.gentitle_format);
 }
 
 static void
 get_song_info (char *filename, char **title, int *length)
 {
-	TitleInput *tuple;
+	Tuple *tuple;
 
 	*length = -1;
 	*title = NULL;
 
 	if ((tuple = get_song_tuple(filename)) != NULL) {
-    	    *length = tuple->length;
+    	    *length = tuple_get_int(tuple, "length");
     	    *title = get_song_title(tuple);
 	}
 
-	bmp_title_input_free(tuple);
+	mowgli_object_unref(tuple);
 }
 
 static void *
@@ -473,7 +473,7 @@
 	gchar *filename = playback->filename;
 	char *title = NULL;
 	int datasize, origsize, bitrate;
-	TitleInput *tuple = NULL;
+	Tuple *tuple = NULL;
 
 	////////////////////////////////////////
 	// open TTA file
@@ -503,7 +503,7 @@
 
 	tuple = get_song_tuple(filename);
 	title = get_song_title(tuple);
-	bmp_title_input_free(tuple);
+	mowgli_object_unref(tuple);
 
 	datasize = file_size(filename) - info.DATAPOS;
 	origsize = info.DATALENGTH * info.BSIZE * info.NCH;
@@ -563,10 +563,10 @@
     mseek(data, millisec);
 }
 
-static TitleInput *
+static Tuple *
 get_song_tuple(char *filename)
 {
-	TitleInput *tuple = NULL;
+	Tuple *tuple = NULL;
 	tta_info *ttainfo;
 	VFSFile *file;
 	gchar *realfn = NULL;
@@ -575,36 +575,32 @@
 
 	if((file = vfs_fopen(filename, "rb")) != NULL) {
 		if(open_tta_file(filename, ttainfo, 0) >= 0) {
-			tuple = bmp_title_input_new();
+			tuple = tuple_new_from_filename(filename);
 
-			realfn = g_filename_from_uri(filename, NULL, NULL);
-			tuple->file_name = g_path_get_basename(realfn ? realfn : filename);
-			tuple->file_path = g_path_get_dirname(realfn ? realfn : filename);
-			tuple->file_ext = extname(realfn ? realfn : filename);
-			tuple->length = ttainfo->LENGTH * 1000;
-			g_free(realfn); realfn = NULL;
+			tuple_associate_string(tuple, "codec", "True Audio (TTA)");
+			tuple_associate_string(tuple, "quality", "lossless");
 
 			if (ttainfo->ID3.id3has) {
-				if(ttainfo->ID3.artist && strlen((char *)ttainfo->ID3.artist))
-					tuple->performer = g_strdup((gchar *)ttainfo->ID3.artist);
+				if (ttainfo->ID3.artist)
+					tuple_associate_string(tuple, "artist", (gchar *) ttainfo->ID3.artist);
 
-				if(ttainfo->ID3.album && strlen((char *)ttainfo->ID3.album))
-					tuple->album_name = g_strdup((gchar *)ttainfo->ID3.album);
+				if (ttainfo->ID3.album)
+					tuple_associate_string(tuple, "album", (gchar *) ttainfo->ID3.album);
 
-				if(ttainfo->ID3.title && strlen((char *)ttainfo->ID3.title))
-					tuple->track_name = g_strdup((gchar *)ttainfo->ID3.title);
+				if (ttainfo->ID3.title)
+					tuple_associate_string(tuple, "title", (gchar *) ttainfo->ID3.title);
 
-				if(ttainfo->ID3.year && strlen((char *)ttainfo->ID3.year))
-					tuple->year = atoi((char *)ttainfo->ID3.year);
+				if (ttainfo->ID3.year)
+					tuple_associate_int(tuple, "year", atoi((char *)ttainfo->ID3.year));
 
-				if(ttainfo->ID3.track && strlen((char *)ttainfo->ID3.track))
-					tuple->track_number = atoi((char *)ttainfo->ID3.track);
+				if(ttainfo->ID3.track)
+					tuple_associate_int(tuple, "track-number", atoi((char *)ttainfo->ID3.track));
 
-				if(ttainfo->ID3.genre && strlen((char *)ttainfo->ID3.genre))
-					tuple->genre = g_strdup((gchar *)ttainfo->ID3.genre);
+				if(ttainfo->ID3.genre)
+					tuple_associate_string(tuple, "genre", (gchar *) ttainfo->ID3.genre);
 
-				if(ttainfo->ID3.comment && strlen((char *)ttainfo->ID3.comment))
-					tuple->comment = g_strdup((gchar *)ttainfo->ID3.comment);
+				if(ttainfo->ID3.comment)
+					tuple_associate_string(tuple, "comment", (gchar *) ttainfo->ID3.comment);
 			}
 			close_tta_file (ttainfo);
 		}
--- a/src/vtx/vtx.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/vtx/vtx.c	Fri Aug 10 18:17:01 2007 +0300
@@ -241,7 +241,7 @@
 
       g_free (buf);
 
-      bmp_title_input_free(ti);
+      mowgli_object_unref(ti);
 
       playback->playing = TRUE;
       play_thread = g_thread_self();
--- a/src/wavpack/libwavpack.cxx	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/wavpack/libwavpack.cxx	Fri Aug 10 18:17:01 2007 +0300
@@ -388,7 +388,7 @@
     tuple_associate_string(ti, "comment", tag.comment);
     tuple_associate_string(ti, "date", tag.year);
     tuple_associate_string(ti, "quality", WavpackPluginGetQualityString(ctx).c_str());
-    tuple_associate_string(ti, "codec", tag.year);
+    tuple_associate_string(ti, "codec", "WavPack");
 
     tuple_associate_int(ti, "track-number", atoi(tag.track));
     tuple_associate_int(ti, "year", atoi(tag.year));
--- a/src/xspf/xspf.c	Fri Aug 10 14:23:20 2007 +0300
+++ b/src/xspf/xspf.c	Fri Aug 10 18:17:01 2007 +0300
@@ -98,14 +98,14 @@
 static void add_file(xmlNode *track, const gchar *filename, gint pos)
 {
     xmlNode *nptr;
-    TitleInput *tuple;
+    Tuple *tuple;
     gchar *location = NULL;
     Playlist *playlist = playlist_get_active();
 
-    tuple = bmp_title_input_new();
+    tuple = tuple_new();
 
-    tuple->length = -1;
-    tuple->mtime = -1;          // mark as uninitialized.
+    tuple_associate_int(tuple, "length", -1);
+    tuple_associate_int(tuple, "mtime", -1);          // mark as uninitialized.
 
     // creator, album, title, duration, trackNum, annotation, image, 
     for(nptr = track->children; nptr != NULL; nptr = nptr->next) {
@@ -125,30 +125,38 @@
         }
         else if(nptr->type == XML_ELEMENT_NODE
                 && !xmlStrcmp(nptr->name, (xmlChar *)"title")) {
-            tuple->track_name = (gchar *)xmlNodeGetContent(nptr);
+            xmlChar *str = xmlNodeGetContent(nptr);
+	    tuple_associate_string(tuple, "title", (gchar *) str);
+            xmlFree(str);
         }
         else if(nptr->type == XML_ELEMENT_NODE
                 && !xmlStrcmp(nptr->name, (xmlChar *)"creator")) {
-            tuple->performer = (gchar *)xmlNodeGetContent(nptr);
+            xmlChar *str = xmlNodeGetContent(nptr);
+	    tuple_associate_string(tuple, "artist", (gchar *) str);
+            xmlFree(str);
         }
         else if(nptr->type == XML_ELEMENT_NODE
                 && !xmlStrcmp(nptr->name, (xmlChar *)"annotation")) {
-            tuple->comment = (gchar *)xmlNodeGetContent(nptr);
+            xmlChar *str = xmlNodeGetContent(nptr);
+	    tuple_associate_string(tuple, "comment", (gchar *) str);
+            xmlFree(str);
         }
         else if(nptr->type == XML_ELEMENT_NODE
                 && !xmlStrcmp(nptr->name, (xmlChar *)"album")) {
-            tuple->album_name = (gchar *)xmlNodeGetContent(nptr);
+            xmlChar *str = xmlNodeGetContent(nptr);
+	    tuple_associate_string(tuple, "album", (gchar *) str);
+            xmlFree(str);
         }
         else if(nptr->type == XML_ELEMENT_NODE
                 && !xmlStrcmp(nptr->name, (xmlChar *)"trackNum")) {
             xmlChar *str = xmlNodeGetContent(nptr);
-            tuple->track_number = atol((char *)str);
+            tuple_associate_int(tuple, "track-number", atol((char *)str));
             xmlFree(str);
         }
         else if(nptr->type == XML_ELEMENT_NODE
                 && !xmlStrcmp(nptr->name, (xmlChar *)"duration")) {
             xmlChar *str = xmlNodeGetContent(nptr);
-            tuple->length = atol((char *)str);
+            tuple_associate_int(tuple, "length", atol((char *)str));
             xmlFree(str);
         }
 
@@ -165,26 +173,32 @@
 
             if(!xmlStrcmp(rel, (xmlChar *)"year")) {
                 xmlChar *cont = xmlNodeGetContent(nptr);
-                tuple->year = atol((char *)cont);
+                tuple_associate_int(tuple, "year", atol((char *)cont));
                 xmlFree(cont);
                 continue;
             }
             else if(!xmlStrcmp(rel, (xmlChar *)"date")) {
-                tuple->date = (gchar *)xmlNodeGetContent(nptr);
+                xmlChar *cont = xmlNodeGetContent(nptr);
+                tuple_associate_string(tuple, "date", (gchar *) cont);
+                xmlFree(cont);
                 continue;
             }
             else if(!xmlStrcmp(rel, (xmlChar *)"genre")) {
-                tuple->genre = (gchar *)xmlNodeGetContent(nptr);
+                xmlChar *cont = xmlNodeGetContent(nptr);
+                tuple_associate_string(tuple, "genre", (gchar *) cont);
+                xmlFree(cont);
                 continue;
             }
             else if(!xmlStrcmp(rel, (xmlChar *)"formatter")) {
-                tuple->formatter = (gchar *)xmlNodeGetContent(nptr);
+                xmlChar *cont = xmlNodeGetContent(nptr);
+                tuple_associate_string(tuple, "formatter", (gchar *) cont);
+                xmlFree(cont);
                 continue;
             }
             else if(!xmlStrcmp(rel, (xmlChar *)"mtime")) {
                 xmlChar *str = NULL;
                 str = xmlNodeGetContent(nptr);
-                tuple->mtime = (time_t) atoll((char *)str);
+                tuple_associate_int(tuple, "mtime", atoll((char *)str));
                 xmlFree(str);
                 continue;
             }
@@ -196,13 +210,21 @@
 
     if(location) {
         gchar *uri = NULL;
-        tuple->file_name = g_path_get_basename(location);
-        tuple->file_path = g_path_get_dirname(location);
+        gchar *scratch;
+
+        scratch = g_path_get_basename(location);
+        tuple_associate_string(tuple, "file-name", scratch);
+        g_free(scratch);
+
+        scratch = g_path_get_dirname(location);
+        tuple_associate_string(tuple, "file-path", scratch);
+        g_free(scratch);
+
 #ifdef DEBUG
-        printf("xspf: tuple->file_name = %s\n", tuple->file_name);
-        printf("xspf: tuple->file_path = %s\n", tuple->file_path);
+        printf("xspf: tuple->file_name = %s\n", tuple_get_string(tuple, "file-name"));
+        printf("xspf: tuple->file_path = %s\n", tuple_get_string(tuple, "file-path"));
 #endif
-        tuple->file_ext = g_strdup(strrchr(location, '.'));
+        tuple_associate_string(tuple, "file-ext", strrchr(location, '.'));
         // add file to playlist
         uri = g_filename_to_uri(location, NULL, NULL);
         // uri would be NULL if location is already uri. --yaz
@@ -467,52 +489,53 @@
 
         /* do we have a tuple? */
         if(entry->tuple != NULL) {
+            const gchar *scratch;
 
-            if(entry->tuple->track_name != NULL &&
-               g_utf8_validate(entry->tuple->track_name, -1, NULL)) {
+            if((scratch = tuple_get_string(entry->tuple, "track-name")) != NULL &&
+               g_utf8_validate(scratch, -1, NULL)) {
                 tmp = xmlNewNode(NULL, (xmlChar *)"title");
-                xmlAddChild(tmp, xmlNewText((xmlChar *)entry->tuple->track_name));
+                xmlAddChild(tmp, xmlNewText((xmlChar *) scratch));
                 xmlAddChild(track, tmp);
             }
 
-            if(entry->tuple->performer != NULL &&
-               g_utf8_validate(entry->tuple->performer, -1, NULL)) {
+            if((scratch = tuple_get_string(entry->tuple, "artist")) != NULL &&
+               g_utf8_validate(scratch, -1, NULL)) {
                 tmp = xmlNewNode(NULL, (xmlChar *)"creator");
-                xmlAddChild(tmp, xmlNewText((xmlChar *)entry->tuple->performer));
+                xmlAddChild(tmp, xmlNewText((xmlChar *) scratch));
                 xmlAddChild(track, tmp);
             }
 
-            if(entry->tuple->comment != NULL &&
-               g_utf8_validate(entry->tuple->comment, -1, NULL)) {
+            if((scratch = tuple_get_string(entry->tuple, "comment")) != NULL &&
+               g_utf8_validate(scratch, -1, NULL)) {
                 tmp = xmlNewNode(NULL, (xmlChar *)"annotation");
-                xmlAddChild(tmp, xmlNewText((xmlChar *)entry->tuple->comment));
+                xmlAddChild(tmp, xmlNewText((xmlChar *) scratch));
                 xmlAddChild(track, tmp);
             }
 
-            if(entry->tuple->album_name != NULL &&
-               g_utf8_validate(entry->tuple->album_name, -1, NULL)) {
+            if((scratch = tuple_get_string(entry->tuple, "album")) != NULL &&
+               g_utf8_validate(scratch, -1, NULL)) {
                 tmp = xmlNewNode(NULL, (xmlChar *)"album");
-                xmlAddChild(tmp, xmlNewText((xmlChar *)entry->tuple->album_name));
+                xmlAddChild(tmp, xmlNewText((xmlChar *) scratch));
                 xmlAddChild(track, tmp);
             }
 
-            if(entry->tuple->track_number != 0) {
+            if(tuple_get_int(entry->tuple, "track-number") != 0) {
                 gchar *str;
                 str = g_malloc(TMP_BUF_LEN);
                 tmp = xmlNewNode(NULL, (xmlChar *)"trackNum");
-                sprintf(str, "%d", entry->tuple->track_number);
+                sprintf(str, "%d", tuple_get_int(entry->tuple, "track-number"));
                 xmlAddChild(tmp, xmlNewText((xmlChar *)str));
                 g_free(str);
                 str = NULL;
                 xmlAddChild(track, tmp);
             }
 
-            if(entry->tuple->length > 0) {
+            if(tuple_get_int(entry->tuple, "length") > 0) {
                 gchar *str;
                 str = g_malloc(TMP_BUF_LEN);
                 tmp = xmlNewNode(NULL, (xmlChar *)"duration");
-                sprintf(str, "%d", entry->tuple->length);
-                xmlAddChild(tmp, xmlNewText((xmlChar *)str));
+                sprintf(str, "%d", tuple_get_int(entry->tuple, "length"));
+                xmlAddChild(tmp, xmlNewText((xmlChar *) str));
                 g_free(str);
                 str = NULL;
                 xmlAddChild(track, tmp);
@@ -524,39 +547,39 @@
             // year, date, genre, formatter, mtime
             //
 
-            if(entry->tuple->year != 0) {
+            if(tuple_get_int(entry->tuple, "year") != 0) {
                 gchar *str;
                 str = g_malloc(TMP_BUF_LEN);
                 tmp = xmlNewNode(NULL, (xmlChar *)"meta");
                 xmlSetProp(tmp, (xmlChar *)"rel", (xmlChar *)"year");
-                sprintf(str, "%d", entry->tuple->year);
+                sprintf(str, "%d", tuple_get_int(entry->tuple, "year"));
                 xmlAddChild(tmp, xmlNewText((xmlChar *)str));
                 xmlAddChild(track, tmp);
                 g_free(str);
                 str = NULL;
             }
 
-            if(entry->tuple->date != NULL &&
-               g_utf8_validate(entry->tuple->date, -1, NULL)) {
+            if((scratch = tuple_get_string(entry->tuple, "date")) != NULL &&
+               g_utf8_validate(scratch, -1, NULL)) {
                 tmp = xmlNewNode(NULL, (xmlChar *)"meta");
                 xmlSetProp(tmp, (xmlChar *)"rel", (xmlChar *)"date");
-                xmlAddChild(tmp, xmlNewText((xmlChar *)entry->tuple->date));
+                xmlAddChild(tmp, xmlNewText((xmlChar *) scratch));
                 xmlAddChild(track, tmp);
             }
 
-            if(entry->tuple->genre != NULL &&
-               g_utf8_validate(entry->tuple->genre, -1, NULL)) {
+            if((scratch = tuple_get_string(entry->tuple, "genre")) != NULL &&
+               g_utf8_validate(scratch, -1, NULL)) {
                 tmp = xmlNewNode(NULL, (xmlChar *)"meta");
                 xmlSetProp(tmp, (xmlChar *)"rel", (xmlChar *)"genre");
-                xmlAddChild(tmp, xmlNewText((xmlChar *)entry->tuple->genre));
+                xmlAddChild(tmp, xmlNewText((xmlChar *) scratch));
                 xmlAddChild(track, tmp);
             }
 
-            if(entry->tuple->formatter != NULL &&
-               g_utf8_validate(entry->tuple->formatter, -1, NULL)) {
+            if((scratch = tuple_get_string(entry->tuple, "formatter")) != NULL &&
+               g_utf8_validate(scratch, -1, NULL)) {
                 tmp = xmlNewNode(NULL, (xmlChar *)"meta");
                 xmlSetProp(tmp, (xmlChar *)"rel", (xmlChar *)"formatter");
-                xmlAddChild(tmp, xmlNewText((xmlChar *)entry->tuple->formatter));
+                xmlAddChild(tmp, xmlNewText((xmlChar *) scratch));
                 xmlAddChild(track, tmp);
             }
 
@@ -565,7 +588,7 @@
                 gchar *str = g_malloc(TMP_BUF_LEN);
                 tmp = xmlNewNode(NULL, (xmlChar *)"meta");
                 xmlSetProp(tmp, (xmlChar *)"rel", (xmlChar *)"mtime");
-                sprintf(str, "%ld", (long)entry->tuple->mtime);
+                sprintf(str, "%ld", (long) tuple_get_int(entry->tuple, "mtime"));
 
                 xmlAddChild(tmp, xmlNewText((xmlChar *)str));
                 xmlAddChild(track, tmp);