Multi-track, improved
Olivier Galibert <[email protected]>
| Newsgroups | gmane.comp.multimedia.xmms.devel |
|---|---|
| Message-ID | <[email protected]> |
I had forgotten a feature I needed, now the plugin can give xmms the track numbers to use. Useful when the tracks are numbered f.i. 8, 47, 48, 28, 10... in that order, and you sometimes want to filter out some of them too. OG. _______________________________________________ xmms-devel mailing list [email protected] http://lists.xmms.org/mailman/listinfo/xmms-devel
multitrack2.txt
(text/plain, 11.6 KB)
Index: xmms/input.c
===================================================================
RCS file: /cvs/xmms/xmms/input.c,v
retrieving revision 1.18
diff -u -r1.18 input.c
--- xmms/input.c 13 Jul 2003 22:16:39 -0000 1.18
+++ xmms/input.c 18 Nov 2003 23:42:22 -0000
@@ -224,24 +224,33 @@
pthread_mutex_unlock(&vis_mutex);
}
-gboolean input_check_file(gchar * filename)
+guint input_check_file(gchar * filename, int **tracknb)
{
GList *node;
InputPlugin *ip;
+ *tracknb = 0;
+
node = get_input_list();
while (node)
{
ip = (InputPlugin *) node->data;
if (ip && !g_list_find(disabled_iplugins, ip) &&
ip->is_our_file(filename))
- return TRUE;
+ {
+ /* Single-track plugin */
+ if (ip->play_file)
+ return 1;
+ /* Multi-track */
+ else
+ return ip->count_tracks(filename, tracknb);
+ }
node = node->next;
}
- return FALSE;
+ return 0;
}
-void input_play(char *filename)
+void input_play(char *filename, guint track)
{
GList *node;
InputPlugin *ip;
@@ -263,7 +272,10 @@
{
set_current_input_plugin(ip);
ip->output = get_current_output_plugin();
- ip->play_file(filename);
+ if (ip->play_file)
+ ip->play_file(filename);
+ else
+ ip->play_track(filename, track);
ip_data->playing = TRUE;
return;
@@ -339,7 +351,7 @@
get_current_input_plugin()->set_eq(on, preamp, bands);
}
-void input_get_song_info(gchar * filename, gchar ** title, gint * length)
+void input_get_song_info(gchar * filename, guint track, gchar ** title, gint * length)
{
GList *node;
InputPlugin *ip = NULL;
@@ -353,8 +365,13 @@
break;
node = node->next;
}
- if (ip && node && ip->get_song_info)
- ip->get_song_info(filename, title, length);
+ if (ip && node && (ip->play_file ? ip->get_song_info != 0 : ip->get_track_info != 0))
+ {
+ if (ip->play_file)
+ ip->get_song_info(filename, title, length);
+ else
+ ip->get_track_info(filename, track, title, length);
+ }
else
{
gchar *temp, *ext;
Index: xmms/input.h
===================================================================
RCS file: /cvs/xmms/xmms/input.h,v
retrieving revision 1.4
diff -u -r1.4 input.h
--- xmms/input.h 16 Feb 2000 21:05:57 -0000 1.4
+++ xmms/input.h 18 Nov 2003 23:42:22 -0000
@@ -31,14 +31,14 @@
InputPlugin *get_current_input_plugin(void);
void set_current_input_plugin(InputPlugin * ip);
InputVisType input_get_vis_type();
-gboolean input_check_file(gchar * filename);
-void input_play(char *filename);
+guint input_check_file(gchar * filename, int **tracknb);
+void input_play(char *filename, guint track);
void input_stop(void);
void input_pause(void);
int input_get_time(void);
void input_set_eq(int on, float preamp, float *bands);
void input_seek(int time);
-void input_get_song_info(gchar * filename, gchar ** title, gint * length);
+void input_get_song_info(gchar * filename, guint track, gchar ** title, gint * length);
gboolean get_input_playing(void);
gboolean get_input_paused(void);
guchar *input_get_vis(gint time);
Index: xmms/playlist.c
===================================================================
RCS file: /cvs/xmms/xmms/playlist.c,v
retrieving revision 1.78
diff -u -r1.78 playlist.c
--- xmms/playlist.c 6 Nov 2003 23:36:35 -0000 1.78
+++ xmms/playlist.c 18 Nov 2003 23:42:22 -0000
@@ -254,12 +254,13 @@
}
}
-static void __playlist_ins_with_info(char *filename, long pos, char* title, int len)
+static void __playlist_ins_with_info(char *filename, long pos, guint track, char* title, int len)
{
PlaylistEntry *entry;
entry = g_malloc0(sizeof (PlaylistEntry));
entry->filename = g_strdup(filename);
+ entry->track = track;
if (title)
entry->title = g_strdup(title);
entry->length = len;
@@ -271,9 +272,11 @@
playlist_get_info_scan_active = TRUE;
}
-static void __playlist_ins(char * filename, long pos)
+static void __playlist_ins(char * filename, long pos, int *tracknb, guint count)
{
- __playlist_ins_with_info(filename, pos, NULL, -1);
+ guint i;
+ for (i=0; i<count; i++)
+ __playlist_ins_with_info(filename, pos, tracknb ? tracknb[i] : i, NULL, -1);
}
static gboolean is_playlist_name(char *pathname)
@@ -288,13 +291,17 @@
}
-void playlist_ins(gchar * filename, glong pos)
+guint playlist_ins(gchar * filename, glong pos)
{
gboolean ispl = FALSE;
+ guint count = 0;
+ int *tracknb = 0;
ispl = is_playlist_name (filename);
+ if (!ispl)
+ count = input_check_file(filename, &tracknb);
- if (!ispl && !input_check_file(filename))
+ if (!ispl && !count)
{
/*
* Some files (typically produced by some cgi-scripts)
@@ -333,14 +340,16 @@
}
if (ispl)
- playlist_load_ins(filename, pos);
+ return playlist_load_ins(filename, pos);
else
- if (input_check_file(filename))
+ if (count)
{
- __playlist_ins(filename, pos);
+ __playlist_ins(filename, pos, tracknb, count);
playlist_generate_shuffle_list();
playlistwin_update_list();
- }
+ return count;
+ } else
+ return 0;
}
static guint devino_hash(gconstpointer key)
@@ -361,6 +370,13 @@
return TRUE;
}
+struct __playlist_file_entry
+{
+ char *filename;
+ guint track_count;
+ int *tracknb;
+};
+
static GList* playlist_dir_find_files(char *path, gboolean background, GHashTable *htab)
{
DIR *dir;
@@ -399,8 +415,11 @@
node = ilist;
while (node)
{
- char *name = g_strconcat(temp, node->data, NULL);
- list = g_list_prepend(list, name);
+ struct __playlist_file_entry *e = g_malloc (sizeof (*e));
+ e->filename = g_strconcat(temp, node->data, NULL);
+ e->track_count = 1;
+ e->tracknb = 0;
+ list = g_list_prepend(list, e);
g_free(node->data);
node = g_list_next(node);
}
@@ -438,10 +457,28 @@
g_free(filename);
list = g_list_concat(list, sub);
}
- else if (input_check_file(filename))
- list = g_list_prepend(list, filename);
else
- g_free(filename);
+ {
+ int *tracknb = 0;
+ guint track_count = input_check_file(filename, &tracknb);
+ if (track_count)
+ {
+ struct __playlist_file_entry *e = g_malloc (sizeof (*e));
+ e->filename = filename;
+ e->track_count = track_count;
+ if (tracknb)
+ {
+ e->tracknb = g_malloc (sizeof(int)*track_count);
+ memcpy (e->tracknb, tracknb, sizeof(int)*track_count);
+ }
+ else
+ e->tracknb = 0;
+
+ list = g_list_prepend(list, e);
+ }
+ else
+ g_free(filename);
+ }
while (background && gtk_events_pending())
gtk_main_iteration();
@@ -468,11 +505,15 @@
node = list;
while (node)
{
- __playlist_ins(node->data, pos);
- entries++;
+ struct __playlist_file_entry *e = node->data;
+ __playlist_ins(e->filename, pos, e->tracknb, e->track_count);
+ entries += e->track_count;
if (pos >= 0)
- pos++;
- g_free(node->data);
+ pos += e->track_count;
+ if (e->tracknb)
+ g_free (e->tracknb);
+ g_free(e->filename);
+ g_free(e);
node = g_list_next(node);
}
g_list_free(list);
@@ -510,10 +551,7 @@
if (is_playlist_name (string))
i = playlist_load_ins(string, pos);
else
- {
- playlist_ins(string, pos);
- i = 1;
- }
+ i = playlist_ins(string, pos);
}
entries += i;
if (pos >= 0)
@@ -531,6 +569,7 @@
void playlist_play(void)
{
char *filename = NULL;
+ guint track = 0;
if (get_playlist_length() == 0)
return;
@@ -580,13 +619,14 @@
playlist_position = playlist->data;
}
filename = playlist_position->filename;
+ track = playlist_position->track;
}
PL_UNLOCK();
if (!filename)
return;
- input_play(filename);
+ input_play(filename, track);
if (input_get_time() != -1)
{
@@ -1041,7 +1081,10 @@
fprintf(file, "#EXTINF:%d,%s\n",
seconds, entry->title);
}
- fprintf(file, "%s\n", entry->filename);
+ if (entry->track)
+ fprintf(file, "%d %s\n", entry->track, entry->filename);
+ else
+ fprintf(file, "%s\n", entry->filename);
}
node = g_list_next(node);
}
@@ -1056,10 +1099,21 @@
static void playlist_load_ins_file(char *filename, char *playlist_name, long pos, char *title, int len)
{
- char *temp, *path;
+ char *temp, *path, *p;
+ guint track = 0;
filename = g_strstrip(filename);
+ p = filename;
+ while (*p && (*p >= '0' && *p <= '9'))
+ p++;
+
+ if(*p == ' ' && p != filename)
+ {
+ track = strtol(filename, 0, 10);
+ filename = p + 1;
+ }
+
if (cfg.use_backslash_as_dir_delimiter)
{
while ((temp = strchr(filename, '\\')) != NULL)
@@ -1074,16 +1128,16 @@
*temp = '\0';
else
{
- __playlist_ins_with_info(filename, pos, title, len);
+ __playlist_ins_with_info(filename, pos, track, title, len);
return;
}
temp = g_strdup_printf("%s/%s", path, filename);
- __playlist_ins_with_info(temp, pos, title, len);
+ __playlist_ins_with_info(temp, pos, track, title, len);
g_free(temp);
g_free(path);
}
else
- __playlist_ins_with_info(filename, pos, title, len);
+ __playlist_ins_with_info(filename, pos, track, title, len);
}
static void parse_extm3u_info(char *info, char **title, int *length)
@@ -1739,14 +1793,16 @@
*/
char *temp_filename, *temp_title;
int temp_length;
+ guint temp_track;
temp_filename = g_strdup(entry->filename);
+ temp_track = entry->track;
temp_title = NULL;
temp_length = -1;
/* We don't want to lock the playlist while reading info */
PL_UNLOCK();
- input_get_song_info(temp_filename, &temp_title, &temp_length);
+ input_get_song_info(temp_filename, temp_track, &temp_title, &temp_length);
PL_LOCK();
g_free(temp_filename);
Index: xmms/playlist.h
===================================================================
RCS file: /cvs/xmms/xmms/playlist.h,v
retrieving revision 1.19
diff -u -r1.19 playlist.h
--- xmms/playlist.h 8 Jun 2003 21:52:02 -0000 1.19
+++ xmms/playlist.h 18 Nov 2003 23:42:23 -0000
@@ -23,6 +23,7 @@
typedef struct
{
gchar *filename;
+ guint track;
gchar *title;
gint length;
gboolean selected;
@@ -33,7 +34,7 @@
void playlist_delete(gboolean crop);
/* void playlist_add(gchar * filename); */
#define playlist_add(filename) playlist_ins(filename, -1)
-void playlist_ins(gchar * filename, glong pos);
+guint playlist_ins(gchar * filename, glong pos);
/* void playlist_add_dir(gchar * dir); */
#define playlist_add_dir(directory) playlist_ins_dir(directory, -1, TRUE)
guint playlist_ins_dir(char *dir, long pos, gboolean background);
Index: xmms/plugin.h
===================================================================
RCS file: /cvs/xmms/xmms/plugin.h,v
retrieving revision 1.6
diff -u -r1.6 plugin.h
--- xmms/plugin.h 5 Jul 2001 22:35:01 -0000 1.6
+++ xmms/plugin.h 18 Nov 2003 23:42:23 -0000
@@ -92,7 +92,7 @@
int (*is_our_file) (char *filename); /* Return 1 if the plugin can handle the file */
GList *(*scan_dir) (char *dirname); /* Look in Input/cdaudio/cdaudio.c to see how */
/* to use this */
- void (*play_file) (char *filename); /* Guess what... */
+ void (*play_file) (char *filename); /* Play file for single-track per file plugins only */
void (*stop) (void); /* Tricky one */
void (*pause) (short paused); /* Pause or unpause */
void (*seek) (int time); /* Seek to the specified time */
@@ -112,6 +112,13 @@
void (*get_song_info) (char *filename, char **title, int *length); /* Function to grab the title string */
void (*file_info_box) (char *filename); /* Bring up an info window for the filename passed in */
OutputPlugin *output; /* Handle to the current output plugin. Filled in by xmms */
+
+ /* Starting from here the fields are for multi-track plugins */
+
+ int (*count_tracks) (char *filename, int **tracknb); /* Return the number of tracks available in a given file
+ and optionally their numbers */
+ void (*play_track) (char *filename, int track); /* Play a given track from a file */
+ void (*get_track_info) (char *filename, int track, char **title, int *length); /* Function to grab the title string */
}
InputPlugin;