Added fluid_atten2amp for non-standard attenuation and reverted

fluid_cb2amp to original specifications, volume envelope much improved.
This commit is contained in:
Element Green 2005-06-11 11:06:43 +00:00
parent 196ca5724c
commit 4a173dafec
5 changed files with 301 additions and 26 deletions

View file

@ -1,3 +1,15 @@
2005-06-11 <jgreen@users.sourceforge.net>
* fluidsynth.prj: Added Anjuta project file.
* src/fluid_conv.c: fluid_cb2amp conversion set back to real centibels
and added a new fluid_atten2amp table conversion for non-standard
EMU 8k/10k attenuation.
* src/fluid_voice.c (fluid_voice_write): Updated volume calculations to
use fluid_cb2amp for envelope and LFO, but use fluid_atten2amp for
initial attenuation.
(fluid_voice_noteoff): Re-coded volenv_val attack conversion and
verified.
2005-06-10 <jgreen@users.sourceforge.net>
* src/fluid_phase.h: Patch from Sean Bolton to fix big endian long long

235
fluidsynth/fluidsynth.prj Normal file
View file

@ -0,0 +1,235 @@
# Anjuta Version 1.2.2
Compatibility Level: 1
<PROJECT_DESCRIPTION_START>
A SoundFont based software synthesizer.<PROJECT_DESCRIPTION_END>
<CONFIG_PROGS_START>
<CONFIG_PROGS_END>
<CONFIG_LIBS_START>
<CONFIG_LIBS_END>
<CONFIG_HEADERS_START>
<CONFIG_HEADERS_END>
<CONFIG_CHARACTERISTICS_START>
<CONFIG_CHARACTERISTICS_END>
<CONFIG_LIB_FUNCS_START>
<CONFIG_LIB_FUNCS_END>
<CONFIG_ADDITIONAL_START>
<CONFIG_ADDITIONAL_END>
<CONFIG_FILES_START>
<CONFIG_FILES_END>
<MAKEFILE_AM_START>
<MAKEFILE_AM_END>
props.file.type=project
anjuta.version=1.2.2
anjuta.compatibility.level=1
project.name=fluidsynth
project.type=GENERIC
project.target.type=EXECUTABLE
project.version=1.0.5
project.author=Peter Hanappe
project.source.target=fluidsynth
project.has.gettext=0
project.gui.command=
project.programming.language=C
project.excluded.modules=intl
project.config.extra.modules.before=
project.config.extra.modules.after=
project.config.blocked=1
project.config.disable.overwriting=1 1 1 1 1 1 1 1 1
project.menu.entry=fluidsynth Version 1.0.5
project.menu.group=Application
project.menu.comment=fluidsynth Version 1.0.5
project.menu.icon=
project.menu.need.terminal=0
project.configure.options=
anjuta.program.arguments=
preferences.build.option.jobs=0
preferences.build.option.silent=0
preferences.build.option.autosave=0
preferences.make=make
preferences.build.option.keep.going=1
preferences.build.option.warn.undef=0
preferences.autoformat.custom.style= -i8 -sc -bli0 -bl0 -cbi0 -ss
preferences.indent.opening=0
preferences.autoformat.disable=1
preferences.indent.automatic=1
preferences.use.tabs=1
preferences.indent.size=2
preferences.tabsize=8
preferences.indent.closing=0
module.include.name=.
module.include.type=
module.include.files=\
src/fluid_chorus.h\
src/fluidsynth_priv.h\
src/fluid_voice.h\
src/fluid_phase.h\
src/fluid_io.h\
src/fluid_tuning.h\
src/fluid_cmd.h\
src/fluid_gen.h\
src/fluid_mod.h\
src/fluid_rev.h\
src/fluid_sse.h\
src/fluid_sys.h\
src/fluid_ladspa.h\
src/fluid_defsfont.h\
src/fluid_event_priv.h\
src/fluid_midi_router.h\
src/fluid_strtok.h\
src/config.h\
src/fluid_sfont.h\
src/fluid_chan.h\
src/config_win32.h\
src/fluid_conv.h\
src/config_macosx_pb.h\
src/fluid_hash.h\
src/fluid_mdriver.h\
src/fluid_list.h\
src/fluid_midi.h\
src/fluid_synth.h\
src/fluid_settings.h\
src/fluid_adriver.h\
src/fluid_ramsfont.h\
src/config_macosx.h\
src/config_macos.h\
bindings/fluidsynth_jni/src/fluidsynth_Synth.h\
bindings/fluidsynth_jni/src/fluidsynth_Sample.h\
bindings/fluidsynth_jni/src/fluidsynth_jni.h\
bindings/fluidsynth_jni/include/sndfile.h\
bindings/fluidmax/fluidsynth/version.h\
bindings/fluidmax/config_maxmsp43.h\
bindings/fluidmax/ftmax.h\
include/fluidsynth/gen.h\
include/fluidsynth/log.h\
include/fluidsynth/mod.h\
include/fluidsynth/seq.h\
include/fluidsynth/sfont.h\
include/fluidsynth/shell.h\
include/fluidsynth/event.h\
include/fluidsynth/synth.h\
include/fluidsynth/settings.h\
include/fluidsynth/ramsfont.h\
include/fluidsynth/midi.h\
include/fluidsynth/misc.h\
include/fluidsynth/types.h\
include/fluidsynth/voice.h\
include/fluidsynth/audio.h\
include/fluidsynth/seqbind.h\
include/fluidsynth/version.h\
include/fluidsynth.h
module.source.name=.
module.source.type=
module.source.files=\
doc/example.c\
doc/fluidsynth_simple.c\
doc/fluidsynth_fx.c\
src/fluid_chorus.c\
src/fluid_voice.c\
src/fluid_dsp_simple.c\
src/fluid_dsp_float.c\
src/fluid_io.c\
src/fluid_midishare.c\
src/fluid_tuning.c\
src/fluid_cmd.c\
src/fluid_dll.c\
src/fluid_gen.c\
src/fluid_mod.c\
src/fluid_dsp_sse.c\
src/fluid_oss.c\
src/fluid_rev.c\
src/fluid_seq.c\
src/fluid_sys.c\
src/fluid_dsound.c\
src/fluid_ladspa.c\
src/fluid_defsfont.c\
src/fluid_sndmgr.c\
src/fluid_midi_router.c\
src/fluid_coreaudio.c\
src/fluid_strtok.c\
src/fluid_seqbind.c\
src/fluid_dsp_core.c\
src/fluid_alsa.c\
src/fluid_chan.c\
src/fluid_conv.c\
src/fluid_aufile.c\
src/fluid_hash.c\
src/fluid_mdriver.c\
src/fluid_jack.c\
src/fluid_event.c\
src/fluid_list.c\
src/fluid_midi.c\
src/fluid_synth.c\
src/fluidsynth.c\
src/fluid_settings.c\
src/fluid_adriver.c\
src/fluid_ramsfont.c\
src/fluid_winmidi.c\
src/fluid_alsa2.c\
src/fluid_portaudio.c\
bindings/fluidsynth_jni/src/fluidsynth_jni.cpp\
bindings/fluidsynth_jni/src/fluidsynth_Synth.cpp\
bindings/fluidsynth_jni/src/fluidsynth_Sample.cpp\
bindings/fluidsynth_jni/java/fluidsynth/Synth.java\
bindings/fluidsynth_jni/java/fluidsynth/Sample.java\
bindings/fluidsynth_jni/java/fluidsynth/Test.java\
bindings/fluidsynth_jni/java/fluidsynth/FluidException.java\
bindings/fluidmax/fluidmax.c\
bindings/fluidmax/fluidmax_fakefuns.c\
fluidsynth.pc
module.pixmap.name=.
module.pixmap.type=
module.pixmap.files=\
bindings/fluidmax/fluidsynth.jpg
module.data.name=.
module.data.type=
module.data.files=
module.help.name=.
module.help.type=
module.help.files=
module.doc.name=.
module.doc.type=
module.doc.files=\
bindings/README\
bindings/fluidsynth_jni/README\
NEWS\
TODO\
README\
THANKS\
AUTHORS\
INSTALL\
ChangeLog\
COPYING
module.po.files=
compiler.options.supports=
compiler.options.include.paths=\
.\
..
compiler.options.library.paths=
compiler.options.libraries=
compiler.options.libraries.selected=
compiler.options.defines=\
HAVE_CONFIG_H
compiler.options.defines.selected=
compiler.options.warning.buttons=0 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0
compiler.options.optimize.buttons=0 0 1 0
compiler.options.other.buttons=1 0
compiler.options.other.c.flags=
compiler.options.other.l.flags=
compiler.options.other.l.libs=
project.src.paths=

