Logo Search packages:      
Sourcecode: xcfa version File versions

replaygain.c

 /*
 * file      : replaygain.c
 * project   : xcfa
 * with      : Gtk-2
 *
 * copyright : (C) 2003,2004,2005,2006,2007,2008,2009 by Claude Bulin
 *
 * xcfa - GTK+ implementation of the GNU shell command
 * GNU General Public License
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * OLD ADRESS:
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * NEW ADRESS:
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 */


#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

#include "support.h"

#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "global.h"
#include "file.h"
#include "utils.h"
#include "options.h"
#include "win_control.h"
#include "win_norm_replay.h"
#include "replaygain.h"



/*
CORRECTION ALGO REPLAYGAIN
--------------------------

IL FAUT TRAVAILLER SUR DES ENSEMBLES:

EFFACER: Ensemble SOURCE

ALBUM:   Ensemble DESTINATION
PISTE:

ACTION SUR LA SOURCES         FileAction.bool_ReplaygainClear    = file_get_bool_ReplaygainClear_file ();
ACTION SUR LA SOURCES         FileAction.bool_normalize          = file_get_bool_normalize_file ();
ACTION SUR LA SOURCES         FileAction.bool_NormalizeCollectif = file_get_bool_NormalizeCollectif_file ();
CREATION DESTINATION          FileAction.bool_conversion         = file_get_bool_conversion_file ();
ACTION SUR LA DESTINATION     FileAction.bool_ReplaygainApply    = file_get_bool_ReplaygainApply_file ();
*/


/*
*---------------------------------------------------------------------------
* VARIABLES
*---------------------------------------------------------------------------
*/
typedef enum {
      _RPG_NONE_ = 0,         /* Aucune action */
      _RPG_SET_FILE_          /* Fichier en cours de traitement */
} RPG_ETAT;

typedef struct {
      gboolean         bool_etat;
      GString         *MessUser;
      
      gint             NbrElementsInList;
      gint             ElementActif;
      double           total_percent;
      
      pthread_t        nmr_tid;
      guint            handler_timeout;
      gboolean         bool_thread_end;

      gboolean         bool_compteur;
      gint             pass_conv;
      
      gboolean         bool_update;

      TYPE_REPLAYGAIN  type_replaygain;
} RPG;

RPG rpg;

typedef enum {
      MP3GAIN = 0,
      METAFLAC,
      WVGAIN,
      VORBISGAIN
} RPG_TYPE;

typedef struct {
      ETAT_REPLAYGAIN *ReplayGain;
} RPG_LIST_ETAT;
      
#define MAX_RPG_SIZE_BUF 1024



