changeset 2351:db02ad480056

vorbis switched to floating-point output. RG stuff removed
author Eugene Zagidullin <e.asphyx@gmail.com>
date Sat, 02 Feb 2008 02:02:15 +0300
parents 233996ff7603
children 08a7d1f7c4a5
files src/vorbis/configure.c src/vorbis/vorbis.c src/vorbis/vorbis.h
diffstat 3 files changed, 81 insertions(+), 267 deletions(-) [+]
line wrap: on
line diff
--- a/src/vorbis/configure.c	Thu Jan 31 13:10:55 2008 +0300
+++ b/src/vorbis/configure.c	Sat Feb 02 02:02:15 2008 +0300
@@ -15,12 +15,10 @@
 extern GMutex *vf_mutex;
 
 static GtkWidget *vorbis_configurewin = NULL;
-static GtkWidget *vbox, *notebook;
+static GtkWidget *vbox;
 
 static GtkWidget *title_tag_override, *title_tag_box, *title_tag_entry,
     *title_desc;
-static GtkWidget *rg_switch, *rg_clip_switch, *rg_booster_switch,
-    *rg_track_gain;
 
 vorbis_config_t vorbis_cfg;
 
@@ -37,30 +35,11 @@
 
     tb = GTK_TOGGLE_BUTTON(title_tag_override);
     vorbis_cfg.tag_override = gtk_toggle_button_get_active(tb);
-    tb = GTK_TOGGLE_BUTTON(rg_switch);
-    vorbis_cfg.use_replaygain = gtk_toggle_button_get_active(tb);
-    tb = GTK_TOGGLE_BUTTON(rg_clip_switch);
-    vorbis_cfg.use_anticlip = gtk_toggle_button_get_active(tb);
-    tb = GTK_TOGGLE_BUTTON(rg_booster_switch);
-    vorbis_cfg.use_booster = gtk_toggle_button_get_active(tb);
-    tb = GTK_TOGGLE_BUTTON(rg_track_gain);
-    if (gtk_toggle_button_get_active(tb))
-        vorbis_cfg.replaygain_mode = REPLAYGAIN_MODE_TRACK;
-    else
-        vorbis_cfg.replaygain_mode = REPLAYGAIN_MODE_ALBUM;
 
     db = aud_cfg_db_open();
-
     aud_cfg_db_set_bool(db, "vorbis", "tag_override",
                         vorbis_cfg.tag_override);
     aud_cfg_db_set_string(db, "vorbis", "tag_format", vorbis_cfg.tag_format);
-    aud_cfg_db_set_bool(db, "vorbis", "use_anticlip",
-                        vorbis_cfg.use_anticlip);
-    aud_cfg_db_set_bool(db, "vorbis", "use_replaygain",
-                        vorbis_cfg.use_replaygain);
-    aud_cfg_db_set_int(db, "vorbis", "replaygain_mode",
-                       vorbis_cfg.replaygain_mode);
-    aud_cfg_db_set_bool(db, "vorbis", "use_booster", vorbis_cfg.use_booster);
     aud_cfg_db_close(db);
     gtk_widget_destroy(vorbis_configurewin);
 }
@@ -81,21 +60,11 @@
     gtk_widget_set_sensitive(title_desc, override);
 }
 
