mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-02-22 20:01:04 +00:00
Added --enable-trap-on-fpe and --enable-fpe-check configure options for
debuging FPEs, reverted rest of "Effect level clip" patch until something better is done, added hack to work around FPE related to faulty CPU frequency calculation, removed faulty zap_almost_zero macro and replaced with call to fabs() and compare, removed memory alignment hacks.
This commit is contained in:
parent
f34370c3fa
commit
d44800182e
11 changed files with 131 additions and 161 deletions
|
@ -1,3 +1,28 @@
|
||||||
|
2007-11-11 Josh Green <jgreen@users.sourceforge.net>
|
||||||
|
|
||||||
|
* configure.ac: Added --enable-trap-on-fpe and --enable-fpe-check to
|
||||||
|
assist with Floating Point Exception debugging.
|
||||||
|
* src/fluid_chorus.c: Reverted the rest of the chorus "Effect level clip"
|
||||||
|
patch, until something better is devised.
|
||||||
|
* src/fluid_synth.c: Added support for trapping on Floating Point
|
||||||
|
Exceptions on GLIBC systems, to aid developers in tracking down FPEs
|
||||||
|
with gdb, removed buffer alignment hacks since they are no longer
|
||||||
|
needed (not using SSE currently).
|
||||||
|
* src/fluid_sys.c (fluid_time_config): Added check for a CPU freq
|
||||||
|
calculation of 0.0, since this test is inadequate to begin with and
|
||||||
|
was coming up as 0.0 on my laptop, causing a FPE. Will replace with
|
||||||
|
real timer functions, in the future.
|
||||||
|
* src/fluid_voice.c: Removed zap_almost_zero macro as it was buggy and
|
||||||
|
had issues which went away when gcc optimization was turned off and in
|
||||||
|
the case of !WITH_FLOAT was using abs() which is integer based and
|
||||||
|
would cause FPEs.
|
||||||
|
(fluid_voice_write): Removed a memory alignment hack and moved a call
|
||||||
|
to fluid_fpe_check() to a better location.
|
||||||
|
(fluid_voice_effects): Replaced zap_almost_zero with a call to fabs(),
|
||||||
|
added fluid_fpe_check() call.
|
||||||
|
* src/fluidsynth_priv.h: Removed FLUID_ALIGN16BYTE hack, as it is no
|
||||||
|
longer needed.
|
||||||
|
|
||||||
2007-11-10 Josh Green <jgreen@users.sourceforge.net>
|
2007-11-10 Josh Green <jgreen@users.sourceforge.net>
|
||||||
|
|
||||||
* doc/fluidsynth.1: Updated man page with current command line options and other changes (minor).
|
* doc/fluidsynth.1: Updated man page with current command line options and other changes (minor).
|
||||||
|
|
|
@ -111,25 +111,20 @@ if test "x$ENABLE_LADSPA" = "xyes" ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(functioncheck, AS_HELP_STRING([--enable-functioncheck],
|
AC_ARG_ENABLE(trap-on-fpe, AS_HELP_STRING([--enable-trap-on-fpe],
|
||||||
[profiling using FunctionCheck, turns on debugging (default=no)]),
|
[Enable SIGFPE trap on Floating Point Exceptions (debugging)]),
|
||||||
ENABLE_FUNCTIONCHECK=$enableval,
|
ENABLE_TRAPONFPE=$enableval, ENABLE_TRAPONFPE=no)
|
||||||
ENABLE_FUNCTIONCHECK=no)
|
|
||||||
|
|
||||||
FCLDFLAGS=""
|
if test "$ENABLE_TRAPONFPE" = "yes"; then
|
||||||
FCCFLAGS=""
|
AC_DEFINE(TRAP_ON_FPE, 1, [Define to enable SIGFPE assertions])
|
||||||
if test "${ENABLE_FUNCTIONCHECK}" = "yes"; then
|
|
||||||
FCCFLAGS=`fc-config --cflags`
|
|
||||||
FCLDFLAGS=`fc-config --libs`
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_SUBST(FCLDFLAGS)
|
AC_ARG_ENABLE(fpe-check, AS_HELP_STRING([--enable-fpe-check],
|
||||||
|
[Enable Floating Point Exception checks and debug messages]),
|
||||||
|
ENABLE_FPECHECK=$enableval, ENABLE_FPECHECK=no)
|
||||||
|
|
||||||
|
if test "$ENABLE_FPECHECK" = "yes"; then
|
||||||
if test "${ENABLE_FUNCTIONCHECK}" = "yes"; then
|
AC_DEFINE(FPE_CHECK, 1, [Define to enable FPE checks])
|
||||||
ENABLE_DEBUG=yes
|
|
||||||
else
|
|
||||||
ENABLE_DEBUG=no
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],
|
AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],
|
||||||
|
@ -137,11 +132,7 @@ AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],
|
||||||
ENABLE_DEBUG=$enableval)
|
ENABLE_DEBUG=$enableval)
|
||||||
|
|
||||||
if test "$ENABLE_DEBUG" = "yes"; then
|
if test "$ENABLE_DEBUG" = "yes"; then
|
||||||
if test "${ENABLE_FUNCTIONCHECK}" = "yes"; then
|
CFLAGS="${CFLAGS} ${FCCFLAGS} -g -Wall -W -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wstrict-prototypes -Wno-unused"
|
||||||
CFLAGS="${CFLAGS} ${FCCFLAGS} -Wall -W -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wstrict-prototypes -Wno-unused"
|
|
||||||
else
|
|
||||||
CFLAGS="${CFLAGS} ${FCCFLAGS} -g -Wall -W -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wstrict-prototypes -Wno-unused"
|
|
||||||
fi
|
|
||||||
AC_DEFINE(DEBUG, 1, [Define to activate debugging message])
|
AC_DEFINE(DEBUG, 1, [Define to activate debugging message])
|
||||||
else
|
else
|
||||||
CFLAGS="${CFLAGS} ${FCCFLAGS} -O2 -fomit-frame-pointer -funroll-all-loops -finline-functions -Wall -W -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wstrict-prototypes -Wno-unused -Winline"
|
CFLAGS="${CFLAGS} ${FCCFLAGS} -O2 -fomit-frame-pointer -funroll-all-loops -finline-functions -Wall -W -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wstrict-prototypes -Wno-unused -Winline"
|
||||||
|
@ -399,23 +390,29 @@ else
|
||||||
echo "Readline: no"
|
echo "Readline: no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "${ENABLE_DEBUG}" = "yes"; then
|
|
||||||
echo "Debug: yes"
|
|
||||||
else
|
|
||||||
echo "Debug: no"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "${profiling_flag}" = "yes"; then
|
if test "${profiling_flag}" = "yes"; then
|
||||||
echo "Profiling: yes"
|
echo "Profiling: yes"
|
||||||
else
|
else
|
||||||
echo "Profiling: no"
|
echo "Profiling: no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl if test "${ENABLE_FUNCTIONCHECK}" = "yes"; then
|
if test "${ENABLE_DEBUG}" = "yes"; then
|
||||||
dnl echo "FunctionCheck: yes"
|
echo "Debug: yes"
|
||||||
dnl else
|
else
|
||||||
dnl echo "FunctionCheck: no"
|
echo "Debug: no"
|
||||||
dnl fi
|
fi
|
||||||
|
|
||||||
|
if test "${ENABLE_TRAPONFPE}" = "yes"; then
|
||||||
|
echo "Trap on FPE (debug): yes"
|
||||||
|
else
|
||||||
|
echo "Trap on FPE (debug): no"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "${ENABLE_FPECHECK}" = "yes"; then
|
||||||
|
echo "Check FPE (debug): yes"
|
||||||
|
else
|
||||||
|
echo "Check FPE (debug): no"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "**************************************************************"
|
echo "**************************************************************"
|
||||||
echo
|
echo
|
||||||
|
|
|
@ -111,10 +111,9 @@ libfluidsynth_la_LIBADD = $(LIBFLUID_LIBS) $(LASH_LIBS) $(LADCCA_LIBS) \
|
||||||
$(READLINE_LIBS) $(COREAUDIO_LIBS) $(JACK_LIBS) $(ALSA_LIBS)
|
$(READLINE_LIBS) $(COREAUDIO_LIBS) $(JACK_LIBS) $(ALSA_LIBS)
|
||||||
libfluidsynth_la_LDFLAGS = \
|
libfluidsynth_la_LDFLAGS = \
|
||||||
-version-info @LT_VERSION_INFO@ \
|
-version-info @LT_VERSION_INFO@ \
|
||||||
-export-dynamic @FCLDFLAGS@ $(LIBFLUID_LDFLAGS)
|
-export-dynamic $(LIBFLUID_LDFLAGS)
|
||||||
libfluidsynth_la_CPPFLAGS = $(LIBFLUID_CPPFLAGS)
|
libfluidsynth_la_CPPFLAGS = $(LIBFLUID_CPPFLAGS)
|
||||||
|
|
||||||
fluidsynth_SOURCES = fluidsynth.c
|
fluidsynth_SOURCES = fluidsynth.c
|
||||||
fluidsynth_LDADD = libfluidsynth.la
|
fluidsynth_LDADD = libfluidsynth.la
|
||||||
fluidsynth_LDFLAGS = @FCLDFLAGS@
|
|
||||||
fluidsynth_CPPFLAGS = $(FLUIDSYNTH_CPPFLAGS)
|
fluidsynth_CPPFLAGS = $(FLUIDSYNTH_CPPFLAGS)
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
/* Define to activate debugging message */
|
/* Define to activate debugging message */
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
|
|
||||||
|
/* Define to enable FPE checks */
|
||||||
|
#undef FPE_CHECK
|
||||||
|
|
||||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||||
#undef HAVE_ARPA_INET_H
|
#undef HAVE_ARPA_INET_H
|
||||||
|
|
||||||
|
@ -150,6 +153,9 @@
|
||||||
/* Define to 1 if you have the ANSI C header files. */
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
#undef STDC_HEADERS
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
|
/* Define to enable SIGFPE assertions */
|
||||||
|
#undef TRAP_ON_FPE
|
||||||
|
|
||||||
/* Version number of package */
|
/* Version number of package */
|
||||||
#undef VERSION
|
#undef VERSION
|
||||||
|
|
||||||
|
|
|
@ -477,9 +477,7 @@ void fluid_chorus_processmix(fluid_chorus_t* chorus, fluid_real_t *in,
|
||||||
chorus->phase[i] %= (chorus->modulation_period_samples);
|
chorus->phase[i] %= (chorus->modulation_period_samples);
|
||||||
} /* foreach chorus block */
|
} /* foreach chorus block */
|
||||||
|
|
||||||
/* average values based on number of chorus stages */
|
d_out *= chorus->level;
|
||||||
if (chorus->number_blocks)
|
|
||||||
d_out /= chorus->number_blocks;
|
|
||||||
|
|
||||||
/* Add the chorus sum d_out to output */
|
/* Add the chorus sum d_out to output */
|
||||||
left_out[sample_index] += d_out;
|
left_out[sample_index] += d_out;
|
||||||
|
@ -547,9 +545,7 @@ void fluid_chorus_processreplace(fluid_chorus_t* chorus, fluid_real_t *in,
|
||||||
chorus->phase[i] %= (chorus->modulation_period_samples);
|
chorus->phase[i] %= (chorus->modulation_period_samples);
|
||||||
} /* foreach chorus block */
|
} /* foreach chorus block */
|
||||||
|
|
||||||
/* average values based on number of chorus stages */
|
d_out *= chorus->level;
|
||||||
if (chorus->number_blocks)
|
|
||||||
d_out /= chorus->number_blocks;
|
|
||||||
|
|
||||||
/* Store the chorus sum d_out to output */
|
/* Store the chorus sum d_out to output */
|
||||||
left_out[sample_index] = d_out;
|
left_out[sample_index] = d_out;
|
||||||
|
|
|
@ -27,6 +27,14 @@
|
||||||
#include "fluid_settings.h"
|
#include "fluid_settings.h"
|
||||||
#include "fluid_sfont.h"
|
#include "fluid_sfont.h"
|
||||||
|
|
||||||
|
#ifdef TRAP_ON_FPE
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <fenv.h>
|
||||||
|
|
||||||
|
/* seems to not be declared in fenv.h */
|
||||||
|
extern int feenableexcept (int excepts);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
fluid_sfloader_t* new_fluid_defsfloader(void);
|
fluid_sfloader_t* new_fluid_defsfloader(void);
|
||||||
|
|
||||||
|
@ -152,13 +160,18 @@ fluid_synth_init()
|
||||||
{
|
{
|
||||||
fluid_synth_initialized++;
|
fluid_synth_initialized++;
|
||||||
|
|
||||||
|
#ifdef TRAP_ON_FPE
|
||||||
|
/* Turn on floating point exception traps */
|
||||||
|
feenableexcept (FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID);
|
||||||
|
#endif
|
||||||
|
|
||||||
fluid_conversion_config();
|
fluid_conversion_config();
|
||||||
|
|
||||||
fluid_dsp_float_config();
|
fluid_dsp_float_config();
|
||||||
|
|
||||||
fluid_sys_config();
|
fluid_sys_config();
|
||||||
|
|
||||||
init_dither();
|
init_dither();
|
||||||
|
|
||||||
|
|
||||||
/* SF2.01 page 53 section 8.4.1: MIDI Note-On Velocity to Initial Attenuation */
|
/* SF2.01 page 53 section 8.4.1: MIDI Note-On Velocity to Initial Attenuation */
|
||||||
|
@ -464,87 +477,57 @@ new_fluid_synth(fluid_settings_t *settings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the sample buffers
|
/* Allocate the sample buffers */
|
||||||
*
|
|
||||||
* GCC seems to have a bug with alignment (address must be multiple
|
|
||||||
* of 16 bytes. So we have to align for ourselves... As soon as
|
|
||||||
* GCC aligns reliably, this mess can be cleaned up.
|
|
||||||
*/
|
|
||||||
|
|
||||||
synth->left_buf = NULL;
|
synth->left_buf = NULL;
|
||||||
synth->right_buf = NULL;
|
synth->right_buf = NULL;
|
||||||
synth->left_ubuf = NULL;
|
|
||||||
synth->right_ubuf = NULL;
|
|
||||||
synth->fx_left_buf = NULL;
|
synth->fx_left_buf = NULL;
|
||||||
synth->fx_right_buf = NULL;
|
synth->fx_right_buf = NULL;
|
||||||
synth->fx_left_ubuf = NULL;
|
|
||||||
synth->fx_right_ubuf = NULL;
|
|
||||||
|
|
||||||
/* Left and right audio buffers */
|
/* Left and right audio buffers */
|
||||||
|
|
||||||
synth->left_buf = FLUID_ARRAY(fluid_real_t*, synth->nbuf);
|
synth->left_buf = FLUID_ARRAY(fluid_real_t*, synth->nbuf);
|
||||||
synth->right_buf = FLUID_ARRAY(fluid_real_t*, synth->nbuf);
|
synth->right_buf = FLUID_ARRAY(fluid_real_t*, synth->nbuf);
|
||||||
synth->left_ubuf = FLUID_ARRAY(fluid_real_t*, synth->nbuf);
|
|
||||||
synth->right_ubuf = FLUID_ARRAY(fluid_real_t*, synth->nbuf);
|
|
||||||
|
|
||||||
if ((synth->left_buf == NULL) || (synth->right_buf == NULL) ||
|
if ((synth->left_buf == NULL) || (synth->right_buf == NULL)) {
|
||||||
(synth->left_ubuf == NULL) || (synth->right_ubuf == NULL)) {
|
|
||||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||||
goto error_recovery;
|
goto error_recovery;
|
||||||
}
|
}
|
||||||
|
|
||||||
FLUID_MEMSET(synth->left_buf, 0, synth->nbuf * sizeof(fluid_real_t*));
|
FLUID_MEMSET(synth->left_buf, 0, synth->nbuf * sizeof(fluid_real_t*));
|
||||||
FLUID_MEMSET(synth->right_buf, 0, synth->nbuf * sizeof(fluid_real_t*));
|
FLUID_MEMSET(synth->right_buf, 0, synth->nbuf * sizeof(fluid_real_t*));
|
||||||
FLUID_MEMSET(synth->left_ubuf, 0, synth->nbuf * sizeof(fluid_real_t*));
|
|
||||||
FLUID_MEMSET(synth->right_ubuf, 0, synth->nbuf * sizeof(fluid_real_t*));
|
|
||||||
|
|
||||||
for (i = 0; i < synth->nbuf; i++) {
|
for (i = 0; i < synth->nbuf; i++) {
|
||||||
|
|
||||||
/* +4: add four floats for 16 added bytes */
|
synth->left_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE);
|
||||||
|
synth->right_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE);
|
||||||
|
|
||||||
synth->left_ubuf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE + 4);
|
if ((synth->left_buf[i] == NULL) || (synth->right_buf[i] == NULL)) {
|
||||||
synth->right_ubuf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE + 4);
|
|
||||||
|
|
||||||
if ((synth->left_ubuf[i] == NULL) || (synth->right_ubuf[i] == NULL)) {
|
|
||||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||||
goto error_recovery;
|
goto error_recovery;
|
||||||
}
|
}
|
||||||
|
|
||||||
synth->left_buf[i] = (fluid_real_t*) FLUID_ALIGN16BYTE(synth->left_ubuf[i]);
|
|
||||||
synth->right_buf[i] = (fluid_real_t*) FLUID_ALIGN16BYTE(synth->right_ubuf[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Effects audio buffers */
|
/* Effects audio buffers */
|
||||||
|
|
||||||
synth->fx_left_buf = FLUID_ARRAY(fluid_real_t*, synth->effects_channels);
|
synth->fx_left_buf = FLUID_ARRAY(fluid_real_t*, synth->effects_channels);
|
||||||
synth->fx_right_buf = FLUID_ARRAY(fluid_real_t*, synth->effects_channels);
|
synth->fx_right_buf = FLUID_ARRAY(fluid_real_t*, synth->effects_channels);
|
||||||
synth->fx_left_ubuf = FLUID_ARRAY(fluid_real_t*, synth->effects_channels);
|
|
||||||
synth->fx_right_ubuf = FLUID_ARRAY(fluid_real_t*, synth->effects_channels);
|
|
||||||
|
|
||||||
if ((synth->fx_left_buf == NULL) || (synth->fx_left_ubuf == NULL) ||
|
if ((synth->fx_left_buf == NULL) || (synth->fx_right_buf == NULL)) {
|
||||||
(synth->fx_right_buf == NULL) || (synth->fx_right_ubuf == NULL)) {
|
|
||||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||||
goto error_recovery;
|
goto error_recovery;
|
||||||
}
|
}
|
||||||
|
|
||||||
FLUID_MEMSET(synth->fx_left_ubuf, 0, 2 * sizeof(fluid_real_t*));
|
|
||||||
FLUID_MEMSET(synth->fx_left_buf, 0, 2 * sizeof(fluid_real_t*));
|
FLUID_MEMSET(synth->fx_left_buf, 0, 2 * sizeof(fluid_real_t*));
|
||||||
FLUID_MEMSET(synth->fx_right_ubuf, 0, 2 * sizeof(fluid_real_t*));
|
|
||||||
FLUID_MEMSET(synth->fx_right_buf, 0, 2 * sizeof(fluid_real_t*));
|
FLUID_MEMSET(synth->fx_right_buf, 0, 2 * sizeof(fluid_real_t*));
|
||||||
|
|
||||||
for (i = 0; i < synth->effects_channels; i++) {
|
for (i = 0; i < synth->effects_channels; i++) {
|
||||||
|
synth->fx_left_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE);
|
||||||
|
synth->fx_right_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE);
|
||||||
|
|
||||||
/* +4: add four floats for 16 added bytes */
|
if ((synth->fx_left_buf[i] == NULL) || (synth->fx_right_buf[i] == NULL)) {
|
||||||
synth->fx_left_ubuf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE + 4);
|
|
||||||
synth->fx_right_ubuf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE + 4);
|
|
||||||
|
|
||||||
if ((synth->fx_left_ubuf[i] == NULL) || (synth->fx_right_ubuf[i] == NULL)) {
|
|
||||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||||
goto error_recovery;
|
goto error_recovery;
|
||||||
}
|
}
|
||||||
|
|
||||||
synth->fx_left_buf[i] = (fluid_real_t*) FLUID_ALIGN16BYTE(synth->fx_left_ubuf[i]);
|
|
||||||
synth->fx_right_buf[i] = (fluid_real_t*) FLUID_ALIGN16BYTE(synth->fx_right_ubuf[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -655,45 +638,41 @@ delete_fluid_synth(fluid_synth_t* synth)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free all the sample buffers */
|
/* free all the sample buffers */
|
||||||
if (synth->left_ubuf != NULL) {
|
if (synth->left_buf != NULL) {
|
||||||
for (i = 0; i < synth->nbuf; i++) {
|
for (i = 0; i < synth->nbuf; i++) {
|
||||||
if (synth->left_ubuf[i] != NULL) {
|
if (synth->left_buf[i] != NULL) {
|
||||||
FLUID_FREE(synth->left_ubuf[i]);
|
FLUID_FREE(synth->left_buf[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FLUID_FREE(synth->left_ubuf);
|
FLUID_FREE(synth->left_buf);
|
||||||
}
|
}
|
||||||
FLUID_FREE(synth->left_buf);
|
|
||||||
|
|
||||||
if (synth->right_ubuf != NULL) {
|
if (synth->right_buf != NULL) {
|
||||||
for (i = 0; i < synth->nbuf; i++) {
|
for (i = 0; i < synth->nbuf; i++) {
|
||||||
if (synth->right_ubuf[i] != NULL) {
|
if (synth->right_buf[i] != NULL) {
|
||||||
FLUID_FREE(synth->right_ubuf[i]);
|
FLUID_FREE(synth->right_buf[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FLUID_FREE(synth->right_ubuf);
|
FLUID_FREE(synth->right_buf);
|
||||||
}
|
}
|
||||||
FLUID_FREE(synth->right_buf);
|
|
||||||
|
|
||||||
if (synth->fx_left_ubuf != NULL) {
|
if (synth->fx_left_buf != NULL) {
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
if (synth->fx_left_ubuf[i] != NULL) {
|
if (synth->fx_left_buf[i] != NULL) {
|
||||||
FLUID_FREE(synth->fx_left_ubuf[i]);
|
FLUID_FREE(synth->fx_left_buf[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FLUID_FREE(synth->fx_left_ubuf);
|
FLUID_FREE(synth->fx_left_buf);
|
||||||
}
|
}
|
||||||
FLUID_FREE(synth->fx_left_buf);
|
|
||||||
|
|
||||||
if (synth->fx_right_ubuf != NULL) {
|
if (synth->fx_right_buf != NULL) {
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
if (synth->fx_right_ubuf[i] != NULL) {
|
if (synth->fx_right_buf[i] != NULL) {
|
||||||
FLUID_FREE(synth->fx_right_ubuf[i]);
|
FLUID_FREE(synth->fx_right_buf[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FLUID_FREE(synth->fx_right_ubuf);
|
FLUID_FREE(synth->fx_right_buf);
|
||||||
}
|
}
|
||||||
FLUID_FREE(synth->fx_right_buf);
|
|
||||||
|
|
||||||
/* release the reverb module */
|
/* release the reverb module */
|
||||||
if (synth->reverb != NULL) {
|
if (synth->reverb != NULL) {
|
||||||
|
|
|
@ -128,11 +128,6 @@ struct _fluid_synth_t
|
||||||
fluid_real_t** fx_left_buf;
|
fluid_real_t** fx_left_buf;
|
||||||
fluid_real_t** fx_right_buf;
|
fluid_real_t** fx_right_buf;
|
||||||
|
|
||||||
fluid_real_t** left_ubuf; /* Stores the unaligned buffers (see new_fluid_synth) */
|
|
||||||
fluid_real_t** right_ubuf; /* Stores the unaligned buffers (see new_fluid_synth) */
|
|
||||||
fluid_real_t** fx_left_ubuf; /* Stores the unaligned buffers (see new_fluid_synth) */
|
|
||||||
fluid_real_t** fx_right_ubuf; /* Stores the unaligned buffers (see new_fluid_synth) */
|
|
||||||
|
|
||||||
fluid_revmodel_t* reverb;
|
fluid_revmodel_t* reverb;
|
||||||
fluid_chorus_t* chorus;
|
fluid_chorus_t* chorus;
|
||||||
int cur; /** the current sample in the audio buffers to be output */
|
int cur; /** the current sample in the audio buffers to be output */
|
||||||
|
@ -154,7 +149,6 @@ struct _fluid_synth_t
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** returns 1 if the value has been set, 0 otherwise */
|
/** returns 1 if the value has been set, 0 otherwise */
|
||||||
int fluid_synth_setstr(fluid_synth_t* synth, char* name, char* str);
|
int fluid_synth_setstr(fluid_synth_t* synth, char* name, char* str);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
|
|
||||||
#include "fluid_sys.h"
|
#include "fluid_sys.h"
|
||||||
//#include <fpu_control.h>
|
|
||||||
|
|
||||||
static char fluid_errbuf[512]; /* buffer for error message */
|
static char fluid_errbuf[512]; /* buffer for error message */
|
||||||
|
|
||||||
|
@ -796,6 +795,7 @@ void fluid_time_config(void)
|
||||||
{
|
{
|
||||||
if (fluid_cpu_frequency < 0.0) {
|
if (fluid_cpu_frequency < 0.0) {
|
||||||
fluid_cpu_frequency = fluid_estimate_cpu_frequency() / 1000000.0;
|
fluid_cpu_frequency = fluid_estimate_cpu_frequency() / 1000000.0;
|
||||||
|
if (fluid_cpu_frequency == 0.0) fluid_cpu_frequency = 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -856,7 +856,7 @@ double fluid_estimate_cpu_frequency(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#ifdef FPE_CHECK
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
*
|
*
|
||||||
|
@ -890,7 +890,8 @@ double fluid_estimate_cpu_frequency(void)
|
||||||
#define _FPU_CLR_SW() __asm__ ("fnclex" : : )
|
#define _FPU_CLR_SW() __asm__ ("fnclex" : : )
|
||||||
|
|
||||||
/* Purpose:
|
/* Purpose:
|
||||||
* Checks, if the floating point unit has produced an exception in the meantime.
|
* Checks, if the floating point unit has produced an exception, print a message
|
||||||
|
* if so and clear the exception.
|
||||||
*/
|
*/
|
||||||
unsigned int fluid_check_fpe_i386(char* explanation)
|
unsigned int fluid_check_fpe_i386(char* explanation)
|
||||||
{
|
{
|
||||||
|
@ -899,11 +900,10 @@ unsigned int fluid_check_fpe_i386(char* explanation)
|
||||||
_FPU_GET_SW(s);
|
_FPU_GET_SW(s);
|
||||||
_FPU_CLR_SW();
|
_FPU_CLR_SW();
|
||||||
|
|
||||||
if ((s & _FPU_STATUS_IE)
|
s &= _FPU_STATUS_IE | _FPU_STATUS_DE | _FPU_STATUS_ZE | _FPU_STATUS_OE | _FPU_STATUS_UE;
|
||||||
|| (s & _FPU_STATUS_DE)
|
|
||||||
|| (s & _FPU_STATUS_ZE)
|
if (s)
|
||||||
|| (s & _FPU_STATUS_OE)
|
{
|
||||||
|| (s & _FPU_STATUS_UE)) {
|
|
||||||
FLUID_LOG(FLUID_WARN, "FPE exception (before or in %s): %s%s%s%s%s", explanation,
|
FLUID_LOG(FLUID_WARN, "FPE exception (before or in %s): %s%s%s%s%s", explanation,
|
||||||
(s & _FPU_STATUS_IE) ? "Invalid operation " : "",
|
(s & _FPU_STATUS_IE) ? "Invalid operation " : "",
|
||||||
(s & _FPU_STATUS_DE) ? "Denormal number " : "",
|
(s & _FPU_STATUS_DE) ? "Denormal number " : "",
|
||||||
|
@ -915,10 +915,18 @@ unsigned int fluid_check_fpe_i386(char* explanation)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
/* Purpose:
|
||||||
|
* Clear floating point exception.
|
||||||
|
*/
|
||||||
|
void fluid_clear_fpe_i386 (void)
|
||||||
|
{
|
||||||
|
_FPU_CLR_SW();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ifdef FPE_CHECK
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif // #else (its POSIX)
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
|
|
|
@ -284,14 +284,15 @@ extern fluid_profile_data_t fluid_profile_data[];
|
||||||
fluid_check_fpe() checks for "unnormalized numbers" and other
|
fluid_check_fpe() checks for "unnormalized numbers" and other
|
||||||
exceptions of the floating point processsor.
|
exceptions of the floating point processsor.
|
||||||
*/
|
*/
|
||||||
#if 0
|
#ifdef FPE_CHECK
|
||||||
/* Enable FPE exception check */
|
|
||||||
#define fluid_check_fpe(expl) fluid_check_fpe_i386(expl)
|
#define fluid_check_fpe(expl) fluid_check_fpe_i386(expl)
|
||||||
|
#define fluid_clear_fpe() fluid_clear_fpe_i386()
|
||||||
#else
|
#else
|
||||||
/* Disable FPE exception check */
|
|
||||||
#define fluid_check_fpe(expl)
|
#define fluid_check_fpe(expl)
|
||||||
|
#define fluid_clear_fpe()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int fluid_check_fpe_i386(char * explanation_in_case_of_fpe);
|
unsigned int fluid_check_fpe_i386(char * explanation_in_case_of_fpe);
|
||||||
|
void fluid_clear_fpe_i386(void);
|
||||||
|
|
||||||
#endif /* _FLUID_SYS_H */
|
#endif /* _FLUID_SYS_H */
|
||||||
|
|
|
@ -46,21 +46,6 @@
|
||||||
#define FLUID_MIN_VOLENVRELEASE -7200.0f /* ~16ms */
|
#define FLUID_MIN_VOLENVRELEASE -7200.0f /* ~16ms */
|
||||||
|
|
||||||
|
|
||||||
/* Purpose:
|
|
||||||
* zap_almost_zero will return a number, as long as its
|
|
||||||
* absolute value is over a certain threshold. Otherwise 0. See
|
|
||||||
* fluid_rev.c for documentation (denormal numbers)
|
|
||||||
*/
|
|
||||||
|
|
||||||
# if defined(WITH_FLOAT)
|
|
||||||
# define zap_almost_zero(_sample) \
|
|
||||||
((((*(unsigned int*)&(_sample))&0x7f800000) < 0x08000000)? 0.0f : (_sample))
|
|
||||||
# else
|
|
||||||
/* 1e-20 was chosen as an arbitrary (small) threshold. */
|
|
||||||
#define zap_almost_zero(_sample) ((abs(_sample) < 1e-20)? 0.0f : (_sample))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static inline void fluid_voice_effects (fluid_voice_t *voice, int count,
|
static inline void fluid_voice_effects (fluid_voice_t *voice, int count,
|
||||||
fluid_real_t* dsp_left_buf,
|
fluid_real_t* dsp_left_buf,
|
||||||
fluid_real_t* dsp_right_buf,
|
fluid_real_t* dsp_right_buf,
|
||||||
|
@ -267,15 +252,9 @@ fluid_voice_write(fluid_voice_t* voice,
|
||||||
fluid_real_t target_amp; /* target amplitude */
|
fluid_real_t target_amp; /* target amplitude */
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
/* All variables starting with dsp_ are used by the DSP
|
|
||||||
loop. Documented in fluid_dsp_core.c */
|
|
||||||
|
|
||||||
|
|
||||||
int dsp_interp_method = voice->interp_method;
|
int dsp_interp_method = voice->interp_method;
|
||||||
|
|
||||||
/* +4: add four floats for 16 added bytes */
|
fluid_real_t dsp_buf[FLUID_BUFSIZE];
|
||||||
fluid_real_t dsp_buf_unaligned[FLUID_BUFSIZE+4];
|
|
||||||
fluid_real_t* dsp_buf = (fluid_real_t*) FLUID_ALIGN16BYTE(&dsp_buf_unaligned);
|
|
||||||
fluid_env_data_t* env_data;
|
fluid_env_data_t* env_data;
|
||||||
fluid_real_t x;
|
fluid_real_t x;
|
||||||
|
|
||||||
|
@ -603,7 +582,6 @@ fluid_voice_write(fluid_voice_t* voice,
|
||||||
* The buffer has to be filled from 0 to FLUID_BUFSIZE-1.
|
* The buffer has to be filled from 0 to FLUID_BUFSIZE-1.
|
||||||
* Depending on the position in the loop and the loop size, this
|
* Depending on the position in the loop and the loop size, this
|
||||||
* may require several runs. */
|
* may require several runs. */
|
||||||
fluid_check_fpe ("voice_write DSP processing");
|
|
||||||
|
|
||||||
voice->dsp_buf = dsp_buf;
|
voice->dsp_buf = dsp_buf;
|
||||||
|
|
||||||
|
@ -624,6 +602,8 @@ fluid_voice_write(fluid_voice_t* voice,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fluid_check_fpe ("voice_write interpolation");
|
||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
fluid_voice_effects (voice, count, dsp_left_buf, dsp_right_buf,
|
fluid_voice_effects (voice, count, dsp_left_buf, dsp_right_buf,
|
||||||
dsp_reverb_buf, dsp_chorus_buf);
|
dsp_reverb_buf, dsp_chorus_buf);
|
||||||
|
@ -698,12 +678,10 @@ fluid_voice_effects (fluid_voice_t *voice, int count,
|
||||||
int dsp_i;
|
int dsp_i;
|
||||||
float v;
|
float v;
|
||||||
|
|
||||||
/* filter (implement the voice filter according to Soundfont standard) */
|
/* filter (implement the voice filter according to SoundFont standard) */
|
||||||
|
|
||||||
/* Check for denormal number (too close to zero) once in a
|
/* Check for denormal number (too close to zero). */
|
||||||
* while. This is not a big concern here - why would someone play a
|
if (fabs (dsp_hist1) < 1e-20) dsp_hist1 = 0.0f; /* FIXME JMG - Is this even needed? */
|
||||||
* sample with an empty tail? */
|
|
||||||
dsp_hist1 = zap_almost_zero(dsp_hist1);
|
|
||||||
|
|
||||||
/* Two versions of the filter loop. One, while the filter is
|
/* Two versions of the filter loop. One, while the filter is
|
||||||
* changing towards its new setting. The other, if the filter
|
* changing towards its new setting. The other, if the filter
|
||||||
|
@ -792,6 +770,8 @@ fluid_voice_effects (fluid_voice_t *voice, int count,
|
||||||
voice->b02 = dsp_b02;
|
voice->b02 = dsp_b02;
|
||||||
voice->b1 = dsp_b1;
|
voice->b1 = dsp_b1;
|
||||||
voice->filter_coeff_incr_count = dsp_filter_coeff_incr_count;
|
voice->filter_coeff_incr_count = dsp_filter_coeff_incr_count;
|
||||||
|
|
||||||
|
fluid_check_fpe ("voice_effects");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -277,21 +277,6 @@ typedef FILE* fluid_file;
|
||||||
#define fluid_clip(_val, _min, _max) \
|
#define fluid_clip(_val, _min, _max) \
|
||||||
{ (_val) = ((_val) < (_min))? (_min) : (((_val) > (_max))? (_max) : (_val)); }
|
{ (_val) = ((_val) < (_min))? (_min) : (((_val) > (_max))? (_max) : (_val)); }
|
||||||
|
|
||||||
/* Purpose:
|
|
||||||
* Some commands (SSE extensions on Pentium) need aligned data(
|
|
||||||
* The address must be ...xxx0.
|
|
||||||
* Take a pointer, and round it up to the next suitable address.
|
|
||||||
* Obviously, one has to allocate 15 bytes of additional memory.
|
|
||||||
* As soon as proper alignment is supported by the compiler, this
|
|
||||||
* can be removed.
|
|
||||||
*/
|
|
||||||
#ifdef ENABLE_SSE
|
|
||||||
/* FIXME - This is broken on AMD 64 - only used if SSE enabled */
|
|
||||||
#define FLUID_ALIGN16BYTE(ptr)(((int)(ptr)+15) & (~0xFL))
|
|
||||||
#else
|
|
||||||
#define FLUID_ALIGN16BYTE(ptr) ptr
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if WITH_FTS
|
#if WITH_FTS
|
||||||
#define FLUID_PRINTF post
|
#define FLUID_PRINTF post
|
||||||
#define FLUID_FLUSH()
|
#define FLUID_FLUSH()
|
||||||
|
|
Loading…
Reference in a new issue