/*
*---------------------------------------------------------------------------
* GET LIST OF TO SET:
*---------------------------------------------------------------------------
*     TYPE
*           MP3GAIN
*           METAFLAC
*           WVGAIN
*           VORBISGAIN
*---------------------------------------------------------------------------
*     ACTION
*           EFFACER
*           ALBUM
*           PISTE
*---------------------------------------------------------------------------
*/
void replaygain_set_list (RPG_TYPE rpg_type, ETAT_REPLAYGAIN rpg_action)
{
      GList            *list = NULL;
      GList            *ListProg = NULL;
      GList            *ListEtat = NULL;
      DETAIL           *detail = NULL;
      FIC              *fic = NULL;
      gchar            *Ptr = NULL;
      ETAT_REPLAYGAIN  *PtrReplayGain = NULL;
      gboolean          BoolList = FALSE;
      
      if (rpg.bool_thread_end == TRUE) return;
      
GDK_THREADS_ENTER();
      rpg.MessUser = g_string_new (NULL);
      /* Entete global */
      list = g_list_append (list, g_strdup ("nice"));
      list = g_list_append (list, g_strdup ("-n"));
      list = g_list_append (list, g_strdup (conv.valuenice));
      
      /* Entetes particuliers */
      switch (rpg_type) {
      case MP3GAIN :
            list = g_list_append (list, g_strdup ("mp3gain"));
            g_string_append_printf (rpg.MessUser, "<i><b>MP3, mp3gain</b>");
            switch (rpg_action) {
            case RPG_NONE :
            case RPG_ATTENTE :
                  break;
            case RPG_EFFACER :
                  list = g_list_append (list, g_strdup ("-s"));
                  list = g_list_append (list, g_strdup ("d"));
                  g_string_append_printf (rpg.MessUser, ", <b>EFFACER</b></i>");
                  break;
            case RPG_ALBUM :
                  list = g_list_append (list, g_strdup ("-a"));
                  list = g_list_append (list, g_strdup ("-p"));
                  list = g_list_append (list, g_strdup ("-c"));
                  list = g_list_append (list, g_strdup ("-f"));
                  list = g_list_append (list, g_strdup ("-T"));
                  g_string_append_printf (rpg.MessUser, ", <b>ALBUM</b></i>");
                  break;
            case RPG_PISTE :
                  list = g_list_append (list, g_strdup ("-r"));
                  list = g_list_append (list, g_strdup ("-p"));
                  list = g_list_append (list, g_strdup ("-c"));
                  list = g_list_append (list, g_strdup ("-f"));
                  list = g_list_append (list, g_strdup ("-T"));
                  g_string_append_printf (rpg.MessUser, ", <b>PISTE</b></i>");
                  break;
            }
            break;
      case METAFLAC :
            list = g_list_append (list, g_strdup ("metaflac"));
            g_string_append_printf (rpg.MessUser, "<i><b>FLAC, metaflac</b>");
            switch (rpg_action) {
            case RPG_NONE :
            case RPG_ATTENTE :
                  break;
            case RPG_EFFACER :
                  list = g_list_append (list, g_strdup ("--remove-replay-gain"));
                  g_string_append_printf (rpg.MessUser, ", <b>EFFACER</b></i>");
                  break;
            case RPG_ALBUM :
                  list = g_list_append (list, g_strdup ("--add-replay-gain"));
                  g_string_append_printf (rpg.MessUser, ", <b>ALBUM</b></i>");
                  break;
            case RPG_PISTE :
                  /* NONE */
                  break;
            }
            break;
      case WVGAIN :
            list = g_list_append (list, g_strdup ("wvgain"));
            g_string_append_printf (rpg.MessUser, "<i><b>WAVPACK, wvgain</b>");
            switch (rpg_action) {
            case RPG_NONE :
            case RPG_ATTENTE :
                  break;
            case RPG_EFFACER :
                  list = g_list_append (list, g_strdup ("-c"));
                  g_string_append_printf (rpg.MessUser, ", <b>EFFACER</b></i>");
                  break;
            case RPG_ALBUM :
                  list = g_list_append (list, g_strdup ("-a"));
                  g_string_append_printf (rpg.MessUser, ", <b>ALBUM</b></i>");
                  break;
            case RPG_PISTE :
                  g_string_append_printf (rpg.MessUser, ", <b>PISTE</b></i>");
                  break;
            }
            break;
      case VORBISGAIN :
            list = g_list_append (list, g_strdup ("vorbisgain"));
            g_string_append_printf (rpg.MessUser, "<i><b>OGG, vorbisgain</b>");
            switch (rpg_action) {
            case RPG_NONE :
            case RPG_ATTENTE :
                  break;
            case RPG_EFFACER :
                  list = g_list_append (list, g_strdup ("-c"));
                  g_string_append_printf (rpg.MessUser, ", <b>EFFACER</b></i>");
                  break;
            case RPG_ALBUM :
                  list = g_list_append (list, g_strdup ("-a"));
                  g_string_append_printf (rpg.MessUser, ", <b>ALBUM</b></i>");
                  break;
            case RPG_PISTE :
                  g_string_append_printf (rpg.MessUser, ", <b>PISTE</b></i>");
                  break;
            }
            break;
      }

      /* -- RECHERCHE DES NOMS DE FICHIERS QUI SERONT AJOUTES EN FIN DE LISTE */
      ListProg = g_list_first (entetefile);
      while (ListProg) {
            if ((detail = (DETAIL *)ListProg->data)) {
                  
                  /* Test d'entree */
                  if (!detail->type_infosong_file_is == FILE_IS_OGG ||
                      !detail->type_infosong_file_is == FILE_IS_MP3 ||
                      !detail->type_infosong_file_is == FILE_IS_FLAC ||
                      !detail->type_infosong_file_is == FILE_IS_WAVPACK) {
                      
                        ListProg = g_list_next (ListProg);
                        continue;
                  }
                  
                  if ((fic = (FIC *)detail->fic) && fic->Etat_ReplayGain == rpg_action) {
                        /* VORBISGAIN */
                        if (detail->type_infosong_file_is == FILE_IS_OGG && rpg_type == VORBISGAIN) {
                              
                              /* fic->Etat_Normalise = NORM_SCAN_ACTIF; */
                              BoolList = TRUE;
                              
                              /*
                              if (type_replaygain == _CLEAR_REPLAYGAIN_)
                                    ACTION SUR LA SOURCE
                              else if (type_replaygain ==  _APPLY_REPLAYGAIN_)
                                    ACTION SUR LA DESTINATION
                              */
                              list = g_list_append (list, g_strdup (detail->namefile));
                              
                              /* Get pointer Etat Flag */
                              ListEtat = g_list_append (ListEtat, &fic->Etat_ReplayGain);
                              
                              if (fic->EtatTrash == FILE_TRASH_OK) fic->EtatTrash = FILE_TRASH_VERIF_OK;
                              
                              rpg.ElementActif ++;
                        }
                        /* MP3GAIN */
                        else if (detail->type_infosong_file_is == FILE_IS_MP3 && rpg_type == MP3GAIN) {
                        
                              /* fic->Etat_Normalise = NORM_SCAN_ACTIF; */
                              BoolList = TRUE;
                              list = g_list_append (list, g_strdup (detail->namefile));
                              
                              /* Get pointer Etat Flag */
                              ListEtat = g_list_append (ListEtat, &fic->Etat_ReplayGain);
                              
                              if (fic->EtatTrash == FILE_TRASH_OK) fic->EtatTrash = FILE_TRASH_VERIF_OK;
                              
                              rpg.ElementActif ++;
                        }
                        /* METAFLAC */
                        else if (detail->type_infosong_file_is == FILE_IS_FLAC && rpg_type == METAFLAC) {
                              /* PISTE -> NONE */
                              BoolList = TRUE;
                              list = g_list_append (list, g_strdup (detail->namefile));
                              
                              /* Get pointer Etat Flag */
                              ListEtat = g_list_append (ListEtat, &fic->Etat_ReplayGain);
                              
                              if (fic->EtatTrash == FILE_TRASH_OK) fic->EtatTrash = FILE_TRASH_VERIF_OK;
                              
                              rpg.ElementActif ++;
                        }
                        /* WVGAIN */
                        else if (detail->type_infosong_file_is == FILE_IS_WAVPACK && rpg_type == WVGAIN) {
                              BoolList = TRUE;
                              list = g_list_append (list, g_strdup (detail->namefile));
                              
                              /* Get pointer Etat Flag */
                              ListEtat = g_list_append (ListEtat, &fic->Etat_ReplayGain);
                              
                              if (fic->EtatTrash == FILE_TRASH_OK) fic->EtatTrash = FILE_TRASH_VERIF_OK;
                              
                              rpg.ElementActif ++;
                        }
                  }
            }
            ListProg = g_list_next (ListProg);
      }
GDK_THREADS_LEAVE();
      
      /* Test application de ReplayGain */
      if (BoolList == TRUE) {

            /* Appel au ReplayGain */
            rpg.bool_compteur = TRUE;
            rpg.bool_etat = TRUE;
            
            conv.ArgConv = conv_alloc_arg (list);
            conv_exec (FALSE, REPLAYGAIN, list, rpg.MessUser->str);
            g_free (conv.ArgConv);
            conv.ArgConv = NULL;
            
            rpg.bool_compteur = FALSE;

            /* Set update */
            ListProg = g_list_first (ListEtat);
            while (ListProg) {
                  if ((PtrReplayGain = (ETAT_REPLAYGAIN *)ListProg->data)) {
                        *PtrReplayGain = RPG_ATTENTE;
                  }
                  ListProg->data = NULL;
                  ListProg = g_list_next (ListProg);
            }
            g_list_free (ListEtat);
            ListEtat = NULL;
            rpg.bool_update = TRUE;
      }
      
      /* suppression des elements de la liste */
      ListProg = g_list_first (list);
      while (ListProg) {
            if ((Ptr = (gchar *)ListProg->data)) {
                  g_free (Ptr);
                  Ptr = NULL;
            }
            ListProg->data = NULL;
            ListProg = g_list_next (ListProg);
      }
      g_list_free (list);
      list = NULL;
}

