taglib-ruby 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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: