Brian Nickel’s Online Journal

If you don’t C# you’ll B♭

Archive for April, 2007

TagLib# has a new home, and a new release!

Posted by Brian on April 27, 2007

If you’re looking for TagLib#, you have somewhere new to go: taglib-sharp.com! The new, graciously donated, site features a blog, a forum, and a wiki!

And what’s a new site without a sweet new release? TagLib# 1.9.9991 AKA Beta 1 is out featuring all previous formats plus MPEG-4 video, MPEG-1/2, and AVI. It’s a format bonanza! Visit the new download page.

PS. This is the last TagLib# post on this blog. New posts will be on the new blog.

Posted in TagLib# | 1 Comment »

TagLib#: MPEG-(1|2|4) Video

Posted by Brian on April 18, 2007

The past 3 days I’ve committed a couple major changes to TagLib#. Namely, support for MPEG-1/2 files and support for MPEG-4 video. The latter was pretty easy, but the former was an amazing pain, largely due to the amazing lack of online documentation for this 14 year old format. As such, here’s my brief explanation of:

HOW MPEG-1/2 FILES LOOK AND HOW TO UNDERSTAND THEM

MPEG contains two key parts, an audio stream and a video stream. If you were to extract the audio stream from an MPEG file, you’d have an MP3 (which could actually really be an MP2 or and MP1). The MP3 stream is very well documented online. For my personal favorite, click here. MPEG video is a very different format, but the important thing is that we have two streams, audio and video, and we’re combining them into one.

To do this, MPEG does pretty much the exact same thing as OGG, it takes the two streams, splits them into packets, and shuffles them together like playing cards. When you know what each of these cards looks like, the format stops being scary and becomes managable. So, what do the cards look like?

Each packet starts off with a simple packet identifier: 0x000001??. The ?? is replaced with a byte explaining the purpose of the packet. These are:

  • BA: This packet contains information on the MPEG version, a timestamp, and most likely some other useful information. This packet will always appear before BB, C0, or E0. BA should also be the first packet of the file.
  • BB: This contains some more useful information (I’m guessing.)
  • BE: A padding packet.
  • C0: An audio packet.
  • E0: A video packet.
  • B9: End of stream notification.

BA is a very important packet because it provides information on time. It appears before each audio or video packet to let you know when it’s happening. If you have the first and last BA packet, you can determine the duration of the movie. It sure beats the guessing in MP3 and doesn’t depend on weird codec dependent calculations like in OGG.

Now that we know the MPEG version and we know the duration, it is time to piece together the audio information. The first audio and video packets SHOULD contain complete headers for their respective formats and should tell us all we need to know. Audio is no problem for us, as we can just scan to the first C0 and sic our FindFrameHeader functions from the MP3 parser on it, and get every bit of information we need to know.

Video is a completely different format, but now that we understand MPEG files we should be able to understand this, as it uses exactly the same format: 0x000001??. The first packet should be B3, which we parse with VideoHeader.cs.

That just about covers everything except packet size. For all but BA, which is version specific, the first two bytes following the packet identifier describe the packet’s content length (total packet size – 6). This means you can just skip through the file pretty quickly (about 0×800 bytes at a time, depending).

All the work is in subversion. Be sure to note that the file sticks an ID3v2.4 and ID3v1 packet at the it’s end.

Posted in Programming, TagLib# | Leave a Comment »

Summer of Code

Posted by Brian on April 12, 2007

Well, it happened… I got accepted into the Google Summer of Code with the Mono Project! This summer, I’ll be working on a FastCGI bridge for the XSP ASP.NET server. For those of you unfamiliar with the acronyms, XSP is the Mono Project’s implementation of the ASP.NET website system. If ever you see a URL with “.aspx” in it, that’s what this is. Unlike PHP, Phython, PERL, and what-have-you, an ASP.NET implementation really needs a processing daemon/server which holds on to session objects, caches compiled page objects, garbage collects, etc. As such, XSP comes in two flavors, a standalone web server which processes ASP.NET and plain documents, and a server designed to work with an Apache module, mod-mono-server.