/*
*---------------------------------------------------------------------------
* TIMEOUT & THREAD
*---------------------------------------------------------------------------
*/
static gint replaygain_timeout (gpointer data)
{
      if (WinNormReplay_is_get_close () == TRUE) {
            conv_stop_conversion ();
      }
      
      if (conv.bool_percent_conv == TRUE) {
            rpg.total_percent = (double)rpg.ElementActif / (double)rpg.NbrElementsInList;
            WinNormReplay_set_data_progressBar (rpg.total_percent);
      }

      if (rpg.bool_update == TRUE) {
            rpg.bool_update = FALSE;
            file_pixbuf_update_glist_file ();
            file_set_flag_buttons_audio_file ();
            return (TRUE);
      }
      
      if (rpg.bool_etat == TRUE) {
            
            /*WinNormReplay_set_etat (rpg.MessUser->str);*/
            g_string_free (rpg.MessUser, TRUE);
            rpg.MessUser = NULL;
            
            rpg.bool_etat = FALSE;
      }
      
      if (rpg.bool_compteur == TRUE) {
            
            /*
            gchar *str = NULL;
            gchar *spinner="|/-\\";
            
            str = g_strdup_printf ("<b>En cours: %d / %d   %c</b>", rpg.ElementActif, rpg.NbrElementsInList, spinner[rpg.pass_conv++%4]);
            WinNormReplay_set_compteur (str);
            g_free (str);
            str = NULL;
            */
            gchar *str = NULL;
            gchar *spinner="|/-\\";
            gchar *Ptr = NULL;
            gchar  foo [ 2 ];
            
            foo [ 0 ] = spinner[rpg.pass_conv++%4];
            foo [ 1 ] = '\0';
            Ptr = utils_convert_string (foo, TRUE);
            
            str = g_strdup_printf (_("<b>En cours: %d sur %d   %s</b>"),
                              rpg.ElementActif,
                              rpg.NbrElementsInList,
                              Ptr);
            WinNormReplay_set_compteur (str);
            g_free (str);
            str = NULL;
            g_free (Ptr);
            Ptr = NULL;
            
            return (TRUE);
      }
      
      if (rpg.bool_thread_end == TRUE) {
            WinNormReplay_close ();
            fileaction_set_end ();
            gtk_timeout_remove (rpg.handler_timeout);
            conv_set_struct_not_used ();
      }
      
      return (TRUE);
}

