More Audacious Hackery!

Audacious plugin hack to allow "pausing" streaming radio output WITHOUT pausing input, allowing playing something else during the pause, ie. during commercials, etc.


After successfully hacking Audacious (v. 1.5.x) to accept streaming input on STDIN several months ago, I began streaming my fav. radio stations via Mplayer through a fifo into Audacious. Problem with radio these days is that they have gotten to where instead of having talk-shows and music and occassionally taking commercial breaks, they now just play commercials and occassionally take "show breaks". IMHO, most radio commercials are soooo inane that I have gotten in the habit of just hitting the mute button and waiting 5 minutes and unmuting. During this time I’d just assume listen to music since I can usually play 2 entire songs during most breaks!

Problem is, I’d like to be able to mute the radio and still be able to play random songs from my music collection, but the radio has the sound card and the speakers muted. What I need is the ability to have Audacious "pause" (or silence) the output to the sound card, but continue streaming the input, effectively sending the commercials to the bit-bucket, whilst having another player or Audacious instance open to play music or another station, etc.

The solution ended up being somewhat simple – I added a "–pause-mute" (-P) option to cause the "Pause" function to not actually pause, but rather to set a flag so that the buffer being sent to the sound system is "zeroed out" until the Pause button is again pressed, unsetting the flag. This way, the volume is left on (not actually muting the speakers) and the other player can then be heard over the speakers. Now, with 2 button-clicks, I can switch from a talk-show or radio program to music (or something else such as watching a Youtube video), and then return to the program a few minutes later! The other key is if running 2 instances of Audacious, to have each running under a different user. Otherwise, Audacious will simply reuse the 1st instance with the playlist of the 2nd. This is not a bug, but rather a "feature" of Audacious for remote-controlling via dbus. This is no problem for me since I normally run the radio-streaming instance of Audacious under the same severly limited alternate user that I run my web browser under for added security!

** UPDATE! **

I have now added a 2nd command-line option:  "–new" (-n) which will cause a new instance of Audacious to be started.  One can now start up 2 separate instances under the same user.  Remote "audtool" commands via dbus will only be sent to the 1st instance, though!

Ok, now a brief rant:  I know some people will call me a blatant "freetard" for listening to radio and sometimes skipping commercials.  My response is this:  I have no problems with ad-based broadcasting or ads either for that matter.  My problem is the duration ad-breaks have become in recent years.  I can still remember when a typical commercial break was two minutes.  Stations were only allowed about 12 minutes of commercials per hour.  My grandfather, a professional radio engineer once told me that many years ago "back to back spots was considered ‘sinful’" in radio.  I don’t mind at all listening through a one-two minute break or purchasing ad time during such breaks, but when breaks run to 5-6 minutes (10-12 spots) and up, that’s just insane (IMHO) and the broadcasters (and their content providers in particular) have just become flat out GREEDY!  Broadcasters are granted a license to use the PUBLIC airwaves to serve the PUBLIC INTEREST!  How does filling almost half of your air-time with ads serve either the public OR your advertisers’ interests?  If you are purchasing commercial airtime, ask yourself this – is your message being heard if the radio station packs your add in the mist of 8-11 other 30-sec adds?  I don’t think so!  I would want my ad HEARD, even if it ment paying more.  /end-rant.

