e5d951948e7a99cc89858d6d890e79a68159bcf8
[goodguy/history.git] / cinelerra-5.0 / plugins / vocoder / vocoder.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
5  * 
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * 
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * 
20  */
21
22
23 // Originally from the following:
24 /* vocoder.c
25    Version 0.3
26
27    LADSPA Unique ID: 1441
28
29    Version 0.3
30    Added support for changing bands in real time 2003-12-09
31
32    Version 0.2
33    Adapted to LADSPA by Josh Green <jgreen@users.sourceforge.net>
34    15.6.2001 (for the LinuxTag 2001!)
35
36    Original program can be found at:
37    http://www.sirlab.de/linux/
38    Author: Achim Settelmeier <settel-linux@sirlab.de>
39 */
40
41
42
43 #include "bcdisplayinfo.h"
44 #include "bcsignals.h"
45 #include "clip.h"
46 #include "bchash.h"
47 #include "filexml.h"
48 #include "language.h"
49 #include "samples.h"
50 #include "theme.h"
51 #include "units.h"
52 #include "vframe.h"
53 #include "vocoder.h"
54
55 #include <math.h>
56 #include <string.h>
57
58
59
60
61
62
63
64
65
66 REGISTER_PLUGIN(Vocoder)
67
68
69
70
71 //#define USE_BANDWIDTH
72
73 const double decay_table[] =
74 {
75   1/100.0,
76   1/100.0, 1/100.0, 1/100.0,
77   1/125.0, 1/125.0, 1/125.0,
78   1/166.0, 1/166.0, 1/166.0,
79   1/200.0, 1/200.0, 1/200.0,
80   1/250.0, 1/250.0, 1/250.0
81 };
82
83
84 VocoderBand::VocoderBand()
85 {
86         reset();
87 }
88
89 void VocoderBand::reset()
90 {
91         c = f = att = 0;
92
93         freq = 0;
94         low1 = low2 = 0;
95         mid1 = mid2 = 0;
96         high1 = high2 = 0;
97         y = 0;
98 }
99
100 void VocoderBand::copy_from(VocoderBand *src)
101 {
102         c = src->c;
103         f = src->f;
104         att = src->att;
105
106         freq = src->freq;
107         low1 = src->low1;
108         low2 = src->low2;
109         mid1 = src->mid1;
110         mid2 = src->mid2;
111         high1 = src->high1;
112         high2 = src->high2;
113         y = src->y;
114 }
115
116
117 VocoderOut::VocoderOut()
118 {
119         reset();
120 }
121
122 void VocoderOut::reset()
123 {
124         decay = 0;
125         oldval = 0;
126         level = 0;       /* 0.0 - 1.0 level of this output band */
127 }
128
129
130 VocoderConfig::VocoderConfig()
131 {
132         wetness = INFINITYGAIN;
133         carrier_track = 0;
134         bands = MAX_BANDS;
135         level = 0.0;
136 }
137
138
139 int VocoderConfig::equivalent(VocoderConfig &that)
140 {
141         if(!EQUIV(wetness, that.wetness) ||
142                 !EQUIV(level, that.level) ||
143                 carrier_track != that.carrier_track ||
144                 bands != that.bands) return 0;
145         return 1;
146 }
147
148 void VocoderConfig::copy_from(VocoderConfig &that)
149 {
150         wetness = that.wetness;
151         carrier_track = that.carrier_track;
152         bands = that.bands;
153         level = that.level;
154         CLAMP(bands, 1, MAX_BANDS);
155 }
156
157 void VocoderConfig::interpolate(VocoderConfig &prev, 
158                 VocoderConfig &next, 
159                 int64_t prev_frame, 
160                 int64_t next_frame, 
161                 int64_t current_frame)
162 {
163         double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
164         double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
165         wetness = prev.wetness * prev_scale + next.wetness * next_scale;
166         level = prev.level * prev_scale + next.level * next_scale;
167         carrier_track = prev.carrier_track;
168         bands = prev.bands;
169         CLAMP(bands, 1, MAX_BANDS);
170 }
171
172
173
174
175
176
177
178
179
180
181
182
183 VocoderWetness::VocoderWetness(Vocoder *plugin, int x, int y)
184  : BC_FPot(x, y, plugin->config.wetness, INFINITYGAIN, 0)
185 {
186         this->plugin = plugin;
187 }
188
189 int VocoderWetness::handle_event()
190 {
191         plugin->config.wetness = get_value();
192         plugin->send_configure_change();
193         return 1;
194 }
195
196
197
198
199
200 VocoderLevel::VocoderLevel(Vocoder *plugin, int x, int y)
201  : BC_FPot(x, y, plugin->config.level, INFINITYGAIN, 40)
202 {
203         this->plugin = plugin;
204 }
205
206 int VocoderLevel::handle_event()
207 {
208         plugin->config.level = get_value();
209         plugin->send_configure_change();
210         return 1;
211 }
212
213
214
215
216
217
218
219
220
221 VocoderCarrier::VocoderCarrier(Vocoder *plugin, 
222         VocoderWindow *window, 
223         int x, 
224         int y)
225  : BC_TumbleTextBox(window,
226         plugin->config.carrier_track, 
227         0,
228         256,
229         x, 
230         y,
231         100)
232 {
233         this->plugin = plugin;
234 }
235
236 int VocoderCarrier::handle_event()
237 {
238         plugin->config.carrier_track = atoi(get_text());
239         plugin->send_configure_change();
240         return 1;
241 }
242
243
244
245 VocoderBands::VocoderBands(Vocoder *plugin, 
246         VocoderWindow *window, 
247         int x, 
248         int y)
249  : BC_TumbleTextBox(window,
250         plugin->config.bands, 
251         1,
252         MAX_BANDS,
253         x, 
254         y,
255         100)
256 {
257         this->plugin = plugin;
258 }
259
260 int VocoderBands::handle_event()
261 {
262         plugin->config.bands = atoi(get_text());
263         plugin->send_configure_change();
264         return 1;
265 }
266
267
268
269
270
271 VocoderWindow::VocoderWindow(Vocoder *plugin)
272  : PluginClientWindow(plugin, 
273         320, 
274         150, 
275         320, 
276         150,
277         0)
278 {
279         this->plugin = plugin;
280 }
281
282 VocoderWindow::~VocoderWindow()
283 {
284 }
285
286 void VocoderWindow::create_objects()
287 {
288         int x = plugin->get_theme()->widget_border;
289         int y = plugin->get_theme()->widget_border;
290         BC_Title *title = 0;
291
292         int x1 = x;
293         int y1 = y;
294         add_subwindow(title = new BC_Title(x, y, _("Wetness:")));
295         int x2 = x + title->get_w() + plugin->get_theme()->widget_border;
296         y += BC_Pot::calculate_h() + plugin->get_theme()->widget_border;
297         add_subwindow(title = new BC_Title(x, y, _("Level:")));
298         x2 = MAX(x2, x + title->get_w() + plugin->get_theme()->widget_border);
299
300         x = x2;
301         y = y1;
302         add_subwindow(wetness = new VocoderWetness(plugin, x, y));
303         y += wetness->get_h() + plugin->get_theme()->widget_border;
304         add_subwindow(level = new VocoderLevel(plugin, x, y));
305         y += level->get_h() + plugin->get_theme()->widget_border;
306
307         x = x1;
308         add_subwindow(title = new BC_Title(x, y, _("Carrier Track:")));
309         output = new VocoderCarrier(plugin, 
310                 this, 
311                 x + title->get_w() + plugin->get_theme()->widget_border, 
312                 y);
313         output->create_objects();
314         y += output->get_h() + plugin->get_theme()->widget_border;
315
316         add_subwindow(title = new BC_Title(x, y, _("Bands:")));
317         bands = new VocoderBands(plugin, 
318                 this, 
319                 x + title->get_w() + plugin->get_theme()->widget_border, 
320                 y);
321         bands->create_objects();
322         y += bands->get_h() + plugin->get_theme()->widget_border;
323
324         show_window();
325 }
326
327
328
329 void VocoderWindow::update_gui()
330 {
331         wetness->update(plugin->config.wetness);
332         level->update(plugin->config.level);
333         output->update((int64_t)plugin->config.carrier_track);
334         bands->update((int64_t)plugin->config.bands);
335 }
336
337
338
339
340
341
342
343
344
345
346
347 Vocoder::Vocoder(PluginServer *server)
348  : PluginAClient(server)
349 {
350         need_reconfigure = 1;
351         current_bands = 0;
352 }
353
354 Vocoder::~Vocoder()
355 {
356 }
357
358 NEW_WINDOW_MACRO(Vocoder, VocoderWindow)
359
360 LOAD_CONFIGURATION_MACRO(Vocoder, VocoderConfig)
361
362
363 const char* Vocoder::plugin_title() { return N_("Vocoder"); }
364 int Vocoder::is_realtime() { return 1; }
365 int Vocoder::is_multichannel() { return 1; }
366
367 void Vocoder::read_data(KeyFrame *keyframe)
368 {
369         FileXML input;
370         input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
371
372         int result = 0;
373         while(!result)
374         {
375                 result = input.read_tag();
376
377                 if(!result)
378                 {
379                         if(input.tag.title_is("VOCODER"))
380                         {
381                                 config.wetness = input.tag.get_property("WETNESS", config.wetness);
382                                 config.level = input.tag.get_property("LEVEL", config.level);
383                                 config.carrier_track = input.tag.get_property("OUTPUT", config.carrier_track);
384                                 config.bands = input.tag.get_property("BANDS", config.bands);
385                         }
386                 }
387         }
388 }
389
390 void Vocoder::save_data(KeyFrame *keyframe)
391 {
392         FileXML output;
393         output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
394
395         output.tag.set_title("VOCODER");
396         output.tag.set_property("WETNESS", config.wetness);
397         output.tag.set_property("LEVEL", config.level);
398         output.tag.set_property("OUTPUT", config.carrier_track);
399         output.tag.set_property("BANDS", config.bands);
400         output.append_tag();
401         output.append_newline();
402
403         output.terminate_string();
404 }
405
406 void Vocoder::reconfigure()
407 {
408         need_reconfigure = 0;
409         
410         if(current_bands != config.bands)
411         {
412                 current_bands = config.bands;
413                 for(int i = 0; i < config.bands; i++)
414                 {
415                         formant_bands[i].reset();
416                         double a = 16.0 * i / (double)current_bands;
417
418                         if(a < 4.0)
419                                 formant_bands[i].freq = 150 + 420 * a / 4.0;
420                         else
421                                 formant_bands[i].freq = 600 * pow (1.23, a - 4.0);
422
423                         double c = formant_bands[i].freq * 2 * M_PI / get_samplerate();
424                         formant_bands[i].c = c * c;
425
426                         formant_bands[i].f = 0.4 / c;
427                         formant_bands[i].att =
428                         1  / (6.0 + ((exp (formant_bands[i].freq
429                                     / get_samplerate()) - 1) * 10));
430
431                   carrier_bands[i].copy_from(&formant_bands[i]);
432
433                   output_bands[i].decay = decay_table[(int)a];
434                 }
435         }
436 }
437
438 void Vocoder::do_bandpasses(VocoderBand *bands, double sample)
439 {
440         for(int i = 0; i < current_bands; i++)
441     {
442         bands[i].high1 = sample - bands[i].f * bands[i].mid1 - bands[i].low1;
443         bands[i].mid1 += bands[i].high1 * bands[i].c;
444         bands[i].low1 += bands[i].mid1;
445
446         bands[i].high2 = bands[i].low1 - bands[i].f * bands[i].mid2 - 
447                         bands[i].low2;
448         bands[i].mid2 += bands[i].high2 * bands[i].c;
449         bands[i].low2 += bands[i].mid2;
450         bands[i].y = bands[i].high2 * bands[i].att;
451     }
452 }
453
454
455 int Vocoder::process_buffer(int64_t size, 
456         Samples **buffer, 
457         int64_t start_position,
458         int sample_rate)
459 {
460         need_reconfigure |= load_configuration();
461         if(need_reconfigure) reconfigure();
462
463 // Process all except output channel
464         int carrier_track = config.carrier_track;
465         CLAMP(carrier_track, 0, PluginClient::get_total_buffers() - 1);
466         int formant_track = 0;
467         if(carrier_track == 0) formant_track = 1;
468         CLAMP(formant_track, 0, PluginClient::get_total_buffers() - 1);
469
470
471 // Copy level controls to band levels
472         for(int i = 0; i < current_bands; i++)
473         {
474                 output_bands[i].level = 1.0;
475         }
476
477         
478         for(int i = 0; i < get_total_buffers(); i++)
479         {
480                 read_samples(buffer[i],
481                         i,
482                         get_samplerate(),
483                         start_position,
484                         size);
485         }
486
487         double *carrier_samples = buffer[carrier_track]->get_data();
488         double *formant_samples = buffer[formant_track]->get_data();
489         double *output = buffer[0]->get_data();
490         double wetness = DB::fromdb(config.wetness);
491         double level = DB::fromdb(config.level);
492         for(int i = 0; i < size; i++)
493         {
494                 do_bandpasses(carrier_bands, carrier_samples[i]);
495                 do_bandpasses(formant_bands, formant_samples[i]);
496                 
497                 output[i] *= wetness;
498                 double accum = 0;
499                 for(int j = 0; j < current_bands; j++)
500                 {
501                         output_bands[j].oldval = output_bands[j].oldval +
502                         (fabs (formant_bands[j].y) - 
503                                 output_bands[j].oldval) * 
504                         output_bands[j].decay;
505                         double x = carrier_bands[j].y * output_bands[j].oldval;
506                         accum += x * output_bands[j].level;
507                 }
508
509                 accum *= level;
510
511                 output[i] += accum;
512         }
513
514         return 0;
515 }
516
517
518
519
520
521
522
523
524
525
526 void Vocoder::reset()
527 {
528         need_reconfigure = 1;
529         thread = 0;
530 }
531
532 void Vocoder::update_gui()
533 {
534         if(thread)
535         {
536                 if(load_configuration())
537                 {
538                         ((VocoderWindow*)thread->window)->lock_window("Vocoder::update_gui");
539                         ((VocoderWindow*)thread->window)->update_gui();
540                         ((VocoderWindow*)thread->window)->unlock_window();
541                 }
542         }
543 }
544
545
546