/* flac.c * Copyright (C) 2004, 2005 Sylvain Cresto * * This file is part of graveman! * * graveman! 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, or * (at your option) any later version. * * graveman! 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 program; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * * URL: http://www.nongnu.org/graveman/ * */ #include "graveman.h" #ifdef ENABLE_FLAC #include #define FLAC_ERROR_OPEN "An error occurred opening the input file" #define FLAC_ERROR "ERROR" /* extraction de la duree d'un fichier flac */ gboolean getFlacInfo(gchar *Afilename, guint32 *Alength, GError **Aerror) { gboolean Lstatus = TRUE; FLAC__StreamMetadata *Lblock; FLAC__Metadata_Chain *Lchain = FLAC__metadata_chain_new(); FLAC__Metadata_Iterator *Literator = FLAC__metadata_iterator_new(); (*Alength)=0; if (! Lchain) { g_set_error(Aerror, GRAVEMAN_ERROR, _ERR_OUTOFMEMORY, _("FLAC: out of memory !"), Afilename); return FALSE; } if(!FLAC__metadata_chain_read(Lchain, Afilename)) { g_set_error(Aerror, GRAVEMAN_ERROR, _ERR_INAPPROPRIATE_DATA, _("%s is not a valid .flac file !"), Afilename); return FALSE; } FLAC__metadata_iterator_init(Literator, Lchain); Lblock = FLAC__metadata_iterator_get_block(Literator); if (Lblock->data.stream_info.sample_rate) { (*Alength) = Lblock->data.stream_info.total_samples / Lblock->data.stream_info.sample_rate; } FLAC__metadata_iterator_delete(Literator); FLAC__metadata_chain_delete(Lchain); return TRUE; } /* transformation fichier son vers piste audio */ /* pour le moment on ne fais pas grand chose dans le callback ... * plus tard il y aura une meilleur gestion des erreurs ! */ gboolean flac_callback(GIOChannel *Astd, GIOCondition Acond, gpointer Adata) { GIOStatus Lstatus; Tgrave *Lg = (Tgrave *)Adata; gchar *Lbuffer = NULL; gchar *s; gint *Lcont = (gint *) sc_grave_get_data(Lg, "cont"); /* on traite encore des donnees ? */ GError **Lerreur = (GError **) sc_grave_get_data(Lg, "gerror"); /* pointeur erreur */ /* fin du callback lorsque l'on recoi un signal comme quoi le pipe est ferme */ if (Acond == G_IO_HUP || Acond == G_IO_ERR) { *Lcont = 1; return FALSE; } Lstatus = g_io_channel_read_line(Astd, &Lbuffer, NULL, NULL, NULL); _DEB("%s\n", Lbuffer); if (Lbuffer) { if (!strncmp(Lbuffer, FLAC_ERROR_OPEN, strlen(FLAC_ERROR_OPEN))) { g_set_error(Lerreur, GRAVEMAN_ERROR, _ERR_FLAC, _("An error occurred opening the input FLAC file, disk full ?")); g_free(Lbuffer); return FALSE; } else if (strstr(Lbuffer, FLAC_ERROR)) { g_set_error(Lerreur, GRAVEMAN_ERROR, _ERR_FLAC, s+strlen(FLAC_ERROR)); g_free(Lbuffer); return FALSE; } } g_free(Lbuffer); return TRUE; } gboolean FlacToWav(Tgrave *Ag, gchar *AFichier, gchar *AVers, GError **Aerror) { gchar *Lcommandline; gchar **Lcmd; gint *Lpid = (gint *) sc_grave_get_data(Ag, "pid"); gboolean *Labort = (gboolean *)sc_grave_get_data(Ag, "gabort"); gint *Lcont = (gint *) sc_grave_get_data(Ag, "cont"); gint g_out, g_err, Lnbrarg; gchar *Lfic; gchar *Lvers; GIOChannel *Lcom, *Lcomerr; GIOStatus Lstatus; gboolean Lbolstatus; guint Lcomevent, Lcomerrevent; Lfic = sc_strescape(AFichier); Lvers = sc_strescape(AVers); Lcommandline = g_strdup_printf("%s %s -d \"%s\" -o \"%s\"", conf_get_string("flac"), conf_get_string("flacpara"), Lfic, Lvers); g_free(Lvers); g_free(Lfic); _DEB("execution [%s]\n", Lcommandline); Lstatus = g_shell_parse_argv(Lcommandline, &Lnbrarg, &Lcmd, Aerror); g_free(Lcommandline); if (Lstatus == FALSE) { return FALSE; } Lbolstatus = g_spawn_async_with_pipes(NULL, Lcmd, NULL, /* env argument */ (GSpawnFlags ) (G_SPAWN_DO_NOT_REAP_CHILD), NULL, NULL, Lpid, NULL, &g_out, &g_err, Aerror); g_strfreev(Lcmd); if (Lbolstatus == FALSE) { g_warning("ERROR EXECUTION !\n"); return FALSE; } Lcom = g_io_channel_unix_new( g_out ); g_io_channel_set_encoding (Lcom, NULL, NULL); g_io_channel_set_flags( Lcom, G_IO_FLAG_NONBLOCK, NULL ); Lcomevent = g_io_add_watch (Lcom, (G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI), flac_callback, Ag); Lcomerr = g_io_channel_unix_new( g_err ); g_io_channel_set_encoding (Lcomerr, NULL, NULL); g_io_channel_set_flags( Lcomerr, G_IO_FLAG_NONBLOCK, NULL ); Lcomerrevent = g_io_add_watch (Lcomerr, (G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI), flac_callback, Ag); while (*Lcont > 1 && *Labort == FALSE) { gtk_main_iteration(); } exit_prog(*Lpid, *Labort, Aerror, NULL); g_source_remove(Lcomerrevent); g_source_remove(Lcomevent); g_io_channel_shutdown(Lcomerr, FALSE, NULL); g_io_channel_unref(Lcomerr); g_io_channel_shutdown(Lcom, FALSE, NULL); g_io_channel_unref(Lcom); g_spawn_close_pid(*Lpid); *Lpid = 0; /* l'utilisateur a annule l'operation */ if (*Labort==TRUE || *Aerror) return FALSE; return TRUE; } #endif /* * vim:et:ts=8:sts=2:sw=2 */