1/* FluidSynth - A Software Synthesizer
2 *
3 * Copyright (C) 2003  Peter Hanappe and others.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public License
7 * as published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 * 02111-1307, USA
19 */
20
21
22#ifndef _FLUID_VOICE_H
23#define _FLUID_VOICE_H
24
25#include "fluid_phase.h"
26#include "fluid_gen.h"
27#include "fluid_mod.h"
28
29#define NO_CHANNEL             0xff
30
31enum fluid_voice_status
32{
33	FLUID_VOICE_CLEAN,
34	FLUID_VOICE_ON,
35	FLUID_VOICE_SUSTAINED,
36	FLUID_VOICE_OFF
37};
38
39
40/*
41 * envelope data
42 */
43struct _fluid_env_data_t {
44	unsigned int count;
45	fluid_real_t coeff;
46	fluid_real_t incr;
47	fluid_real_t min;
48	fluid_real_t max;
49};
50
51/* Indices for envelope tables */
52enum fluid_voice_envelope_index_t{
53	FLUID_VOICE_ENVDELAY,
54	FLUID_VOICE_ENVATTACK,
55	FLUID_VOICE_ENVHOLD,
56	FLUID_VOICE_ENVDECAY,
57	FLUID_VOICE_ENVSUSTAIN,
58	FLUID_VOICE_ENVRELEASE,
59	FLUID_VOICE_ENVFINISHED,
60	FLUID_VOICE_ENVLAST
61};
62
63/*
64 * fluid_voice_t
65 */
66struct _fluid_voice_t
67{
68	unsigned int id;                /* the id is incremented for every new noteon.
69					   it's used for noteoff's  */
70	unsigned char status;
71	unsigned char chan;             /* the channel number, quick access for channel messages */
72	unsigned char key;              /* the key, quick acces for noteoff */
73	unsigned char vel;              /* the velocity */
74	fluid_channel_t* channel;
75	fluid_gen_t gen[GEN_LAST];
76	fluid_mod_t mod[FLUID_NUM_MOD];
77	int mod_count;
78	int has_looped;                 /* Flag that is set as soon as the first loop is completed. */
79	fluid_sample_t* sample;
80	int check_sample_sanity_flag;   /* Flag that initiates, that sample-related parameters
81					   have to be checked. */
82#if 0
83	/* Instead of keeping a pointer to a fluid_sample_t structure,
84	 * I think it would be better to copy the sample data in the
85	 * voice structure. SoundFont loader then do not have to
86	 * allocate and maintain the fluid_sample_t structure. [PH]
87	 *
88	 * The notify callback may be used also for streaming samples.
89	 */
90	short* sample_data;             /* pointer to the sample data */
91	int sample_data_offset;         /* the offset of data[0] in the whole sample */
92	int sample_data_length;         /* the length of the data array */
93	unsigned int sample_start;
94	unsigned int sample_end;
95	unsigned int sample_loopstart;
96	unsigned int sample_loopend;
97	unsigned int sample_rate;
98	int sample_origpitch;
99	int sample_pitchadj;
100	int sample_type;
101	int (*sample_notify)(fluid_voice_t* voice, int reason);
102	void* sample_userdata;
103#endif
104
105	/* basic parameters */
106	fluid_real_t output_rate;        /* the sample rate of the synthesizer */
107
108	unsigned int start_time;
109	unsigned int ticks;
110
111	fluid_real_t amp;                /* current linear amplitude */
112	fluid_phase_t phase;             /* the phase of the sample wave */
113
114	/* Temporary variables used in fluid_voice_write() */
115
116	fluid_real_t phase_incr;	/* the phase increment for the next 64 samples */
117	fluid_real_t amp_incr;		/* amplitude increment value */
118	fluid_real_t *dsp_buf;		/* buffer to store interpolated sample data to */
119
120	/* End temporary variables */
121
122	/* basic parameters */
123	fluid_real_t pitch;              /* the pitch in midicents */
124	fluid_real_t attenuation;        /* the attenuation in centibels */
125	fluid_real_t min_attenuation_cB; /* Estimate on the smallest possible attenuation
126					  * during the lifetime of the voice */
127	fluid_real_t root_pitch;
128
129	/* sample and loop start and end points (offset in sample memory).  */
130	int start;
131	int end;
132	int loopstart;
133	int loopend;	/* Note: first point following the loop (superimposed on loopstart) */
134
135	/* master gain */
136	fluid_real_t synth_gain;
137
138	/* vol env */
139	fluid_env_data_t volenv_data[FLUID_VOICE_ENVLAST];
140	unsigned int volenv_count;
141	int volenv_section;
142	fluid_real_t volenv_val;
143	fluid_real_t amplitude_that_reaches_noise_floor_nonloop;
144	fluid_real_t amplitude_that_reaches_noise_floor_loop;
145
146	/* mod env */
147	fluid_env_data_t modenv_data[FLUID_VOICE_ENVLAST];
148	unsigned int modenv_count;
149	int modenv_section;
150	fluid_real_t modenv_val;         /* the value of the modulation envelope */
151	fluid_real_t modenv_to_fc;
152	fluid_real_t modenv_to_pitch;
153
154	/* mod lfo */
155	fluid_real_t modlfo_val;          /* the value of the modulation LFO */
156	unsigned int modlfo_delay;       /* the delay of the lfo in samples */
157	fluid_real_t modlfo_incr;         /* the lfo frequency is converted to a per-buffer increment */
158	fluid_real_t modlfo_to_fc;
159	fluid_real_t modlfo_to_pitch;
160	fluid_real_t modlfo_to_vol;
161
162	/* vib lfo */
163	fluid_real_t viblfo_val;        /* the value of the vibrato LFO */
164	unsigned int viblfo_delay;      /* the delay of the lfo in samples */
165	fluid_real_t viblfo_incr;       /* the lfo frequency is converted to a per-buffer increment */
166	fluid_real_t viblfo_to_pitch;
167
168	/* resonant filter */
169	fluid_real_t fres;              /* the resonance frequency, in cents (not absolute cents) */
170	fluid_real_t last_fres;         /* Current resonance frequency of the IIR filter */
171	/* Serves as a flag: A deviation between fres and last_fres */
172	/* indicates, that the filter has to be recalculated. */
173	fluid_real_t q_lin;             /* the q-factor on a linear scale */
174	fluid_real_t filter_gain;       /* Gain correction factor, depends on q */
175	fluid_real_t hist1, hist2;      /* Sample history for the IIR filter */
176	int filter_startup;             /* Flag: If set, the filter will be set directly.
177					   Else it changes smoothly. */
178
179	/* filter coefficients */
180	/* The coefficients are normalized to a0. */
181	/* b0 and b2 are identical => b02 */
182	fluid_real_t b02;              /* b0 / a0 */
183	fluid_real_t b1;              /* b1 / a0 */
184	fluid_real_t a1;              /* a0 / a0 */
185	fluid_real_t a2;              /* a1 / a0 */
186
187	fluid_real_t b02_incr;
188	fluid_real_t b1_incr;
189	fluid_real_t a1_incr;
190	fluid_real_t a2_incr;
191	int filter_coeff_incr_count;
192
193	/* pan */
194	fluid_real_t pan;
195	fluid_real_t amp_left;
196	fluid_real_t amp_right;
197
198	/* reverb */
199	fluid_real_t reverb_send;
200	fluid_real_t amp_reverb;
201
202	/* chorus */
203	fluid_real_t chorus_send;
204	fluid_real_t amp_chorus;
205
206	/* interpolation method, as in fluid_interp in fluidsynth.h */
207	int interp_method;
208
209	/* for debugging */
210	int debug;
211	double ref;
212};
213
214
215fluid_voice_t* new_fluid_voice(fluid_real_t output_rate);
216int delete_fluid_voice(fluid_voice_t* voice);
217
218void fluid_voice_start(fluid_voice_t* voice);
219
220int fluid_voice_write(fluid_voice_t* voice,
221		      fluid_real_t* left, fluid_real_t* right,
222		      fluid_real_t* reverb_buf, fluid_real_t* chorus_buf);
223
224int fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
225		     fluid_channel_t* channel, int key, int vel,
226		     unsigned int id, unsigned int time, fluid_real_t gain);
227
228int fluid_voice_modulate(fluid_voice_t* voice, int cc, int ctrl);
229int fluid_voice_modulate_all(fluid_voice_t* voice);
230
231/** Set the NRPN value of a generator. */
232int fluid_voice_set_param(fluid_voice_t* voice, int gen, fluid_real_t value, int abs);
233
234
235/** Set the gain. */
236int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain);
237
238
239/** Update all the synthesis parameters, which depend on generator
240    'gen'. This is only necessary after changing a generator of an
241    already operating voice.  Most applications will not need this
242    function.*/
243void fluid_voice_update_param(fluid_voice_t* voice, int gen);
244
245int fluid_voice_noteoff(fluid_voice_t* voice);
246int fluid_voice_off(fluid_voice_t* voice);
247int fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice);
248fluid_channel_t* fluid_voice_get_channel(fluid_voice_t* voice);
249int calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base,
250				 int gen_key2base, int is_decay);
251int fluid_voice_kill_excl(fluid_voice_t* voice);
252fluid_real_t fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t* voice);
253fluid_real_t fluid_voice_determine_amplitude_that_reaches_noise_floor_for_sample(fluid_voice_t* voice);
254void fluid_voice_check_sample_sanity(fluid_voice_t* voice);
255
256#define fluid_voice_set_id(_voice, _id)  { (_voice)->id = (_id); }
257#define fluid_voice_get_chan(_voice)     (_voice)->chan
258
259
260#define _PLAYING(voice)  (((voice)->status == FLUID_VOICE_ON) || ((voice)->status == FLUID_VOICE_SUSTAINED))
261
262/* A voice is 'ON', if it has not yet received a noteoff
263 * event. Sending a noteoff event will advance the envelopes to
264 * section 5 (release). */
265#define _ON(voice)  ((voice)->status == FLUID_VOICE_ON && (voice)->volenv_section < FLUID_VOICE_ENVRELEASE)
266#define _SUSTAINED(voice)  ((voice)->status == FLUID_VOICE_SUSTAINED)
267#define _AVAILABLE(voice)  (((voice)->status == FLUID_VOICE_CLEAN) || ((voice)->status == FLUID_VOICE_OFF))
268#define _RELEASED(voice)  ((voice)->chan == NO_CHANNEL)
269#define _SAMPLEMODE(voice) ((int)(voice)->gen[GEN_SAMPLEMODE].val)
270
271
272fluid_real_t fluid_voice_gen_value(fluid_voice_t* voice, int num);
273
274#define _GEN(_voice, _n) \
275  ((fluid_real_t)(_voice)->gen[_n].val \
276   + (fluid_real_t)(_voice)->gen[_n].mod \
277   + (fluid_real_t)(_voice)->gen[_n].nrpn)
278
279#define FLUID_SAMPLESANITY_CHECK (1 << 0)
280#define FLUID_SAMPLESANITY_STARTUP (1 << 1)
281
282
283/* defined in fluid_dsp_float.c */
284
285void fluid_dsp_float_config (void);
286int fluid_dsp_float_interpolate_none (fluid_voice_t *voice);
287int fluid_dsp_float_interpolate_linear (fluid_voice_t *voice);
288int fluid_dsp_float_interpolate_4th_order (fluid_voice_t *voice);
289int fluid_dsp_float_interpolate_7th_order (fluid_voice_t *voice);
290
291#endif /* _FLUID_VOICE_H */
292