Path: blob/master/libs/fluidsynth/src/rvoice/fluid_rvoice.h
4396 views
/* FluidSynth - A Software Synthesizer1*2* Copyright (C) 2003 Peter Hanappe and others.3*4* This library is free software; you can redistribute it and/or5* modify it under the terms of the GNU Lesser General Public License6* as published by the Free Software Foundation; either version 2.1 of7* the License, or (at your option) any later version.8*9* This library is distributed in the hope that it will be useful, but10* WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12* Lesser General Public License for more details.13*14* You should have received a copy of the GNU Lesser General Public15* License along with this library; if not, write to the Free16* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA17* 02110-1301, USA18*/192021#ifndef _FLUID_RVOICE_H22#define _FLUID_RVOICE_H2324#include "fluidsynth_priv.h"25#include "fluid_iir_filter.h"26#include "fluid_adsr_env.h"27#include "fluid_lfo.h"28#include "fluid_phase.h"29#include "fluid_sfont.h"3031typedef struct _fluid_rvoice_envlfo_t fluid_rvoice_envlfo_t;32typedef struct _fluid_rvoice_dsp_t fluid_rvoice_dsp_t;33typedef struct _fluid_rvoice_buffers_t fluid_rvoice_buffers_t;34typedef struct _fluid_rvoice_t fluid_rvoice_t;3536/* Smallest amplitude that can be perceived (full scale is +/- 0.5)37* 16 bits => 96+4=100 dB dynamic range => 0.0000138* 24 bits => 144-4 = 140 dB dynamic range => 1.e-739* 1.e-7 * 2 == 2.e-7 :)40*/41#define FLUID_NOISE_FLOOR ((fluid_real_t)2.e-7)4243enum fluid_loop44{45FLUID_UNLOOPED = 0,46FLUID_LOOP_DURING_RELEASE = 1,47FLUID_START_ON_RELEASE = 2, /* this is a looping mode introduced by Polyphone, see #1398 for more info */48FLUID_LOOP_UNTIL_RELEASE = 349};5051/*52* rvoice ticks-based parameters53* These parameters must be updated even if the voice is currently quiet.54*/55struct _fluid_rvoice_envlfo_t56{57/* Note-off minimum length */58unsigned int ticks;59unsigned int noteoff_ticks;6061/* vol env */62fluid_adsr_env_t volenv;6364/* mod env */65fluid_adsr_env_t modenv;66fluid_real_t modenv_to_fc;67fluid_real_t modenv_to_pitch;6869/* mod lfo */70fluid_lfo_t modlfo;71fluid_real_t modlfo_to_fc;72fluid_real_t modlfo_to_pitch;73fluid_real_t modlfo_to_vol;7475/* vib lfo */76fluid_lfo_t viblfo;77fluid_real_t viblfo_to_pitch;78};7980/*81* rvoice parameters needed for dsp interpolation82*/83struct _fluid_rvoice_dsp_t84{85/* interpolation method, as in fluid_interp in fluidsynth.h */86enum fluid_interp interp_method;87enum fluid_loop samplemode;8889/* Flag that is set as soon as the first loop is completed. */90char has_looped;9192/* Flag that initiates, that sample-related parameters have to be checked. */93char check_sample_sanity_flag;9495fluid_sample_t *sample;9697/* sample and loop start and end points (offset in sample memory). */98int start;99int end;100int loopstart;101int loopend; /* Note: first point following the loop (superimposed on loopstart) */102103/* Stuff needed for portamento calculations */104fluid_real_t pitchoffset; /* the portamento range in midicents */105fluid_real_t pitchinc; /* the portamento increment in midicents */106107/* Stuff needed for phase calculations */108109fluid_real_t pitch; /* the pitch in midicents */110fluid_real_t root_pitch_hz;111fluid_real_t output_rate;112113/* Stuff needed for amplitude calculations */114115fluid_real_t attenuation; /* the attenuation in centibels */116fluid_real_t prev_attenuation; /* the previous attenuation in centibels117used by fluid_rvoice_multi_retrigger_attack() */118fluid_real_t min_attenuation_cB; /* Estimate on the smallest possible attenuation119* during the lifetime of the voice */120fluid_real_t amplitude_that_reaches_noise_floor_nonloop;121fluid_real_t amplitude_that_reaches_noise_floor_loop;122fluid_real_t synth_gain; /* master gain */123124/* Dynamic input to the interpolator below */125126fluid_real_t amp; /* current linear amplitude */127fluid_real_t amp_incr; /* amplitude increment value for the next FLUID_BUFSIZE samples */128129fluid_phase_t phase; /* the phase (current sample offset) of the sample wave */130fluid_real_t phase_incr; /* the phase increment for the next FLUID_BUFSIZE samples */131};132133/* Currently left, right, reverb, chorus. To be changed if we134ever add surround positioning, or stereo reverb/chorus */135#define FLUID_RVOICE_MAX_BUFS (4)136137/*138* rvoice mixer-related parameters139*/140struct _fluid_rvoice_buffers_t141{142unsigned int count; /* Number of records in "bufs" */143struct144{145/* the actual, linearly interpolated amplitude with which the dsp sample should be mixed into the buf */146fluid_real_t current_amp;147148/* the desired amplitude [...] mixed into the buf (directly set by e.g. rapidly changing PAN events) */149fluid_real_t target_amp;150151/* Mapping to mixdown buffer index */152int mapping;153} bufs[FLUID_RVOICE_MAX_BUFS];154};155156157/*158* Hard real-time parameters needed to synthesize a voice159*/160struct _fluid_rvoice_t161{162fluid_rvoice_envlfo_t envlfo;163fluid_rvoice_dsp_t dsp;164fluid_iir_filter_t resonant_filter; /* IIR resonant dsp filter */165fluid_iir_filter_t resonant_custom_filter; /* optional custom/general-purpose IIR resonant filter */166fluid_rvoice_buffers_t buffers;167};168169170int fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf);171172DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_buffers_set_amp);173DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_buffers_set_mapping);174175DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_noteoff);176DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_voiceoff);177DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_reset);178DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_multi_retrigger_attack);179DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_portamento);180DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_output_rate);181DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_interp_method);182DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_root_pitch_hz);183DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_pitch);184DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_attenuation);185DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_min_attenuation_cB);186DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_viblfo_to_pitch);187DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_pitch);188DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_vol);189DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_fc);190DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modenv_to_fc);191DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modenv_to_pitch);192DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_synth_gain);193DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_start);194DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_end);195DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_loopstart);196DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_loopend);197DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_samplemode);198DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_sample);199200/* defined in fluid_rvoice_dsp.c */201void fluid_rvoice_dsp_config(void);202int fluid_rvoice_dsp_interpolate_none(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);203int fluid_rvoice_dsp_interpolate_linear(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);204int fluid_rvoice_dsp_interpolate_4th_order(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);205int fluid_rvoice_dsp_interpolate_7th_order(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);206207208/*209* Combines the most significant 16 bit part of a sample with a potentially present210* least sig. 8 bit part in order to create a 24 bit sample.211*/212static FLUID_INLINE int32_t213fluid_rvoice_get_sample(const short int *dsp_msb, const char *dsp_lsb, unsigned int idx)214{215/* cast sample to unsigned type, so we can safely shift and bitwise or216* without relying on undefined behaviour (should never happen anyway ofc...) */217uint32_t msb = (uint32_t)dsp_msb[idx];218uint8_t lsb = 0U;219220/* most soundfonts have 16 bit samples, assume that it's unlikely we221* experience 24 bit samples here */222if(FLUID_UNLIKELY(dsp_lsb != NULL))223{224lsb = (uint8_t)dsp_lsb[idx];225}226227return (int32_t)((msb << 8) | lsb);228}229230#endif231232233