Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/servers/audio/effects/audio_effect_reverb.cpp
11353 views
1
/**************************************************************************/
2
/* audio_effect_reverb.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "audio_effect_reverb.h"
32
33
#include "servers/audio/audio_server.h"
34
35
void AudioEffectReverbInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
36
for (int i = 0; i < 2; i++) {
37
Reverb &r = reverb[i];
38
39
r.set_predelay(base->predelay);
40
r.set_predelay_feedback(base->predelay_fb);
41
r.set_highpass(base->hpf);
42
r.set_room_size(base->room_size);
43
r.set_damp(base->damping);
44
r.set_extra_spread(base->spread);
45
r.set_wet(base->wet);
46
r.set_dry(base->dry);
47
}
48
49
int todo = p_frame_count;
50
int offset = 0;
51
52
while (todo) {
53
int to_mix = MIN(todo, Reverb::INPUT_BUFFER_MAX_SIZE);
54
55
for (int j = 0; j < to_mix; j++) {
56
tmp_src[j] = p_src_frames[offset + j].left;
57
}
58
59
reverb[0].process(tmp_src, tmp_dst, to_mix);
60
61
for (int j = 0; j < to_mix; j++) {
62
p_dst_frames[offset + j].left = tmp_dst[j];
63
tmp_src[j] = p_src_frames[offset + j].right;
64
}
65
66
reverb[1].process(tmp_src, tmp_dst, to_mix);
67
68
for (int j = 0; j < to_mix; j++) {
69
p_dst_frames[offset + j].right = tmp_dst[j];
70
}
71
72
offset += to_mix;
73
todo -= to_mix;
74
}
75
}
76
77
AudioEffectReverbInstance::AudioEffectReverbInstance() {
78
reverb[0].set_mix_rate(AudioServer::get_singleton()->get_mix_rate());
79
reverb[0].set_extra_spread_base(0);
80
reverb[1].set_mix_rate(AudioServer::get_singleton()->get_mix_rate());
81
reverb[1].set_extra_spread_base(0.000521); //for stereo effect
82
}
83
84
Ref<AudioEffectInstance> AudioEffectReverb::instantiate() {
85
Ref<AudioEffectReverbInstance> ins;
86
ins.instantiate();
87
ins->base = Ref<AudioEffectReverb>(this);
88
return ins;
89
}
90
91
void AudioEffectReverb::set_predelay_msec(float p_msec) {
92
predelay = p_msec;
93
}
94
95
void AudioEffectReverb::set_predelay_feedback(float p_feedback) {
96
predelay_fb = CLAMP(p_feedback, 0, 0.98);
97
}
98
99
void AudioEffectReverb::set_room_size(float p_size) {
100
room_size = p_size;
101
}
102
103
void AudioEffectReverb::set_damping(float p_damping) {
104
damping = p_damping;
105
}
106
107
void AudioEffectReverb::set_spread(float p_spread) {
108
spread = p_spread;
109
}
110
111
void AudioEffectReverb::set_dry(float p_dry) {
112
dry = p_dry;
113
}
114
115
void AudioEffectReverb::set_wet(float p_wet) {
116
wet = p_wet;
117
}
118
119
void AudioEffectReverb::set_hpf(float p_hpf) {
120
hpf = p_hpf;
121
}
122
123
float AudioEffectReverb::get_predelay_msec() const {
124
return predelay;
125
}
126
127
float AudioEffectReverb::get_predelay_feedback() const {
128
return predelay_fb;
129
}
130
131
float AudioEffectReverb::get_room_size() const {
132
return room_size;
133
}
134
135
float AudioEffectReverb::get_damping() const {
136
return damping;
137
}
138
139
float AudioEffectReverb::get_spread() const {
140
return spread;
141
}
142
143
float AudioEffectReverb::get_dry() const {
144
return dry;
145
}
146
147
float AudioEffectReverb::get_wet() const {
148
return wet;
149
}
150
151
float AudioEffectReverb::get_hpf() const {
152
return hpf;
153
}
154
155
void AudioEffectReverb::_bind_methods() {
156
ClassDB::bind_method(D_METHOD("set_predelay_msec", "msec"), &AudioEffectReverb::set_predelay_msec);
157
ClassDB::bind_method(D_METHOD("get_predelay_msec"), &AudioEffectReverb::get_predelay_msec);
158
159
ClassDB::bind_method(D_METHOD("set_predelay_feedback", "feedback"), &AudioEffectReverb::set_predelay_feedback);
160
ClassDB::bind_method(D_METHOD("get_predelay_feedback"), &AudioEffectReverb::get_predelay_feedback);
161
162
ClassDB::bind_method(D_METHOD("set_room_size", "size"), &AudioEffectReverb::set_room_size);
163
ClassDB::bind_method(D_METHOD("get_room_size"), &AudioEffectReverb::get_room_size);
164
165
ClassDB::bind_method(D_METHOD("set_damping", "amount"), &AudioEffectReverb::set_damping);
166
ClassDB::bind_method(D_METHOD("get_damping"), &AudioEffectReverb::get_damping);
167
168
ClassDB::bind_method(D_METHOD("set_spread", "amount"), &AudioEffectReverb::set_spread);
169
ClassDB::bind_method(D_METHOD("get_spread"), &AudioEffectReverb::get_spread);
170
171
ClassDB::bind_method(D_METHOD("set_dry", "amount"), &AudioEffectReverb::set_dry);
172
ClassDB::bind_method(D_METHOD("get_dry"), &AudioEffectReverb::get_dry);
173
174
ClassDB::bind_method(D_METHOD("set_wet", "amount"), &AudioEffectReverb::set_wet);
175
ClassDB::bind_method(D_METHOD("get_wet"), &AudioEffectReverb::get_wet);
176
177
ClassDB::bind_method(D_METHOD("set_hpf", "amount"), &AudioEffectReverb::set_hpf);
178
ClassDB::bind_method(D_METHOD("get_hpf"), &AudioEffectReverb::get_hpf);
179
180
ADD_GROUP("Predelay", "predelay_");
181
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "predelay_msec", PROPERTY_HINT_RANGE, "20,500,1,suffix:ms"), "set_predelay_msec", "get_predelay_msec");
182
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "predelay_feedback", PROPERTY_HINT_RANGE, "0,0.98,0.01"), "set_predelay_feedback", "get_predelay_feedback");
183
ADD_GROUP("", "");
184
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "room_size", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_room_size", "get_room_size");
185
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping", "get_damping");
186
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spread", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_spread", "get_spread");
187
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "hipass", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_hpf", "get_hpf");
188
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dry", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dry", "get_dry");
189
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wet", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_wet", "get_wet");
190
}
191
192
AudioEffectReverb::AudioEffectReverb() {
193
predelay = 150;
194
predelay_fb = 0.4;
195
hpf = 0;
196
room_size = 0.8;
197
damping = 0.5;
198
spread = 1.0;
199
dry = 1.0;
200
wet = 0.5;
201
}
202
203