diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ba9bae0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,45 @@
+# TagLib
+Used to set meta data tags on the following audio formats:
+
+```
+ape
+flac
+mp3
+mpc
+mpeg
+ogg
+```
+
+Supports reading and writing the following attributes:
+
+```
+title
+artist
+album
+year
+track
+genre
+```
+
+And reading the attributes:
+```
+bitRate
+sampleRate
+channels
+length
+```
+
+Example use (load and modify a track genre):
+
+```Io
+t := TagLib clone setPath("foo.mp3") load
+writeln("genre = ", t genre)
+t setGenre("ambient")
+t save
+```
+
+# Installation
+`taglib` should be installed and foundable in your system. Then:
+```
+eerie install https://github.com/IoLanguage/TagLib.git
+```
diff --git a/build.io b/build.io
new file mode 100755
index 0000000..1b7662b
--- /dev/null
+++ b/build.io
@@ -0,0 +1,10 @@
+AddonBuilder clone do(
+ dependsOnLib("tag_c")
+ dependsOnHeader("taglib/tag_c.h")
+
+ debs atPut("tag_c", "libtagc0-dev")
+ ebuilds atPut("tag_c", "taglib")
+ pkgs atPut("tag_c", "taglib")
+ rpms atPut("tag_c", "taglib-devel")
+)
+
diff --git a/depends b/depends
new file mode 100644
index 0000000..e69de29
diff --git a/io/TagLib.io b/io/TagLib.io
new file mode 100644
index 0000000..18d4ef3
--- /dev/null
+++ b/io/TagLib.io
@@ -0,0 +1 @@
+/* TagLib */
diff --git a/io/TagLib_extras.io b/io/TagLib_extras.io
new file mode 100644
index 0000000..aa810db
--- /dev/null
+++ b/io/TagLib_extras.io
@@ -0,0 +1,13 @@
+TagLib do(
+ path ::= nil
+ title ::= nil
+ artist ::= nil
+ album ::= nil
+ year ::= nil
+ track ::= nil
+ genre ::= nil
+ bitRate ::= nil
+ sampleRate ::= nil
+ channels ::= nil
+ length ::= nil
+)
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..a81c58b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "TagLib",
+ "version": "0.1",
+ "description": "Used to set meta data tags on the following audio formats: ape, flac, mp3, mpc, mpeg, ogg.",
+ "author": "Steve Dekorte",
+ "website": "http://iolanguage.org/",
+ "readme": "README.md",
+ "protos": ["TagLib"],
+ "dependencies": {
+ "libs": ["tag_c"],
+ "headers": ["taglib/tag_c.h"],
+ "protos": [],
+ "packages": []
+ }
+}
diff --git a/protos b/protos
new file mode 100755
index 0000000..0a6c64c
--- /dev/null
+++ b/protos
@@ -0,0 +1 @@
+TagLib
diff --git a/samples/sounds/max.mp3 b/samples/sounds/max.mp3
new file mode 100644
index 0000000..30c5d4f
Binary files /dev/null and b/samples/sounds/max.mp3 differ
diff --git a/samples/sounds/max.wav b/samples/sounds/max.wav
new file mode 100644
index 0000000..b4660e5
Binary files /dev/null and b/samples/sounds/max.wav differ
diff --git a/samples/tag.io b/samples/tag.io
new file mode 100755
index 0000000..12d1b24
--- /dev/null
+++ b/samples/tag.io
@@ -0,0 +1,18 @@
+#!/usr/bin/env io
+
+TagLib do(
+newSlot("path")
+newSlot("title")
+newSlot("artist")
+newSlot("album")
+newSlot("year")
+newSlot("comment")
+newSlot("track")
+newSlot("genre")
+)
+
+path := Path with(System launchPath, "sounds/max.mp3")
+tag := TagLib clone setPath(path) load
+writeln(tag)
+tag setComment("max headroom saying 'hello, this is max headroom'")
+tag save
diff --git a/source/IoTagLib.c b/source/IoTagLib.c
new file mode 100644
index 0000000..bc52edf
--- /dev/null
+++ b/source/IoTagLib.c
@@ -0,0 +1,170 @@
+//metadoc TagLib copyright Steve Dekorte, 2004
+//metadoc TagLib license BSD revised
+//metadoc TagLib category API
+/*metadoc TagLib description
+Used to set meta data tags on the following audio formats:
+
+ape
+flac
+mp3
+mpc
+mpeg
+ogg
+
+Supports reading and writing the following attributes:
+title
+artist
+album
+year
+track
+genre
+
+And reading the attributes:
+
+bitRate
+sampleRate
+channels
+length
+
+
+Example use (load and modify a track genre):
+
+
+t := TagLib clone setPath("foo.mp3") load
+writeln("genre = ", t genre)
+t setGenre("ambient")
+t save
+
+*/
+
+//doc TagLib setPath(aSeq) Sets the path to the file.
+//doc TagLib path Returns the path to the file.
+
+#include "IoTagLib.h"
+#include "IoState.h"
+#include "IoNumber.h"
+#include "IoSeq.h"
+#include
+
+#define DATA(self) ((IoTagLibData *)IoObject_dataPointer(self))
+static const char *protoId = "TagLib";
+
+IoTag *IoTagLib_newTag(void *state)
+{
+ IoTag *tag = IoTag_newWithName_("TagLib");
+ IoTag_state_(tag, state);
+ IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoTagLib_rawClone);
+ return tag;
+}
+
+IoTagLib *IoTagLib_proto(void *state)
+{
+ IoObject *self = IoObject_new(state);
+ IoObject_tag_(self, IoTagLib_newTag(state));
+
+ IoState_registerProtoWithId_(state, self, protoId);
+
+ {
+ IoMethodTable methodTable[] = {
+ {"load", IoTagLib_load},
+ {"save", IoTagLib_save},
+ {NULL, NULL},
+ };
+ IoObject_addMethodTable_(self, methodTable);
+ }
+
+ return self;
+}
+
+IoTagLib *IoTagLib_rawClone(IoTagLib *proto)
+{
+ IoObject *self = IoObject_rawClonePrimitive(proto);
+ return self;
+}
+
+IoTagLib *IoTagLib_new(void *state)
+{
+ IoObject *proto = IoState_protoWithId_(state, protoId);
+ return IOCLONE(proto);
+}
+
+// -----------------------------------------------------------
+
+
+IoObject *IoTagLib_load(IoTagLib *self, IoObject *locals, IoMessage *m)
+{
+ /*doc TagLib load
+ Loads tag data from the file specified in the path slot. Returns self.
+ */
+
+ TagLib_File *file;
+ TagLib_Tag *tag;
+ const TagLib_AudioProperties *properties;
+ IoSeq *path = IoObject_symbolGetSlot_(self, IOSYMBOL("path"));
+ IOASSERT(path, "missing path slot");
+
+ taglib_set_strings_unicode(0);
+
+ file = taglib_file_new(CSTRING(path));
+
+ IOASSERT(file, "unable to open file");
+
+ tag = (TagLib_Tag *)taglib_file_tag(file);
+ properties = taglib_file_audioproperties(file);
+
+ IoObject_setSlot_to_(self, IOSYMBOL("title"), IOSYMBOL(taglib_tag_title(tag)));
+ IoObject_setSlot_to_(self, IOSYMBOL("artist"), IOSYMBOL(taglib_tag_artist(tag)));
+ IoObject_setSlot_to_(self, IOSYMBOL("album"), IOSYMBOL(taglib_tag_album(tag)));
+ IoObject_setSlot_to_(self, IOSYMBOL("year"), IONUMBER(taglib_tag_year(tag)));
+ IoObject_setSlot_to_(self, IOSYMBOL("comment"), IOSYMBOL(taglib_tag_comment(tag)));
+ IoObject_setSlot_to_(self, IOSYMBOL("track"), IONUMBER(taglib_tag_track(tag)));
+ IoObject_setSlot_to_(self, IOSYMBOL("genre"), IOSYMBOL(taglib_tag_genre(tag)));
+
+ // audio data - can't write this - it's up to the mp3 encoder
+ IoObject_setSlot_to_(self, IOSYMBOL("bitRate"), IONUMBER(taglib_audioproperties_bitrate(properties)));
+ IoObject_setSlot_to_(self, IOSYMBOL("sampleRate"), IONUMBER(taglib_audioproperties_samplerate(properties)));
+ IoObject_setSlot_to_(self, IOSYMBOL("channels"), IONUMBER(taglib_audioproperties_channels(properties)));
+ IoObject_setSlot_to_(self, IOSYMBOL("length"), IONUMBER(taglib_audioproperties_length(properties)));
+
+ taglib_tag_free_strings();
+ taglib_file_free(file);
+
+ return self;
+}
+
+IoObject *IoTagLib_save(IoTagLib *self, IoObject *locals, IoMessage *m)
+{
+ /*doc TagLib save
+ Saves the tag settings and returns self.
+ */
+
+ TagLib_File *file;
+ TagLib_Tag *tag;
+ //const TagLib_AudioProperties *properties;
+ IoSeq *path = IoObject_symbolGetSlot_(self, IOSYMBOL("path"));
+ IOASSERT(path, "missing path slot");
+
+ taglib_set_strings_unicode(0);
+
+ file = taglib_file_new(CSTRING(path));
+
+ IOASSERT(file, "unable to open file");
+
+ tag = (TagLib_Tag *)taglib_file_tag(file);
+
+ taglib_tag_set_title(tag, CSTRING(IoObject_seqGetSlot_(self, IOSYMBOL("title"))));
+ taglib_tag_set_album(tag, CSTRING(IoObject_seqGetSlot_(self, IOSYMBOL("album"))));
+ taglib_tag_set_year(tag, (int)IoObject_doubleGetSlot_(self, IOSYMBOL("year")));
+ taglib_tag_set_comment(tag, CSTRING(IoObject_seqGetSlot_(self, IOSYMBOL("comment"))));
+ taglib_tag_set_track(tag, (int)IoObject_doubleGetSlot_(self, IOSYMBOL("track")));
+ taglib_tag_set_genre(tag, CSTRING(IoObject_seqGetSlot_(self, IOSYMBOL("genre"))));
+
+ taglib_file_save(file);
+
+ taglib_tag_free_strings();
+ taglib_file_free(file);
+
+ return self;
+
+}
+
diff --git a/source/IoTagLib.h b/source/IoTagLib.h
new file mode 100644
index 0000000..d963e2a
--- /dev/null
+++ b/source/IoTagLib.h
@@ -0,0 +1,29 @@
+/* copyright: Steve Dekorte, 2002
+ * All rights reserved. See _BSDLicense.txt.
+ */
+
+#ifndef IoTagLib_DEFINED
+#define IoTagLib_DEFINED 1
+
+#include "IoObject.h"
+#include "IoSeq.h"
+
+typedef IoObject IoTagLib;
+
+typedef struct
+{
+
+} IoTagLibData;
+
+IoTagLib *IoTagLib_proto(void *state);
+IoTagLib *IoTagLib_new(void *state);
+IoTagLib *IoTagLib_rawClone(IoTagLib *self);
+
+void IoTagLib_free(IoTagLib *self);
+
+// -----------------------------------------------------------
+
+IoObject *IoTagLib_load(IoTagLib *self, IoObject *locals, IoMessage *m);
+IoObject *IoTagLib_save(IoTagLib *self, IoObject *locals, IoMessage *m);
+
+#endif