static void replaygain_thread (void *arg)
{
      rpg.bool_thread_end = FALSE;
      
      if (rpg.type_replaygain == _CLEAR_REPLAYGAIN_) {
            
            replaygain_set_list (MP3GAIN, RPG_EFFACER);
            replaygain_set_list (METAFLAC, RPG_EFFACER);
            replaygain_set_list (WVGAIN, RPG_EFFACER);
            replaygain_set_list (VORBISGAIN, RPG_EFFACER);
      }
      else if (rpg.type_replaygain ==  _APPLY_REPLAYGAIN_) {
            
            replaygain_set_list (MP3GAIN, RPG_PISTE);
            replaygain_set_list (MP3GAIN, RPG_ALBUM);
            replaygain_set_list (METAFLAC, RPG_ALBUM);
            replaygain_set_list (WVGAIN, RPG_PISTE);
            replaygain_set_list (WVGAIN, RPG_ALBUM);
            replaygain_set_list (VORBISGAIN, RPG_PISTE);
            replaygain_set_list (VORBISGAIN, RPG_ALBUM);
      }
      
      rpg.bool_thread_end = TRUE;
      pthread_exit(0);
}

/*
*---------------------------------------------------------------------------
* GET LIST REPLAYGAIN -- CLEAR & APPLY
*---------------------------------------------------------------------------
*/    
void replaygain_get_list_Clear (void)
{
      GList   *list = NULL;
      DETAIL  *detail = NULL;
      FIC     *fic = NULL;

      /*PRINT_FUNC_LF();*/

      list = g_list_first (entetefile);
      while (list) {
            if ((detail = (DETAIL *)list->data)) {
                  if (detail->type_infosong_file_is == FILE_IS_OGG ||
                        detail->type_infosong_file_is == FILE_IS_MP3 ||
                        detail->type_infosong_file_is == FILE_IS_FLAC ||
                        detail->type_infosong_file_is == FILE_IS_WAVPACK) {
                        if ((fic = (FIC *)detail->fic)) {
                              if (fic->Etat_ReplayGain == RPG_EFFACER) {
                                    rpg.NbrElementsInList ++;
                              }
                        }
                  }
            }
            list = g_list_next (list);
      }
}

