rb_cdio 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. data/ChangeLog.txt +17 -2
  2. data/VERSION +1 -1
  3. data/doc/classes/CdIo.html +19 -31
  4. data/doc/classes/CdIo.src/M000001.html +1 -1
  5. data/doc/classes/CdIo.src/M000002.html +1 -1
  6. data/doc/classes/CdIo.src/M000003.html +1 -1
  7. data/doc/classes/CdIo.src/M000004.html +1 -1
  8. data/doc/classes/CdIo.src/M000005.html +1 -1
  9. data/doc/classes/CdIo.src/M000006.html +1 -1
  10. data/doc/classes/CdIo.src/M000007.html +1 -1
  11. data/doc/classes/CdIo.src/M000008.html +1 -1
  12. data/doc/classes/CdIo/Cd.html +51 -51
  13. data/doc/classes/CdIo/Cd.src/{M000011.html → M000020.html} +1 -1
  14. data/doc/classes/CdIo/Cd.src/M000021.html +3 -3
  15. data/doc/classes/CdIo/Cd.src/M000022.html +3 -3
  16. data/doc/classes/CdIo/Cd.src/M000023.html +3 -3
  17. data/doc/classes/CdIo/Cd.src/M000024.html +3 -3
  18. data/doc/classes/CdIo/Cd.src/M000025.html +3 -3
  19. data/doc/classes/CdIo/Cd.src/M000026.html +3 -3
  20. data/doc/classes/CdIo/Cd.src/M000027.html +3 -3
  21. data/doc/classes/CdIo/Cd.src/M000028.html +3 -3
  22. data/doc/classes/CdIo/Cd.src/M000029.html +3 -3
  23. data/doc/classes/CdIo/Cd.src/M000030.html +3 -3
  24. data/doc/classes/CdIo/Cd.src/M000031.html +3 -3
  25. data/doc/classes/CdIo/Cd.src/M000032.html +3 -3
  26. data/doc/classes/CdIo/Cd.src/M000033.html +3 -3
  27. data/doc/classes/CdIo/Cd.src/M000034.html +3 -3
  28. data/doc/classes/CdIo/Cd.src/M000035.html +3 -3
  29. data/doc/classes/CdIo/Cdda.html +428 -0
  30. data/doc/classes/CdIo/{Cd.src/M000016.html → Cdda.src/M000009.html} +3 -3
  31. data/doc/classes/CdIo/{Cd.src/M000013.html → Cdda.src/M000010.html} +3 -3
  32. data/doc/classes/CdIo/{Cd.src/M000036.html → Cdda.src/M000011.html} +3 -3
  33. data/doc/classes/CdIo/{Cd.src/M000014.html → Cdda.src/M000012.html} +3 -3
  34. data/doc/classes/CdIo/Cdda.src/M000013.html +17 -0
  35. data/doc/classes/CdIo/{Cd.src/M000019.html → Cdda.src/M000014.html} +3 -3
  36. data/doc/classes/CdIo/Cdda.src/M000015.html +17 -0
  37. data/doc/classes/CdIo/Cdda.src/M000016.html +17 -0
  38. data/doc/classes/CdIo/Cdda.src/M000017.html +17 -0
  39. data/doc/classes/CdIo/Cdda.src/M000018.html +17 -0
  40. data/doc/classes/CdIo/Cdda.src/M000019.html +17 -0
  41. data/doc/classes/CdIo/{Cd.src/M000015.html → Cdda.src/M000020.html} +3 -3
  42. data/doc/classes/CdIo/{Cd.src/M000017.html → Cdda.src/M000021.html} +3 -3
  43. data/doc/classes/CdIo/{Cd.src/M000018.html → Cdda.src/M000022.html} +3 -3
  44. data/doc/classes/CdIo/Cdda.src/M000023.html +17 -0
  45. data/doc/classes/CdIo/Cdda.src/M000024.html +17 -0
  46. data/doc/classes/CdIo/Exception.html +118 -0
  47. data/doc/classes/CdIo/Exception/BadParameter.html +111 -0
  48. data/doc/classes/CdIo/Exception/BadPointer.html +111 -0
  49. data/doc/classes/CdIo/{Device.html → Exception/CddbConn.html} +5 -5
  50. data/doc/classes/CdIo/Exception/CddbError.html +111 -0
  51. data/doc/classes/CdIo/{CdText.html → Exception/Error.html} +5 -5
  52. data/doc/{files/test/testall_rb.html → classes/CdIo/Exception/NoDriver.html} +26 -25
  53. data/doc/classes/CdIo/Exception/NotPermitted.html +111 -0
  54. data/doc/classes/CdIo/Exception/Unsupported.html +111 -0
  55. data/doc/classes/CdIo/Track.html +16 -16
  56. data/doc/classes/CdIo/Track.src/M000017.html +3 -3
  57. data/doc/classes/CdIo/Track.src/M000018.html +3 -3
  58. data/doc/classes/CdIo/Track.src/M000019.html +3 -3
  59. data/doc/classes/CdIo/Track.src/{M000009.html → M000025.html} +1 -1
  60. data/doc/classes/CdIo/Track.src/{M000010.html → M000026.html} +1 -1
  61. data/doc/classes/CdIo/Track.src/{M000011.html → M000027.html} +1 -1
  62. data/doc/classes/CdIo/TrackCdda.html +169 -0
  63. data/doc/classes/CdIo/TrackCdda.src/M000031.html +17 -0
  64. data/doc/classes/CdIo/TrackCdda.src/M000039.html +17 -0
  65. data/doc/classes/CdIo/TrackCdda.src/M000040.html +17 -0
  66. data/doc/classes/CdIo/TrackCdda.src/M000041.html +17 -0
  67. data/doc/classes/CdIo/Tracks.html +15 -15
  68. data/doc/classes/CdIo/Tracks.src/{M000020.html → M000028.html} +1 -1
  69. data/doc/classes/CdIo/Tracks.src/{M000021.html → M000029.html} +1 -1
  70. data/doc/classes/CdIo/Tracks.src/{M000022.html → M000030.html} +1 -1
  71. data/doc/classes/CdIo/{Cd.src/M000012.html → Tracks.src/M000036.html} +3 -3
  72. data/doc/classes/CdIo/Tracks.src/M000037.html +17 -0
  73. data/doc/classes/CdIo/Tracks.src/M000038.html +17 -0
  74. data/doc/created.rid +1 -1
  75. data/doc/files/__/rb_cdio_def_rb.html +235 -0
  76. data/doc/files/rb_cdio_def_rb.html +80 -5
  77. data/doc/fr_class_index.html +11 -0
  78. data/doc/fr_method_index.html +33 -14
  79. data/ext/CdIo.c +58 -3
  80. data/ext/CdIo.h +74 -1
  81. data/ext/CdIo_Cd.c +33 -80
  82. data/ext/CdIo_Cdda.c +607 -0
  83. data/ext/CdIo_Common.c +53 -8
  84. data/ext/CdIo_Modulo.c +12 -4
  85. data/ext/CdIo_Track.c +23 -35
  86. data/ext/CdIo_TrackCdda.c +13 -0
  87. data/ext/CdIo_TrackIso9660.c +1 -9
  88. data/ext/CdIo_Tracks.c +12 -2
  89. data/ext/extconf.rb +3 -0
  90. data/ext/mkmf.log +23 -0
  91. data/lib/rb_cdio_read.rb +23 -14
  92. data/rb_cdio.def.rb +157 -16
  93. data/test/data/bad-file.toc +13 -0
  94. data/test/data/cdda-read.right +3 -0
  95. data/test/data/cdda.cue +1 -0
  96. data/test/data/cdda.right +5 -28
  97. data/test/data/cdda.toc +2 -1
  98. data/test/data/check_common_fn +9 -9
  99. data/test/data/check_common_fn.in +9 -9
  100. data/test/data/check_cue.sh.in +35 -20
  101. data/test/data/check_iso.sh.in +23 -3
  102. data/test/data/check_nrg.sh.in +18 -16
  103. data/test/data/check_opts0.right +2 -24
  104. data/test/data/check_opts1.right +2 -24
  105. data/test/data/check_opts2.right +5 -27
  106. data/test/data/check_opts3.right +5 -27
  107. data/test/data/check_opts4.right +5 -27
  108. data/test/data/check_opts5.right +5 -27
  109. data/test/data/check_opts6.right +5 -27
  110. data/test/data/check_opts7.right +5 -27
  111. data/test/data/check_paranoia.sh.in +78 -0
  112. data/test/data/check_sizeof.c +5 -5
  113. data/test/data/copying-rr.iso +0 -0
  114. data/test/data/copying-rr.right +25 -0
  115. data/test/data/copying.right +3 -3
  116. data/test/data/data5.toc +3 -3
  117. data/test/data/data6.toc +2 -2
  118. data/test/data/data7.toc +3 -3
  119. data/test/data/isofs-m1-no-rr.right +33 -0
  120. data/test/data/isofs-m1-read.right +3 -0
  121. data/test/data/isofs-m1.right +12 -36
  122. data/test/data/joliet-nojoliet.right +23 -0
  123. data/test/data/joliet.iso +0 -0
  124. data/test/data/joliet.right +23 -0
  125. data/test/data/testbincue.c +19 -3
  126. data/test/data/testdefault.c +8 -2
  127. data/test/data/testiso9660.c +10 -5
  128. data/test/data/testparanoia.c +185 -0
  129. data/test/data/testtoc.c +18 -5
  130. data/test/data/vcd2.toc +23 -0
  131. data/test/data/vcd_demo.right +55 -79
  132. data/test/data/vcd_demo_vcdinfo.right +97 -0
  133. data/test/data/videocd.right +37 -61
  134. data/test/test_cdda.rb +73 -0
  135. data/test/testall.rb +1 -0
  136. data/test/testbincue.rb +6 -1
  137. data/test/testclose.rb +6 -1
  138. data/test/testmethods.rb +29 -21
  139. data/test/testtoc.rb +9 -2
  140. metadata +137 -80
  141. data/doc/classes/CdIo.src/M000009.html +0 -17
  142. data/doc/classes/CdIo.src/M000010.html +0 -17
  143. data/doc/classes/CdIo.src/M000011.html +0 -17
  144. data/doc/classes/CdIo.src/M000012.html +0 -17
  145. data/doc/classes/CdIo.src/M000013.html +0 -17
  146. data/doc/classes/CdIo.src/M000014.html +0 -17
  147. data/doc/classes/CdIo.src/M000015.html +0 -17
  148. data/doc/classes/CdIo.src/M000016.html +0 -17
  149. data/doc/classes/CdIo/Track.src/M000020.html +0 -17
  150. data/test/data/check_cd_read.sh +0 -53
  151. data/test/data/check_cue.sh +0 -102
  152. data/test/data/check_iso.sh +0 -32
  153. data/test/data/check_nrg.sh +0 -68
  154. data/test/data/check_opts.sh +0 -33
