Parse more fields.
[jelmer/ptabtools.git] / ptbinfo.c
1 /*
2         (c) 2004: Jelmer Vernooij <jelmer@samba.org>
3
4         This program is free software; you can redistribute it and/or modify
5         it under the terms of the GNU General Public License as published by
6         the Free Software Foundation; either version 2 of the License, or
7         (at your option) any later version.
8
9         This program is distributed in the hope that it will be useful,
10         but WITHOUT ANY WARRANTY; without even the implied warranty of
11         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12         GNU General Public License for more details.
13
14         You should have received a copy of the GNU General Public License
15         along with this program; if not, write to the Free Software
16         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include <stdio.h>
20 #include <errno.h>
21 #include <popt.h>
22 #include "dlinklist.h"
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27
28 #ifdef HAVE_STDINT_H
29 #  include <stdint.h>
30 #endif
31
32 #include "ptb.h"
33
34 #define COND_PRINTF(desc,field) if(field) printf("%s: %s\n", desc, field);
35
36 #define PRINT_LIST(ls,t,fn) { t l = ls; while(l) { fn(l); l = l->next; } }
37
38
39 static const char *notenames[] = { "c", "cis", "d", "dis", "e", "f", "fis", "g", "gis", "a", "ais", "b" };
40
41 void write_musicbar(struct ptb_musicbar *mb)
42 {
43         printf("\t\tOffset: %d\n", mb->offset);
44         printf("\t\tProperties: %d\n", mb->properties);
45         printf("\t\tLetter: %c\n", mb->letter);
46         if (mb->description) printf("\t\tDescription: %s\n", mb->description);
47         printf("\n");
48 }
49
50 void write_linedata(struct ptb_linedata *ld)
51 {
52         printf("\t\t\t\tFret: %d, String: %d\n", ld->detailed.fret, ld->detailed.string);
53         if (ld->properties & LINEDATA_PROPERTY_TIE) printf("\t\t\t\tTie\n");
54         if (ld->properties & LINEDATA_PROPERTY_MUTED) printf("\t\t\t\tMuted\n");
55         if (ld->properties & LINEDATA_PROPERTY_CONTINUES) printf("\t\t\t\tContinues\n");
56         if (ld->properties & LINEDATA_PROPERTY_HAMMERON_FROM) printf("\t\t\t\tStart of hammer-on\n");
57         if (ld->properties & LINEDATA_PROPERTY_PULLOFF_FROM) printf("\t\t\t\tStart of pull-off\n");
58         if (ld->properties & LINEDATA_PROPERTY_DEST_NOWHERE) printf("\t\t\t\tDest-nowhere(?)\n");
59         if (ld->properties & LINEDATA_PROPERTY_NATURAL_HARMONIC) printf("\t\t\t\tNatural Harmonic\n");
60         if (ld->properties & LINEDATA_PROPERTY_GHOST_NOTE) printf("\t\t\t\tGhost Note\n");
61
62         if (ld->transcribe) {
63                 printf("\t\t\t\tTranscribed: ");
64                 if (ld->transcribe & LINEDATA_TRANSCRIBE_8VA) printf("8va ");
65                 if (ld->transcribe & LINEDATA_TRANSCRIBE_15MA) printf("15ma ");
66                 if (ld->transcribe & LINEDATA_TRANSCRIBE_8VB) printf("8vb ");
67                 if (ld->transcribe & LINEDATA_TRANSCRIBE_15MB) printf("15mb ");
68                 printf("\n");
69         }
70
71         printf("\n");
72 }
73
74 void write_position(struct ptb_position *pos)
75 {
76         printf("\t\t\tOffset: %d\n", pos->offset);
77         printf("\t\t\tLength: %d\n", pos->length);
78         printf("\t\t\t    Attached data:\n");
79         PRINT_LIST(pos->linedatas, struct ptb_linedata *, write_linedata);
80         printf("\n");
81 }
82
83 void write_staff(struct ptb_staff *staff)
84 {
85         printf("\t\tLowest Note Space: %d, Highest Note Space: %d\n", staff->lowest_note_space, staff->highest_note_space);
86         printf("\t\tSymbol Space: %d, Tablature Staff Space: %d\n", staff->symbol_space, staff->tab_staff_space);
87         printf("\t\tProperties: %d\n", staff->properties);
88
89         printf("\t\t    Positions:\n");
90         PRINT_LIST(staff->positions[0], struct ptb_position *, write_position);
91         PRINT_LIST(staff->positions[0], struct ptb_position *, write_position);
92         printf("\n");
93 }
94
95 void write_chordtext(struct ptb_chordtext *ct)
96 {
97         printf("\t\tName: %d(%s)/%d(%s)\n", ct->name[1], notenames[ct->name[1]-16],
98                    ct->name[0], notenames[ct->name[0]-16]);
99         printf("\t\tOffset: %d\n", ct->offset);
100         printf("\n");
101 }
102
103 void write_rhythmslash(struct ptb_rhythmslash *sl)
104 {
105         printf("\t\tOffset: %d\n", sl->offset);
106         printf("\t\tLength: %d\n", sl->length);
107         printf("\n");
108 }
109
110 void write_direction(struct ptb_direction *dr)
111 {
112         printf("\n");
113 }
114
115 void write_section(struct ptb_section *section)
116 {
117         printf("\tSection(%c): %s\n", section->letter, section->description);
118         printf("\tEnd-Mark: %d\n", section->end_mark);
119         printf("\tMeter Type: %d\n", section->meter_type);
120         printf("\tMetronome Pulses Per Measure: %d\n", section->metronome_pulses_per_measure);
121         printf("\tProperties: %d\n", section->properties);
122         printf("\tKey Extra: %d\n", section->key_extra);
123         printf("\tPosition Width: %d\n", section->position_width);
124
125         if (section->staffs) {
126                 printf("\t    Staffs:\n");
127                 PRINT_LIST(section->staffs, struct ptb_staff *, write_staff);
128         }
129
130         if (section->chordtexts) {
131                 printf("\t    Chordtexts:\n");
132                 PRINT_LIST(section->chordtexts, struct ptb_chordtext *, write_chordtext);
133         }
134
135         if (section->rhythmslashes) {
136                 printf("\t    Rhythmslashes:\n");
137                 PRINT_LIST(section->rhythmslashes, struct ptb_rhythmslash *, write_rhythmslash);
138         }
139
140         if (section->directions) {
141                 printf("\t    Directions:\n");
142                 PRINT_LIST(section->directions, struct ptb_direction *, write_direction);
143         }
144         
145         if (section->musicbars) {
146                 printf("\t    Music Bars:\n");
147                 PRINT_LIST(section->musicbars, struct ptb_musicbar *, write_musicbar);
148         }
149
150         printf("\n");
151 }
152
153 void write_sectionsymbol(struct ptb_sectionsymbol *ssb)
154 {
155         printf("\tData: %d\n", ssb->data);
156         printf("\n");
157 }
158
159 void write_tempomarker(struct ptb_tempomarker *tm)
160 {
161         printf("\tDescription: %s\n", tm->description);
162         printf("\tType: %d\n", tm->type);
163         printf("\tBPM: %d\n", tm->bpm);
164         printf("\tSection: %d\n", tm->section);
165         printf("\tOffset: %d\n", tm->offset);
166         printf("\n");
167 }
168
169 void write_dynamic(struct ptb_dynamic *dn)
170 {
171         printf("\tSection: %d\n", dn->section);
172         printf("\tPosition: %d\n", dn->position);
173         printf("\tStaff: %d\n", dn->staff);
174         printf("\tVolume: %d\n", dn->volume);
175         printf("\n");
176 }
177
178 void write_guitar(struct ptb_guitar *gtr)
179 {
180         int i;
181         printf("\tNumber: %d\n", gtr->index);
182         printf("\tTitle: %s\n", gtr->title);
183         printf("\tType: %s\n", gtr->type);
184         printf("\tStrings(%d):\n", gtr->nr_strings);
185         for (i = 0; i < gtr->nr_strings; i++) 
186                 printf("\t\t%s at octave %d (%d)\n", notenames[gtr->strings[i]%12], gtr->strings[i]/12, gtr->strings[i]);
187
188         printf("\tReverb: %d\n", gtr->reverb);
189         printf("\tChorus: %d\n", gtr->chorus);
190         printf("\tTremolo: %d\n", gtr->chorus);
191         printf("\tPan: %d\n", gtr->pan);
192         printf("\tCapo on fret: %d\n", gtr->capo);
193         printf("\tInitial volume: %d\n", gtr->initial_volume);
194         printf("\tMidi Instrument: %d\n", gtr->midi_instrument);
195         printf("\tHalf up(?): %d\n", gtr->half_up);
196         printf("\tSimulate (?): %d\n", gtr->simulate);
197         printf("\n");
198 }
199
200 void write_guitarin(struct ptb_guitarin *gtr)
201 {
202         printf("\tOffset: %d\n", gtr->offset);
203         printf("\tSection: %d\n", gtr->section);
204         printf("\tStaff: %d\n", gtr->staff);
205         printf("\tRhythmslash: %d\n", gtr->rhythm_slash);
206         printf("\tStaff In(?): %d\n", gtr->staff_in);
207         printf("\n");
208 }
209
210 void write_chorddiagram(struct ptb_chorddiagram *chd)
211 {
212         int i;
213         printf("\tName: %c%c\n", chd->name.name[0], chd->name.name[1]);
214         printf("\tType: %d\n", chd->name.type);
215         printf("\tFret Offset: %d\n", chd->frets);
216         printf("\tTones(%d): \n", chd->nr_strings);
217         for (i = 0; i < chd->nr_strings; i++) 
218                 printf("\t\t%d\n", chd->tones[i]);
219         printf("\n");
220 }
221
222 void write_font(struct ptb_font *font)
223 {
224         printf("%s, Size: %d, Weight: %d, Underlined: %d, Italic: %d", font->family, font->pointsize, font->weight, font->underlined, font->italic);
225 }
226
227 void write_floatingtext(struct ptb_floatingtext *ft)
228 {
229         printf("\tText: %s\n", ft->text);
230         printf("\tAlignment: ");
231         switch (ft->alignment & (ALIGN_LEFT|ALIGN_CENTER|ALIGN_RIGHT)) {
232         case ALIGN_LEFT: printf("Left");break;
233         case ALIGN_CENTER: printf("Center"); break;
234         case ALIGN_RIGHT: printf("Right"); break;
235         }
236         if (ft->alignment & ALIGN_BORDER) printf(", Print Border");
237         printf("\n");
238         printf("\tFont: "); write_font(&ft->font); printf("\n");
239         printf("\n");
240 }
241
242
243 void write_praudio_info(struct ptb_hdr *hdr)
244 {
245         printf("Audio Type: ");
246         switch(hdr->class_info.song.release_info.pr_audio.type)
247         { 
248         case AUDIO_TYPE_SINGLE: printf("Single\n"); break;
249         case AUDIO_TYPE_EP: printf("EP\n"); break;
250         case AUDIO_TYPE_ALBUM: printf("Album\n"); break;
251         case AUDIO_TYPE_DOUBLE_ALBUM: printf("Double Album\n"); break;
252         case AUDIO_TYPE_TRIPLE_ALBUM: printf("Triple Album\n"); break;
253         case AUDIO_TYPE_BOXSET: printf("Boxset\n"); break;
254         }
255         COND_PRINTF("Album Title", hdr->class_info.song.release_info.pr_audio.album_title);
256         printf("Year: %d\n", hdr->class_info.song.release_info.pr_audio.year);
257         printf("Live recording? %s\n", hdr->class_info.song.release_info.pr_audio.is_live_recording?"Yes":"No");
258 }
259
260 void write_prvideo_info(struct ptb_hdr *hdr)
261 {
262         COND_PRINTF("Video Title", hdr->class_info.song.release_info.pr_video.video_title);
263         printf("Year: %d\n", hdr->class_info.song.release_info.pr_video.year);
264         printf("Live recording? %s\n", hdr->class_info.song.release_info.pr_video.is_live_recording?"Yes":"No");
265 }
266
267 void write_bootleg_info(struct ptb_hdr *hdr)
268 {
269         COND_PRINTF("Bootleg Title", hdr->class_info.song.release_info.bootleg.title);
270         printf("Date: %d-%d-%d\n", 
271                    hdr->class_info.song.release_info.bootleg.day,
272                    hdr->class_info.song.release_info.bootleg.month,
273                    hdr->class_info.song.release_info.bootleg.year);
274 }
275
276 void write_song_info(struct ptb_hdr *hdr)
277 {
278         COND_PRINTF("Title", hdr->class_info.song.title);
279         COND_PRINTF("Artist", hdr->class_info.song.artist);
280         COND_PRINTF("Words By", hdr->class_info.song.words_by);
281         COND_PRINTF("Music By", hdr->class_info.song.music_by);
282         COND_PRINTF("Arranged By", hdr->class_info.song.arranged_by);
283         COND_PRINTF("Guitar Transcribed By", hdr->class_info.song.guitar_transcribed_by);
284         COND_PRINTF("Bass Transcribed By", hdr->class_info.song.bass_transcribed_by);
285         if(hdr->class_info.song.lyrics) 
286                 printf("Lyrics\n----------\n%s\n\n", hdr->class_info.song.lyrics);
287         COND_PRINTF("Copyright", hdr->class_info.song.copyright);
288
289         printf("Release type: ");
290         switch(hdr->class_info.song.release_type) {
291         case RELEASE_TYPE_PR_AUDIO:
292                 printf("Public Release (Audio)\n");
293                 write_praudio_info(hdr);
294                 break;
295         case RELEASE_TYPE_PR_VIDEO:
296                 printf("Public Release (Video)\n");
297                 write_prvideo_info(hdr);
298                 break;
299         case RELEASE_TYPE_BOOTLEG:
300                 printf("Bootleg\n");
301                 write_bootleg_info(hdr);
302                 break;
303         case RELEASE_TYPE_UNRELEASED:
304                 printf("Unreleased\n");
305                 break;
306         }
307 }
308
309 void write_lesson_info(struct ptb_hdr *hdr)
310 {
311         COND_PRINTF("Title", hdr->class_info.lesson.title);
312         COND_PRINTF("Artist", hdr->class_info.lesson.artist);
313         printf("Style: %d\n", hdr->class_info.lesson.style);
314         printf("Level: ");
315         switch(hdr->class_info.lesson.level) {
316         case LEVEL_BEGINNER: printf("Beginner"); break;
317         case LEVEL_INTERMEDIATE: printf("Intermediate"); break;
318         case LEVEL_ADVANCED: printf("Advanced"); break;
319         }
320         COND_PRINTF("Author", hdr->class_info.lesson.author);
321         COND_PRINTF("Copyright", hdr->class_info.lesson.copyright);
322 }
323
324 int main(int argc, const char **argv) 
325 {
326         struct ptbf *ret;
327         int tree = 0;
328         int debugging = 0;
329         int c, tmp1, tmp2;
330         int version = 0;
331         poptContext pc;
332         struct poptOption options[] = {
333                 POPT_AUTOHELP
334                 {"debug", 'd', POPT_ARG_NONE, &debugging, 0, "Turn on debugging output" },
335                 {"tree", 't', POPT_ARG_NONE, &tree, 't', "Print tree of PowerTab file" },
336                 {"version", 'v', POPT_ARG_NONE, &version, 'v', "Show version information" },
337                 POPT_TABLEEND
338         };
339
340         pc = poptGetContext(argv[0], argc, argv, options, 0);
341         poptSetOtherOptionHelp(pc, "file.ptb");
342         while((c = poptGetNextOpt(pc)) >= 0) {
343                 switch(c) {
344                 case 'v':
345                         printf("ptbinfo Version "PACKAGE_VERSION"\n");
346                         printf("(C) 2004 Jelmer Vernooij <jelmer@samba.org>\n");
347                         exit(0);
348                         break;
349                 }
350         }
351                         
352         ptb_set_debug(debugging);
353         ptb_set_asserts_fatal(0);
354         
355         if(!poptPeekArg(pc)) {
356                 poptPrintUsage(pc, stderr, 0);
357                 return -1;
358         }
359         ret = ptb_read_file(poptGetArg(pc));
360         
361         if(!ret) {
362                 perror("Read error: ");
363                 return -1;
364         } 
365
366         printf("File type: ");
367         switch(ret->hdr.classification) {
368         case CLASSIFICATION_SONG: 
369                 printf("Song\n");
370                 write_song_info(&ret->hdr);
371                 break;
372         case CLASSIFICATION_LESSON:
373                 printf("Lesson\n");
374                 write_lesson_info(&ret->hdr);
375                 break;
376         default: 
377                 printf("Unknown\n");
378                 break;
379         }
380
381         DLIST_LEN(ret->instrument[0].sections, tmp1, struct ptb_section *);
382         DLIST_LEN(ret->instrument[1].sections, tmp2, struct ptb_section *);
383         printf("Number of sections: \tRegular: %d Bass: %d\n", tmp1, tmp2);
384
385         DLIST_LEN(ret->instrument[0].guitars, tmp1, struct ptb_guitar *);
386         DLIST_LEN(ret->instrument[1].guitars, tmp2, struct ptb_guitar *);
387
388         printf("Number of guitars: \tRegular: %d Bass: %d\n", tmp1, tmp2);
389
390         if (tree) 
391         {
392                 int i;
393                 printf("\n");
394                 for (i = 0; i < 2; i++) {
395                         printf("\n");
396                         if (i == 0) printf("Guitar\n"); else printf("Bass\n");
397
398                         if (ret->instrument[i].guitars) {
399                                 printf("    Guitars:\n");
400                                 PRINT_LIST(ret->instrument[i].guitars, struct ptb_guitar *, write_guitar);
401                         }
402
403                         if (ret->instrument[i].guitarins) {
404                                 printf("    GuitarIns:\n");
405                                 PRINT_LIST(ret->instrument[i].guitarins, struct ptb_guitarin *, write_guitarin);
406                         }
407
408                         if (ret->instrument[i].chorddiagrams) {
409                                 printf("    Chord Diagrams:\n");
410                                 PRINT_LIST(ret->instrument[i].chorddiagrams, struct ptb_chorddiagram *, write_chorddiagram);
411                         }
412
413                         if (ret->instrument[i].tempomarkers) {
414                                 printf("    Tempo Markers:\n");
415                                 PRINT_LIST(ret->instrument[i].tempomarkers, struct ptb_tempomarker *, write_tempomarker);
416                         }
417
418                         if (ret->instrument[i].dynamics) {
419                                 printf("    Dynamics:\n");
420                                 PRINT_LIST(ret->instrument[i].dynamics, struct ptb_dynamic *, write_dynamic);
421                         }
422
423                         if (ret->instrument[i].floatingtexts) {
424                                 printf("    Floating Texts:\n");
425                                 PRINT_LIST(ret->instrument[i].floatingtexts, struct ptb_floatingtext *, write_floatingtext);
426                         }
427
428                         if (ret->instrument[i].sectionsymbols) {
429                                 printf("    Section Symbols:\n");
430                                 PRINT_LIST(ret->instrument[i].sectionsymbols, struct ptb_sectionsymbol *, write_sectionsymbol);
431                         }
432
433                         if (ret->instrument[i].sections) {
434                                 printf("    Sections:\n");
435                                 PRINT_LIST(ret->instrument[i].sections, struct ptb_section *, write_section);
436                         }
437                 }
438
439                 printf("Default Font: "); write_font(&ret->default_font); printf("\n");
440                 printf("Chord Name Font: "); write_font(&ret->chord_name_font); printf("\n");
441                 printf("Tablature Font: "); write_font(&ret->tablature_font); printf("\n");
442         }
443
444         ptb_free(ret);
445
446         return (ret?0:1);
447 }