General discussion

Here you can discuss everything related to MOC which doesn't fit other subforum.

Shuffle by albums in mocp

Hi,

i use mocp for a long time, but i missed shuffle by albums feature. This patch adds [ALBUM] item (next to [SHUFFLE], [NEXT], [REPEAT], etc...) toggled by CTRL + a key. When the [ALBUM] is activated, key for 'play next/prev' is jumping on the albums instead of jumping on the tracks. Now when the [SHUFFLE] and [ALBUM] is activated and we add files to playlist, playlist will be shuffled by albums.

Patch is adhcoc solution and it is not optimized, but relatively works :-). My big metal collection process 2 minutes, but then plays ;-).

In troubles I recomended to delete mocp cache.

From: Vaclav Svirga
Date: Tue Jul 3 08:59:32 CEST 2012
Subject: Add support for playback of albums

---
diff -ru moc/audio.c moc/audio.c
--- moc/audio.c 2012-07-03 08:51:40.453897385 +0200
+++ moc/audio.c 2012-07-03 08:48:15.125323921 +0200
@@ -297,6 +297,7 @@
static void go_to_another_file ()
{
int shuffle = options_get_int ("Shuffle");
+ int album = options_get_int ("Album");
int go_next = (play_next || options_get_int("AutoNext"));
int curr_playing_curr_pos;
/* XXX: Shouldn't play_next be protected by mutex? */
@@ -334,8 +335,13 @@

if (plist_count(&playlist)
&& !plist_count(&shuffled_plist)) {
- plist_cat (&shuffled_plist, &playlist);
- plist_shuffle (&shuffled_plist);
+ if(album)
+ plist_shuffle_album (&playlist, &shuffled_plist);
+ else
+ {
+ plist_cat (&shuffled_plist, &playlist);
+ plist_shuffle (&shuffled_plist);
+ }

if (curr_playing_fname)
plist_swap_first_fname (&shuffled_plist,
@@ -365,8 +371,12 @@
started_playing_in_queue = 0;
}
else
- curr_playing = plist_prev (curr_plist,
- curr_playing_curr_pos);
+ {
+ if(play_prev && album)
+ curr_playing = plist_prev_album(curr_plist, curr_playing_curr_pos);
+ else
+ curr_playing = plist_prev(curr_plist, curr_playing_curr_pos);
+ }

if (curr_playing == -1) {
if (options_get_int("Repeat"))
@@ -385,14 +395,23 @@
started_playing_in_queue = 0;
}
else
- curr_playing = plist_next (curr_plist,
- curr_playing_curr_pos);
+ {
+ if(play_next && album)
+ curr_playing = plist_next_album(curr_plist, curr_playing_curr_pos);
+ else
+ curr_playing = plist_next(curr_plist, curr_playing_curr_pos);
+ }

if (curr_playing == -1 && options_get_int("Repeat")) {
if (shuffle) {
plist_clear (&shuffled_plist);
- plist_cat (&shuffled_plist, &playlist);
- plist_shuffle (&shuffled_plist);
+ if(album)
+ plist_shuffle_album (&playlist, &shuffled_plist);
+ else
+ {
+ plist_cat (&shuffled_plist, &playlist);
+ plist_shuffle (&shuffled_plist);
+ }
}
curr_playing = plist_next (curr_plist, -1);
logit ("Going back to the first item.");
@@ -562,8 +581,13 @@
}
else if (options_get_int("Shuffle")) {
plist_clear (&shuffled_plist);
- plist_cat (&shuffled_plist, &playlist);
- plist_shuffle (&shuffled_plist);
+ if(options_get_int("Album"))
+ plist_shuffle_album(&playlist, &shuffled_plist);
+ else
+ {
+ plist_cat (&shuffled_plist, &playlist);
+ plist_shuffle(&shuffled_plist);
+ }
plist_swap_first_fname (&shuffled_plist, fname);

curr_plist = &shuffled_plist;
diff -ru moc/interface.c moc/interface.c
--- moc/interface.c 2012-07-03 08:51:40.441897824 +0200
+++ moc/interface.c 2012-07-03 08:49:18.383036093 +0200
@@ -3110,6 +3110,9 @@
case KEY_CMD_TOGGLE_SHUFFLE:
toggle_option ("Shuffle");
break;
+ case KEY_CMD_TOGGLE_ALBUM:
+ toggle_option ("Album");
+ break;
case KEY_CMD_TOGGLE_REPEAT:
toggle_option ("Repeat");
break;
@@ -4087,6 +4090,8 @@
tok = "AutoNext";
else if(!strncmp (tok, "repeat", 7) || !strncmp (tok, "r", 2))
tok = "Repeat";
+ else if(!strncmp (tok, "album", 6) || !strncmp (tok, "a", 2))
+ tok = "Album";
else {
fprintf (stderr, "Unknown option '%s'\n", tok);
break;
diff -ru moc/interface_elements.c moc/interface_elements.c
--- moc/interface_elements.c 2012-07-03 08:51:40.441897824 +0200
+++ moc/interface_elements.c 2012-07-03 03:13:34.076264867 +0200
@@ -238,6 +238,7 @@
int state_shuffle;
int state_repeat;
int state_next;
+ int state_album;
int state_net;

int bitrate; /* in kbps */
@@ -2694,6 +2695,7 @@
w->state_shuffle = 0;
w->state_repeat = 0;
w->state_next = 0;
+ w->state_album = 0;
w->state_play = STATE_STOP;
w->state_net = 0;

@@ -3101,6 +3103,7 @@
info_win_draw_switch (w, 53, 2, "SHUFFLE", w->state_shuffle);
info_win_draw_switch (w, 63, 2, "REPEAT", w->state_repeat);
info_win_draw_switch (w, 72, 2, "NEXT", w->state_next);
+ info_win_draw_switch (w, 79, 2, "ALBUM", w->state_album);
}

static void info_win_make_entry (struct info_win *w, const enum entry_type type)
@@ -3309,6 +3312,8 @@
w->state_next = value;
else if (!strcasecmp(name, "Net"))
w->state_net = value;
+ else if (!strcasecmp(name, "Album"))
+ w->state_album = value;
else
abort ();

diff -ru moc/keys.c moc/keys.c
--- moc/keys.c 2012-07-03 08:51:40.461897095 +0200
+++ moc/keys.c 2012-07-03 08:57:02.690266980 +0200
@@ -178,6 +178,14 @@
1
},
{
+ KEY_CMD_TOGGLE_ALBUM,
+ "toggle_album",
+ "Toggle Album",
+ CON_MENU,
+ { CTRL('a'), -1 },
+ 1
+ },
+ {
KEY_CMD_TOGGLE_REPEAT,
"toggle_repeat",
"Toggle Repeat",
diff -ru moc/keys.h moc/keys.h
--- moc/keys.h 2012-07-03 08:51:40.445897675 +0200
+++ moc/keys.h 2012-07-03 03:25:04.019287993 +0200
@@ -53,6 +53,7 @@
KEY_CMD_GO_DIR,
KEY_CMD_GO_DIR_UP,
KEY_CMD_TOGGLE_SHUFFLE,
+ KEY_CMD_TOGGLE_ALBUM,
KEY_CMD_NEXT_SEARCH,
KEY_CMD_CANCEL,
KEY_CMD_GO_URL,
diff -ru moc/main.c moc/main.c
--- moc/main.c 2012-07-03 08:51:40.449897534 +0200
+++ moc/main.c 2012-07-03 07:41:37.338294818 +0200
@@ -319,9 +319,9 @@
"-e --recursively Alias for -a.\n"
"-k --seek N Seek by N seconds (can be negative).\n"
"-j --jump N{%%,s} Jump to some position of the current track.\n"
-"-o --on Turn on a control (shuffle, autonext, repeat).\n"
-"-u --off Turn off a control (shuffle, autonext, repeat).\n"
-"-t --toggle Toggle a control (shuffle, autonext, repeat).\n"
+"-o --on Turn on a control (shuffle, autonext, repeat, album).\n"
+"-u --off Turn off a control (shuffle, autonext, repeat, album).\n"
+"-t --toggle Toggle a control (shuffle, autonext, repeat, album).\n"
, prg_name);
}

diff -ru moc/options.c moc/options.c
--- moc/options.c 2012-07-03 08:51:40.449897534 +0200
+++ moc/options.c 2012-07-03 03:17:54.122851022 +0200
@@ -560,6 +560,7 @@
add_bool ("ShowStreamErrors", false);
add_bool ("Repeat", false);
add_bool ("Shuffle", false);
+ add_bool ("Album", false);
add_bool ("AutoNext", true);
add_symb ("Sort", "FileName", CHECK_SYMBOL(1), "FileName");
add_str ("FormatString",
diff -ru moc/playlist.c moc/playlist.c
--- moc/playlist.c 2012-07-03 08:51:40.461897095 +0200
+++ moc/playlist.c 2012-07-03 08:51:08.039069897 +0200
@@ -285,6 +285,33 @@
return i < plist->num ? i : -1;
}

+int plist_next_album (struct plist *plist, int num)
+{
+ char calbum[1000] = "";
+ struct file_tags *tags = read_file_tags(plist->items[num].file, NULL, TAGS_COMMENTS);
+ if(tags && tags->filled & TAGS_COMMENTS && tags->album)
+ {
+ strncpy(calbum, tags->album, 1000);
+ tags_free(tags);
+ }
+ int n = num;
+ while(1)
+ {
+ n = plist_next(plist, n);
+ if(n == -1) return -1;
+ tags = read_file_tags(plist->items[n].file, NULL, TAGS_COMMENTS);
+ if(tags && tags->filled & TAGS_COMMENTS && tags->album)
+ {
+ if(strcmp(calbum, tags->album) != 0)
+ {
+ tags_free(tags);
+ return n;
+ }
+ tags_free(tags);
+ }
+ }
+}
+
/* Get the number of the previous item on the list (skipping deleted items).
* If num == -1, get the first item.
* Return -1 if it is the beginning of the playlist.
@@ -302,6 +329,33 @@
return i >= 0 ? i : -1;
}

+int plist_prev_album (struct plist *plist, int num)
+{
+ char calbum[1000] = "";
+ struct file_tags *tags = read_file_tags(plist->items[num].file, NULL, TAGS_COMMENTS);
+ if(tags && tags->filled & TAGS_COMMENTS && tags->album)
+ {
+ strncpy(calbum, tags->album, 1000);
+ tags_free(tags);
+ }
+ int n = num;
+ while(1)
+ {
+ n = plist_prev(plist, n);
+ if(n == -1) return -1;
+ tags = read_file_tags(plist->items[n].file, NULL, TAGS_COMMENTS);
+ if(tags && tags->filled & TAGS_COMMENTS && tags->album)
+ {
+ if(strcmp(calbum, tags->album) != 0)
+ {
+ tags_free(tags);
+ return n;
+ }
+ tags_free(tags);
+ }
+ }
+}
+
void plist_free_item_fields (struct plist_item *item)
{
if (item->file) {
@@ -805,6 +859,70 @@
rb_insert (&plist->search_tree, (void *)i);
}

+void plist_shuffle_album (struct plist *s_plist, struct plist *d_plist)
+{
+ plist_t_item_ix i;
+ plist_t_item_ix albums[50000];
+ albums[0] = 0;
+ int album_c = 1;
+ struct file_tags *tags;
+ char album[1000] = "";
+
+ //create index of albums
+ for(i = 0; i < s_plist->num; i++)
+ {
+ assert(i != 50000);
+ tags = read_file_tags(s_plist->items.file, NULL, TAGS_COMMENTS);
+ if(tags && tags->filled & TAGS_COMMENTS && tags->album)
+ {
+ if(i == 0)
+ {
+ strncpy(album, tags->album, 1000);
+ }
+ else if(strncmp(album, tags->album, 1000) != 0)
+ {
+ albums[album_c] = i;
+ album_c++;
+ strncpy(album, tags->album, 1000);
+ }
+ tags_free(tags);
+ }
+ }
+
+ //carete shuffle index of albums
+ int albums_s[50000];
+ for(i = 0; i < album_c; i++) albums_s = i;
+ int x,n;
+ for(i = 0; i < album_c; i++)
+ {
+ x = albums_s;
+ n = (rand()/(float)RAND_MAX) * (album_c - 1);
+ albums_s = albums_s[n];
+ albums_s[n] = x;
+ }
+
+ //copy items by shuffled albums
+ plist_t_item_ix first_i, last_i;
+ plist_t_item_ix j;
+ for(i = 0; i < album_c; i++)
+ {
+ first_i = albums[albums_s];
+ last_i = albums_s == album_c - 1 ? s_plist->num - 1 : albums[albums_s + 1] - 1;
+
+ for(j = first_i; j <= last_i; j++)
+ {
+ if (!plist_deleted(s_plist, j) && plist_find_fname(d_plist, s_plist->items[j].file) == -1)
+ {
+ plist_add_from_item (d_plist, &s_plist->items[j]);
+ }
+ }
+ }
+ rb_clear (&d_plist->search_tree);
+
+ for (i = 0; i < d_plist->num; i++)
+ rb_insert (&d_plist->search_tree, (void *)i);
+}
+
/* Swap the first item on the playlist with the item with file fname. */
void plist_swap_first_fname (struct plist *plist, const char *fname)
{
diff -ru moc/playlist.h moc/playlist.h
--- moc/playlist.h 2012-07-03 08:51:40.449897534 +0200
+++ moc/playlist.h 2012-07-03 07:48:28.255370553 +0200
@@ -74,7 +74,9 @@
int plist_add_from_item (struct plist *plist, const struct plist_item *item);
char *plist_get_file (const struct plist *plist, int i);
int plist_next (struct plist *plist, int num);
+int plist_next_album (struct plist *plist, int num);
int plist_prev (struct plist *plist, int num);
+int plist_prev_album (struct plist *plist, int num);
void plist_clear (struct plist *plist);
void plist_delete (struct plist *plist, const int num);
void plist_free (struct plist *plist);
@@ -102,6 +104,7 @@
int get_item_time (const struct plist *plist, const int i);
int plist_total_time (const struct plist *plisti, int *all_files);
void plist_shuffle (struct plist *plist);
+void plist_shuffle_album (struct plist *s_plist, struct plist *d_plist);
void plist_swap_first_fname (struct plist *plist, const char *fname);
struct plist_item *plist_new_item ();
void plist_free_item_fields (struct plist_item *item);
diff -ru moc/server.c moc/server.c
--- moc/server.c 2012-07-03 08:51:40.441897824 +0200
+++ moc/server.c 2012-07-03 08:53:36.929692524 +0200
@@ -759,6 +759,7 @@
return !strcasecmp(name, "ShowStreamErrors")
|| !strcasecmp(name, "Repeat")
|| !strcasecmp(name, "Shuffle")
+ || !strcasecmp(name, "Album")
|| !strcasecmp(name, "AutoNext");
}

youtube extension

Is there an extension or something for MOC so that it can stream/play the audio parts of youtube videos.

Layout1

I have set up moc without any problems added a new theme, then noticed start up was slow.

Moc is telling me Layout1 syntax has changed, could not get full console directory to '#'ed out Layout1. Now using key 'l' to hide playlist.

Can someone tell me the correct syntax for a full screen directory layout? Could theme change how layout works?

[patch] Search for libresid-builder.so instead of libresid-builder.la

Summarizing:

- libsidplay2 doesn't use libtool (libltdl), therefore libsidplay2 doesn't need libtool archives (.la) files for loading any plugins

- libresid-builder doesn't link against anything else than the C library

Therefore it doesn't make sense at all to install libtool files (.la) with the libsidplay2 package. So distributions don't even package the .la files from libsidplay2, and if they do, it's a mistake (bug).

And therefore it doesn't make any sense for moc to search for libresid-builder.la files from decoder_plugins/sidplay2/sidplay2.m4. It should simply search libresid-builder.so files since those are actually required for linking (-lresid-builder).

And yes I know that moc is using libtool's libltdl and for moc it actually makes sense to install the .la files with the package for the loader. But that's entirely different issue.
As in, moc should install .la files BUT libsidplay2 shouldn't!

This simple patch will take care of the problem, it was also reported here http://bugs.gentoo.org/416619

--- decoder_plugins/sidplay2/sidplay2.m4
+++ decoder_plugins/sidplay2/sidplay2.m4
@@ -19,10 +19,10 @@
if test "x$sidutils_OK" = "xyes"; then
s2lib=`$PKG_CONFIG --variable=libdir libsidplay2 2>/dev/null`
resid_OK="no"
- AC_CHECK_FILE([$s2lib/libresid-builder.la],
- [resid_lib="$s2lib/libresid-builder.la"
+ AC_CHECK_FILE([$s2lib/libresid-builder.so],
+ [resid_lib="$s2lib/libresid-builder.so"
resid_OK="yes"],
- [resid_lib="$s2lib/sidplay/builders/libresid-builder.la"
+ [resid_lib="$s2lib/sidplay/builders/libresid-builder.so"
AC_CHECK_FILE($resid_lib, [resid_OK="yes"],)])
if test "x$resid_OK" = "xyes"; then
sidplay2_LDFLAGS="$resid_lib"

If you want to read more about useless .la files, here is some very nice posts:

http://blog.flameeyes.eu/2008/04/what-about-those-la-files
http://blog.flameeyes.eu/2010/10/libtool-archives-and-their-pointless-points
http://blog.flameeyes.eu/2010/01/more-pointless-la-files
http://blog.flameeyes.eu/2009/09/removing-la-files-for-dum-w-uncertain-people
http://blog.flameeyes.eu/2009/07/identifying-pointless-la-files-for-plugins (this one is in particular matching moc :-)

MOCP blocks user input after failing to load/restore playlists

I don't know it this is supposed to be a desired behavior, but after I unmounted my music folder (located on a sambaserver) and restarting moc, the previous playlist was still loaded and after trying to play its first song, mocp gave some error messages about not being able to load those files. That's okay, I guess, but instead of being able to clear the playlist all of my input (shift+c, q/Q) was just ignored and moc succeeded to try to play the files from the playlist.

This should'n be a samba problem, though you might want to reproduce this "bug" like this:
1. mount a folder with music on /path/to/mount
2. start mocp, add some of the songs from /path/to/mount to the playlist
3. (I guess SavePlaylist option has to be set to Yes) quit moc (shift q)
4. unmount /path/to/mount
5. start moc and play a song from the playlist

OnTitleChange

Hi there,

It would be wonderful to have new feature like "OnSongChange" but for listening internet radio. When you are listening radio Song doesnt change only Title changes and therefore impossible to use here "OnSongChange".

Return to reading file's folder

I would like to know if there is a way to return to the folder where a file is played.
Indeed, when I quit the moc interface (by 'q') and then return to it, it always start in my MusicDir.
It is annoying because I want to return automatically to the folder where a music is played.

Thank you for answering.

ps: I'm french... Hope you'll understand :-)

FTP Login?

Hi,

i want download a script for moc but the server ask me for login. i tried to type my name and password for this page but it doesn't work.

can someone tellme how i can get ftp access?

thanks

Pages

Subscribe to RSS - General discussion