taglib-ruby 0.2.1 → 0.3.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 (53) hide show
  1. data/CHANGES.md +7 -0
  2. data/Gemfile +1 -2
  3. data/Gemfile.lock +9 -8
  4. data/README.md +22 -7
  5. data/Rakefile +9 -15
  6. data/docs/taglib/base.rb +31 -8
  7. data/docs/taglib/id3v1.rb +5 -0
  8. data/docs/taglib/mpeg.rb +8 -0
  9. data/docs/taglib/ogg.rb +77 -0
  10. data/docs/taglib/vorbis.rb +43 -0
  11. data/ext/taglib_base/includes.i +25 -1
  12. data/ext/taglib_base/taglib_base.i +46 -2
  13. data/ext/taglib_base/taglib_base_wrap.cxx +176 -185
  14. data/ext/taglib_id3v1/extconf.rb +4 -0
  15. data/ext/taglib_id3v1/taglib_id3v1.i +11 -0
  16. data/ext/taglib_id3v1/taglib_id3v1_wrap.cxx +3092 -0
  17. data/ext/taglib_id3v2/taglib_id3v2.i +0 -8
  18. data/ext/taglib_id3v2/taglib_id3v2_wrap.cxx +194 -248
  19. data/ext/taglib_mpeg/taglib_mpeg.i +16 -2
  20. data/ext/taglib_mpeg/taglib_mpeg_wrap.cxx +157 -149
  21. data/ext/taglib_ogg/extconf.rb +4 -0
  22. data/ext/taglib_ogg/taglib_ogg.i +36 -0
  23. data/ext/taglib_ogg/taglib_ogg_wrap.cxx +3613 -0
  24. data/ext/taglib_vorbis/extconf.rb +4 -0
  25. data/ext/taglib_vorbis/taglib_vorbis.i +48 -0
  26. data/ext/taglib_vorbis/taglib_vorbis_wrap.cxx +3056 -0
  27. data/ext/win.cmake +6 -0
  28. data/lib/taglib/id3v1.rb +1 -0
  29. data/lib/taglib/ogg.rb +1 -0
  30. data/lib/taglib/version.rb +2 -2
  31. data/lib/taglib/vorbis.rb +1 -0
  32. data/lib/taglib.rb +10 -0
  33. data/taglib-ruby.gemspec +35 -11
  34. data/tasks/ext.rake +79 -0
  35. data/tasks/swig.rake +43 -0
  36. data/test/data/Makefile +15 -0
  37. data/test/data/id3v1-create.cpp +31 -0
  38. data/test/data/id3v1.mp3 +0 -0
  39. data/test/data/vorbis-create.cpp +42 -0
  40. data/test/data/vorbis.oga +0 -0
  41. data/test/test_fileref_write.rb +38 -0
  42. data/test/test_id3v1_tag.rb +36 -0
  43. data/test/test_id3v2_frames.rb +5 -0
  44. data/test/test_id3v2_memory.rb +23 -0
  45. data/test/test_id3v2_relative_volume.rb +5 -0
  46. data/test/test_id3v2_tag.rb +5 -0
  47. data/test/test_id3v2_unicode.rb +5 -0
  48. data/test/test_id3v2_write.rb +6 -1
  49. data/test/test_mpeg_file.rb +18 -1
  50. data/test/test_vorbis_file.rb +44 -0
  51. data/test/test_vorbis_tag.rb +79 -0
  52. metadata +113 -137
  53. data/ext/Rakefile +0 -32
data/CHANGES.md CHANGED
@@ -1,6 +1,13 @@
1
1
  Changes in Releases of taglib-ruby
2
2
  ==================================
3
3
 
