This commit was manufactured by cvs2svn to create tag
[gnokii.git] / common / gsm-ringtones.c
1 /*
2
3   G N O K I I
4
5   A Linux/Unix toolset and driver for Nokia mobile phones.
6
7   Released under the terms of the GNU GPL, see file COPYING for more details.
8
9   This file provides support for ringtones.
10
11 */
12
13 #ifdef WIN32
14   #include <windows.h>
15   #include "misc_win32.h"
16 #else
17   #include <unistd.h>
18 #endif
19
20 #include "gsm-api.h"
21
22 GSM_Ringtone SMringtone;
23 GSM_BinRingtone ringtone;
24
25 /* Beats-per-Minute Encoding */
26
27 int BeatsPerMinute[] = {
28    25,  28,  31,  35,  40,  45,  50,  56,  63,  70,
29    80,  90, 100, 112, 125, 140, 160, 180, 200, 225,
30   250, 285, 320, 355, 400, 450, 500, 565, 635, 715,
31   800, 900
32 };
33
34 struct OneRingtone RingingTones[] = {
35          {"",0,0},
36 /*  1 */ {"Uploaded #1",0,0},   /*  2 */ {"Ring ring",0,0},
37 /*  3 */ {"Low",0,0},           /*  4 */ {"Fly",0,0},
38 /*  5 */ {"Mosquito",0,0},      /*  6 */ {"Bee",0,0},
39 /*  7 */ {"Intro",0,0},         /*  8 */ {"Etude",0,0},
40 /*  9 */ {"Hunt",0,0},          /* 10 */ {"Going up",0,0},
41 /* 11 */ {"City bird",0,0},     /* 12 */ {"Chase",0,0},
42 /* 13 */ {"Scifi",0,0},         /* 14 */ {"Kick",0,0},
43 /* 15 */ {"Do-mi-so",0,0},      /* 16 */ {"Robo N1X",0,0},
44 /* 17 */ {"Dizzy",0,0},         /* 18 */ {"Playground",0,0},
45 /* 19 */ {"That's it!",0,0},    /* 20 */ {"Grande valse",0,0},
46 /* 21 */ {"Knock knock",0,0},   /* 22 */ {"Knock again",0,0},
47 /* 23 */ {"Helan",0,0},         /* 24 */ {"Fuga",0,0},          
48 /* 25 */ {"Menuet",0,0},        /* 26 */ {"Ode to Joy",0,0},
49 /* 27 */ {"Elise",0,0},         /* 28 */ {"Mozart 40",0,0},
50 /* 29 */ {"Piano Concerto",0,0},/* 30 */ {"William Tell",0,0},
51 /* 31 */ {"Badinerie",0,0},     /* 32 */ {"Polka",0,0},
52 /* 33 */ {"Attraction",0,0},    /* 34 */ {"Polite",0,0},
53 /* 35 */ {"Persuasion",0,0},    /* 36 */ {"Tick tick",0,0},
54 /* 37 */ {"Samba",0,0},         /* 38 */ {"Orient",0,0},
55 /* 39 */ {"Charleston",0,0},    /* 40 */ {"Songette",0,0},    
56 /* 41 */ {"Jumping",0,0},       /* 42 */ {"Lamb",0,0},
57 /* 43 */ {"Marry",0,0},         /* 44 */ {"Tango",0,0},
58 /* 45 */ {"Tangoed",0,0},       /* 46 */ {"Down",0,0},
59 /* 47 */ {"Polska",0,0},        /* 48 */ {"WalzeBrilliant",0,0},
60 /* 49 */ {"Cicada",0,0},        /* 50 */ {"Trio",0,0},
61 /* 51 */ {"Circles",0,0},       /* 52 */ {"Nokia tune",0,0},
62 /* 53 */ {"Sunny walks",0,0},   /* 54 */ {"Basic rock",0,0},
63 /* 55 */ {"Reveille",0,0},      /* 56 */ {"Groovy Blue",0,0},
64 /* 57 */ {"Brave Scotland",0,0},/* 58 */ {"Matilda",0,0},
65 /* 59 */ {"Bumblebee",0,0},     /* 60 */ {"Hungarian",0,0},
66 /* 61 */ {"Valkyrie",0,0},      /* 62 */ {"Bach #3",0,0},
67 /* 63 */ {"Toreador",0,0},      /* 64 */ {"9th Symphony",0,0},
68 /* 65 */ {"Uploaded #2",0,0},   /* 66 */ {"Uploaded #3",0,0},
69 /* 67 */ {"Uploaded #4",0,0},   /* 68 */ {"Uploaded #5",0,0},
70          {"",0,0}
71 };
72
73 int OctetAlign(unsigned char *Dest, int CurrentBit)
74 {
75   int i=0;
76
77   while((CurrentBit+i)%8) {
78     ClearBit(Dest, CurrentBit+i);
79     i++;
80   }
81
82   return CurrentBit+i;
83 }
84
85 int OctetAlignNumber(int CurrentBit)
86 {
87   int i=0;
88
89   while((CurrentBit+i)%8) { i++; }
90
91   return CurrentBit+i;
92 }
93
94 int BitPack(unsigned char *Dest, int CurrentBit, unsigned char *Source, int Bits)
95 {
96
97   int i;
98
99   for (i=0; i<Bits; i++)
100     if (GetBit(Source, i))   SetBit(Dest, CurrentBit+i);
101                       else ClearBit(Dest, CurrentBit+i);
102
103   return CurrentBit+Bits;
104 }
105
106 int GSM_GetTempo(int Beats) {
107
108   int i=0;
109
110   while ( i < sizeof(BeatsPerMinute)/sizeof(BeatsPerMinute[0])) {
111
112     if (Beats<=BeatsPerMinute[i]) break;
113     i++;
114   }
115
116   return i<<3;
117 }    
118
119 int BitPackByte(unsigned char *Dest, int CurrentBit, unsigned char Command, int Bits) {
120
121   unsigned char Byte[]={Command};
122
123   return BitPack(Dest, CurrentBit, Byte, Bits);
124 }
125
126
127 /* This is messy but saves using the math library! */
128
129 int GSM_GetDuration(int number, unsigned char *spec) {
130
131   int duration=0;
132
133   switch (number) {
134
135   case 128*3/2: duration=Duration_Full; *spec=DottedNote;        break;  
136   case 128*2/3: duration=Duration_Full; *spec=Length_2_3;        break;  
137   case 128    : duration=Duration_Full; *spec=NoSpecialDuration; break;  
138   case 64*9/4 : duration=Duration_1_2;  *spec=DoubleDottedNote;  break;    
139   case 64*3/2 : duration=Duration_1_2;  *spec=DottedNote;        break;  
140   case 64*2/3 : duration=Duration_1_2;  *spec=Length_2_3;        break;  
141   case 64     : duration=Duration_1_2;  *spec=NoSpecialDuration; break;  
142   case 32*9/4 : duration=Duration_1_4;  *spec=DoubleDottedNote;  break;    
143   case 32*3/2 : duration=Duration_1_4;  *spec=DottedNote;        break;  
144   case 32*2/3 : duration=Duration_1_4;  *spec=Length_2_3;        break;  
145   case 32     : duration=Duration_1_4;  *spec=NoSpecialDuration; break;  
146   case 16*9/4 : duration=Duration_1_8;  *spec=DoubleDottedNote;  break;    
147   case 16*3/2 : duration=Duration_1_8;  *spec=DottedNote;        break;  
148   case 16*2/3 : duration=Duration_1_8;  *spec=Length_2_3;        break;  
149   case 16     : duration=Duration_1_8;  *spec=NoSpecialDuration; break;  
150   case 8*9/4  : duration=Duration_1_16; *spec=DoubleDottedNote;  break;    
151   case 8*3/2  : duration=Duration_1_16; *spec=DottedNote;        break;  
152   case 8*2/3  : duration=Duration_1_16; *spec=Length_2_3;        break;  
153   case 8      : duration=Duration_1_16; *spec=NoSpecialDuration; break;  
154   case 4*9/4  : duration=Duration_1_32; *spec=DoubleDottedNote;  break;    
155   case 4*3/2  : duration=Duration_1_32; *spec=DottedNote;        break;  
156   case 4*2/3  : duration=Duration_1_32; *spec=Length_2_3;        break;  
157   case 4      : duration=Duration_1_32; *spec=NoSpecialDuration; break;  
158   }
159
160   return duration;
161 }
162
163
164 int GSM_GetNote(int number) {
165   
166   int note=0;
167  
168   if (number!=255) {
169     note=number%14;
170     switch (note) {
171
172     case  0: note=Note_C;   break;
173     case  1: note=Note_Cis; break;
174     case  2: note=Note_D;   break;
175     case  3: note=Note_Dis; break;
176     case  4: note=Note_E;   break;
177     case  6: note=Note_F;   break;
178     case  7: note=Note_Fis; break;
179     case  8: note=Note_G;   break;
180     case  9: note=Note_Gis; break;
181     case 10: note=Note_A;   break;
182     case 11: note=Note_Ais; break;
183     case 12: note=Note_H;   break;
184     }
185   }
186   else note = Note_Pause;
187
188   return note;
189
190 }
191
192 int GSM_GetScale(int number) {
193
194   int scale=-1;
195
196   if (number!=255) {
197     scale=number/14;
198
199     /* Ensure the scale is valid */
200     scale%=4;
201
202     scale=scale<<6;
203   }
204   return scale;
205 }
206
207 /* This function packs the ringtone from the structure "ringtone" to
208    "package", where maxlength means length of package.
209    Function returns number of packed notes and change maxlength to
210    number of used chars in "package" */
211 u8 GSM_PackRingtone(GSM_Ringtone *ringtone, unsigned char *package, int *maxlength)
212 {
213   int StartBit=0;
214   unsigned char CommandLength = 0x02;
215   unsigned char spec;
216   int oldscale=10, newscale=0, oldstyle=0, oldtempo=0;
217   int HowMany=0;              /* How many instructions packed */
218   int HowLong=0;              /* How many bits packed */
219   int StartNote=0, EndNote=0; /* First and last packed note from ringtone */
220
221   /* Default ringtone parameters */
222   u8 DefNoteScale=2, DefNoteDuration=4;
223   int DefNoteTempo=63;
224   u8 DefNoteStyle=NaturalStyle;
225   
226   int buffer[6];\r              /* Used to find default ringtone parameters */
227   int i,j,k=0,thisnote,thisnotelong;\r
228   
229   /* Find the most frequently used duration and use this for the default */\r
230  \r for (i=0;i<6;i++) buffer[i]=0;\r
231   for (i=0;i<ringtone->NrNotes;i++) {\r
232     switch (ringtone->notes[i].duration) {\r
233       case 192: buffer[0]++; break;\r
234       case 128: buffer[0]++; break;\r
235       case  96: buffer[1]++; break;\r
236       case  64: buffer[1]++; break;\r
237       case  48: buffer[2]++; break;\r
238       case  32: buffer[2]++; break;\r
239       case  24: buffer[3]++; break;\r
240       case  16: buffer[3]++; break;\r
241       case  12: buffer[4]++; break;\r
242       case   8: buffer[4]++; break;\r
243       case   6: buffer[5]++; break;\r
244       case   4: buffer[5]++; break;\r
245     }\r
246   }\r
247 \r
248   /* Now find the most frequently used */\r
249   j=0;\r
250   for (i=0;i<6;i++) {\r
251     if (buffer[i]>j) {\r
252       k=i; \r
253       j=buffer[i];\r
254     }\r
255   }\r
256 \r
257   /* Finally convert the default duration */\r
258   switch (k) {\r
259       case 0: DefNoteDuration=128; break;       \r
260       case 1: DefNoteDuration= 64; break;       \r
261       case 2: DefNoteDuration= 32; break;       \r
262       case 3: DefNoteDuration= 16; break;       \r
263       case 4: DefNoteDuration=  8; break;       \r
264       case 5: DefNoteDuration=  4; break;       \r
265      default: DefNoteDuration= 16; break;       \r
266   }  \r
267 \r
268   /* Find the most frequently used scale and use this for the default */\r\r
269   for (i=0;i<6;i++) buffer[i]=0;\r
270   for (i=0;i<ringtone->NrNotes;i++) {\r
271     if (ringtone->notes[i].note!=255) {\r
272       buffer[ringtone->notes[i].note/14]++;\r
273     }\r
274   }\r
275   j=0;\r
276   for (i=0;i<6;i++) {\r
277     if (buffer[i]>j) {\r
278       DefNoteScale=i;\r
279       j=buffer[i];\r
280     }\r
281   }\r
282
283   StartBit=BitPackByte(package, StartBit, CommandLength, 8);
284   StartBit=BitPackByte(package, StartBit, RingingToneProgramming, 7);
285
286   /* The page 3-23 of the specs says that <command-part> is always
287      octet-aligned. */
288   StartBit=OctetAlign(package, StartBit);
289
290   StartBit=BitPackByte(package, StartBit, Sound, 7);
291   StartBit=BitPackByte(package, StartBit, BasicSongType, 3);
292
293   /* Set special chars in ringtone name */
294   for (i=0;i<strlen(ringtone->name);i++) {
295     if (ringtone->name[i]=='~') ringtone->name[i]=1; //enables/disables blinking
296     if (ringtone->name[i]=='`') ringtone->name[i]=0; //hides rest ot contents
297   }
298
299   /* Packing the name of the tune. */
300   StartBit=BitPackByte(package, StartBit, strlen(ringtone->name)<<4, 4);
301   StartBit=BitPack(package, StartBit, ringtone->name, 8*strlen(ringtone->name));
302
303   /* Set special chars in ringtone name */
304   for (i=0;i<strlen(ringtone->name);i++) {
305     if (ringtone->name[i]==1) ringtone->name[i]='~'; //enables/disables blinking
306     if (ringtone->name[i]==0) ringtone->name[i]='`'; //hides rest ot contents
307   }
308
309   /* Info about song pattern */
310   StartBit=BitPackByte(package, StartBit, 0x01, 8); /* One song pattern */
311   StartBit=BitPackByte(package, StartBit, PatternHeaderId, 3);
312   StartBit=BitPackByte(package, StartBit, A_part, 2);
313   StartBit=BitPackByte(package, StartBit, ringtone->Loop<<4, 4);
314
315   /* Info, how long is contents for SMS */
316   HowLong=8+8+7+3+4+8*strlen(ringtone->name)+8+3+2+4+8+3+2+3+5;
317   
318   /* Calculating number of instructions in the tune.
319      Each Note contains Note and (sometimes) Scale.
320      Default Tempo and Style are instructions too. */
321   HowMany=2; /* Default Tempo and Style */
322
323   /* Default style and tempo */
324   DefNoteStyle=ringtone->notes[0].style;
325   DefNoteTempo=ringtone->notes[0].tempo;
326   oldstyle=DefNoteStyle;
327   oldtempo=DefNoteTempo;
328
329   for(i=0; i<ringtone->NrNotes; i++) {
330
331     /* PC Composer 2.0.010 doesn't like, when we start ringtone from pause:
332        displays, that format is invalid and
333        hangs, when you move mouse over place, where pause is */       
334     if (GSM_GetNote(ringtone->notes[i].note)==Note_Pause && oldscale==10) {
335       StartNote++;
336     } else {
337
338       thisnote=0;
339       thisnotelong=0;
340      
341       /* we don't write Scale/Style info before "Pause" note - it saves place */
342       if (GSM_GetNote(ringtone->notes[i].note)!=Note_Pause) {
343
344         if (ringtone->allnotesscale ||
345             oldscale!=(newscale=GSM_GetScale(ringtone->notes[i].note))) {
346
347           /* We calculate, if we have space to add next scale instruction */
348           if (((OctetAlignNumber(HowLong+5)+8)/8)<=(*maxlength)) {
349             oldscale=newscale;
350             HowLong+=5;
351             HowMany++;
352             thisnote++;
353             thisnotelong+=5;
354           } else {
355             break;
356           }
357         }
358         if (ringtone->notes[i].style!=oldstyle) {
359           /* We calculate, if we have space to add next style instruction */
360           if (((OctetAlignNumber(HowLong+5)+8)/8)<=(*maxlength)) {
361             oldstyle=ringtone->notes[i].style;
362             HowLong+=5;
363             HowMany++;
364             thisnote++;
365             thisnotelong+=5;
366           } else {
367             HowLong=HowLong-thisnotelong;
368             HowMany=HowMany-thisnote;
369             break;
370           }
371         }
372       }
373       
374       if (ringtone->notes[i].tempo!=oldtempo) {
375         /* We calculate, if we have space to add next tempo instruction */
376         if (((OctetAlignNumber(HowLong+8)+8)/8)<=(*maxlength)) {
377           oldtempo=ringtone->notes[i].tempo;
378           HowLong+=8;
379           HowMany++;
380           thisnote++;
381           thisnotelong+=8;
382         } else {
383           HowLong=HowLong-thisnotelong;
384           HowMany=HowMany-thisnote;
385           break;
386         }
387       }
388     
389       /* We calculate, if we have space to add next note instruction */
390       if (((OctetAlignNumber(HowLong+12)+8)/8)<=(*maxlength)) {
391         HowMany++;
392         EndNote++;
393         HowLong+=12;
394       } else {
395         HowLong=HowLong-thisnotelong;
396         HowMany=HowMany-thisnote;
397         break;
398       }
399     }
400
401     /* We are sure, we pack it for SMS or setting to phone, not for OTT file */    
402     if (*maxlength<1000) {
403        /* Like Pc Composer say - before of phone limitations...*/
404       if ((EndNote-StartNote)==FB61_MAX_RINGTONE_NOTES-1) break;
405     }
406   }
407
408   StartBit=BitPackByte(package, StartBit, HowMany, 8);
409 #ifdef DEBUG
410 //  fprintf(stdout,_("length of new pattern: %i %i\n"),HowMany,StartBit);
411 #endif
412
413   /* Style */
414   StartBit=BitPackByte(package, StartBit, StyleInstructionId, 3);
415   StartBit=BitPackByte(package, StartBit, DefNoteStyle, 2);
416     
417   /* Beats per minute/tempo of the tune */
418   StartBit=BitPackByte(package, StartBit, TempoInstructionId, 3);
419   StartBit=BitPackByte(package, StartBit, GSM_GetTempo(DefNoteTempo), 5);
420 #ifdef DEBUG
421 //  fprintf(stdout,_("def temp: %i %i\n"),GSM_GetTempo(DefNoteTempo),StartBit);
422 #endif
423
424   /* Default scale */
425   oldscale=10;
426   
427   /* Default style */
428   oldstyle=DefNoteStyle;
429
430   /* Default tempo */
431   oldtempo=DefNoteTempo;
432
433   /* Notes packing */
434   for(i=StartNote; i<(EndNote+StartNote); i++) {
435
436     /* we don't write Scale info before "Pause" note - it saves place */
437     if (GSM_GetNote(ringtone->notes[i].note)!=Note_Pause) {
438       if (ringtone->allnotesscale ||
439           oldscale!=(newscale=GSM_GetScale(ringtone->notes[i].note))) {
440 #ifdef DEBUG
441 //    fprintf(stdout,_("Scale\n"));
442 #endif
443         oldscale=newscale;
444         StartBit=BitPackByte(package, StartBit, ScaleInstructionId, 3);
445         StartBit=BitPackByte(package, StartBit, GSM_GetScale(ringtone->notes[i].note), 2);
446       }
447       if (ringtone->notes[i].style!=oldstyle) {
448         /* Style */
449         StartBit=BitPackByte(package, StartBit, StyleInstructionId, 3);
450         StartBit=BitPackByte(package, StartBit, ringtone->notes[i].style, 2);
451         oldstyle=ringtone->notes[i].style;
452       }
453     }
454
455     if (ringtone->notes[i].tempo!=oldtempo) {
456       /* Beats per minute/tempo of the tune */
457       StartBit=BitPackByte(package, StartBit, TempoInstructionId, 3);
458       StartBit=BitPackByte(package, StartBit, GSM_GetTempo(ringtone->notes[i].tempo), 5);
459       oldtempo=ringtone->notes[i].tempo;
460     }    
461     
462     /* Note */
463     StartBit=BitPackByte(package, StartBit, NoteInstructionId, 3);
464     StartBit=BitPackByte(package, StartBit, GSM_GetNote(ringtone->notes[i].note), 4);
465     StartBit=BitPackByte(package, StartBit, GSM_GetDuration(ringtone->notes[i].duration,&spec), 3);
466     StartBit=BitPackByte(package, StartBit, spec, 2);
467
468 #ifdef DEBUG    
469 //    fprintf(stdout,_("note(%i): %i, scale: %i, duration: %i, spec: %i\n"),i,ringtone->notes[i].note,GSM_GetScale(ringtone->notes[i].note),GSM_GetDuration(ringtone->notes[i].duration,&spec),spec);
470 #endif
471
472   }
473
474   StartBit=OctetAlign(package, StartBit);
475
476   StartBit=BitPackByte(package, StartBit, CommandEnd, 8);
477   
478 #ifdef DEBUG
479   if (StartBit!=OctetAlignNumber(HowLong)+8)
480     fprintf(stdout,_("Error in PackRingtone - StartBit different to HowLong %d - %d)\n"),StartBit,OctetAlignNumber(HowLong)+8);
481 #endif
482
483   *maxlength=StartBit/8;  
484
485   return(EndNote+StartNote);
486 }
487
488 int BitUnPack(unsigned char *Dest, int CurrentBit, unsigned char *Source, int Bits)
489 {
490   int i;
491
492   for (i=0; i<Bits; i++)
493     if (GetBit(Dest, CurrentBit+i)) {   SetBit(Source, i); }
494                                else { ClearBit(Source, i); }
495
496   return CurrentBit+Bits;
497 }
498
499 int BitUnPackInt(unsigned char *Src, int CurrentBit, int *integer, int Bits) {
500
501   int l=0,z=128,i;
502
503   for (i=0; i<Bits; i++) {
504     if (GetBit(Src, CurrentBit+i)) l=l+z;
505     z=z/2;
506   }
507
508   *integer=l;
509   
510   return CurrentBit+i;
511 }
512
513 int OctetUnAlign(int CurrentBit)
514 {
515   int i=0;
516
517   while((CurrentBit+i)%8) i++;
518
519   return CurrentBit+i;
520 }
521
522 /* TODO: better checking, if contents of ringtone is OK */
523 GSM_Error GSM_UnPackRingtone(GSM_Ringtone *ringtone, char *package, int maxlength)
524 {
525   int StartBit=0;
526   int HowMany;
527   int l,q,i;
528   int spec;
529
530   /* Default ringtone parameters */
531   u8 DefNoteScale=2, DefNoteDuration=4;
532   int DefNoteTempo=63;
533   u8 DefNoteStyle=NaturalStyle;
534
535   ringtone->allnotesscale=false;
536   
537   StartBit=BitUnPackInt(package,StartBit,&l,8);
538 #ifdef DEBUG
539   if (l!=0x02)
540     fprintf(stdout,_("Not header\n"));  
541 #endif
542   if (l!=0x02) return GE_SUBFORMATNOTSUPPORTED;
543
544   StartBit=BitUnPackInt(package,StartBit,&l,7);    
545 #ifdef DEBUG
546   if (l!=RingingToneProgramming)
547     fprintf(stdout,_("Not RingingToneProgramming\n"));  
548 #endif
549   if (l!=RingingToneProgramming) return GE_SUBFORMATNOTSUPPORTED;
550     
551   /* The page 3-23 of the specs says that <command-part> is always
552      octet-aligned. */
553   StartBit=OctetUnAlign(StartBit);
554
555   StartBit=BitUnPackInt(package,StartBit,&l,7);    
556 #ifdef DEBUG
557   if (l!=Sound)
558     fprintf(stdout,_("Not Sound\n"));  
559 #endif
560   if (l!=Sound) return GE_SUBFORMATNOTSUPPORTED;
561
562   StartBit=BitUnPackInt(package,StartBit,&l,3);    
563 #ifdef DEBUG
564   if (l!=BasicSongType)
565     fprintf(stdout,_("Not BasicSongType\n"));  
566 #endif
567   if (l!=BasicSongType) return GE_SUBFORMATNOTSUPPORTED;
568
569   /* Getting length of the tune name */
570   StartBit=BitUnPackInt(package,StartBit,&l,4);
571   l=l>>4;
572 #ifdef DEBUG
573 //  fprintf(stdout,_("Length of name: %i\n"),l);
574 #endif
575
576   /* Unpacking the name of the tune. */
577   StartBit=BitUnPack(package, StartBit, ringtone->name, 8*l);
578   ringtone->name[l]=0;
579
580   /* Set special chars in ringtone name */
581   for (i=0;i<strlen(ringtone->name);i++) {
582     if (ringtone->name[i]==1) ringtone->name[i]='~'; //enables/disables blinking
583     if (ringtone->name[i]==0) ringtone->name[i]='`'; //hides rest ot contents
584   }
585
586 #ifdef DEBUG
587 //   fprintf(stdout,_("Name: %s\n"),ringtone->name);
588 #endif
589
590   StartBit=BitUnPackInt(package,StartBit,&l,8);    
591 #ifdef DEBUG
592 //  fprintf(stdout,_("Number of song patterns: %i\n"),l);
593 #endif
594   if (l!=1) return GE_SUBFORMATNOTSUPPORTED; //we support only one song pattern
595
596   StartBit=BitUnPackInt(package,StartBit,&l,3);          
597 #ifdef DEBUG
598   if (l!=PatternHeaderId)
599     fprintf(stdout,_("Not PatternHeaderId\n"));
600 #endif
601   if (l!=PatternHeaderId) return GE_SUBFORMATNOTSUPPORTED;
602
603   StartBit+=2; //Pattern ID - we ignore it
604
605   StartBit=BitUnPackInt(package,StartBit,&l,4);          
606   l=l>>4;
607 #ifdef DEBUG
608   fprintf(stdout,_("Loop value: %i\n"),l);
609 #endif
610   ringtone->Loop=l;
611
612   HowMany=0;
613   StartBit=BitUnPackInt(package, StartBit, &HowMany, 8);
614 #ifdef DEBUG
615   fprintf(stdout,_("length of new pattern: %i %i\n"),HowMany,StartBit);
616 #endif
617
618   ringtone->NrNotes=0;
619     
620   for (i=0;i<HowMany;i++) {
621
622     StartBit=BitUnPackInt(package,StartBit,&q,3);              
623     switch (q) {
624       case VolumeInstructionId:
625 #ifdef DEBUG
626 //        fprintf(stdout,_("Volume\n"));
627 #endif
628         StartBit+=4;
629         break;
630       case StyleInstructionId:
631         StartBit=BitUnPackInt(package,StartBit,&l,2);              
632 #ifdef DEBUG
633 //      fprintf(stdout,_("Style %i\n"),l>>6);
634 #endif
635         switch (l) {
636           case StaccatoStyle  : DefNoteStyle=StaccatoStyle;   break;
637           case ContinuousStyle: DefNoteStyle=ContinuousStyle; break;
638           case NaturalStyle   : DefNoteStyle=NaturalStyle;    break;
639         }
640         break;
641       case TempoInstructionId:
642         StartBit=BitUnPackInt(package,StartBit,&l,5);                   
643         l=l>>3;
644         DefNoteTempo=BeatsPerMinute[l];
645 #ifdef DEBUG
646 //      fprintf(stdout,_("Tempo %i\n"),l);
647 #endif
648         break;
649       case ScaleInstructionId:
650         StartBit=BitUnPackInt(package,StartBit,&l,2);
651         DefNoteScale=l>>6;
652 #ifdef DEBUG
653 //      fprintf(stdout,_("scale: %i %i\n"),DefNoteScale,ringtone->NrNotes);
654 #endif
655         break;
656       case NoteInstructionId:
657         StartBit=BitUnPackInt(package,StartBit,&l,4);    
658
659         switch (l) {
660           case Note_C  :ringtone->notes[ringtone->NrNotes].note=0;break;
661           case Note_Cis:ringtone->notes[ringtone->NrNotes].note=1;break;
662           case Note_D  :ringtone->notes[ringtone->NrNotes].note=2;break;
663           case Note_Dis:ringtone->notes[ringtone->NrNotes].note=3;break;
664           case Note_E  :ringtone->notes[ringtone->NrNotes].note=4;break;
665           case Note_F  :ringtone->notes[ringtone->NrNotes].note=6;break;
666           case Note_Fis:ringtone->notes[ringtone->NrNotes].note=7;break;
667           case Note_G  :ringtone->notes[ringtone->NrNotes].note=8;break;
668           case Note_Gis:ringtone->notes[ringtone->NrNotes].note=9;break;
669           case Note_A  :ringtone->notes[ringtone->NrNotes].note=10;break;
670           case Note_Ais:ringtone->notes[ringtone->NrNotes].note=11;break;
671           case Note_H  :ringtone->notes[ringtone->NrNotes].note=12;break;
672           default      :ringtone->notes[ringtone->NrNotes].note=255;break; //Pause ?
673         }
674       
675         if (ringtone->notes[ringtone->NrNotes].note!=255)
676           ringtone->notes[ringtone->NrNotes].note=ringtone->notes[ringtone->NrNotes].note+DefNoteScale*14;
677
678         StartBit=BitUnPackInt(package,StartBit,&l,3);    
679         DefNoteDuration=l;
680
681         StartBit=BitUnPackInt(package,StartBit,&spec,2);    
682
683         if (DefNoteDuration==Duration_Full && spec==DottedNote)
684             ringtone->notes[ringtone->NrNotes].duration=128*3/2;
685         if (DefNoteDuration==Duration_Full && spec==Length_2_3)
686             ringtone->notes[ringtone->NrNotes].duration=128*2/3;
687         if (DefNoteDuration==Duration_Full && spec==NoSpecialDuration)
688             ringtone->notes[ringtone->NrNotes].duration=128;
689         if (DefNoteDuration==Duration_1_2 && spec==DottedNote)
690             ringtone->notes[ringtone->NrNotes].duration=64*3/2;
691         if (DefNoteDuration==Duration_1_2 && spec==Length_2_3)
692             ringtone->notes[ringtone->NrNotes].duration=64*2/3;
693         if (DefNoteDuration==Duration_1_2 && spec==NoSpecialDuration)
694             ringtone->notes[ringtone->NrNotes].duration=64;
695         if (DefNoteDuration==Duration_1_4 && spec==DottedNote)
696             ringtone->notes[ringtone->NrNotes].duration=32*3/2;
697         if (DefNoteDuration==Duration_1_4 && spec==Length_2_3)
698             ringtone->notes[ringtone->NrNotes].duration=32*2/3;
699         if (DefNoteDuration==Duration_1_4 && spec==NoSpecialDuration)
700             ringtone->notes[ringtone->NrNotes].duration=32;
701         if (DefNoteDuration==Duration_1_8 && spec==DottedNote)
702             ringtone->notes[ringtone->NrNotes].duration=16*3/2;
703         if (DefNoteDuration==Duration_1_8 && spec==Length_2_3)
704             ringtone->notes[ringtone->NrNotes].duration=16*2/3;
705         if (DefNoteDuration==Duration_1_8 && spec==NoSpecialDuration)
706             ringtone->notes[ringtone->NrNotes].duration=16;
707         if (DefNoteDuration==Duration_1_16 && spec==DottedNote)
708             ringtone->notes[ringtone->NrNotes].duration=8*3/2;
709         if (DefNoteDuration==Duration_1_16 && spec==Length_2_3)
710             ringtone->notes[ringtone->NrNotes].duration=8*2/3;
711         if (DefNoteDuration==Duration_1_16 && spec==NoSpecialDuration)
712             ringtone->notes[ringtone->NrNotes].duration=8;
713         if (DefNoteDuration==Duration_1_32 && spec==DottedNote)
714             ringtone->notes[ringtone->NrNotes].duration=4*3/2;
715         if (DefNoteDuration==Duration_1_32 && spec==Length_2_3)
716             ringtone->notes[ringtone->NrNotes].duration=4*2/3;
717         if (DefNoteDuration==Duration_1_32 && spec==NoSpecialDuration)
718             ringtone->notes[ringtone->NrNotes].duration=4;
719
720         ringtone->notes[ringtone->NrNotes].style=DefNoteStyle;
721
722         ringtone->notes[ringtone->NrNotes].tempo=DefNoteTempo;
723         
724 #ifdef DEBUG    
725 //    fprintf(stdout,_("note(%i): %i, scale: %i, duration: %i, spec: %i\n"),ringtone->NrNotes,ringtone->notes[ringtone->NrNotes].note,DefNoteScale,DefNoteDuration,spec);
726 #endif
727         if (ringtone->NrNotes==FB61_MAX_RINGTONE_NOTES) break;
728         
729         ringtone->NrNotes++;
730         break;
731       default:
732 #ifdef DEBUG
733     fprintf(stdout,_("Unsupported block %i %i\n"),q,i);  
734 #endif
735         return GE_SUBFORMATNOTSUPPORTED;
736     } 
737   }
738
739 #ifdef DEBUG
740 //  printf("Number of notes=%d\n",ringtone->NrNotes);
741 #endif
742
743   return GE_NONE;
744 }
745
746 GSM_Error GSM_ReadRingtone(GSM_SMSMessage *message, GSM_Ringtone *ringtone)
747 {
748   if (message->UDHType==GSM_RingtoneUDH) {
749     return GSM_UnPackRingtone(ringtone, message->MessageText, message->Length);
750   } else return GE_SUBFORMATNOTSUPPORTED;
751 }
752
753 int GSM_GetFrequency(int number) {
754   
755   int freq=0;
756
757   /* Values according to the software from http://iki.fi/too/sw/xring/
758      generated with:
759      perl -e 'print int(4400 * (2 **($_/12)) + .5)/10, "\n" for(3..14)'
760   */ 
761   if (number!=255) {
762     freq=number%14;
763     switch (freq) {
764
765     case  0: freq=523.3; break; // C
766     case  1: freq=554.4; break; // Cis
767
768     case  2: freq=587.3; break; //D
769     case  3: freq=622.3; break; //Dis
770     
771     case  4: freq=659.3; break; //E
772
773     case  6: freq=698.5; break; //F
774     case  7: freq=740;   break; //Fis
775
776     case  8: freq=784;   break; //G
777     case  9: freq=830.6; break; //Gis
778
779     case 10: freq=880;   break; //A
780     case 11: freq=932.3; break; //Ais
781     
782     case 12: freq=987.8; break; //H
783
784     default: freq=0; break;
785     }
786   }
787   else freq = 0;
788
789   if ((number/14)!=0) freq=freq*(number/14);
790                  else freq=freq/2;
791
792   return freq;
793
794 }
795
796 /* Very fast hack. It should be written correctly ! */
797 void GSM_PlayOneNote (GSM_RingtoneNote note) {
798   int Hz;
799
800   Hz=GSM_GetFrequency(note.note);
801         
802   GSM->PlayTone(Hz,5);
803
804   /* Is it correct ? Experimental values here */
805   switch (note.style) {
806     case StaccatoStyle:
807       usleep (7500);
808       GSM->PlayTone(0,0);       
809       usleep ((1500000/note.tempo*note.duration)-(7500));
810       break;
811     case ContinuousStyle:
812       usleep  (1500000/note.tempo*note.duration);
813       break;
814     case NaturalStyle:
815       usleep  (1500000/note.tempo*note.duration-50);
816       GSM->PlayTone(0,0);       
817       usleep (50);
818       break;    
819   }
820 }
821
822 void GSM_PlayRingtone (GSM_Ringtone *ringtone) {
823
824   int i;
825   
826   for (i=0;i<ringtone->NrNotes;i++) {
827      GSM_PlayOneNote(ringtone->notes[i]);
828   }      
829
830   /* Disables buzzer */
831   GSM->PlayTone(255*255,0);  
832 }
833
834 /* Initializes one ringtone: first is number of ringtone in 
835    RingingTones in gnokii.h, second its' code, last position in phone menu */
836 void RT(int number, int code, int menu) {
837   RingingTones[number].code=code;
838   RingingTones[number].menu=menu;
839 }
840
841 /* This function initializes structures with ringtones names adequate for
842    your phone model and firmware; if your phone is not now supported:
843    1.set first ringtone in 1'st profile in your phone
844    2.make ./gnokii --getprofile 1
845    3.read ringtone code
846    4.see in gnokii.h, if ringtone name is gnokii.h in RingingTones (if not, add)
847    5.put here RT(a,b,c), where a is number of name in RingingTones in gnokii.h,
848      b is its' code and c is number of ringtone in phone menu
849    6.repeat steps 1-5 for all ringtones
850    7.send me (Marcin-Wiacek@Topnet.PL) all RT and phone model */
851 void PrepareRingingTones(char model[64], char rev[64]) {
852
853   char rev2[64];
854   int i;
855   bool doit;
856
857   if (!RingingTones[0].code) {
858     if (!strcmp(model,"NSE-1")) //5110
859     {
860       RT( 2,18, 1);RT( 3,19, 2);RT( 7,23, 3);RT( 5,21, 4);RT( 9,25, 5);
861                    RT(20,48, 7);RT(11,27, 8);RT(33,59, 9);RT(35,62,10);
862       RT(46,60,11);RT(16,36,12);RT(17,37,13);RT(13,32,14);RT(14,34,15);
863       RT(19,43,16);RT(18,39,17);RT(24,50,18);RT(31,57,19);RT(28,54,20);
864       RT(30,56,21);RT(40,73,22);RT(39,72,23);RT(37,69,24);
865       RT(23,49,26);RT(38,71,27);             RT(41,74,29);
866       
867       strcpy(rev2,"05.23"); //5.24 and higher
868       doit=false;
869       for(i=0;i<5;i++)
870       {
871         if (rev[i]<rev2[i]) break;
872         if (rev[i]>rev2[i]) doit=true;
873       }
874       
875       if (doit) {
876          RT(22,47, 6);RT(47,58,25);RT(45,80,28);RT(43,75,30);
877       } else
878       {
879          RT(21,47, 6);RT(32,58,25);RT(44,80,28);RT(42,75,30);
880       }
881       RingingTones[0].menu=30; /* How many ringtones in phone */
882     }
883     if (!strcmp(model,"NSM-1")) //6150
884     {
885       RT( 2,18, 1);RT( 3,19, 2);RT( 7,23, 3);RT( 6,22, 4);
886       RT( 4,20, 5);RT( 5,21, 6);RT(15,35, 7);RT(12,30, 8);
887       RT( 9,25, 9);RT(20,47,10);RT( 8,24,11);RT(11,27,12);
888       RT(10,26,13);RT(34,60,14);RT(33,58,15);RT(35,61,16);
889       RT(16,36,17);RT(13,32,18);RT(19,43,19);RT(18,39,20);
890       RT(24,49,21);RT(31,56,22);RT(25,50,23);RT(27,52,24);
891       RT(26,51,25);RT(28,53,26);RT(29,54,27);RT(30,55,28);
892       RT(39,71,29);RT(37,68,30);RT(47,57,31);RT(23,48,32);
893       RT(38,70,33);RT(36,67,34);RT(41,73,35);
894       /*uploadable ringtone*/
895       RT( 1,17,36);
896       RingingTones[0].menu=36; /* How many ringtones in phone */
897     }
898     if (!strcmp(model,"NPE-3")) //6210
899     {
900       RT(19,64, 1);RT( 2,65, 2);RT( 3,66, 3);RT(15,67, 4);RT( 6,68, 5);
901       RT(49,69, 6);RT(50,70, 7);RT( 7,71, 8);RT(35,72, 9);RT(33,73,10);
902       RT(18,74,11);RT( 5,75,12);RT(51,76,13);RT(52,77,14);RT(53,78,15);
903       RT(37,79,16);RT(54,80,17);RT(55,81,18);RT(56,82,19);RT(57,83,20);
904       RT(58,84,21);RT(59,85,22);RT(25,86,23);RT(27,87,24);RT(30,88,25);
905       RT(39,89,26);RT(24,90,27);RT( 8,91,28);RT(60,92,29);RT(61,93,30);
906       RT(31,94,31);RT(62,95,32);RT(63,96,33);RT(64,97,34);RT(48,98,35);
907       /* Uploadable ringtones */
908       RT( 1,137,36);RT(65,138,37);RT(66,139,38);RT(67,140,39);RT(68,141,40);
909
910       RingingTones[0].menu=40; /* How many ringtones in phone */
911     }
912     RingingTones[0].code=true;
913   }
914 }
915
916 /* returns names from code or number in menu */
917 char *RingingToneName(int code, int menu)
918 {
919   int index=1;
920   GSM_Error error;
921
922   if (code==0)
923   {
924     while (strcmp(RingingTones[index].name,"")) {
925       if (RingingTones[index].menu==menu) break;
926       index++;
927     }
928   } else
929   {
930     while (strcmp(RingingTones[index].name,"")) {
931       if (RingingTones[index].code==code) break;
932       index++;
933     }
934   }
935
936   if (!strncmp(RingingTones[index].name,"Uploaded ",9)) {
937     ringtone.location=atoi(&RingingTones[index].name[10]);
938
939     error=GSM_GetPhoneRingtone(&ringtone,&SMringtone);
940      
941     if (error==GE_NONE) {
942       if (GetModelFeature (FN_RINGTONES)==F_RING_SM) return SMringtone.name;
943                                                 else return ringtone.name;
944     }
945   }
946   
947   return RingingTones[index].name;
948 }
949
950 /* returns code from number in menu */
951 int RingingToneCode(int menu)
952 {
953   int index=1;
954
955   while ( RingingTones[index].menu!=menu) index++;
956
957   return RingingTones[index].code;
958 }
959
960 /* returns number in menu from code */
961 int RingingToneMenu(int code)
962 {
963   int index=1;
964
965   while ( RingingTones[index].code!=code) index++;
966
967   return RingingTones[index].menu;
968 }
969
970 int NumberOfRingtones()
971 {
972   return RingingTones[0].menu;
973 }
974
975 int GSM_SaveRingtoneToSMS(GSM_MultiSMSMessage *SMS,
976                           GSM_Ringtone *ringtone, bool profilestyle)
977 {  
978   int i, j;
979   unsigned char MessageBuffer[GSM_MAX_SMS_8_BIT_LENGTH*4];
980   unsigned char MessageBuffer2[GSM_MAX_SMS_8_BIT_LENGTH*4];
981   int MessageLength;
982   GSM_UDH UDHType;
983   
984   EncodeUDHHeader(MessageBuffer, GSM_RingtoneUDH);
985   MessageLength=GSM_MAX_SMS_8_BIT_LENGTH-(MessageBuffer[0]+1);
986   i=GSM_PackRingtone(ringtone, MessageBuffer, &MessageLength);
987
988   if (i!=ringtone->NrNotes && profilestyle)
989   {
990     MessageLength=0;
991     MessageBuffer[MessageLength++]=0x30;          //SM version. Here 3.0
992     MessageBuffer[MessageLength++]=SM30_RINGTONE; //ID for ringtone
993
994     MessageBuffer[MessageLength++]=0x01;          //length hi.Later changed
995     MessageBuffer[MessageLength++]=0x00;          //length lo.Later changed
996
997     j=SM30_MAX_RINGTONE_FRAME_LENGTH;
998     i=GSM_PackRingtone(ringtone, MessageBuffer2, &j);
999     MessageLength=MessageLength+j;
1000     memcpy(MessageBuffer+4,MessageBuffer2,j);
1001       
1002     MessageBuffer[2]=j/256;
1003     MessageBuffer[3]=j%256;
1004
1005     UDHType=GSM_ProfileUDH;
1006   } else
1007     UDHType=GSM_RingtoneUDH;
1008
1009   GSM_MakeMultiPartSMS2(SMS,MessageBuffer,MessageLength, UDHType, GSM_Coding_Default);
1010
1011   return i;
1012 }
1013
1014 GSM_Error GSM_GetPhoneRingtone(GSM_BinRingtone *ringtone,GSM_Ringtone *SMringtone)
1015 {
1016   GSM_Error error;
1017   int i;
1018
1019   error=GSM->GetBinRingtone(ringtone);
1020
1021   if (error==GE_UNKNOWNMODEL)
1022   {    
1023     /* In 3310,... we have normal "Smart Messaging" format */
1024     if (GetModelFeature (FN_RINGTONES)==F_RING_SM) {      
1025       i=7;
1026       if (ringtone->frame[9]==0x4a && ringtone->frame[10]==0x3a) i=8;
1027       ringtone->frame[i]=0x02;
1028         
1029       GSM_UnPackRingtone(SMringtone, ringtone->frame+i, ringtone->length-i);
1030
1031       return GE_NONE;
1032     }
1033   }
1034
1035   return error;
1036 }