catori 0.2.5

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 (71) hide show
  1. data/VERSION +1 -0
  2. data/bin/catori +9 -0
  3. data/changelog.txt +3 -0
  4. data/construir +3 -0
  5. data/crear_vista.sql +8 -0
  6. data/ext/audiofile/MANIFEST +8 -0
  7. data/ext/audiofile/README +11 -0
  8. data/ext/audiofile/audiofile.c +833 -0
  9. data/ext/audiofile/audiofile.rd +265 -0
  10. data/ext/audiofile/depend +0 -0
  11. data/ext/audiofile/extconf.rb +8 -0
  12. data/ext/audiofile/fail.rb +22 -0
  13. data/ext/audiofile/mkmf.log +34 -0
  14. data/ext/audiofile/test.rb +229 -0
  15. data/ext/flac/extconf.rb +5 -0
  16. data/ext/flac/flac.c +75 -0
  17. data/ext/flac/mkmf.log +12 -0
  18. data/ext/flac/test.rb +3 -0
  19. data/ext/mahoro-0.1/INSTALL +9 -0
  20. data/ext/mahoro-0.1/extconf.rb +7 -0
  21. data/ext/mahoro-0.1/mahoro.c +187 -0
  22. data/ext/mahoro-0.1/mkmf.log +24 -0
  23. data/ext/mahoro-0.1/test.rb +41 -0
  24. data/ext/mpc/extconf.rb +5 -0
  25. data/ext/mpc/id3tag.c +245 -0
  26. data/ext/mpc/id3tag.h +5 -0
  27. data/ext/mpc/mkmf.log +12 -0
  28. data/ext/mpc/mpc.c +56 -0
  29. data/ext/mpc/mpp.h +194 -0
  30. data/ext/mpc/mppdec.h +1171 -0
  31. data/ext/mpc/test.rb +3 -0
  32. data/ext/rmac/extconf.rb +7 -0
  33. data/ext/rmac/mkmf.log +22 -0
  34. data/ext/rmac/rmac.cpp +162 -0
  35. data/ext/vorbisfile/ChangeLog +11 -0
  36. data/ext/vorbisfile/README +33 -0
  37. data/ext/vorbisfile/configure +2 -0
  38. data/ext/vorbisfile/extconf.rb +9 -0
  39. data/ext/vorbisfile/mkmf.log +68 -0
  40. data/ext/vorbisfile/test.rb +78 -0
  41. data/ext/vorbisfile/vorbisfile.c +482 -0
  42. data/instalar.txt +19 -0
  43. data/install.rb +11 -0
  44. data/lib/audioinfo.rb +321 -0
  45. data/lib/catori.rb +131 -0
  46. data/lib/catori/Catalogador.rb +71 -0
  47. data/lib/catori/Db.rb +81 -0
  48. data/lib/catori/Gui.rb +52 -0
  49. data/lib/catori/Installer.rb +16 -0
  50. data/lib/catori/Query.rb +82 -0
  51. data/lib/catori/XML.rb +42 -0
  52. data/lib/catori/catori_gui.glade +340 -0
  53. data/lib/catori/catori_gui.glade.bak +340 -0
  54. data/lib/catori/catori_gui.gladep +8 -0
  55. data/lib/catori/catori_gui.gladep.bak +8 -0
  56. data/lib/catori/taglib.rb +227 -0
  57. data/lib/pixmaps/album.png +0 -0
  58. data/lib/pixmaps/artist.png +0 -0
  59. data/lib/pixmaps/cdr.png +0 -0
  60. data/lib/pixmaps/song.png +0 -0
  61. data/lib/taglib.rb +230 -0
  62. data/sql/catori_mysql.sql +68 -0
  63. data/sql/catori_pg.sql +65 -0
  64. data/tests/saw.ape +0 -0
  65. data/tests/saw.flac +0 -0
  66. data/tests/saw.mp3 +0 -0
  67. data/tests/saw.mpc +0 -0
  68. data/tests/saw.ogg +0 -0
  69. data/tests/saw.wav +0 -0
  70. data/tests/test_audioinfo.rb +43 -0
  71. metadata +217 -0
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.5
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift(File.dirname(File.symlink?(__FILE__)? File.readlink(__FILE__) : __FILE__)+"/../lib/")
3
+ #begin
4
+ require 'catori'
5
+ #rescue LoadError
6
+ # require 'rubygems'
7
+ # gem 'catori'
8
+ #end
9
+ Catori::App.new.run
@@ -0,0 +1,3 @@
1
+ CHANGELOG
2
+ 0.2.4 : Update support for ruby-mp3info (0.5.1)
3
+ 0.2.3 : Added support to Mysql and installer
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+ gem build catori.gemspec
3
+ sudo gem install catori-0.2.5.gem
@@ -0,0 +1,8 @@
1
+ DROP VIEW vista_cd;
2
+ CREATE VIEW vista_cd as
3
+ SELECT cd_id,file_name, a.artist_name, b.album_name, ab.as_track, s.song_name
4
+ FROM FILE f JOIN artist a ON f.artist_id= a.artist_id
5
+ JOIN ALBUM b ON f.artist_id = b.artist_id AND f.album_id = b.album_id
6
+ JOIN album_song ab ON f.artist_id=ab.artist_id AND f.album_id=ab.album_id
7
+ and f.song_id=ab.song_id
8
+ JOIN song s ON f.song_id::text = s.song_id::text;
@@ -0,0 +1,8 @@
1
+ MANIFEST
2
+ audiofile.c
3
+ audiofile.rd
4
+ audiofile.html
5
+ depend
6
+ extconf.rb
7
+ fail.rb
8
+ test.rb
@@ -0,0 +1,11 @@
1
+ to install, run these commands:
2
+
3
+ ruby extconf.rb
4
+ make
5
+ su
6
+ make install
7
+
8
+ the audiofile library and headers are required.
9
+
10
+ enjoy!
11
+ -jared
@@ -0,0 +1,833 @@
1
+ /*********************************************************
2
+
3
+ audiofile.c
4
+
5
+ a Ruby extension to bind Ruby to audiofile
6
+ (http://dreamscape.68k.org/~michael/audiofile/)
7
+
8
+ patterned very very closely off of gdbm.c by matz in
9
+ the ruby 1.6.4 distribution. very closely. thanks matz!
10
+
11
+ $Author: jaredj $
12
+ $Date: 2001/07/26 04:31:45 $
13
+
14
+ *********************************************************/
15
+
16
+ /* conventions:
17
+ *
18
+ * _s_ in function name: singleton method
19
+ * fh : filehandle
20
+ * fn : filename
21
+ * af : audiofile
22
+ * p : pointer
23
+ */
24
+
25
+ /* assumptions:
26
+ * you always mean AF_DEFAULT_TRACK.
27
+ * the audiofile lib currently supports only formats with one track.
28
+ * so we'll always use AF_DEFAULT_TRACK, at least for
29
+ * this version of the bindings.
30
+ * (this doesn't mean one *channel*; stereo files are fully supported.)
31
+ *
32
+ *
33
+ * you will always set everything about the file before attempting to write it.
34
+ * (rate, bits, channels, byte_order, compression, file_format, sample_format)
35
+ */
36
+
37
+ /* things supported:
38
+ *
39
+ * opening/closing/flushing audio files
40
+ * reading frames into a new string and an existing one
41
+ * NEW: writing audio files from strings
42
+ * NEW: setting things about files to be created (sample rate, etc)
43
+ * moving forward/telling position in a file
44
+ * getting frame count & size
45
+ * getting real sample rate
46
+ * getting real byte order
47
+ * getting/setting virtual byte order
48
+ * calling all this from ruby
49
+ *
50
+ */
51
+
52
+ /* things not yet supported (in order of importance):
53
+ *
54
+ * raw-reading files well
55
+ * (afInitDataOffset not supported, so you can't skip headers easily)
56
+ * setting parameters for compression schemes when writing
57
+ * (this might make the ability to set the compression scheme useless)
58
+ * really correct error handling
59
+ * querying the capabilities of the audiofile library (afQuery)
60
+ * things relating to loops, instruments or non-strictly-audio data
61
+ * things that audiofile has API for but doesn't actually support yet
62
+ * (e.g., virtual sample rates and virtual compression schemes)
63
+ */
64
+
65
+ /* open doesn't appear to work, even though i copied it straight from
66
+ * matz's gdbm extenstion. */
67
+
68
+ #include "ruby.h"
69
+ #include <audiofile.h>
70
+
71
+ static VALUE cAudioFile, rb_eAudioFileError;
72
+
73
+ /* I know AFfilehandle is just a struct _AFfilehandle *
74
+ * but i chose to keep it in its own structure instead of
75
+ * just using the _AFfilehandle structure for future
76
+ * expansibility and caching stuff, like matz did in
77
+ * the gdbm ext.
78
+ */
79
+
80
+ struct af_data {
81
+ char *name;
82
+ // char mode;
83
+ int sample_format;
84
+ int sample_width;
85
+ AFfilehandle handle;
86
+ AFfilesetup setup;
87
+ };
88
+
89
+
90
+ /* this will pad 24-bit values to 32 bits.
91
+ * replace 1 with 0 to disable */
92
+ #define EXPAND_3TO4 1
93
+
94
+ static VALUE af_close(VALUE obj);
95
+
96
+
97
+ static void closed_af()
98
+ {
99
+ rb_raise(rb_eRuntimeError, "audio file already closed");
100
+ }
101
+
102
+ #define GetAFP(obj, afp) {\
103
+ Data_Get_Struct(obj, struct af_data, afp);\
104
+ if(afp == NULL) closed_af();\
105
+ if(afp->handle == AF_NULL_FILEHANDLE) closed_af();\
106
+ }
107
+
108
+ #define GetAFPWithoutOpenChecking(obj, afp) {\
109
+ Data_Get_Struct(obj, struct af_data, afp);\
110
+ }
111
+
112
+ static void free_af(struct af_data *afp)
113
+ {
114
+ if(afp) {
115
+ if(afp->handle) {
116
+ afCloseFile(afp->handle);
117
+ /* the error handler will get it */
118
+ }
119
+ if(afp->setup) {
120
+ afFreeFileSetup(afp->setup);
121
+ }
122
+ if(afp->name) {
123
+ free(afp->name);
124
+ }
125
+ free(afp);
126
+ }
127
+ }
128
+
129
+ static int af_is_open(struct af_data *afp)
130
+ {
131
+ if(afp) {
132
+ return (afp->handle != NULL);
133
+ } else {
134
+ rb_raise(rb_eRuntimeError, "somehow an AudioFile with no data was asked if it was open");
135
+ return 0;
136
+ }
137
+ }
138
+
139
+ static VALUE af_initialize(int argc, VALUE *argv, VALUE obj)
140
+ {
141
+ AFfilehandle fh;
142
+ struct af_data *afp;
143
+ /* struct af_file_setup *fsp;
144
+ AFfilesetup file_setup; */
145
+ char *mode, *fn;
146
+
147
+ VALUE v_return;
148
+ VALUE v_fn, v_mode, v_file_setup;
149
+
150
+
151
+ switch(rb_scan_args(argc, argv, "12", &v_fn, &v_mode, &v_file_setup)) {
152
+ case 1: /* only filename specified. use default (read) */
153
+
154
+ mode = malloc(2);
155
+ mode[0] = 'r';
156
+ mode[1] = '\0';
157
+
158
+ break;
159
+ case 2: /* filename & mode */
160
+ Check_Type(v_mode, T_STRING);
161
+
162
+ /* get mode into a C-string */
163
+ mode = malloc(2);
164
+ mode[0] = *(RSTRING(v_mode)->ptr);
165
+ mode[1] = '\0';
166
+
167
+ switch(*mode) {
168
+ case 'r':
169
+ case 'w':
170
+ /* OK */
171
+ break;
172
+ default:
173
+ rb_raise(rb_eArgError, "unknown mode specification");
174
+ break;
175
+ }
176
+ break;
177
+ default:
178
+ rb_raise(rb_eArgError, "wrong number of arguments");
179
+ break;
180
+ }
181
+
182
+ Check_Type(v_fn, T_STRING);
183
+
184
+ /* i don't know exactly what this does, but matz did it so it must work :) */
185
+ v_fn = rb_str_to_str(v_fn);
186
+ Check_SafeStr(v_fn);
187
+
188
+ switch(*mode) {
189
+ case 'r':
190
+
191
+ fh = afOpenFile(RSTRING(v_fn)->ptr, mode, AF_NULL_FILESETUP);
192
+ if(fh != AF_NULL_FILEHANDLE) {
193
+ afp = ALLOC(struct af_data);
194
+ DATA_PTR(obj) = afp;
195
+
196
+ /* default sample format and width. see af_sample_format_eq
197
+ * below for details about this ugly hack. */
198
+
199
+ afp->sample_format = AF_SAMPFMT_TWOSCOMP;
200
+ afp->sample_width = 16;
201
+
202
+ afp->name = NULL;
203
+ afp->setup = AF_NULL_FILESETUP;
204
+ afp->handle = fh;
205
+
206
+ v_return = obj;
207
+ } else {
208
+ v_return = Qnil;
209
+ }
210
+ free(mode);
211
+ break;
212
+
213
+ case 'w':
214
+
215
+ fn = malloc(RSTRING(v_fn)->len+1);
216
+ strcpy(fn, RSTRING(v_fn)->ptr);
217
+
218
+ afp = ALLOC(struct af_data);
219
+ DATA_PTR(obj) = afp;
220
+
221
+ afp->sample_format = AF_SAMPFMT_TWOSCOMP;
222
+ afp->sample_width = 16;
223
+
224
+ afp->name = fn;
225
+ afp->handle = AF_NULL_FILEHANDLE;
226
+ afp->setup = afNewFileSetup();
227
+
228
+ v_return = obj;
229
+ free(mode);
230
+ break;
231
+
232
+ default:
233
+ free(mode);
234
+ rb_raise(rb_eArgError, "unknown mode specified");
235
+ break;
236
+ }
237
+
238
+ return v_return;
239
+ }
240
+
241
+
242
+ static VALUE af_s_new(int argc, VALUE *argv, VALUE klass)
243
+ {
244
+ /* i don't know what the last param is in this 'call' */
245
+
246
+ VALUE obj = Data_Wrap_Struct(klass, 0, free_af, 0);
247
+ rb_obj_call_init(obj, argc, argv);
248
+ return obj;
249
+ }
250
+
251
+ /* ---------------- fundamental methods -------------------------*/
252
+
253
+ static VALUE af_s_open(int argc, VALUE *argv, VALUE klass)
254
+ {
255
+
256
+ VALUE obj = Data_Wrap_Struct(klass, 0, free_af, 0);
257
+
258
+ if(NIL_P(af_initialize(argc, argv, obj))) {
259
+ return Qnil;
260
+ }
261
+
262
+ if(rb_block_given_p()) {
263
+ return rb_ensure(rb_yield, obj, af_close, obj);
264
+ }
265
+
266
+ return obj;
267
+ }
268
+
269
+ static VALUE af_close(VALUE obj)
270
+ {
271
+ struct af_data *afp;
272
+
273
+ GetAFPWithoutOpenChecking(obj, afp);
274
+ if(af_is_open(afp)) {
275
+ afCloseFile(afp->handle);
276
+ afp->handle = AF_NULL_FILEHANDLE;
277
+ }
278
+
279
+ return Qnil;
280
+ }
281
+
282
+ static VALUE af_flush(VALUE obj)
283
+ {
284
+ struct af_data *afp;
285
+
286
+ GetAFP(obj, afp);
287
+ if(af_is_open(afp)) {
288
+ afSyncFile(afp->handle);
289
+ }
290
+
291
+ return obj;
292
+ }
293
+
294
+
295
+
296
+ static VALUE af_read(int argc, VALUE *argv, VALUE obj)
297
+ {
298
+ VALUE v_frames;
299
+ VALUE returnString;
300
+ struct af_data *afp;
301
+ long int frames, actual_frames, frame_size;
302
+ long int bytes, actual_bytes;
303
+ void *buf;
304
+
305
+ GetAFP(obj, afp);
306
+ if(rb_scan_args(argc, argv, "01", &v_frames) == 1) {
307
+ if(FIXNUM_P(v_frames)) {
308
+ frames = NUM2INT(v_frames);
309
+ } else {
310
+ rb_raise(rb_eArgError, "invalid argument to AudioFile#read");
311
+ }
312
+ } else {
313
+ frames = afGetFrameCount(afp->handle, AF_DEFAULT_TRACK);
314
+ }
315
+
316
+ frame_size = afGetFrameSize(afp->handle, AF_DEFAULT_TRACK, EXPAND_3TO4);
317
+ bytes = frames * frame_size;
318
+ buf = malloc(bytes);
319
+
320
+ actual_frames = afReadFrames(afp->handle, AF_DEFAULT_TRACK, buf, frames);
321
+ actual_bytes = actual_frames * frame_size;
322
+
323
+ returnString = rb_str_new(buf, actual_bytes);
324
+ return returnString;
325
+ }
326
+
327
+ static VALUE af_read_into(VALUE obj, VALUE readIntoString)
328
+ {
329
+ struct af_data *afp;
330
+ long int frames, actual_frames, frame_size;
331
+ long int bytes, actual_bytes;
332
+ void *buf;
333
+
334
+ GetAFP(obj, afp);
335
+
336
+
337
+ Check_Type(readIntoString, T_STRING);
338
+ bytes = RSTRING(readIntoString)->len;
339
+ buf = RSTRING(readIntoString)->ptr;
340
+
341
+ frame_size = afGetFrameSize(afp->handle, AF_DEFAULT_TRACK, EXPAND_3TO4);
342
+ frames = bytes / frame_size;
343
+
344
+ actual_frames = afReadFrames(afp->handle, AF_DEFAULT_TRACK, buf, frames);
345
+ actual_bytes = actual_frames * frame_size;
346
+
347
+ return INT2NUM(actual_bytes);
348
+ }
349
+
350
+ static VALUE actually_write(VALUE obj, VALUE writeFromString)
351
+ {
352
+ struct af_data *afp;
353
+ long int frames, actual_frames, frame_size;
354
+ long int bytes, actual_bytes;
355
+ void *buf;
356
+
357
+ GetAFP(obj, afp);
358
+
359
+ Check_Type(writeFromString, T_STRING);
360
+ bytes = RSTRING(writeFromString)->len;
361
+ buf = RSTRING(writeFromString)->ptr;
362
+
363
+ frame_size = afGetFrameSize(afp->handle, AF_DEFAULT_TRACK, EXPAND_3TO4);
364
+ frames = bytes / frame_size;
365
+
366
+ actual_frames = afWriteFrames(afp->handle, AF_DEFAULT_TRACK, buf, frames);
367
+ actual_bytes = actual_frames * frame_size;
368
+
369
+ return INT2NUM(actual_bytes);
370
+ }
371
+
372
+ static VALUE af_write(VALUE obj, VALUE writeFromString)
373
+ {
374
+ struct af_data *afp;
375
+
376
+ GetAFPWithoutOpenChecking(obj, afp);
377
+ if(af_is_open(afp)) {
378
+ return actually_write(obj, writeFromString);
379
+ } else {
380
+ if(afp->name) {
381
+ afp->handle = afOpenFile(afp->name, "w", afp->setup);
382
+ free(afp->name);
383
+ afp->name = NULL;
384
+
385
+ return actually_write(obj, writeFromString);
386
+ } else {
387
+ rb_raise(rb_eAudioFileError, "write attempted on apparently unopenable file");
388
+ return Qnil;
389
+ }
390
+ }
391
+ }
392
+
393
+
394
+
395
+ /* ------ getters --------------------------------------------------------*/
396
+
397
+ static VALUE af_frame_size(VALUE obj)
398
+ {
399
+ struct af_data *afp;
400
+
401
+ GetAFP(obj, afp);
402
+ return INT2NUM((afGetFrameSize(afp->handle, AF_DEFAULT_TRACK, EXPAND_3TO4)));
403
+ }
404
+
405
+ static VALUE af_frame_count(VALUE obj)
406
+ {
407
+ struct af_data *afp;
408
+
409
+ GetAFP(obj, afp);
410
+ return INT2NUM((afGetFrameCount(afp->handle, AF_DEFAULT_TRACK)));
411
+ }
412
+
413
+ static VALUE af_pos(VALUE obj)
414
+ {
415
+ struct af_data *afp;
416
+
417
+ GetAFP(obj, afp);
418
+ return INT2NUM((afTellFrame(afp->handle, AF_DEFAULT_TRACK)));
419
+ }
420
+
421
+ static VALUE af_sample_rate(VALUE obj)
422
+ {
423
+ struct af_data *afp;
424
+
425
+ GetAFP(obj, afp);
426
+ return INT2NUM((afGetRate(afp->handle, AF_DEFAULT_TRACK)));
427
+ }
428
+
429
+
430
+ static VALUE af_byte_order(VALUE obj)
431
+ {
432
+ struct af_data *afp;
433
+ int byte_order;
434
+
435
+ GetAFP(obj, afp);
436
+ byte_order = afGetByteOrder(afp->handle, AF_DEFAULT_TRACK);
437
+
438
+ /* for now */
439
+ return INT2NUM(byte_order);
440
+ }
441
+
442
+ static VALUE af_virtual_byte_order(VALUE obj)
443
+ {
444
+ struct af_data *afp;
445
+ int byte_order;
446
+
447
+ GetAFP(obj, afp);
448
+ byte_order = afGetVirtualByteOrder(afp->handle, AF_DEFAULT_TRACK);
449
+
450
+ /* for now */
451
+ return INT2NUM(byte_order);
452
+ }
453
+
454
+ static VALUE af_channels(VALUE obj)
455
+ {
456
+ struct af_data *afp;
457
+
458
+ GetAFP(obj, afp);
459
+
460
+ return INT2NUM(afGetChannels(afp->handle, AF_DEFAULT_TRACK));
461
+ }
462
+
463
+
464
+ static VALUE af_sample_format(VALUE obj)
465
+ {
466
+ struct af_data *afp;
467
+ int format, width;
468
+
469
+ GetAFP(obj, afp);
470
+
471
+ afGetSampleFormat(afp->handle, AF_DEFAULT_TRACK, &format, &width);
472
+ return INT2FIX(format);
473
+ }
474
+
475
+ static VALUE af_sample_width(VALUE obj)
476
+ {
477
+ struct af_data *afp;
478
+ int format, width;
479
+
480
+ GetAFP(obj, afp);
481
+
482
+ afGetSampleFormat(afp->handle, AF_DEFAULT_TRACK, &format, &width);
483
+ return INT2FIX(width);
484
+ }
485
+
486
+ static VALUE af_compression(VALUE obj)
487
+ {
488
+ struct af_data *afp;
489
+
490
+ GetAFP(obj, afp);
491
+
492
+ return INT2NUM(afGetCompression(afp->handle, AF_DEFAULT_TRACK));
493
+ }
494
+
495
+ static VALUE af_pcm_mapping(VALUE obj)
496
+ {
497
+ struct af_data *afp;
498
+ double slope, intercept, min_clip, max_clip;
499
+
500
+ GetAFP(obj, afp);
501
+
502
+ afGetPCMMapping(afp->handle, AF_DEFAULT_TRACK, &slope,
503
+ &intercept, &min_clip, &max_clip);
504
+
505
+ return rb_ary_new3(4,
506
+ rb_float_new(slope),
507
+ rb_float_new(intercept),
508
+ rb_float_new(min_clip),
509
+ rb_float_new(max_clip));
510
+ }
511
+
512
+
513
+ static VALUE af_file_format(VALUE obj)
514
+ {
515
+ struct af_data *afp;
516
+ int ver;
517
+
518
+ GetAFP(obj, afp);
519
+
520
+ return INT2NUM(afGetFileFormat(afp->handle, &ver));
521
+ }
522
+
523
+ static VALUE af_file_format_version(VALUE obj)
524
+ {
525
+ struct af_data *afp;
526
+ int ver;
527
+
528
+ GetAFP(obj, afp);
529
+ afGetFileFormat(afp->handle, &ver);
530
+
531
+ return INT2NUM(ver);
532
+ }
533
+
534
+ /*
535
+ * ------ setters --------------------------------------------------------
536
+ */
537
+
538
+ static VALUE af_pos_eq(VALUE obj, VALUE new_pos)
539
+ {
540
+ struct af_data *afp;
541
+ AFfileoffset here, there;
542
+
543
+ GetAFP(obj, afp);
544
+ here = afTellFrame(afp->handle, AF_DEFAULT_TRACK);
545
+ there = NUM2INT(new_pos);
546
+ if(there >= here) {
547
+ return INT2NUM((afSeekFrame(afp->handle, AF_DEFAULT_TRACK, (there - here))));
548
+ } else {
549
+ rb_raise(rb_eArgError, "cannot seek backwards");
550
+ }
551
+ }
552
+
553
+
554
+ #define ATTEMPT(foo) ("attempt to set " foo " on an already-open file")
555
+ static void bail_if_open(struct af_data *afp, const char *message)
556
+ {
557
+ if(af_is_open(afp)) {
558
+ rb_raise(rb_eAudioFileError, message);
559
+ }
560
+ }
561
+
562
+ static VALUE af_file_format_eq(VALUE obj, VALUE format)
563
+ {
564
+ struct af_data *afp;
565
+
566
+ GetAFPWithoutOpenChecking(obj, afp);
567
+ bail_if_open(afp, ATTEMPT("file format"));
568
+
569
+ afInitFileFormat(afp->setup, NUM2INT(format));
570
+ return format;
571
+ }
572
+
573
+ static VALUE af_sample_rate_eq(VALUE obj, VALUE rate)
574
+ {
575
+ struct af_data *afp;
576
+
577
+ GetAFPWithoutOpenChecking(obj, afp);
578
+
579
+ bail_if_open(afp, ATTEMPT("sample rate"));
580
+
581
+ afInitRate(afp->setup, AF_DEFAULT_TRACK, NUM2INT(rate));
582
+ return rate;
583
+ }
584
+
585
+ static VALUE af_byte_order_eq(VALUE obj, VALUE byte_order)
586
+ {
587
+ struct af_data *afp;
588
+
589
+ GetAFPWithoutOpenChecking(obj, afp);
590
+ bail_if_open(afp, ATTEMPT("byte order"));
591
+
592
+ afInitByteOrder(afp->setup, AF_DEFAULT_TRACK, NUM2INT(byte_order));
593
+ return byte_order;
594
+ }
595
+
596
+ static VALUE af_virtual_byte_order_eq(VALUE obj, VALUE new_bo)
597
+ {
598
+ struct af_data *afp;
599
+
600
+ GetAFP(obj, afp);
601
+
602
+ /* for now */
603
+ afSetVirtualByteOrder(afp->handle, AF_DEFAULT_TRACK, NUM2INT(new_bo));
604
+
605
+ return new_bo;
606
+ }
607
+
608
+ static VALUE af_channels_eq(VALUE obj, VALUE channels)
609
+ {
610
+ struct af_data *afp;
611
+
612
+ GetAFPWithoutOpenChecking(obj, afp);
613
+
614
+ bail_if_open(afp, ATTEMPT("channels"));
615
+
616
+ afInitChannels(afp->setup, AF_DEFAULT_TRACK, NUM2INT(channels));
617
+ return channels;
618
+ }
619
+
620
+ /* Details about this dirty hack.
621
+ * I added two members, sample_format and sample_width, to the
622
+ * af_data structure because you can only set them both at a time,
623
+ * and you can't get inside the AFfilesetup structure prettily.
624
+ * So those are to preserve what you set the sample_format to so
625
+ * that the sample_width can set it to that, and vice versa.
626
+ * They only have defaults so that your program won't barf if you
627
+ * don't explicitly set one or both. Course, your program will barf
628
+ * if you don't set the rest of the stuff in the filesetup structure
629
+ * anyway... unless afNewFileSetup makes the new filesetup have defaults
630
+ *
631
+ */
632
+
633
+ static VALUE af_sample_format_eq(VALUE obj, VALUE sample_format)
634
+ {
635
+ struct af_data *afp;
636
+
637
+ GetAFPWithoutOpenChecking(obj, afp);
638
+ bail_if_open(afp, ATTEMPT("sample format"));
639
+
640
+ afp->sample_format = NUM2INT(sample_format);
641
+ afInitSampleFormat(afp->setup, AF_DEFAULT_TRACK,
642
+ afp->sample_format,
643
+ afp->sample_width);
644
+ return sample_format;
645
+ }
646
+
647
+ static VALUE af_sample_width_eq(VALUE obj, VALUE sample_width)
648
+ {
649
+ struct af_data *afp;
650
+
651
+ GetAFPWithoutOpenChecking(obj, afp);
652
+ bail_if_open(afp, ATTEMPT("sample width"));
653
+
654
+ afp->sample_width = NUM2INT(sample_width);
655
+ afInitSampleFormat(afp->setup, AF_DEFAULT_TRACK,
656
+ afp->sample_format,
657
+ afp->sample_width);
658
+ return sample_width;
659
+ }
660
+
661
+ static VALUE af_compression_eq(VALUE obj, VALUE compression)
662
+ {
663
+ struct af_data *afp;
664
+ GetAFPWithoutOpenChecking(obj, afp);
665
+ bail_if_open(afp, ATTEMPT("compression scheme"));
666
+
667
+ afInitCompression(afp->setup, AF_DEFAULT_TRACK, NUM2INT(compression));
668
+ return compression;
669
+ }
670
+
671
+
672
+
673
+
674
+
675
+ static VALUE af_pcm_mapping_eq(VALUE obj, VALUE args)
676
+ {
677
+ VALUE v_slope, v_intercept, v_min_clip, v_max_clip;
678
+ /* double slope, intercept, min_clip, max_clip; */
679
+ struct af_data *afp;
680
+
681
+ Check_Type(args, T_ARRAY);
682
+ if(RARRAY(args)->len != 1) {
683
+ rb_raise(rb_eArgError, "incorrect argument(s) to AudioFile#pcm_mapping=");
684
+ }
685
+ args = *(RARRAY(args)->ptr);
686
+ if(RARRAY(args)->len != 4) {
687
+ rb_raise(rb_eArgError, "incorrect argument(s) to AudioFile#pcm_mapping=");
688
+ }
689
+
690
+ v_slope = RARRAY(args)->ptr[0];
691
+ v_intercept = RARRAY(args)->ptr[1];
692
+ v_min_clip = RARRAY(args)->ptr[2];
693
+ v_max_clip = RARRAY(args)->ptr[3];
694
+ Check_Type(v_slope, T_FLOAT);
695
+ Check_Type(v_intercept, T_FLOAT);
696
+ Check_Type(v_min_clip, T_FLOAT);
697
+ Check_Type(v_max_clip, T_FLOAT);
698
+
699
+ GetAFPWithoutOpenChecking(obj, afp);
700
+
701
+ if(af_is_open(afp)) {
702
+ afSetTrackPCMMapping(afp->handle, AF_DEFAULT_TRACK,
703
+ RFLOAT(v_slope)->value, RFLOAT(v_intercept)->value,
704
+ RFLOAT(v_min_clip)->value, RFLOAT(v_max_clip)->value);
705
+ } else {
706
+ afInitPCMMapping(afp->setup, AF_DEFAULT_TRACK,
707
+ RFLOAT(v_slope)->value, RFLOAT(v_intercept)->value,
708
+ RFLOAT(v_min_clip)->value, RFLOAT(v_max_clip)->value);
709
+ }
710
+
711
+ return Qnil;
712
+ }
713
+
714
+
715
+ void af_error_function(long error_num, const char *message)
716
+ {
717
+ rb_raise(rb_eAudioFileError, message);
718
+ }
719
+
720
+ void Init_audiofile()
721
+ {
722
+ struct {
723
+ const char *name;
724
+ VALUE (*func)();
725
+ int args;
726
+ } instance_methods[] = {
727
+ { "initialize", af_initialize, -1 },
728
+ { "close", af_close, 0 },
729
+ { "read", af_read, -1 },
730
+ { "flush", af_flush, 0 },
731
+ { "write", af_write, 1 },
732
+ { "read_into", af_read_into, 1 },
733
+ { "frame_size", af_frame_size, 0 },
734
+ { "frame_count", af_frame_count, 0 },
735
+
736
+ /* getters */
737
+ { "pos", af_pos, 0 },
738
+ { "rate", af_sample_rate, 0 },
739
+ { "bits", af_sample_width, 0 },
740
+ { "channels", af_channels, 0 },
741
+ { "byte_order", af_byte_order, 0 },
742
+ { "compression", af_compression, 0 },
743
+ { "file_format", af_file_format, 0 },
744
+ { "sample_format", af_sample_format, 0 },
745
+ { "virtual_byte_order", af_virtual_byte_order, 0 },
746
+ { "pcm_mapping", af_pcm_mapping, 0 },
747
+ { "file_format_version", af_file_format_version, 0 },
748
+
749
+ /* setters */
750
+ { "pos=", af_pos_eq, 1 },
751
+ { "rate=", af_sample_rate_eq, 1 },
752
+ { "bits=", af_sample_width_eq, 1 },
753
+ { "channels=", af_channels_eq, 1 },
754
+ { "byte_order=", af_byte_order_eq, 1 },
755
+ { "compression=", af_compression_eq, 1 },
756
+ { "file_format=", af_file_format_eq, 1 },
757
+ { "sample_format=", af_sample_format_eq, 1 },
758
+ { "virtual_byte_order=", af_virtual_byte_order_eq, 1 },
759
+ { "pcm_mapping=", af_pcm_mapping_eq, -2 },
760
+ { 0 }
761
+ };
762
+
763
+ struct {
764
+ const char *name;
765
+ VALUE value;
766
+ } constants[] = {
767
+ { "BIG_ENDIAN", INT2FIX(AF_BYTEORDER_BIGENDIAN) },
768
+ { "LITTLE_ENDIAN", INT2FIX(AF_BYTEORDER_LITTLEENDIAN) },
769
+
770
+ { "TWOS_COMPLEMENT", INT2FIX(AF_SAMPFMT_TWOSCOMP) },
771
+ { "UNSIGNED", INT2FIX(AF_SAMPFMT_UNSIGNED) },
772
+ { "FLOAT", INT2FIX(AF_SAMPFMT_FLOAT) },
773
+ { "DOUBLE", INT2FIX(AF_SAMPFMT_DOUBLE) },
774
+
775
+ { "COMPRESSION_UNKNOWN", INT2FIX(AF_COMPRESSION_UNKNOWN) },
776
+ { "NONE", INT2FIX(AF_COMPRESSION_NONE) },
777
+ { "G722", INT2FIX(AF_COMPRESSION_G722) },
778
+ { "G711_ULAW", INT2FIX(AF_COMPRESSION_G711_ULAW) },
779
+ { "G711_ALAW", INT2FIX(AF_COMPRESSION_G711_ALAW) },
780
+ { "APPLE_ACE2", INT2FIX(AF_COMPRESSION_APPLE_ACE2) },
781
+ { "APPLE_ACE8", INT2FIX(AF_COMPRESSION_APPLE_ACE8) },
782
+ { "APPLE_MAC3", INT2FIX(AF_COMPRESSION_APPLE_MAC3) },
783
+ { "APPLE_MAC6", INT2FIX(AF_COMPRESSION_APPLE_MAC6) },
784
+ { "G726", INT2FIX(AF_COMPRESSION_G726) },
785
+ { "G728", INT2FIX(AF_COMPRESSION_G728) },
786
+ { "DVI_AUDIO", INT2FIX(AF_COMPRESSION_DVI_AUDIO) },
787
+ { "GSM", INT2FIX(AF_COMPRESSION_GSM) },
788
+ { "FS1016", INT2FIX(AF_COMPRESSION_FS1016) },
789
+
790
+ { "FILE_UNKNOWN", INT2FIX(AF_FILE_UNKNOWN) },
791
+ { "RAW", INT2FIX(AF_FILE_RAWDATA) },
792
+ { "AIFF_C", INT2FIX(AF_FILE_AIFFC) },
793
+ { "AIFF", INT2FIX(AF_FILE_AIFF) },
794
+ { "NEXT_SND", INT2FIX(AF_FILE_NEXTSND) },
795
+ { "WAV", INT2FIX(AF_FILE_WAVE) },
796
+ { 0 }
797
+ };
798
+
799
+ int i;
800
+
801
+ afSetErrorHandler(af_error_function);
802
+
803
+ cAudioFile = rb_define_class("AudioFile", rb_cObject);
804
+ rb_eAudioFileError = rb_define_class("AudioFileError", rb_eStandardError);
805
+
806
+ rb_define_singleton_method(cAudioFile, "new", af_s_new, -1);
807
+ rb_define_singleton_method(cAudioFile, "open", af_s_open, -1);
808
+
809
+ for(i=0; instance_methods[i].name; i++) {
810
+ rb_define_method(cAudioFile, instance_methods[i].name,
811
+ instance_methods[i].func, instance_methods[i].args);
812
+ }
813
+
814
+ /*rb_define_method(cAudioFile, "pcm_mapping", af_pcm_mapping, 0);
815
+ *
816
+ * afGetPCMMapping is declared in audiofile.h, but not defined in
817
+ * libaudiofile.so! So I can't call it. So this method doesn't get defined.
818
+ *
819
+ */
820
+
821
+
822
+ /*
823
+ * these might need synchronization with other people's constants
824
+ * this would require changing the sample_format and other functions
825
+ * (see "for now" in above functions.)
826
+ *
827
+ */
828
+
829
+ for(i=0; constants[i].name; i++) {
830
+ rb_define_const(cAudioFile, constants[i].name, constants[i].value);
831
+ }
832
+
833
+ }