View file

@ -24,6 +24,7 @@
/* conversion tables */
fluid_real_t fluid_ct2hz_tab[FLUID_CENTS_HZ_SIZE];
fluid_real_t fluid_cb2amp_tab[FLUID_CB_AMP_SIZE];
fluid_real_t fluid_atten2amp_tab[FLUID_ATTEN_AMP_SIZE];
fluid_real_t fluid_posbp_tab[128];
fluid_real_t fluid_concave_tab[128];
fluid_real_t fluid_convex_tab[128];
@ -48,14 +49,19 @@ fluid_conversion_config(void)
* Note: SF2.01 section 8.1.3: Initial attenuation range is
* between 0 and 144 dB. Therefore a negative attenuation is
* not allowed.
*
* WARNING!! EMU8k and EMU10k devices don't conform to the SoundFont
* specification in regards to the attenuation. The below calculation
* is an approx. equation for generating a table equivelant to the
* cb_to_amp_table[] in tables.c of the TiMidity++ source.
*/
for (i = 0; i < FLUID_CB_AMP_SIZE; i++) {
fluid_cb2amp_tab[i] = (fluid_real_t) pow(10.0, (double) i / FLUID_CB_POWER_FACTOR);
fluid_cb2amp_tab[i] = (fluid_real_t) pow(10.0, (double) i / -200.0);
}
/* NOTE: EMU8k and EMU10k devices don't conform to the SoundFont
* specification in regards to volume attenuation. The below calculation
* is an approx. equation for generating a table equivelant to the
* cb_to_amp_table[] in tables.c of the TiMidity++ source, which I'm told
* was generated from device testing. By the spec this should be centibels.
*/
for (i = 0; i < FLUID_ATTEN_AMP_SIZE; i++) {
fluid_atten2amp_tab[i] = (fluid_real_t) pow(10.0, (double) i / FLUID_ATTEN_POWER_FACTOR);
}
/* initialize the conversion tables (see fluid_mod.c
@ -128,7 +134,7 @@ fluid_ct2hz(fluid_real_t cents)
/*
* fluid_cb2amp
*
* in: a value between 0 and 961, 0 is no attenuation
* in: a value between 0 and 960, 0 is no attenuation
* out: a value between 1 and 0
*/
fluid_real_t
@ -150,6 +156,23 @@ fluid_cb2amp(fluid_real_t cb)
return fluid_cb2amp_tab[(int) cb];
}
/*
* fluid_atten2amp
*
* in: a value between 0 and 1440, 0 is no attenuation
* out: a value between 1 and 0
*
* Note: Volume attenuation is supposed to be centibels but EMU8k/10k don't
* follow this. Thats the reason for separate fluid_cb2amp and fluid_atten2amp.
*/
fluid_real_t
fluid_atten2amp(fluid_real_t atten)
{
if (atten < 0) return 1.0;
else if (atten >= FLUID_ATTEN_AMP_SIZE) return 0.0;
else return fluid_atten2amp_tab[(int) atten];
}
/*
* fluid_tc2sec_delay
*/

