[Goodies-commits] r5343 - xfburn/trunk/xfburn

David Mohr squisher at xfce.org
Tue Sep 2 06:13:00 CEST 2008


Author: squisher
Date: 2008-09-02 04:13:00 +0000 (Tue, 02 Sep 2008)
New Revision: 5343

Modified:
   xfburn/trunk/xfburn/xfburn-audio-composition.c
   xfburn/trunk/xfburn/xfburn-audio-composition.h
   xfburn/trunk/xfburn/xfburn-burn-audio-cd-composition-dialog.c
Log:
Improved error handling for audio CDs

Modified: xfburn/trunk/xfburn/xfburn-audio-composition.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-audio-composition.c	2008-09-02 00:21:51 UTC (rev 5342)
+++ xfburn/trunk/xfburn/xfburn-audio-composition.c	2008-09-02 04:13:00 UTC (rev 5343)
@@ -32,7 +32,10 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <fcntl.h>
 
+#include <errno.h>
+
 #include <gtk/gtk.h>
 #include <libxfce4util/libxfce4util.h>
 #include <libxfcegui4/libxfcegui4.h>
@@ -86,6 +89,12 @@
 
 typedef enum
 {
+  NOT_ADDING_EXT,
+  NOT_ADDING_FMT,
+} XfburnNotAddingReason;
+
+typedef enum
+{
   AUDIO_COMPOSITION_TYPE_RAW,
 } AudioCompositionEntryType;
 
@@ -159,6 +168,8 @@
 static gboolean thread_add_file_to_list (XfburnAudioComposition * dc, GtkTreeModel * model, const gchar * path, 
                                          GtkTreeIter * iter, GtkTreeIter * insertion, GtkTreeViewDropPosition position);
 static gboolean has_audio_ext (const gchar *path);
+static gboolean valid_wav_headers (char header[44]);
+static gboolean is_valid_wav (const gchar *path);
                                   
 typedef struct
 {
@@ -171,7 +182,7 @@
   gchar *selected_files;
   GtkTreePath *path_where_insert;
 
-  gboolean warned_about_non_audio;
+  XfburnNotAddingReason warned_about_not_adding;
 
   GdkDragContext * dc;
   gboolean success;
@@ -1023,15 +1034,107 @@
   return (strcmp (ext, "wav") == 0);
 }
 
