Audacious Patch

I really liked the old, now defunct “xmms” music player software.  A fork of it seems to have replaced it called “Audacious”.  I gave it a try, and it seems to really work and sound well, much better than “vlc”.  Anyway, a couple of annoyances have crept into it as of the latest version 1.5.1:

1) The “File Open” window pops up when specifying the cdrom (cdda://) as the play target on the command-line.

2) Starting Audacious without a play target (music files, playlist file, url, or cdd*:// device) causes the last played playlist to start up automatically. That’s well and good, but I wanted a way to start up Audacious with an empty playlist.

3) For some strange reason, you can stream audio, at least mp3 from a url, but NOT from STDIN?!

I found a patch here that partially addresses (1) here: http://atheme.org/attachments/15/1.5.1-commandline-options.patch Thanks Tony Vroon! I applied this, but it did not fix 1 completly, so I developed another patch based from this one to fix (1) and add a “-c/–clear” command-line option to address (2).  I also patched the plugin file (stdio.c) to address 3.  Whilst I was at it, I decided to also add the ability to pipe in a playlist (list of files/urls to play) into STDIN as well!  For piping a song, one needs to append the extension to the STDIN filename (“-) in indicate to Audacious what type of file it’s processing.    I ended up having to hack several of the plugins, so that it now works (tested) for ogg, wav, and mp3-ish files.

I ended up having to also include the “file://” prefix since otherwise Audacious thinks “-.mp3” is an option.  Anyway, these patches are against Audacious v. 1.5.1 (audacious_1.5.1.orig.tar.gz) and Plugins, v. 1.5.1 (audacious-plugins_1.5.1.orig.tar.gz).

To pipe in a song, do:

cat ~/mymusic/coolsong.mp3 | audacious file://-.mp3

To pipe in a play list, do:

ls ~/mymusic | audacious –

Now I can do cool things like stream radio that is in a format that Audacious can’t play, like “asf” through Audacious without filling up my hard disk, ie.:

rm -f /tmp/fifo.wav
mkfifo /tmp/fifo.wav
cat /tmp/fifo.wav | audacious file://-.wav &
sleep 1
mplayer -msglevel all=-1 -nojoystick -nolirc http://68.142.72.75:80/citadelcc_WBAP_AM?MSWMExt=.asf -vc null -vo null -ao pcm:waveheader:file=/tmp/fifo.wav &