View file

@ -26,17 +26,19 @@
#define FLUID_CENTS_HZ_SIZE 1200
#define FLUID_VEL_CB_SIZE 128
#define FLUID_CB_AMP_SIZE 961
#define FLUID_ATTEN_AMP_SIZE 1441
#define FLUID_PAN_SIZE 1002
/* EMU 8k/10k don't follow spec in regards to volume attenuation in centibels.
* This factor is used in the equation pow (10.0, cb / FLUID_CB_AMP_POWER_FACTOR).
* By the standard this should be -200.0. */
#define FLUID_CB_POWER_FACTOR (-531.509)
/* EMU 8k/10k don't follow spec in regards to volume attenuation.
* This factor is used in the equation pow (10.0, cb / FLUID_ATTEN_POWER_FACTOR).
* By the standard this should be -200.0. */
#define FLUID_ATTEN_POWER_FACTOR (-531.509)
void fluid_conversion_config(void);
fluid_real_t fluid_ct2hz(fluid_real_t cents);
fluid_real_t fluid_cb2amp(fluid_real_t cb);
fluid_real_t fluid_atten2amp(fluid_real_t atten);
fluid_real_t fluid_tc2sec(fluid_real_t tc);
fluid_real_t fluid_tc2sec_delay(fluid_real_t tc);
fluid_real_t fluid_tc2sec_attack(fluid_real_t tc);