-static void
-rg_switch_cb(GtkWidget * w, gpointer data)
-{
-    gtk_widget_set_sensitive(GTK_WIDGET(data),
-                             gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
-                                                          (w)));
-}
-
 void
 vorbis_configure(void)
 {
     GtkWidget *title_frame, *title_tag_vbox, *title_tag_label;
-    GtkWidget *rg_frame, *rg_vbox;
     GtkWidget *bbox, *ok, *cancel;
-    GtkWidget *rg_type_frame, *rg_type_vbox, *rg_album_gain;
 
     if (vorbis_configurewin != NULL) {
         gtk_window_present(GTK_WINDOW(vorbis_configurewin));
@@ -119,8 +88,6 @@
     vbox = gtk_vbox_new(FALSE, 10);
     gtk_container_add(GTK_CONTAINER(vorbis_configurewin), vbox);
 
-    notebook = gtk_notebook_new();
-    gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
 
     /* Title config.. */
 
@@ -151,72 +118,9 @@
 
     title_tag_entry = gtk_entry_new();
     gtk_entry_set_text(GTK_ENTRY(title_tag_entry), vorbis_cfg.tag_format);
-    gtk_box_pack_start(GTK_BOX(title_tag_box), title_tag_entry, TRUE, TRUE,
-                       0);
-
-    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), title_frame,
-                             gtk_label_new(_("Title")));
-
-    /* Replay Gain.. */
-
-    rg_frame = gtk_frame_new(_("ReplayGain Settings:"));
-    gtk_container_border_width(GTK_CONTAINER(rg_frame), 5);
-
-    rg_vbox = gtk_vbox_new(FALSE, 10);
-    gtk_container_border_width(GTK_CONTAINER(rg_vbox), 5);
-    gtk_container_add(GTK_CONTAINER(rg_frame), rg_vbox);
-
-    rg_clip_switch =
-        gtk_check_button_new_with_label(_("Enable Clipping Prevention"));
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rg_clip_switch),
-                                 vorbis_cfg.use_anticlip);
-    gtk_box_pack_start(GTK_BOX(rg_vbox), rg_clip_switch, FALSE, FALSE, 0);
-
-    rg_switch = gtk_check_button_new_with_label(_("Enable ReplayGain"));
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rg_switch),
-                                 vorbis_cfg.use_replaygain);
-    gtk_box_pack_start(GTK_BOX(rg_vbox), rg_switch, FALSE, FALSE, 0);
-
-    rg_type_frame = gtk_frame_new(_("ReplayGain Type:"));
-    gtk_box_pack_start(GTK_BOX(rg_vbox), rg_type_frame, FALSE, FALSE, 0);
-
-    g_signal_connect(G_OBJECT(rg_switch), "toggled",
-                     G_CALLBACK(rg_switch_cb), rg_type_frame);
+    gtk_box_pack_start(GTK_BOX(title_tag_box), title_tag_entry, TRUE, TRUE, 0);
 
-    rg_type_vbox = gtk_vbox_new(FALSE, 5);
-    gtk_container_set_border_width(GTK_CONTAINER(rg_type_vbox), 5);
-    gtk_container_add(GTK_CONTAINER(rg_type_frame), rg_type_vbox);
-
-    rg_track_gain =
-        gtk_radio_button_new_with_label(NULL, _("use Track Gain/Peak"));
-    if (vorbis_cfg.replaygain_mode == REPLAYGAIN_MODE_TRACK)
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rg_track_gain), TRUE);
-    else
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rg_track_gain), FALSE);
-    gtk_box_pack_start(GTK_BOX(rg_type_vbox), rg_track_gain, FALSE, FALSE, 0);
-
-    rg_album_gain =
-        gtk_radio_button_new_with_label(gtk_radio_button_group
-                                        (GTK_RADIO_BUTTON(rg_track_gain)),
-                                        _("use Album Gain/Peak"));
-    if (vorbis_cfg.replaygain_mode == REPLAYGAIN_MODE_ALBUM)
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rg_album_gain), TRUE);
-    else
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rg_album_gain), FALSE);
-    gtk_box_pack_start(GTK_BOX(rg_type_vbox), rg_album_gain, FALSE, FALSE, 0);
-
-    if (!vorbis_cfg.use_replaygain)
-        gtk_widget_set_sensitive(rg_type_frame, FALSE);
-
-    rg_booster_switch =
-        gtk_check_button_new_with_label(_
-                                        ("Enable 6dB Boost + Hard Limiting"));
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rg_booster_switch),
-                                 vorbis_cfg.use_booster);
-    gtk_box_pack_start(GTK_BOX(rg_vbox), rg_booster_switch, FALSE, FALSE, 0);
-
-    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), rg_frame,
-                             gtk_label_new(_("ReplayGain")));
+    gtk_box_pack_start(GTK_BOX(vbox), title_frame, TRUE, TRUE, 0);
 
     /* Buttons */
 
