1 /*
2 * cd.c -- cd functions
3 *
4 * Copyright (C) 2004, 2005, 2006, 2007, 2013 Svend Sorensen
5 * For license terms, see the file COPYING in this distribution.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "cd.h"
12
13 typedef struct Data Data;
14 struct Data {
15 int type; /* DataType */
16 char *name; /* data source name */
17 long start; /* start time for data */
18 long length; /* length of data */
19 };
20
21 struct Track {
22 Data zero_pre; /* pre-gap generated with zero data */
23 Data file; /* track data file */
24 Data zero_post; /* post-gap generated with zero data */
25 int mode; /* track mode */
26 int sub_mode; /* sub-channel mode */
27 int flags; /* flags */
28 char *isrc; /* IRSC Code (5.22.4) 12 bytes */
29 Cdtext *cdtext; /* CD-TEXT */
30 int nindex; /* number of indexes */
31 long index[MAXINDEX]; /* indexes (in frames) (5.29.2.5)
32 * relative to start of track
33 * index[0] should always be zero */
34 };
35
36 struct Cd {
37 int mode; /* disc mode */
38 char *catalog; /* Media Catalog Number (5.22.3) */
39 Cdtext *cdtext; /* CD-TEXT */
40 int ntrack; /* number of tracks in album */
41 Track *track[MAXTRACK]; /* array of tracks */
42 };
43
cd_init()44 Cd *cd_init()
45 {
46 Cd *cd = NULL;
47 cd = malloc(sizeof(Cd));
48
49 if(NULL == cd) {
50 fprintf(stderr, "unable to create cd\n");
51 } else {
52 cd->mode = MODE_CD_DA;
53 cd->catalog = NULL;
54 cd->cdtext = cdtext_init();
55 cd->ntrack = 0;
56 }
57
58 return cd;
59 }
60
track_init()61 Track *track_init()
62 {
63 Track *track = NULL;
64 track = malloc(sizeof(Track));
65
66 if (NULL == track) {
67 fprintf(stderr, "unable to create track\n");
68 } else {
69 track->zero_pre.type = DATA_ZERO;
70 track->zero_pre.name = NULL;
71 track->zero_pre.start = 0;
72 track->zero_pre.length = 0;
73
74 track->file.type = DATA_AUDIO;
75 track->file.name = NULL;
76 track->file.start = 0;
77 track->file.length = 0;
78
79 track->zero_post.type = DATA_ZERO;
80 track->zero_post.name = NULL;
81 track->zero_post.start = 0;
82 track->zero_post.length = 0;
83
84 track->mode = MODE_AUDIO;
85 track->sub_mode = SUB_MODE_RW;
86 track->flags = FLAG_NONE;
87 track->isrc = NULL;
88 track->cdtext = cdtext_init();
89 track->nindex = 0;
90 }
91
92 return track;
93 }
94
95 /*
96 * cd structure functions
97 */
cd_set_mode(Cd * cd,int mode)98 void cd_set_mode(Cd *cd, int mode)
99 {
100 cd->mode = mode;
101 }
102
cd_get_mode(Cd * cd)103 int cd_get_mode(Cd *cd)
104 {
105 return cd->mode;
106 }
107
cd_set_catalog(Cd * cd,char * catalog)108 void cd_set_catalog(Cd *cd, char *catalog)
109 {
110 if (cd->catalog) {
111 free(cd->catalog);
112 }
113
114 cd->catalog = strdup(catalog);
115 }
116
cd_get_catalog(Cd * cd)117 char *cd_get_catalog(Cd *cd)
118 {
119 return cd->catalog;
120 }
121
cd_get_cdtext(Cd * cd)122 Cdtext *cd_get_cdtext(Cd *cd)
123 {
124 return cd->cdtext;
125 }
126
cd_add_track(Cd * cd)127 Track *cd_add_track(Cd *cd)
128 {
129 if (MAXTRACK > cd->ntrack) {
130 cd->ntrack++;
131 } else {
132 fprintf(stderr, "too many tracks\n");
133 }
134
135 /* this will reinit last track if there were too many */
136 cd->track[cd->ntrack - 1] = track_init();
137
138 return cd->track[cd->ntrack - 1];
139 }
140
141
cd_get_ntrack(Cd * cd)142 int cd_get_ntrack(Cd *cd)
143 {
144 return cd->ntrack;
145 }
146
cd_get_track(Cd * cd,int i)147 Track *cd_get_track(Cd *cd, int i)
148 {
149 if (0 < i && i <= cd->ntrack) {
150 return cd->track[i - 1];
151 }
152
153 return NULL;
154 }
155
156 /*
157 * track structure functions
158 */
159
track_set_filename(Track * track,char * filename)160 void track_set_filename(Track *track, char *filename)
161 {
162 if (track->file.name) {
163 free(track->file.name);
164 }
165
166 track->file.name = strdup(filename);
167 }
168
track_get_filename(Track * track)169 char *track_get_filename(Track *track)
170 {
171 return track->file.name;
172 }
173
track_set_start(Track * track,long start)174 void track_set_start(Track *track, long start)
175 {
176 track->file.start = start;
177 }
178
track_get_start(Track * track)179 long track_get_start(Track *track)
180 {
181 return track->file.start;
182 }
183
track_set_length(Track * track,long length)184 void track_set_length(Track *track, long length)
185 {
186 track->file.length = length;
187 }
188
track_get_length(Track * track)189 long track_get_length(Track *track)
190 {
191 return track->file.length;
192 }
193
track_set_mode(Track * track,int mode)194 void track_set_mode(Track *track, int mode)
195 {
196 track->mode = mode;
197 }
198
track_get_mode(Track * track)199 int track_get_mode(Track *track)
200 {
201 return track->mode;
202 }
203
track_set_sub_mode(Track * track,int sub_mode)204 void track_set_sub_mode(Track *track, int sub_mode)
205 {
206 track->sub_mode = sub_mode;
207 }
208
track_get_sub_mode(Track * track)209 int track_get_sub_mode(Track *track)
210 {
211 return track->sub_mode;
212 }
213
track_set_flag(Track * track,int flag)214 void track_set_flag(Track *track, int flag)
215 {
216 track->flags |= flag;
217 }
218
track_clear_flag(Track * track,int flag)219 void track_clear_flag(Track *track, int flag)
220 {
221 track->flags &= ~flag;
222 }
223
track_is_set_flag(Track * track,int flag)224 int track_is_set_flag(Track *track, int flag)
225 {
226 return track->flags & flag;
227 }
228
track_set_zero_pre(Track * track,long length)229 void track_set_zero_pre(Track *track, long length)
230 {
231 track->zero_pre.length = length;
232 }
233
track_get_zero_pre(Track * track)234 long track_get_zero_pre(Track *track)
235 {
236 return track->zero_pre.length;
237 }
238
track_set_zero_post(Track * track,long length)239 void track_set_zero_post(Track *track, long length)
240 {
241 track->zero_post.length = length;
242 }
243
track_get_zero_post(Track * track)244 long track_get_zero_post(Track *track)
245 {
246 return track->zero_post.length;
247 }
track_set_isrc(Track * track,char * isrc)248 void track_set_isrc(Track *track, char *isrc)
249 {
250 if (track->isrc) {
251 free(track->isrc);
252 }
253
254 track->isrc = strdup(isrc);
255 }
256
track_get_isrc(Track * track)257 char *track_get_isrc(Track *track)
258 {
259 return track->isrc;
260 }
261
track_get_cdtext(Track * track)262 Cdtext *track_get_cdtext(Track *track)
263 {
264 return track->cdtext;
265 }
266
track_add_index(Track * track,long index)267 void track_add_index(Track *track, long index)
268 {
269 if (MAXINDEX > track->nindex) {
270 track->nindex++;
271 } else {
272 fprintf(stderr, "too many indexes\n");
273 }
274
275 /* this will overwrite last index if there were too many */
276 track->index[track->nindex - 1] = index;
277 }
278
track_get_nindex(Track * track)279 int track_get_nindex(Track *track)
280 {
281 return track->nindex;
282 }
283
track_get_index(Track * track,int i)284 long track_get_index(Track *track, int i)
285 {
286 if (0 <= i && i < track->nindex) {
287 return track->index[i];
288 }
289
290 return -1;
291 }
292
293 /*
294 * dump cd information
295 */
cd_track_dump(Track * track)296 void cd_track_dump(Track *track)
297 {
298 int i;
299
300 printf("zero_pre: %ld\n", track->zero_pre.length);
301 printf("filename: %s\n", track->file.name);
302 printf("start: %ld\n", track->file.start);
303 printf("length: %ld\n", track->file.length);
304 printf("zero_post: %ld\n", track->zero_post.length);
305 printf("mode: %d\n", track->mode);
306 printf("sub_mode: %d\n", track->sub_mode);
307 printf("flags: 0x%x\n", track->flags);
308 printf("isrc: %s\n", track->isrc);
309 printf("indexes: %d\n", track->nindex);
310
311 for (i = 0; i < track->nindex; ++i) {
312 printf("index %d: %ld\n", i, track->index[i]);
313 }
314
315 if (NULL != track->cdtext) {
316 printf("cdtext:\n");
317 cdtext_dump(track->cdtext, 1);
318 }
319 }
320
cd_dump(Cd * cd)321 void cd_dump(Cd *cd)
322 {
323 int i;
324
325 printf("Disc Info\n");
326 printf("mode: %d\n", cd->mode);
327 printf("catalog: %s\n", cd->catalog);
328 if (NULL != cd->cdtext) {
329 printf("cdtext:\n");
330 cdtext_dump(cd->cdtext, 0);
331 }
332
333 for (i = 0; i < cd->ntrack; ++i) {
334 printf("Track %d Info\n", i + 1);
335 cd_track_dump(cd->track[i]);
336 }
337 }
338