View file

@ -493,17 +493,19 @@ fluid_voice_write(fluid_voice_t* voice,
goto post_process;
} else if (voice->volenv_section == FLUID_VOICE_ENVATTACK) {
/* the envelope is in the attack section: ramp linearly to max value.
* A positive modlfo_to_vol should increase volume (negative attenuation).
*/
dsp_amp = (fluid_cb2amp(voice->attenuation + voice->modlfo_val * -voice->modlfo_to_vol)
* voice->volenv_val);
* A positive modlfo_to_vol should increase volume (negative attenuation).
*/
dsp_amp = fluid_atten2amp(voice->attenuation)
* fluid_cb2amp (voice->modlfo_val * -voice->modlfo_to_vol)
* voice->volenv_val;
} else {
fluid_real_t amplitude_that_reaches_noise_floor;
fluid_real_t amp_max;
dsp_amp = fluid_cb2amp(voice->attenuation
+ 960.0f * (1.0f - voice->volenv_val)
+ voice->modlfo_val * -voice->modlfo_to_vol);
dsp_amp = fluid_atten2amp(voice->attenuation)
* fluid_cb2amp (960.0f * (1.0f - voice->volenv_val)
+ voice->modlfo_val * -voice->modlfo_to_vol);
/* Here we are trying to turn off a voice, if the volume has dropped
* low enough.
* Motivation:
@ -543,8 +545,8 @@ fluid_voice_write(fluid_voice_t* voice,
* amplitude of sample and volenv cannot exceed amp_max (since
* volenv_val can only drop):
*/
amp_max = fluid_cb2amp(voice->min_attenuation_cB
+ 960.0f * (1.0f - voice->volenv_val));
amp_max = fluid_atten2amp(voice->min_attenuation_cB) * voice->volenv_val;
/* printf("Att min: %f Amp max: %f Limit: %f\n",voice->min_attenuation_cB,amp_max, amplitude_that_reaches_noise_floor); */
@ -1632,13 +1634,14 @@ fluid_voice_noteoff(fluid_voice_t* voice)
if (voice->volenv_section == FLUID_VOICE_ENVATTACK) {
/* A voice is turned off during the attack section of the volume
* envelope. The attack section ramps up linearly with
* amplitude. The other sections use logarithmic scaling. So
* convert from linear amplitude to cb.
* amplitude. The other sections use logarithmic scaling. Calculate new
* volenv_val to achieve equievalent amplitude during the release phase
* for seamless volume transition.
*/
if (voice->volenv_val > 0){
fluid_real_t attn_and_lfo = voice->attenuation + voice->modlfo_val * -voice->modlfo_to_vol;
fluid_real_t amp = voice->volenv_val * pow (10.0, attn_and_lfo / FLUID_CB_POWER_FACTOR);
fluid_real_t env_value = - ((FLUID_CB_POWER_FACTOR * log (amp) / log (10.) - attn_and_lfo) / 960.0 - 1);
fluid_real_t lfo = voice->modlfo_val * -voice->modlfo_to_vol;
fluid_real_t amp = voice->volenv_val * pow (10.0, lfo / -200);
fluid_real_t env_value = - ((-200 * log (amp) / log (10.0) - lfo) / 960.0 - 1);
fluid_clip (env_value, 0.0, 1.0);
voice->volenv_val = env_value;
}