1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
2
3 #include "smmorphlfo.hh"
4 #include "smmorphplan.hh"
5 #include "smleakdebugger.hh"
6
7 #include <assert.h>
8
9 using namespace SpectMorph;
10
11 using std::string;
12 using std::vector;
13
14 static LeakDebugger leak_debugger ("SpectMorph::MorphLFO");
15
MorphLFOProperties(MorphLFO * lfo)16 MorphLFOProperties::MorphLFOProperties (MorphLFO *lfo) :
17 frequency (lfo, "Frequency", "%.3f Hz", 0.01, 10, &MorphLFO::frequency, &MorphLFO::set_frequency),
18 depth (lfo, "Depth", "-", 0, 1, &MorphLFO::depth, &MorphLFO::set_depth),
19 center (lfo, "Center", "%.2f", -1, 1, &MorphLFO::center, &MorphLFO::set_center),
20 start_phase (lfo, "Start Phase", "%.1f", -180, 180, &MorphLFO::start_phase, &MorphLFO::set_start_phase)
21 {
22 /* FIXME: ideally the storage format should be changed -> store depth as percent */
23 depth.set_custom_formatter ([](float f) -> string { return string_locale_printf ("%.1f %%", f * 100); });
24 }
25
MorphLFO(MorphPlan * morph_plan)26 MorphLFO::MorphLFO (MorphPlan *morph_plan) :
27 MorphOperator (morph_plan)
28 {
29 m_wave_type = WAVE_SINE;
30 m_frequency = 1;
31 m_depth = 1;
32 m_center = 0;
33 m_start_phase = 0;
34 m_sync_voices = false;
35 m_beat_sync = false;
36 m_note = NOTE_1_4;
37 m_note_mode = NOTE_MODE_STRAIGHT;
38
39 leak_debugger.add (this);
40 }
41
~MorphLFO()42 MorphLFO::~MorphLFO()
43 {
44 leak_debugger.del (this);
45 }
46
47 const char *
type()48 MorphLFO::type()
49 {
50 return "SpectMorph::MorphLFO";
51 }
52
53 int
insert_order()54 MorphLFO::insert_order()
55 {
56 return 200;
57 }
58
59 bool
save(OutFile & out_file)60 MorphLFO::save (OutFile& out_file)
61 {
62 out_file.write_int ("wave_type", m_wave_type);
63 out_file.write_float ("frequency", m_frequency);
64 out_file.write_float ("depth", m_depth);
65 out_file.write_float ("center", m_center);
66 out_file.write_float ("start_phase", m_start_phase);
67 out_file.write_bool ("sync_voices", m_sync_voices);
68 out_file.write_bool ("beat_sync", m_beat_sync);
69 out_file.write_int ("note", m_note);
70 out_file.write_int ("note_mode", m_note_mode);
71
72 return true;
73 }
74
75 bool
load(InFile & ifile)76 MorphLFO::load (InFile& ifile)
77 {
78 while (ifile.event() != InFile::END_OF_FILE)
79 {
80 if (ifile.event() == InFile::INT)
81 {
82 if (ifile.event_name() == "wave_type")
83 {
84 m_wave_type = static_cast<WaveType> (ifile.event_int());
85 }
86 else if (ifile.event_name() == "note")
87 {
88 m_note = static_cast<Note> (ifile.event_int());
89 }
90 else if (ifile.event_name() == "note_mode")
91 {
92 m_note_mode = static_cast<NoteMode> (ifile.event_int());
93 }
94 else
95 {
96 g_printerr ("bad int\n");
97 return false;
98 }
99 }
100 else if (ifile.event() == InFile::FLOAT)
101 {
102 if (ifile.event_name() == "frequency")
103 {
104 m_frequency = ifile.event_float();
105 }
106 else if (ifile.event_name() == "depth")
107 {
108 m_depth = ifile.event_float();
109 }
110 else if (ifile.event_name() == "center")
111 {
112 m_center = ifile.event_float();
113 }
114 else if (ifile.event_name() == "start_phase")
115 {
116 m_start_phase = ifile.event_float();
117 }
118 else
119 {
120 g_printerr ("bad float\n");
121 return false;
122 }
123 }
124 else if (ifile.event() == InFile::BOOL)
125 {
126 if (ifile.event_name() == "sync_voices")
127 {
128 m_sync_voices = ifile.event_bool();
129 }
130 else if (ifile.event_name() == "beat_sync")
131 {
132 m_beat_sync = ifile.event_bool();
133 }
134 else
135 {
136 g_printerr ("bad bool\n");
137 return false;
138 }
139 }
140 else
141 {
142 g_printerr ("bad event\n");
143 return false;
144 }
145 ifile.next_event();
146 }
147 return true;
148 }
149
150 MorphOperator::OutputType
output_type()151 MorphLFO::output_type()
152 {
153 return OUTPUT_CONTROL;
154 }
155
156 MorphLFO::WaveType
wave_type()157 MorphLFO::wave_type()
158 {
159 return m_wave_type;
160 }
161
162 void
set_wave_type(WaveType new_wave_type)163 MorphLFO::set_wave_type (WaveType new_wave_type)
164 {
165 m_wave_type = new_wave_type;
166
167 m_morph_plan->emit_plan_changed();
168 }
169
170 float
frequency() const171 MorphLFO::frequency() const
172 {
173 return m_frequency;
174 }
175
176 void
set_frequency(float frequency)177 MorphLFO::set_frequency (float frequency)
178 {
179 m_frequency = frequency;
180
181 m_morph_plan->emit_plan_changed();
182 }
183
184 float
depth() const185 MorphLFO::depth() const
186 {
187 return m_depth;
188 }
189
190 void
set_depth(float depth)191 MorphLFO::set_depth (float depth)
192 {
193 m_depth = depth;
194
195 m_morph_plan->emit_plan_changed();
196 }
197
198 float
center() const199 MorphLFO::center() const
200 {
201 return m_center;
202 }
203
204 void
set_center(float center)205 MorphLFO::set_center (float center)
206 {
207 m_center = center;
208
209 m_morph_plan->emit_plan_changed();
210 }
211
212 float
start_phase() const213 MorphLFO::start_phase() const
214 {
215 return m_start_phase;
216 }
217
218 void
set_start_phase(float start_phase)219 MorphLFO::set_start_phase (float start_phase)
220 {
221 m_start_phase = start_phase;
222
223 m_morph_plan->emit_plan_changed();
224 }
225
226 bool
sync_voices() const227 MorphLFO::sync_voices() const
228 {
229 return m_sync_voices;
230 }
231
232 void
set_sync_voices(float sync_voices)233 MorphLFO::set_sync_voices (float sync_voices)
234 {
235 m_sync_voices = sync_voices;
236
237 m_morph_plan->emit_plan_changed();
238 }
239
240 bool
beat_sync() const241 MorphLFO::beat_sync() const
242 {
243 return m_beat_sync;
244 }
245
246 void
set_beat_sync(bool beat_sync)247 MorphLFO::set_beat_sync (bool beat_sync)
248 {
249 m_beat_sync = beat_sync;
250
251 m_morph_plan->emit_plan_changed();
252 }
253
254 MorphLFO::Note
note() const255 MorphLFO::note() const
256 {
257 return m_note;
258 }
259
260 void
set_note(Note note)261 MorphLFO::set_note (Note note)
262 {
263 m_note = note;
264
265 m_morph_plan->emit_plan_changed();
266 }
267
268 MorphLFO::NoteMode
note_mode() const269 MorphLFO::note_mode() const
270 {
271 return m_note_mode;
272 }
273
274 void
set_note_mode(NoteMode mode)275 MorphLFO::set_note_mode (NoteMode mode)
276 {
277 m_note_mode = mode;
278
279 m_morph_plan->emit_plan_changed();
280 }
281