Created
July 30, 2011 18:56
-
-
Save RichGuk/1115853 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Copyright 2010-2011 Vincent Carmona | |
vinc4mai+taglib@gmail.com | |
This file is part of ruby-taglib2. | |
ruby-taglib2 is free software; you can redistribute it and/or modify | |
it under the terms of the GNU General Public License as published by | |
the Free Software Foundation; either version 2 of the License, or | |
(at your option) any later version. | |
ruby-taglib2 is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License | |
along with ruby-taglib2; if not, write to the Free Software | |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
*/ | |
#include <ruby.h> | |
#include <taglib/tag_c.h> | |
typedef struct | |
{ | |
TagLib_File *file; | |
TagLib_Tag *tag; | |
const TagLib_AudioProperties *audio; | |
int closed; | |
} tgFileData; | |
VALUE mTagLib; | |
VALUE eBadFile, eBadTag, eBadAudioProperties, eFileClosed; | |
VALUE cFile; | |
static void | |
free_tgFileData(tgFileData *d) | |
{ | |
if (!d->closed) | |
taglib_file_free(d->file); | |
free(d); | |
} | |
TagLib_Tag * | |
file_tag(VALUE self) | |
{ | |
tgFileData *d; | |
TagLib_Tag *tgTag; | |
Data_Get_Struct(self, tgFileData, d); | |
if (d->tag==NULL) | |
{ | |
tgTag=taglib_file_tag(d->file); | |
if (tgTag==NULL) | |
rb_raise(eBadTag, "Bad tag"); | |
d->tag=tgTag; | |
} | |
return d->tag; | |
} | |
const TagLib_AudioProperties * | |
file_audio(VALUE self) | |
{ | |
tgFileData *d; | |
const TagLib_AudioProperties *tgAudio; | |
Data_Get_Struct(self, tgFileData, d); | |
if (d->audio==NULL) | |
{ | |
tgAudio=taglib_file_audioproperties(d->file); | |
if (tgAudio==NULL) | |
rb_raise(eBadAudioProperties, "Bad audio properties"); | |
d->audio=tgAudio; | |
} | |
return d->audio; | |
} | |
void | |
file_check_closed(VALUE self) | |
{ | |
tgFileData *d; | |
Data_Get_Struct(self, tgFileData, d); | |
if (d->closed) | |
rb_raise(eFileClosed, "File closed"); | |
} | |
/*:nodoc:*/ | |
VALUE | |
file_alloc(VALUE self) | |
{ | |
tgFileData *data; | |
data=ALLOC(tgFileData); | |
data->tag=NULL; | |
data->audio=NULL; | |
data->closed=0; | |
return Data_Wrap_Struct(self, 0, free_tgFileData, data); | |
} | |
/* | |
call-seq: new(path, type=nil) | |
Creates a new File object. | |
path: pathname of an audio file as a ruby string | |
type: a TagLib::Type (i.e TagLib::OggVorbis, TagLib::MP4) | |
*/ | |
VALUE | |
file_init(int argc, VALUE* argv, VALUE self) | |
{ | |
VALUE path, type; | |
TagLib_File *tgFile; | |
tgFileData *data; | |
rb_scan_args(argc, argv, "11", &path, &type); | |
if (NIL_P(type)) | |
{ | |
tgFile=taglib_file_new(StringValuePtr(path)); | |
} | |
else | |
{ | |
taglib_file_new_type(StringValuePtr(path), NUM2INT(type)); | |
} | |
if (tgFile==NULL) | |
rb_raise(eBadFile, "Bad file"); | |
Data_Get_Struct(self, tgFileData, data); | |
data->file=tgFile; | |
rb_iv_set(self, "@path", path); | |
rb_iv_set(self, "@type", type); | |
return Qnil; | |
} | |
/*Save modifications to the audio file.*/ | |
VALUE | |
file_save(VALUE self) | |
{ | |
tgFileData *data; | |
file_check_closed(self); | |
Data_Get_Struct(self, tgFileData, data); | |
if (taglib_file_save(data->file)) | |
{ | |
return Qtrue; | |
} | |
else | |
{ | |
return Qfalse; | |
} | |
} | |
/*Close audio file*/ | |
VALUE | |
file_close(VALUE self) | |
{ | |
tgFileData *data; | |
Data_Get_Struct(self, tgFileData, data); | |
if (data->closed) | |
return self; | |
taglib_file_free(data->file); | |
data->closed=1; | |
return self; | |
} | |
/*Get track title*/ | |
VALUE | |
file_get_title(VALUE self) | |
{ | |
VALUE str; | |
file_check_closed(self); | |
str=rb_str_new2(taglib_tag_title(file_tag(self))); | |
taglib_tag_free_strings; | |
return str; | |
} | |
/* | |
call-seq: title=title | |
Set track title to title | |
title: a string | |
*/ | |
VALUE | |
file_set_title(VALUE self, VALUE title) | |
{ | |
file_check_closed(self); | |
taglib_tag_set_title(file_tag(self), StringValuePtr(title)); | |
return title; | |
} | |
/*Get track artist*/ | |
VALUE | |
file_get_artist(VALUE self) | |
{ | |
VALUE str; | |
file_check_closed(self); | |
str=rb_str_new2(taglib_tag_artist(file_tag(self))); | |
taglib_tag_free_strings; | |
return str; | |
} | |
/* | |
call-seq: artist=artist | |
Set track artist to artist | |
artist: a string | |
*/ | |
VALUE | |
file_set_artist(VALUE self, VALUE artist) | |
{ | |
file_check_closed(self); | |
taglib_tag_set_artist(file_tag(self), StringValuePtr(artist)); | |
return artist; | |
} | |
/*Get track album*/ | |
VALUE | |
file_get_album(VALUE self) | |
{ | |
VALUE str; | |
file_check_closed(self); | |
str=rb_str_new2(taglib_tag_album(file_tag(self))); | |
taglib_tag_free_strings; | |
return str; | |
} | |
/* | |
call-seq: album=album | |
Set track album to album | |
album: a string | |
*/ | |
VALUE | |
file_set_album(VALUE self, VALUE album) | |
{ | |
file_check_closed(self); | |
taglib_tag_set_album(file_tag(self), StringValuePtr(album)); | |
return album; | |
} | |
/*Get track comment*/ | |
VALUE | |
file_get_comment(VALUE self) | |
{ | |
VALUE str; | |
file_check_closed(self); | |
str=rb_str_new2(taglib_tag_comment(file_tag(self))); | |
taglib_tag_free_strings; | |
return str; | |
} | |
/* | |
call-seq: comment=comment | |
Set track comment to comment | |
comment: a string | |
*/ | |
VALUE | |
file_set_comment(VALUE self, VALUE comment) | |
{ | |
file_check_closed(self); | |
taglib_tag_set_comment(file_tag(self), StringValuePtr(comment)); | |
return comment; | |
} | |
/*Get track genre*/ | |
VALUE | |
file_get_genre(VALUE self) | |
{ | |
VALUE str; | |
file_check_closed(self); | |
str=rb_str_new2(taglib_tag_genre(file_tag(self))); | |
taglib_tag_free_strings; | |
return str; | |
} | |
/* | |
call-seq: genre=genre | |
Set track genre to genre | |
genre: a string | |
*/ | |
VALUE | |
file_set_genre(VALUE self, VALUE genre) | |
{ | |
file_check_closed(self); | |
taglib_tag_set_genre(file_tag(self), StringValuePtr(genre)); | |
return genre; | |
} | |
/*Get track year*/ | |
VALUE | |
file_get_year(VALUE self) | |
{ | |
file_check_closed(self); | |
return INT2FIX(taglib_tag_year(file_tag(self))); | |
} | |
/* | |
call-seq: year=year | |
Set track year to year | |
year: a Fixnum | |
*/ | |
VALUE | |
file_set_year(VALUE self, VALUE year) | |
{ | |
file_check_closed(self); | |
taglib_tag_set_year(file_tag(self), NUM2INT(year)); | |
return year; | |
} | |
/*Get track number*/ | |
VALUE | |
file_get_track(VALUE self) | |
{ | |
file_check_closed(self); | |
return INT2FIX(taglib_tag_track(file_tag(self))); | |
} | |
/* | |
call-seq: track=number | |
Set track number to number | |
number: a Fixnum | |
*/ | |
VALUE | |
file_set_track(VALUE self, VALUE track) | |
{ | |
file_check_closed(self); | |
taglib_tag_set_track(file_tag(self), NUM2INT(track)); | |
return track; | |
} | |
/*Get track length in seconds*/ | |
VALUE | |
file_get_length(VALUE self) | |
{ | |
file_check_closed(self); | |
return INT2NUM(taglib_audioproperties_length(file_audio(self))); | |
} | |
/*Get track bitrate in kb/s*/ | |
VALUE | |
file_get_bitrate(VALUE self) | |
{ | |
file_check_closed(self); | |
return INT2NUM(taglib_audioproperties_bitrate(file_audio(self))); | |
} | |
/*Get track samplerate in Hz*/ | |
VALUE | |
file_get_samplerate(VALUE self) | |
{ | |
file_check_closed(self); | |
return INT2NUM(taglib_audioproperties_samplerate(file_audio(self))); | |
} | |
/*Get the number of channels in the audio stream*/ | |
VALUE | |
file_get_channels(VALUE self) | |
{ | |
file_check_closed(self); | |
return INT2NUM(taglib_audioproperties_channels(file_audio(self))); | |
} | |
void | |
Init_taglib2() | |
{ | |
/* | |
ruby-taglib2 is a Ruby interface to TagLib, the audio meta-data library. | |
require 'taglib2' | |
tag=TagLib::File.new('music.ogg') | |
tag.title | |
tag.genre="my genre" | |
tag.save | |
*/ | |
mTagLib=rb_define_module("TagLib"); | |
eBadFile=rb_define_class_under(mTagLib, "BadFile", rb_eException); | |
eBadTag=rb_define_class_under(mTagLib, "BadTag", rb_eException); | |
eBadAudioProperties=rb_define_class_under(mTagLib, "BadAudioProperties", rb_eException); | |
eFileClosed=rb_define_class_under(mTagLib, "FileClosed", rb_eException); | |
rb_define_const(mTagLib, "MPEG", INT2FIX(TagLib_File_MPEG)); | |
rb_define_const(mTagLib, "OggVorbis", INT2FIX(TagLib_File_OggVorbis)); | |
rb_define_const(mTagLib, "FLAC", INT2FIX(TagLib_File_FLAC)); | |
rb_define_const(mTagLib, "MPC", INT2FIX(TagLib_File_MPC)); | |
rb_define_const(mTagLib, "OggFlac", INT2FIX(TagLib_File_OggFlac)); | |
rb_define_const(mTagLib, "WavPack", INT2FIX(TagLib_File_WavPack)); | |
rb_define_const(mTagLib, "Speex", INT2FIX(TagLib_File_Speex)); | |
rb_define_const(mTagLib, "TrueAudio", INT2FIX(TagLib_File_TrueAudio)); | |
rb_define_const(mTagLib, "MP4", INT2FIX(TagLib_File_MP4)); | |
rb_define_const(mTagLib, "ASF", INT2FIX(TagLib_File_ASF)); | |
cFile=rb_define_class_under(mTagLib, "File", rb_cObject); | |
rb_define_alloc_func(cFile, file_alloc); | |
rb_define_method(cFile, "initialize", file_init, -1); | |
rb_define_method(cFile, "save", file_save, 0); | |
rb_define_method(cFile, "close", file_close, 0); | |
rb_define_method(cFile, "title", file_get_title, 0); | |
rb_define_method(cFile, "title=", file_set_title, 1); | |
rb_define_method(cFile, "artist", file_get_artist, 0); | |
rb_define_method(cFile, "artist=", file_set_artist, 1); | |
rb_define_method(cFile, "album", file_get_album, 0); | |
rb_define_method(cFile, "album=", file_set_album, 1); | |
rb_define_method(cFile, "comment", file_get_comment, 0); | |
rb_define_method(cFile, "comment=", file_set_comment, 1); | |
rb_define_method(cFile, "genre", file_get_genre, 0); | |
rb_define_method(cFile, "genre=", file_set_genre, 1); | |
rb_define_method(cFile, "year", file_get_year, 0); | |
rb_define_method(cFile, "year=", file_set_year, 1); | |
rb_define_method(cFile, "track", file_get_track, 0); | |
rb_define_method(cFile, "track=", file_set_track, 1); | |
rb_define_method(cFile, "length", file_get_length, 0); | |
rb_define_method(cFile, "bitrate", file_get_bitrate, 0); | |
rb_define_method(cFile, "samplerate", file_get_samplerate, 0); | |
rb_define_method(cFile, "channels", file_get_channels, 0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment