1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5
6 #include "general.h"
7 #include "fileoutput.h"
8
9 /*
10
11 Ringtone Tools - Copyright 2001-2005 Michael Kohn (mike@mikekohn.net)
12 This falls under the Kohnian license. Please read
13 it at http://ringtonetools.mikekohn.net/
14
15 This program is NOT opensourced. You may not use any part
16 of this program for your own software.
17
18 */
19
20 int pushback=-1;
21
gettoken(FILE * fp,char * token,int flag)22 int gettoken(FILE *fp, char *token, int flag)
23 {
24 int tokentype;
25 int ptr,ch;
26
27 tokentype=0;
28 ptr=0;
29 token[0]=0;
30
31 while (1)
32 {
33 if (ptr>15) break;
34
35 if (pushback!=-1)
36 { ch=pushback; pushback=-1; }
37 else
38 { ch=getc(fp); }
39
40 if (flag==0)
41 { if ((ch==' ' || ch=='\t') || (ch=='\n' || ch=='\r')) continue; }
42 else
43 { if ((ch==' ' || ch=='\t' || ch=='\n' || ch=='\r') && ptr==0) continue; }
44
45 if (flag==2 && (ch<'0' || ch>'9'))
46 {
47 ungetc(ch,fp);
48 break;
49 }
50
51 if (ch==EOF && ptr==0) return -1;
52 else
53 if (ch==EOF) { pushback=ch; break; }
54
55 if ((ch>='A' && ch<='Z') || (ch>='a' && ch<='z'))
56 {
57 if (tokentype==1) { token[ptr++]=ch; }
58 else
59 if (ptr==0) { token[ptr++]=ch; tokentype=1; }
60 else
61 { pushback=ch; break; }
62 }
63 else
64 if (ch>='0' && ch<='9')
65 {
66 if (tokentype==2) { token[ptr++]=ch; }
67 else
68 if (ptr==0) { token[ptr++]=ch; tokentype=2; }
69 else
70 { pushback=ch; break; }
71 }
72 else
73 {
74 if (ptr==0)
75 {
76 tokentype=3;
77 token[ptr++]=ch;
78 break;
79 }
80 else
81 {
82 pushback=ch;
83 break;
84 }
85 }
86
87 }
88
89 token[ptr]=0;
90 return tokentype;
91 }
92
parse_rtttl(FILE * in,FILE * out,int out_type,struct note_t * note)93 int parse_rtttl(FILE *in, FILE *out, int out_type, struct note_t *note)
94 {
95 char token[16];
96 int t,r,l,ch;
97 int d,o,scale;
98 int length,tone,octave,modifier;
99
100 d=4;
101 o=6;
102 note->bpm=63;
103 tone=0;
104
105 scale=-1;
106
107 l=0;
108 t=0;
109 if (note->songname[0]!=0) t=1;
110 while(1)
111 {
112 ch=getc(in);
113 if (ch==':') break;
114 if (ch==EOF)
115 {
116 printf("Error: Illegal RTTTL format file\n");
117 return -1;
118 }
119
120 if (l<SONGNAME_LEN-1 && t==0) note->songname[l++]=ch;
121 }
122
123 if (t!=0) note->songname[l]=0;
124
125 #ifdef DEBUG
126 printf("\n Song Name: %s\n",note->songname);
127 #endif
128
129 r=0;
130 while(1)
131 {
132 if (gettoken(in,token,0)==-1)
133 {
134 printf("Error: Illegal RTTTL format file\n");
135 return -1;
136 }
137
138 if (r==0)
139 {
140 if (strcmp(token,",")==0) continue;
141 else
142 if (strcmp(token,":")==0) break;
143 else
144 if (strcasecmp(token,"d")==0) r=1;
145 else
146 if (strcasecmp(token,"o")==0) r=2;
147 else
148 if (strcasecmp(token,"b")==0) r=3;
149 else
150 if (strcasecmp(token,"s")==0) r=4;
151 else
152 if (strcasecmp(token,"l")==0) r=5;
153 }
154 else
155 if (strcmp(token,"=")==0)
156 {
157 gettoken(in,token,0);
158
159 if (r==1) d=atoi(token);
160 else
161 if (r==2) o=atoi(token);
162 else
163 if (r==3) note->bpm=atoi(token);
164 else
165 if (r==4)
166 {
167 if (strcasecmp(token,"n")==0)
168 { note->style=0; }
169 else
170 if (strcasecmp(token,"c")==0)
171 { note->style=1; }
172 else
173 if (strcasecmp(token,"s")==0)
174 { note->style=2; }
175 }
176 else
177 if (r==5) note->flats=atoi(token);
178 r=0;
179 }
180 else
181 {
182 printf("Error: Illegal format\n");
183 return -1;
184 }
185 }
186
187 if (note->flats==15) note->flats=31;
188
189 #ifdef DEBUG
190 printf("Default Duration: %d\n",d);
191 printf(" Default Scale: %d\n",o);
192 printf("Beats Per Minute: %d\n",note->bpm);
193 printf(" Style: ");
194 if (note->style==0) printf("Natural\n");
195 else
196 if (note->style==1) printf("Continuous\n");
197 else
198 if (note->style==2) printf("Staccato\n");
199 printf(" Loop: %d\n",note->flats);
200 #endif
201
202 header_route(out,note,0,out_type);
203
204 while(1)
205 {
206 t=gettoken(in,token,0);
207 if (t==-1)
208 { break; }
209
210 #ifdef DEBUG
211 printf("%s\n",token);
212 #endif
213 if (strcmp(token,";")==0) break;
214
215 length=d;
216
217 if (t==2)
218 {
219 length=atoi(token);
220 t=gettoken(in,token,0);
221 }
222
223 #ifdef DEBUG
224 printf("Length: %d\n",length);
225 #endif
226
227 if (length==1) length=0;
228 else
229 if (length==2) length=1;
230 else
231 if (length==4) length=2;
232 else
233 if (length==8) length=3;
234 else
235 if (length==16) length=4;
236 else
237 if (length==32) length=5;
238
239 token[0]=tolower(token[0]);
240
241 if (token[0]=='p') tone=0;
242 else
243 if (token[0]=='a') tone=10;
244 else
245 if (token[0]=='h' || token[0]=='b') tone=12;
246 else
247 if (token[0]=='c') tone=1;
248 else
249 if (token[0]=='d') tone=3;
250 else
251 if (token[0]=='e') tone=5;
252 else
253 if (token[0]=='f') tone=6;
254 else
255 if (token[0]=='g') tone=8;
256 else
257 if (token[0]=='o') tone=1;
258 else
259 if (token[0]=='s') tone=2;
260
261 #ifdef DEBUG
262 printf("tone: %d\n",tone);
263 #endif
264
265 t=gettoken(in,token,0);
266
267 if (token[0]=='=')
268 {
269 #ifdef DEBUG
270 printf("equals\n");
271 #endif
272 t=gettoken(in,token,0);
273 #ifdef DEBUG
274 printf("token: %s\n",token);
275 #endif
276
277 if (tone==12)
278 {
279 note->bpm=atoi(token);
280 tempo_route(out, note, 0, out_type);
281 }
282 else
283 if (tone==1)
284 {
285 o=atoi(token);
286 }
287 else
288 if (tone==2)
289 {
290 if (strcasecmp(token,"n")==0)
291 { note->style=0; }
292 else
293 if (strcasecmp(token,"c")==0)
294 { note->style=1; }
295 else
296 if (strcasecmp(token,"s")==0)
297 { note->style=2; }
298
299 if (out_type==4)
300 { write_nokia_style(out, note); }
301 }
302
303 t=gettoken(in,token,0);
304 if (strcmp(token,",")!=0)
305 {
306 printf("Error: expecting , and found %s\n",token);
307 }
308
309 continue;
310 }
311
312 modifier=0;
313 octave=-1;
314
315 while(1)
316 {
317 if (token[0]==',' || token[0]==';' || t==-1) break;
318
319 if (token[0]=='#')
320 { tone=tone+1; }
321 else
322 if (t==2)
323 { octave=atoi(token); }
324 else
325 if (strcmp(token,".")==0)
326 { modifier++; }
327
328 t=gettoken(in,token,0);
329 }
330
331 if (tone!=0)
332 {
333 if (octave==-1) octave=o;
334 if (tone>12)
335 {
336 tone=tone-12;
337 octave++;
338 }
339
340 if (scale!=octave)
341 {
342 scale=octave;
343 }
344 }
345
346 note->tone=tone;
347 note->length=length;
348 note->modifier=modifier;
349 note->scale=octave-note->a440;
350
351 note_route(out,note,0,out_type);
352
353 if (t==-1)
354 { break; }
355 }
356
357 footer_route(out,note,0,out_type);
358
359 return (0);
360 }
361
362
363
364