--- a/src/vorbis/vorbis.c	Thu Jan 31 13:10:55 2008 +0300
+++ b/src/vorbis/vorbis.c	Sat Feb 02 02:02:15 2008 +0300
@@ -3,6 +3,7 @@
  * Copyright (C) 2001-2002  Haavard Kvaalen <havardk@xmms.org>
  * Copyright (C) 2007 William Pitcock <nenolod@sacredspiral.co.uk>
  * Copyright (C) 2008 Cristi Măgherușan <majeru@gentoo.ro>
+ * Copyright (C) 2008 Eugene Zagidullin <e.asphyx@gmail.com>
  *
  * ReplayGain processing Copyright (C) 2002 Gian-Carlo Pascutto <gcp@sjeng.org>
  *
@@ -73,9 +74,9 @@
 static void vorbis_aboutbox(void);
 static void vorbis_init(void);
 static void vorbis_cleanup(void);
-static long vorbis_process_replaygain(float **pcm, int samples, int ch,
-                                      char *pcmout, float rg_scale);
-static gboolean vorbis_update_replaygain(float *scale);
+static long vorbis_interleave_buffer(float **pcm, int samples, int ch,
+                                     float *pcmout);
+static gboolean vorbis_update_replaygain(ReplayGainInfo *rg_info);
 
 static size_t ovcb_read(void *ptr, size_t size, size_t nmemb,
                         void *datasource);
@@ -231,6 +232,9 @@
     }
 }
 
+#define PCM_FRAMES 1024
+#define PCM_BUFSIZE PCM_FRAMES*2
+
 static gpointer
 vorbis_play_loop(gpointer arg)
 {
@@ -248,8 +252,10 @@
     VFSFile *stream = NULL;
     void *datasource = NULL;
 
-    gboolean use_rg;
-    float rg_scale = 1.0;
+    /*gboolean use_rg;
+    /float rg_scale = 1.0;*/
+
+    ReplayGainInfo rg_info;
 
     memset(&vf, 0, sizeof(vf));
 
@@ -262,7 +268,8 @@
     fd->fd = stream;
     datasource = (void *) fd;
 
-    char pcmout[4096];
+    /*char pcmout[4096];*/
+    float pcmout[PCM_BUFSIZE*sizeof(float)];
     int bytes;
     float **pcm;
 
@@ -300,8 +307,9 @@
     }
 
     title = vorbis_generate_title(&vf, filename);
-    use_rg = vorbis_update_replaygain(&rg_scale);
-
+    vorbis_update_replaygain(&rg_info);
+    playback->set_replaygain_info(playback, &rg_info);
+    
     vi = ov_info(&vf, -1);
 
     samplerate = vi->rate;
@@ -311,7 +319,7 @@
     g_mutex_unlock(vf_mutex);
 
     playback->set_params(playback, title, time, br, samplerate, channels);
-    if (!playback->output->open_audio(FMT_S16_NE, vi->rate, vi->channels)) {
+    if (!playback->output->open_audio(FMT_FLOAT, vi->rate, vi->channels)) {
         playback->error = TRUE;
         goto play_cleanup;
     }
@@ -339,19 +347,11 @@
         int current_section = last_section;
 
         g_mutex_lock(vf_mutex);
-        if (use_rg) {
-            bytes =
-                ov_read_float(&vf, &pcm, sizeof(pcmout) / 2 / channels,
-                        &current_section);
-            if (bytes > 0)
-                bytes = vorbis_process_replaygain(pcm, bytes, channels,
-                        pcmout, rg_scale);
-        }
-        else {
-            bytes = ov_read(&vf, pcmout, sizeof(pcmout),
-                    (int) (G_BYTE_ORDER == G_BIG_ENDIAN),
-                    2, 1, &current_section);
-        }
+        
+        bytes = ov_read_float(&vf, &pcm, PCM_FRAMES, &current_section);
+        
+        if (bytes > 0)
+            bytes = vorbis_interleave_buffer(pcm, bytes, channels, pcmout);
 
         /*
          * We got some sort of error. Bail.
@@ -391,19 +391,21 @@
                 playback->output->buffer_free();
                 playback->output->close_audio();
                 if (!playback->output->
-                        open_audio(FMT_S16_NE, vi->rate, vi->channels)) {
+                        open_audio(FMT_FLOAT, vi->rate, vi->channels)) {
                     playback->error = TRUE;
                     playback->eof = TRUE;
                     g_mutex_unlock(vf_mutex);
                     goto stop_processing;
                 }
                 playback->output->flush(ov_time_tell(&vf) * 1000);
+                vorbis_update_replaygain(&rg_info);
+                playback->set_replaygain_info(playback, &rg_info); /* audio reopened */
             }
         }
 
         g_mutex_unlock(vf_mutex);
 
