Line | Count | Source |
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.89k | { |
46 | 1.89k | Cd *cd = NULL; |
47 | 1.89k | cd = malloc(sizeof(Cd)); |
48 | | |
49 | 1.89k | if(NULL == cd) { |
50 | 0 | fprintf(stderr, "unable to create cd\n"); |
51 | 1.89k | } else { |
52 | 1.89k | cd->mode = MODE_CD_DA; |
53 | 1.89k | cd->catalog = NULL; |
54 | 1.89k | cd->cdtextfile = NULL; |
55 | 1.89k | cd->cdtext = cdtext_init(); |
56 | 1.89k | cd->rem = rem_new(); |
57 | 1.89k | cd->ntrack = 0; |
58 | 1.89k | } |
59 | | |
60 | 1.89k | return cd; |
61 | 1.89k | } |
62 | | |
63 | | void track_delete(struct Track* track) |
64 | 3.77k | { |
65 | 3.77k | if (track != NULL) |
66 | 3.77k | { |
67 | 3.77k | cdtext_delete(track_get_cdtext(track)); |
68 | | |
69 | 3.77k | rem_free(track_get_rem(track)); |
70 | | |
71 | 3.77k | free(track->isrc); |
72 | | |
73 | 3.77k | free(track->zero_pre.name); |
74 | | |
75 | 3.77k | free(track->zero_post.name); |
76 | | |
77 | 3.77k | free(track->file.name); |
78 | | |
79 | 3.77k | free(track); |
80 | 3.77k | } |
81 | 3.77k | } |
82 | | |
83 | | void cd_delete(struct Cd* cd) |
84 | 2.92k | { |
85 | 2.92k | int i = 0; |
86 | | |
87 | 2.92k | if (cd != NULL) |
88 | 1.89k | { |
89 | 1.89k | free(cd->catalog); |
90 | | |
91 | 1.89k | free(cd->cdtextfile); |
92 | | |
93 | 5.67k | for (i = 0; i < cd->ntrack; i++) |
94 | 3.77k | track_delete(cd->track[i]); |
95 | | |
96 | 1.89k | cdtext_delete(cd_get_cdtext(cd)); |
97 | | |
98 | 1.89k | rem_free(cd_get_rem(cd)); |
99 | | |
100 | 1.89k | free(cd); |
101 | 1.89k | } |
102 | 2.92k | } |
103 | | |
104 | | Track *track_init(void) |
105 | 3.77k | { |
106 | 3.77k | Track *track = NULL; |
107 | 3.77k | track = malloc(sizeof(Track)); |
108 | | |
109 | 3.77k | if (NULL == track) { |
110 | 0 | fprintf(stderr, "unable to create track\n"); |
111 | 3.77k | } else { |
112 | 3.77k | track->zero_pre.type = DATA_ZERO; |
113 | 3.77k | track->zero_pre.name = NULL; |
114 | 3.77k | track->zero_pre.start = -1; |
115 | 3.77k | track->zero_pre.length = -1; |
116 | | |
117 | 3.77k | track->file.type = DATA_AUDIO; |
118 | 3.77k | track->file.name = NULL; |
119 | 3.77k | track->file.start = -1; |
120 | 3.77k | track->file.length = -1; |
121 | | |
122 | 3.77k | track->zero_post.type = DATA_ZERO; |
123 | 3.77k | track->zero_post.name = NULL; |
124 | 3.77k | track->zero_post.start = -1; |
125 | 3.77k | track->zero_post.length = -1; |
126 | | |
127 | 3.77k | track->mode = MODE_AUDIO; |
128 | 3.77k | track->sub_mode = SUB_MODE_RW; |
129 | 3.77k | track->flags = FLAG_NONE; |
130 | 3.77k | track->isrc = NULL; |
131 | 3.77k | track->cdtext = cdtext_init(); |
132 | 3.77k | track->rem = rem_new(); |
133 | | |
134 | 3.77k | int i; |
135 | 381k | for (i=0; i<=MAXINDEX; i++) |
136 | 377k | track->index[i] = -1; |
137 | 3.77k | } |
138 | | |
139 | 3.77k | return track; |
140 | 3.77k | } |
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 | 353 | { |
157 | 353 | free(cd->catalog); |
158 | 353 | cd->catalog = strdup(catalog); |
159 | 353 | } |
160 | | |
161 | | const char *cd_get_catalog(const Cd *cd) |
162 | 0 | { |
163 | 0 | return cd->catalog; |
164 | 0 | } |
165 | | |
166 | | void cd_set_cdtextfile(Cd *cd, char *cdtextfile) |
167 | 287 | { |
168 | 287 | free(cd->cdtextfile); |
169 | 287 | cd->cdtextfile = strdup(cdtextfile); |
170 | 287 | } |
171 | | |
172 | | const char *cd_get_cdtextfile(const Cd *cd) |
173 | 0 | { |
174 | 0 | return cd->cdtextfile; |
175 | 0 | } |
176 | | |
177 | | Cdtext *cd_get_cdtext(const Cd *cd) |
178 | 3.79k | { |
179 | 3.79k | if (cd != NULL) |
180 | 3.79k | return cd->cdtext; |
181 | 0 | else |
182 | 0 | return NULL; |
183 | 3.79k | } |
184 | | |
185 | | Rem* |
186 | | cd_get_rem(const Cd* cd) |
187 | 3.79k | { |
188 | 3.79k | if (cd != NULL) |
189 | 3.79k | return cd->rem; |
190 | 0 | else |
191 | 0 | return NULL; |
192 | 3.79k | } |
193 | | |
194 | | Track *cd_add_track(Cd *cd) |
195 | 4.26k | { |
196 | 4.26k | if (MAXTRACK > cd->ntrack) |
197 | 3.77k | cd->ntrack++; |
198 | 493 | else |
199 | 493 | { |
200 | 493 | fprintf(stderr, "too many tracks\n"); |
201 | 493 | return cd->track[cd->ntrack - 1]; |
202 | 493 | } |
203 | | |
204 | 3.77k | cd->track[cd->ntrack - 1] = track_init(); |
205 | | |
206 | 3.77k | return cd->track[cd->ntrack - 1]; |
207 | 4.26k | } |
208 | | |
209 | | int cd_get_ntrack(const Cd *cd) |
210 | 0 | { |
211 | 0 | return cd->ntrack; |
212 | 0 | } |
213 | | |
214 | | Track *cd_get_track(const Cd *cd, int i) |
215 | 0 | { |
216 | 0 | if ((0 < i) && (cd != NULL) && (i <= cd->ntrack)) |
217 | 0 | return cd->track[i - 1]; |
218 | 0 | else |
219 | 0 | return NULL; |
220 | 0 | } |
221 | | |
222 | | /* |
223 | | * track structure functions |
224 | | */ |
225 | | |
226 | | void track_set_filename(Track *track, char *filename) |
227 | 1.13k | { |
228 | 1.13k | free(track->file.name); |
229 | 1.13k | track->file.name = strdup(filename); |
230 | 1.13k | } |
231 | | |
232 | | const char *track_get_filename(const Track *track) |
233 | 0 | { |
234 | 0 | return track->file.name; |
235 | 0 | } |
236 | | |
237 | | void track_set_start(Track *track, long start) |
238 | 1.75k | { |
239 | 1.75k | track->file.start = start; |
240 | 1.75k | } |
241 | | |
242 | | long track_get_start(const Track *track) |
243 | 447 | { |
244 | 447 | return track->file.start; |
245 | 447 | } |
246 | | |
247 | | void track_set_length(Track *track, long length) |
248 | 447 | { |
249 | 447 | track->file.length = length; |
250 | 447 | } |
251 | | |
252 | | long track_get_length(const Track *track) |
253 | 1.56k | { |
254 | 1.56k | return track->file.length; |
255 | 1.56k | } |
256 | | |
257 | | void track_set_mode(Track *track, int mode) |
258 | 1.49k | { |
259 | 1.49k | track->mode = mode; |
260 | 1.49k | } |
261 | | |
262 | | enum TrackMode track_get_mode(const Track *track) |
263 | 0 | { |
264 | 0 | return track->mode; |
265 | 0 | } |
266 | | |
267 | | void track_set_sub_mode(Track *track, int sub_mode) |
268 | 0 | { |
269 | 0 | track->sub_mode = sub_mode; |
270 | 0 | } |
271 | | |
272 | | enum TrackSubMode track_get_sub_mode(const Track *track) |
273 | 0 | { |
274 | 0 | return track->sub_mode; |
275 | 0 | } |
276 | | |
277 | | void track_set_flag(Track *track, int flag) |
278 | 620 | { |
279 | 620 | track->flags |= flag; |
280 | 620 | } |
281 | | |
282 | | void track_clear_flag(Track *track, int flag) |
283 | 0 | { |
284 | 0 | track->flags &= ~flag; |
285 | 0 | } |
286 | | |
287 | | int track_is_set_flag(const Track *track, enum TrackFlag flag) |
288 | 0 | { |
289 | 0 | return track->flags & flag; |
290 | 0 | } |
291 | | |
292 | | void track_set_zero_pre(Track *track, long length) |
293 | 2.21k | { |
294 | 2.21k | track->zero_pre.length = length; |
295 | 2.21k | } |
296 | | |
297 | | long track_get_zero_pre(const Track *track) |
298 | 0 | { |
299 | 0 | return track->zero_pre.length; |
300 | 0 | } |
301 | | |
302 | | void track_set_zero_post(Track *track, long length) |
303 | 194 | { |
304 | 194 | track->zero_post.length = length; |
305 | 194 | } |
306 | | |
307 | | long track_get_zero_post(const Track *track) |
308 | 0 | { |
309 | 0 | return track->zero_post.length; |
310 | 0 | } |
311 | | void track_set_isrc(Track *track, char *isrc) |
312 | 194 | { |
313 | 194 | free(track->isrc); |
314 | 194 | track->isrc = strdup(isrc); |
315 | 194 | } |
316 | | |
317 | | const char *track_get_isrc(const Track *track) |
318 | 0 | { |
319 | 0 | return track->isrc; |
320 | 0 | } |
321 | | |
322 | | Cdtext *track_get_cdtext(const Track *track) |
323 | 8.04k | { |
324 | 8.04k | if (track != NULL) |
325 | 8.04k | return track->cdtext; |
326 | 0 | else |
327 | 0 | return NULL; |
328 | 8.04k | } |
329 | | |
330 | | Rem* |
331 | | track_get_rem(const Track* track) |
332 | 8.04k | { |
333 | 8.04k | if (track != NULL) |
334 | 8.04k | return track->rem; |
335 | 0 | else |
336 | 0 | return NULL; |
337 | 8.04k | } |
338 | | |
339 | | void track_set_index(Track *track, int i, long ind) |
340 | 3.52k | { |
341 | 3.52k | if (i < 0 || i > MAXINDEX) { |
342 | 877 | fprintf(stderr, "too many indexes\n"); |
343 | 877 | return; |
344 | 877 | } |
345 | | |
346 | 2.64k | track->index[i] = ind; |
347 | 2.64k | } |
348 | | |
349 | | long track_get_index(const Track *track, int i) |
350 | 2.54k | { |
351 | 2.54k | if ((0 <= i) && (i <= MAXINDEX)) |
352 | 2.54k | return track->index[i]; |
353 | | |
354 | 0 | return -1; |
355 | 2.54k | } |
356 | | |
357 | | /* |
358 | | * dump cd information |
359 | | */ |
360 | | static void cd_track_dump(Track *track) |
361 | 0 | { |
362 | 0 | int i; |
363 | |
|
364 | 0 | printf("zero_pre: %ld\n", track->zero_pre.length); |
365 | 0 | printf("filename: %s\n", track->file.name); |
366 | 0 | printf("start: %ld\n", track->file.start); |
367 | 0 | printf("length: %ld\n", track->file.length); |
368 | 0 | printf("zero_post: %ld\n", track->zero_post.length); |
369 | 0 | printf("mode: %d\n", track->mode); |
370 | 0 | printf("sub_mode: %d\n", track->sub_mode); |
371 | 0 | printf("flags: 0x%x\n", track->flags); |
372 | 0 | printf("isrc: %s\n", track->isrc); |
373 | |
|
374 | 0 | for (i = 0; i <= MAXINDEX; ++i) |
375 | 0 | if (track->index[i] != -1) |
376 | 0 | printf("index %d: %ld\n", i, track->index[i]); |
377 | |
|
378 | 0 | if (NULL != track->cdtext) { |
379 | 0 | printf("cdtext:\n"); |
380 | 0 | cdtext_dump(track->cdtext, 1); |
381 | 0 | } |
382 | |
|
383 | 0 | if (track->rem != NULL) |
384 | 0 | { |
385 | 0 | printf("rem:\n"); |
386 | 0 | rem_dump(track->rem); |
387 | 0 | } |
388 | 0 | } |
389 | | |
390 | | void cd_dump(Cd *cd) |
391 | 0 | { |
392 | 0 | int i; |
393 | |
|
394 | 0 | printf("Disc Info\n"); |
395 | 0 | printf("mode: %d\n", cd->mode); |
396 | 0 | printf("catalog: %s\n", cd->catalog); |
397 | 0 | printf("cdtextfile: %s\n", cd->cdtextfile); |
398 | 0 | if (NULL != cd->cdtext) { |
399 | 0 | printf("cdtext:\n"); |
400 | 0 | cdtext_dump(cd->cdtext, 0); |
401 | 0 | } |
402 | |
|
403 | 0 | if (cd->rem != NULL) |
404 | 0 | { |
405 | 0 | printf("rem:\n"); |
406 | 0 | rem_dump(cd->rem); |
407 | 0 | } |
408 | |
|
409 | 0 | for (i = 0; i < cd->ntrack; ++i) { |
410 | 0 | printf("Track %d Info\n", i + 1); |
411 | 0 | cd_track_dump(cd->track[i]); |
412 | 0 | } |
413 | 0 | } |