taglib-ruby 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1552,7 +1552,7 @@ SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int flags)
1552
1552
  downcast methods. */
1553
1553
  if (obj != Qnil) {
1554
1554
  VALUE value = rb_iv_get(obj, "@__swigtype__");
1555
- char* type_name = RSTRING_PTR(value);
1555
+ const char* type_name = RSTRING_PTR(value);
1556
1556
 
1557
1557
  if (strcmp(type->name, type_name) == 0) {
1558
1558
  return obj;
@@ -78,14 +78,7 @@ VALUE taglib_id3v2_framelist_to_ruby_array(TagLib::ID3v2::FrameList *list) {
78
78
  }
79
79
  %apply TagLib::ID3v2::FrameList & { const TagLib::ID3v2::FrameList & };
80
80
 
81
- %typemap(in, noblock=1) TagLib::ID3v2::Frame * (int res = 0) {
82
- res = SWIG_ConvertPtr($input, %as_voidptrptr(&$1), $descriptor, SWIG_POINTER_DISOWN | %convertptr_flags);
83
- if (!SWIG_IsOK(res)) {
84
- %argument_fail(res, "$type", $symname, $argnum);
85
- }
86
- SWIG_RubyUnlinkObjects($1);
87
- SWIG_RubyRemoveTracking($1);
88
- }
81
+ %apply SWIGTYPE *DISOWN { TagLib::ID3v2::Frame *frame };
89
82
  %ignore TagLib::ID3v2::Tag::removeFrame(Frame *, bool);
90
83
  %include <taglib/id3v2tag.h>
91
84
  %clear TagLib::ID3v2::Frame *;
@@ -1552,7 +1552,7 @@ SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int flags)
1552
1552
  downcast methods. */
1553
1553
  if (obj != Qnil) {
1554
1554
  VALUE value = rb_iv_get(obj, "@__swigtype__");
1555
- char* type_name = RSTRING_PTR(value);
1555
+ const char* type_name = RSTRING_PTR(value);
1556
1556
 
1557
1557
  if (strcmp(type->name, type_name) == 0) {
1558
1558
  return obj;
@@ -1555,7 +1555,7 @@ SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int flags)
1555
1555
  downcast methods. */
1556
1556
  if (obj != Qnil) {
1557
1557
  VALUE value = rb_iv_get(obj, "@__swigtype__");
1558
- char* type_name = RSTRING_PTR(value);
1558
+ const char* type_name = RSTRING_PTR(value);
1559
1559
 
1560
1560
  if (strcmp(type->name, type_name) == 0) {
1561
1561
  return obj;
@@ -1552,7 +1552,7 @@ SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int flags)
1552
1552
  downcast methods. */
1553
1553
  if (obj != Qnil) {
1554
1554
  VALUE value = rb_iv_get(obj, "@__swigtype__");
1555
- char* type_name = RSTRING_PTR(value);
1555
+ const char* type_name = RSTRING_PTR(value);
1556
1556
 
1557
1557
  if (strcmp(type->name, type_name) == 0) {
1558
1558
  return obj;
@@ -1555,7 +1555,7 @@ SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int flags)
1555
1555
  downcast methods. */
1556
1556
  if (obj != Qnil) {
1557
1557
  VALUE value = rb_iv_get(obj, "@__swigtype__");
1558
- char* type_name = RSTRING_PTR(value);
1558
+ const char* type_name = RSTRING_PTR(value);
1559
1559
 
1560
1560
  if (strcmp(type->name, type_name) == 0) {
1561
1561
  return obj;
data/lib/taglib.rb CHANGED
@@ -12,3 +12,4 @@ require 'taglib/id3v1'
12
12
  require 'taglib/id3v2'
13
13
  require 'taglib/ogg'
14
14
  require 'taglib/vorbis'
15
+ require 'taglib/flac'
@@ -0,0 +1,7 @@
1
+ require 'taglib_flac'
2
+
3
+ module TagLib::FLAC
4
+ class File
5
+ extend ::TagLib::FileOpenable
6
+ end
7
+ end
@@ -1,7 +1,7 @@
1
1
  module TagLib
2
2
  module Version
3
3
  MAJOR = 0
4
- MINOR = 4
4
+ MINOR = 5
5
5
  PATCH = 0
6
6
  BUILD = nil
7
7
 
data/taglib-ruby.gemspec CHANGED
@@ -13,7 +13,8 @@ Gem::Specification.new do |s|
13
13
  s.licenses = ["MIT"]
14
14
  s.summary = "Ruby interface for the taglib C++ library"
15
15
  s.description = <<DESC
16
- Ruby interface for the taglib C++ library.
16
+ Ruby interface for the taglib C++ library, for reading and writing
17
+ meta-data (tags) of many audio formats.
17
18
 
18
19
  In contrast to other libraries, this one wraps the C++ API using SWIG,
19
20
  not only the minimal C API. This means that all tags can be accessed.
@@ -34,6 +35,7 @@ DESC
34
35
  "ext/taglib_id3v2/extconf.rb",
35
36
  "ext/taglib_ogg/extconf.rb",
36
37
  "ext/taglib_vorbis/extconf.rb",
38
+ "ext/taglib_flac/extconf.rb",
37
39
  ]
38
40
  s.extra_rdoc_files = [
39
41
  "CHANGES.md",
@@ -50,6 +52,7 @@ DESC
50
52
  "Rakefile",
51
53
  "docs/default/fulldoc/html/css/common.css",
52
54
  "docs/taglib/base.rb",
55
+ "docs/taglib/flac.rb",
53
56
  "docs/taglib/id3v1.rb",
54
57
  "docs/taglib/id3v2.rb",
55
58
  "docs/taglib/mpeg.rb",
@@ -60,6 +63,8 @@ DESC
60
63
  "ext/taglib_base/includes.i",
61
64
  "ext/taglib_base/taglib_base.i",
62
65
  "ext/taglib_base/taglib_base_wrap.cxx",
66
+ "ext/taglib_flac/taglib_flac.i",
67
+ "ext/taglib_flac/taglib_flac_wrap.cxx",
63
68
  "ext/taglib_id3v1/extconf.rb",
64
69
  "ext/taglib_id3v1/taglib_id3v1.i",
65
70
  "ext/taglib_id3v1/taglib_id3v1_wrap.cxx",
@@ -80,6 +85,7 @@ DESC
80
85
  "ext/win.cmake",
81
86
  "lib/taglib.rb",
82
87
  "lib/taglib/base.rb",
88
+ "lib/taglib/flac.rb",
83
89
  "lib/taglib/id3v1.rb",
84
90
  "lib/taglib/id3v2.rb",
85
91
  "lib/taglib/mpeg.rb",
@@ -94,7 +100,10 @@ DESC
94
100
  "test/data/Makefile",
95
101
  "test/data/add-relative-volume.cpp",
96
102
  "test/data/crash.mp3",
103
+ "test/data/flac-create.cpp",
104
+ "test/data/flac.flac",
97
105
  "test/data/globe_east_540.jpg",
106
+ "test/data/globe_east_90.jpg",
98
107
  "test/data/id3v1-create.cpp",
99
108
  "test/data/id3v1.mp3",
100
109
  "test/data/relative-volume.mp3",
@@ -106,6 +115,8 @@ DESC
106
115
  "test/fileref_open_test.rb",
107
116
  "test/fileref_properties_test.rb",
108
117
  "test/fileref_write_test.rb",
118
+ "test/flac_file_test.rb",
119
+ "test/flac_file_write_test.rb",
109
120
  "test/id3v1_tag_test.rb",
110
121
  "test/id3v2_frames_test.rb",
111
122
  "test/id3v2_memory_test.rb",
@@ -4,19 +4,34 @@ task :docs_coverage do |t|
4
4
  objects.sort_by { |obj| obj.path }
5
5
  end
6
6
 
7
+ def synthetic_methods(cls)
8
+ methods = cls.inherited_meths
9
+ methods.map do |m|
10
+ YARD::CodeObjects::MethodObject.new(cls, m.name)
11
+ end
12
+ end
13
+
7
14
  YARD.parse("ext/**/*_wrap.cxx")
8
15
  ext_codeobjects = sort(YARD::Registry.all)
16
+
9
17
  YARD::Registry.clear
10
18
  YARD.parse("docs/**/*.rb")
11
- docs_codeobjects = sort(YARD::Registry.all(:module, :class, :method))
19
+ docs_classes = YARD::Registry.all(:class)
20
+ docs_others = YARD::Registry.all(:module, :method)
21
+ docs_codeobjects = sort(docs_classes + docs_others)
22
+
23
+ # SWIG generates methods for base classes in the subclasses too, we
24
+ # don't want them appearing in the "only in ext" list.
25
+ inherited_methods = docs_classes.map { |c| synthetic_methods(c) }.flatten
12
26
 
13
- only_in_ext = (ext_codeobjects - docs_codeobjects)
27
+ only_in_ext = (ext_codeobjects - docs_codeobjects - inherited_methods)
14
28
  only_in_docs = (docs_codeobjects - ext_codeobjects)
15
29
 
16
30
  unless only_in_ext.empty?
17
31
  puts
18
32
  puts "=== Only in ext (to document): "
19
33
  puts only_in_ext
34
+ p only_in_ext[4].explicit
20
35
  end
21
36
  unless only_in_docs.empty?
22
37
  puts
data/tasks/ext.rake CHANGED
@@ -42,6 +42,9 @@ end
42
42
  Rake::ExtensionTask.new("taglib_vorbis", $gemspec) do |ext|
43
43
  configure_cross_compile(ext)
44
44
  end
45
+ Rake::ExtensionTask.new("taglib_flac", $gemspec) do |ext|
46
+ configure_cross_compile(ext)
47
+ end
45
48
 
46
49
  task :cross => [:taglib] do
47
50
  # Mkmf just uses "g++" as C++ compiler, despite what's in rbconfig.rb.
data/tasks/swig.rake CHANGED
@@ -14,7 +14,9 @@ task :swig =>
14
14
  'ext/taglib_id3v1/taglib_id3v1_wrap.cxx',
15
15
  'ext/taglib_id3v2/taglib_id3v2_wrap.cxx',
16
16
  'ext/taglib_ogg/taglib_ogg_wrap.cxx',
17
- 'ext/taglib_vorbis/taglib_vorbis_wrap.cxx']
17
+ 'ext/taglib_vorbis/taglib_vorbis_wrap.cxx',
18
+ 'ext/taglib_flac/taglib_flac_wrap.cxx',
19
+ ]
18
20
 
19
21
  base_dependencies = ['ext/taglib_base/taglib_base.i', 'ext/taglib_base/includes.i']
20
22
 
@@ -41,3 +43,7 @@ end
41
43
  file 'ext/taglib_vorbis/taglib_vorbis_wrap.cxx' => ['ext/taglib_vorbis/taglib_vorbis.i'] + base_dependencies do
42
44
  run_swig('taglib_vorbis')
43
45
  end
46
+
47
+ file 'ext/taglib_flac/taglib_flac_wrap.cxx' => ['ext/taglib_flac/taglib_flac.i'] + base_dependencies do
48
+ run_swig('taglib_flac')
49
+ end
data/test/data/Makefile CHANGED
@@ -1,6 +1,6 @@
1
1
  .PHONY: all clean
2
2
 
3
- all:: add-relative-volume id3v1-create vorbis-create
3
+ all:: add-relative-volume id3v1-create vorbis-create flac-create
4
4
 
5
5
  add-relative-volume: add-relative-volume.cpp
6
6
  g++ -o $@ $< -ltag -I/usr/include/taglib
@@ -11,5 +11,8 @@ id3v1-create: id3v1-create.cpp
11
11
  vorbis-create: vorbis-create.cpp
12
12
  g++ -o $@ $< -ltag -I/usr/include/taglib
13
13
 
14
+ flac-create: flac-create.cpp
15
+ g++ -o $@ $< -ltag -I/usr/include/taglib
16
+
14
17
  clean::
15
- -rm add-relative-volume id3v1-create
18
+ -rm add-relative-volume id3v1-create vorbis-create flac-create
@@ -0,0 +1,80 @@
1
+ #include <iostream>
2
+ #include <fstream>
3
+ #include <stdlib.h>
4
+
5
+ #include <taglib/taglib.h>
6
+ #include <taglib/flacfile.h>
7
+ #include <taglib/xiphcomment.h>
8
+
9
+ using namespace TagLib;
10
+
11
+ ByteVector getPictureData(const char *filename);
12
+
13
+ int main(int argc, char **argv) {
14
+ if (argc != 2) {
15
+ std::cout << "usage: " << argv[0] << " file" << std::endl;
16
+ exit(1);
17
+ }
18
+ char *filename = argv[1];
19
+
20
+ FLAC::File file(filename);
21
+ Ogg::XiphComment *tag = file.xiphComment(true);
22
+
23
+ tag->setTitle("Title");
24
+ tag->setArtist("Artist");
25
+ tag->setAlbum("Album");
26
+ tag->setComment("Comment");
27
+ tag->setGenre("Pop");
28
+ tag->setYear(2011);
29
+ tag->setTrack(7);
30
+
31
+ tag->addField("VERSION", "original");
32
+ tag->addField("PERFORMER", "Performer");
33
+ tag->addField("COPYRIGHT", "2011 Me, myself and I");
34
+ tag->addField("LICENSE", "Any Use Permitted");
35
+ tag->addField("ORGANIZATION", "Organization");
36
+ tag->addField("DESCRIPTION", "Test file");
37
+ tag->addField("LOCATION", "Earth");
38
+ tag->addField("CONTACT", "Contact");
39
+
40
+ tag->addField("MULTIPLE", "A");
41
+ tag->addField("MULTIPLE", "B", false);
42
+
43
+ FLAC::Picture *picture = new FLAC::Picture();
44
+
45
+ picture->setType(FLAC::Picture::FrontCover);
46
+ picture->setMimeType("image/jpeg");
47
+ picture->setDescription("Globe");
48
+ picture->setWidth(90);
49
+ picture->setHeight(90);
50
+ picture->setColorDepth(8);
51
+ picture->setNumColors(0);
52
+
53
+ ByteVector data = getPictureData("globe_east_90.jpg");
54
+ picture->setData(data);
55
+
56
+ file.addPicture(picture);
57
+
58
+ file.save();
59
+ }
60
+
61
+ ByteVector getPictureData(const char *filename) {
62
+ std::ifstream is;
63
+ is.open(filename, std::ios::binary);
64
+
65
+ is.seekg(0, std::ios::end);
66
+ int length = is.tellg();
67
+ is.seekg(0, std::ios::beg);
68
+
69
+ char *buffer = new char[length];
70
+
71
+ is.read(buffer, length);
72
+ is.close();
73
+
74
+ ByteVector result(buffer, length);
75
+ delete[] buffer;
76
+
77
+ return result;
78
+ }
79
+
80
+ // vim: set filetype=cpp sw=2 ts=2 expandtab:
Binary file
Binary file
@@ -0,0 +1,101 @@
1
+ require File.join(File.dirname(__FILE__), 'helper')
2
+
3
+ class FlacFileTest < Test::Unit::TestCase
4
+ context "TagLib::FLAC::File" do
5
+ setup do
6
+ @file = TagLib::FLAC::File.new("test/data/flac.flac")
7
+ end
8
+
9
+ should "have a tag" do
10
+ tag = @file.tag
11
+ assert_not_nil tag
12
+ assert_equal TagLib::Tag, tag.class
13
+ end
14
+
15
+ should "have XiphComment" do
16
+ tag = @file.xiph_comment
17
+ assert_not_nil tag
18
+ assert_equal TagLib::Ogg::XiphComment, tag.class
19
+ end
20
+
21
+ should "have method for ID3v1 tag" do
22
+ assert_nil @file.id3v1_tag
23
+ end
24
+
25
+ should "have method for ID3v2 tag" do
26
+ assert_nil @file.id3v2_tag
27
+ end
28
+
29
+ context "audio properties" do
30
+ setup do
31
+ @properties = @file.audio_properties
32
+ end
33
+
34
+ should "exist" do
35
+ assert_not_nil @properties
36
+ end
37
+
38
+ should "contain basic information" do
39
+ assert_equal 1, @properties.length
40
+ assert_equal 212, @properties.bitrate
41
+ assert_equal 44100, @properties.sample_rate
42
+ assert_equal 1, @properties.channels
43
+ end
44
+
45
+ should "contain flac-specific information" do
46
+ assert_equal 16, @properties.sample_width
47
+ assert_equal "x\xD1\x9B\x86\xDF,\xD4\x88\xB3YW\xE6\xBD\x88Ih", @properties.signature
48
+ end
49
+ end
50
+
51
+ context "picture_list" do
52
+ setup do
53
+ @pictures = @file.picture_list
54
+ end
55
+
56
+ should "have a picture" do
57
+ assert_equal 1, @pictures.size
58
+ end
59
+
60
+ context "first element" do
61
+ setup do
62
+ @picture = @pictures.first
63
+ end
64
+
65
+ should "be a TagLib::FLAC::Picture," do
66
+ assert_equal TagLib::FLAC::Picture, @picture.class
67
+ end
68
+
69
+ should "have meta-data" do
70
+ assert_equal TagLib::FLAC::Picture::FrontCover, @picture.type
71
+ assert_equal "image/jpeg", @picture.mime_type
72
+ assert_equal "Globe", @picture.description
73
+ assert_equal 90, @picture.width
74
+ assert_equal 90, @picture.height
75
+ assert_equal 8, @picture.color_depth
76
+ assert_equal 0, @picture.num_colors
77
+ end
78
+
79
+ should "have data" do
80
+ picture_data = File.open("test/data/globe_east_90.jpg", 'rb'){ |f| f.read }
81
+ assert_equal picture_data, @picture.data
82
+ end
83
+ end
84
+ end
85
+
86
+ teardown do
87
+ @file.close
88
+ @file = nil
89
+ end
90
+ end
91
+
92
+ context "TagLib::FLAC::File.open" do
93
+ should "should work" do
94
+ title = nil
95
+ TagLib::FLAC::File.open("test/data/flac.flac", false) do |file|
96
+ title = file.tag.title
97
+ end
98
+ assert_equal "Title", title
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,81 @@
1
+ require File.join(File.dirname(__FILE__), 'helper')
2
+
3
+ class FlacFileWriteTest < Test::Unit::TestCase
4
+
5
+ SAMPLE_FILE = "test/data/flac.flac"
6
+ OUTPUT_FILE = "test/data/output.flac"
7
+ PICTURE_FILE = "test/data/globe_east_90.jpg"
8
+
9
+ def reloaded
10
+ TagLib::FLAC::File.open(OUTPUT_FILE, false) do |file|
11
+ yield file
12
+ end
13
+ end
14
+
15
+ context "TagLib::FLAC::File" do
16
+ setup do
17
+ FileUtils.cp SAMPLE_FILE, OUTPUT_FILE
18
+ @file = TagLib::FLAC::File.new(OUTPUT_FILE, false)
19
+ end
20
+
21
+ should "be able to save the title" do
22
+ tag = @file.tag
23
+ assert_not_nil tag
24
+ tag.title = "New Title"
25
+ success = @file.save
26
+ assert success
27
+ @file.close
28
+ @file = nil
29
+
30
+ written_title = reloaded do |file|
31
+ file.tag.title
32
+ end
33
+ assert_equal "New Title", written_title
34
+ end
35
+
36
+ should "be able to remove pictures" do
37
+ assert_equal 1, @file.picture_list.size
38
+ @file.remove_pictures
39
+ assert_equal 0, @file.picture_list.size
40
+ success = @file.save
41
+ assert success
42
+ end
43
+
44
+ should "be able to add and save a new picture" do
45
+ picture_data = File.open(PICTURE_FILE, 'rb') { |f| f.read }
46
+
47
+ pic = TagLib::FLAC::Picture.new
48
+ pic.type = TagLib::FLAC::Picture::FrontCover
49
+ pic.mime_type = "image/jpeg"
50
+ pic.description = "desc"
51
+ pic.width = 90
52
+ pic.height = 90
53
+ pic.data = picture_data
54
+
55
+ assert_equal 1, @file.picture_list.size
56
+ @file.add_picture(pic)
57
+ assert_equal 2, @file.picture_list.size
58
+
59
+ success = @file.save
60
+ assert success
61
+
62
+ reloaded do |file|
63
+ written_pic = file.picture_list.last
64
+ assert_equal TagLib::FLAC::Picture::FrontCover, written_pic.type
65
+ assert_equal "image/jpeg", written_pic.mime_type
66
+ assert_equal "desc", written_pic.description
67
+ assert_equal 90, written_pic.width
68
+ assert_equal 90, written_pic.height
69
+ assert_equal picture_data, written_pic.data
70
+ end
71
+ end
72
+
73
+ teardown do
74
+ if @file
75
+ @file.close
76
+ @file = nil
77
+ end
78
+ FileUtils.rm OUTPUT_FILE
79
+ end
80
+ end
81
+ end