-        playback->pass_audio(playback, FMT_S16_NE, channels, bytes, pcmout, &playback->playing);
+        playback->pass_audio(playback, FMT_FLOAT, channels, bytes, pcmout, &playback->playing);
 
         if (!playback->playing)
             goto stop_processing;
@@ -414,35 +416,32 @@
         stop_processing:
    
         if (current_section <= last_section) {
-        /*
-         * set total play time, bitrate, rate, and channels of
-         * current section
-         */
-        if (title)
-            g_free(title);
+            /*
+            * set total play time, bitrate, rate, and channels of
+            * current section
+            */
+            if (title)
+                g_free(title);
 
-        g_mutex_lock(vf_mutex);
-        title = vorbis_generate_title(&vf, filename);
-        use_rg = vorbis_update_replaygain(&rg_scale);
+            g_mutex_lock(vf_mutex);
+            title = vorbis_generate_title(&vf, filename);
 
-        if (time != -1)
-            time = ov_time_total(&vf, -1) * 1000;
+            if (time != -1)
+                time = ov_time_total(&vf, -1) * 1000;
 
-        g_mutex_unlock(vf_mutex);
-   
-        playback->set_params(playback, title, time, br, samplerate, channels);
+            g_mutex_unlock(vf_mutex);
+        
+            playback->set_params(playback, title, time, br, samplerate, channels);
 
-        timercount = playback->output->output_time();
+            timercount = playback->output->output_time();
 
-        last_section = current_section;
+            last_section = current_section;
          
         }
-}
-
+    } /* main loop */
 
-
-if (!playback->error)
-    playback->output->close_audio();
+    if (!playback->error)
+        playback->output->close_audio();
     /* fall through intentional */
 
     /*this loop makes it not skip the last ~4 seconds, but the playback 
@@ -450,17 +449,17 @@
      *
      * majeru
      */
-while(playback->output->buffer_playing()&& playback->output->buffer_free())
-    g_usleep(50000);
+    while(playback->output->buffer_playing()&& playback->output->buffer_free())
+        g_usleep(50000);
 
 
-play_cleanup:
-g_free(title);
+    play_cleanup:
+    g_free(title);
 
-/*
- * ov_clear closes the stream if its open.  Safe to call on an
- * uninitialized structure as long as we've zeroed it
- */
+    /*
+     * ov_clear closes the stream if its open.  Safe to call on an
+     * uninitialized structure as long as we've zeroed it
+     */
     g_mutex_lock(vf_mutex);
     ov_clear(&vf);
     g_mutex_unlock(vf_mutex);
@@ -506,112 +505,43 @@
 }
 
 /* Make sure you've locked vf_mutex */
+
 static gboolean
