Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/servers/audio/effects/audio_effect_phaser.cpp
10278 views
1
/**************************************************************************/
2
/* audio_effect_phaser.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_phaser.h"
32
#include "servers/audio_server.h"
33
34
void AudioEffectPhaserInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
35
float sampling_rate = AudioServer::get_singleton()->get_mix_rate();
36
37
float dmin = base->range_min / (sampling_rate / 2.0);
38
float dmax = base->range_max / (sampling_rate / 2.0);
39
40
float increment = Math::TAU * (base->rate / sampling_rate);
41
42
for (int i = 0; i < p_frame_count; i++) {
43
phase += increment;
44
45
while (phase >= Math::TAU) {
46
phase -= Math::TAU;
47
}
48
49
float d = dmin + (dmax - dmin) * ((std::sin(phase) + 1.f) / 2.f);
50
51
//update filter coeffs
52
for (int j = 0; j < 6; j++) {
53
allpass[0][j].delay(d);
54
allpass[1][j].delay(d);
55
}
56
57
//calculate output
58
float y = allpass[0][0].update(
59
allpass[0][1].update(
60
allpass[0][2].update(
61
allpass[0][3].update(
62
allpass[0][4].update(
63
allpass[0][5].update(p_src_frames[i].left + h.left * base->feedback))))));
64
h.left = y;
65
66
p_dst_frames[i].left = p_src_frames[i].left + y * base->depth;
67
68
y = allpass[1][0].update(
69
allpass[1][1].update(
70
allpass[1][2].update(
71
allpass[1][3].update(
72
allpass[1][4].update(
73
allpass[1][5].update(p_src_frames[i].right + h.right * base->feedback))))));
74
h.right = y;
75
76
p_dst_frames[i].right = p_src_frames[i].right + y * base->depth;
77
}
78
}
79
80
Ref<AudioEffectInstance> AudioEffectPhaser::instantiate() {
81
Ref<AudioEffectPhaserInstance> ins;
82
ins.instantiate();
83
ins->base = Ref<AudioEffectPhaser>(this);
84
ins->phase = 0;
85
ins->h = AudioFrame(0, 0);
86
87
return ins;
88
}
89
90
void AudioEffectPhaser::set_range_min_hz(float p_hz) {
91
range_min = p_hz;
92
}
93
94
float AudioEffectPhaser::get_range_min_hz() const {
95
return range_min;
96
}
97
98
void AudioEffectPhaser::set_range_max_hz(float p_hz) {
99
range_max = p_hz;
100
}
101
102
float AudioEffectPhaser::get_range_max_hz() const {
103
return range_max;
104
}
105
106
void AudioEffectPhaser::set_rate_hz(float p_hz) {
107
rate = p_hz;
108
}
109
110
float AudioEffectPhaser::get_rate_hz() const {
111
return rate;
112
}
113
114
void AudioEffectPhaser::set_feedback(float p_fbk) {
115
feedback = p_fbk;
116
}
117
118
float AudioEffectPhaser::get_feedback() const {
119
return feedback;
120
}
121
122
void AudioEffectPhaser::set_depth(float p_depth) {
123
depth = p_depth;
124
}
125
126
float AudioEffectPhaser::get_depth() const {
127
return depth;
128
}
129
130
void AudioEffectPhaser::_bind_methods() {
131
ClassDB::bind_method(D_METHOD("set_range_min_hz", "hz"), &AudioEffectPhaser::set_range_min_hz);
132
ClassDB::bind_method(D_METHOD("get_range_min_hz"), &AudioEffectPhaser::get_range_min_hz);
133
134
ClassDB::bind_method(D_METHOD("set_range_max_hz", "hz"), &AudioEffectPhaser::set_range_max_hz);
135
ClassDB::bind_method(D_METHOD("get_range_max_hz"), &AudioEffectPhaser::get_range_max_hz);
136
137
ClassDB::bind_method(D_METHOD("set_rate_hz", "hz"), &AudioEffectPhaser::set_rate_hz);
138
ClassDB::bind_method(D_METHOD("get_rate_hz"), &AudioEffectPhaser::get_rate_hz);
139
140
ClassDB::bind_method(D_METHOD("set_feedback", "fbk"), &AudioEffectPhaser::set_feedback);
141
ClassDB::bind_method(D_METHOD("get_feedback"), &AudioEffectPhaser::get_feedback);
142
143
ClassDB::bind_method(D_METHOD("set_depth", "depth"), &AudioEffectPhaser::set_depth);
144
ClassDB::bind_method(D_METHOD("get_depth"), &AudioEffectPhaser::get_depth);
145
146
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "range_min_hz", PROPERTY_HINT_RANGE, "10,10000,suffix:Hz"), "set_range_min_hz", "get_range_min_hz");
147
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "range_max_hz", PROPERTY_HINT_RANGE, "10,10000,suffix:Hz"), "set_range_max_hz", "get_range_max_hz");
148
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rate_hz", PROPERTY_HINT_RANGE, "0.01,20,suffix:Hz"), "set_rate_hz", "get_rate_hz");
149
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "feedback", PROPERTY_HINT_RANGE, "0.1,0.9,0.1"), "set_feedback", "get_feedback");
150
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_RANGE, "0.1,4,0.1"), "set_depth", "get_depth");
151
}
152
153
AudioEffectPhaser::AudioEffectPhaser() {
154
range_min = 440;
155
range_max = 1600;
156
rate = 0.5;
157
feedback = 0.7;
158
depth = 1;
159
}
160
161