Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/fluidsynth/src/rvoice/fluid_rvoice.h
4396 views
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 Lesser General Public License
7
* as published by the Free Software Foundation; either version 2.1 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
* Lesser General Public License for more details.
14
*
15
* You should have received a copy of the GNU Lesser 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_RVOICE_H
23
#define _FLUID_RVOICE_H
24
25
#include "fluidsynth_priv.h"
26
#include "fluid_iir_filter.h"
27
#include "fluid_adsr_env.h"
28
#include "fluid_lfo.h"
29
#include "fluid_phase.h"
30
#include "fluid_sfont.h"
31
32
typedef struct _fluid_rvoice_envlfo_t fluid_rvoice_envlfo_t;
33
typedef struct _fluid_rvoice_dsp_t fluid_rvoice_dsp_t;
34
typedef struct _fluid_rvoice_buffers_t fluid_rvoice_buffers_t;
35
typedef struct _fluid_rvoice_t fluid_rvoice_t;
36
37
/* Smallest amplitude that can be perceived (full scale is +/- 0.5)
38
* 16 bits => 96+4=100 dB dynamic range => 0.00001
39
* 24 bits => 144-4 = 140 dB dynamic range => 1.e-7
40
* 1.e-7 * 2 == 2.e-7 :)
41
*/
42
#define FLUID_NOISE_FLOOR ((fluid_real_t)2.e-7)
43
44
enum fluid_loop
45
{
46
FLUID_UNLOOPED = 0,
47
FLUID_LOOP_DURING_RELEASE = 1,
48
FLUID_START_ON_RELEASE = 2, /* this is a looping mode introduced by Polyphone, see #1398 for more info */
49
FLUID_LOOP_UNTIL_RELEASE = 3
50
};
51
52
/*
53
* rvoice ticks-based parameters
54
* These parameters must be updated even if the voice is currently quiet.
55
*/
56
struct _fluid_rvoice_envlfo_t
57
{
58
/* Note-off minimum length */
59
unsigned int ticks;
60
unsigned int noteoff_ticks;
61
62
/* vol env */
63
fluid_adsr_env_t volenv;
64
65
/* mod env */
66
fluid_adsr_env_t modenv;
67
fluid_real_t modenv_to_fc;
68
fluid_real_t modenv_to_pitch;
69
70
/* mod lfo */
71
fluid_lfo_t modlfo;
72
fluid_real_t modlfo_to_fc;
73
fluid_real_t modlfo_to_pitch;
74
fluid_real_t modlfo_to_vol;
75
76
/* vib lfo */
77
fluid_lfo_t viblfo;
78
fluid_real_t viblfo_to_pitch;
79
};
80
81
/*
82
* rvoice parameters needed for dsp interpolation
83
*/
84
struct _fluid_rvoice_dsp_t
85
{
86
/* interpolation method, as in fluid_interp in fluidsynth.h */
87
enum fluid_interp interp_method;
88
enum fluid_loop samplemode;
89
90
/* Flag that is set as soon as the first loop is completed. */
91
char has_looped;
92
93
/* Flag that initiates, that sample-related parameters have to be checked. */
94
char check_sample_sanity_flag;
95
96
fluid_sample_t *sample;
97
98
/* sample and loop start and end points (offset in sample memory). */
99
int start;
100
int end;
101
int loopstart;
102
int loopend; /* Note: first point following the loop (superimposed on loopstart) */
103
104
/* Stuff needed for portamento calculations */
105
fluid_real_t pitchoffset; /* the portamento range in midicents */
106
fluid_real_t pitchinc; /* the portamento increment in midicents */
107
108
/* Stuff needed for phase calculations */
109
110
fluid_real_t pitch; /* the pitch in midicents */
111
fluid_real_t root_pitch_hz;
112
fluid_real_t output_rate;
113
114
/* Stuff needed for amplitude calculations */
115
116
fluid_real_t attenuation; /* the attenuation in centibels */
117
fluid_real_t prev_attenuation; /* the previous attenuation in centibels
118
used by fluid_rvoice_multi_retrigger_attack() */
119
fluid_real_t min_attenuation_cB; /* Estimate on the smallest possible attenuation
120
* during the lifetime of the voice */
121
fluid_real_t amplitude_that_reaches_noise_floor_nonloop;
122
fluid_real_t amplitude_that_reaches_noise_floor_loop;
123
fluid_real_t synth_gain; /* master gain */
124
125
/* Dynamic input to the interpolator below */
126
127
fluid_real_t amp; /* current linear amplitude */
128
fluid_real_t amp_incr; /* amplitude increment value for the next FLUID_BUFSIZE samples */
129
130
fluid_phase_t phase; /* the phase (current sample offset) of the sample wave */
131
fluid_real_t phase_incr; /* the phase increment for the next FLUID_BUFSIZE samples */
132
};
133
134
/* Currently left, right, reverb, chorus. To be changed if we
135
ever add surround positioning, or stereo reverb/chorus */
136
#define FLUID_RVOICE_MAX_BUFS (4)
137
138
/*
139
* rvoice mixer-related parameters
140
*/
141
struct _fluid_rvoice_buffers_t
142
{
143
unsigned int count; /* Number of records in "bufs" */
144
struct
145
{
146
/* the actual, linearly interpolated amplitude with which the dsp sample should be mixed into the buf */
147
fluid_real_t current_amp;
148
149
/* the desired amplitude [...] mixed into the buf (directly set by e.g. rapidly changing PAN events) */
150
fluid_real_t target_amp;
151
152
/* Mapping to mixdown buffer index */
153
int mapping;
154
} bufs[FLUID_RVOICE_MAX_BUFS];
155
};
156
157
158
/*
159
* Hard real-time parameters needed to synthesize a voice
160
*/
161
struct _fluid_rvoice_t
162
{
163
fluid_rvoice_envlfo_t envlfo;
164
fluid_rvoice_dsp_t dsp;
165
fluid_iir_filter_t resonant_filter; /* IIR resonant dsp filter */
166
fluid_iir_filter_t resonant_custom_filter; /* optional custom/general-purpose IIR resonant filter */
167
fluid_rvoice_buffers_t buffers;
168
};
169
170
171
int fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf);
172
173
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_buffers_set_amp);
174
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_buffers_set_mapping);
175
176
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_noteoff);
177
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_voiceoff);
178
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_reset);
179
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_multi_retrigger_attack);
180
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_portamento);
181
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_output_rate);
182
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_interp_method);
183
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_root_pitch_hz);
184
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_pitch);
185
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_attenuation);
186
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_min_attenuation_cB);
187
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_viblfo_to_pitch);
188
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_pitch);
189
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_vol);
190
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_fc);
191
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modenv_to_fc);
192
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modenv_to_pitch);
193
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_synth_gain);
194
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_start);
195
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_end);
196
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_loopstart);
197
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_loopend);
198
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_samplemode);
199
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_sample);
200
201
/* defined in fluid_rvoice_dsp.c */
202
void fluid_rvoice_dsp_config(void);
203
int fluid_rvoice_dsp_interpolate_none(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);
204
int fluid_rvoice_dsp_interpolate_linear(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);
205
int fluid_rvoice_dsp_interpolate_4th_order(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);
206
int fluid_rvoice_dsp_interpolate_7th_order(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);
207
208
209
/*
210
* Combines the most significant 16 bit part of a sample with a potentially present
211
* least sig. 8 bit part in order to create a 24 bit sample.
212
*/
213
static FLUID_INLINE int32_t
214
fluid_rvoice_get_sample(const short int *dsp_msb, const char *dsp_lsb, unsigned int idx)
215
{
216
/* cast sample to unsigned type, so we can safely shift and bitwise or
217
* without relying on undefined behaviour (should never happen anyway ofc...) */
218
uint32_t msb = (uint32_t)dsp_msb[idx];
219
uint8_t lsb = 0U;
220
221
/* most soundfonts have 16 bit samples, assume that it's unlikely we
222
* experience 24 bit samples here */
223
if(FLUID_UNLIKELY(dsp_lsb != NULL))
224
{
225
lsb = (uint8_t)dsp_lsb[idx];
226
}
227
228
return (int32_t)((msb << 8) | lsb);
229
}
230
231
#endif
232
233