The problem is that these two flavors limit you to two server options, Apache or XSP, and since you’re probably not going to use XSP as your full web server, you’re basically limited to Apache. There is a protocol called FastCGI which was designed to speed up CGI programs by keeping them as a running server and creating a fake CGI environment. It is also supported directly or indirectly by a large number of web servers, so using it as a communication bridge for an ASP.NET server like XSP is like a match made in heaven. My project is to make that bridge.

That, plus some configuration stuff (mod_mono is super confusing to configure), is pretty much the gist of what I’m planning. You can check out my abstract for more info.

UPDATE: 

Considering that this post is going to appear on Monologue, I should probably introduce myself. I’m Brian Nickel a Chemical Engineering Computer Systems Engineering major at Arizona State University. I’ve been using Linux for about 8 years, started working with .NET writing plugins for Muine, and now develop and maintain TagLib#, a library for reading and writing tags to audio (and soon video) files. Outside of computing, I’m currently the president of my fraternity Theta Tau at ASU (I also wrote their website entirely in C, if you can believe it); I’ve got a girlfriend of over two years, Edith; I really want to move out of Phoenix; some of my favorite places to eat are Byblos, Capistranos, Ivan’s Tacos, Long Wongs, and the Chuckbox; and I seriously can’t believe Scott Peterson made a CIL brainfuck compiler, that’s seriously giving my flashbacks to junior year of high school.

I’m seriously looking forward to this summer.

Posted in Summer of Code 2007 | 3 Comments »

OpenSUSE for 12 hours

Posted by Brian on April 11, 2007

Gentoo is nice, but I waste too much time with it. Especially with unstable overlays. After running it on my laptop for about a year, I’ve accumulated enough errors through old configuration, corrupt libraries, etc, that I decided to uninstall and install my old sweetheart (metaphorically speaking), OpenSUSE.

I must say, the installation didn’t suck. It recognized my IPW3945 driver out of the box so I didn’t have to worry about finding a network cable (This has been a HUGE issue in the past.) which meant the only thing I needed to worry about was the ATI driver (the X1400 is not supported by the open source driver) but fortunately there were plenty of instructions online. All I had to do was:

  1. Install the kernel-headers and the latest kernel.
  2. Restart (so the driver would build properly, it will fail on a fresh install otherwise).
  3. Download the latest driver from the ATI website.
  4. Run the program to build the RPM.
  5. Install the RPM.
  6. sax2 -r -m 0=fglrx
  7. Restart the XServer.

See http://en.opensuse.org/ATI_Driver_HOWTO for more detailed information.

The XGL  starter doesn’t recognize the X1400 driver as XGL ready, so you need to run “gnome-xgl-switch –enable-xgl” manually (ignore the messages, they’re just there to confuse you) and restart the display manager.