Anyway, here’s the patch (to the previously patched version of this file that I did to allow streaming via STDIN, see my April 22nd, 2009 blog entry. You will need to first patch everything according to the patches of that post, then apply these patches!:

audacious-1.5.1/src/audacious/main.h:

80a81
> extern gboolean MuteInLieuOfPause;   /* JWT: ADDED 20100205 TO SAVE VALUE OF "-M" COMMAND-LINE OPTION TO ALLOW MUTING OF OUTPUT ON PAUSE (INPUT CONTINUES)! */

audacious-1.5.1/src/audacious/main.c

103a104,105
>     gboolean pauseismute;
>     gboolean newinstance;
115a118
> gboolean MuteInLieuOfPause;   /* JWT: ADDED 20100205 TO SAVE VALUE OF "-P" COMMAND-LINE OPTION TO ALLOW MUTING OF OUTPUT ON PAUSE (INPUT CONTINUES)! */
278a282,283
>     {"pause-mute", ‘P’, 0, G_OPTION_ARG_NONE, &options.pauseismute, N_("Pause mutes instead of pausing"), NULL},
>     {"new", ‘n’, 0, G_OPTION_ARG_NONE, &options.newinstance, N_("New Instance"), NULL},
391c396
<     gboolean is_running = audacious_remote_is_running(session);

>     gboolean is_running = options.newinstance ? FALSE : audacious_remote_is_running(session);
510c515
<                 gchar *filename;

>                 gchar *filename = "";
594a600,604
>         if (options.pauseismute) /* JWT: ADDED 20100205 "-M" COMMAND-LINE OPTION TO ALLOW MUTING OF OUTPUT ON PAUSE (INPUT CONTINUES)! */
>             MuteInLieuOfPause = TRUE;
>         else
>             MuteInLieuOfPause = FALSE;
>

audacious-1.5.1/src/audacious/output.c

72a73,75
> gshort iamPaused = 0;   /* JWT:  ADDED FOR ALLOWING PAUSE TO CONTINUE READING STREAMS, ONLY PAUSING OUTPUT! */
> gboolean MuteInLieuOfPause;   /* JWT: ADDED 20100205 TO SAVE VALUE OF "-M" COMMAND-LINE OPTION TO ALLOW MUTING OF OUTPUT ON PAUSE (INPUT CONTINUES)! */
>
413a417,421
>
>     /* ZERO-OUT (SILENCE) STREAM GOING TO OUTPUT WHILST PAUSING */
>     if (iamPaused)
>         memset(ptr, ”, length);
>
477c485,494
<     op->pause(paused);

>     /* JWT:  IF -P OPTION SPECIFIED, PAUSE SHOULD THEN JUST SUSPEND OUTPUT.
>              THIS IS SO WE CAN "MUTE" COMMERCIALS FROM RADIO WHILST PLAYING
>              SOMETHING ELSE!  THIS WAY, WE CAN LET THE RADIO BLATHER AWAY
>              TO THE BIT-BUCKET AND LISTEN TO SOMETHING ELSE FOR THE 5+ MINUTES
>              BETWEEN SHOW BREAKS! 😉
>     */
>     if (MuteInLieuOfPause)
>         iamPaused = paused;
>     else
>         op->pause(paused);

Fix Filewriter plugin to NOT accidently overwrite the input file:

audacious-plugins-1.5.1/src/filewriter/filewriter.c

91a92
> static gchar outputPluginFileExtType[10];  /* JWT: ADDED 20100208 TO SAVE THE EXTENSION (.PART) OF THE -o OPTION IF SPECIFIED. */
195a197,232
>     /* JWT: ADDED 20100208 – TRY TO FETCH THE FILE-EXTENSION TYPE FROM THE -o
>      * COMMAND-LINE OPTION, IF IT WAS SPECIFIED (IT IS STORED IN A TEMP. FILE
>      * SINCE I COULD NOT FIGURE OUT A WAY TO PASS IT IN AS A PARAMETER?!
>      * THE COMMAND-LINE OPTION IS:  -o filewriter[.wav|.ogg|vorbis|flac|mp3]
>      */
>     FILE *TMPFILE = fopen("/tmp/audacious_pluginext.tmp", "r");
>     if (TMPFILE)
>     {
>         fread(outputPluginFileExtType, 9, 1, TMPFILE);
>         fclose(TMPFILE);
>         remove("/tmp/audacious_pluginext.tmp");  /* REMOVE THE TEMP. FILE. */
>         if (strlen(outputPluginFileExtType))
>         {
> #ifdef FILEWRITER_MP3
>             if (!strcmp(outputPluginFileExtType, "MP3") || !strcmp(outputPluginFileExtType, "mp3"))
>                     fileext = MP3;
> #endif
> #ifdef FILEWRITER_VORBIS
>             if (!strcmp(outputPluginFileExtType, "Vorbis") || !strcmp(outputPluginFileExtType, "VORBIS")
>                     || !strcmp(outputPluginFileExtType, "vorbis") || !strcmp(outputPluginFileExtType, "OGG")
>                     || !strcmp(outputPluginFileExtType, "ogg"))  fileext = VORBIS;
> #endif
> #ifdef FILEWRITER_FLAC
>             if (!strcmp(outputPluginFileExtType, "FLAC") || !strcmp(outputPluginFileExtType, "flac"))
>                     fileext = FLAC;
> #endif
>
>             if (strlen(outputPluginFileExtType) > 0)
>             {
>                 set_plugin();
>                 if (plugin.init)
>                     plugin.init();
>             }
>         }
>     }
>
207,209c244,245
<         return 0;
<
<     if (filenamefromtags)

>         filename = g_strdup_printf("aud-out");
>     else
211c247,249
<         gchar *utf8 = aud_tuple_formatter_make_title_string(tuple, aud_get_gentitle_format());

>         if (filenamefromtags)
>         {
>             gchar *utf8 = aud_tuple_formatter_make_title_string(tuple, aud_get_gentitle_format());
213c251
<         g_strchomp(utf8); //chop trailing ^J –yaz

>             g_strchomp(utf8); //chop trailing ^J –yaz
215,225c253,278
<         filename = g_locale_from_utf8(utf8, -1, NULL, NULL, NULL);
<         g_free(utf8);
<         while (filename != NULL && (temp = strchr(filename, ‘/’)) != NULL)
<             *temp = ‘-‘;
<     }
<     if (filename == NULL)
<     {
<         filename = g_strdup(aud_tuple_get_string(tuple, FIELD_FILE_NAME, NULL));
<         if (!use_suffix)
<             if ((temp = strrchr(filename, ‘.’)) != NULL)
<                 *temp = ”;

>             filename = g_locale_from_utf8(utf8, -1, NULL, NULL, NULL);
>             g_free(utf8);
>             while (filename != NULL && (temp = strchr(filename, ‘/’)) != NULL)
>                 *temp = ‘-‘;
>         }
>         if (filename == NULL)
>         {
>             filename = g_strdup(aud_tuple_get_string(tuple, FIELD_FILE_NAME, NULL));
>             if (!use_suffix)
>                 if ((temp = strrchr(filename, ‘.’)) != NULL)
>                     *temp = ”;
>         }
>         if (filename == NULL)
>             filename = g_strdup_printf("aud-%d", pos);
>
>         if (prependnumber)
>         {
>             gint number = aud_tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL);
>             if (!tuple || !number)
>                 number = pos + 1;
>
>             temp = g_strdup_printf("%.02d %s", number, filename);
>             g_free(filename);
>             filename = temp;
>         }
>         if (!strcmp(filename, "-"))  filename = g_strdup_printf("aud-out");
227,228d279
<     if (filename == NULL)
<         filename = g_strdup_printf("aud-%d", pos);
230,231c281
<
<     if (prependnumber)

