1 /*************************************************************************/
2 /*  audio_effect_chorus.h                                                */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
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 #ifndef AUDIOEFFECTCHORUS_H
32 #define AUDIOEFFECTCHORUS_H
33 
34 #include "servers/audio/audio_effect.h"
35 
36 class AudioEffectChorus;
37 
38 class AudioEffectChorusInstance : public AudioEffectInstance {
39 	GDCLASS(AudioEffectChorusInstance, AudioEffectInstance);
40 	friend class AudioEffectChorus;
41 	Ref<AudioEffectChorus> base;
42 
43 	Vector<AudioFrame> audio_buffer;
44 	unsigned int buffer_pos;
45 	unsigned int buffer_mask;
46 
47 	AudioFrame filter_h[4];
48 	uint64_t cycles[4];
49 
50 	void _process_chunk(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count);
51 
52 public:
53 	virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count);
54 };
55 
56 class AudioEffectChorus : public AudioEffect {
57 	GDCLASS(AudioEffectChorus, AudioEffect);
58 
59 	friend class AudioEffectChorusInstance;
60 
61 public:
62 	enum {
63 
64 		MAX_DELAY_MS = 50,
65 		MAX_DEPTH_MS = 20,
66 		MAX_WIDTH_MS = 50,
67 		MAX_VOICES = 4,
68 		CYCLES_FRAC = 16,
69 		CYCLES_MASK = (1 << CYCLES_FRAC) - 1,
70 		MAX_CHANNELS = 4,
71 		MS_CUTOFF_MAX = 16000
72 	};
73 
74 private:
75 	struct Voice {
76 
77 		float delay;
78 		float rate;
79 		float depth;
80 		float level;
81 		float cutoff;
82 		float pan;
83 
VoiceVoice84 		Voice() {
85 
86 			delay = 12.0;
87 			rate = 1;
88 			depth = 0;
89 			level = 0;
90 			cutoff = MS_CUTOFF_MAX;
91 			pan = 0;
92 		}
93 
94 	} voice[MAX_VOICES];
95 
96 	int voice_count;
97 
98 	float wet;
99 	float dry;
100 
101 protected:
102 	void _validate_property(PropertyInfo &property) const;
103 
104 	static void _bind_methods();
105 
106 public:
107 	void set_voice_count(int p_voices);
108 	int get_voice_count() const;
109 
110 	void set_voice_delay_ms(int p_voice, float p_delay_ms);
111 	float get_voice_delay_ms(int p_voice) const;
112 
113 	void set_voice_rate_hz(int p_voice, float p_rate_hz);
114 	float get_voice_rate_hz(int p_voice) const;
115 
116 	void set_voice_depth_ms(int p_voice, float p_depth_ms);
117 	float get_voice_depth_ms(int p_voice) const;
118 
119 	void set_voice_level_db(int p_voice, float p_level_db);
120 	float get_voice_level_db(int p_voice) const;
121 
122 	void set_voice_cutoff_hz(int p_voice, float p_cutoff_hz);
123 	float get_voice_cutoff_hz(int p_voice) const;
124 
125 	void set_voice_pan(int p_voice, float p_pan);
126 	float get_voice_pan(int p_voice) const;
127 
128 	void set_wet(float amount);
129 	float get_wet() const;
130 
131 	void set_dry(float amount);
132 	float get_dry() const;
133 
134 	Ref<AudioEffectInstance> instance();
135 
136 	AudioEffectChorus();
137 };
138 
139 #endif // AUDIOEFFECTCHORUS_H
140