Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/fluidsynth/src/synth/fluid_voice.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_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_rvoice_event.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
float percussion; /**< Is this voice on the drum channel? Then add this score */
41
float released; /**< Is this voice in release stage? Then add this score (usually negative) */
42
float sustained; /**< Is this voice sustained? Then add this score (usually negative) */
43
float volume; /**< Multiply current (or future) volume (a value between 0 and 1) */
44
float age; /**< This score will be divided by the number of seconds the voice has lasted */
45
float important; /**< This score will be added to all important channels */
46
char *important_channels; /**< "important" flags indexed by MIDI channel number */
47
int num_important_channels; /**< Number of elements in the important_channels array */
48
};
49
50
enum fluid_voice_status
51
{
52
FLUID_VOICE_CLEAN,
53
FLUID_VOICE_ON,
54
FLUID_VOICE_SUSTAINED, /* Sustained by Sustain pedal */
55
FLUID_VOICE_HELD_BY_SOSTENUTO, /* Sustained by Sostenuto pedal */
56
FLUID_VOICE_OFF
57
};
58
59
60
/*
61
* fluid_voice_t
62
*/
63
struct _fluid_voice_t
64
{
65
unsigned int id; /* the id is incremented for every new noteon.
66
it's used for noteoff's */
67
unsigned char status;
68
unsigned char chan; /* the channel number, quick access for channel messages */
69
unsigned char key; /* the key of the noteon event, quick access for noteoff */
70
unsigned char vel; /* the velocity of the noteon event */
71
fluid_channel_t *channel;
72
fluid_rvoice_eventhandler_t *eventhandler;
73
fluid_zone_range_t *zone_range; /* instrument zone range*/
74
fluid_sample_t *sample; /* Pointer to sample (dupe in rvoice) */
75
fluid_sample_t *overflow_sample; /* Pointer to sample (dupe in overflow_rvoice) */
76
77
unsigned int start_time;
78
int mod_count;
79
fluid_mod_t mod[FLUID_NUM_MOD];
80
fluid_gen_t gen[GEN_LAST];
81
82
/* basic parameters */
83
fluid_real_t output_rate; /* the sample rate of the synthesizer (dupe in rvoice) */
84
85
/* basic parameters */
86
fluid_real_t pitch; /* the pitch in midicents (dupe in rvoice) */
87
fluid_real_t attenuation; /* the attenuation in centibels (dupe in rvoice) */
88
fluid_real_t root_pitch;
89
90
/* master gain (dupe in rvoice) */
91
fluid_real_t synth_gain;
92
93
/* pan */
94
fluid_real_t pan;
95
96
/* balance */
97
fluid_real_t balance;
98
99
/* reverb */
100
fluid_real_t reverb_send;
101
102
/* chorus */
103
fluid_real_t chorus_send;
104
105
/* rvoice control */
106
fluid_rvoice_t *rvoice;
107
fluid_rvoice_t *overflow_rvoice; /* Used temporarily and only in overflow situations */
108
char can_access_rvoice; /* False if rvoice is being rendered in separate thread */
109
char can_access_overflow_rvoice; /* False if overflow_rvoice is being rendered in separate thread */
110
char has_noteoff; /* Flag set when noteoff has been sent */
111
112
#ifdef WITH_PROFILING
113
/* for debugging */
114
double ref;
115
#endif
116
};
117
118
119
fluid_voice_t *new_fluid_voice(fluid_rvoice_eventhandler_t *handler, fluid_real_t output_rate);
120
void delete_fluid_voice(fluid_voice_t *voice);
121
122
void fluid_voice_start(fluid_voice_t *voice);
123
void fluid_voice_calculate_gen_pitch(fluid_voice_t *voice);
124
125
int fluid_voice_init(fluid_voice_t *voice, fluid_sample_t *sample,
126
fluid_zone_range_t *inst_zone_range,
127
fluid_channel_t *channel, int key, int vel,
128
unsigned int id, unsigned int time, fluid_real_t gain);
129
130
int fluid_voice_modulate(fluid_voice_t *voice, int cc, int ctrl);
131
int fluid_voice_modulate_all(fluid_voice_t *voice);
132
133
/** Set the NRPN value of a generator. */
134
int fluid_voice_set_param(fluid_voice_t *voice, int gen, fluid_real_t value);
135
136
137
/** Set the gain. */
138
int fluid_voice_set_gain(fluid_voice_t *voice, fluid_real_t gain);
139
140
void fluid_voice_set_output_rate(fluid_voice_t *voice, fluid_real_t value);
141
142
143
/** Update all the synthesis parameters, which depend on generator
144
'gen'. This is only necessary after changing a generator of an
145
already operating voice. Most applications will not need this
146
function.*/
147
void fluid_voice_update_param(fluid_voice_t *voice, int gen);
148
149
/** legato modes */
150
/* force in the attack section for legato mode multi_retrigger: 1 */
151
void fluid_voice_update_multi_retrigger_attack(fluid_voice_t *voice, int tokey, int vel);
152
/* Update portamento parameter */
153
void fluid_voice_update_portamento(fluid_voice_t *voice, int fromkey, int tokey);
154
155
156
void fluid_voice_release(fluid_voice_t *voice);
157
void fluid_voice_noteoff(fluid_voice_t *voice);
158
void fluid_voice_off(fluid_voice_t *voice);
159
void fluid_voice_stop(fluid_voice_t *voice);
160
void fluid_voice_add_mod_local(fluid_voice_t *voice, fluid_mod_t *mod, int mode, int check_limit_count);
161
void fluid_voice_overflow_rvoice_finished(fluid_voice_t *voice);
162
163
int fluid_voice_kill_excl(fluid_voice_t *voice);
164
float fluid_voice_get_overflow_prio(fluid_voice_t *voice,
165
fluid_overflow_prio_t *score,
166
unsigned int cur_time);
167
168
#define OVERFLOW_PRIO_CANNOT_KILL 999999.
169
170
/**
171
* Locks the rvoice for rendering, so it can't be modified directly
172
*/
173
static FLUID_INLINE void
174
fluid_voice_lock_rvoice(fluid_voice_t *voice)
175
{
176
voice->can_access_rvoice = 0;
177
}
178
179
/**
180
* Unlocks the rvoice for rendering, so it can be modified directly
181
*/
182
static FLUID_INLINE void
183
fluid_voice_unlock_rvoice(fluid_voice_t *voice)
184
{
185
voice->can_access_rvoice = 1;
186
}
187
188
#define _AVAILABLE(voice) ((voice)->can_access_rvoice && \
189
(((voice)->status == FLUID_VOICE_CLEAN) || ((voice)->status == FLUID_VOICE_OFF)))
190
//#define _RELEASED(voice) ((voice)->chan == NO_CHANNEL)
191
#define _SAMPLEMODE(voice) ((int)(voice)->gen[GEN_SAMPLEMODE].val)
192
193
194
fluid_real_t fluid_voice_gen_value(const fluid_voice_t *voice, int num);
195
void fluid_voice_set_custom_filter(fluid_voice_t *voice, enum fluid_iir_filter_type type, enum fluid_iir_filter_flags flags);
196
197
198
#endif /* _FLUID_VOICE_H */
199
200