Or the real fix (which could be found after running valgrind and analysing, taking 10 minutes in all):
In main.c in static FILE_LIST* alloc_node(const char* file)
change
node->dc_offset = calloc(2, sizeof(double *));
to
node->dc_offset = calloc(10, sizeof(double));
We want doubles not pointers to doubles. I changed to 2 to 10, as you would get probs if you want to open multi channel wavs. I think 10 is pretty safe but not a real fix. It should in fact be set to the source's channels.
Then I found out wavegain is leaking, and a few minutes more I fixed it. I think I should submit a patch to John. (In wavegain.c in get_gain: Search for "float **buffer = malloc(sizeof(float *) * wg_opts->channels);" and the second find is the place where to substitue with this code. I guess you'll see how.)
else
{
float **buffer = malloc(sizeof(float *) * wg_opts->channels);
for (i = 0; i < wg_opts->channels; i++)
buffer[i] = malloc(BUFFER_LEN * sizeof(float));
while (1) {
long samples_read;
samples_read = wg_opts->read_samples(wg_opts->readdata, buffer, BUFFER_LEN, 0, 0);
if (samples_read == 0) {
break;
}
else {
if (samples_read < 0) {
/* Error in the stream. Not a problem, just reporting it in case
* we (the app) cares. In this case, we don't
*/
}
else {
long i;
int j;
for (i = 0; i < wg_opts->channels; i++) {
for (j = 0; j < samples_read; j++) {
if (buffer[i][j] > 0.f)
total_plus[i] += buffer[i][j];
else if (buffer[i][j] < 0.f)
total_minus[i] += buffer[i][j];
buffer[i][j] *= 0x7fff;
if (FABS(buffer[i][j]) > peak)
peak = FABS(buffer[i][j]);
}
}
if (AnalyzeSamples(buffer[0], buffer[1], samples_read,
wg_opts->channels) != GAIN_ANALYSIS_OK) {
fprintf(stderr, " Error processing samples.\n");
for (i = 0; i < wg_opts->channels; i++)
if (buffer[i]) free(buffer[i]);
if (buffer) free(buffer);
goto exit;
}
}
}
}
for (i = 0; i < wg_opts->channels; i++)
if (buffer[i]) free(buffer[i]);
if (buffer) free(buffer);
BTW, wavegain uses an old version of gain_analysis.c, as far as I can see. You may want to sync to latest one found in latest mp3gain for a nice speed-up.
I also wrote a tiny cmake (cmake.org) project file. Using cmake you can compile cross platform. With this project file you can generate unix makefiles, kdevelop and msvc++ project files (and probably more).
CMakeLists.txt
# cmake project file by Prakash Punnoor
PROJECT(Wavegain)
ADD_EXECUTABLE(wavegain
audio.c
dither.c
gain_analysis.c
getopt1.c
getopt.c
main.c
misc.c
recurse.c
wavegain.c
)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-lm ")
INSTALL_TARGETS(/bin wavegain)
It is not perfect, but works. To compile, run something like:
cmake . -DCMAKE_C_FLAGS:STRING="-march=i686 -O2"
make
Of course you should use optimal CFLAGS for your platform.
HTH,
Prakash