[gimp-gap/gap-2-8] use g_spawn_sync to call external audio cnverter sox (for windows compatibility).



commit 359308ba201622ec69a16d94c869726fd0824edf
Author: Wolfgang Hofer <wolfgangh svn gnome org>
Date:   Sun Jan 12 09:26:25 2014 +0100

    use g_spawn_sync to call external audio cnverter sox (for windows compatibility).

 ChangeLog           |   20 ++++
 gap/gap_story_sox.c |  266 ++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 271 insertions(+), 15 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index e03e0b3..2d777ee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2014-01-12 Wolfgang Hofer <hof gimp org>
+
+- audio resample via external tool (sox) did not work in WINDOWS environment.
+  The old code was restricted to Unix only.
+  Fixed the parameter substitution and use g_spawn_sync for the external audio converter call
+  that now shall work on other operating systems than unix.
+  
+  tests on windows with sox as external converter were successful,
+  but only in case when the external converter was configured with
+  the full absolute path.
+  sox is available on Linux, Windows, and MacOSX
+  see http://sox.sourceforge.net/
+
+  (note that this fix was already done 2013-01-16 in my local 
+   environment and already mentioned in the commit message on that date
+   .. but the file gap/gap_story_sox.c was forgotten to be added in the commit
+   .. now i recognized that mistake and can provide the fix)
+
+  * gap/gap_story_sox.c
+
 2013-11-09 Wolfgang Hofer <hof gimp org>
   - fixed comment lines 
     (related to #711402)
diff --git a/gap/gap_story_sox.c b/gap/gap_story_sox.c
index 95fd365..1a5caa5 100644
--- a/gap/gap_story_sox.c
+++ b/gap/gap_story_sox.c
@@ -1,5 +1,8 @@
 /* gap_story_sox.c
- *    Audio resampling Modules based on calls to UNIX Utility Program sox
+ *    Audio resampling Modules based on calls to external audio converter program.
+ *    Default for the external converter is the Utility Program sox
+ *    (that is available on Linux, Windows, and MacOSX
+ *     see http://sox.sourceforge.net/ )
  */
 /*
  * Copyright
@@ -22,6 +25,7 @@
 #include <config.h>
 
 #include <stdlib.h>
+#include <string.h>
 
 #include <glib/gstdio.h>
 
@@ -32,6 +36,76 @@
 
 extern int gap_debug;  /* 1 == print debug infos , 0 dont print debug infos */
 
+
+/* --------------------------------------------
+ * p_allocate_and_substitute_calling_parameters
+ * --------------------------------------------
+ */
+char *
+p_allocate_and_substitute_calling_parameters(char *in_audiofile
+               ,char *out_audiofile
+               ,gint32 samplerate
+               ,char *util_sox_options)
+{
+  char *optPtr;
+  char *paramString;
+  char *paramStringNew;
+
+  paramString = g_strdup("");
+  if (util_sox_options != NULL)
+  {
+    optPtr = util_sox_options;
+
+    while(*optPtr != '\0')
+    {
+      if (strncmp("$IN", optPtr, strlen("$IN")) == 0)
+      {
+        paramStringNew = g_strdup_printf("%s%s"
+                      , paramString
+                      , in_audiofile               /* input audio file */
+                      );
+        g_free(paramString);
+        paramString = paramStringNew;
+        optPtr += strlen("$IN");
+      }
+      else if (strncmp("$OUT", optPtr, strlen("$OUT")) == 0)
+      {
+        paramStringNew = g_strdup_printf("%s%s"
+                      , paramString
+                      , out_audiofile              /* output audio file (tmp 16-bit wav file) */
+                      );
+        g_free(paramString);
+        paramString = paramStringNew;
+        optPtr += strlen("$OUT");
+      }
+      else if (strncmp("$RATE", optPtr, strlen("$RATE")) == 0)
+      {
+        paramStringNew = g_strdup_printf("%s%d"
+                      , paramString
+                      , (int)samplerate
+                      );
+        g_free(paramString);
+        paramString = paramStringNew;
+        optPtr += strlen("$RATE");
+      }
+      else
+      {
+        paramStringNew = g_strdup_printf("%s%c"
+                      , paramString
+                      , *optPtr
+                      );
+        g_free(paramString);
+        paramString = paramStringNew;
+        optPtr++;
+      }
+    }
+  }
+
+  return (paramString);
+
+}  /* end p_allocate_and_substitute_calling_parameters */
+
+
 /* --------------------------------
  * gap_story_sox_exec_resample
  * --------------------------------
@@ -44,36 +118,198 @@ gap_story_sox_exec_resample(char *in_audiofile
                ,char *util_sox_options
                )
 {
-  gchar *l_cmd;
+  gchar *l_cmd_argv[50];
+  gchar *paramString;
+  gchar *l_util_sox;
+  gchar *l_util_sox_options;
+  int    l_ret;
+  int    l_arg_idx;
+  char  *l_ptr;
+  char  *l_split_args_string;
+
+
 
   if(util_sox == NULL)
   {
-    util_sox = GAP_STORY_SOX_DEFAULT_UTIL_SOX;
+     if(gap_debug)
+     {
+       printf("util_sox is NULL\n");
+     }
+     l_util_sox = gimp_gimprc_query("video_encode_com_util_sox");
+     if(l_util_sox == NULL)
+     {
+       l_util_sox = g_strdup(GAP_STORY_SOX_DEFAULT_UTIL_SOX);
+     }
+  }
+  else
+  {
+    l_util_sox = g_strdup(util_sox);
   }
+
   if(util_sox_options == NULL)
   {
-    util_sox_options = GAP_STORY_SOX_DEFAULT_UTIL_SOX_OPTIONS;
+    l_util_sox_options = gimp_gimprc_query("video_encode_com_util_sox_options");
+    if(l_util_sox_options == NULL)
+    {
+      l_util_sox_options = g_strdup(GAP_STORY_SOX_DEFAULT_UTIL_SOX_OPTIONS);
+    }
   }
+  else
+  {
+    l_util_sox_options = g_strdup(util_sox_options);
+  }
+
 
-  /* the calling style requres UNIX Shell for Environment Variables
+  /* build the parameter string for calling the external audio converter tool
    * IN, OUT, RATE  that are used for Parameter substitution
    */
+  paramString = p_allocate_and_substitute_calling_parameters(in_audiofile
+                   ,out_audiofile
+                   ,samplerate
+                   ,l_util_sox_options
+                   );
+
+
+  l_arg_idx = 0;
+  l_cmd_argv[l_arg_idx++] = l_util_sox;  /* 1st param is name of called program */
+  
+  
+  /* split the substituted parameter string in substrings with whitespae as separator
+   * and put '\0' terminator characters wherever a substring ends.
+   * The l_cmd_argv[] array is filled with pointers
+   * to the substring start positions.
+   */
+  l_split_args_string = g_strdup(paramString);
+  l_ptr = l_split_args_string;
+  if (l_ptr != NULL)
+  {
+#define PARSE_STATUS_IS_SPACE     0
+#define PARSE_STATUS_IS_SINGLE_QT 1
+#define PARSE_STATUS_IS_DOUBLE_QT 2
+#define PARSE_STATUS_IS_TEXT      3
+
+    gint parseStatus = PARSE_STATUS_IS_SPACE;
+    
+    while(*l_ptr != '\0')
+    {
+      switch(parseStatus)
+      {
+        case PARSE_STATUS_IS_SINGLE_QT:
+          switch(*l_ptr)
+          {
+            case '\'':
+              parseStatus = PARSE_STATUS_IS_SPACE;
+              *l_ptr = '\0';  /* set termintate marker for substring */
+              break;
+            default:
+              break;
+          }
+          break;
+        case PARSE_STATUS_IS_DOUBLE_QT:
+          switch(*l_ptr)
+          {
+            case '"':
+              parseStatus = PARSE_STATUS_IS_SPACE;
+              *l_ptr = '\0';  /* set termintate marker for substring */
+              break;
+            default:
+              break;
+          }
+          break;
+        case PARSE_STATUS_IS_TEXT:
+          switch(*l_ptr)
+          {
+            case ' ':
+            case '\t':
+            case '\n':
+              parseStatus = PARSE_STATUS_IS_SPACE;
+              *l_ptr = '\0';  /* set termintate marker for substring */
+              break;    /* skip sequence of white space charactes */
+            default:
+              break;
+          }
+          break;
+        case PARSE_STATUS_IS_SPACE:
+          switch(*l_ptr)
+          {
+            case '\'':
+              parseStatus = PARSE_STATUS_IS_SINGLE_QT;
+              l_cmd_argv[l_arg_idx++] = &l_ptr[1];
+              break;
+            case '"':
+              parseStatus = PARSE_STATUS_IS_DOUBLE_QT;
+              l_cmd_argv[l_arg_idx++] = &l_ptr[1];
+              break;
+            case ' ':
+            case '\t':
+            case '\n':
+              break;    /* skip sequence of white space charactes */
+            default:
+              parseStatus = PARSE_STATUS_IS_TEXT;
+              l_cmd_argv[l_arg_idx++] = l_ptr;
+              break;
+          }
+          break;
+      }
+      
+      
+      l_ptr++;  /* advance to next character */
+    }
+  }
+ 
+  l_cmd_argv[l_arg_idx++] = NULL; /* (char *)0 indicates end of calling args */
+  
+
 
-  l_cmd = g_strdup_printf("IN='%s';OUT='%s';RATE=%d;%s %s\n"
-           , in_audiofile               /* input audio file */
-           , out_audiofile              /* output audio file (tmp 16-bit wav file) */
-           , (int)samplerate
-           , util_sox
-           , util_sox_options
-           );
 
   if(gap_debug)
   {
-    printf("Execute resample CMD:%s\n", l_cmd);
+    printf("Execute-resample CMD:%s  args:%s\n", l_util_sox, paramString);
   }
 
-  system(l_cmd);
-  g_free(l_cmd);
+  /* spawn external converter program (l_util_sox) */
+  {
+    gboolean spawnRc;
+    GSpawnFlags spawnFlags = G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL;
+    GError     *spawnError = NULL;
+    gint exit_status;
+
+    if(!g_file_test (l_util_sox, G_FILE_TEST_IS_EXECUTABLE) )
+    {
+      /* in case the external program was not configured with absolute path
+       * enable the search Path flag
+       */
+      spawnFlags |= G_SPAWN_SEARCH_PATH;
+    }
+    spawnRc = g_spawn_sync(NULL,        /*  const gchar *working_directory  NULL: inherit from parent */
+                          l_cmd_argv,   /*  argument vector for the external program */
+                          NULL,         /*  gchar **envp NULL inherit from parent */
+                          spawnFlags,
+                          NULL,         /*  GSpawnChildSetupFunc child_setup function to run in the child 
just before exec() */
+                          NULL,         /*  gpointer user_data */
+                          NULL,         /*  gchar **standard_output */
+                          NULL,         /*  gchar **standard_error */
+                          &exit_status,
+                          NULL          /* GError **spawnError */
+                          );
+
+    if(!spawnRc)
+    {
+      printf("Failed to spawn external audio converter program: %s %s"
+        , l_util_sox
+        , paramString
+        );
+    }
+                          
+  }
+
+  g_free(l_util_sox);
+  g_free(l_util_sox_options);
+
+  g_free(l_split_args_string);
+  g_free(paramString);
+
+
 }  /* end gap_story_sox_exec_resample */
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]