-vorbis_update_replaygain(float *scale)
+vorbis_update_replaygain(ReplayGainInfo *rg_info)
 {
     vorbis_comment *comment;
-    char *rg_gain = NULL, *rg_peak_str = NULL;
-    float rg_peak;
+    char *rg_gain = NULL, *rg_peak = NULL;
 
-    if (!vorbis_cfg.use_replaygain && !vorbis_cfg.use_anticlip)
-        return FALSE;
-    if ((comment = ov_comment(&vf, -1)) == NULL)
+    if (rg_info == NULL || (comment = ov_comment(&vf, -1)) == NULL)
         return FALSE;
 
-    *scale = 1.0;
-
-    if (vorbis_cfg.use_replaygain) {
-        if (vorbis_cfg.replaygain_mode == REPLAYGAIN_MODE_ALBUM) {
-            rg_gain =
-                vorbis_comment_query(comment, "replaygain_album_gain", 0);
-            if (!rg_gain)
-                rg_gain = vorbis_comment_query(comment, "rg_audiophile", 0);    /* Old */
-        }
-
-        if (!rg_gain)
-            rg_gain =
-                vorbis_comment_query(comment, "replaygain_track_gain", 0);
-        if (!rg_gain)
-            rg_gain = vorbis_comment_query(comment, "rg_radio", 0); /* Old */
-
-        /* FIXME: Make sure this string is the correct format first? */
-        if (rg_gain)
-            *scale = pow(10., atof(rg_gain) / 20);
-    }
-
-    if (vorbis_cfg.use_anticlip) {
-        if (vorbis_cfg.replaygain_mode == REPLAYGAIN_MODE_ALBUM)
-            rg_peak_str =
-                vorbis_comment_query(comment, "replaygain_album_peak", 0);
+    rg_gain = vorbis_comment_query(comment, "replaygain_album_gain", 0);
+    if (!rg_gain) rg_gain = vorbis_comment_query(comment, "rg_audiophile", 0);    /* Old */
+    rg_info->album_gain = rg_gain != NULL ? atof(rg_gain) : 0.0;
+    
+    rg_gain = vorbis_comment_query(comment, "replaygain_track_gain", 0);
+    if (!rg_gain) rg_gain = vorbis_comment_query(comment, "rg_radio", 0);    /* Old */
+    rg_info->track_gain = rg_gain != NULL ? atof(rg_gain) : 0.0;
+    
+    rg_peak = vorbis_comment_query(comment, "replaygain_album_peak", 0);
+    rg_info->album_peak = rg_peak != NULL ? atof(rg_peak) : 0.0;
+    
+    rg_peak = vorbis_comment_query(comment, "replaygain_track_peak", 0);
+    if (!rg_peak) rg_peak = vorbis_comment_query(comment, "rg_peak", 0);  /* Old */
+    rg_info->track_peak = rg_peak != NULL ? atof(rg_peak) : 0.0;
 
-        if (!rg_peak_str)
-            rg_peak_str =
-                vorbis_comment_query(comment, "replaygain_track_peak", 0);
-        if (!rg_peak_str)
-            rg_peak_str = vorbis_comment_query(comment, "rg_peak", 0);  /* Old */
-
-        if (rg_peak_str) {
-            rg_peak = atof(rg_peak_str);
-            rg_peak = rg_peak == 0.0 ? 1.0 : rg_peak; /* be aware of incorrect formatted strings --eugene */
-        }
-        else
-            rg_peak = 1;
-
-        if (*scale * rg_peak > 1.0)
-            *scale = 1.0 / rg_peak;
-    }
-
-    if (*scale != 1.0 || vorbis_cfg.use_booster) {
-        /* safety */
-        if (*scale > 15.0)
-            *scale = 15.0;
-
-        return TRUE;
-    }
-
-    return FALSE;
+    return TRUE;
 }
 
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
-#  define GET_BYTE1(val) ((val) >> 8)
-#  define GET_BYTE2(val) ((val) & 0xff)
-#else
-#  define GET_BYTE1(val) ((val) & 0xff)
-#  define GET_BYTE2(val) ((val) >> 8)
-#endif
-
 static long
