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  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, 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 #include "fluid_iir_filter.h"
29 #include "fluid_adsr_env.h"
30 #include "fluid_lfo.h"
31 #include "fluid_rvoice.h"
32 #include "fluid_sys.h"
33 
34 #define NO_CHANNEL             0xff
35 
36 typedef struct _fluid_overflow_prio_t fluid_overflow_prio_t;
37 
38 struct _fluid_overflow_prio_t
39 {
40   fluid_real_t percussion; /**< Is this voice on the drum channel? Then add this score */
41   fluid_real_t released; /**< Is this voice in release stage? Then add this score (usually negative) */
42   fluid_real_t sustained; /**< Is this voice sustained? Then add this score (usually negative) */
43   fluid_real_t volume; /**< Multiply current (or future) volume (a value between 0 and 1) */
44   fluid_real_t age; /**< This score will be divided by the number of seconds the voice has lasted */
45 };
46 
47 enum fluid_voice_status
48 {
49 	FLUID_VOICE_CLEAN,
50 	FLUID_VOICE_ON,
51 	FLUID_VOICE_SUSTAINED,         /* Sustained by Sustain pedal */
52 	FLUID_VOICE_HELD_BY_SOSTENUTO, /* Sustained by Sostenuto pedal */
53 	FLUID_VOICE_OFF
54 };
55 
56 
57 /*
58  * fluid_voice_t
59  */
60 struct _fluid_voice_t
61 {
62 	unsigned int id;                /* the id is incremented for every new noteon.
63 					   it's used for noteoff's  */
64 	unsigned char status;
65 	unsigned char chan;             /* the channel number, quick access for channel messages */
66 	unsigned char key;              /* the key, quick access for noteoff */
67 	unsigned char vel;              /* the velocity */
68 	fluid_channel_t* channel;
69 	fluid_gen_t gen[GEN_LAST];
70 	fluid_mod_t mod[FLUID_NUM_MOD];
71 	int mod_count;
72 	fluid_sample_t* sample;         /* Pointer to sample (dupe in rvoice) */
73 
74 	int has_noteoff;                /* Flag set when noteoff has been sent */
75 
76 	/* basic parameters */
77 	fluid_real_t output_rate;        /* the sample rate of the synthesizer (dupe in rvoice) */
78 
79 	unsigned int start_time;
80 	fluid_adsr_env_t volenv;         /* Volume envelope (dupe in rvoice) */
81 
82 	/* basic parameters */
83 	fluid_real_t pitch;              /* the pitch in midicents (dupe in rvoice) */
84 	fluid_real_t attenuation;        /* the attenuation in centibels (dupe in rvoice) */
85 	fluid_real_t root_pitch;
86 
87 	/* master gain (dupe in rvoice) */
88 	fluid_real_t synth_gain;
89 
90 	/* pan */
91 	fluid_real_t pan;
92 	fluid_real_t amp_left;
93 	fluid_real_t amp_right;
94 
95 	/* reverb */
96 	fluid_real_t reverb_send;
97 	fluid_real_t amp_reverb;
98 
99 	/* chorus */
100 	fluid_real_t chorus_send;
101 	fluid_real_t amp_chorus;
102 
103 	/* rvoice control */
104 	fluid_rvoice_t* rvoice;
105 	fluid_rvoice_t* overflow_rvoice; /* Used temporarily and only in overflow situations */
106 	int can_access_rvoice; /* False if rvoice is being rendered in separate thread */
107 	int can_access_overflow_rvoice; /* False if overflow_rvoice is being rendered in separate thread */
108 
109 	/* for debugging */
110 	int debug;
111 	double ref;
112 };
113 
114 
115 fluid_voice_t* new_fluid_voice(fluid_real_t output_rate);
116 int delete_fluid_voice(fluid_voice_t* voice);
117 
118 void fluid_voice_start(fluid_voice_t* voice);
119 void  fluid_voice_calculate_gen_pitch(fluid_voice_t* voice);
120 
121 int fluid_voice_write (fluid_voice_t* voice, fluid_real_t *dsp_buf);
122 
123 int fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
124 		     fluid_channel_t* channel, int key, int vel,
125 		     unsigned int id, unsigned int time, fluid_real_t gain);
126 
127 int fluid_voice_modulate(fluid_voice_t* voice, int cc, int ctrl);
128 int fluid_voice_modulate_all(fluid_voice_t* voice);
129 
130 /** Set the NRPN value of a generator. */
131 int fluid_voice_set_param(fluid_voice_t* voice, int gen, fluid_real_t value, int abs);
132 
133 
134 /** Set the gain. */
135 int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain);
136 
137 int fluid_voice_set_output_rate(fluid_voice_t* voice, fluid_real_t value);
138 
139 
140 /** Update all the synthesis parameters, which depend on generator
141     'gen'. This is only necessary after changing a generator of an
142     already operating voice.  Most applications will not need this
143     function.*/
144 void fluid_voice_update_param(fluid_voice_t* voice, int gen);
145 
146 /**  fluid_voice_release
147  Force the voice into release stage. Usefuf anywhere a voice
148  needs to be damped even if pedals (sustain sostenuto) are depressed.
149  See fluid_synth_damp_voices_LOCAL(), fluid_synth_damp_voices_by_sostenuto_LOCAL,
150  fluid_voice_noteoff(), fluid_synth_stop_LOCAL().
151 */
152 void fluid_voice_release(fluid_voice_t* voice);
153 int fluid_voice_noteoff(fluid_voice_t* voice);
154 int fluid_voice_off(fluid_voice_t* voice);
155 void fluid_voice_overflow_rvoice_finished(fluid_voice_t* voice);
156 void fluid_voice_mix (fluid_voice_t *voice, int count, fluid_real_t* dsp_buf,
157 		 fluid_real_t* left_buf, fluid_real_t* right_buf,
158 		 fluid_real_t* reverb_buf, fluid_real_t* chorus_buf);
159 
160 int fluid_voice_kill_excl(fluid_voice_t* voice);
161 fluid_real_t fluid_voice_get_overflow_prio(fluid_voice_t* voice,
162 					    fluid_overflow_prio_t* score,
163 					    unsigned int cur_time);
164 
165 #define OVERFLOW_PRIO_CANNOT_KILL 999999.
166 
167 /**
168  * Locks the rvoice for rendering, so it can't be modified directly
169  */
170 static FLUID_INLINE fluid_rvoice_t*
fluid_voice_lock_rvoice(fluid_voice_t * voice)171 fluid_voice_lock_rvoice(fluid_voice_t* voice)
172 {
173   voice->can_access_rvoice = 0;
174   return voice->rvoice;
175 }
176 
177 /**
178  * Unlocks the rvoice for rendering, so it can be modified directly
179  */
180 static FLUID_INLINE void
fluid_voice_unlock_rvoice(fluid_voice_t * voice)181 fluid_voice_unlock_rvoice(fluid_voice_t* voice)
182 {
183   voice->can_access_rvoice = 1;
184 }
185 
186 
187 #define fluid_voice_get_channel(voice)  ((voice)->channel)
188 
189 
190 #define fluid_voice_set_id(_voice, _id)  { (_voice)->id = (_id); }
191 #define fluid_voice_get_chan(_voice)     (_voice)->chan
192 
193 
194 #define _PLAYING(voice)  (((voice)->status == FLUID_VOICE_ON) || \
195                                            _SUSTAINED(voice)  || \
196                                            _HELD_BY_SOSTENUTO(voice) )
197 
198 /* A voice is 'ON', if it has not yet received a noteoff
199  * event. Sending a noteoff event will advance the envelopes to
200  * section 5 (release). */
201 #define _ON(voice)  ((voice)->status == FLUID_VOICE_ON && !voice->has_noteoff)
202 #define _SUSTAINED(voice)  ((voice)->status == FLUID_VOICE_SUSTAINED)
203 #define _HELD_BY_SOSTENUTO(voice)  ((voice)->status == FLUID_VOICE_HELD_BY_SOSTENUTO)
204 #define _AVAILABLE(voice)  ((voice)->can_access_rvoice && \
205  (((voice)->status == FLUID_VOICE_CLEAN) || ((voice)->status == FLUID_VOICE_OFF)))
206 //#define _RELEASED(voice)  ((voice)->chan == NO_CHANNEL)
207 #define _SAMPLEMODE(voice) ((int)(voice)->gen[GEN_SAMPLEMODE].val)
208 
209 
210 /* FIXME - This doesn't seem to be used anywhere - JG */
211 fluid_real_t fluid_voice_gen_value(fluid_voice_t* voice, int num);
212 
213 #define fluid_voice_get_loudness(voice) (fluid_adsr_env_get_max_val(&voice->volenv))
214 
215 #define _GEN(_voice, _n) \
216   ((fluid_real_t)(_voice)->gen[_n].val \
217    + (fluid_real_t)(_voice)->gen[_n].mod \
218    + (fluid_real_t)(_voice)->gen[_n].nrpn)
219 
220 /* defined in fluid_dsp_float.c */
221 
222 void fluid_dsp_float_config (void);
223 int fluid_dsp_float_interpolate_none (fluid_voice_t *voice);
224 int fluid_dsp_float_interpolate_linear (fluid_voice_t *voice);
225 int fluid_dsp_float_interpolate_4th_order (fluid_voice_t *voice);
226 int fluid_dsp_float_interpolate_7th_order (fluid_voice_t *voice);
227 
228 #endif /* _FLUID_VOICE_H */
229