1 /* autotalent.c
2 A pitch-correcting LADSPA plugin.
3
4 Free software by Thomas A. Baran.
5 http://web.mit.edu/tbaran/www/autotalent.html
6 VERSION 0.2
7 March 20, 2010
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23 */
24
25 /*****************************************************************************/
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <math.h>
30 #include <stdio.h>
31 #define PI (float)3.14159265358979323846
32 #define L2SC (float)3.32192809488736218171
33
34 /*****************************************************************************/
35
36 #include "ladspa.h"
37
38 #include "mayer_fft.h"
39
40 // Variables for FFT routine
41 typedef struct
42 {
43 int nfft; // size of FFT
44 int numfreqs; // number of frequencies represented (nfft/2 + 1)
45 float* fft_data; // array for writing/reading to/from FFT function
46 } fft_vars;
47
48 // Constructor for FFT routine
fft_con(int nfft)49 fft_vars* fft_con(int nfft)
50 {
51 fft_vars* membvars = (fft_vars*) malloc(sizeof(fft_vars));
52
53 membvars->nfft = nfft;
54 membvars->numfreqs = nfft/2 + 1;
55
56 membvars->fft_data = (float*) calloc(nfft, sizeof(float));
57
58 return membvars;
59 }
60
61 // Destructor for FFT routine
fft_des(fft_vars * membvars)62 void fft_des(fft_vars* membvars)
63 {
64 free(membvars->fft_data);
65
66 free(membvars);
67 }
68
69 // Perform forward FFT of real data
70 // Accepts:
71 // membvars - pointer to struct of FFT variables
72 // input - pointer to an array of (real) input values, size nfft
73 // output_re - pointer to an array of the real part of the output,
74 // size nfft/2 + 1
75 // output_im - pointer to an array of the imaginary part of the output,
76 // size nfft/2 + 1
fft_forward(fft_vars * membvars,float * input,float * output_re,float * output_im)77 void fft_forward(fft_vars* membvars, float* input, float* output_re, float* output_im)
78 {
79 int ti;
80 int nfft;
81 int hnfft;
82 int numfreqs;
83
84 nfft = membvars->nfft;
85 hnfft = nfft/2;
86 numfreqs = membvars->numfreqs;
87
88 for (ti=0; ti<nfft; ti++) {
89 membvars->fft_data[ti] = input[ti];
90 }
91
92 mayer_realfft(nfft, membvars->fft_data);
93
94 output_im[0] = 0;
95 for (ti=0; ti<hnfft; ti++) {
96 output_re[ti] = membvars->fft_data[ti];
97 output_im[ti+1] = membvars->fft_data[nfft-1-ti];
98 }
99 output_re[hnfft] = membvars->fft_data[hnfft];
100 output_im[hnfft] = 0;
101 }
102
103 // Perform inverse FFT, returning real data
104 // Accepts:
105 // membvars - pointer to struct of FFT variables
106 // input_re - pointer to an array of the real part of the output,
107 // size nfft/2 + 1
108 // input_im - pointer to an array of the imaginary part of the output,
109 // size nfft/2 + 1
110 // output - pointer to an array of (real) input values, size nfft
fft_inverse(fft_vars * membvars,float * input_re,float * input_im,float * output)111 void fft_inverse(fft_vars* membvars, float* input_re, float* input_im, float* output)
112 {
113 int ti;
114 int nfft;
115 int hnfft;
116 int numfreqs;
117
118 nfft = membvars->nfft;
119 hnfft = nfft/2;
120 numfreqs = membvars->numfreqs;
121
122 for (ti=0; ti<hnfft; ti++) {
123 membvars->fft_data[ti] = input_re[ti];
124 membvars->fft_data[nfft-1-ti] = input_im[ti+1];
125 }
126 membvars->fft_data[hnfft] = input_re[hnfft];
127
128 mayer_realifft(nfft, membvars->fft_data);
129
130 for (ti=0; ti<nfft; ti++) {
131 output[ti] = membvars->fft_data[ti];
132 }
133 }
134
135 // DONE WITH FFT CODE
136
137
138 // The port numbers
139
140 #define AT_TUNE 0
141 #define AT_FIXED 1
142 #define AT_PULL 2
143 #define AT_A 3
144 #define AT_Bb 4
145 #define AT_B 5
146 #define AT_C 6
147 #define AT_Db 7
148 #define AT_D 8
149 #define AT_Eb 9
150 #define AT_E 10
151 #define AT_F 11
152 #define AT_Gb 12
153 #define AT_G 13
154 #define AT_Ab 14
155 #define AT_AMOUNT 15
156 #define AT_SMOOTH 16
157 #define AT_SHIFT 17
158 #define AT_SCWARP 18
159 #define AT_LFOAMP 19
160 #define AT_LFORATE 20
161 #define AT_LFOSHAPE 21
162 #define AT_LFOSYMM 22
163 #define AT_LFOQUANT 23
164 #define AT_FCORR 24
165 #define AT_FWARP 25
166 #define AT_MIX 26
167 #define AT_PITCH 27
168 #define AT_CONF 28
169 #define AT_INPUT1 29
170 #define AT_OUTPUT1 30
171 #define AT_LATENCY 31
172
173
174
175 /*************************
176 * THE MEMBER VARIABLES *
177 *************************/
178
179 typedef struct {
180
181 LADSPA_Data* m_pfTune;
182 LADSPA_Data* m_pfFixed;
183 LADSPA_Data* m_pfPull;
184 LADSPA_Data* m_pfA;
185 LADSPA_Data* m_pfBb;
186 LADSPA_Data* m_pfB;
187 LADSPA_Data* m_pfC;
188 LADSPA_Data* m_pfDb;
189 LADSPA_Data* m_pfD;
190 LADSPA_Data* m_pfEb;
191 LADSPA_Data* m_pfE;
192 LADSPA_Data* m_pfF;
193 LADSPA_Data* m_pfGb;
194 LADSPA_Data* m_pfG;
195 LADSPA_Data* m_pfAb;
196 LADSPA_Data* m_pfAmount;
197 LADSPA_Data* m_pfSmooth;
198 LADSPA_Data* m_pfShift;
199 LADSPA_Data* m_pfScwarp;
200 LADSPA_Data* m_pfLfoamp;
201 LADSPA_Data* m_pfLforate;
202 LADSPA_Data* m_pfLfoshape;
203 LADSPA_Data* m_pfLfosymm;
204 LADSPA_Data* m_pfLfoquant;
205 LADSPA_Data* m_pfFcorr;
206 LADSPA_Data* m_pfFwarp;
207 LADSPA_Data* m_pfMix;
208 LADSPA_Data* m_pfPitch;
209 LADSPA_Data* m_pfConf;
210 LADSPA_Data* m_pfInputBuffer1;
211 LADSPA_Data* m_pfOutputBuffer1;
212 LADSPA_Data* m_pfLatency;
213 fft_vars* fmembvars; // member variables for fft routine
214
215 unsigned long fs; // Sample rate
216
217 unsigned long cbsize; // size of circular buffer
218 unsigned long corrsize; // cbsize/2 + 1
219 unsigned long cbiwr;
220 unsigned long cbord;
221 float* cbi; // circular input buffer
222 float* cbf; // circular formant correction buffer
223 float* cbo; // circular output buffer
224
225 float* cbwindow; // hann of length N/2, zeros for the rest
226 float* acwinv; // inverse of autocorrelation of window
227 float* hannwindow; // length-N hann
228 int noverlap;
229
230 float* ffttime;
231 float* fftfreqre;
232 float* fftfreqim;
233
234 // VARIABLES FOR LOW-RATE SECTION
235 float aref; // A tuning reference (Hz)
236 float inpitch; // Input pitch (semitones)
237 float conf; // Confidence of pitch period estimate (between 0 and 1)
238 float outpitch; // Output pitch (semitones)
239 float vthresh; // Voiced speech threshold
240
241 float pmax; // Maximum allowable pitch period (seconds)
242 float pmin; // Minimum allowable pitch period (seconds)
243 unsigned long nmax; // Maximum period index for pitch prd est
244 unsigned long nmin; // Minimum period index for pitch prd est
245
246 float lrshift; // Shift prescribed by low-rate section
247 int ptarget; // Pitch target, between 0 and 11
248 float sptarget; // Smoothed pitch target
249
250 float lfophase;
251
252 // VARIABLES FOR PITCH SHIFTER
253 float phprdd; // default (unvoiced) phase period
254 double inphinc; // input phase increment
255 double outphinc; // input phase increment
256 double phincfact; // factor determining output phase increment
257 double phasein;
258 double phaseout;
259 float* frag; // windowed fragment of speech
260 unsigned long fragsize; // size of fragment in samples
261
262 // VARIABLES FOR FORMANT CORRECTOR
263 int ford;
264 float falph;
265 float flamb;
266 float* fk;
267 float* fb;
268 float* fc;
269 float* frb;
270 float* frc;
271 float* fsig;
272 float* fsmooth;
273 float fhp;
274 float flp;
275 float flpa;
276 float** fbuff;
277 float* ftvec;
278 float fmute;
279 float fmutealph;
280
281 } Autotalent;
282
283
284
285 /********************
286 * THE CONSTRUCTOR *
287 ********************/
288
289 LADSPA_Handle
instantiateAutotalent(const LADSPA_Descriptor * Descriptor,unsigned long SampleRate)290 instantiateAutotalent(const LADSPA_Descriptor * Descriptor,
291 unsigned long SampleRate) {
292
293 unsigned long ti;
294
295 Autotalent* membvars = malloc(sizeof(Autotalent));
296
297 membvars->aref = 440;
298
299 membvars->fs = SampleRate;
300
301 if (SampleRate>=88200) {
302 membvars->cbsize = 4096;
303 }
304 else {
305 membvars->cbsize = 2048;
306 }
307 membvars->corrsize = membvars->cbsize / 2 + 1;
308
309 membvars->pmax = 1/(float)70; // max and min periods (ms)
310 membvars->pmin = 1/(float)700; // eventually may want to bring these out as sliders
311
312 membvars->nmax = (unsigned long)(SampleRate * membvars->pmax);
313 if (membvars->nmax > membvars->corrsize) {
314 membvars->nmax = membvars->corrsize;
315 }
316 membvars->nmin = (unsigned long)(SampleRate * membvars->pmin);
317
318 membvars->cbi = calloc(membvars->cbsize, sizeof(float));
319 membvars->cbf = calloc(membvars->cbsize, sizeof(float));
320 membvars->cbo = calloc(membvars->cbsize, sizeof(float));
321
322 membvars->cbiwr = 0;
323 membvars->cbord = 0;
324
325 membvars->lfophase = 0;
326
327 // Initialize formant corrector
328 membvars->ford = 7; // should be sufficient to capture formants
329 membvars->falph = pow(0.001, (float) 80 / (SampleRate));
330 membvars->flamb = -(0.8517*sqrt(atan(0.06583*SampleRate))-0.1916); // or about -0.88 @ 44.1kHz
331 membvars->fk = calloc(membvars->ford, sizeof(float));
332 membvars->fb = calloc(membvars->ford, sizeof(float));
333 membvars->fc = calloc(membvars->ford, sizeof(float));
334 membvars->frb = calloc(membvars->ford, sizeof(float));
335 membvars->frc = calloc(membvars->ford, sizeof(float));
336 membvars->fsig = calloc(membvars->ford, sizeof(float));
337 membvars->fsmooth = calloc(membvars->ford, sizeof(float));
338 membvars->fhp = 0;
339 membvars->flp = 0;
340 membvars->flpa = pow(0.001, (float) 10 / (SampleRate));
341 membvars->fbuff = (float**) malloc((membvars->ford)*sizeof(float*));
342 for (ti=0; ti<membvars->ford; ti++) {
343 membvars->fbuff[ti] = calloc(membvars->cbsize, sizeof(float));
344 }
345 membvars->ftvec = calloc(membvars->ford, sizeof(float));
346 membvars->fmute = 1;
347 membvars->fmutealph = pow(0.001, (float)1 / (SampleRate));
348
349 // Standard raised cosine window, max height at N/2
350 membvars->hannwindow = calloc(membvars->cbsize, sizeof(float));
351 for (ti=0; ti<membvars->cbsize; ti++) {
352 membvars->hannwindow[ti] = -0.5*cos(2*PI*ti/membvars->cbsize) + 0.5;
353 }
354
355 // Generate a window with a single raised cosine from N/4 to 3N/4
356 membvars->cbwindow = calloc(membvars->cbsize, sizeof(float));
357 for (ti=0; ti<(membvars->cbsize / 2); ti++) {
358 membvars->cbwindow[ti+membvars->cbsize/4] = -0.5*cos(4*PI*ti/(membvars->cbsize - 1)) + 0.5;
359 }
360
361 membvars->noverlap = 4;
362
363 membvars->fmembvars = fft_con(membvars->cbsize);
364
365 membvars->ffttime = calloc(membvars->cbsize, sizeof(float));
366 membvars->fftfreqre = calloc(membvars->corrsize, sizeof(float));
367 membvars->fftfreqim = calloc(membvars->corrsize, sizeof(float));
368
369
370 // ---- Calculate autocorrelation of window ----
371 membvars->acwinv = calloc(membvars->cbsize, sizeof(float));
372 for (ti=0; ti<membvars->cbsize; ti++) {
373 membvars->ffttime[ti] = membvars->cbwindow[ti];
374 }
375 fft_forward(membvars->fmembvars, membvars->cbwindow, membvars->fftfreqre, membvars->fftfreqim);
376 for (ti=0; ti<membvars->corrsize; ti++) {
377 membvars->fftfreqre[ti] = (membvars->fftfreqre[ti])*(membvars->fftfreqre[ti]) + (membvars->fftfreqim[ti])*(membvars->fftfreqim[ti]);
378 membvars->fftfreqim[ti] = 0;
379 }
380 fft_inverse(membvars->fmembvars, membvars->fftfreqre, membvars->fftfreqim, membvars->ffttime);
381 for (ti=1; ti<membvars->cbsize; ti++) {
382 membvars->acwinv[ti] = membvars->ffttime[ti]/membvars->ffttime[0];
383 if (membvars->acwinv[ti] > 0.000001) {
384 membvars->acwinv[ti] = (float)1/membvars->acwinv[ti];
385 }
386 else {
387 membvars->acwinv[ti] = 0;
388 }
389 }
390 membvars->acwinv[0] = 1;
391 // ---- END Calculate autocorrelation of window ----
392
393
394 membvars->lrshift = 0;
395 membvars->ptarget = 0;
396 membvars->sptarget = 0;
397
398 membvars->vthresh = 0.7; // The voiced confidence (unbiased peak) threshold level
399
400 // Pitch shifter initialization
401 membvars->phprdd = 0.01; // Default period
402 membvars->inphinc = (float)1/(membvars->phprdd * SampleRate);
403 membvars->phincfact = 1;
404 membvars->phasein = 0;
405 membvars->phaseout = 0;
406 membvars->frag = calloc(membvars->cbsize, sizeof(float));
407 membvars->fragsize = 0;
408
409
410 return membvars;
411 }
412
413
414 // Connect port
415 void
connectPortToAutotalent(LADSPA_Handle Instance,unsigned long Port,LADSPA_Data * DataLocation)416 connectPortToAutotalent(LADSPA_Handle Instance,
417 unsigned long Port,
418 LADSPA_Data * DataLocation) {
419
420 Autotalent * psAutotalent;
421
422 psAutotalent = (Autotalent *)Instance;
423 switch (Port) {
424 case AT_TUNE:
425 psAutotalent->m_pfTune = DataLocation;
426 break;
427 case AT_FIXED:
428 psAutotalent->m_pfFixed = DataLocation;
429 break;
430 case AT_PULL:
431 psAutotalent->m_pfPull = DataLocation;
432 break;
433 case AT_A:
434 psAutotalent->m_pfA = DataLocation;
435 break;
436 case AT_Bb:
437 psAutotalent->m_pfBb = DataLocation;
438 break;
439 case AT_B:
440 psAutotalent->m_pfB = DataLocation;
441 break;
442 case AT_C:
443 psAutotalent->m_pfC = DataLocation;
444 break;
445 case AT_Db:
446 psAutotalent->m_pfDb = DataLocation;
447 break;
448 case AT_D:
449 psAutotalent->m_pfD = DataLocation;
450 break;
451 case AT_Eb:
452 psAutotalent->m_pfEb = DataLocation;
453 break;
454 case AT_E:
455 psAutotalent->m_pfE = DataLocation;
456 break;
457 case AT_F:
458 psAutotalent->m_pfF = DataLocation;
459 break;
460 case AT_Gb:
461 psAutotalent->m_pfGb = DataLocation;
462 break;
463 case AT_G:
464 psAutotalent->m_pfG = DataLocation;
465 break;
466 case AT_Ab:
467 psAutotalent->m_pfAb = DataLocation;
468 break;
469 case AT_AMOUNT:
470 psAutotalent->m_pfAmount = DataLocation;
471 break;
472 case AT_SMOOTH:
473 psAutotalent->m_pfSmooth = DataLocation;
474 break;
475 case AT_SHIFT:
476 psAutotalent->m_pfShift = DataLocation;
477 break;
478 case AT_SCWARP:
479 psAutotalent->m_pfScwarp = DataLocation;
480 break;
481 case AT_LFOAMP:
482 psAutotalent->m_pfLfoamp = DataLocation;
483 break;
484 case AT_LFORATE:
485 psAutotalent->m_pfLforate = DataLocation;
486 break;
487 case AT_LFOSHAPE:
488 psAutotalent->m_pfLfoshape = DataLocation;
489 break;
490 case AT_LFOSYMM:
491 psAutotalent->m_pfLfosymm = DataLocation;
492 break;
493 case AT_LFOQUANT:
494 psAutotalent->m_pfLfoquant = DataLocation;
495 break;
496 case AT_FCORR:
497 psAutotalent->m_pfFcorr = DataLocation;
498 break;
499 case AT_FWARP:
500 psAutotalent->m_pfFwarp = DataLocation;
501 break;
502 case AT_MIX:
503 psAutotalent->m_pfMix = DataLocation;
504 break;
505 case AT_PITCH:
506 psAutotalent->m_pfPitch = DataLocation;
507 break;
508 case AT_CONF:
509 psAutotalent->m_pfConf = DataLocation;
510 break;
511 case AT_INPUT1:
512 psAutotalent->m_pfInputBuffer1 = DataLocation;
513 break;
514 case AT_OUTPUT1:
515 psAutotalent->m_pfOutputBuffer1 = DataLocation;
516 break;
517 case AT_LATENCY:
518 psAutotalent->m_pfLatency = DataLocation;
519 *(psAutotalent->m_pfLatency) = psAutotalent->cbsize - 1;
520 break;
521 }
522 }
523
524
525 // Called every time we get a new chunk of audio
526 void
runAutotalent(LADSPA_Handle Instance,unsigned long SampleCount)527 runAutotalent(LADSPA_Handle Instance,
528 unsigned long SampleCount) {
529
530 LADSPA_Data* pfInput;
531 LADSPA_Data* pfOutput;
532 float fAmount;
533 float fSmooth;
534 int iNotes[12];
535 int iPitch2Note[12];
536 int iNote2Pitch[12];
537 int numNotes;
538 float fTune;
539 float fFixed;
540 float fPull;
541 float fShift;
542 int iScwarp;
543 float fLfoamp;
544 float fLforate;
545 float fLfoshape;
546 float fLfosymm;
547 int iLfoquant;
548 int iFcorr;
549 float fFwarp;
550 float fMix;
551 Autotalent* psAutotalent;
552 unsigned long lSampleIndex;
553
554 long int N;
555 long int Nf;
556 long int fs;
557 float pmin;
558 float pmax;
559 unsigned long nmin;
560 unsigned long nmax;
561
562 long int ti;
563 long int ti2;
564 long int ti3;
565 long int ti4;
566 float tf;
567 float tf2;
568
569 // Variables for cubic spline interpolator
570 float indd;
571 int ind0;
572 int ind1;
573 int ind2;
574 int ind3;
575 float vald;
576 float val0;
577 float val1;
578 float val2;
579 float val3;
580
581 int lowersnap;
582 int uppersnap;
583 float lfoval;
584
585 float pperiod;
586 float inpitch;
587 float conf;
588 float outpitch;
589 float aref;
590 float fa;
591 float fb;
592 float fc;
593 float fk;
594 float flamb;
595 float frlamb;
596 float falph;
597 float foma;
598 float f1resp;
599 float f0resp;
600 float flpa;
601 int ford;
602 psAutotalent = (Autotalent *)Instance;
603
604 pfInput = psAutotalent->m_pfInputBuffer1;
605 pfOutput = psAutotalent->m_pfOutputBuffer1;
606 fAmount = (float) *(psAutotalent->m_pfAmount);
607 fSmooth = (float) *(psAutotalent->m_pfSmooth) * 0.8; // Scales max to a more reasonable value
608 fTune = (float) *(psAutotalent->m_pfTune);
609 iNotes[0] = (int) *(psAutotalent->m_pfA);
610 iNotes[1] = (int) *(psAutotalent->m_pfBb);
611 iNotes[2] = (int) *(psAutotalent->m_pfB);
612 iNotes[3] = (int) *(psAutotalent->m_pfC);
613 iNotes[4] = (int) *(psAutotalent->m_pfDb);
614 iNotes[5] = (int) *(psAutotalent->m_pfD);
615 iNotes[6] = (int) *(psAutotalent->m_pfEb);
616 iNotes[7] = (int) *(psAutotalent->m_pfE);
617 iNotes[8] = (int) *(psAutotalent->m_pfF);
618 iNotes[9] = (int) *(psAutotalent->m_pfGb);
619 iNotes[10] = (int) *(psAutotalent->m_pfG);
620 iNotes[11] = (int) *(psAutotalent->m_pfAb);
621 fFixed = (float) *(psAutotalent->m_pfFixed);
622 fPull = (float) *(psAutotalent->m_pfPull);
623 fShift = (float) *(psAutotalent->m_pfShift);
624 iScwarp = (int) *(psAutotalent->m_pfScwarp);
625 fLfoamp = (float) *(psAutotalent->m_pfLfoamp);
626 fLforate = (float) *(psAutotalent->m_pfLforate);
627 fLfoshape = (float) *(psAutotalent->m_pfLfoshape);
628 fLfosymm = (float) *(psAutotalent->m_pfLfosymm);
629 iLfoquant = (int) *(psAutotalent->m_pfLfoquant);
630 iFcorr = (int) *(psAutotalent->m_pfFcorr);
631 fFwarp = (float) *(psAutotalent->m_pfFwarp);
632 fMix = (float) *(psAutotalent->m_pfMix);
633
634 // Some logic for the semitone->scale and scale->semitone conversion
635 // If no notes are selected as being in the scale, instead snap to all notes
636 ti2 = 0;
637 for (ti=0; ti<12; ti++) {
638 if (iNotes[ti]>=0) {
639 iPitch2Note[ti] = ti2;
640 iNote2Pitch[ti2] = ti;
641 ti2 = ti2 + 1;
642 }
643 else {
644 iPitch2Note[ti] = -1;
645 }
646 }
647 numNotes = ti2;
648 while (ti2<12) {
649 iNote2Pitch[ti2] = -1;
650 ti2 = ti2 + 1;
651 }
652 if (numNotes==0) {
653 for (ti=0; ti<12; ti++) {
654 iNotes[ti] = 1;
655 iPitch2Note[ti] = ti;
656 iNote2Pitch[ti] = ti;
657 }
658 numNotes = 12;
659 }
660 iScwarp = (iScwarp + numNotes*5)%numNotes;
661
662 ford = psAutotalent->ford;
663 falph = psAutotalent->falph;
664 foma = (float)1 - falph;
665 flpa = psAutotalent->flpa;
666 flamb = psAutotalent->flamb;
667 tf = pow((float)2,fFwarp/2)*(1+flamb)/(1-flamb);
668 frlamb = (tf - 1)/(tf + 1);
669
670 psAutotalent->aref = (float)fTune;
671
672 N = psAutotalent->cbsize;
673 Nf = psAutotalent->corrsize;
674 fs = psAutotalent->fs;
675
676 pmax = psAutotalent->pmax;
677 pmin = psAutotalent->pmin;
678 nmax = psAutotalent->nmax;
679 nmin = psAutotalent->nmin;
680
681 aref = psAutotalent->aref;
682 pperiod = psAutotalent->pmax;
683 inpitch = psAutotalent->inpitch;
684 conf = psAutotalent->conf;
685 outpitch = psAutotalent->outpitch;
686
687
688 /*******************
689 * MAIN DSP LOOP *
690 *******************/
691 for (lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) {
692
693 // load data into circular buffer
694 tf = (float) *(pfInput++);
695 ti4 = psAutotalent->cbiwr;
696 psAutotalent->cbi[ti4] = tf;
697
698 if (iFcorr>=1) {
699 // Somewhat experimental formant corrector
700 // formants are removed using an adaptive pre-filter and
701 // re-introduced after pitch manipulation using post-filter
702 // tf is signal input
703 fa = tf - psAutotalent->fhp; // highpass pre-emphasis filter
704 psAutotalent->fhp = tf;
705 fb = fa;
706 for (ti=0; ti<ford; ti++) {
707 psAutotalent->fsig[ti] = fa*fa*foma + psAutotalent->fsig[ti]*falph;
708 fc = (fb-psAutotalent->fc[ti])*flamb + psAutotalent->fb[ti];
709 psAutotalent->fc[ti] = fc;
710 psAutotalent->fb[ti] = fb;
711 fk = fa*fc*foma + psAutotalent->fk[ti]*falph;
712 psAutotalent->fk[ti] = fk;
713 tf = fk/(psAutotalent->fsig[ti] + 0.000001);
714 tf = tf*foma + psAutotalent->fsmooth[ti]*falph;
715 psAutotalent->fsmooth[ti] = tf;
716 psAutotalent->fbuff[ti][ti4] = tf;
717 fb = fc - tf*fa;
718 fa = fa - tf*fc;
719 }
720 psAutotalent->cbf[ti4] = fa;
721 // Now hopefully the formants are reduced
722 // More formant correction code at the end of the DSP loop
723 }
724 else {
725 psAutotalent->cbf[ti4] = tf;
726 }
727
728
729 // Input write pointer logic
730 psAutotalent->cbiwr++;
731 if (psAutotalent->cbiwr >= N) {
732 psAutotalent->cbiwr = 0;
733 }
734
735
736 // ********************
737 // * Low-rate section *
738 // ********************
739
740 // Every N/noverlap samples, run pitch estimation / manipulation code
741 if ((psAutotalent->cbiwr)%(N/psAutotalent->noverlap) == 0) {
742
743 // ---- Obtain autocovariance ----
744
745 // Window and fill FFT buffer
746 ti2 = psAutotalent->cbiwr;
747 for (ti=0; ti<N; ti++) {
748 psAutotalent->ffttime[ti] = (float)(psAutotalent->cbi[(ti2-ti+N)%N]*psAutotalent->cbwindow[ti]);
749 }
750
751 // Calculate FFT
752 fft_forward(psAutotalent->fmembvars, psAutotalent->ffttime, psAutotalent->fftfreqre, psAutotalent->fftfreqim);
753
754 // Remove DC
755 psAutotalent->fftfreqre[0] = 0;
756 psAutotalent->fftfreqim[0] = 0;
757
758 // Take magnitude squared
759 for (ti=1; ti<Nf; ti++) {
760 psAutotalent->fftfreqre[ti] = (psAutotalent->fftfreqre[ti])*(psAutotalent->fftfreqre[ti]) + (psAutotalent->fftfreqim[ti])*(psAutotalent->fftfreqim[ti]);
761 psAutotalent->fftfreqim[ti] = 0;
762 }
763
764 // Calculate IFFT
765 fft_inverse(psAutotalent->fmembvars, psAutotalent->fftfreqre, psAutotalent->fftfreqim, psAutotalent->ffttime);
766
767 // Normalize
768 tf = (float)1/psAutotalent->ffttime[0];
769 for (ti=1; ti<N; ti++) {
770 psAutotalent->ffttime[ti] = psAutotalent->ffttime[ti] * tf;
771 }
772 psAutotalent->ffttime[0] = 1;
773
774 // ---- END Obtain autocovariance ----
775
776
777 // ---- Calculate pitch and confidence ----
778
779 // Calculate pitch period
780 // Pitch period is determined by the location of the max (biased)
781 // peak within a given range
782 // Confidence is determined by the corresponding unbiased height
783 tf2 = 0;
784 pperiod = pmin;
785 for (ti=nmin; ti<nmax; ti++) {
786 ti2 = ti-1;
787 ti3 = ti+1;
788 if (ti2<0) {
789 ti2 = 0;
790 }
791 if (ti3>Nf) {
792 ti3 = Nf;
793 }
794 tf = psAutotalent->ffttime[ti];
795
796 if (tf>psAutotalent->ffttime[ti2] && tf>=psAutotalent->ffttime[ti3] && tf>tf2) {
797 tf2 = tf;
798 ti4 = ti;
799 }
800 }
801 if (tf2>0) {
802 conf = tf2*psAutotalent->acwinv[ti4];
803 if (ti4>0 && ti4<Nf) {
804 // Find the center of mass in the vicinity of the detected peak
805 tf = psAutotalent->ffttime[ti4-1]*(ti4-1);
806 tf = tf + psAutotalent->ffttime[ti4]*(ti4);
807 tf = tf + psAutotalent->ffttime[ti4+1]*(ti4+1);
808 tf = tf/(psAutotalent->ffttime[ti4-1] + psAutotalent->ffttime[ti4] + psAutotalent->ffttime[ti4+1]);
809 pperiod = tf/fs;
810 }
811 else {
812 pperiod = (float)ti4/fs;
813 }
814 }
815
816 // Convert to semitones
817 tf = (float) -12*log10((float)aref*pperiod)*L2SC;
818 if (conf>=psAutotalent->vthresh) {
819 inpitch = tf;
820 psAutotalent->inpitch = tf; // update pitch only if voiced
821 }
822 psAutotalent->conf = conf;
823
824 *(psAutotalent->m_pfPitch) = (LADSPA_Data) inpitch;
825 *(psAutotalent->m_pfConf) = (LADSPA_Data) conf;
826
827 // ---- END Calculate pitch and confidence ----
828
829
830 // ---- Modify pitch in all kinds of ways! ----
831
832 outpitch = inpitch;
833
834 // Pull to fixed pitch
835 outpitch = (1-fPull)*outpitch + fPull*fFixed;
836
837 // -- Convert from semitones to scale notes --
838 ti = (int)(outpitch/12 + 32) - 32; // octave
839 tf = outpitch - ti*12; // semitone in octave
840 ti2 = (int)tf;
841 ti3 = ti2 + 1;
842 // a little bit of pitch correction logic, since it's a convenient place for it
843 if (iNotes[ti2%12]<0 || iNotes[ti3%12]<0) { // if between 2 notes that are more than a semitone apart
844 lowersnap = 1;
845 uppersnap = 1;
846 }
847 else {
848 lowersnap = 0;
849 uppersnap = 0;
850 if (iNotes[ti2%12]==1) { // if specified by user
851 lowersnap = 1;
852 }
853 if (iNotes[ti3%12]==1) { // if specified by user
854 uppersnap = 1;
855 }
856 }
857 // (back to the semitone->scale conversion)
858 // finding next lower pitch in scale
859 while (iNotes[(ti2+12)%12]<0) {
860 ti2 = ti2 - 1;
861 }
862 // finding next higher pitch in scale
863 while (iNotes[ti3%12]<0) {
864 ti3 = ti3 + 1;
865 }
866 tf = (tf-ti2)/(ti3-ti2) + iPitch2Note[(ti2+12)%12];
867 if (ti2<0) {
868 tf = tf - numNotes;
869 }
870 outpitch = tf + numNotes*ti;
871 // -- Done converting to scale notes --
872
873 // The actual pitch correction
874 ti = (int)(outpitch+128) - 128;
875 tf = outpitch - ti - 0.5;
876 ti2 = ti3-ti2;
877 if (ti2>2) { // if more than 2 semitones apart, put a 2-semitone-like transition halfway between
878 tf2 = (float)ti2/2;
879 }
880 else {
881 tf2 = (float)1;
882 }
883 if (fSmooth<0.001) {
884 tf2 = tf*tf2/0.001;
885 }
886 else {
887 tf2 = tf*tf2/fSmooth;
888 }
889 if (tf2<-0.5) tf2 = -0.5;
890 if (tf2>0.5) tf2 = 0.5;
891 tf2 = 0.5*sin(PI*tf2) + 0.5; // jumping between notes using horizontally-scaled sine segment
892 tf2 = tf2 + ti;
893 if ( (tf<0.5 && lowersnap) || (tf>=0.5 && uppersnap) ) {
894 outpitch = fAmount*tf2 + ((float)1-fAmount)*outpitch;
895 }
896
897 // Add in pitch shift
898 outpitch = outpitch + fShift;
899
900 // LFO logic
901 tf = fLforate*N/(psAutotalent->noverlap*fs);
902 if (tf>1) tf=1;
903 psAutotalent->lfophase = psAutotalent->lfophase + tf;
904 if (psAutotalent->lfophase>1) psAutotalent->lfophase = psAutotalent->lfophase-1;
905 lfoval = psAutotalent->lfophase;
906 tf = (fLfosymm + 1)/2;
907 if (tf<=0 || tf>=1) {
908 if (tf<=0) lfoval = 1-lfoval;
909 }
910 else {
911 if (lfoval<=tf) {
912 lfoval = lfoval/tf;
913 }
914 else {
915 lfoval = 1 - (lfoval-tf)/(1-tf);
916 }
917 }
918 if (fLfoshape>=0) {
919 // linear combination of cos and line
920 lfoval = (0.5 - 0.5*cos(lfoval*PI))*fLfoshape + lfoval*(1-fLfoshape);
921 lfoval = fLfoamp*(lfoval*2 - 1);
922 }
923 else {
924 // smoosh the sine horizontally until it's squarish
925 tf = 1 + fLfoshape;
926 if (tf<0.001) {
927 lfoval = (lfoval - 0.5)*2/0.001;
928 }
929 else {
930 lfoval = (lfoval - 0.5)*2/tf;
931 }
932 if (lfoval>1) lfoval = 1;
933 if (lfoval<-1) lfoval = -1;
934 lfoval = fLfoamp*sin(lfoval*PI*0.5);
935 }
936 // add in quantized LFO
937 if (iLfoquant>=1) {
938 outpitch = outpitch + (int)(numNotes*lfoval + numNotes + 0.5) - numNotes;
939 }
940
941
942 // Convert back from scale notes to semitones
943 outpitch = outpitch + iScwarp; // output scale rotate implemented here
944 ti = (int)(outpitch/numNotes + 32) - 32;
945 tf = outpitch - ti*numNotes;
946 ti2 = (int)tf;
947 ti3 = ti2 + 1;
948 outpitch = iNote2Pitch[ti3%numNotes] - iNote2Pitch[ti2];
949 if (ti3>=numNotes) {
950 outpitch = outpitch + 12;
951 }
952 outpitch = outpitch*(tf - ti2) + iNote2Pitch[ti2];
953 outpitch = outpitch + 12*ti;
954 outpitch = outpitch - (iNote2Pitch[iScwarp] - iNote2Pitch[0]); //more scale rotation here
955
956 // add in unquantized LFO
957 if (iLfoquant<=0) {
958 outpitch = outpitch + lfoval*2;
959 }
960
961
962 if (outpitch<-36) outpitch = -48;
963 if (outpitch>24) outpitch = 24;
964
965 psAutotalent->outpitch = outpitch;
966
967 // ---- END Modify pitch in all kinds of ways! ----
968
969 // Compute variables for pitch shifter that depend on pitch
970 psAutotalent->inphinc = aref*pow(2,inpitch/12)/fs;
971 psAutotalent->outphinc = aref*pow(2,outpitch/12)/fs;
972 psAutotalent->phincfact = psAutotalent->outphinc/psAutotalent->inphinc;
973 }
974 // ************************
975 // * END Low-Rate Section *
976 // ************************
977
978
979
980 // *****************
981 // * Pitch Shifter *
982 // *****************
983
984 // Pitch shifter (kind of like a pitch-synchronous version of Fairbanks' technique)
985 // Note: pitch estimate is naturally N/2 samples old
986 psAutotalent->phasein = psAutotalent->phasein + psAutotalent->inphinc;
987 psAutotalent->phaseout = psAutotalent->phaseout + psAutotalent->outphinc;
988
989 // When input phase resets, take a snippet from N/2 samples in the past
990 if (psAutotalent->phasein >= 1) {
991 psAutotalent->phasein = psAutotalent->phasein - 1;
992 ti2 = psAutotalent->cbiwr - N/2;
993 for (ti=-N/2; ti<N/2; ti++) {
994 psAutotalent->frag[(ti+N)%N] = psAutotalent->cbf[(ti + ti2 + N)%N];
995 }
996 }
997
998 // When output phase resets, put a snippet N/2 samples in the future
999 if (psAutotalent->phaseout >= 1) {
1000 psAutotalent->fragsize = psAutotalent->fragsize*2;
1001 if (psAutotalent->fragsize > N) {
1002 psAutotalent->fragsize = N;
1003 }
1004 psAutotalent->phaseout = psAutotalent->phaseout - 1;
1005 ti2 = psAutotalent->cbord + N/2;
1006 ti3 = (long int)(((float)psAutotalent->fragsize) / psAutotalent->phincfact);
1007 if (ti3>=N/2) {
1008 ti3 = N/2 - 1;
1009 }
1010 for (ti=-ti3/2; ti<(ti3/2); ti++) {
1011 tf = psAutotalent->hannwindow[(long int)N/2 + ti*(long int)N/ti3];
1012 // 3rd degree polynomial interpolator - based on eqns from Hal Chamberlin's book
1013 indd = psAutotalent->phincfact*ti;
1014 ind1 = (int)indd;
1015 ind2 = ind1+1;
1016 ind3 = ind1+2;
1017 ind0 = ind1-1;
1018 val0 = psAutotalent->frag[(ind0+N)%N];
1019 val1 = psAutotalent->frag[(ind1+N)%N];
1020 val2 = psAutotalent->frag[(ind2+N)%N];
1021 val3 = psAutotalent->frag[(ind3+N)%N];
1022 vald = 0;
1023 vald = vald - (float)0.166666666667 * val0 * (indd - ind1) * (indd - ind2) * (indd - ind3);
1024 vald = vald + (float)0.5 * val1 * (indd - ind0) * (indd - ind2) * (indd - ind3);
1025 vald = vald - (float)0.5 * val2 * (indd - ind0) * (indd - ind1) * (indd - ind3);
1026 vald = vald + (float)0.166666666667 * val3 * (indd - ind0) * (indd - ind1) * (indd - ind2);
1027 psAutotalent->cbo[(ti + ti2 + N)%N] = psAutotalent->cbo[(ti + ti2 + N)%N] + vald*tf;
1028 }
1029 psAutotalent->fragsize = 0;
1030 }
1031 psAutotalent->fragsize++;
1032
1033 // Get output signal from buffer
1034 tf = psAutotalent->cbo[psAutotalent->cbord]; // read buffer
1035
1036 psAutotalent->cbo[psAutotalent->cbord] = 0; // erase for next cycle
1037 psAutotalent->cbord++; // increment read pointer
1038 if (psAutotalent->cbord >= N) {
1039 psAutotalent->cbord = 0;
1040 }
1041
1042 // *********************
1043 // * END Pitch Shifter *
1044 // *********************
1045
1046 ti4 = (psAutotalent->cbiwr + 2)%N;
1047 if (iFcorr>=1) {
1048 // The second part of the formant corrector
1049 // This is a post-filter that re-applies the formants, designed
1050 // to result in the exact original signal when no pitch
1051 // manipulation is performed.
1052 // tf is signal input
1053 // gotta run it 3 times because of a pesky delay free loop
1054 // first time: compute 0-response
1055 tf2 = tf;
1056 fa = 0;
1057 fb = fa;
1058 for (ti=0; ti<ford; ti++) {
1059 fc = (fb-psAutotalent->frc[ti])*frlamb + psAutotalent->frb[ti];
1060 tf = psAutotalent->fbuff[ti][ti4];
1061 fb = fc - tf*fa;
1062 psAutotalent->ftvec[ti] = tf*fc;
1063 fa = fa - psAutotalent->ftvec[ti];
1064 }
1065 tf = -fa;
1066 for (ti=ford-1; ti>=0; ti--) {
1067 tf = tf + psAutotalent->ftvec[ti];
1068 }
1069 f0resp = tf;
1070 // second time: compute 1-response
1071 fa = 1;
1072 fb = fa;
1073 for (ti=0; ti<ford; ti++) {
1074 fc = (fb-psAutotalent->frc[ti])*frlamb + psAutotalent->frb[ti];
1075 tf = psAutotalent->fbuff[ti][ti4];
1076 fb = fc - tf*fa;
1077 psAutotalent->ftvec[ti] = tf*fc;
1078 fa = fa - psAutotalent->ftvec[ti];
1079 }
1080 tf = -fa;
1081 for (ti=ford-1; ti>=0; ti--) {
1082 tf = tf + psAutotalent->ftvec[ti];
1083 }
1084 f1resp = tf;
1085 // now solve equations for output, based on 0-response and 1-response
1086 tf = (float)2*tf2;
1087 tf2 = tf;
1088 tf = ((float)1 - f1resp + f0resp);
1089 if (tf!=0) {
1090 tf2 = (tf2 + f0resp) / tf;
1091 }
1092 else {
1093 tf2 = 0;
1094 }
1095 // third time: update delay registers
1096 fa = tf2;
1097 fb = fa;
1098 for (ti=0; ti<ford; ti++) {
1099 fc = (fb-psAutotalent->frc[ti])*frlamb + psAutotalent->frb[ti];
1100 psAutotalent->frc[ti] = fc;
1101 psAutotalent->frb[ti] = fb;
1102 tf = psAutotalent->fbuff[ti][ti4];
1103 fb = fc - tf*fa;
1104 fa = fa - tf*fc;
1105 }
1106 tf = tf2;
1107 tf = tf + flpa*psAutotalent->flp; // lowpass post-emphasis filter
1108 psAutotalent->flp = tf;
1109 // Bring up the gain slowly when formant correction goes from disabled
1110 // to enabled, while things stabilize.
1111 if (psAutotalent->fmute>0.5) {
1112 tf = tf*(psAutotalent->fmute - 0.5)*2;
1113 }
1114 else {
1115 tf = 0;
1116 }
1117 tf2 = psAutotalent->fmutealph;
1118 psAutotalent->fmute = (1-tf2) + tf2*psAutotalent->fmute;
1119 // now tf is signal output
1120 // ...and we're done messing with formants
1121 }
1122 else {
1123 psAutotalent->fmute = 0;
1124 }
1125
1126 // Write audio to output of plugin
1127 // Mix (blend between original (delayed) =0 and processed =1)
1128 *(pfOutput++) = (LADSPA_Data) fMix*tf + (1-fMix)*psAutotalent->cbi[ti4];
1129
1130 }
1131
1132 // Tell the host the algorithm latency
1133 *(psAutotalent->m_pfLatency) = (LADSPA_Data) (N-1);
1134 }
1135
1136
1137
1138 /********************
1139 * THE DESTRUCTOR! *
1140 ********************/
1141 void
cleanupAutotalent(LADSPA_Handle Instance)1142 cleanupAutotalent(LADSPA_Handle Instance) {
1143 int ti;
1144 fft_des(((Autotalent*)Instance)->fmembvars);
1145 free(((Autotalent*)Instance)->cbi);
1146 free(((Autotalent*)Instance)->cbf);
1147 free(((Autotalent*)Instance)->cbo);
1148 free(((Autotalent*)Instance)->cbwindow);
1149 free(((Autotalent*)Instance)->hannwindow);
1150 free(((Autotalent*)Instance)->acwinv);
1151 free(((Autotalent*)Instance)->frag);
1152 free(((Autotalent*)Instance)->ffttime);
1153 free(((Autotalent*)Instance)->fftfreqre);
1154 free(((Autotalent*)Instance)->fftfreqim);
1155 free(((Autotalent*)Instance)->fk);
1156 free(((Autotalent*)Instance)->fb);
1157 free(((Autotalent*)Instance)->fc);
1158 free(((Autotalent*)Instance)->frb);
1159 free(((Autotalent*)Instance)->frc);
1160 free(((Autotalent*)Instance)->fsmooth);
1161 free(((Autotalent*)Instance)->fsig);
1162 for (ti=0; ti<((Autotalent*)Instance)->ford; ti++) {
1163 free(((Autotalent*)Instance)->fbuff[ti]);
1164 }
1165 free(((Autotalent*)Instance)->fbuff);
1166 free(((Autotalent*)Instance)->ftvec);
1167 free((Autotalent*)Instance);
1168 }
1169
1170
1171 LADSPA_Descriptor * g_psDescriptor;
1172
1173 // Called when first loaded
1174 void
_init()1175 _init() {
1176
1177 char ** pcPortNames;
1178 LADSPA_PortDescriptor * piPortDescriptors;
1179 LADSPA_PortRangeHint * psPortRangeHints;
1180
1181 g_psDescriptor
1182 = (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
1183
1184 if (g_psDescriptor) {
1185
1186 g_psDescriptor->UniqueID
1187 = 4262;
1188 g_psDescriptor->Label
1189 = strdup("autotalent");
1190 g_psDescriptor->Properties
1191 = LADSPA_PROPERTY_HARD_RT_CAPABLE;
1192 g_psDescriptor->Name
1193 = strdup("Autotalent");
1194 g_psDescriptor->Maker
1195 = strdup("Tom Baran");
1196 g_psDescriptor->Copyright
1197 = strdup("2010");
1198 g_psDescriptor->PortCount
1199 = 32;
1200 piPortDescriptors
1201 = (LADSPA_PortDescriptor *)calloc(32, sizeof(LADSPA_PortDescriptor));
1202 g_psDescriptor->PortDescriptors
1203 = (const LADSPA_PortDescriptor *)piPortDescriptors;
1204 piPortDescriptors[AT_TUNE]
1205 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1206 piPortDescriptors[AT_FIXED]
1207 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1208 piPortDescriptors[AT_PULL]
1209 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1210 piPortDescriptors[AT_A]
1211 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1212 piPortDescriptors[AT_Bb]
1213 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1214 piPortDescriptors[AT_B]
1215 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1216 piPortDescriptors[AT_C]
1217 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1218 piPortDescriptors[AT_Db]
1219 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1220 piPortDescriptors[AT_D]
1221 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1222 piPortDescriptors[AT_Eb]
1223 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1224 piPortDescriptors[AT_E]
1225 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1226 piPortDescriptors[AT_F]
1227 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1228 piPortDescriptors[AT_Gb]
1229 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1230 piPortDescriptors[AT_G]
1231 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1232 piPortDescriptors[AT_Ab]
1233 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1234 piPortDescriptors[AT_AMOUNT]
1235 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1236 piPortDescriptors[AT_SMOOTH]
1237 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1238 piPortDescriptors[AT_SHIFT]
1239 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1240 piPortDescriptors[AT_SCWARP]
1241 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1242 piPortDescriptors[AT_LFOAMP]
1243 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1244 piPortDescriptors[AT_LFORATE]
1245 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1246 piPortDescriptors[AT_LFOSHAPE]
1247 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1248 piPortDescriptors[AT_LFOSYMM]
1249 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1250 piPortDescriptors[AT_LFOQUANT]
1251 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1252 piPortDescriptors[AT_FCORR]
1253 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1254 piPortDescriptors[AT_FWARP]
1255 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1256 piPortDescriptors[AT_MIX]
1257 = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
1258 piPortDescriptors[AT_PITCH]
1259 = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
1260 piPortDescriptors[AT_CONF]
1261 = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
1262 piPortDescriptors[AT_INPUT1]
1263 = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
1264 piPortDescriptors[AT_OUTPUT1]
1265 = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
1266 piPortDescriptors[AT_LATENCY]
1267 = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
1268 pcPortNames
1269 = (char **)calloc(32, sizeof(char *));
1270 g_psDescriptor->PortNames
1271 = (const char **)pcPortNames;
1272 pcPortNames[AT_TUNE]
1273 = strdup("Concert A (Hz)");
1274 pcPortNames[AT_FIXED]
1275 = strdup("Fixed pitch (semitones w.r.t. A)");
1276 pcPortNames[AT_PULL]
1277 = strdup("Pull to fixed pitch");
1278 pcPortNames[AT_A]
1279 = strdup("A");
1280 pcPortNames[AT_Bb]
1281 = strdup("Bb");
1282 pcPortNames[AT_B]
1283 = strdup("B");
1284 pcPortNames[AT_C]
1285 = strdup("C");
1286 pcPortNames[AT_Db]
1287 = strdup("Db");
1288 pcPortNames[AT_D]
1289 = strdup("D");
1290 pcPortNames[AT_Eb]
1291 = strdup("Eb");
1292 pcPortNames[AT_E]
1293 = strdup("E");
1294 pcPortNames[AT_F]
1295 = strdup("F");
1296 pcPortNames[AT_Gb]
1297 = strdup("Gb");
1298 pcPortNames[AT_G]
1299 = strdup("G");
1300 pcPortNames[AT_Ab]
1301 = strdup("Ab");
1302 pcPortNames[AT_AMOUNT]
1303 = strdup("Correction strength");
1304 pcPortNames[AT_SMOOTH]
1305 = strdup("Correction smoothness");
1306 pcPortNames[AT_SHIFT]
1307 = strdup("Pitch shift (scale notes)");
1308 pcPortNames[AT_SCWARP]
1309 = strdup("Output scale rotate (scale notes)");
1310 pcPortNames[AT_LFOAMP]
1311 = strdup("LFO depth");
1312 pcPortNames[AT_LFORATE]
1313 = strdup("LFO rate (Hz)");
1314 pcPortNames[AT_LFOSHAPE]
1315 = strdup("LFO shape (square->sine->tri)");
1316 pcPortNames[AT_LFOSYMM]
1317 = strdup("LFO symmetry");
1318 pcPortNames[AT_LFOQUANT]
1319 = strdup("LFO quantization");
1320 pcPortNames[AT_FCORR]
1321 = strdup("Formant correction");
1322 pcPortNames[AT_FWARP]
1323 = strdup("Formant warp");
1324 pcPortNames[AT_MIX]
1325 = strdup("Mix");
1326 pcPortNames[AT_PITCH]
1327 = strdup("Detected pitch (semitones w.r.t. A)");
1328 pcPortNames[AT_CONF]
1329 = strdup("Pitch detection confidence");
1330 pcPortNames[AT_INPUT1]
1331 = strdup("Input");
1332 pcPortNames[AT_OUTPUT1]
1333 = strdup("Output");
1334 pcPortNames[AT_LATENCY]
1335 = strdup("latency");
1336 psPortRangeHints = ((LADSPA_PortRangeHint *)
1337 calloc(32, sizeof(LADSPA_PortRangeHint)));
1338 g_psDescriptor->PortRangeHints
1339 = (const LADSPA_PortRangeHint *)psPortRangeHints;
1340 psPortRangeHints[AT_TUNE].HintDescriptor
1341 = (LADSPA_HINT_BOUNDED_BELOW |
1342 LADSPA_HINT_BOUNDED_ABOVE |
1343 LADSPA_HINT_DEFAULT_440);
1344 psPortRangeHints[AT_TUNE].LowerBound
1345 = 400;
1346 psPortRangeHints[AT_TUNE].UpperBound
1347 = 480;
1348 psPortRangeHints[AT_FIXED].HintDescriptor
1349 = (LADSPA_HINT_BOUNDED_BELOW |
1350 LADSPA_HINT_BOUNDED_ABOVE |
1351 LADSPA_HINT_DEFAULT_0);
1352 psPortRangeHints[AT_FIXED].LowerBound
1353 = -36;
1354 psPortRangeHints[AT_FIXED].UpperBound
1355 = 12;
1356 psPortRangeHints[AT_PULL].HintDescriptor
1357 = (LADSPA_HINT_BOUNDED_BELOW |
1358 LADSPA_HINT_BOUNDED_ABOVE |
1359 LADSPA_HINT_DEFAULT_0);
1360 psPortRangeHints[AT_PULL].LowerBound
1361 = 0;
1362 psPortRangeHints[AT_PULL].UpperBound
1363 = 1;
1364 psPortRangeHints[AT_A].HintDescriptor
1365 = (LADSPA_HINT_BOUNDED_BELOW |
1366 LADSPA_HINT_BOUNDED_ABOVE |
1367 LADSPA_HINT_INTEGER |
1368 LADSPA_HINT_DEFAULT_0);
1369 psPortRangeHints[AT_A].LowerBound
1370 = -1.1;
1371 psPortRangeHints[AT_A].UpperBound
1372 = 1.1;
1373 psPortRangeHints[AT_Bb].HintDescriptor
1374 = (LADSPA_HINT_BOUNDED_BELOW |
1375 LADSPA_HINT_BOUNDED_ABOVE |
1376 LADSPA_HINT_INTEGER |
1377 LADSPA_HINT_DEFAULT_MINIMUM);
1378 psPortRangeHints[AT_Bb].LowerBound
1379 = -1.1;
1380 psPortRangeHints[AT_Bb].UpperBound
1381 = 1.1;
1382 psPortRangeHints[AT_B].HintDescriptor
1383 = (LADSPA_HINT_BOUNDED_BELOW |
1384 LADSPA_HINT_BOUNDED_ABOVE |
1385 LADSPA_HINT_INTEGER |
1386 LADSPA_HINT_DEFAULT_0);
1387 psPortRangeHints[AT_B].LowerBound
1388 = -1.1;
1389 psPortRangeHints[AT_B].UpperBound
1390 = 1.1;
1391 psPortRangeHints[AT_C].HintDescriptor
1392 = (LADSPA_HINT_BOUNDED_BELOW |
1393 LADSPA_HINT_BOUNDED_ABOVE |
1394 LADSPA_HINT_INTEGER |
1395 LADSPA_HINT_DEFAULT_0);
1396 psPortRangeHints[AT_C].LowerBound
1397 = -1.1;
1398 psPortRangeHints[AT_C].UpperBound
1399 = 1.1;
1400 psPortRangeHints[AT_Db].HintDescriptor
1401 = (LADSPA_HINT_BOUNDED_BELOW |
1402 LADSPA_HINT_BOUNDED_ABOVE |
1403 LADSPA_HINT_INTEGER |
1404 LADSPA_HINT_DEFAULT_MINIMUM);
1405 psPortRangeHints[AT_Db].LowerBound
1406 = -1.1;
1407 psPortRangeHints[AT_Db].UpperBound
1408 = 1.1;
1409 psPortRangeHints[AT_D].HintDescriptor
1410 = (LADSPA_HINT_BOUNDED_BELOW |
1411 LADSPA_HINT_BOUNDED_ABOVE |
1412 LADSPA_HINT_INTEGER |
1413 LADSPA_HINT_DEFAULT_0);
1414 psPortRangeHints[AT_D].LowerBound
1415 = -1.1;
1416 psPortRangeHints[AT_D].UpperBound
1417 = 1.1;
1418 psPortRangeHints[AT_Eb].HintDescriptor
1419 = (LADSPA_HINT_BOUNDED_BELOW |
1420 LADSPA_HINT_BOUNDED_ABOVE |
1421 LADSPA_HINT_INTEGER |
1422 LADSPA_HINT_DEFAULT_MINIMUM);
1423 psPortRangeHints[AT_Eb].LowerBound
1424 = -1.1;
1425 psPortRangeHints[AT_Eb].UpperBound
1426 = 1.1;
1427 psPortRangeHints[AT_E].HintDescriptor
1428 = (LADSPA_HINT_BOUNDED_BELOW |
1429 LADSPA_HINT_BOUNDED_ABOVE |
1430 LADSPA_HINT_INTEGER |
1431 LADSPA_HINT_DEFAULT_0);
1432 psPortRangeHints[AT_E].LowerBound
1433 = -1.1;
1434 psPortRangeHints[AT_E].UpperBound
1435 = 1.1;
1436 psPortRangeHints[AT_F].HintDescriptor
1437 = (LADSPA_HINT_BOUNDED_BELOW |
1438 LADSPA_HINT_BOUNDED_ABOVE |
1439 LADSPA_HINT_INTEGER |
1440 LADSPA_HINT_DEFAULT_0);
1441 psPortRangeHints[AT_F].LowerBound
1442 = -1.1;
1443 psPortRangeHints[AT_F].UpperBound
1444 = 1.1;
1445 psPortRangeHints[AT_Gb].HintDescriptor
1446 = (LADSPA_HINT_BOUNDED_BELOW |
1447 LADSPA_HINT_BOUNDED_ABOVE |
1448 LADSPA_HINT_INTEGER |
1449 LADSPA_HINT_DEFAULT_MINIMUM);
1450 psPortRangeHints[AT_Gb].LowerBound
1451 = -1.1;
1452 psPortRangeHints[AT_Gb].UpperBound
1453 = 1.1;
1454 psPortRangeHints[AT_G].HintDescriptor
1455 = (LADSPA_HINT_BOUNDED_BELOW |
1456 LADSPA_HINT_BOUNDED_ABOVE |
1457 LADSPA_HINT_INTEGER |
1458 LADSPA_HINT_DEFAULT_0);
1459 psPortRangeHints[AT_G].LowerBound
1460 = -1.1;
1461 psPortRangeHints[AT_G].UpperBound
1462 = 1.1;
1463 psPortRangeHints[AT_Ab].HintDescriptor
1464 = (LADSPA_HINT_BOUNDED_BELOW |
1465 LADSPA_HINT_BOUNDED_ABOVE |
1466 LADSPA_HINT_INTEGER |
1467 LADSPA_HINT_DEFAULT_MINIMUM);
1468 psPortRangeHints[AT_Ab].LowerBound
1469 = -1.1;
1470 psPortRangeHints[AT_Ab].UpperBound
1471 = 1.1;
1472 psPortRangeHints[AT_AMOUNT].HintDescriptor
1473 = (LADSPA_HINT_BOUNDED_BELOW |
1474 LADSPA_HINT_BOUNDED_ABOVE |
1475 LADSPA_HINT_DEFAULT_1);
1476 psPortRangeHints[AT_AMOUNT].LowerBound
1477 = 0;
1478 psPortRangeHints[AT_AMOUNT].UpperBound
1479 = 1;
1480 psPortRangeHints[AT_SMOOTH].HintDescriptor
1481 = (LADSPA_HINT_BOUNDED_BELOW |
1482 LADSPA_HINT_BOUNDED_ABOVE |
1483 LADSPA_HINT_DEFAULT_0);
1484 psPortRangeHints[AT_SMOOTH].LowerBound
1485 = 0;
1486 psPortRangeHints[AT_SMOOTH].UpperBound
1487 = 1;
1488 psPortRangeHints[AT_SHIFT].HintDescriptor
1489 = (LADSPA_HINT_BOUNDED_BELOW |
1490 LADSPA_HINT_BOUNDED_ABOVE |
1491 LADSPA_HINT_DEFAULT_0);
1492 psPortRangeHints[AT_SHIFT].LowerBound
1493 = -12;
1494 psPortRangeHints[AT_SHIFT].UpperBound
1495 = 12;
1496 psPortRangeHints[AT_SCWARP].HintDescriptor
1497 = (LADSPA_HINT_BOUNDED_BELOW |
1498 LADSPA_HINT_BOUNDED_ABOVE |
1499 LADSPA_HINT_INTEGER |
1500 LADSPA_HINT_DEFAULT_0);
1501 psPortRangeHints[AT_SCWARP].LowerBound
1502 = -5.1;
1503 psPortRangeHints[AT_SCWARP].UpperBound
1504 = 5.1;
1505 psPortRangeHints[AT_LFOAMP].HintDescriptor
1506 = (LADSPA_HINT_BOUNDED_BELOW |
1507 LADSPA_HINT_BOUNDED_ABOVE |
1508 LADSPA_HINT_DEFAULT_0);
1509 psPortRangeHints[AT_LFOAMP].LowerBound
1510 = 0;
1511 psPortRangeHints[AT_LFOAMP].UpperBound
1512 = 1;
1513 psPortRangeHints[AT_LFORATE].HintDescriptor
1514 = (LADSPA_HINT_BOUNDED_BELOW |
1515 LADSPA_HINT_BOUNDED_ABOVE |
1516 LADSPA_HINT_DEFAULT_MIDDLE);
1517 psPortRangeHints[AT_LFORATE].LowerBound
1518 = 0;
1519 psPortRangeHints[AT_LFORATE].UpperBound
1520 = 10;
1521 psPortRangeHints[AT_LFOSHAPE].HintDescriptor
1522 = (LADSPA_HINT_BOUNDED_BELOW |
1523 LADSPA_HINT_BOUNDED_ABOVE |
1524 LADSPA_HINT_DEFAULT_0);
1525 psPortRangeHints[AT_LFOSHAPE].LowerBound
1526 = -1;
1527 psPortRangeHints[AT_LFOSHAPE].UpperBound
1528 = 1;
1529 psPortRangeHints[AT_LFOSYMM].HintDescriptor
1530 = (LADSPA_HINT_BOUNDED_BELOW |
1531 LADSPA_HINT_BOUNDED_ABOVE |
1532 LADSPA_HINT_DEFAULT_0);
1533 psPortRangeHints[AT_LFOSYMM].LowerBound
1534 = -1;
1535 psPortRangeHints[AT_LFOSYMM].UpperBound
1536 = 1;
1537 psPortRangeHints[AT_LFOQUANT].HintDescriptor
1538 = (LADSPA_HINT_TOGGLED |
1539 LADSPA_HINT_DEFAULT_0);
1540 psPortRangeHints[AT_FCORR].HintDescriptor
1541 = (LADSPA_HINT_TOGGLED |
1542 LADSPA_HINT_DEFAULT_0);
1543 psPortRangeHints[AT_FWARP].HintDescriptor
1544 = (LADSPA_HINT_BOUNDED_BELOW |
1545 LADSPA_HINT_BOUNDED_ABOVE |
1546 LADSPA_HINT_DEFAULT_0);
1547 psPortRangeHints[AT_FWARP].LowerBound
1548 = -1;
1549 psPortRangeHints[AT_FWARP].UpperBound
1550 = 1;
1551 psPortRangeHints[AT_MIX].HintDescriptor
1552 = (LADSPA_HINT_BOUNDED_BELOW |
1553 LADSPA_HINT_BOUNDED_ABOVE |
1554 LADSPA_HINT_DEFAULT_1);
1555 psPortRangeHints[AT_MIX].LowerBound
1556 = 0;
1557 psPortRangeHints[AT_MIX].UpperBound
1558 = 1;
1559 psPortRangeHints[AT_PITCH].HintDescriptor
1560 = 0;
1561 psPortRangeHints[AT_CONF].HintDescriptor
1562 = 0;
1563 psPortRangeHints[AT_INPUT1].HintDescriptor
1564 = 0;
1565 psPortRangeHints[AT_OUTPUT1].HintDescriptor
1566 = 0;
1567 psPortRangeHints[AT_LATENCY].HintDescriptor
1568 = 0;
1569
1570 g_psDescriptor->instantiate
1571 = instantiateAutotalent;
1572 g_psDescriptor->connect_port
1573 = connectPortToAutotalent;
1574 g_psDescriptor->activate
1575 = NULL;
1576 g_psDescriptor->run
1577 = runAutotalent;
1578 g_psDescriptor->run_adding
1579 = NULL;
1580 g_psDescriptor->set_run_adding_gain
1581 = NULL;
1582 g_psDescriptor->deactivate
1583 = NULL;
1584 g_psDescriptor->cleanup
1585 = cleanupAutotalent;
1586 }
1587
1588 }
1589
1590
1591
1592 void
deleteDescriptor(LADSPA_Descriptor * psDescriptor)1593 deleteDescriptor(LADSPA_Descriptor * psDescriptor) {
1594 unsigned long lIndex;
1595 if (psDescriptor) {
1596 free((char *)psDescriptor->Label);
1597 free((char *)psDescriptor->Name);
1598 free((char *)psDescriptor->Maker);
1599 free((char *)psDescriptor->Copyright);
1600 free((LADSPA_PortDescriptor *)psDescriptor->PortDescriptors);
1601 for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
1602 free((char *)(psDescriptor->PortNames[lIndex]));
1603 free((char **)psDescriptor->PortNames);
1604 free((LADSPA_PortRangeHint *)psDescriptor->PortRangeHints);
1605 free(psDescriptor);
1606 }
1607 }
1608
1609
1610 // Called when library is unloaded
1611 void
_fini()1612 _fini() {
1613 deleteDescriptor(g_psDescriptor);
1614 }
1615
1616
1617 // Return the plugin descriptor (there's only one in this file)
1618 const LADSPA_Descriptor *
ladspa_descriptor(unsigned long Index)1619 ladspa_descriptor(unsigned long Index) {
1620 switch (Index) {
1621 case 0:
1622 return g_psDescriptor;
1623 default:
1624 return NULL;
1625 }
1626 }
1627
1628
1629 // All done
1630