Skip to content

Instantly share code, notes, and snippets.

@RichGuk
Created July 30, 2011 18:56
Show Gist options
  • Save RichGuk/1115853 to your computer and use it in GitHub Desktop.
Save RichGuk/1115853 to your computer and use it in GitHub Desktop.
/*
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