Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / icedax / inf2cdtext.pl
1 #!/usr/bin/perl -w
2 # Copyright 2002 by Heiko Eißfeldt (Eissfeldt)
3 use strict;
4 use integer;
5
6 # read all .inf files and generate the binary cdtext block
7 # for cdrecord.
8
9 my @results;
10
11 sub fill_packet
12 {
13         my $ID = shift;
14         my $track = shift;
15         my $seq_nr = shift;
16         my $charpos = shift;
17         my $text = shift;
18         my $todo = shift;
19
20         return if (!defined($$text));
21
22         my @packet = ();
23         push @packet, chr($ID); # track title, performer, ...
24         push @packet, chr($$track);
25         push @packet, chr($$seq_nr);
26         $$charpos = 15 if ($$charpos > 15);
27         push @packet, chr($$charpos);
28
29         my $cp = 0;
30         my $tracks_inp = 0;
31         while (length($$text) + 1 < 12 - $cp) {
32                 push @packet, split(//, $$text);
33                 push @packet, chr(0);
34                 $cp += length($$text) + 1;
35                 $$charpos = 0;
36                 $tracks_inp++;
37
38                 $$text = shift @$todo;
39                 if ($#$todo < 1 && (!defined($$text) || $$text eq "") ) {
40                         push @packet, (chr(0)) x (12 - $cp);
41                         $$seq_nr++;
42                         print_packet(@packet);
43                         return;
44                 }
45                 $$text = "" if (!defined($$text));
46                 $$track++;
47         }
48
49         # packet gets full
50         my $left = 12 - $cp;
51         if ($left > length($$text)) {
52                 # title fits into packet
53                 push @packet, split(//, $$text);
54                 push @packet, chr(0);
55                 $tracks_inp++;
56                 print_packet(@packet);
57
58                 $$charpos = 0;
59                 $$text = shift @$todo;
60                 unless ((!defined($$text) || $$text eq "") && $#$todo < 1) { $$track++; }
61                 $$seq_nr++;
62         } else {
63                 # print current packet and more if more entries are present
64                 push @packet, split(//, substr($$text, 0, $left));
65                 print_packet(@packet);
66
67                 $$text = substr($$text, $left);
68                 $$charpos += $left;
69                 $$seq_nr++;
70         }
71 }
72
73 my @crctab =(
74     0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
75     0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
76     0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
77     0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
78     0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
79     0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
80     0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
81     0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
82     0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
83     0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
84     0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
85     0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
86     0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
87     0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
88     0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
89     0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
90     0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
91     0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
92     0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
93     0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
94     0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
95     0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
96     0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
97     0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
98     0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
99     0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
100     0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
101     0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
102     0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
103     0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
104     0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
105     0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0,
106 );
107
108 sub add_crc
109 {
110         # crc with polynomial: x^16 + x^12 + x^5 + 1
111         # 1,0001,0000,0010,0001
112         my $packref = shift;
113         my $crc = 0;
114
115         foreach (@$packref) {
116                 $crc = ($crc << 8) ^ $crctab[
117                                         ( ($crc >> (16-8)) ^ ord($_) ) & 0xff
118                                         ];
119                 $crc &= 0xffff;
120         }
121         $$packref[16] = chr((($crc >> 8) & 0xff) ^ 0xff);
122         $$packref[17] = chr(($crc & 0xff) ^ 0xff);
123 }
124
125 sub print_packet
126 {
127         return if ($#_ < 1);
128         my @packet = (@_);
129         add_crc(\@packet);
130         if ($packet[0] ne chr(0x8f)) {
131                 printf STDERR ("%02x "x4 ." "."%c "x12 ." "."%02x "x2), map( defined($_) ? ord($_) : "___undef", @packet );
132         } else {
133                 printf STDERR ("%02x "x4 ." "."%02x "x12 ." "."%02x "x2), map( defined($_) ? ord($_) : "___undef", @packet );
134         }
135         printf STDERR "\n";
136         push @results, @packet;
137 }
138
139 my $defaultperformer = $ARGV[0] || die "usage: ", $^X, " defaultperformer_name\n";
140 my $prefix = $ARGV[1] || "audio";
141 @ARGV = glob("${prefix}_??.inf");
142 my @albumtitles;
143 my @tracktitles;
144 my @performers;
145 my $ISRC;
146 my @ISRCs;
147 my $MCN;
148
149 my $performer;
150 while (<>) {
151         if (/^Performer=\s+'(.*?)'$/) {
152                 $performer = $1;
153         }
154         if (/^Albumtitle=\s+'(.*?)'$/) {
155                 push @albumtitles, $1;
156         }
157         if (/^Tracktitle=\s+'(.*?)'$/) {
158                 push @tracktitles, $1;
159         }
160         if (/^ISRC=\s+(\S+?)$/) {
161                 $ISRC = $1;
162         }
163         if (/^MCN=\s+(\S+?)$/) {
164                 $MCN = $1;
165         }
166         if (eof) {
167                 close ARGV;
168                 $performer = $defaultperformer if (!defined($performer));
169                 push @performers, $performer;
170                 $performer = undef;
171                 push @ISRCs, $ISRC;
172                 $ISRC = undef;
173         }
174 }
175
176 #
177 my $seq_nr = 0;
178
179 my @todo;
180 my $text;
181 my $track;
182 my $charpos;
183
184 # build cdtext packets
185
186 # build track titles
187 @todo = ($albumtitles[0], @tracktitles);
188 $text = shift @todo;
189 $track = 0;
190 $charpos = 0;
191
192 while ($#todo > 1 || defined($text)) {
193         fill_packet(0x80, \$track, \$seq_nr, \$charpos, \$text, \@todo);
194 }
195
196 my $trackpacks = $seq_nr;       # store for later reference
197 my $last_track = $track;
198
199 # build performer entries
200 #@todo = ($performer) x (1 + scalar(@tracktitles));
201 @todo = ($defaultperformer, @performers);
202 $text = shift @todo;
203 $track = 0;
204 $charpos = 0;
205
206 while ($#todo > 1 || defined($text)) {
207         fill_packet(0x81, \$track, \$seq_nr, \$charpos, \$text, \@todo);
208 }
209
210 my $perfpacks = $seq_nr - $trackpacks;  # store for later reference
211
212 # build ISRC entries
213 @todo = ($MCN, @ISRCs);
214 $text = shift @todo;
215 $track = 0;
216 $charpos = 0;
217
218 while ($#todo > 1 || defined($text)) {
219         $text = "" if (!defined($text));
220         fill_packet(0x8e, \$track, \$seq_nr, \$charpos, \$text, \@todo);
221 }
222
223 my $isrcpacks = $seq_nr - $trackpacks - $perfpacks;     # store for later reference
224
225 # build size information blocks
226 my $size1 = chr(0) . chr(1) . chr($last_track) . chr(0)
227          . chr($trackpacks) . chr($perfpacks) . chr(0) x 5;
228 my $size2 = chr(0) x 6 . chr($isrcpacks) . chr(3) . chr($seq_nr+2) . chr(0) x 2;
229 my $size3 = chr(0) x 4 . chr(9);        # hard coded language 09 = english
230 @todo = ($size1, $size2, $size3);
231 $text = shift @todo;
232 $track = 0;
233 $charpos = 0;
234
235 while ((defined($text) && $text ne "") ) {
236         fill_packet(0x8f, \$track, \$seq_nr, \$charpos, \$text, \@todo);
237 }
238
239 # write out the results
240 my $size = @results + 2;
241 print chr($size >> 8), chr($size & 0xff), chr(0), chr(0), @results;