shithub: sox

Download patch

ref: 3ae7e2e44b739c26b560b79f8a66fa191ff8cf08
parent: 7844afed6e899a5ed1327721e92f1fbad1e198a5
author: cbagwell <cbagwell>
date: Fri Sep 1 22:12:36 EDT 2006

Moving handlers back to functional handler interface for win32

--- a/src/8svx.c
+++ b/src/8svx.c
@@ -396,7 +396,7 @@
   NULL
 };
 
-st_format_t st_svx_format = {
+static st_format_t st_svx_format = {
   svxnames,
   NULL,
   ST_FILE_STEREO,
@@ -408,3 +408,8 @@
   st_svxstopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_svx_format_fn(void)
+{
+    return &st_svx_format;
+}
--- a/src/aiff.c
+++ b/src/aiff.c
@@ -1108,7 +1108,7 @@
   NULL
 };
 
-st_format_t st_aiff_format = {
+static st_format_t st_aiff_format = {
   aiffnames,
   NULL,
   ST_FILE_STEREO | ST_FILE_LOOPS | ST_FILE_SEEK,
@@ -1120,3 +1120,8 @@
   st_aiffstopwrite,
   st_aiffseek
 };
+
+const st_format_t *st_aiff_format_fn(void)
+{
+    return &st_aiff_format;
+}
--- a/src/alsa.c
+++ b/src/alsa.c
@@ -637,7 +637,7 @@
   NULL
 };
 
-st_format_t st_alsa_format = {
+static st_format_t st_alsa_format = {
    alsanames,
    NULL,
    ST_FILE_STEREO | ST_FILE_NOSTDIO,
@@ -649,4 +649,9 @@
    st_alsastopwrite,
    st_format_nothing_seek
 };
+
+const st_format_t *st_alsa_format_fn(void)
+{
+    return &st_alsa_format;
+}
 #endif /* HAVE_ALSA */
--- a/src/au.c
+++ b/src/au.c
@@ -469,7 +469,7 @@
   NULL
 };
 
-st_format_t st_au_format = {
+static st_format_t st_au_format = {
   aunames,
   NULL,
   ST_FILE_STEREO | ST_FILE_SEEK,
@@ -481,3 +481,8 @@
   st_austopwrite,
   st_auseek
 };
+
+const st_format_t *st_au_format_fn(void)
+{
+    return &st_au_format;
+}
--- a/src/auto.c
+++ b/src/auto.c
@@ -202,7 +202,7 @@
   NULL
 };
 
-st_format_t st_auto_format = {
+static st_format_t st_auto_format = {
   autonames,
   NULL,
   ST_FILE_STEREO,
@@ -214,3 +214,8 @@
   st_format_nothing,
   st_format_nothing_seek
 };
+
+const st_format_t *st_auto_format_fn(void)
+{
+    return &st_auto_format;
+}
--- a/src/avr.c
+++ b/src/avr.c
@@ -296,7 +296,7 @@
   NULL
 };
 
-st_format_t st_avr_format = {
+static st_format_t st_avr_format = {
   avrnames,
   NULL,
   ST_FILE_STEREO,
@@ -308,3 +308,8 @@
   st_avrstopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_avr_format_fn(void)
+{
+    return &st_avr_format;
+}
--- a/src/cdr.c
+++ b/src/cdr.c
@@ -165,7 +165,7 @@
   NULL
 };
 
-st_format_t st_cdr_format = {
+static st_format_t st_cdr_format = {
   cdrnames,
   NULL,
   ST_FILE_STEREO | ST_FILE_SEEK,
@@ -177,3 +177,8 @@
   st_cdrstopwrite,
   st_rawseek
 };
+
+const st_format_t *st_cdr_format_fn(void)
+{
+    return &st_cdr_format;
+}
--- a/src/cvsd.c
+++ b/src/cvsd.c
@@ -676,7 +676,7 @@
   NULL
 };
 
-st_format_t st_cvsd_format = {
+static st_format_t st_cvsd_format = {
   cvsdnames,
   NULL,
   0,
@@ -689,6 +689,10 @@
   st_format_nothing_seek
 };
 
+const st_format_t *st_cvsd_format_fn(void)
+{
+    return &st_cvsd_format;
+}
 /* Cont. Variable Solot Delta */
 static char *dvmsnames[] = {
   "vms",
@@ -696,7 +700,7 @@
   NULL
 };
 
-st_format_t st_dvms_format = {
+static st_format_t st_dvms_format = {
   dvmsnames,
   NULL,
   0,
@@ -708,3 +712,8 @@
   st_dvmsstopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_dvms_format_fn(void)
+{
+    return &st_dvms_format;
+}
--- a/src/dat.c
+++ b/src/dat.c
@@ -181,7 +181,7 @@
   NULL
 };
 
-st_format_t st_dat_format = {
+static st_format_t st_dat_format = {
   datnames,
   NULL,
   0,
@@ -193,3 +193,8 @@
   st_format_nothing,
   st_format_nothing_seek
 };
+
+const st_format_t *st_dat_format_fn(void)
+{
+    return &st_dat_format;
+}
--- a/src/gsm.c
+++ b/src/gsm.c
@@ -244,7 +244,7 @@
   NULL
 };
 
-st_format_t st_gsm_format = {
+static st_format_t st_gsm_format = {
   gsmnames,
   NULL,
   0,
@@ -256,4 +256,9 @@
   st_gsmstopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_gsm_format_fn(void)
+{
+    return &st_gsm_format;
+}
 #endif /* ENABLE_GSM */
--- a/src/handlers.c
+++ b/src/handlers.c
@@ -14,64 +14,58 @@
  * Sound Tools file format and effect tables.
  */
 
-st_format_t st_terminate_format =
-{
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
 /* File format handlers. */
-st_format_t *st_formats[] = {
-  &st_aiff_format,
-  &st_al_format,
+st_format_fn_t st_format_fns[] = {
+  st_aiff_format_fn,
+  st_al_format_fn,
 #if     defined(HAVE_ALSA)
-  &st_alsa_format,
+  st_alsa_format_fn,
 #endif
-  &st_au_format,
-  &st_auto_format,
-  &st_avr_format,
-  &st_cdr_format,
-  &st_cvsd_format,
-  &st_dat_format,
-  &st_dvms_format,
+  st_au_format_fn,
+  st_auto_format_fn,
+  st_avr_format_fn,
+  st_cdr_format_fn,
+  st_cvsd_format_fn,
+  st_dat_format_fn,
+  st_dvms_format_fn,
 #ifdef ENABLE_GSM
-  &st_gsm_format,
+  st_gsm_format_fn,
 #endif
-  &st_hcom_format,
-  &st_la_format,
-  &st_lu_format,
-  &st_maud_format,
+  st_hcom_format_fn,
+  st_la_format_fn,
+  st_lu_format_fn,
+  st_maud_format_fn,
 #if defined(HAVE_LIBMAD) || defined(HAVE_LAME)
-  &st_mp3_format,
+  st_mp3_format_fn,
 #endif
-  &st_nul_format,
+  st_nul_format_fn,
 #if     defined(HAVE_OSS)
-  &st_ossdsp_format,
+  st_ossdsp_format_fn,
 #endif
-  &st_prc_format,
-  &st_raw_format,
-  &st_sb_format,
-  &st_sf_format,
-  &st_sl_format,
-  &st_smp_format,
-  &st_snd_format,
-  &st_sphere_format,
+  st_prc_format_fn,
+  st_raw_format_fn,
+  st_sb_format_fn,
+  st_sf_format_fn,
+  st_sl_format_fn,
+  st_smp_format_fn,
+  st_snd_format_fn,
+  st_sphere_format_fn,
 #if     defined(HAVE_SUNAUDIO)
-  &st_sun_format,
+  st_sun_format_fn,
 #endif
-  &st_svx_format,
-  &st_sw_format,
-  &st_txw_format,
-  &st_ub_format,
-  &st_ul_format,
-  &st_uw_format,
-  &st_voc_format,
+  st_svx_format_fn,
+  st_sw_format_fn,
+  st_txw_format_fn,
+  st_ub_format_fn,
+  st_ul_format_fn,
+  st_uw_format_fn,
+  st_voc_format_fn,
 #ifdef HAVE_LIBVORBIS
-  &st_vorbis_format,
+  st_vorbis_format_fn,
 #endif
-  &st_vox_format,
-  &st_wav_format,
-  &st_wve_format,
-  &st_terminate_format,
+  st_vox_format_fn,
+  st_wav_format_fn,
+  st_wve_format_fn,
   NULL
 };
 
--- a/src/hcom.c
+++ b/src/hcom.c
@@ -578,7 +578,7 @@
   NULL
 };
 
-st_format_t st_hcom_format = {
+static st_format_t st_hcom_format = {
   hcomnames,
   NULL,
   0,
@@ -590,3 +590,8 @@
   st_hcomstopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_hcom_format_fn(void)
+{
+    return &st_hcom_format;
+}
--- a/src/maud.c
+++ b/src/maud.c
@@ -394,7 +394,7 @@
   NULL,
 };
 
-st_format_t st_maud_format = {
+static st_format_t st_maud_format = {
   maudnames,
   NULL,
   ST_FILE_STEREO,
@@ -406,3 +406,8 @@
   st_maudstopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_maud_format_fn(void)
+{
+    return &st_maud_format;
+}
--- a/src/mp3.c
+++ b/src/mp3.c
@@ -528,7 +528,7 @@
   NULL,
 };
 
-st_format_t st_mp3_format = {
+static st_format_t st_mp3_format = {
   mp3names,
   NULL,
   ST_FILE_STEREO,
@@ -540,4 +540,9 @@
   st_mp3stopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_mp3_format_fn(void)
+{
+    return &st_mp3_format;
+}
 #endif
--- a/src/nulfile.c
+++ b/src/nulfile.c
@@ -91,7 +91,7 @@
   NULL,
 };
 
-st_format_t st_nul_format = {
+static st_format_t st_nul_format = {
   nulnames,
   NULL,
   ST_FILE_STEREO | ST_FILE_NOSTDIO,
@@ -103,3 +103,8 @@
   st_nulstopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_nul_format_fn(void)
+{
+    return &st_nul_format;
+}
--- a/src/oss.c
+++ b/src/oss.c
@@ -222,7 +222,7 @@
   NULL
 };
 
-st_format_t st_ossdsp_format = {
+static st_format_t st_ossdsp_format = {
   ossdspnames,
   NULL,
   ST_FILE_STEREO,
@@ -234,4 +234,9 @@
   st_rawstopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_ossdsp_format_fn(void)
+{
+    return &st_ossdsp_format;
+}
 #endif
--- a/src/prc.c
+++ b/src/prc.c
@@ -216,7 +216,7 @@
   NULL
 };
 
-st_format_t st_prc_format = {
+static st_format_t st_prc_format = {
   prcnames,
   NULL,
   ST_FILE_SEEK,
@@ -228,3 +228,8 @@
   st_prcstopwrite,
   st_prcseek
 };
+
+const st_format_t *st_prc_format_fn(void)
+{
+    return &st_prc_format;
+}
--- a/src/raw.c
+++ b/src/raw.c
@@ -827,7 +827,7 @@
   NULL
 };
 
-st_format_t st_raw_format = {
+static st_format_t st_raw_format = {
    rawnames,
    NULL,
    ST_FILE_STEREO | ST_FILE_SEEK,
@@ -840,6 +840,11 @@
    st_rawseek
 };
 
+const st_format_t *st_raw_format_fn(void)
+{
+    return &st_raw_format;
+}
+
 /* a-law byte raw */
 static char *alnames[] = {
   "al",
@@ -846,7 +851,7 @@
   NULL
 };
 
-st_format_t st_al_format = {
+static st_format_t st_al_format = {
   alnames,
   NULL,
   ST_FILE_STEREO,
@@ -859,6 +864,11 @@
   st_format_nothing_seek
 };
 
+const st_format_t *st_al_format_fn(void)
+{
+    return &st_al_format;
+}
+
 /* inverse a-law byte raw */
 static char *lanames[] = {
   "la",
@@ -865,7 +875,7 @@
   NULL
 };
 
-st_format_t st_la_format = {
+static st_format_t st_la_format = {
   lanames,
   NULL,
   ST_FILE_STEREO,
@@ -878,6 +888,11 @@
   st_format_nothing_seek
 };
 
+const st_format_t *st_la_format_fn(void)
+{
+    return &st_la_format;
+}
+
 /* inverse u-law byte raw */
 static char *lunames[] = {
   "lu",
@@ -884,7 +899,7 @@
   NULL
 };
 
-st_format_t st_lu_format = {
+static st_format_t st_lu_format = {
   lunames,
   NULL,
   ST_FILE_STEREO,
@@ -897,12 +912,17 @@
   st_format_nothing_seek
 };
 
+const st_format_t *st_lu_format_fn(void)
+{
+    return &st_lu_format;
+}
+
 static char *sbnames[] = {
   "sb",
   NULL
 };
 
-st_format_t st_sb_format = {
+static st_format_t st_sb_format = {
   sbnames,
   NULL,
   ST_FILE_STEREO,
@@ -915,12 +935,17 @@
   st_format_nothing_seek
 };
 
+const st_format_t *st_sb_format_fn(void)
+{
+    return &st_sb_format;
+}
+
 static char *slnames[] = {
   "sl",
   NULL,
 };
 
-st_format_t st_sl_format = {
+static st_format_t st_sl_format = {
   slnames,
   NULL,
   ST_FILE_STEREO,
@@ -933,12 +958,17 @@
   st_format_nothing_seek
 };
 
+const st_format_t *st_sl_format_fn(void)
+{
+    return &st_sl_format;
+}
+
 static char *swnames[] = {
   "sw",
   NULL
 };
 
-st_format_t st_sw_format = {
+static st_format_t st_sw_format = {
   swnames,
   NULL,
   ST_FILE_STEREO,
@@ -951,6 +981,11 @@
   st_format_nothing_seek
 };
 
+const st_format_t *st_sw_format_fn(void)
+{
+    return &st_sw_format;
+}
+
 static char *ubnames[] = {
   "ub",
   "sou",
@@ -958,7 +993,7 @@
   NULL
 };
 
-st_format_t st_ub_format = {
+static st_format_t st_ub_format = {
   ubnames,
   NULL,
   ST_FILE_STEREO,
@@ -971,12 +1006,17 @@
   st_format_nothing_seek
 };
 
+const st_format_t *st_ub_format_fn(void)
+{
+    return &st_ub_format;
+}
+
 static char *ulnames[] = {
   "ul",
   NULL
 };
 
-st_format_t st_ul_format = {
+static st_format_t st_ul_format = {
    ulnames,
    NULL,
    ST_FILE_STEREO,
@@ -989,12 +1029,17 @@
    st_format_nothing_seek
 };
 
+const st_format_t *st_ul_format_fn(void)
+{
+    return &st_ul_format;
+}
+
 static char *uwnames[] = {
   "uw",
   NULL
 };
 
-st_format_t st_uw_format = {
+static st_format_t st_uw_format = {
   uwnames,
   NULL,
   ST_FILE_STEREO,
@@ -1006,3 +1051,8 @@
   st_rawstopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_uw_format_fn(void)
+{
+    return &st_uw_format;
+}
--- a/src/sf.c
+++ b/src/sf.c
@@ -228,7 +228,7 @@
   NULL
 };
 
-st_format_t st_sf_format = {
+static st_format_t st_sf_format = {
   sfnames,
   NULL,
   ST_FILE_STEREO | ST_FILE_SEEK,
@@ -240,3 +240,8 @@
   st_rawstopwrite,
   st_sfseek
 };
+
+const st_format_t *st_sf_format_fn(void)
+{
+    return &st_sf_format;
+}
--- a/src/smp.c
+++ b/src/smp.c
@@ -437,7 +437,7 @@
   NULL,
 };
 
-st_format_t st_smp_format = {
+static st_format_t st_smp_format = {
   smpnames,
   NULL,
   ST_FILE_STEREO | ST_FILE_LOOPS | ST_FILE_SEEK,
@@ -449,3 +449,8 @@
   st_smpstopwrite,
   st_smpseek
 };
+
+const st_format_t *st_smp_format_fn(void)
+{
+    return &st_smp_format;
+}
--- a/src/sndrtool.c
+++ b/src/sndrtool.c
@@ -262,7 +262,7 @@
   NULL
 };
 
-st_format_t st_snd_format = {
+const st_format_t st_snd_format = {
   sndtnames,
   NULL,
   ST_FILE_STEREO | ST_FILE_SEEK,
@@ -274,3 +274,8 @@
   st_sndtstopwrite,
   st_sndseek
 };
+
+const st_format_t *st_snd_format_fn(void)
+{
+    return &st_snd_format;
+}
--- a/src/sox.c
+++ b/src/sox.c
@@ -174,6 +174,7 @@
         if (file_count >= MAX_FILES)
         {
             st_fail("to many filenames. max of %d input files and 1 output files\n", MAX_INPUT_FILES);
+            exit(1);
         }
 
         /*
@@ -248,7 +249,6 @@
             /* st_open_read() will call st_warn for most errors.
              * Rely on that printing something.
              */
-            cleanup();
             exit(2);
         }
     }
@@ -328,13 +328,21 @@
                 str = optarg;
                 if ((!sscanf(optarg, "%u", &fo->info.rate)) ||
                     (fo->info.rate <= 0))
+                {
                     st_fail("-r must be given a positive integer");
+                    cleanup();
+                    exit(1);
+                }
                 break;
             case 'v':
                 str = optarg;
                 if (!sscanf(str, "%lf", &fo->volume))
+                {
                     st_fail("Volume value '%s' is not a number",
                             optarg);
+                    cleanup();
+                    exit(1);
+                }
                 fo->uservolume = 1;
                 if (fo->volume < 0.0)
                     st_report("Volume adjustment is negative.  This will result in a phase change\n");
@@ -343,7 +351,11 @@
             case 'c':
                 str = optarg;
                 if (!sscanf(str, "%d", &i))
+                {
                     st_fail("-c must be given a number");
+                    cleanup();
+                    exit(1);
+                }
                 /* Since we use -1 as a special internal value,
                  * we must do some extra logic so user doesn't
                  * get confused when we translate -1 to mean
@@ -350,7 +362,11 @@
                  * something valid.
                  */
                 if (i < 1)
+                {
                     st_fail("-c must be given a positive number");
+                    cleanup();
+                    exit(1);
+                }
                 fo->info.channels = i;
                 break;
             case 'b':
@@ -497,6 +513,7 @@
         if (compare_input(file_desc[0], file_desc[f]) != ST_SUCCESS)
         {
             st_fail("Input files must have the same rate, channels, data size, and encoding");
+            exit(1);
         }
     }
 
@@ -598,6 +615,8 @@
         if (!ibuf[f])
         {
             st_fail("could not allocate memory");
+            cleanup();
+            exit(1);
         }
 
         if (status)
@@ -821,6 +840,8 @@
         if (nuser_effects >= MAX_USER_EFF)
         {
             st_fail("To many effects specified.\n");
+            cleanup();
+            exit(2);
         }
 
         argc_effect = st_geteffect_opt(&user_efftab[nuser_effects],
@@ -834,6 +855,7 @@
                 fprintf(stderr, "%s ", st_effects[i1]->name);
             fprintf(stderr, "\n\n");
             st_fail("Effect '%s' is not known!", argv[optind]);
+            cleanup();
             exit(2);
         }
 
@@ -848,6 +870,7 @@
 
         if (effect_rc == ST_EOF)
         {
+            cleanup();
             exit(2);
         }
 
@@ -888,7 +911,11 @@
     }
 
     if (haschan > 1)
+    {
         st_fail("Can not specify multiple effects that modify channel #");
+        cleanup();
+        exit(2);
+    }
     if (hasrate > 1)
         st_report("Can not specify multiple effects that change sample rate");
 
@@ -1086,6 +1113,8 @@
         if (efftab[e].obuf == NULL)
         {
             st_fail("could not allocate memory");
+            cleanup();
+            exit(2);
         }
         if (efftabR[e].name)
         {
@@ -1094,6 +1123,8 @@
             if (efftabR[e].obuf == NULL)
             {
                 st_fail("could not allocate memory");
+                cleanup();
+                exit(2);
             }
         }
     }
@@ -1389,7 +1420,11 @@
         return ST_EOF;
     }
     if (done == 0)
+    {
         st_fail("Effect took & gave no samples!");
+        cleanup();
+        exit(2);
+    }
     return ST_SUCCESS;
 }
 
@@ -1610,6 +1645,7 @@
 static void usage(char *opt)
 {
     int i;
+    const st_format_t *f;
 
     printf("%s: ", myname);
     printf("Version %s\n\n", st_version());
@@ -1652,9 +1688,13 @@
 "\n");
 
     printf("Supported file formats: ");
-    for (i = 0; st_formats[i]->names != NULL; i++) {
-        /* only print the first name */
-        printf("%s ", st_formats[i]->names[0]);
+    for (i = 0; st_format_fns[i]; i++) {
+        f = st_format_fns[i]();
+        if (f && f->names)
+        {
+            /* only print the first name */
+            printf("%s ", f->names[0]);
+        }
     }
 
     printf("\n\nSupported effects: ");
--- a/src/sphere.c
+++ b/src/sphere.c
@@ -315,7 +315,7 @@
   NULL
 };
 
-st_format_t st_sphere_format = {
+static st_format_t st_sphere_format = {
   spherenames,
   NULL,
   ST_FILE_STEREO,
@@ -327,3 +327,8 @@
   st_spherestopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_sphere_format_fn(void)
+{
+    return &st_sphere_format;
+}
--- a/src/st.h
+++ b/src/st.h
@@ -193,7 +193,7 @@
     st_fileinfo_t   file;                 /* File data block */
     int             st_errno;             /* Failure error codes */
     char            st_errstr[256];       /* Extend Failure text */
-    st_format_t     *h;                   /* format struct for this file */
+    const st_format_t *h;                 /* format struct for this file */
     /* The following is a portable trick to align this variable on
      * an 8-byte bounder.  Once this is done, the buffer alloced
      * after it should be align on an 8-byte boundery as well.
@@ -203,8 +203,6 @@
     double priv1;
     char   priv[ST_MAX_FILE_PRIVSIZE]; /* format's private data area */
 };
-
-extern st_format_t *st_formats[];
 
 /* file flags field */
 #define ST_FILE_STEREO  1  /* does file format support stereo? */
--- a/src/st_i.h
+++ b/src/st_i.h
@@ -147,54 +147,58 @@
  *=============================================================================
  */
 
-st_format_t st_svx_format;
-st_format_t st_aiff_format;
+typedef const st_format_t *(*st_format_fn_t)(void);
+
+extern st_format_fn_t st_format_fns[];
+
+extern const st_format_t *st_aiff_format_fn(void);
 #ifdef HAVE_ALSA
-st_format_t st_alsa_format;
+extern const st_format_t *st_alsa_format_fn(void);
 #endif
-st_format_t st_au_format;
-st_format_t st_auto_format;
-st_format_t st_avr_format;
-st_format_t st_cdr_format;
-st_format_t st_cvsd_format;
-st_format_t st_dvms_format;
-st_format_t st_dat_format;
+extern const st_format_t *st_au_format_fn(void);
+extern const st_format_t *st_auto_format_fn(void);
+extern const st_format_t *st_avr_format_fn(void);
+extern const st_format_t *st_cdr_format_fn(void);
+extern const st_format_t *st_cvsd_format_fn(void);
+extern const st_format_t *st_dvms_format_fn(void);
+extern const st_format_t *st_dat_format_fn(void);
 #ifdef ENABLE_GSM
-st_format_t st_gsm_format;
+extern const st_format_t *st_gsm_format_fn(void);
 #endif
-st_format_t st_hcom_format;
-st_format_t st_maud_format;
-st_format_t st_mp3_format;
-st_format_t st_nul_format;
+extern const st_format_t *st_hcom_format_fn(void);
+extern const st_format_t *st_maud_format_fn(void);
+extern const st_format_t *st_mp3_format_fn(void);
+extern const st_format_t *st_nul_format_fn(void);
 #ifdef HAVE_OSS
-st_format_t st_ossdsp_format;
+extern const st_format_t *st_ossdsp_format_fn(void);
 #endif
-st_format_t st_prc_format;
-st_format_t st_raw_format;
-st_format_t st_al_format;
-st_format_t st_la_format;
-st_format_t st_lu_format;
-st_format_t st_sb_format;
-st_format_t st_sl_format;
-st_format_t st_sw_format;
-st_format_t st_ub_format;
-st_format_t st_ul_format;
-st_format_t st_uw_format;
-st_format_t st_sf_format;
-st_format_t st_smp_format;
-st_format_t st_snd_format;
-st_format_t st_sphere_format;
+extern const st_format_t *st_prc_format_fn(void);
+extern const st_format_t *st_raw_format_fn(void);
+extern const st_format_t *st_al_format_fn(void);
+extern const st_format_t *st_la_format_fn(void);
+extern const st_format_t *st_lu_format_fn(void);
+extern const st_format_t *st_sb_format_fn(void);
+extern const st_format_t *st_sl_format_fn(void);
+extern const st_format_t *st_sw_format_fn(void);
+extern const st_format_t *st_ub_format_fn(void);
+extern const st_format_t *st_ul_format_fn(void);
+extern const st_format_t *st_uw_format_fn(void);
+extern const st_format_t *st_sf_format_fn(void);
+extern const st_format_t *st_smp_format_fn(void);
+extern const st_format_t *st_snd_format_fn(void);
+extern const st_format_t *st_sphere_format_fn(void);
 #ifdef HAVE_SUNAUDIO
-st_format_t st_sun_format;
+extern const st_format_t *st_sun_format_fn(void);
 #endif
-st_format_t st_txw_format;
-st_format_t st_voc_format;
+extern const st_format_t *st_svx_format_fn(void);
+extern const st_format_t *st_txw_format_fn(void);
+extern const st_format_t *st_voc_format_fn(void);
 #ifdef HAVE_LIBVORBIS
-st_format_t st_vorbis_format;
+extern const st_format_t *st_vorbis_format_fn(void);
 #endif
-st_format_t st_vox_format;
-st_format_t st_wav_format;
-st_format_t st_wve_format;
+extern const st_format_t *st_vox_format_fn(void);
+extern const st_format_t *st_wav_format_fn(void);
+extern const st_format_t *st_wve_format_fn(void);
 
 /* Raw I/O
  */
--- a/src/sunaudio.c
+++ b/src/sunaudio.c
@@ -319,7 +319,7 @@
   NULL
 };
 
-st_format_t st_sun_format = {
+static st_format_t st_sun_format = {
   sunnames,
   NULL,
   ST_FILE_STEREO,
@@ -331,4 +331,9 @@
   st_rawstopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_sun_format_fn(void)
+{
+    return &st_sun_format;
+}
 #endif
--- a/src/tx16w.c
+++ b/src/tx16w.c
@@ -382,7 +382,7 @@
   NULL
 };
 
-st_format_t st_txw_format = {
+static st_format_t st_txw_format = {
    txwnames,
    NULL,
    0,
@@ -394,3 +394,8 @@
    st_txwstopwrite,
    st_format_nothing_seek
 };
+
+const st_format_t *st_txw_format_fn(void)
+{
+    return &st_txw_format;
+}
--- a/src/util.c
+++ b/src/util.c
@@ -131,30 +131,32 @@
  */
 int st_gettype(ft_t formp)
 {
-        char **list;
-        int i;
+    char **list;
+    int i;
+    const st_format_t *f;
 
-        if (! formp->filetype){
-            st_fail_errno(formp,
-                          ST_EFMT,
-                          "Filetype was not specified");
-                return(ST_EFMT);
-        }
-        for(i = 0; st_formats[i]->names; i++) {
-                for(list = st_formats[i]->names; *list; list++) {
-                        char *s1 = *list, *s2 = formp->filetype;
-                        if (! strcmpcase(s1, s2))
-                                break;  /* not a match */
-                }
-                if (! *list)
-                        continue;
-                /* Found it! */
-                formp->h = st_formats[i];
-                return ST_SUCCESS;
+    if (! formp->filetype){
+        st_fail_errno(formp,
+                      ST_EFMT,
+                      "Filetype was not specified");
+        return(ST_EFMT);
+    }
+    for(i = 0; st_format_fns[i]; i++) {
+        f = st_format_fns[i]();
+        for(list = f->names; *list; list++) {
+            char *s1 = *list, *s2 = formp->filetype;
+            if (! strcmpcase(s1, s2))
+                break;  /* not a match */
         }
-        st_fail_errno(formp, ST_EFMT, "File type '%s' is not known",
-                      formp->filetype);
-        return ST_EFMT;
+        if (! *list)
+            continue;
+        /* Found it! */
+        formp->h = f;
+        return ST_SUCCESS;
+    }
+    st_fail_errno(formp, ST_EFMT, "File type '%s' is not known",
+                  formp->filetype);
+    return ST_EFMT;
 }
 
 /*
--- a/src/voc.c
+++ b/src/voc.c
@@ -823,7 +823,7 @@
   NULL
 };
 
-st_format_t st_voc_format = {
+static st_format_t st_voc_format = {
   vocnames,
   NULL,
   ST_FILE_STEREO,
@@ -835,3 +835,8 @@
   st_vocstopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_voc_format_fn(void)
+{
+    return &st_voc_format;
+}
--- a/src/vorbis.c
+++ b/src/vorbis.c
@@ -464,7 +464,7 @@
   NULL
 };
 
-st_format_t st_vorbis_format = {
+static st_format_t st_vorbis_format = {
   vorbisnames,
   NULL,
   ST_FILE_STEREO,
@@ -477,4 +477,8 @@
   st_format_nothing_seek
 };
 
+const st_format_t *st_vorbis_format_fn(void)
+{
+    return &st_vorbis_format;
+}
 #endif /* HAVE_LIBVORBIS */
--- a/src/vox.c
+++ b/src/vox.c
@@ -447,7 +447,7 @@
   NULL
 };
 
-st_format_t st_vox_format = {
+static st_format_t st_vox_format = {
   voxnames,
   NULL,
   0,
@@ -459,3 +459,8 @@
   st_voxstopwrite,
   st_format_nothing_seek
 };
+
+const st_format_t *st_vox_format_fn(void)
+{
+    return &st_vox_format;
+}
--- a/src/wav.c
+++ b/src/wav.c
@@ -1789,7 +1789,7 @@
   NULL
 };
 
-st_format_t st_wav_format = {
+static st_format_t st_wav_format = {
   wavnames,
   NULL,
   ST_FILE_STEREO | ST_FILE_SEEK,
@@ -1801,3 +1801,8 @@
   st_wavstopwrite,
   st_wavseek
 };
+
+const st_format_t *st_wav_format_fn()
+{
+    return &st_wav_format;
+}
--- a/src/wve.c
+++ b/src/wve.c
@@ -238,7 +238,7 @@
   NULL
 };
 
-st_format_t st_wve_format = {
+static st_format_t st_wve_format = {
   wvenames,
   NULL,
   ST_FILE_SEEK,
@@ -250,3 +250,8 @@
   st_wvestopwrite,
   st_wveseek
 };
+
+const st_format_t *st_wve_format_fn(void)
+{
+    return &st_wve_format;
+}