4
+ ## 0.3.0 (2012-01-02)
5
+
6
+ * Add support for Ogg Vorbis
7
+ * Add support for ID3v1 (#2)
8
+ * Add #close to File classes for explicitly releasing resources
9
+ * Fix compilation on Windows
10
+
4
11
  ## 0.2.1 (2011-11-05)
5
12
 
6
13
  * Fix compilation error due to missing typedef on some systems (#5)
data/Gemfile CHANGED
@@ -6,8 +6,7 @@ group :development do
6
6
  gem 'shoulda', '~> 2.11'
7
7
  gem 'bundler', '~> 1.0.0'
8
8
  gem 'jeweler', '~> 1.6.4'
9
- gem 'rcov', '>= 0'
10
9
  gem 'yard', '~> 0.7'
11
- gem 'redcarpet'
10
+ gem 'redcarpet', '~> 1.0'
12
11
  gem 'guard-test', '~> 0.4.0'
13
12
  end
data/Gemfile.lock CHANGED
@@ -1,35 +1,36 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
+ ffi (1.0.11)
4
5
  git (1.2.5)
5
- guard (0.8.4)
6
+ guard (0.9.3)
7
+ ffi (>= 0.5.0)
6
8
  thor (~> 0.14.6)
7
- guard-test (0.4.0)
9
+ guard-test (0.4.3)
8
10
  guard (>= 0.4)
9
11
  test-unit (~> 2.2)
10
12
  jeweler (1.6.4)
11
13
  bundler (~> 1.0)
12
14
  git (>= 1.2.5)
13
15
  rake
14
- rake (0.9.2)
16
+ rake (0.9.2.2)
15
17
  rake-compiler (0.7.9)
16
18
  rake
17
- rcov (0.9.11)
18
19
  redcarpet (1.17.2)
19
20
  shoulda (2.11.3)
20
- test-unit (2.4.0)
21
+ test-unit (2.4.3)
21
22
  thor (0.14.6)
22
- yard (0.7.3)
23
+ yard (0.7.4)
23
24
 
24
25
  PLATFORMS
25
26
  ruby
27
+ x86-mingw32
26
28
 
27
29
  DEPENDENCIES
28
30
  bundler (~> 1.0.0)
29
31
  guard-test (~> 0.4.0)
30
32
  jeweler (~> 1.6.4)
31
33
  rake-compiler (~> 0.7)
32
- rcov
33
- redcarpet
34
+ redcarpet (~> 1.0)
34
35
  shoulda (~> 2.11)
35
36
  yard (~> 0.7)
data/README.md CHANGED
@@ -3,15 +3,24 @@ taglib-ruby
3
3
 
4
4
  Ruby interface for the [TagLib C++ library][taglib].
5
5
 
6
- In contrast to other libraries, this one wraps the full C++ API using
7
- SWIG, not only the minimal C API. This means that all tags can be
8
- accessed.
6
+ In contrast to other libraries, this one wraps the full C++ API, not
7
+ only the minimal C API. This means that all tag data can be accessed,
8
+ e.g. cover art of ID3v2 or custom fields of Ogg Vorbis comments.
9
9
 
10
- taglib-ruby is work in progress, here are some of the things still left
11
- to do (contributors very welcome):
10
+ taglib-ruby is work in progress, but the following is already available:
12
11
 
13
- * Pre-compiled Gem for Windows
14
- * More coverage of the library besides ID3v2
12
+ * Reading/writing common tag data of all formats that TagLib supports
13
+ * Reading/writing ID3v1 and ID3v2 including ID3v2.4 and Unicode
14
+ * Reading/writing Ogg Vorbis comments
15
+ * Reading audio properties (e.g. bitrate) of the above formats
16
+
17
+ Some things are still left to do (contributors very welcome):
18
+
19
+ * Pre-compiled Gem for Windows:
20
+ * Unicode filename support
21
+ * More coverage of the library
22
+
23
+ [![flattr this project][flattr-img]][flattr-link]
15
24
 
16
25
  Installation
17
26
  ------------
@@ -61,6 +70,9 @@ track.to_s #=> "7/10"
61
70
  cover = tag.frame_list('APIC').first
62
71
  cover.mime_type #=> "image/jpeg"
63
72
  cover.picture #=> "\xFF\xD8\xFF\xE0\x00\x10JFIF..."
73
+
74
+ # Close file to release resources
75
+ file.close
64
76
  ```
65
77
 
66
78
  And here's an example for writing one:
@@ -83,6 +95,7 @@ apic.picture = File.open("cover.jpg", 'rb'){ |f| f.read }
83
95
  tag.add_frame(apic)
84
96
 
85
97
  file.save
98
+ file.close
86
99
  ```
87
100
 
88
101
  ### Encoding
@@ -139,3 +152,5 @@ see LICENSE.txt for details.
139
152
  Copyright (c) 2010, 2011 Robin Stocker.
140
153
 
141
154
  [taglib]: http://developer.kde.org/~wheeler/taglib.html
155
+ [flattr-img]: http://api.flattr.com/button/flattr-badge-large.png
156
+ [flattr-link]: https://flattr.com/submit/auto?user_id=robinst&url=https://github.com/robinst/taglib-ruby&title=taglib-ruby&tags=github&category=software
data/Rakefile CHANGED
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'rubygems'
4
+ require "rubygems/package_task"
4
5
  require 'bundler'
5
6
  begin
6
7
  Bundler.setup(:default, :development)
@@ -13,7 +14,7 @@ require 'rake'
13
14
 
14
15
  require 'jeweler'
15
16
  require './lib/taglib/version.rb'
16
- Jeweler::Tasks.new do |gem|
17
+ jeweler_tasks = Jeweler::Tasks.new do |gem|
17
18
  # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
18
19
  gem.name = "taglib-ruby"
19
20
  gem.summary = %Q{Ruby interface for the taglib C++ library}
@@ -31,16 +32,15 @@ not only the minimal C API. This means that all tags can be accessed.
31
32
  gem.authors = ["Robin Stocker"]
32
33
  gem.extensions = ['ext/taglib_base/extconf.rb',
33
34
  'ext/taglib_mpeg/extconf.rb',
34
- 'ext/taglib_id3v2/extconf.rb']
35
+ 'ext/taglib_id3v1/extconf.rb',
36
+ 'ext/taglib_id3v2/extconf.rb',
37
+ 'ext/taglib_ogg/extconf.rb',
38
+ 'ext/taglib_vorbis/extconf.rb']
39
+ gem.extra_rdoc_files = ["README.md", "CHANGES.md", "LICENSE.txt"]
35
40
  # dependencies defined in Gemfile
36
41
  end
37
42
  Jeweler::RubygemsDotOrgTasks.new
38
43
 
39
- require 'rake/extensiontask'
40
- Rake::ExtensionTask.new("taglib_base")
41
- Rake::ExtensionTask.new("taglib_mpeg")
42
- Rake::ExtensionTask.new("taglib_id3v2")
43
-
44
44
  require 'rake/testtask'
45
45
  Rake::TestTask.new(:test) do |test|
46
46
  test.libs << 'lib' << 'test'
@@ -48,14 +48,6 @@ Rake::TestTask.new(:test) do |test|
48
48
  test.verbose = true
49
49
  end
50
50
 
51
- require 'rcov/rcovtask'
52
- Rcov::RcovTask.new do |test|
53
- test.libs << 'test'
54
- test.pattern = 'test/**/test_*.rb'
55
- test.verbose = true
56
- test.rcov_opts << '--exclude "gems/*"'
57
- end
58
-
59
51
  task :default => :test
60
52
 
61
53
  require 'yard'
@@ -64,4 +56,6 @@ YARD::Rake::YardocTask.new do |t|
64
56
  t.options = ['--title', "taglib-ruby #{version}"]
65
57
  end
66
58
 
59
+ $gemspec = jeweler_tasks.jeweler.gemspec.dup
60
+
67
61
  FileList['tasks/**/*.rake'].each { |task| import task }
data/docs/taglib/base.rb CHANGED
@@ -7,6 +7,7 @@
7
7
  # * Reading properties of MPEG files: {TagLib::MPEG::File}
8
8
  # * Reading/writing ID3v2 tags: {TagLib::MPEG::File} and
9
9
  # {TagLib::MPEG::File#id3v2_tag}
10
+ # * Reading/writing Ogg Vorbis tags: {TagLib::Ogg::Vorbis::File}.
10
11
  #
11
12
  # ## String Encodings
12
13
  #
@@ -60,10 +61,36 @@ module TagLib
60
61
  # @return [TagLib::Tag] the tag
61
62
  def tag
62
63
  end
64
+
65
+ # Closes the file and releases all objects that were read from the
66
+ # file.
67
+ #
68
+ # @see TagLib::File#close
69
+ #
70
+ # @return [void]
71
+ def close
72
+ end
63
73
  end
64
74
 
65
75
  # @abstract Base class for files, see subclasses.
66
76
  class File
77
+ # Closes the file and releases all objects that were read from the
78
+ # file.
79
+ #
80
+ # After this method has been called, no other methods on this object
81
+ # may be called. So it's a good idea to always use it like this:
82
+ #
83
+ # file.close
84
+ # file = nil
85
+ #
86
+ # This method should always be called as soon as you're finished
87
+ # with a file. Otherwise the file will only be closed when GC is
88
+ # run, which may be much later. On Windows, this is especially
89
+ # important as the file is locked until it is closed.
90
+ #
91
+ # @return [void]
92
+ def close
93
+ end
67
94
  end
68
95
 
69
96
  # @abstract Base class for tags.
@@ -112,19 +139,15 @@ module TagLib
112
139
  Accurate = 2
113
140
 
114
141
  # @return [Integer] length of the file in seconds
115
- def length
116
- end
142
+ attr_reader :length
117
143
 
118
144
  # @return [Integer] bit rate in kb/s (kilobit per second)
119
- def bitrate
120
- end
145
+ attr_reader :bitrate
121
146
 
122
147
  # @return [Integer] sample rate in Hz
123
- def sample_rate
124
- end
148
+ attr_reader :sample_rate
125
149
 
126
150
  # @return [Integer] number of channels
127
- def channels
128
- end
151
+ attr_reader :channels
129
152
  end
130
153
  end
@@ -0,0 +1,5 @@
1
+ module TagLib::ID3v1
2
+ # An ID3v1 tag.
3
+ class Tag < TagLib::Tag
4
+ end
5
+ end
data/docs/taglib/mpeg.rb CHANGED
@@ -17,6 +17,14 @@ module TagLib::MPEG
17
17
  def tag
18
18
  end
19
19
 
20
+ # Returns the ID3v1 tag.
21
+ #
22
+ # @param create if a new tag should be created when none exists
23
+ # @return [TagLib::ID3v1::Tag]
24
+ # @return [nil] if not present
25
+ def id3v1_tag(create=false)
26
+ end
27
+
20
28
  # Returns the ID3v2 tag.
21
29
  #
22
30
  # @param create if a new tag should be created when none exists
@@ -0,0 +1,77 @@
1
+ module TagLib::Ogg
2
+
3
+ # @abstract Base class for Ogg files, see subclasses.
4
+ class File < TagLib::File
5
+ end
6
+
7
+ # Xiph comments (aka VorbisComment), a metadata format used for Ogg
8
+ # Vorbis and other codecs.
9
+ #
10
+ # A Xiph comment is structured as a set of fields. Each field has a
11
+ # name and a value. Multiple fields with the same name are allowed, so
12
+ # you can also view it as a map from names to a list of values.
13
+ class XiphComment < TagLib::Tag
14
+
15
+ # Add a name-value pair to the comment.
16
+ #
17
+ # @param [String] name field name
18
+ # @param [String] value field value
19
+ # @param [Boolean] replace if true, all existing fields with the
20
+ # given name will be replaced
21
+ # @return [void]
22
+ def add_field(name, value, replace=true)
23
+ end
24
+
25
+ # Check if the comment contains a field.
26
+ #
27
+ # @param [String] name field name
28
+ # @return [Boolean]
29
+ def contains?(name)
30
+ end
31
+
32
+ # Count the number of fields.
33
+ #
34
+ # @return [Integer] the number of fields in the comment (name-value
35
+ # pairs)
36
+ def field_count
37
+ end
38
+
39
+ # Get the contents of the comment as a hash, with the key being a
40
+ # field name String and the value a list of field values for that
41
+ # key. Example result:
42
+ #
43
+ # { 'TITLE' => ["Title"],
44
+ # 'GENRE' => ["Rock", "Pop"] }
45
+ #
46
+ # Note that the returned hash is read-only. Changing it will have no
47
+ # effect on the comment; use {#add_field} and {#remove_field} for
48
+ # that.
49
+ #
50
+ # @return [Hash<String, Array<String>>] a hash from field names to
51
+ # value lists
52
+ def field_list_map
53
+ end
54
+
55
+ # Remove one or more fields.
56
+ #
57
+ # @overload remove_field(name)
58
+ # Removes all fields with the given name.
59
+ #
60
+ # @param [String] name field name
61
+ #
62
+ # @overload remove_field(name, value)
63
+ # Removes the field with the given name and value.
64
+ #
65
+ # @param [String] name field name
66
+ # @param [String] value field value
67
+ #
68
+ # @return [void]
69
+ def remove_field
70
+ end
71
+
72
+ # @return [String] vendor ID of the encoder used
73
+ attr_reader :vendor_id
74
+
75
+ end
76
+
77
+ end
@@ -0,0 +1,43 @@
1
+ module TagLib::Ogg::Vorbis
2
+
3
+ # The file class for `.ogg` and other `.oga` files.
4
+ class File < TagLib::Ogg::File
5
+ # Load an Ogg Vorbis file.
6
+ #
7
+ # @param [String] filename
8
+ # @param [Boolean] read_properties if audio properties should be
9
+ # read
10
+ def initialize(filename, read_properties=true)
11
+ end
12
+
13
+ # Returns the VorbisComment tag.
14
+ #
15
+ # @return [TagLib::Ogg::XiphComment]
16
+ def tag
17
+ end
18
+
19
+ # Returns audio properties.
20
+ #
21
+ # @return [TagLib::Ogg::Vorbis::Properties]
22
+ def audio_properties
23
+ end
24
+ end
25
+
26
+ # Ogg Vorbis audio properties.
27
+ class Properties < TagLib::AudioProperties
28
+ # @return [Integer] Vorbis version
29
+ attr_reader :vorbis_version
30
+
31
+ # @return [Integer] maximum bitrate from Vorbis identification
32
+ # header
33
+ attr_reader :bitrate_maximum
34
+
35
+ # @return [Integer] nominal bitrate from Vorbis identification
36
+ # header
37
+ attr_reader :bitrate_nominal
38
+
39
+ # @return [Integer] minimum bitrate from Vorbis identification
40
+ # header
41
+ attr_reader :bitrate_minimum
42
+ end
43
+ end
@@ -1,7 +1,8 @@
1
1
  %trackobjects;
2
2
 
3
- // Undefine macro
3
+ // Undefine macros we don't need for wrapping
4
4
  #define TAGLIB_EXPORT
5
+ #define TAGLIB_IGNORE_MISSING_DESTRUCTOR
5
6
 
6
7
  // Replaces the typemap from swigtype.swg and just adds the line
7
8
  // SWIG_RubyUnlinkObjects. This is done to be safe in the case when a
@@ -15,6 +16,10 @@
15
16
  }
