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