+static gboolean 
+is_valid_wav (const gchar *path)
+{
+  int fd;
+  char header[44];
+  gboolean ret;
+
+  fd = open (path, 0);
+
+  if (fd == -1) {
+    xfce_warn (_("Could not open %s!"), path);
+    return FALSE;
+  }
+
+  read (fd, header, 44);
+
+  ret = valid_wav_headers (header);
+
+  close (fd);
+
+  return ret;
+}
+
+/*
+ * Simple check of .wav headers, most info from
+ * http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
+ *
+ * This check might very well not be complete, but should catch
+ * the most important pieces.
+ * FIXME: eventually replace this with a proper check,
+ * also this works on x86, and does not consider endianness!
+ */
+static gboolean
+valid_wav_headers (char header[44])
+{
+  /* check if first 4 bytes are RIFF or RIFX */
+  if (header[0] == 'R' && header[1] == 'I' && header[2] == 'F') {
+    if (!(header[3] == 'X' || header[3] == 'F')) {
+      g_warning ("File not in riff format");
+      return FALSE;
+    }
+  }
+
+  /* check if bytes 8-11 are WAVE */
+  if (!(header[8] == 'W' && header[9] == 'A' && header[10] == 'V' && header[11] == 'E')) {
+    g_warning ("RIFF file not in WAVE format");
+    return FALSE;
+  }
+
+  /* subchunk starts with 'fmt ' */
+  if (!(header[12] == 'f' && header[13] == 'm' && header[14] == 't' && header[15] == ' ')) {
+    g_warning ("Could not find format subchunk");
+    return FALSE;
+  }
+
+  /* check for PCM format */
+  if (header[16] != 16 || header[20] != 1) {
+    g_warning ("Not in PCM format");
+    return FALSE;
+  }
+
+  /* check for stereo */
+  if (header[22] != 2) {
+    g_warning ("Not in stereo");
+    return FALSE;
+  }
+
+  /* check for 44100 Hz sample rate,
+   * being lazy here and just compare the bytes to what I know they should be */
+  if (header[24] == 0x44 && header[25] == 0xAC && header[26] == 0 && header[27] == 0) {
+    g_warning ("Does not have a sample rate of 44100 Hz");
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
 static void
-notify_not_adding_ext (XfburnAudioComposition * dc, const gchar *path)
+notify_not_adding (XfburnAudioComposition * dc, XfburnNotAddingReason r, const gchar *path)
 {
   XfburnAudioCompositionPrivate *priv = XFBURN_AUDIO_COMPOSITION_GET_PRIVATE (dc);
 
-  g_message ("%s is not a .wav file, not adding it!", path);
-  if (!priv->warned_about_non_audio) {
-    priv->warned_about_non_audio = TRUE;
-    xfce_warn (_("At the moment only .wav files can get added to the compilation!"));
+  if (!(priv->warned_about_not_adding & r)) {
+    const gchar *str;
+
+    priv->warned_about_not_adding |= r;
+
+    switch (r) {
+      case NOT_ADDING_EXT:
+        xfce_warn (_("At the moment only .wav files can get added to the compilation!"));
+        break;
+      case NOT_ADDING_FMT:
+        xfce_warn (_("At the moment only CD quality uncompressed (pcm) .wav files can get added to the compilation!"));
+        break;
+      default:
+        /* This should never happen... */
+        str = _("Unsupported files cannot get added to the compilation!");
+        xfce_warn (str);
+        g_warning (str);
+        break;
+    }
   }
 }
 
@@ -1136,11 +1239,18 @@
     else if (S_ISREG (s.st_mode)) {
       if (!has_audio_ext (path)) {
         gdk_threads_enter ();
-        notify_not_adding_ext (dc, path);
+        notify_not_adding (dc, NOT_ADDING_EXT, path);
         gdk_threads_leave ();
         return FALSE;
       }
 
+      if (!is_valid_wav (path)) {
+        gdk_threads_enter ();
+        notify_not_adding (dc, NOT_ADDING_FMT, path);
+        gdk_threads_leave ();
+        return FALSE;
+      }
+
       gdk_threads_enter ();
       if (insertion != NULL) {
         if (position == GTK_TREE_VIEW_DROP_AFTER)
@@ -1606,7 +1716,7 @@
         priv->full_paths_to_add = g_list_append (priv->full_paths_to_add, full_path);
         ret = TRUE;
       } else {
-        notify_not_adding_ext (composition, full_path);
+        notify_not_adding (composition, NOT_ADDING_EXT, full_path);
       }
 
       file = strtok (NULL, "\n");
@@ -1658,7 +1768,7 @@
           priv->full_paths_to_add = g_list_prepend (priv->full_paths_to_add, full_path);
           ret = TRUE;
         } else {
-          notify_not_adding_ext (composition, full_path);
+          notify_not_adding (composition, NOT_ADDING_EXT, full_path);
         }
       }
       thunar_vfs_path_list_free (vfs_paths);

Modified: xfburn/trunk/xfburn/xfburn-audio-composition.h
===================================================================
--- xfburn/trunk/xfburn/xfburn-audio-composition.h	2008-09-02 00:21:51 UTC (rev 5342)
+++ xfburn/trunk/xfburn/xfburn-audio-composition.h	2008-09-02 04:13:00 UTC (rev 5343)
@@ -58,6 +58,7 @@
   gint pos;
   gchar *artist;
   gchar *title;
+  gboolean swap;
 } XfburnAudioTrack;
 
 GtkType xfburn_audio_composition_get_type (void);

Modified: xfburn/trunk/xfburn/xfburn-burn-audio-cd-composition-dialog.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-burn-audio-cd-composition-dialog.c	2008-09-02 00:21:51 UTC (rev 5342)
+++ xfburn/trunk/xfburn/xfburn-burn-audio-cd-composition-dialog.c	2008-09-02 04:13:00 UTC (rev 5343)
@@ -83,6 +83,7 @@
 static void cb_disc_refreshed (GtkWidget *device_box, XfburnDevice *device, XfburnBurnAudioCdCompositionDialog * dialog);
 static void cb_dialog_response (XfburnBurnAudioCdCompositionDialog * dialog, gint response_id,
                                 XfburnBurnAudioCdCompositionDialogPrivate * priv);
+static gboolean needs_swap (char header[44]);
 
 /* globals */
 static XfceTitledDialogClass *parent_class = NULL;
@@ -490,59 +491,13 @@
   burn_write_opts_free (burn_options);
 }
 
-/*
- * Simple check of .wav headers, most info from
- * http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
- *
- * This check might very well not be complete, but should catch
- * the most important pieces.
- * FIXME: eventually replace this with a proper check,
- * also this works on x86, and does not consider endianness!
- */
 static gboolean
-valid_wav_headers (char header[44], gboolean *swap)
+needs_swap (char header[44])
 {
-  *swap = FALSE;
-  /* check if first 4 bytes are RIFF or RIFX */
-  if (header[0] == 'R' && header[1] == 'I' && header[2] == 'F') {
-    if (header[3] == 'X')
-      *swap = TRUE;
-    else if (header[3] != 'F')
-      return FALSE;
-  }
-
-  /* check if bytes 8-11 are WAVE */
-  if (!(header[8] == 'W' && header[9] == 'A' && header[10] == 'V' && header[11] == 'E')) {
-    g_warning ("RIFF file not in WAVE format");
+  if (header[0] == 'R' && header[1] == 'I' && header[2] == 'F' && header[3] == 'X')
+    return TRUE;
+  else 
     return FALSE;
-  }
-
-  /* subchunk starts with 'fmt ' */
-  if (!(header[12] == 'f' && header[13] == 'm' && header[14] == 't' && header[15] == ' ')) {
-    g_warning ("Could not find format subchunk");
-    return FALSE;
-  }
-
-  /* check for PCM format */
-  if (header[16] != 16 || header[20] != 1) {
-    g_warning ("Not in PCM format");
-    return FALSE;
-  }
-
-  /* check for stereo */
-  if (header[22] != 2) {
-    g_warning ("Not in stereo");
-    return FALSE;
-  }
-
-  /* check for 44100 Hz sample rate,
-   * being lazy here and just compare the bytes to what I know they should be */
-  if (header[24] == 0x44 && header[25] == 0xAC && header[26] == 0 && header[27] == 0) {
-    g_warning ("Does not have a sample rate of 44100 Hz");
-    return FALSE;
-  }
-
-  return TRUE;
 }
 
 static void