>     if (save_original && tuple)
233,242d282
<         gint number = aud_tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL);
<         if (!tuple || !number)
<             number = pos + 1;
<
<         temp = g_strdup_printf("%.02d %s", number, filename);
<         g_free(filename);
<         filename = temp;
<     }
<
<     if (save_original)
243a284,285
>         if (directory[0] != ‘/’)  directory = file_path;
>     }
247,248c289,308
<     temp = g_strdup_printf("file://%s/%s.%s",
<                            directory, filename, fileext_str[fileext]);

>     /* JWT: CHECK EXISTANCE OF OUTPUT FILE – DON’T OVERWRITE THE INPUT FILE! */
>     gboolean fexists = TRUE;
>     gint fvsn = 0;
>     while (fexists)
>     {
>         gchar *tfn = (fvsn > 0) ? g_strdup_printf("%s/%s_%d.%s", directory, filename, fvsn, fileext_str[fileext])
>                 : g_strdup_printf("%s/%s.%s", directory, filename, fileext_str[fileext]);
>         TMPFILE = fopen(tfn, "r");
>         if (TMPFILE)
>         {
>             fclose(TMPFILE);
>             ++fvsn;
>         }
>         else
>             fexists = FALSE;
>     }
>
>     temp = (fvsn > 0) ? g_strdup_printf("file://%s/%s_%d.%s", directory, filename, fvsn,
>             fileext_str[fileext])
>         : g_strdup_printf("file://%s/%s.%s", directory, filename, fileext_str[fileext]);
392c452,454
<     aud_cfg_db_set_int(db, "filewriter", "fileext", fileext);

>     /* JWT: ADDED IF-COND. 20100208 – ONLY SAVE EXT. TYPE TO DATABASE IF *NOT* SPECIFIED ON
>      * COMMAND-LINE SO THE COMMAND-LINE OVERRIDE ONLY APPLIES TO THE *CURRENT* RUN! */
>     if (strlen(outputPluginFileExtType) <= 0)  aud_cfg_db_set_int(db, "filewriter", "fileext", fileext);

=========== UPDATE! ===========

This additional unrelated patch fixes a long-standing failure of the amidi plugin to load due to this warning:

"Failed to load plugin (/usr/local/lib/audacious/Input/amidi-plug.so): /usr/local/lib/audacious/Input/amidi-plug.so: undefined symbol: audacious_drct_get_playing
cdaudio-ng: use_dae = 1, limitspeed = 0, use_cdtext = 1, use_cddb = 0, cddbserver = "freedb.org", cddbpath = "", cddbport = 8880, cddbhttp = 0, device = "/dev/scd0", debug = 1"

audacious-plugins-1.5.1/src/amidi-plug/i_configure.c:

30a31
> #include <audacious/plugin.h>     /* JWT: ADDED 20100204 TO ELIMINATE FAILURE-2-LOAD ERROR: "undefined symbol: audacious_drct_get_playing cdaudio-ng"! */

========== END PATCH ==========

To pay radio:

sudo su -c "/bin/bash" $ALT_USER
mkfifo /tmp/fifo.wav
cat /tmp/fifo.wav | audacious -P file://-.wav &
sleep 1
mplayer -idle -slave -msglevel all=-1 -nojoystick -nolirc http://$YOUR_RADIOSTATION_URL -vc null -vo null -ao pcm:waveheader:file=/tmp/fifo.wav &

Enjoy continueous listening!

Advertisements

One Trackback

  1. […] streaming my music and pause-toggle between the two during commercials (using my awesomely-cool HACK that will mute only the radio instance while continuing to stream (to the bit bucket) allowing […]

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: