Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2004, 2005, 2006, 2007, Svend Sorensen |
3 | | * Copyright (c) 2009, 2010 Jochen Keil |
4 | | * For license terms, see the file COPYING in this distribution. |
5 | | */ |
6 | | |
7 | | #include <stdio.h> |
8 | | #include <stdlib.h> |
9 | | #include <string.h> |
10 | | #include "cd.h" |
11 | | |
12 | | typedef struct Data Data; |
13 | | struct Data { |
14 | | int type; /* DataType */ |
15 | | char *name; /* data source name */ |
16 | | long start; /* start time for data */ |
17 | | long length; /* length of data */ |
18 | | }; |
19 | | |
20 | | struct Track { |
21 | | Data zero_pre; /* pre-gap generated with zero data */ |
22 | | Data file; /* track data file */ |
23 | | Data zero_post; /* post-gap generated with zero data */ |
24 | | int mode; /* track mode */ |
25 | | int sub_mode; /* sub-channel mode */ |
26 | | int flags; /* flags */ |
27 | | char *isrc; /* IRSC Code (5.22.4) 12 bytes */ |
28 | | Cdtext *cdtext; /* CD-TEXT */ |
29 | | Rem* rem; |
30 | | long index[MAXINDEX+1]; /* indexes (in frames) (5.29.2.5) |
31 | | * relative to start of file */ |
32 | | }; |
33 | | |
34 | | struct Cd { |
35 | | int mode; /* disc mode */ |
36 | | char *catalog; /* Media Catalog Number (5.22.3) */ |
37 | | char *cdtextfile; /* Filename of CDText File */ |
38 | | Cdtext *cdtext; /* CD-TEXT */ |
39 | | Rem* rem; |
40 | | int ntrack; /* number of tracks in album */ |
41 | | Track *track[MAXTRACK]; /* array of tracks */ |
42 | | }; |
43 | | |
44 | | Cd *cd_init(void) |
45 | 1.87k | { |
46 | 1.87k | Cd *cd = NULL; |
47 | 1.87k | cd = malloc(sizeof(Cd)); |
48 | | |
49 | 1.87k | if(NULL == cd) { |
50 | 0 | fprintf(stderr, "unable to create cd\n"); |
51 | 1.87k | } else { |
52 | 1.87k | cd->mode = MODE_CD_DA; |
53 | 1.87k | cd->catalog = NULL; |
54 | 1.87k | cd->cdtextfile = NULL; |
55 | 1.87k | cd->cdtext = cdtext_init(); |
56 | 1.87k | cd->rem = rem_new(); |
57 | 1.87k | cd->ntrack = 0; |
58 | 1.87k | } |
59 | | |
60 | 1.87k | return cd; |
61 | 1.87k | } |
62 | | |
63 | | void track_delete(struct Track* track) |
64 | 4.12k | { |
65 | 4.12k | if (track != NULL) |
66 | 4.12k | { |
67 | 4.12k | cdtext_delete(track_get_cdtext(track)); |
68 | | |
69 | 4.12k | rem_free(track_get_rem(track)); |
70 | | |
71 | 4.12k | free(track->isrc); |
72 | | |
73 | 4.12k | free(track->zero_pre.name); |
74 | | |
75 | 4.12k | free(track->zero_post.name); |
76 | | |
77 | 4.12k | free(track->file.name); |
78 | | |
79 | 4.12k | free(track); |
80 | 4.12k | } |
81 | 4.12k | } |
82 | | |
83 | | void cd_delete(struct Cd* cd) |
84 | 2.89k | { |
85 | 2.89k | int i = 0; |
86 | | |
87 | 2.89k | if (cd != NULL) |
88 | 1.87k | { |
89 | 1.87k | free(cd->catalog); |
90 | | |
91 | 1.87k | free(cd->cdtextfile); |
92 | | |
93 | 5.99k | for (i = 0; i < cd->ntrack; i++) |
94 | 4.12k | track_delete(cd->track[i]); |
95 | | |
96 | 1.87k | cdtext_delete(cd_get_cdtext(cd)); |
97 | | |
98 | 1.87k | rem_free(cd_get_rem(cd)); |
99 | | |
100 | 1.87k | free(cd); |
101 | 1.87k | } |
102 | 2.89k | } |
103 | | |
104 | | Track *track_init(void) |
105 | 4.12k | { |
106 | 4.12k | Track *track = NULL; |
107 | 4.12k | track = malloc(sizeof(Track)); |
108 | | |
109 | 4.12k | if (NULL == track) { |
110 | 0 | fprintf(stderr, "unable to create track\n"); |
111 | 4.12k | } else { |
112 | 4.12k | track->zero_pre.type = DATA_ZERO; |
113 | 4.12k | track->zero_pre.name = NULL; |
114 | 4.12k | track->zero_pre.start = -1; |
115 | 4.12k | track->zero_pre.length = -1; |
116 | | |
117 | 4.12k | track->file.type = DATA_AUDIO; |
118 | 4.12k | track->file.name = NULL; |
119 | 4.12k | track->file.start = -1; |
120 | 4.12k | track->file.length = -1; |
121 | | |
122 | 4.12k | track->zero_post.type = DATA_ZERO; |
123 | 4.12k | track->zero_post.name = NULL; |
124 | 4.12k | track->zero_post.start = -1; |
125 | 4.12k | track->zero_post.length = -1; |
126 | | |
127 | 4.12k | track->mode = MODE_AUDIO; |
128 | 4.12k | track->sub_mode = SUB_MODE_RW; |
129 | 4.12k | track->flags = FLAG_NONE; |
130 | 4.12k | track->isrc = NULL; |
131 | 4.12k | track->cdtext = cdtext_init(); |
132 | 4.12k | track->rem = rem_new(); |
133 | | |
134 | 4.12k | int i; |
135 | 416k | for (i=0; i<=MAXINDEX; i++) |
136 | 412k | track->index[i] = -1; |
137 | 4.12k | } |
138 | | |
139 | 4.12k | return track; |
140 | 4.12k | } |
141 | | |
142 | | /* |
143 | | * cd structure functions |
144 | | */ |
145 | | void cd_set_mode(Cd *cd, int mode) |
146 | 0 | { |
147 | 0 | cd->mode = mode; |
148 | 0 | } |
149 | | |
150 | | enum DiscMode cd_get_mode(const Cd *cd) |
151 | 0 | { |
152 | 0 | return cd->mode; |
153 | 0 | } |
154 | | |
155 | | void cd_set_catalog(Cd *cd, char *catalog) |
156 | 481 | { |
157 | 481 | if (cd->catalog) |
158 | 462 | free(cd->catalog); |
159 | | |
160 | 481 | cd->catalog = strdup(catalog); |
161 | 481 | } |
162 | | |
163 | | void cd_set_cdtextfile(Cd *cd, char *cdtextfile) |
164 | 417 | { |
165 | 417 | if (cd->cdtextfile) |
166 | 399 | free(cd->cdtextfile); |
167 | | |
168 | 417 | cd->cdtextfile = strdup(cdtextfile); |
169 | 417 | } |
170 | | |
171 | | const char *cd_get_cdtextfile(const Cd *cd) |
172 | 0 | { |
173 | 0 | return cd->cdtextfile; |
174 | 0 | } |
175 | | |
176 | | Cdtext *cd_get_cdtext(const Cd *cd) |
177 | 3.75k | { |
178 | 3.75k | if (cd != NULL) |
179 | 3.75k | return cd->cdtext; |
180 | 0 | else |
181 | 0 | return NULL; |
182 | 3.75k | } |
183 | | |
184 | | Rem* |
185 | | cd_get_rem(const Cd* cd) |
186 | 3.75k | { |
187 | 3.75k | if (cd != NULL) |
188 | 3.75k | return cd->rem; |
189 | 0 | else |
190 | 0 | return NULL; |
191 | 3.75k | } |
192 | | |
193 | | Track *cd_add_track(Cd *cd) |
194 | 10.6k | { |
195 | 10.6k | if (MAXTRACK > cd->ntrack) |
196 | 4.12k | cd->ntrack++; |
197 | 6.49k | else |
198 | 6.49k | { |
199 | 6.49k | fprintf(stderr, "too many tracks\n"); |
200 | 6.49k | return cd->track[cd->ntrack - 1]; |
201 | 6.49k | } |
202 | | |
203 | 4.12k | cd->track[cd->ntrack - 1] = track_init(); |
204 | | |
205 | 4.12k | return cd->track[cd->ntrack - 1]; |
206 | 10.6k | } |
207 | | |
208 | | int cd_get_ntrack(const Cd *cd) |
209 | 0 | { |
210 | 0 | return cd->ntrack; |
211 | 0 | } |
212 | | |
213 | | Track *cd_get_track(const Cd *cd, int i) |
214 | 0 | { |
215 | 0 | if ((0 < i) && (i <= cd->ntrack) && (cd != NULL)) |
216 | 0 | return cd->track[i - 1]; |
217 | 0 | else |
218 | 0 | return NULL; |
219 | 0 | } |
220 | | |
221 | | /* |
222 | | * track structure functions |
223 | | */ |
224 | | |
225 | | void track_set_filename(Track *track, char *filename) |
226 | 7.75k | { |
227 | 7.75k | if (track->file.name) |
228 | 6.73k | free(track->file.name); |
229 | | |
230 | 7.75k | track->file.name = strdup(filename); |
231 | 7.75k | } |
232 | | |
233 | | const char *track_get_filename(const Track *track) |
234 | 0 | { |
235 | 0 | return track->file.name; |
236 | 0 | } |
237 | | |
238 | | void track_set_start(Track *track, long start) |
239 | 4.68k | { |
240 | 4.68k | track->file.start = start; |
241 | 4.68k | } |
242 | | |
243 | | long track_get_start(const Track *track) |
244 | 674 | { |
245 | 674 | return track->file.start; |
246 | 674 | } |
247 | | |
248 | | void track_set_length(Track *track, long length) |
249 | 674 | { |
250 | 674 | track->file.length = length; |
251 | 674 | } |
252 | | |
253 | | long track_get_length(const Track *track) |
254 | 1.68k | { |
255 | 1.68k | return track->file.length; |
256 | 1.68k | } |
257 | | |
258 | | void track_set_mode(Track *track, int mode) |
259 | 3.71k | { |
260 | 3.71k | track->mode = mode; |
261 | 3.71k | } |
262 | | |
263 | | enum TrackMode track_get_mode(const Track *track) |
264 | 0 | { |
265 | 0 | return track->mode; |
266 | 0 | } |
267 | | |
268 | | void track_set_sub_mode(Track *track, int sub_mode) |
269 | 0 | { |
270 | 0 | track->sub_mode = sub_mode; |
271 | 0 | } |
272 | | |
273 | | enum TrackSubMode track_get_sub_mode(const Track *track) |
274 | 0 | { |
275 | 0 | return track->sub_mode; |
276 | 0 | } |
277 | | |
278 | | void track_set_flag(Track *track, int flag) |
279 | 291 | { |
280 | 291 | track->flags |= flag; |
281 | 291 | } |
282 | | |
283 | | void track_clear_flag(Track *track, int flag) |
284 | 0 | { |
285 | 0 | track->flags &= ~flag; |
286 | 0 | } |
287 | | |
288 | | int track_is_set_flag(const Track *track, enum TrackFlag flag) |
289 | 0 | { |
290 | 0 | return track->flags & flag; |
291 | 0 | } |
292 | | |
293 | | void track_set_zero_pre(Track *track, long length) |
294 | 7.70k | { |
295 | 7.70k | track->zero_pre.length = length; |
296 | 7.70k | } |
297 | | |
298 | | long track_get_zero_pre(const Track *track) |
299 | 0 | { |
300 | 0 | return track->zero_pre.length; |
301 | 0 | } |
302 | | |
303 | | void track_set_zero_post(Track *track, long length) |
304 | 66 | { |
305 | 66 | track->zero_post.length = length; |
306 | 66 | } |
307 | | |
308 | | long track_get_zero_post(const Track *track) |
309 | 0 | { |
310 | 0 | return track->zero_post.length; |
311 | 0 | } |
312 | | void track_set_isrc(Track *track, char *isrc) |
313 | 643 | { |
314 | 643 | if (track->isrc) |
315 | 541 | free(track->isrc); |
316 | | |
317 | 643 | track->isrc = strdup(isrc); |
318 | 643 | } |
319 | | |
320 | | const char *track_get_isrc(const Track *track) |
321 | 0 | { |
322 | 0 | return track->isrc; |
323 | 0 | } |
324 | | |
325 | | Cdtext *track_get_cdtext(const Track *track) |
326 | 14.7k | { |
327 | 14.7k | if (track != NULL) |
328 | 14.7k | return track->cdtext; |
329 | 0 | else |
330 | 0 | return NULL; |
331 | 14.7k | } |
332 | | |
333 | | Rem* |
334 | | track_get_rem(const Track* track) |
335 | 14.7k | { |
336 | 14.7k | if (track != NULL) |
337 | 14.7k | return track->rem; |
338 | 0 | else |
339 | 0 | return NULL; |
340 | 14.7k | } |
341 | | |
342 | | void track_set_index(Track *track, int i, long ind) |
343 | 8.91k | { |
344 | 8.91k | if (i < 0 || i > MAXINDEX) { |
345 | 1.84k | fprintf(stderr, "too many indexes\n"); |
346 | 1.84k | return; |
347 | 1.84k | } |
348 | | |
349 | 7.07k | track->index[i] = ind; |
350 | 7.07k | } |
351 | | |
352 | | long track_get_index(const Track *track, int i) |
353 | 8.03k | { |
354 | 8.03k | if ((0 <= i) && (i <= MAXINDEX)) |
355 | 8.03k | return track->index[i]; |
356 | | |
357 | 0 | return -1; |
358 | 8.03k | } |
359 | | |
360 | | /* |
361 | | * dump cd information |
362 | | */ |
363 | | static void cd_track_dump(Track *track) |
364 | 0 | { |
365 | 0 | int i; |
366 | |
|
367 | 0 | printf("zero_pre: %ld\n", track->zero_pre.length); |
368 | 0 | printf("filename: %s\n", track->file.name); |
369 | 0 | printf("start: %ld\n", track->file.start); |
370 | 0 | printf("length: %ld\n", track->file.length); |
371 | 0 | printf("zero_post: %ld\n", track->zero_post.length); |
372 | 0 | printf("mode: %d\n", track->mode); |
373 | 0 | printf("sub_mode: %d\n", track->sub_mode); |
374 | 0 | printf("flags: 0x%x\n", track->flags); |
375 | 0 | printf("isrc: %s\n", track->isrc); |
376 | |
|
377 | 0 | for (i = 0; i <= MAXINDEX; ++i) |
378 | 0 | if (track->index[i] != -1) |
379 | 0 | printf("index %d: %ld\n", i, track->index[i]); |
380 | |
|
381 | 0 | if (NULL != track->cdtext) { |
382 | 0 | printf("cdtext:\n"); |
383 | 0 | cdtext_dump(track->cdtext, 1); |
384 | 0 | } |
385 | |
|
386 | 0 | if (track->rem != NULL) |
387 | 0 | { |
388 | 0 | printf("rem:\n"); |
389 | 0 | rem_dump(track->rem); |
390 | 0 | } |
391 | 0 | } |
392 | | |
393 | | void cd_dump(Cd *cd) |
394 | 0 | { |
395 | 0 | int i; |
396 | |
|
397 | 0 | printf("Disc Info\n"); |
398 | 0 | printf("mode: %d\n", cd->mode); |
399 | 0 | printf("catalog: %s\n", cd->catalog); |
400 | 0 | printf("cdtextfile: %s\n", cd->cdtextfile); |
401 | 0 | if (NULL != cd->cdtext) { |
402 | 0 | printf("cdtext:\n"); |
403 | 0 | cdtext_dump(cd->cdtext, 0); |
404 | 0 | } |
405 | |
|
406 | 0 | if (cd->rem != NULL) |
407 | 0 | { |
408 | 0 | printf("rem:\n"); |
409 | 0 | rem_dump(cd->rem); |
410 | 0 | } |
411 | |
|
412 | 0 | for (i = 0; i < cd->ntrack; ++i) { |
413 | 0 | printf("Track %d Info\n", i + 1); |
414 | 0 | cd_track_dump(cd->track[i]); |
415 | 0 | } |
416 | 0 | } |