@@ -556,8 +511,9 @@
   struct burn_source **srcs;
   int *fds;
   int n_tracks;
-  int i;
+  int i,j;
   GSList *track_list;
+  gboolean abort = FALSE;
 
   struct burn_drive_info *drive_info = NULL;
 
@@ -579,30 +535,46 @@
   track_list = params->tracks;
   for (i=0; i<n_tracks; i++) {
     char header[44];
-    gboolean swap = FALSE;
     XfburnAudioTrack *atrack = track_list->data;
 
     fds[i] = open (atrack->inputfile, 0);
-    if (fds[i] == -1)
-      g_error ("Could not open %s!", atrack->inputfile);
+    if (fds[i] == -1) {
+      gchar *str;
+      str = g_strdup_printf (_("Could not open %s!"), atrack->inputfile);
+      xfburn_progress_dialog_burning_failed (XFBURN_PROGRESS_DIALOG (dialog_progress), str);
+      g_free (str);
+      abort = TRUE;
+      break;
+    }
 
+    /* perform a read so that libburn skips the wav header */
     read (fds[i], header, 44);
 
     srcs[i] = burn_fd_source_new (fds[i], -1 , 0);
-    if (srcs[i] == NULL)
-      g_error ("Could not create burn_source from %s!", atrack->inputfile);
+    if (srcs[i] == NULL) {
+      gchar *str;
+      str = g_strdup_printf (_("Could not create burn_source from %s!"), atrack->inputfile);
+      xfburn_progress_dialog_burning_failed (XFBURN_PROGRESS_DIALOG (dialog_progress), str);
+      g_free (str);
+      close(fds[i]);
+      abort = TRUE;
+      break;
+    }
 
     tracks[i] = burn_track_create ();
     
-    if (burn_track_set_source (tracks[i], srcs[i]) != BURN_SOURCE_OK)
-      g_error ("Could not add source to track!");
+    if (burn_track_set_source (tracks[i], srcs[i]) != BURN_SOURCE_OK) {
+      gchar *str;
+      str = g_strdup_printf (_("Could not add source to track!"));
+      xfburn_progress_dialog_burning_failed (XFBURN_PROGRESS_DIALOG (dialog_progress), str);
+      g_free (str);
+      close(fds[i]);
+      burn_source_free (srcs[i]);
+      abort = TRUE;
+      break;
+    }
 
-    /* simple check of wav headers, will hopefully get replaced
-     * later by gstreamer */
-    if (!valid_wav_headers (header, &swap))
-      g_error ("%s is not a .wav file, or has the wrong format!", atrack->inputfile);
-
-    if (swap)
+    if (needs_swap (header))
       burn_track_set_byte_swap (tracks[i], TRUE);
 
     burn_track_define_data (tracks[i], 0, 0, 1, BURN_AUDIO);
@@ -616,17 +588,19 @@
   */
 
 
-  if (!xfburn_device_grab (params->device, &drive_info)) {
-    xfburn_progress_dialog_burning_failed (XFBURN_PROGRESS_DIALOG (dialog_progress), _("Unable to grab drive"));
-  } else {
-    thread_burn_prep_and_burn (params, drive_info->drive, disc, session, n_tracks, tracks);
-    burn_drive_release (drive_info->drive, params->eject ? 1 : 0);
+  if (!abort) {
+    if (!xfburn_device_grab (params->device, &drive_info)) {
+      xfburn_progress_dialog_burning_failed (XFBURN_PROGRESS_DIALOG (dialog_progress), _("Unable to grab drive"));
+    } else {
+      thread_burn_prep_and_burn (params, drive_info->drive, disc, session, n_tracks, tracks);
+      burn_drive_release (drive_info->drive, params->eject ? 1 : 0);
+    }
   }
 
-  for (i=0; i<n_tracks; i++) {
-    burn_track_free (tracks[i]);
-    burn_source_free (srcs[i]);
-    close (fds[i]);
+  for (j=0; j<i; j++) {
+    burn_track_free (tracks[j]);
+    burn_source_free (srcs[j]);
+    close (fds[j]);
   }
   g_free (srcs);
   g_free (tracks);




More information about the Goodies-commits mailing list