void replaygain_get_list_Apply (void)
{
      GList   *list = NULL;
      DETAIL  *detail = NULL;
      FIC     *fic = NULL;

      /*PRINT_FUNC_LF();*/

      list = g_list_first (entetefile);
      while (list) {
            if ((detail = (DETAIL *)list->data)) {
                  if (detail->type_infosong_file_is == FILE_IS_OGG ||
                        detail->type_infosong_file_is == FILE_IS_MP3 ||
                        detail->type_infosong_file_is == FILE_IS_FLAC ||
                        detail->type_infosong_file_is == FILE_IS_WAVPACK) {
                        if ((fic = (FIC *)detail->fic)) {
                              if (fic->Etat_ReplayGain != RPG_EFFACER && fic->Etat_ReplayGain != RPG_ATTENTE) {
                                    rpg.NbrElementsInList ++;
                              }
                        }
                  }
            }
            list = g_list_next (list);
      }
}

/*
*---------------------------------------------------------------------------
* ACTION
*---------------------------------------------------------------------------
*/
void replaygain_action (TYPE_REPLAYGAIN type_replaygain)
{
      g_snprintf (conv.valuenice ,    4, "%d", options_get_val_nice ());
      
      rpg.bool_thread_end = FALSE;
      rpg.bool_etat = FALSE;
      rpg.NbrElementsInList = 0;
      rpg.ElementActif = 0;
      rpg.bool_compteur = FALSE;
      rpg.pass_conv = -1;
      rpg.bool_update = FALSE;
      rpg.type_replaygain = type_replaygain;
      
      if (type_replaygain == _CLEAR_REPLAYGAIN_)       replaygain_get_list_Clear ();
      else if (type_replaygain ==  _APPLY_REPLAYGAIN_) replaygain_get_list_Apply ();

      conv_reset_struct ();
      
      WinNormReplay_Create ("ReplayGain");
      WinNormReplay_reset_progressBar ();
      rpg.handler_timeout = gtk_timeout_add (100, replaygain_timeout, 0);
      pthread_create (&rpg.nmr_tid, NULL ,(void *)replaygain_thread, (void *)NULL);
}





Generated by  Doxygen 1.6.0   Back to index