-vorbis_process_replaygain(float **pcm, int samples, int ch,
-                          char *pcmout, float rg_scale)
+vorbis_interleave_buffer(float **pcm, int samples, int ch, float *pcmout)
 {
     int i, j;
-    /* ReplayGain processing */
     for (i = 0; i < samples; i++)
-        for (j = 0; j < ch; j++) {
-            float sample = pcm[j][i] * rg_scale;
-            int value;
-
-            if (vorbis_cfg.use_booster) {
-                sample *= 2;
+        for (j = 0; j < ch; j++)
+            *pcmout++ = pcm[j][i];
 
-                /* hard 6dB limiting */
-                if (sample < -0.5)
-                    sample = tanh((sample + 0.5) / 0.5) * 0.5 - 0.5;
-                else if (sample > 0.5)
-                    sample = tanh((sample - 0.5) / 0.5) * 0.5 + 0.5;
-            }
-
-            value = sample * 32767;
-            if (value > 32767)
-                value = 32767;
-            else if (value < -32767)
-                value = -32767;
-
-            *pcmout++ = GET_BYTE1(value);
-            *pcmout++ = GET_BYTE2(value);
-        }
-
-    return 2 * ch * samples;
+    return ch * samples * sizeof(float);
 }
 
 static void _aud_tuple_associate_string(Tuple *tuple, const gint nfield, const gchar *field, const gchar *string)
@@ -764,7 +694,8 @@
                                         "Jack Moffitt <jack@icecast.org>\n"
                                         "Jorn Baayen <jorn@nl.linux.org>\n"
                                         "Haavard Kvaalen <havardk@xmms.org>\n"
-                                        "Gian-Carlo Pascutto <gcp@sjeng.org>\n\n"
+                                        "Gian-Carlo Pascutto <gcp@sjeng.org>\n"
+                                        "Eugene Zagidullin <e.asphyx@gmail.com>\n\n"
                                         "Visit the Xiph.org Foundation at http://www.xiph.org/\n"),
                                        _("Ok"), FALSE, NULL, NULL);
       g_signal_connect(G_OBJECT(about_window), "destroy",
@@ -788,10 +719,6 @@
     vorbis_cfg.proxy_pass = NULL;
     vorbis_cfg.tag_override = FALSE;
     vorbis_cfg.tag_format = NULL;
-    vorbis_cfg.use_anticlip = FALSE;
-    vorbis_cfg.use_replaygain = FALSE;
-    vorbis_cfg.replaygain_mode = REPLAYGAIN_MODE_TRACK;
-    vorbis_cfg.use_booster = FALSE;
 
     db = aud_cfg_db_open();
     aud_cfg_db_get_int(db, "vorbis", "http_buffer_size",
@@ -809,13 +736,6 @@
     if (!aud_cfg_db_get_string(db, "vorbis", "tag_format",
                                &vorbis_cfg.tag_format))
         vorbis_cfg.tag_format = g_strdup("%p - %t");
-    aud_cfg_db_get_bool(db, "vorbis", "use_anticlip",
-                        &vorbis_cfg.use_anticlip);
-    aud_cfg_db_get_bool(db, "vorbis", "use_replaygain",
-                        &vorbis_cfg.use_replaygain);
-    aud_cfg_db_get_int(db, "vorbis", "replaygain_mode",
-                       &vorbis_cfg.replaygain_mode);
-    aud_cfg_db_get_bool(db, "vorbis", "use_booster", &vorbis_cfg.use_booster);
 
     aud_cfg_db_get_bool(db, NULL, "use_proxy", &vorbis_cfg.use_proxy);
     aud_cfg_db_get_string(db, NULL, "proxy_host", &vorbis_cfg.proxy_host);
--- a/src/vorbis/vorbis.h	Thu Jan 31 13:10:55 2008 +0300
+++ b/src/vorbis/vorbis.h	Sat Feb 02 02:02:15 2008 +0300
@@ -31,20 +31,10 @@
     gchar *save_http_path;
     gboolean tag_override;
     gchar *tag_format;
-    gboolean use_anticlip;
-    gboolean use_replaygain;
-    gint replaygain_mode;
-    gboolean use_booster;
     gboolean title_encoding_enabled;
-    gchar *title_encoding;        
+    gchar *title_encoding;
 } vorbis_config_t;
 
-enum {
-    REPLAYGAIN_MODE_TRACK,
-    REPLAYGAIN_MODE_ALBUM,
-    REPLAYGAIN_MODE_LAST
-};
-
 #define         ENCODING_SEPARATOR      " ,:;|/"
 
 #endif                          /* __VORBIS_H__ */