creation
[cantarino-library:cantarino-library.git] / cantarino.pde
1 /*
2 from
3 http://code.google.com/p/tinkerit/wiki/Cantarino
4 license
5 http://creativecommons.org/licenses/by-sa/3.0/
6 */
7
8
9
10 #include <avr/io.h>
11 #include <avr/interrupt.h>
12 #include <avr/pgmspace.h>
13
14
15
16
17
18 uint16_t pitchPhase, form1Phase,form2Phase,form3Phase;
19 uint16_t pitchPhaseInc,form1PhaseInc,form2PhaseInc,form3PhaseInc;
20 uint8_t form1Amp,form2Amp,form3Amp;
21 uint8_t noiseMod=10;
22
23 int8_t sinCalc[256] PROGMEM = {
24   /* This table rolls a lot of functions together for speed.
25      Extracting phase and amplitude from the nybble packed form
26      Sine calculation
27      Exponential amplitude mapping
28      Scaling to appropriate range
29      
30      ROUND(
31        FLOOR(a/16,1)
32        *SIN(
33          2
34          * PI()
35          * IF(
36            MOD(a,16),
37            EXP(0.18*MOD(a,16)),
38            0
39          ) /16
40        )*127
41      ,0)
42   */
43   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
44   0,2,2,3,3,4,5,6,7,8,10,12,14,17,20,24,
45   0,4,4,5,6,7,9,11,13,15,18,22,26,31,37,45,
46   0,5,6,7,8,10,12,14,17,20,24,28,34,41,49,58,
47   0,5,6,7,9,10,12,15,18,21,26,31,37,44,53,63,
48   0,5,6,7,8,10,12,14,17,20,24,28,34,41,49,58,
49   0,4,4,5,6,7,9,11,13,15,18,22,26,31,37,45,
50   0,2,2,3,3,4,5,6,7,8,10,12,14,17,20,24,
51   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
52   0,-2,-2,-3,-3,-4,-5,-6,-7,-8,-10,-12,-14,-17,-20,-24,
53   0,-4,-4,-5,-6,-7,-9,-11,-13,-15,-18,-22,-26,-31,-37,-45,
54   0,-5,-6,-7,-8,-10,-12,-14,-17,-20,-24,-28,-34,-41,-49,-58,
55   0,-5,-6,-7,-9,-10,-12,-15,-18,-21,-26,-31,-37,-44,-53,-63,
56   0,-5,-6,-7,-8,-10,-12,-14,-17,-20,-24,-28,-34,-41,-49,-58,
57   0,-4,-4,-5,-6,-7,-9,-11,-13,-15,-18,-22,-26,-31,-37,-45,
58   0,-2,-2,-3,-3,-4,-5,-6,-7,-8,-10,-12,-14,-17,-20,-24
59 };
60
61 int8_t sqrCalc[256] PROGMEM ={
62   0,1,2,2,2,3,3,4,5,5,6,8,9,11,13,16,
63   0,1,2,2,2,3,3,4,5,5,6,8,9,11,13,16,
64   0,1,2,2,2,3,3,4,5,5,6,8,9,11,13,16,
65   0,1,2,2,2,3,3,4,5,5,6,8,9,11,13,16,
66   0,1,2,2,2,3,3,4,5,5,6,8,9,11,13,16,
67   0,1,2,2,2,3,3,4,5,5,6,8,9,11,13,16,
68   0,1,2,2,2,3,3,4,5,5,6,8,9,11,13,16,
69   0,1,2,2,2,3,3,4,5,5,6,8,9,11,13,16,
70   0,-1,-2,-2,-2,-3,-3,-4,-5,-5,-6,-8,-9,-11,-13,-16,
71   0,-1,-2,-2,-2,-3,-3,-4,-5,-5,-6,-8,-9,-11,-13,-16,
72   0,-1,-2,-2,-2,-3,-3,-4,-5,-5,-6,-8,-9,-11,-13,-16,
73   0,-1,-2,-2,-2,-3,-3,-4,-5,-5,-6,-8,-9,-11,-13,-16,
74   0,-1,-2,-2,-2,-3,-3,-4,-5,-5,-6,-8,-9,-11,-13,-16,
75   0,-1,-2,-2,-2,-3,-3,-4,-5,-5,-6,-8,-9,-11,-13,-16,
76   0,-1,-2,-2,-2,-3,-3,-4,-5,-5,-6,-8,-9,-11,-13,-16,
77   0,-1,-2,-2,-2,-3,-3,-4,-5,-5,-6,-8,-9,-11,-13,-16
78 };
79
80
81
82 void audioOn() {
83 #if defined(__AVR_ATmega8__)
84   // ATmega8 has different registers
85   TCCR2 = _BV(WGM20) | _BV(COM21) | _BV(CS20);
86   TIMSK = _BV(TOIE2);
87 #elif defined(__AVR_ATmega1280__)
88   TCCR3A = _BV(COM3C1) | _BV(WGM30);
89   TCCR3B = _BV(CS30);
90   TIMSK3 = _BV(TOIE3);
91 #else
92   // Set up PWM to 31.25kHz, phase accurate
93   TCCR2A = _BV(COM2B1) | _BV(WGM20);
94   TCCR2B = _BV(CS20);
95   TIMSK2 = _BV(TOIE2);
96 #endif
97 }
98
99
100
101
102 #define FORMANT_SZ 7
103
104 enum {
105   _SP,_DOT,_QM,_COM,_HYP,_IY,_IH,_EH,_AE,_AA,
106   _AH,_AO,_UH,_AX,_IX,_ER,_UX,_OH,_RX,_LX,
107   _WX,_YX,_WH,_R,_L,_W,_Y,_M,_N,_NX,
108   _DX,_Q,_S,_SH,_F,_TH,__H,__X,_Z,_ZH,
109   _V,_DH,_CHa,_CHb,_Ja,_Jb,_Jc,_Jd,_EY,_AY,
110   _OY,_AW,_OW,_UW,_Ba,_Bb,_Bc,_Da,_Db,_Dc,
111   _Ga,_Gb,_Gc,_GXa,_GXb,_GXc,_Pa,_Pb,_Pc,_Ta,
112   _Tb,_Tc,_Ka,_Kb,_Kc,_KXa,_KXb,_KXc
113 };
114
115 uint8_t formantTable[] PROGMEM = {
116    0x0, 0x0, 0x0,0x0,0x0,0x0,0x0,/*00 space*/ 0x13,0x43,0x5b,0x0,0x0,0x0,0x0,/*01 .*/
117   0x13,0x43,0x5b,0x0,0x0,0x0,0x0,/*02 ?*/     0x13,0x43,0x5b,0x0,0x0,0x0,0x0,/*03 ,*/
118   0x13,0x43,0x5b,0x0,0x0,0x0,0x0,/*04 -*/      0xa,0x54,0x6e,0xd,0xa,0x8,0x0,/*05 IY*/
119    0xe,0x49,0x5d,0xd,0x8,0x7,0x0,/*06 IH*/    0x13,0x43,0x5b,0xe,0xd,0x8,0x0,/*07 EH*/
120   0x18,0x3f,0x58,0xf,0xe,0x8,0x0,/*08 AE*/    0x1b,0x28,0x59,0xf,0xd,0x1,0x0,/*09 AA*/
121   0x17,0x2c,0x57,0xf,0xc,0x1,0x0,/*10 AH*/    0x15,0x1f,0x58,0xf,0xc,0x0,0x0,/*11 AO*/
122   0x10,0x25,0x52,0xf,0xb,0x1,0x0,/*12 UH*/    0x14,0x2c,0x57,0xe,0xb,0x0,0x0,/*13 AX*/
123    0xe,0x49,0x5d,0xd,0xb,0x7,0x0,/*14 IX*/    0x12,0x31,0x3e,0xc,0xb,0x5,0x0,/*15 ER*/
124    0xe,0x24,0x52,0xf,0xc,0x1,0x0,/*16 UX*/    0x12,0x1e,0x58,0xf,0xc,0x0,0x0,/*17 OH*/
125   0x12,0x33,0x3e,0xd,0xc,0x6,0x0,/*18 RX*/    0x10,0x25,0x6e,0xd,0x8,0x1,0x0,/*19 LX*/
126    0xd,0x1d,0x50,0xd,0x8,0x0,0x0,/*20 WX*/     0xf,0x45,0x5d,0xe,0xc,0x7,0x0,/*21 YX*/
127    0xb,0x18,0x5a,0xd,0x8,0x0,0x0,/*22 WH*/    0x12,0x32,0x3c,0xc,0xa,0x5,0x0,/*23 R*/
128    0xe,0x1e,0x6e,0xd,0x8,0x1,0x0,/*24 L*/      0xb,0x18,0x5a,0xd,0x8,0x0,0x0,/*25 W*/
129    0x9,0x53,0x6e,0xd,0xa,0x8,0x0,/*26 Y*/      0x6,0x2e,0x51,0xc,0x3,0x0,0x0,/*27 M*/
130    0x6,0x36,0x79,0x9,0x9,0x0,0x0,/*28 N*/      0x6,0x56,0x65,0x9,0x6,0x3,0x0,/*29 NX*/
131    0x6,0x36,0x79,0x0,0x0,0x0,0x0,/*30 DX*/    0x11,0x43,0x5b,0x0,0x0,0x0,0x0,/*31 Q*/
132    0x6,0x49,0x63,0x7,0xa,0xd,0xf,/*32 S*/      0x6,0x4f,0x6a,0x0,0x0,0x0,0x0,/*33 SH*/
133    0x6,0x1a,0x51,0x3,0x3,0x3,0xf,/*34 F*/      0x6,0x42,0x79,0x0,0x0,0x0,0x0,/*35 TH*/
134    0xe,0x49,0x5d,0x0,0x0,0x0,0x0,/*36 /H*/    0x10,0x25,0x52,0x0,0x0,0x0,0x0,/*37 /X*/
135    0x9,0x33,0x5d,0xf,0x3,0x0,0x3,/*38 Z*/      0xa,0x42,0x67,0xb,0x5,0x1,0x0,/*39 ZH*/
136    0x8,0x28,0x4c,0xb,0x3,0x0,0x0,/*40 V*/      0xa,0x2f,0x5d,0xb,0x4,0x0,0x0,/*41 DH*/
137    0x6,0x4f,0x65,0x0,0x0,0x0,0x0,/*42 CHa*/    0x6,0x4f,0x65,0x0,0x0,0x0,0x0,/*43 CHb*/
138    0x6,0x42,0x79,0x1,0x0,0x0,0x0,/*44 Ja*/     0x5,0x42,0x79,0x1,0x0,0x0,0x0,/*45 Jb*/
139    0x6,0x6e,0x79,0x0,0xa,0xe,0x0,/*46 Jc*/     0x0, 0x0, 0x0,0x2,0x2,0x1,0x0,/*47 Jd*/
140   0x13,0x48,0x5a,0xe,0xe,0x9,0x0,/*48 EY*/    0x1b,0x27,0x58,0xf,0xd,0x1,0x0,/*49 AY*/
141   0x15,0x1f,0x58,0xf,0xc,0x0,0x0,/*50 OY*/    0x1b,0x2b,0x58,0xf,0xd,0x1,0x0,/*51 AW*/
142   0x12,0x1e,0x58,0xf,0xc,0x0,0x0,/*52 OW*/     0xd,0x22,0x52,0xd,0x8,0x0,0x0,/*53 UW*/
143    0x6,0x1a,0x51,0x2,0x0,0x0,0x0,/*54 Ba*/     0x6,0x1a,0x51,0x4,0x1,0x0,0xf,/*55 Bb*/
144    0x6,0x1a,0x51,0x0,0x0,0x0,0x0,/*56 Bc*/     0x6,0x42,0x79,0x2,0x0,0x0,0x0,/*57 Da*/
145    0x6,0x42,0x79,0x4,0x1,0x0,0xf,/*58 Db*/     0x6,0x42,0x79,0x0,0x0,0x0,0x0,/*59 Dc*/
146    0x6,0x6e,0x70,0x1,0x0,0x0,0x0,/*60 Ga*/     0x6,0x6e,0x6e,0x4,0x1,0x0,0xf,/*61 Gb*/
147    0x6,0x6e,0x6e,0x0,0x0,0x0,0x0,/*62 Gc*/     0x6,0x54,0x5e,0x1,0x0,0x0,0x0,/*63 GXa*/
148    0x6,0x54,0x5e,0x4,0x1,0x0,0xf,/*64 GXb*/    0x6,0x54,0x5e,0x0,0x0,0x0,0x0,/*65 GXc*/
149    0x6,0x1a,0x51,0x0,0x0,0x0,0x0,/*66 Pa*/     0x6,0x1a,0x51,0x0,0x0,0x0,0x0,/*67 Pb*/
150    0x6,0x1a,0x51,0x0,0x0,0x0,0x0,/*68 Pc*/     0x6,0x42,0x79,0x0,0x0,0x0,0x0,/*69 Ta*/
151    0x6,0x42,0x79,0x0,0x0,0x0,0x0,/*70 Tb*/     0x6,0x42,0x79,0x0,0x0,0x0,0x0,/*71 Tc*/
152    0x6,0x6d,0x65,0x0,0x0,0x0,0x0,/*72 Ka*/     0xa,0x56,0x65,0xc,0xa,0x7,0x0,/*73 Kb*/
153    0xa,0x6d,0x70,0x0,0x0,0x0,0x0,/*74 Kc*/     0x6,0x54,0x5e,0x0,0x0,0x0,0x0,/*75 KXa*/
154    0x6,0x54,0x5e,0x0,0xa,0x5,0x0,/*76 KXb*/    0x6,0x54,0x5e,0x0,0x0,0x0,0x0 /*77 KXc*/
155 };
156
157 uint16_t pitchTable[64] = {
158   // Covers A1 to C7
159   58,61,65,69,73,77,82,86,92,97,
160   103,109,115,122,129,137,145,154,163,173,
161   183,194,206,218,231,244,259,274,291,308,
162   326,346,366,388,411,435,461,489,518,549,
163   581,616,652,691,732,776,822,871,923,978,
164   1036,1097,1163,1232,1305,1383,1465,1552,1644,1742,
165   1845,1955,2071,2195
166 };
167
168
169 //uint8_t frameList[] PROGMEM = {
170 uint8_t frameList[]  = {
171 #if 1
172   _Da,3,0,39,_Db,1,0,39,_Dc,1,3,39,_EY,8,6,39,_YX,20,3,39, // Dai..
173   _Z,100,0,36,_IY,35,3,36, // ..sy
174   _Da,3,0,32,_Db,1,0,32,_Dc,1,3,32,_EY,8,6,32,_YX,20,3,32, // Dai..
175   _Z,10,0,27,_IY,35,3,27, // ..sy
176   _Ga,2,0,29,_Gb,2,0,29,_Gc,2,0,29,_IH,10,3,29,_V,5,0,29, // Give
177   _M,2,0,31,_IY,10,3,31, // me
178   _YX,5,0,32,_AO,10,0,32,_RX,5,0,32, // your
179   _AH,25,0,29,_NX,5,0,29, // an..
180   _S,2,0,32,_ER,10,0,32,_RX,3,0,32, // ..swer
181   _Da,3,0,27,_Db,1,0,27,_Dc,1,3,27,_UX,80,3,27,_WX,5,0,27, // do
182   _AY,5,20,34,_YX,10,0,34,_M,80,0,34, // I'm
183  
184   #endif
185   _Ta,0,0,61
186 };
187
188 int frameTime = 15; // ms
189 uint16_t basePitch;
190 int formantScale;
191
192 void cantar() {
193   formantScale = 54;//random(20,80);//54;
194   uint8_t *framePos = frameList;
195   while(1) {
196     int n;
197     uint8_t startFormant,staticFrames,tweenFrames;
198     uint16_t startPitch,nextPitch;
199     uint8_t nextFormant;
200     int16_t startForm1PhaseInc,startForm2PhaseInc,startForm3PhaseInc;
201     uint8_t startForm1Amp,startForm2Amp,startForm3Amp;
202     uint8_t startMod;
203     uint8_t *formantPos;
204
205     // Read next framelist item
206     
207     //exemple : _Da,3,0,39
208    // startFormant = (framePos++);//_Da
209    // staticFrames = (framePos++);//3
210     
211     startFormant = byte(*framePos++);//_Da
212     staticFrames = byte(*framePos++);//3
213
214     if (!staticFrames) break; // End of phrase
215
216    // tweenFrames = (framePos++);//0
217     
218     tweenFrames = byte(*framePos++);//0
219
220     startPitch = pitchTable[byte(*framePos++)];//39
221     nextFormant = byte(*framePos);
222     nextPitch = pitchTable[byte(*framePos+3)];
223     pitchPhaseInc = startPitch;
224     formantPos = formantTable + startFormant * FORMANT_SZ;
225     form1PhaseInc = startForm1PhaseInc = pgm_read_byte(formantPos++)*formantScale;
226     form2PhaseInc = startForm2PhaseInc = pgm_read_byte(formantPos++)*formantScale;
227     form3PhaseInc = startForm3PhaseInc = pgm_read_byte(formantPos++)*formantScale;
228     form1Amp = startForm1Amp = pgm_read_byte(formantPos++);
229     form2Amp = startForm2Amp = pgm_read_byte(formantPos++);
230     form3Amp = startForm3Amp = pgm_read_byte(formantPos++);
231     noiseMod = startMod = pgm_read_byte(formantPos++);
232
233     for (;staticFrames--;) delay(frameTime);
234     if (tweenFrames) {
235       uint8_t* formantPos;
236       int16_t deltaForm1PhaseInc,deltaForm2PhaseInc,deltaForm3PhaseInc;
237       int8_t deltaForm1Amp,deltaForm2Amp,deltaForm3Amp;
238       int8_t deltaMod;
239       uint8_t nextMod;
240       int16_t deltaPitch;
241       tweenFrames--;
242       formantPos = formantTable + nextFormant * FORMANT_SZ;
243       deltaForm1PhaseInc = pgm_read_byte(formantPos++)*formantScale - startForm1PhaseInc;
244       deltaForm2PhaseInc = pgm_read_byte(formantPos++)*formantScale - startForm2PhaseInc;
245       deltaForm3PhaseInc = pgm_read_byte(formantPos++)*formantScale - startForm3PhaseInc;
246       deltaForm1Amp = pgm_read_byte(formantPos++) - startForm1Amp;
247       deltaForm2Amp = pgm_read_byte(formantPos++) - startForm2Amp;
248       deltaForm3Amp = pgm_read_byte(formantPos++) - startForm3Amp;
249       deltaMod = pgm_read_byte(formantPos++) - startMod;
250       deltaPitch = nextPitch - startPitch;
251       deltaMod = nextMod - startMod;
252       for (int i=1; i<=tweenFrames; i++) {
253         form1PhaseInc = startForm1PhaseInc + (i*deltaForm1PhaseInc)/tweenFrames;
254         form2PhaseInc = startForm2PhaseInc + (i*deltaForm2PhaseInc)/tweenFrames;
255         form3PhaseInc = startForm3PhaseInc + (i*deltaForm3PhaseInc)/tweenFrames;
256         form1Amp = startForm1Amp + (i*deltaForm1Amp)/tweenFrames;
257         form2Amp = startForm2Amp + (i*deltaForm2Amp)/tweenFrames;
258         form3Amp = startForm3Amp + (i*deltaForm3Amp)/tweenFrames;
259         pitchPhaseInc = startPitch + (i*deltaPitch)/tweenFrames;
260         noiseMod = startMod + (i*deltaMod)/tweenFrames;
261         delay(frameTime);
262       }
263     }
264   }
265   
266 }
267
268 SIGNAL(PWM_INTERRUPT)
269 {
270   int8_t value;
271   static int8_t noise;
272   int16_t phaseNoise = noise * noiseMod;
273   noise += noise<<2; noise++;  // noise' = 5*noise+1
274   
275   form1Phase += form1PhaseInc;
276   value = pgm_read_byte(sinCalc+(((form1Phase>>8) & 0xf0) | form1Amp));
277   form2Phase += form2PhaseInc;
278   value += pgm_read_byte(sinCalc+(((form2Phase>>8) & 0xf0) | form2Amp));
279   form3Phase += form3PhaseInc;
280   value += pgm_read_byte(sqrCalc+(((form3Phase>>8) & 0xf0) | form3Amp));
281
282   value = (value * (0xff^(pitchPhase>>8)))>>8;
283   pitchPhase += pitchPhaseInc;
284   if ((pitchPhase+phaseNoise) < pitchPhaseInc) {
285     form1Phase = 0;
286     form2Phase = 0;
287     form3Phase = 0;
288   }
289   PWM_VALUE = value + 0x80;
290 }
291
292
293
294
295 void ecritLaChanson(String phonem[]){
296
297 Serial.println("ajoute:"+phonem[0]);
298     
299    /*
300    Serial.println("ajoute:"+phonem[1]);
301     Serial.println("ajoute:"+phonem[2]);
302     Serial.println("ajoute:"+phonem[3]);
303     frameList[0]=phonem[0];
304     frameList[1]=phonem[1];
305     frameList[2]=phonem[2];
306     frameList[3]=phonem[3];
307     */
308     Serial.println(char(frameList[0]));
309     Serial.println(char(frameList[1]));
310     Serial.println(char(frameList[2]));
311     Serial.println(char(frameList[3]));
312     Serial.println(char(frameList[4]));
313     Serial.println(char(frameList[5]));
314
315
316 }