#include "FLAC/metadata.h" #include "ruby.h" #include #include static VALUE mFlac; static VALUE cInfo; // static VALUE rb_cinfo_new(VALUE self); static VALUE rb_flac_info(VALUE module, VALUE filename); static void set_tag(FLAC__StreamMetadata_VorbisComment_Entry * tag, VALUE info); void Init_flac() { mFlac = rb_define_module("Flac"); cInfo = rb_define_class_under(mFlac, "Info", rb_cObject); int i = 0; #define NA 5 const char *attr2[NA] = { "time", "sample_rate", "channels", "bits_per_sample", "comments" }; for (i = 0; i < NA; i++) { rb_define_attr(cInfo, attr2[i], 1, 0); } rb_define_module_function(mFlac, "info", rb_flac_info, 1); } VALUE rb_flac_info(VALUE self, VALUE filename) { FLAC__StreamMetadata si; FLAC__StreamMetadata *tags; // char *tag; char *cfilename = STR2CSTR(filename); FLAC__metadata_get_streaminfo(cfilename, &si); int i = 0; VALUE info = rb_class_new_instance(0, NULL, cInfo); VALUE comments = rb_hash_new(); double time = (double) si.data.stream_info.total_samples / (double) si.data.stream_info.sample_rate; rb_iv_set(info, "@sample_rate", INT2FIX(si.data.stream_info.sample_rate)); rb_iv_set(info, "@channels", INT2FIX(si.data.stream_info.channels)); rb_iv_set(info, "@bits_per_sample", INT2FIX(si.data.stream_info.bits_per_sample)); rb_iv_set(info, "@time", rb_float_new(time)); FLAC__metadata_get_tags(cfilename, &tags); for (i = 0; i < tags->data.vorbis_comment.num_comments; i++) { set_tag(&(tags->data.vorbis_comment.comments[i]), comments); } rb_iv_set(info, "@comments", comments); FLAC__metadata_object_delete(tags); return info; } static void set_tag(FLAC__StreamMetadata_VorbisComment_Entry * tag, VALUE comments) { // printf("%s\n",tag->entry); char *s = tag->entry; char *equals_pos = strchr(s, '='); VALUE key, value; if (0 != equals_pos) { int i = 0; for (; i < equals_pos - s; i++) { s[i] = tolower(s[i]); } key = rb_str_new(s, equals_pos - s); value = rb_str_new(equals_pos + 1, strlen(equals_pos + 1)); rb_hash_aset(comments, key, value); } }