16
17
 
17
18
  %{
19
+ #include <taglib/tstring.h>
20
+ #include <taglib/tstringlist.h>
21
+ #include <taglib/tfile.h>
22
+
18
23
  #if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H
19
24
  # include <ruby/encoding.h>
20
25
  # define ASSOCIATE_UTF8_ENCODING(value) rb_enc_associate(value, rb_utf8_encoding());
@@ -68,6 +73,25 @@ TagLib::StringList ruby_array_to_taglib_string_list(VALUE ary) {
68
73
  }
69
74
  return result;
70
75
  }
76
+
77
+ VALUE taglib_filename_to_ruby_string(TagLib::FileName filename) {
78
+ #ifdef _WIN32
79
+ const char *s = (const char *) filename;
80
+ return rb_tainted_str_new2(s);
81
+ #else
82
+ return rb_tainted_str_new2(filename);
83
+ #endif
84
+ }
85
+
86
+ TagLib::FileName ruby_string_to_taglib_filename(VALUE s) {
87
+ #ifdef _WIN32
88
+ const char *filename = StringValuePtr(s);
89
+ return TagLib::FileName(filename);
90
+ #else
91
+ return StringValuePtr(s);
92
+ #endif
93
+ }
94
+
71
95
  %}
72
96
 
73
97
  // vim: set filetype=cpp sw=2 ts=2 expandtab: