ref: dd60a438af3d3a551ab2949f58244c6b3f052d0c
parent: f20e48eb7e16e00e53c518110800c37b81413a9d
author: cbagwell <cbagwell>
date: Thu Oct 23 21:47:24 EDT 2008
malloc effect chains on demand to save memory.
--- a/src/sox.c
+++ b/src/sox.c
@@ -137,9 +137,8 @@
static sox_effects_chain_t *effects_chain = NULL;
static sox_effect_t *save_output_eff = NULL;
-#define MAX_USER_EFF_CHAINS 256
-static struct { char *name; int argc; char *argv[FILENAME_MAX]; } user_effargs[MAX_USER_EFF_CHAINS][MAX_USER_EFF];
-static unsigned nuser_effects[MAX_USER_EFF_CHAINS];
+static struct { char *name; int argc; char *argv[FILENAME_MAX]; } (*user_effargs)[MAX_USER_EFF] = NULL;
+static unsigned *nuser_effects = NULL;
static int current_eff_chain = 0;
static int eff_chain_count = 0;
static char *effects_filename = NULL;
@@ -589,8 +588,28 @@
exit(2); /* The effects chain should have displayed an error message */
}
-static void delete_user_effargs(void)
+static void init_eff_chains(void)
{
+ user_effargs = lsx_malloc(sizeof(user_effargs[0][0]) * MAX_USER_EFF);
+ nuser_effects = lsx_malloc(sizeof(*nuser_effects));
+ nuser_effects[0] = 0;
+} /* init_eff_chains */
+
+/* add_eff_chain() - NOTE: this only adds memory for one
+ * additional effects chain beyond value of eff_chain_count. It
+ * does not unconditionally increase size of effects chain.
+ */
+static void add_eff_chain(void)
+{
+ user_effargs = lsx_realloc(user_effargs, (eff_chain_count+1) *
+ sizeof(user_effargs[0][0]) * MAX_USER_EFF);
+ nuser_effects = lsx_realloc(nuser_effects, (eff_chain_count+1) *
+ sizeof(*nuser_effects));
+ nuser_effects[eff_chain_count] = 0;
+} /* add_eff_chain */
+
+static void delete_eff_chains(void)
+{
unsigned j;
int i, k;
@@ -611,8 +630,12 @@
}
nuser_effects[i] = 0;
}
+ free(user_effargs);
+ free(nuser_effects);
+ user_effargs = NULL;
+ nuser_effects = NULL;
eff_chain_count = 0;
-} /* delete_user_effargs */
+} /* delete_eff_chains */
static sox_bool is_pseudo_effect(char *s)
{
@@ -626,17 +649,11 @@
static void parse_effects(int argc, char **argv)
{
- nuser_effects[eff_chain_count] = 0;
while (optind < argc) {
unsigned eff_offset;
int j;
int newline_mode = 0;
- if (eff_chain_count >= MAX_USER_EFF_CHAINS) {
- sox_fail("too many effects chains specified (at most %i allowed)", MAX_USER_EFF_CHAINS);
- exit(1);
- }
-
eff_offset = nuser_effects[eff_chain_count];
if (eff_offset >= MAX_USER_EFF) {
sox_fail("too many effects specified (at most %i allowed)", MAX_USER_EFF);
@@ -650,7 +667,10 @@
* Error checking will be done when loop is restarted.
*/
if (nuser_effects[eff_chain_count] != 0)
- nuser_effects[++eff_chain_count] = 0;
+ {
+ eff_chain_count++;
+ add_eff_chain();
+ }
optind++;
continue;
}
@@ -663,7 +683,8 @@
*/
if (nuser_effects[eff_chain_count] != 0)
{
- nuser_effects[++eff_chain_count] = 0;
+ eff_chain_count++;
+ add_eff_chain();
continue;
}
newline_mode = 1;
@@ -676,7 +697,8 @@
*/
if (nuser_effects[eff_chain_count] != 0)
{
- nuser_effects[++eff_chain_count] = 0;
+ eff_chain_count++;
+ add_eff_chain();
continue;
}
newline_mode = 1;
@@ -694,7 +716,8 @@
if (newline_mode)
{
output_method = sox_multiple;
- nuser_effects[++eff_chain_count] = 0;
+ eff_chain_count++;
+ add_eff_chain();
}
}
} /* parse_effects */
@@ -762,8 +785,12 @@
char *argv[FILENAME_MAX];
int len;
- delete_user_effargs();
+ /* Free any command line options and then re-initialize to
+ * starter user_effargs.
+ */
+ delete_eff_chains();
current_eff_chain = 0;
+ init_eff_chains();
if (file == NULL)
{
@@ -794,11 +821,15 @@
*/
optind = 0;
parse_effects(argc, argv);
+
/* Advance to next effect but only if current chain has been
* filled in. This recovers from side affects of psuedo-effects.
*/
if (nuser_effects[eff_chain_count] > 0)
+ {
eff_chain_count++;
+ add_eff_chain();
+ }
}
fclose(file);
@@ -2378,10 +2409,17 @@
set_replay_gain(files[i]->ft->oob.comments, files[i]);
signal(SIGINT, SIG_DFL);
+ init_eff_chains();
+
/* Loop through the rest of the arguments looking for effects */
parse_effects(argc, argv);
if (eff_chain_count == 0 || nuser_effects[eff_chain_count] > 0)
+ {
eff_chain_count++;
+ /* Note: Purposely not calling add_eff_chain() to save some
+ * memory although it would be more consistent to do so.
+ */
+ }
/* Not the best way for users to do this; now deprecated in favour of soxi. */
if (!show_progress && !nuser_effects[current_eff_chain] &&
@@ -2427,7 +2465,7 @@
}
sox_delete_effects_chain(effects_chain);
- delete_user_effargs();
+ delete_eff_chains();
for (i = 0; i < file_count; ++i)
if (files[i]->ft->clips != 0)