Other than that and a severe lack of supported audio codecs (add http://packman.il-bremen.de/suse/10.2/ as a install service), things couldn’t have gone smoother. It is definitely the fastest and least painful install I’ve tried to do on this machine (including Fedora, Ubuntu, Gentoo, and SLED9 but those were a while ago so things may have gotten better). Bravo to Novell and the OpenSUSE developers.

Posted in Uncategorized | Leave a Comment »

Entertaining comments: New name for TagLib#, Website & Hosting

Posted by Brian on April 9, 2007

UPDATE: The website is now hosted at http://www.taglib-sharp.com and I’m keeping the name as is. Thanks to everyone who volunteered to host it.

1. TagLib# has gone through enormous changes since it was originally ported from TagLib (C++/Linux), it deals with a different audience, it handles different files, and the name similarity has caused some confusion for new users. I am thinking of renaming the project, maybe dropping the “-sharp” moniker, perhaps commenting on the impending Video support.

In short, What should I call it?

2. It seems like the Windows developer community and newer developers (I’m not dogging on the Windows community, but the two groups are similar in this respect) are more comfortable with forums and online documentation than mailing lists and monodoc. As such, TagLib# needs its own website, preferably new-project-name.com, that said, two things:

What all should go on a library’s website? Examples, Forum, Documentation, etc.

Is anyone willing to host a website and buy me a domain? I’m broke!

Please comment.

Posted in Programming, TagLib# | 2 Comments »

Dock: Okay, I’m obviously not finishing this in the near future…

Posted by Brian on April 6, 2007

So, enjoy my code. I’m sure something good can come of it: dock-ng.zip. I’ll call it MIT-X11 licensed.

Posted in Cairo, Programming, XInputShape | Leave a Comment »

TagLib#: Fire good, Ogg happy

Posted by Brian on April 6, 2007

I tagged this myself!

$ mono ReadFromUri.exe mac_pc_linux_2.OGG
mac_pc_linux_2.OGG
Title:      Second Novell "I'm a mac..." parody ad
Artists:    Novell
Performers:
Composers:
Album:
Comment:
Genres:
Year:       2007
Track:      2
TrackCount: 0
Disc:       0
DiscCount:  0
Lyrics:

Audio Properties
Bitrate:    56
SampleRate: 22050
Channels:   2

Length:     00:00:41.9000000

Embedded Pictures: 0

What I ended up doing is, on Save(), reading the OGG structure in an identical manner to the initial Read() (minus scanning to the end for duration information). Along the way, I store all the Pages I’ve collected, and by the end of the “Read”, I’ll have read all the way to the end of the taggable region. Then I dump the pages into stream specific Paginators which separate the pages into packets. After that, I take the stream specific XiphComments and use the appropriate codec to stick it in the packet collection. Then, all I need to do is Paginate (which could use some improvement), shuffle the pages back together, and insert the chunk where the old packets used to be. Wow, that could have been a lot clearer.

But anyway, the code is now in subversion: http://svn.myrealbox.com/viewcvs/trunk/taglib-sharp/ and if haven’t yet seen it, see “Blades of Glory”. It is not just Will Farrell’s funniest movie (which isn’t saying much) but it’s the funniest movie I’ve seen in a long time. I haven’t laughed out loud like this in a movie theatre since opening night of Episode III, and this one was actually supposed to be funny (but had significantly less gay innuendo)!

Posted in Uncategorized | Leave a Comment »

TagLib#: Special thanks to the people at #theora

Posted by Brian on April 4, 2007

I’ve made a bit of progress:

$ mono ReadFromUri.exe ~/Downloads/mac_pc_linux_2.OGG
/home/brian/Downloads/mac_pc_linux_2.OGG
Audio
Video
Title:
Artists:
Performers:
Composers:
Album:
Comment:
Genres:
Year:       0
Track:      0
TrackCount: 0
Disc:       0
DiscCount:  0
Lyrics:

Audio Properties
Bitrate:    56
SampleRate: 22050
Channels:   2

Video Properties
Width:      320
Height:     240

Length:     00:00:41.8750000

Embedded Pictures: 0

---------------------------------------

Total running time:    00:00:00.2400040
Total files read:      1
Average time per file: 00:00:00.2400040

The original file ended with a Vorbis page, which is easy to read, so I corrupted it and got duration parsing from a final Theora header (with some great help from the people at #theora on freenode).

The main problem now is: How do I update the tags. I’m going to have to look at the TagLib implementation more thoroughly, but at this point I’m scratching my head. Should I extract all the packets from the first page containing comment data to the last, then generate my own pages? It’ll probably take me a couple days to figure this out.

And then… M4V, MPEG (Just stick a ID3v2.4 on the end?), AVI, and I’m done! With all this change, I think this’ll be 2.0.

Posted in Programming, TagLib# | Leave a Comment »

Speakers, Ogg, and Flashing Realizations that I’m Wasting My Life

Posted by Brian on April 4, 2007

Speakers

This weekend, my chapter hosted the Western Regional Convention for Theta Tau. As we are a professional fraternity, we had a few speakers. One talked about some fascinating molecules which are liquid at room temperature and solidify at body temperature (counter-intuitive, huh?) and the other discussed what ABET says an engineer should be, what’s wrong with ASU’s current direction for engineering, and the most important thing an engineer should do with his life: Get a PhD in public policy and become a legislator. Needless to say, the talk was incredibly mind blowing and inspirational, not to mention dead on. As engineers, it is our life’s work to build, to invent, to improve. The weakest link in the betterment of mankind is those who say what we can and cannot do… Mainly because they cannot or do not know what we can and cannot do. We need rational, analytical, and just plain logical people making decisions.

On Monday, I found a insert in my New York Times advertising the launch of the School of Earth and Space Exploration (because “school of geology and astronomy” sounds lame) at ASU, and attended the some really interesting lectures by science writers. Science writing is a huge challenge because it is taking some of the greatest and most profound ideas and discoveries, then simplifying and clarifying it so that everyone can understand it. I feel the two lectures go hand in hand. We must be both effective thinkers and effective speakers if we are going to move the world forward. Profound thoughts are meaningless if the mouth and the pen cannot convey them to the audience.

Ogg

OGG is a great protocol for streaming. Really top of the line. Its like an MPEG stream but without the codec limitations. That said, OGG is a thorn in my side. As it is currently written, TagLib# has a TagLib.Ogg.File and a TagLib.Ogg.Vorbis.File, the former featuring File.GetPacket(int) which parses the stream (assumed singular) for packets, and the latter featuring File.Read() which gets the metadata from packet[0] and the comment from packet[1]. (I do not yet understand how writing works.)

So, I decided to abolish TagLib.Ogg.Vorbis.File and TagLib.Ogg.Flac.File in place of TagLib.Ogg.File + TagLib.Ogg.Codecs.Vorbis, etc. This will be helpful when I have multi-streamed files, like Vorbis + Theora. That being said, I’ve come up with this little diagram of how to read a stream:

-> Read Page
   -> Send Page to Bitstream Parser
      -> If BOS:
         -> Get Codec
         -> Add stream to "working streams"
      -> Send Page to Codec
      -> Returns false if more info needed.
   -> If not all streams return "true" (there are "working streams", Read Page

After that, I should know everything except the duration. For that, I have to read the last page of the stream, figure out which bitstream it belongs to, then use (last_granular_position – first_granular_position) / codec_encoding_specific_context.

-> File.RFind ("OggS")
-> Codec.GetDuration (GetPageHeader().last_granular_position)

Overall, it’s not that bad. But unlike the other big two containers (MPEG-4 and ASF), I have to worry about the codec, as there is no general “Media Properties” block, and I have to seek to the end of the file and do a backward search for a value. OGG, MPEG-4, and ASF SHOULD NOT be categorized together two are boxed formats and one is just a method for multiplexing data streams.

Flashing Realizations that I’m Wasting My Life

These are always the worst when they strike. I had one of those recently and changed my major from the loathsome Chemical Engineering to Computer Systems Engineering. I’ve had my reservations about CSE, but truth be told, I hate reactor design, I hate separations, and I do not want to watch valves. Well, as I was sitting around trying to piece together my financial situation for the remainder of my schooling, I realized that I’m a mess. As such I started cleaning my room and doing my much overdue laundry. But what I really need to do is start making money. If I am going to survive the fall and spring semesters, I will need to devote almost all my time to my coursework, and as such will not be working. As such, I estimate that I will need $6707.50 and a serious change in behavior before summer ends. Even with Summer of Code (God willing), I’ll need to work my tail off until June 1st to make everything work out. And stop spending. Alas.

Posted in Arizona State University, Folly, Programming, TagLib#, Theta Tau | Leave a Comment »