@@ -0,0 +1,607 @@
1
+ #include "CdIo.h"
2
+
3
+ #define GET_SUB(p,s) \
4
+ cdio_subchannel_t sub; \
5
+ verify_return_code(cdio_audio_read_subchannel(p_cdio, &sub));
6
+ /**
7
+ * CDDB
8
+ * Extraido desde cd-info.
9
+ **/
10
+
11
+ static int
12
+ cddb_dec_digit_sum(int n)
13
+ {
14
+ int ret = 0;
15
+
16
+ for (;;) {
17
+ ret += n % 10;
18
+ n = n / 10;
19
+ if (!n)
20
+ return ret;
21
+ }
22
+ }
23
+
24
+ /*
25
+ * Return the number of seconds (discarding frame portion) of an MSF
26
+ */
27
+ static inline unsigned int
28
+ msf_seconds(msf_t * msf)
29
+ {
30
+ return cdio_from_bcd8(msf->m) * 60 + cdio_from_bcd8(msf->s);
31
+ }
32
+
33
+ static unsigned long
34
+ cddb_discid(CdIo * p_cdio, int i_tracks)
35
+ {
36
+ int i,
37
+ t,
38
+ n = 0;
39
+ msf_t start_msf;
40
+ msf_t msf;
41
+
42
+ for (i = 1; i <= i_tracks; i++) {
43
+ cdio_get_track_msf(p_cdio, i, &msf);
44
+ n += cddb_dec_digit_sum(msf_seconds(&msf));
45
+ }
46
+
47
+ cdio_get_track_msf(p_cdio, 1, &start_msf);
48
+ cdio_get_track_msf(p_cdio, CDIO_CDROM_LEADOUT_TRACK, &msf);
49
+
50
+ t = msf_seconds(&msf) - msf_seconds(&start_msf);
51
+
52
+ return ((n % 0xff) << 24 | t << 8 | i_tracks);
53
+ }
54
+
55
+ static cddb_disc_t *
56
+ cd_create(int dlength, int tcount, int *foffset, int use_time)
57
+ {
58
+ int i;
59
+ cddb_disc_t *disc;
60
+ cddb_track_t *track;
61
+
62
+ /*
63
+ * Create a new disc structure.
64
+ */
65
+ disc = cddb_disc_new();
66
+
67
+ /*
68
+ * If the pointer is NULL then an error occured (out of memory).
69
+ * Otherwise we continue.
70
+ */
71
+ if (disc) {
72
+ /*
73
+ * Initialize the disc length in the structure.
74
+ */
75
+ cddb_disc_set_length(disc, dlength);
76
+
77
+ /*
78
+ * Now we have to add the basic track data.
79
+ */
80
+ for (i = 0; i < tcount; i++) {
81
+ /*
82
+ * Create a new libcddb track structure for this track.
83
+ */
84
+ track = cddb_track_new();
85
+
86
+ /*
87
+ * If the pointer is NULL then an error occured (out of
88
+ * memory). Otherwise we continue.
89
+ */
90
+ if (!track) {
91
+ /*
92
+ * Destroy the disc because we can not return half of it.
93
+ * Return NULL to signal failure.
94
+ */
95
+ cddb_disc_destroy(disc);
96
+ return NULL;
97
+ }
98
+
99
+ /*
100
+ * First add the track to the disc.
101
+ */
102
+ cddb_disc_add_track(disc, track);
103
+
104
+ if (use_time) {
105
+ /*
106
+ * Set length in track structure. Since this track is
107
+ * already part of a disc, the frame offset for the track
108
+ * will be calculated automatically when we set its
109
+ * length.
110
+ */
111
+ cddb_track_set_length(track, foffset[i]);
112
+ } else {
113
+ /*
114
+ * Set frame offset in track structure.
115
+ */
116
+ cddb_track_set_frame_offset(track, foffset[i]);
117
+ }
118
+ }
119
+ }
120
+ return disc;
121
+ }
122
+
123
+ static cddb_disc_t *
124
+ cd_read(VALUE obj)
125
+ {
126
+ GET_CDIO(obj, cdio);
127
+ cddb_disc_t *disc = NULL; /* libcddb disc structure */
128
+ track_t cnt,
129
+ t; /* track counters */
130
+ lsn_t lsn; /* Logical Sector Number */
131
+ int *foffset = NULL; /* list of frame offsets */
132
+
133
+ /*
134
+ * Get the track count for the CD.
135
+ */
136
+ cnt = cdio_get_num_tracks(cdio);
137
+ if (cnt == 0) {
138
+ libcdio_error_exit("no audio tracks on CD");
139
+ }
140
+ // printf("CD contains %d track(s)\n", cnt);
141
+
142
+ /*
143
+ * Reserve some memory for the frame offsets.
144
+ */
145
+ foffset = calloc(cnt, sizeof(int));
146
+
147
+ /*
148
+ * Now we go and fetch the track data.
149
+ */
150
+ for (t = 1; t <= cnt; t++) {
151
+
152
+ /*
153
+ * We only want to process audio CDs.
154
+ */
155
+ if (cdio_get_track_format(cdio, t) != TRACK_FORMAT_AUDIO) {
156
+ // libcdio_error_exit("track %d is not an audio track", t);
157
+ }
158
+
159
+ /*
160
+ * Get frame offset of next track.
161
+ */
162
+ lsn = cdio_get_track_lsn(cdio, t);
163
+ if (lsn == CDIO_INVALID_LSN) {
164
+ // libcdio_error_exit ("track %d has invalid Logical Sector
165
+ // Number", t);
166
+ }
167
+
168
+ /*
169
+ * Add this offset to the list. We have to make sure that we add
170
+ * two seconds of lead-in.
171
+ */
172
+ foffset[t - 1] = lsn + SECONDS_TO_FRAMES(2);
173
+ }
174
+
175
+ /*
176
+ * Now all we still have to do, is calculate the length of the disc in
177
+ * seconds. We use the LEADOUT_TRACK for this.
178
+ */
179
+ lsn = cdio_get_track_lsn(cdio, CDIO_CDROM_LEADOUT_TRACK);
180
+ if (lsn == CDIO_INVALID_LSN) {
181
+ // libcdio_error_exit ("LEADOUT_TRACK has invalid Logical Sector
182
+ // Number");
183
+ }
184
+
185
+ /*
186
+ * Now we have to create the libcddb disc structure.
187
+ */
188
+ disc = cd_create(FRAMES_TO_SECONDS(lsn), cnt, foffset, 0);
189
+
190
+ /*
191
+ * Free all resources held by libcdio CD access structure.
192
+ */
193
+
194
+ /*
195
+ * more clean up
196
+ */
197
+ if (foffset != NULL) {
198
+ free(foffset);
199
+ }
200
+ return disc;
201
+ }
202
+
203
+ static void
204
+ rb_cdio_cddb_destroy(cddb_disc_t * disc, cddb_conn_t * conn)
205
+ {
206
+ if (conn != NULL) {
207
+ cddb_destroy(conn);
208
+ }
209
+ if (disc != NULL) {
210
+ cddb_disc_destroy(disc);
211
+ }
212
+ }
213
+
214
+
215
+
216
+ /**
217
+ * Audio Functions
218
+ */
219
+
220
+
221
+
222
+
223
+ VALUE
224
+ rb_cdio_cdda_get_volume(VALUE obj)
225
+ {
226
+ int i;
227
+ cdio_audio_volume_t vol;
228
+ GET_CDIO(obj, p_cdio);
229
+ VALUE out = rb_ary_new();
230
+ verify_return_code(cdio_audio_get_volume(p_cdio, &vol));
231
+ for (i = 0; i < 4; i++) {
232
+ rb_ary_push(out, INT2FIX(vol.level[i]));
233
+ }
234
+ return out;
235
+ }
236
+
237
+ VALUE
238
+ rb_cdio_cdda_set_volume(VALUE obj, VALUE volume)
239
+ {
240
+ int i;
241
+ cdio_audio_volume_t vol;
242
+ GET_CDIO(obj, p_cdio);
243
+ Check_Type(volume, T_ARRAY);
244
+ if (RARRAY(volume)->len != 4) {
245
+ rb_raise(rb_eArgError, "Your array must have 4 nums");
246
+ }
247
+ for (i = 0; i < 4; i++) {
248
+ FIXNUM_P(rb_ary_entry(volume, i));
249
+ vol.level[i] = FIX2INT(rb_ary_entry(volume, i));
250
+ }
251
+ verify_return_code(cdio_audio_set_volume(p_cdio, &vol));
252
+ return Qtrue;
253
+ }
254
+
255
+
256
+ VALUE
257
+ rb_cdio_cdda_pause(VALUE obj)
258
+ {
259
+ GET_CDIO(obj, p_cdio);
260
+ GET_SUB(p_cdio, sub);
261
+ if (sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY) {
262
+ verify_return_code(cdio_audio_pause(p_cdio));
263
+ }
264
+ return Qtrue;
265
+ }
266
+
267
+ VALUE
268
+ rb_cdio_cdda_resume(VALUE obj)
269
+ {
270
+ GET_CDIO(obj, p_cdio);
271
+ GET_SUB(p_cdio, sub);
272
+ // printf("%d", sub.audio_status);
273
+ if (sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED) {
274
+ verify_return_code(cdio_audio_resume(p_cdio));
275
+ }
276
+ return Qtrue;
277
+ }
278
+
279
+ VALUE
280
+ rb_cdio_cdda_stop(VALUE obj)
281
+ {
282
+ GET_CDIO(obj, p_cdio);
283
+ verify_return_code(cdio_audio_stop(p_cdio));
284
+ return Qtrue;
285
+ }
286
+
287
+ VALUE
288
+ rb_cdio_cdda_play(int argc, VALUE * argv, VALUE obj)
289
+ {
290
+ VALUE Vbegin,
291
+ Vend;
292
+ track_t begin,
293
+ end,
294
+ first,
295
+ last;
296
+ GET_CDIO(obj, p_cdio);
297
+ first = cdio_get_first_track_num(p_cdio);
298
+ last = cdio_get_last_track_num(p_cdio);
299
+ rb_scan_args(argc, argv, "02", &Vbegin, &Vend);
300
+ if (Qnil == Vend) {
301
+ end = last;
302
+ } else {
303
+ FIXNUM_P(Vend);
304
+ end = FIX2INT(Vend);
305
+ }
306
+ if (Qnil == Vbegin) {
307
+ begin = first;
308
+ } else {
309
+ FIXNUM_P(Vbegin);
310
+ begin = FIX2INT(Vbegin);
311
+ }
312
+ // verify than begin and end are corrects
313
+ if (begin > end) {
314
+ end = begin;
315
+ }
316
+ if (begin > last) {
317
+ begin = last;
318
+ }
319
+ if (begin < first) {
320
+ begin = first;
321
+ }
322
+ if (end < first) {
323
+ end = first;
324
+ }
325
+ if (end > last) {
326
+ end = last;
327
+ }
328
+ VALUE res = rb_ary_new();
329
+ rb_ary_push(res, INT2FIX(begin));
330
+ rb_ary_push(res, INT2FIX(end));
331
+ rb_cdio_cdda_pause(obj);
332
+ msf_t msf_start,
333
+ msf_end;
334
+ cdio_get_track_msf(p_cdio, begin, &msf_start);
335
+ cdio_get_track_msf(p_cdio, end + 1, &msf_end);
336
+ verify_return_code(cdio_audio_play_msf(p_cdio, &msf_start, &msf_end));
337
+ return res;
338
+ }
339
+
340
+ VALUE
341
+ rb_cdio_cdda_cddb_id(VALUE obj)
342
+ {
343
+ char cddb[8];
344
+ GET_CDIO(obj, p_cdio);
345
+ track_t nt = cdio_get_num_tracks(p_cdio);
346
+ sprintf(cddb, "%08lx", cddb_discid(p_cdio, nt));
347
+ return rb_str_new2(cddb);
348
+ }
349
+
350
+
351
+
352
+ VALUE
353
+ rb_cdio_cdda_cddb_matches(VALUE obj)
354
+ {
355
+ #ifdef HAVE_CDDB
356
+ cddb_disc_t *disc = NULL;
357
+ cddb_conn_t *conn = cddb_new();
358
+ VALUE res = rb_ary_new();
359
+ if (conn == NULL) {
360
+ rb_raise(eCdIoCddbConn, "Unable to create connection structure");
361
+ }
362
+ disc = cd_read(obj);
363
+ /*
364
+ * (2) execute query command
365
+ */
366
+ int matches = cddb_query(conn, disc);
367
+ if (matches == -1) {
368
+ rb_raise(rb_eException, (cddb_error_str(cddb_errno(conn))));
369
+ }
370
+
371
+ while (matches > 0) {
372
+ VALUE hMatch = rb_hash_new();
373
+ /*
374
+ * (3) ... use disc ...
375
+ */
376
+ char year[4];
377
+ char id[20];
378
+ char length[20];
379
+ sprintf(id, "%u", cddb_disc_get_discid(disc));
380
+ sprintf(year, "%d", cddb_disc_get_year(disc));
381
+ sprintf(length, "%d", cddb_disc_get_length(disc));
382
+ HASH_STR(hMatch, "id", id);
383
+ HASH_STR(hMatch, "category", cddb_disc_get_category_str(disc));
384
+ HASH_STR(hMatch, "genre", cddb_disc_get_genre(disc));
385
+ HASH_STR(hMatch, "artist", cddb_disc_get_artist(disc));
386
+ HASH_STR(hMatch, "title", cddb_disc_get_title(disc));
387
+ HASH_STR(hMatch, "year", year);
388
+ HASH_STR(hMatch, "length", length);
389
+ rb_ary_push(res, hMatch);
390
+ /*
391
+ * (4) get next query result if there is one left
392
+ */
393
+ matches--;
394
+ if (matches > 0) {
395
+ if (!cddb_query_next(conn, disc)) {
396
+ rb_raise(eCdIoCddbConn,
397
+ "Unable to create connection structure");
398
+ }
399
+ }
400
+ }
401
+ rb_cdio_cddb_destroy(disc, conn);
402
+ return res;
403
+ #else
404
+ rb_raise(rb_eException, "You need libcddb");
405
+ #endif
406
+ }
407
+
408
+ VALUE
409
+ rb_cdio_cdda_cddb_fetch(VALUE obj, VALUE match)
410
+ {
411
+ #ifdef HAVE_CDDB
412
+ FIXNUM_P(match);
413
+ int match_i,
414
+ i;
415
+ match_i = FIX2INT(match);
416
+ if (match_i < 1) {
417
+ rb_raise(rb_eArgError, "Match must be >1");
418
+ }
419
+ cddb_disc_t *disc = NULL;
420
+ cddb_conn_t *conn = cddb_new();
421
+ if (conn == NULL) {
422
+ rb_raise(eCdIoCddbConn, "Unable to create connection structure");
423
+ }
424
+ disc = cd_read(obj);
425
+ /*
426
+ * (2) execute query command
427
+ */
428
+ int matches = cddb_query(conn, disc);
429
+ if (matches == -1) {
430
+ rb_raise(rb_eException, (cddb_error_str(cddb_errno(conn))));
431
+ } else if (match_i > matches) {
432
+ char error[255];
433
+ sprintf(error, "Match %d requested, %d availables", match_i,
434
+ matches);
435
+
436
+ rb_raise(eCdIoCddbError, error);
437
+ }
438
+ i = 1;
439
+ while (matches > 0) {
440
+ if (i == match_i) {
441
+ int success;
442
+ cddb_disc_set_category(disc, cddb_disc_get_category(disc));
443
+ cddb_disc_set_discid(disc, cddb_disc_get_discid(disc));
444
+ success = cddb_read(conn, disc);
445
+ if (!success) {
446
+ rb_raise(rb_eException,
447
+ (cddb_error_str(cddb_errno(conn))));
448
+ }
449
+ /*
450
+ * put data on the object
451
+ */
452
+ char year[4];
453
+ char id[20];
454
+ char length[20];
455
+ sprintf(year, "%d", cddb_disc_get_year(disc));
456
+ sprintf(length, "%d", cddb_disc_get_length(disc));
457
+ rb_iv_set(obj, "@category",
458
+ rb_str_new2(cddb_disc_get_category_str(disc)));
459
+ rb_iv_set(obj, "@genre",
460
+ rb_str_new2(cddb_disc_get_genre(disc)));
461
+ rb_iv_set(obj, "@artist",
462
+ rb_str_new2(cddb_disc_get_artist(disc)));
463
+ rb_iv_set(obj, "@title",
464
+ rb_str_new2(cddb_disc_get_title(disc)));
465
+ rb_iv_set(obj, "@year", rb_str_new2(year));
466
+ rb_iv_set(obj, "@length", rb_str_new2(length));
467
+ if (NULL != cddb_disc_get_ext_data(disc)) {
468
+ rb_iv_set(obj, "@extra_data",
469
+ rb_str_new2(cddb_disc_get_ext_data(disc)));
470
+ }
471
+ /*
472
+ * put data on tracks
473
+ */
474
+ VALUE oTrack,
475
+ oTracks;
476
+ cddb_track_t *track;
477
+ int track_i;
478
+ rb_cdio_cd_get_tracks(obj);
479
+ oTracks = rb_iv_get(obj, "@tracks");
480
+ track = cddb_disc_get_track_first(disc);
481
+ while (track != NULL) {
482
+ track_i = cddb_track_get_number(track);
483
+ oTrack = rb_cdio_tracks_index(oTracks, INT2FIX(track_i));
484
+ const char *artist = cddb_track_get_artist(track);
485
+ char *title = cddb_track_get_title(track);
486
+ rb_iv_set(oTrack, "@artist",
487
+ rb_str_new2((NULL != artist) ? artist : ""));
488
+ rb_iv_set(oTrack, "@title",
489
+ rb_str_new2((NULL != title) ? title : ""));
490
+ //
491
+ track = cddb_disc_get_track_next(disc);
492
+ }
493
+ // destroy and send ok
494
+ rb_cdio_cddb_destroy(disc, conn);
495
+ return Qtrue;
496
+ }
497
+ i++;
498
+ /*
499
+ * (4) get next query result if there is one left
500
+ */
501
+ matches--;
502
+ if (matches > 0) {
503
+ if (!cddb_query_next(conn, disc)) {
504
+ rb_raise(eCdIoCddbConn,
505
+ "Unable to create connection structure");
506
+ }
507
+ }
508
+ }
509
+ return Qfalse;
510
+ #else
511
+ rb_raise(rb_eException, "You need libcddb");
512
+ #endif
513
+
514
+ }
515
+ VALUE
516
+ rb_cdio_cdda_category(VALUE obj)
517
+ {
518
+ return rb_iv_get(obj, "@category");
519
+ }
520
+ VALUE
521
+ rb_cdio_cdda_title(VALUE obj)
522
+ {
523
+ return rb_iv_get(obj, "@title");
524
+ }
525
+ VALUE
526
+ rb_cdio_cdda_artist(VALUE obj)
527
+ {
528
+ return rb_iv_get(obj, "@artist");
529
+ }
530
+ VALUE
531
+ rb_cdio_cdda_year(VALUE obj)
532
+ {
533
+ return rb_iv_get(obj, "@year");
534
+ }
535
+ VALUE
536
+ rb_cdio_cdda_genre(VALUE obj)
537
+ {
538
+ return rb_iv_get(obj, "@genre");
539
+ }
540
+ VALUE
541
+ rb_cdio_cdda_length(VALUE obj)
542
+ {
543
+ return rb_iv_get(obj, "@length");
544
+ }
545
+
546
+ VALUE
547
+ rb_cdio_cdda_extra_data(VALUE obj)
548
+ {
549
+ return rb_iv_get(obj, "@extra_data");
550
+ }
551
+ #define SET_SUB_I(o,k,v) rb_hash_aset(o,rb_str_new2(k),INT2FIX(v));
552
+ #define SET_SUB_S(o,k,v) rb_hash_aset(o,rb_str_new2(k),rb_str_new2(v));
553
+
554
+ VALUE
555
+ rb_cdio_cdda_subchannel(VALUE obj)
556
+ {
557
+ GET_CDIO(obj, p_cdio);
558
+ GET_SUB(p_cdio, sub);
559
+ VALUE out = rb_hash_new();
560
+ /*
561
+ * { uint8_t format; uint8_t audio_status; uint8_t address: 4; uint8_t
562
+ * control: 4; uint8_t track; uint8_t index; msf_t abs_addr; msf_t
563
+ * rel_addr; } cdio_subchannel_t;
564
+ */
565
+ char *as_s;
566
+ switch (sub.audio_status) {
567
+ case CDIO_MMC_READ_SUB_ST_INVALID:
568
+ as_s = "invalid";
569
+ break;
570
+ case CDIO_MMC_READ_SUB_ST_PLAY:
571
+ as_s = "play";
572
+ break;
573
+ case CDIO_MMC_READ_SUB_ST_PAUSED:
574
+ as_s = "paused";
575
+ break;
576
+ case CDIO_MMC_READ_SUB_ST_COMPLETED:
577
+ as_s = "completed";
578
+ break;
579
+ case CDIO_MMC_READ_SUB_ST_ERROR:
580
+ as_s = "error";
581
+ break;
582
+ case CDIO_MMC_READ_SUB_ST_NO_STATUS:
583
+ as_s = "no_status";
584
+ break;
585
+ }
586
+ msf_t msf_abs,
587
+ msf_rel;
588
+ char *msf_abs_s,
589
+ *msf_rel_s;
590
+ msf_abs_s = cdio_msf_to_str(&sub.abs_addr);
591
+ msf_rel_s = cdio_msf_to_str(&sub.rel_addr);
592
+ SET_SUB_I(out, "format", sub.format);
593
+ SET_SUB_I(out, "audio_status", sub.audio_status);
594
+ SET_SUB_S(out, "audio_status_desc", as_s);
595
+ SET_SUB_I(out, "address", sub.address);
596
+ SET_SUB_I(out, "control", sub.control);
597
+ SET_SUB_I(out, "track", sub.track);
598
+ SET_SUB_I(out, "index", sub.index);
599
+ SET_SUB_S(out, "abs_addr", msf_abs_s);
600
+ SET_SUB_S(out, "rel_addr", msf_rel_s);
601
+ free(msf_abs_s);
602
+ free(msf_rel_s);
603
+ return out;
604
+ }
605
+
606
+ #undef SET_SUB_I
607
+ #undef SET_SUB_S