main.c (diff):
102a103
>     gboolean clear;
276a278
>     {“clear”, ‘c’, 0, G_OPTION_ARG_NONE, &options.clear, N_(“Clear Playlist”), NULL},
291a294,359
> static gboolean
> add2playlist_via_stdin(gpointer unused)
> {
>     gchar *filename;
>     gchar *current_dir = g_get_current_dir();
>     GList *fns = NULL;
>     char s[500];
>     time_t timeout = 1;
>
>     long original = (long)fcntl(0, F_GETFL);
>     gboolean dataRead = FALSE;
>
>     fcntl(0, F_SETFL, O_NONBLOCK);
>     while (!dataRead && (timeout > 0))
>     {
>         if (fgets(s, 500, stdin) != NULL) {
>             dataRead = TRUE;
>         } else {
>                  if (feof(stdin))
>                  {
>                 g_list_foreach(fns, (GFunc) g_free, NULL);
>                 g_list_free(fns);
>                 return FALSE;
>                  }
>             g_list_foreach(fns, (GFunc) g_free, NULL);
>             g_list_free(fns);
>             /* sleep(1); */
>             g_usleep(20000);
>             timeout–;
>         }
>     }
>     fcntl(0, F_SETFL, original);
>     if(dataRead)
>     {
>         if (strlen(s) > 1 && s[0] != ‘#’)       /* filter out the comments*/
>         {
>                  s[strlen(s)-1] = ”;
>                  /* if (strlen(s) <= 0)  break; */
>                  if (!strstr(s, “://”))
>                  {
>                          if (s[0] == ‘/’)
>                     filename = g_strdup_printf(“file:///%s”, s);
>                 else
>                     filename = g_strdup_printf(“file:///%s/%s”,
>                             current_dir, s);
>                 fns = g_list_prepend(fns, filename);
>             }
>             else
>             {
>                 filename = g_strdup(s);
>                 fns = g_list_prepend(fns, filename);
>             }
>             drct_pl_add(fns);
>         }
>         g_list_foreach(fns, (GFunc) g_free, NULL);
>         g_list_free(fns);
>         return TRUE;
>     }
>     else
>     {
>         g_list_foreach(fns, (GFunc) g_free, NULL);
>         g_list_free(fns);
>         return TRUE;
>     }
> }
>
318c386
< handle_cmd_line_options()

> handle_cmd_line_options(gboolean skip)
433c501
<     { /* !is_running */

>     if (!skip) { /* !is_running */
448a517,518
>                     else if (filenames[i][0] == ‘-‘)
>                          g_idle_add_full(G_PRIORITY_LOW, add2playlist_via_stdin, NULL, NULL);
456c526
<                 fns = g_list_prepend(fns, filename);

>                 if (filenames[i][0] != ‘-‘)  fns = g_list_prepend(fns, filename);
489a560,564
>         }
>         else if (options.clear) /* JWT: ADDED “-c” COMMAND-LINE OPTION TO START UP W/EMPTY PLAYLIST! */
>         {
>             drct_pl_clear();
>             drct_stop();
718c793
<     handle_cmd_line_options();

>     handle_cmd_line_options(TRUE);
737a813,814
>     handle_cmd_line_options(FALSE);
>

auddrct.c. (diff):
103,104c103,104
< else
< mainwin_eject_pushed();

> /* JWT: PREVENT “Open Files” DIALOG WINDOW POPPING UP WHEN OPENED WITHOUT USER REQUESTING – else
> mainwin_eject_pushed(); */

(plugins) madplug/plugin.c (diff):
263a264,270
>     /* JWT:  EXCLUDE NON-MP3 EXTENSIONS! */
>     if (strstr(filename, “file://-.”))
>     {
>         if ((ext != NULL) && strcasecmp(“mp2”, ext) && strcasecmp(“mp3”, ext)
>                     && strcasecmp(“mpg”, ext) && strcasecmp(“bmu”, ext))  return 0;
>     }
>
344a352,357
>     if (strstr(filename, “file://-.”))    /* JWT:  EXCLUDE NON-MP3 EXTENSIONS IF STDIN TO AVOID OPEN/READ! */
>     {
>         gchar *ext = extname(filename);
>         if ((ext != NULL) && strcasecmp(“mp2”, ext) && strcasecmp(“mp3”, ext)
>                     && strcasecmp(“mpg”, ext) && strcasecmp(“bmu”, ext))  return 0;
>     }

(plugins) sndfile/plugin.c (diff):
105c105,118
<     snd_file = sf_open_virtual (&sf_virtual_io, SFM_READ, tmp_sfinfo, *vfsfile);

>     if (filename[7] == ‘-‘ && filename[8] == ‘.’)  /* JWT:  IF stdin “OPEN” DIFFERENTLY – JUST TO GET sndfile OBJECT! */
>     {
>         if (sndfile == NULL)    /* JWT:  ONLY OPEN (stdin) IF THIS IS 1ST CALL. */
>         {
>             memset(&sfinfo, 0, sizeof(sfinfo));
>             snd_file = sf_open_fd(STDIN_FILENO, SFM_READ, &sfinfo, 0);
>             sndfile = snd_file;
>         }
>         snd_file = sndfile;
>     }
>     else
>     {
>         snd_file = sf_open_virtual (&sf_virtual_io, SFM_READ, tmp_sfinfo, *vfsfile);
>     }
159c172
<     close_sndfile (tmp_sndfile, vfsfile);

>     if (filename[7] != ‘-‘ || filename[8] != ‘.’)  close_sndfile (tmp_sndfile, vfsfile);
351a365,368
>     /* JWT:  AVOID (RE-)OPENING stdin! */
>     if (strstr(filename, “//-.wav”) || strstr(filename, “//-.aiff”) || strstr(filename, “//-.au”)
>             || strstr(filename, “//-.raw”))  return TRUE;
>
455c472,474
<     if (sfinfo.samplerate > 0)

>     if (playback->filename[7] == ‘-‘ && playback->filename[8] == ‘.’)
>         song_length =  -1;
>     else if (sfinfo.samplerate > 0)
496c515
<     sndfile = NULL;

>     /* JWT:WILL CLOSE AND NULL IN play_loop!    sndfile = NULL; */
524c543
<     fill_song_tuple(filename, ti);

>     if (filename[7] != ‘-‘ || filename[8] != ‘.’)  fill_song_tuple(filename, ti);
533a553,556
>     /* JWT:  AVOID (RE-)OPENING stdin! */
>     if (strstr(filename, “//-.wav”) || strstr(filename, “//-.aiff”) || strstr(filename, “//-.au”)
>             || strstr(filename, “//-.raw”))  return TRUE;
>

(plugins) vorbis/vorbis.c (diff):
96a97,103
> ov_callbacks vorbis_callbacks_stdin = {
>     ovcb_read,
>     NULL,
>     NULL,
>     NULL
> };
>
150c157,159
<     result = ov_test_callbacks(fd, &vfile, NULL, 0, aud_vfs_is_streaming(stream) ? vorbis_callbacks_stream : vorbis_callbacks);

>     if (!strstr(filename, “//-.ogg”) && !strstr(filename, “//-.ogm”))   /* JWT: FILE IS NOT stdin */
>     {
>         result = ov_test_callbacks(fd, &vfile, NULL, 0, aud_vfs_is_streaming(stream) ? vorbis_callbacks_stream : vorbis_callbacks);
152,153c161,162
<     switch (result) {
<     case OV_EREAD:

>         switch (result) {
>         case OV_EREAD:
155c164
<         g_message(“** vorbis.c: Media read error: %s”, filename);

>             g_message(“** vorbis.c: Media read error: %s”, filename);
157,160c166,169
<         g_mutex_unlock(vf_mutex);
<         return FALSE;
<         break;
<     case OV_ENOTVORBIS:

>             g_mutex_unlock(vf_mutex);
>             return FALSE;
>             break;
>         case OV_ENOTVORBIS:
162c171
<         g_message(“** vorbis.c: Not Vorbis data: %s”, filename);

>             g_message(“** vorbis.c: Not Vorbis data: %s”, filename);
164,167c173,176
<         g_mutex_unlock(vf_mutex);
<         return FALSE;
<         break;
<     case OV_EVERSION:

>             g_mutex_unlock(vf_mutex);
>             return FALSE;
>             break;
>         case OV_EVERSION:
169c178
<         g_message(“** vorbis.c: Version mismatch: %s”, filename);

>             g_message(“** vorbis.c: Version mismatch: %s”, filename);
171,174c180,183
<         g_mutex_unlock(vf_mutex);
<         return FALSE;
<         break;
<     case OV_EBADHEADER:

>             g_mutex_unlock(vf_mutex);
>             return FALSE;
>             break;
>         case OV_EBADHEADER:
176,177c185,186
<         g_message(“** vorbis.c: Invalid Vorbis bistream header: %s”,
<                   filename);

>             g_message(“** vorbis.c: Invalid Vorbis bistream header: %s”,
>                       filename);
179,182c188,191
<         g_mutex_unlock(vf_mutex);
<         return FALSE;
<         break;
<     case OV_EFAULT:

>             g_mutex_unlock(vf_mutex);
>             return FALSE;
>             break;
>         case OV_EFAULT:
184,185c193,194
<         g_message(“** vorbis.c: Internal logic fault while reading %s”,
<                   filename);

>             g_message(“** vorbis.c: Internal logic fault while reading %s”,
>                       filename);
187,194c196,203
<         g_mutex_unlock(vf_mutex);
<         return FALSE;
<         break;
<     case 0:
<         break;
<     default:
<         break;
<     }

>             g_mutex_unlock(vf_mutex);
>             return FALSE;
>             break;
>         case 0:
>             break;
>         default:
>             break;
>         }
196,197c205,207
<     ov_clear(&vfile);           /* once the ov_open succeeds, the stream belongs to
<                                    vorbisfile.a.  ov_clear will fclose it */

>         ov_clear(&vfile);           /* once the ov_open succeeds, the stream belongs to
>                                        vorbisfile.a.  ov_clear will fclose it */
>     }
286,290c296,312
<     if (ov_open_callbacks(datasource, &vf, NULL, 0, aud_vfs_is_streaming(fd->fd) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) {
<         vorbis_callbacks.close_func(datasource);
<         g_mutex_unlock(vf_mutex);
<         playback->eof = TRUE;
<         goto play_cleanup;

>     if (filename[7] == ‘-‘ && filename[8] == ‘.’)   /* JWT: FILE IS stdin */
>     {
>         if (ov_open_callbacks(datasource, &vf, NULL, 0, vorbis_callbacks_stdin) < 0) {
>             vorbis_callbacks.close_func(datasource);
>             g_mutex_unlock(vf_mutex);
>             playback->eof = TRUE;
>             goto play_cleanup;
>         }
>     }
>     else
>     {
>         if (ov_open_callbacks(datasource, &vf, NULL, 0, aud_vfs_is_streaming(fd->fd) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) {
>             vorbis_callbacks.close_func(datasource);
>             g_mutex_unlock(vf_mutex);
>             playback->eof = TRUE;
>             goto play_cleanup;
>         }
294c316
<     if (aud_vfs_is_streaming(fd->fd))

>     if ((filename[7] == ‘-‘ && filename[8] == ‘.’) || aud_vfs_is_streaming(fd->fd))
296c318
<     else

>     else   /* JWT: FILE IS AN ACTUAL FILE, NOT stdin OR A STREAM. */
565c587
<     if (aud_vfs_is_streaming(vfd->fd))

>     if ((filename[7] == ‘-‘ && filename[8] == ‘.’) || aud_vfs_is_streaming(vfd->fd))
567c589
<     else

>     else   /* JWT: FILE IS AN ACTUAL FILE, NOT stdin OR A STREAM. */
623,626c645,650
<     if (ov_open_callbacks(fd, &vfile, NULL, 0, aud_vfs_is_streaming(stream) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) {
<         aud_vfs_fclose(stream);
<         return NULL;
<     }

>     if (filename[7] != ‘-‘ || filename[8] != ‘.’)   /* JWT: FILE IS NOT stdin */
>     {
>         if (ov_open_callbacks(fd, &vfile, NULL, 0, aud_vfs_is_streaming(stream) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) {
>             aud_vfs_fclose(stream);
>             return NULL;
>         }
628c652
<     tuple = get_aud_tuple_for_vorbisfile(&vfile, filename);

>         tuple = get_aud_tuple_for_vorbisfile(&vfile, filename);
630,634c654,658
<     /*
<      * once the ov_open succeeds, the stream belongs to
<      * vorbisfile.a.  ov_clear will fclose it
<      */
<     ov_clear(&vfile);

>         /*
>          * once the ov_open succeeds, the stream belongs to
>          * vorbisfile.a.  ov_clear will fclose it
>          */
>         ov_clear(&vfile);
636c660,663
<     return tuple;

>         return tuple;
>     }
>
>     return NULL;

(plugins) stdio/stdio.c (diff):
86c86,89
<     file->handle = fopen(decpath != NULL ? decpath : path, mode);

>     if (decpath[0] == ‘/’ && decpath[1] == ‘-‘ && decpath[2] == ‘.’)   /* JWT: TREAT “file://-.xxx” as “-” (stdin)! */
>         file->handle = stdin;
>     else
>         file->handle = fopen(decpath != NULL ? decpath : path, mode);
108a112,113
>         if (strstr(file->uri, “file://-.”))  return ret;  /* JWT:  DON’T CLOSE STDIN! (file://-.xxx)! */
>

Recompiled from source obtained here: http://packages.debian.org/source/testing/audacious

Also found this cool streaming radio site while testing: http://scfire-ntc-aa03.stream.aol.com:80/stream/1018

Advertisements

Feel Free to Comment (Name/Email/Website optional):

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: