rb_cdio 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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