Mythdora 10 / MythTV + Antec Fusion 430 VFD LCD + lircd + LCDd

Problem

This guide is how to setup the Antec Fusion 430 Case to work with Mythdora 10 and MythTV. I found a lot of guides on how to setup the drivers, but they were all out of date.

Pieces

There are three things you need to get running :

  1. lirc_imon kernel driver
  2. LCDd daemon
  3. mythlcdserver daemon

All of these things came installed w/ Myth and didn’t require any additional patching or compiling.

To see the exact device we’re working with, run lsusb :

Bus 003 Device 002: ID 15c2:ffdc SoundGraph Inc. iMON PAD Remote Controller

This is all for the “Old” imon, or 1st generation, or “FFDC” version of the LCD device.

1. LIRC lirc_imon kernel driver

yum install lirc lirc-libs

Edit /etc/modprob.conf and add this line :

options lirc_imon display_type=1

The display_type=1 option was not documented well, but that was the key in making the module work. Without it I was seeing the following in the /var/log/messages after adding debug=1 to the above. I also was missing /dev/lcd0 even though the kernel driver was loading!

Nov 22 21:18:09 localhost kernel: lirc_imon: imon_probe: found IMON device
Nov 22 21:18:09 localhost kernel: lirc_imon: imon_probe: found IR endpoint
Nov 22 21:18:09 localhost kernel: lirc_imon: imon_probe: found VFD endpoint
Nov 22 21:18:09 localhost kernel: lirc_imon: imon_probe: device has no display
Nov 22 21:18:09 localhost kernel: lirc_imon: ir_onboard_decode: 1
Nov 22 21:18:09 localhost kernel: lirc_dev: lirc_register_plugin: sample_rate: 0
Nov 22 21:18:09 localhost kernel: lirc_imon: imon_probe: Registered iMON plugin(minor:1)
Nov 22 21:18:09 localhost kernel: lirc_imon: imon_probe: iMON device on usb<3:2> initialized

That “device has no display” line is cured by the “display_type=1″ option. /var/log/messages now looks like this (with debug=1) :

Nov 22 21:21:55 localhost kernel: lirc_imon: Driver for Soundgraph iMON MultiMedia IR/VFD, v0.4
Nov 22 21:21:55 localhost kernel: lirc_imon: Venky Raju 
Nov 22 21:21:55 localhost kernel: lirc_imon: imon_probe: found IMON device
Nov 22 21:21:55 localhost kernel: lirc_imon: imon_probe: found IR endpoint
Nov 22 21:21:55 localhost kernel: lirc_imon: imon_probe: found VFD endpoint
Nov 22 21:21:55 localhost kernel: lirc_imon: ir_onboard_decode: 1
Nov 22 21:21:55 localhost kernel: lirc_imon: vfd_proto_6p: 1
Nov 22 21:21:55 localhost kernel: lirc_dev: lirc_register_plugin: sample_rate: 0
Nov 22 21:21:55 localhost kernel: lirc_imon: imon_probe: Registered iMON plugin(minor:1)
Nov 22 21:21:55 localhost kernel: lirc_imon: Registering VFD with sysfs
Nov 22 21:21:55 localhost kernel: lirc_imon: imon_probe: iMON device on usb<3:2> initialized
Nov 22 21:21:55 localhost kernel: usbcore: registered new interface driver lirc_imon

At this point you should have a /dev/lcd0 and you can test it with this command :

echo "hello world" > /dev/lcd0

OK, now that we have a working kernel driver, let’s move on to the LCD daemon

2. LCDd Daemon

  1. yum install lcdproc
  2. Edit /etc/sysconfig/lcdproc/LCD.conf to look like this :
    [server]
    Driver=imon
    Bind=127.0.0.1
    Port=13666
    
    # Sets the reporting level; defaults to 2 (warnings and errors only).
    #ReportLevel=3
    
    # Should we report to syslog instead of stderr ? Default: no
    ReportToSyslog=yes
    
    # Sets the default time in seconds to displays a screen.
    WaitTime=5
    
    # User to run as.  LCDd will drop its root priviledges,
    # if any, and run as this user instead.
    User=nobody
    
    # If yes, the the serverscreen will be rotated as a usual info screen. If no,
    # it will be a background screen, only visible when no other screens are
    # active.
    ServerScreen=no
    
    # The server will stay in the foreground if set to true.
    #Foreground=no
    
    DriverPath=/usr/lib/lcdproc/
    
    # GoodBye message: each entry represents a display line; default: builtin
    GoodBye=""
    GoodBye=""
    
    ToggleRotateKey=Enter
    PrevScreenKey=Left
    NextScreenKey=Right
    
    [menu]
    MenuKey=Escape
    EnterKey=Enter
    UpKey=Up
    DownKey=Down
    
    [imon]
    Device=/dev/lcd0
    Size=16x2
    

    Note that you want the imon driver, not imon_lcd or any other one.

  3. Boot the driver
    service LCDd restart
    tail /var/log/messages
    dmesg | tail
    

At this point you should see the output of LCDd on the VFD display. If not, rinse and repeat.

3. mythlcdserver

Follow these directions on mythtv.org to turn on the LCD settings in MythTV from the front-end in the Appearance menu. Restart the front-end and it should launch mythlcdserver. If not, you can launch mythlcdserver as the same user as the front-end.

Share and Enjoy:
  • Facebook
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Blogosphere News
  • email
  • LinkedIn
  • Print
  • Reddit
  • Slashdot
  • Add to favorites
  • RSS
  • Technorati
  • PDF

Updating your BIOS in DOS w/ Window 7 / Vista using a USB Drive

Problem

You need to update your BIOS using a DOS boot disk and you’re running Windows 7, or Vista. Chances are you haven’t seen a DOS floppy, much less the floppy drive to put it in, since 1985.

Solution

I found many sites telling you how to make a USB stick bootable for installing Windows 7, but none on how to make it bootable for DOS for upgrading the BIOS or other diag.

Here is one solution I found :

  1. Download a Windows 98 Bootable CD image from http://www.allbootdisks.com/download/iso.html and burn it to a CD.
  2. Download the HP Flash Drive Format program that you will find mentioned on tons of differents sites : http://h20000.www2.hp.com/bizsupport/TechSupport/SoftwareDescription.jsp?lang=en&cc=us&swItem=MTX-UNITY-I23839&jumpid=reg_R1002_USEN and install it.
  3. Using that utility, format your flash drive with FAT32, Make it Bootable, and point the utility to your CDROM drive with the CD you made in Step 1.
  4. Copy your BIOS and flash utility to the USB drive
  5. Boot the computer using the USB stick. This may require entering a Boot Menu w/ F11 or F12, and/or changing some settings in the BIOS such as “Enable Legacy USB Support”. Chances are it will just work by putting the USB stick in and rebooting.
  6. Follow the motherboard manufacturer instructions on how to flash the BIOS.

Good luck and enjoy!
-m

Share and Enjoy:
  • Facebook
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Blogosphere News
  • email
  • LinkedIn
  • Print
  • Reddit
  • Slashdot
  • Add to favorites
  • RSS
  • Technorati
  • PDF

Getting Accents / UTF8 in Mutt using Xterm with TrueType

Overview

I’m starting to adopt Unicode/UTF-8 into my world to allow for more internationalization in my projects. Someday I might play with Perl6′s UTF-8 stuff too. I also want to be able have different charactersets render correctly while using Mutt. I often get email from people in Western Europe, Eastern Europe, and SouthEast Asia, and they are all using different character sets. UTF-8 is the “universal” one.

Shows Hebrew, Chinese and Western European characters all at the same time.

Shows Hebrew, Chinese and Western European characters all at the same time.

The Components

Xterm

In order to have a nice playing Xterm with UTF-8, 256-colors and TrueType, I have to roll my own.

  1. Download the latest one from ftp://invisible-island.net/xterm/xterm.tar.gz.
  2. Compile it
    ./configure \
         --disable-desktop \
         --with-x \
         --enable-256-color \
         --enable-load-vt-fonts \
         --enable-paste64 \
         --enable-readline-mouse \
         --enable-tcap-fkeys \
         --enable-tcap-query \
         --enable-wide-chars \
         --with-Xaw3d
     
    make
    make install

    Note the crucial –enable-wide-chars needed for UTF-8. Your xterm may already be compiled with some or all of these options.

Once I have that, I create a small shell script that I call xt that launches it for me :

#!/bin/sh
# None of these have extended charsets :-(
font="Consolas"
#font="DejaVu Sans Mono"
#font="Bitstream Vera Sans Mono"
#font="luxi mono"
#font="Andale Mono"
#font="courier"
font_size=12
 
exec xterm -bg black -fg white \
    -fa "$font" \
    -fd "$font" \
    -fs $font_size \
    -j -s \
    -sb -si -sk -vb -sl 1024 -rightbar \
    +sf +dc -cr darkgreen  \
    -u8 -geometry 100x40 \
    $@ & 
exit

The important options here are -u8, -fa and -fd. This would be perfect, except that I can’t find a good mono-spaced TrueType font that has all of the character sets. More on that in the font section.

If you want support for all character sets, you can use the “fixed” font built in to X, which has a very
complete character set. I use this script inspired by Marjan Parsa instead :

#!/bin/sh
 
exec xterm -bg black -fg white \
    -j -s \
    -sb -si -sk -vb -sl 1024 -rightbar \
    +sf +dc -cr darkgreen  \
    -u8 -geometry 100x40 \
    -xrm "xterm*font:-misc-fixed-medium-r-normal--18-120-100-100-c-90-iso10646-1"  \
    -xrm "xterm*wideFont:-misc-fixed-medium-r-normal-ja-18-120-100-100-c-180-iso10646-1"  \
    $@ & 
exit

Fonts

You have two choices here : Fixed fonts and TrueType fonts. In my experience, the TrueType fonts look better, and the Fixed fonts have more characters supported.

TrueType

I can’t seem to find a perfect TrueType “Console” font that is fixed-width, looks great, and supports all the Unicode (UTF-8) character sets like Europe, Hebrew, Japanese, Chinese, etc. So I compromise the character set support and just get the pretty one. So far I am most happy with Microsoft’s “Consolas”. Yes, Microsoft!

Here are some good ones to check out:

If you would like to add TrueType fonts to your account / home directory locally, just create a ~/.fonts directory and then copy the .ttf fonts into it. Try these command to explore what fonts you have :

fc-list                 #  see what fonts are loaded.
xfd -fa "DejaVu Sans Mono"  #  explore a certain font

Fixed / System Fonts

I use the following two options when launching Xterm to specify the system fonts :

-xrm "xterm*font:-misc-fixed-medium-r-normal--18-120-100-100-c-90-iso10646-1"
-xrm "xterm*wideFont:-misc-fixed-medium-r-normal-ja-18-120-100-100-c-180-iso10646-1"

Try these commands to see what UTF-8 fonts you have and what’s in them :

xlsfonts | grep 10646
xfd -fn "-ibm-courier-medium-r-normal--0-0-0-0-m-0-iso10646-1"

This is the settings / fonts I used for the above screen shot. See also this Linux Font Tutorial.

Shell / Environment Variables

Key to all of this is that you have your LANG environment variable set correctly

Edit ~/.bashrc and make sure this line is happening :

export LANG=en_US.utf8

Remember, you will need this on two machines : the machine you are creating the X-Term window on, and the machine that you are launching mutt on. These may be the same machine, maybe not.

To get a list of the locales available use this command :

locale -a | grep -i utf

Note that these are case-sensitive, so if you have it set to en_US.UTF8 instead of en_US.utf8 you will get some wanky errors.

Mutt

Mutt works pretty well out of the box w/ UTF8. For reference see The Mutt FAQ.

I used these options in my .muttrc:

set allow_8bit
set allow_ansi=yes                  # in msgs
charset-hook us-ascii iso-8859-1
set send_charset="us-ascii:iso-8859-1"

So what this is doing is still using UTF-8 as my LANG setting and encoding for the terminal, but it’s sending my messages out as iso-8859-1. It also is assuming that anything that comes in as “us-ascii” is actually iso-8859-1.

Share and Enjoy:
  • Facebook
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Blogosphere News
  • email
  • LinkedIn
  • Print
  • Reddit
  • Slashdot
  • Add to favorites
  • RSS
  • Technorati
  • PDF

iTunes – Fixing ID3 tags in MP3′s – Take two

Overview

In these last three posts [1] [2] [3] I tackled fixing my existing MP3′s to make them more iTunes friendly. I did it with three Perl scripts using two different ID3 libraries : Audio::TabLib which is a Perl wrapper to KDE’s TagLib, and MP3::Tag.

I’ve since given up on MP3::Tag. Although updated recently, it still does not support ID3v2 2.4, which, unfortunately is the default in iTunes versions 7 and 8. So I’ve combined all three scripts into one script that only uses Audio::TagLib. One bonus of this, is that TagLib is a fast C++ library, and so the script runs a lot faster than a Pure Perl based method. One batch run on 160GB of MP3′s only took a couple minutes.

The Script

The following script does all three of the functions from my last posts :

  1. Add Folder.jpg (or another image) to the MP3 for Cover Art
  2. Convert version 1 tags (ID3v1) to version 2 (ID3v2)
  3. Set the iTunes Compilation Flag (ICMP)

You can download the script here : http://warped.org/linux/mp3_fix_tag or copy paste from below :

#!/usr/bin/perl -w
# mp3_tag_fix
# Max Baker max@warped.org
# 5/3/09
 
$VERSION=1.1;
 
use File::Glob qw(:globally :glob);
use Audio::TagLib;
use Getopt::Long;
GetOptions (\%Args, "h|help", "f|front=s", 'b|back=s',
            'c|covers|addcovers','v1tov2', 'comp|compilation');
 
$Cover_Front = $Args{f} || "Folder.jpg";
$Cover_Back  = $Args{b} || "Folder_back.jpg";
 
die &usage if (! scalar @ARGV or $Args{h});
die &usage unless ($Args{c} || $Args{v1tov2} || $Args{comp});
 
foreach my $f (@ARGV) {
    if (-d $f) {
        recurse_dir($f);
        next;
    }
    go($f);
}
 
exit;
 
sub go {
    my $f = shift;
 
    # Only work on files that end in .mp3
    return if $f eq '.';
    return if $f eq '..';
    return unless -r $f and $f =~ /\.mp3$/i;
 
    print "  $f\n";
 
    my $mp3 = Audio::TagLib::MPEG::File->new($f) or die;
    my $id3v1 = $mp3->ID3v1Tag(1);
    my $id3v2 = $mp3->ID3v2Tag(1);
 
    # Cover Art
    if ($Args{c}) {
        #print "    --> Adding Cover Art\n";
        add_image($id3v2,$f,"$root/$Cover_Front","FrontCover","Cover (front)") if -r "$root/$Cover_Front";
        add_image($id3v2,$f,"$root/$Cover_Back", "BackCover", "Cover (back)")  if -r "$root/$Cover_Back";
    }
 
    # Copy v1 tags to v2
    if ($Args{v1tov2}) {
        print "    --> Copying ID3v1 data to ID3v2\n";
        $id3v2->setArtist(Audio::TagLib::String->new($id3v1->artist)) if nb($id3v1->artist);
        $id3v2->setAlbum(Audio::TagLib::String->new($id3v1->album))  if nb($id3v1->album);
        $id3v2->setTitle(Audio::TagLib::String->new($id3v1->title))  if nb($id3v1->title);
        $id3v2->setYear($id3v1->year)                                if nb($id3v1->year);
        $id3v2->setTrack($id3v1->track)                              if nb($id3v1->track);
        $id3v2->setGenre(Audio::TagLib::String->new($id3v1->genre))  if nb($id3v1->genre);
    }
 
    # Add/Replace TCMP - Compilation Tag
    if ($Args{comp}) {
        print "    --> Setting Compilation Flag\n";
        my $tcmp = Audio::TagLib::ByteVector->new("TCMP");
        $id3v2->removeFrames($tcmp);
 
        #my $f = Audio::TagLib::ID3v2::TextIdentificationFrame->new($tcmp, "UTF8");
        my $f = Audio::TagLib::ID3v2::TextIdentificationFrame->new($tcmp);
        $f->setText(Audio::TagLib::String->new("1"));
        $id3v2->addFrame($f);
    }
 
    $mp3->save();
}
 
sub recurse_dir {
    my $root = shift;
 
    print "Entering $root\n";
 
    # bsd_glob handles spaces in file names/paths
    my @files = bsd_glob("$root/*",GLOB_QUOTE);
    foreach my $f (@files) {
        if (-d $f) {
            recurse_dir($f);
            next;
        }
        go($f);
    }
}
 
# not blank or undef
sub nb {
    my $string = shift;
    return 0 unless defined $string;
    return 0 if $string =~ /^\s*$/;
    return 1;
}
 
sub add_image {
    my ($id3v2,$f,$img,$type,$desc) = @_;
 
    print "    --> add_image($type) $img -> $f\n";
 
    open(PICFILE, "< $img") or die "Can't open image $img. $!\n";
 
    my $imgdata;
    my $filesize = -s PICFILE;
    binmode(PICFILE);
    read(PICFILE, $imgdata, $filesize);
    close(PICFILE);
 
    my $imgbv = Audio::TagLib::ByteVector->new();
    $imgbv->setData($imgdata,$filesize);
    my $bv = Audio::TagLib::ByteVector->new("APIC");
    my $field = Audio::TagLib::ID3v2::AttachedPictureFrame->new($bv, "UTF8");
    $field->setPicture($imgbv);
    $field->setTextEncoding("UTF8");
    $field->setMimeType(Audio::TagLib::String->new("image/jpeg"));
    $field->setType($type);
    $field->setDescription(Audio::TagLib::String->new($desc));
    $id3v2->addFrame($field);
}
 
sub usage {
    return < < "end_usage";
USAGE: $0 <dir> <cmd> [options]
 
mp3_tag_fix Version $VERSION
 
This script is used to fix up MP3 files for use in iTunes.
 
It can do the following things :
    * Recursively go through a directory and embed album art 
    * Copy ID3v1 tag data into ID3v2
 
<commands>
    -c | --addcovers - Embed $Cover_Front / $Cover_Back into the MP3
    --v1tov2         - Copy ID3v1 Tags into ID3v2 Tag
    --comp           - Set iTunes Compilation flag (TCMP)
 
[OPTIONS]
    -f - The name of the image to look for in each dir to embed front-covers
    -b - The name of the image to look for in each dir to embed back-covers
 
Max Baker max\@warped.org 5/3/2009
end_usage
}
</commands></cmd>

Prerequisites

See the Prerequisites section on this post.

Share and Enjoy:
  • Facebook
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Blogosphere News
  • email
  • LinkedIn
  • Print
  • Reddit
  • Slashdot
  • Add to favorites
  • RSS
  • Technorati
  • PDF

iTunes – Copying ID3 Tags in your MP3s from ID3v1 to ID3v2 in Perl

Update

I’ve consolidated this script into a new one. GO HERE : http://warped.org/blog/2009/05/03/itunes-fixing-id3-tags-in-mp3s-take-two/

Overview

MP3′s have been around almost 15 years now. In the beginning there was a slot in the top of the MP3 file where you could hold the Artist, Album Name, Title, Track Number, etc. This is called the ID3 tag, and is part of every MP3 file. Fast forward some years and the ID3 standard has changed a number of times from V1 to V2 to V2.2, V2.4, etc.

iTunes sucks. iTunes will only use the ID3v2 information in your file, even though the other info is present and perfectly usable. Thanks Apple. FAIL.

The Script

The following script is based on this one by Bob of the UK : http://rnewson.blogspot.com/2005/10/itunes-artwork-fetcher.html

#!/usr/bin/perl -w
# Based on http://rnewson.blogspot.com/2005/10/itunes-artwork-fetcher.html
use MP3::Tag;
 
# Bug that you may need to patch for : https://rt.cpan.org/Ticket/Display.html?id=45647
 
 
foreach my $file (@ARGV) {
    next unless -r $file;
    id3v1_to_id3v2($file);
}
 
sub id3v1_to_id3v2 {
    my $file = shift;
 
    print "$file\n";
    my $mp3 = MP3::Tag->new($file);
    $mp3->get_tags;
    $mp3->config('write_v24',1);
    my $id3v1 = $mp3->{ID3v1};
    my $id3v2 = $mp3->{ID3v2};
    $id3v2 = $mp3->new_tag("ID3v2") unless defined $id3v2;
 
 
    # === TIT2 (Title/songname/content description): Sordid
    # === TPE1 (Lead performer(s)/Soloist(s)): Amon Tobin
    # === TALB (Album/Movie/Show title): Funkungfusion: Ninja Cuts, Vol
    # === TYER (Year): 1998
    # === TRCK (Track number/Position in set): 2
 
    copy($id3v2, 'TPE1', $id3v1->artist);
    copy($id3v2, 'TALB', $id3v1->album);
    copy($id3v2, 'TCON', $id3v1->genre);
    copy($id3v2, 'TRCK', $id3v1->track);
    copy($id3v2, 'TIT2', $id3v1->song);
    copy($id3v2, 'TYER', $id3v1->year);
    copy($id3v2, 'COMM', 'ENG', $id3v1->comment,$id3v1->comment) if $id3v1->comment;
    $id3v2->write_tag;
    $mp3->close;
}
 
sub copy {
   my ($id3v2, $frame, @data) = @_;
    my $value = $data[0];
    return unless defined $value;
    return unless $value !~ /^\s*$/;
 
    my $frameids = $id3v2->get_frame_ids;
    if (exists $$frameids{$frame}) {
        print "  Changing $frame to @data\n";
        $id3v2->change_frame($frame, @data);
    } else {
        print "  Adding $frame = @data\n";
        $id3v2->add_frame($frame, @data);
    }
}

Prerequisites

This script uses MP3::Tag. I had to patch it to work around a bug. See my post on setting the compilation tag for details.

Share and Enjoy:
  • Facebook
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Blogosphere News
  • email
  • LinkedIn
  • Print
  • Reddit
  • Slashdot
  • Add to favorites
  • RSS
  • Technorati
  • PDF

iTunes – Setting the Compilation Flag on MP3′s using Perl

Update

I’ve consolidated this script into a new one. GO HERE : http://warped.org/blog/2009/05/03/itunes-fixing-id3-tags-in-mp3s-take-two/

Overview

If you have an album that’s a compilation or DJ mix, then Cover Flow gets confused and does not group all the tracks together into an album because there is a different “Artist” for each track.

iTunes gets around this by setting it’s own custom flag in the ID3 tag : the TCMP frame in ID3v2 to be specific.

The Script

The following script uses MP3::Tag to set the TCMP flag on all the MP3′s in the current directory, or the files specified on the command line.

#!/usr/bin/perl -w
# mp3_make_comp
# Max Baker
# 4/29/09
#
# This script will set the I-Tunes Compilation Tag (TCMP)
# on Files passed to it.   If no files are passed, it works on *.mp3 in the current directory.
#
 
use MP3::Tag;
 
unless (scalar @ARGV) {
    @ARGV = glob("*.mp3");
}
 
foreach my $f (@ARGV) {
    next unless -r $f;
    add_comp($f);
}
 
sub add_comp {
    my $file = shift;
    my $mp3 = MP3::Tag-&gt;new($file);
    $mp3-&gt;config('write_v24' =&gt; 1);
 
    # scan file for existing tags
    $mp3-&gt;get_tags;
 
    unless (exists $mp3-&gt;{ID3v2}) {
        $mp3-&gt;new_tag("ID3v2");
    }
 
    # check for existing tag
    my ($info, $name, @rest) = $mp3-&gt;{ID3v2}-&gt;get_frame("TCMP");
    if (defined($info)) {
        print "$file : TCMP=$info already set.\n";
        return;
    }   
 
    print "$file : Setting TCMP=1\n";
    $mp3-&gt;{ID3v2}-&gt;add_frame("TCMP", "1") or die "$file : Adding TCMP frame failed.\n";
    $mp3-&gt;{ID3v2}-&gt;write_tag;
    $mp3-&gt;close();
}

Prerequisites

I managed to find a bug in MP3::Tag, so you may have to do the patch found here.

$data = pack("N", length($data)) . compress $data
unless $frame-&gt;flags-&gt;{unchanged};

Becomes:

$data = pack("N", length($data)) . compress $data
unless $frame-&gt;{flags}-&gt;{unchanged};

On line 585 of ID3v2.pm.

Next Up : Copying ID3v1 tags to ID3v2 tags.

Share and Enjoy:
  • Facebook
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Blogosphere News
  • email
  • LinkedIn
  • Print
  • Reddit
  • Slashdot
  • Add to favorites
  • RSS
  • Technorati
  • PDF

ITunes – Embedding Folder.jpg into your MP3s for Cover Flow

Update

I’ve consolidated this script into a new one. GO HERE : http://warped.org/blog/2009/05/03/itunes-fixing-id3-tags-in-mp3s-take-two/

Overview

Let’s say that you have a well organized MP3 collection that you previously used with something like nAMP / Apache::MP3 that already has album art in each directory. Or better yet, you have a friend who does!

You may have collected album art for every album that you have, but good old Itunes will not recognize that. It will only find album art based on the ID3v2 tags in the files, and if the album is available for purchase from Apple.

There are plenty of programs you can download to help you manually add album art to the MP3′s. But if you already have done this, it sucks to have to do it again.

The Script

This script in Perl will embed a Folder.jpg and a Folder_back.jpg to files for use in Itunes. It’s partially based on another script I saw. As soon as I found that again, I’ll add the attribution back in here.

#!/usr/bin/perl -w
# mp3_add_art
# Max Baker <max @warped.org>
# 4/5/09
 
use File::Glob qw(:globally :glob);
use Audio::TagLib;
use Getopt::Long;
GetOptions (\%Args, "h|help", "f|front=s", 'b|back=s');
 
$Cover_Front = $Args{f} || "Folder.jpg";
$Cover_Back  = $Args{b} || "Folder_back.jpg";
 
die &usage if (! scalar @ARGV or $Args{h});
 
foreach my $d (@ARGV) {
    recurse_dir($d);
}
 
exit;
 
sub recurse_dir {
    my $root = shift;
 
    print "Entering $root\n";
 
    # bsd_glob handles spaces in file names/paths
    my @files = bsd_glob("$root/*",GLOB_QUOTE);
    foreach my $f (@files) {
        #print "'$f'\n";
        next if $f eq '.';
        next if $f eq '..';
 
        if (-d $f) {
            recurse_dir($f);
            next;
        }
        if (-r $f and $f =~ /\.mp3$/) {
            add_image($f,"$root/$Cover_Front","FrontCover","Cover (front)") if -r "$root/$Cover_Front";
            add_image($f,"$root/$Cover_Back", "BackCover", "Cover (back)")  if -r "$root/$Cover_Back";
        }
    }
}
sub add_image {
    my ($f,$img,$type,$desc) = @_;
 
    print "add_image($type) $img -> $f\n";
 
    my $mp3 = Audio::TagLib::MPEG::File->new($f) or die;
    my $id3v2 = $mp3->ID3v2Tag(1);
    open(PICFILE, "< $img") or die "Can't open image $img. $!\n";
 
    my $imgdata;
    my $filesize = -s PICFILE;
    binmode(PICFILE);
    read(PICFILE, $imgdata, $filesize);
    close(PICFILE);
 
    my $imgbv = Audio::TagLib::ByteVector->new();
    $imgbv->setData($imgdata,$filesize);
    my $bv = Audio::TagLib::ByteVector->new("APIC");
    my $field = Audio::TagLib::ID3v2::AttachedPictureFrame->new($bv, "UTF8");
    $field->setPicture($imgbv);
    $field->setTextEncoding("UTF8");
    $field->setMimeType(Audio::TagLib::String->new("image/jpeg"));
    $field->setType($type);
    $field->setDescription(Audio::TagLib::String->new($desc));
    $id3v2->addFrame($field);
    $mp3->save();
}
 
sub usage {
    return < < "end_usage";
 
mp3addart <dir>
 
Max Baker </max><max \@warped.org> 4/6/2009
 
This script recursively goes through a directory and imbeds album
art into MP3 Files. It uses taglib and Audio::TagLib.
 
USAGE: $0 <dir> [-f $Cover_Front] [-b $Cover_Back]
 
    -f - The name of the image to look for in each dir to embed front-covers
    -b - The name of the image to look for in each dir to embed back-covers
 
 
end_usage
}
</dir></max>

Prerequisites

You’ll notice in the prerequisites a Perl module you can get off of CPAN : Audio::Taglib.
For which you’ll need the TagLib library.

You should install the TagLib library using packages. For me using Fedora/Mythdora 10 I used this command :

yum install taglib-devel

The only problem is that TagLib has moved on to version 1.5 and Audio::TagLib hasn’t quite caught up yet. So you need to modify one line in Audio::TagLib before installing it. The file you are editing is
Makefile.PL.

BEGIN {
    # a simple work around to perform the neccessary pre-check
    # instead of overloading subs of MakeMaker or other wrapper
    print STDERR "ONLY support TagLib version 1.4.*\n";
    require Carp;
	# FIXME
	# openned for FreeBSD, OS X (darwin) and Cygwin
    Carp::croak("$^O is not supported currently") 
		unless $^O eq 'linux' or $^O eq 'freebsd' or $^O eq 'darwin' or 
		    $^O eq 'cygwin';
	Carp::croak("Please install taglib C++ package first") unless 
		system("taglib-config --version") == 0;
	our $libver = qx(taglib-config --version);
	chomp($libver);
	Carp::croak("Please install taglib ver 1.4.*") unless 
		$libver =~ m/^1\.4/io;
	our $libs = qx(taglib-config --libs);
	our $inc  = ' -I/usr/include -I./include -I. '. qx(taglib-config --cflags);
}

BECOMES :

BEGIN {
    # a simple work around to perform the neccessary pre-check
    # instead of overloading subs of MakeMaker or other wrapper
    print STDERR "ONLY support TagLib version 1.4.*\n";
    require Carp;
	# FIXME
	# openned for FreeBSD, OS X (darwin) and Cygwin
    Carp::croak("$^O is not supported currently") 
		unless $^O eq 'linux' or $^O eq 'freebsd' or $^O eq 'darwin' or 
		    $^O eq 'cygwin';
	Carp::croak("Please install taglib C++ package first") unless 
		system("taglib-config --version") == 0;
	our $libver = qx(taglib-config --version);
	chomp($libver);
	Carp::croak("Please install taglib ver >1.4.*") unless 
		$libver =~ m/^1\.[45]/io;
	our $libs = qx(taglib-config --libs);
	our $inc  = ' -I/usr/include -I./include -I. '. qx(taglib-config --cflags);
}

So that Version 1.4 and 1.5 are OK. Some tests fail, but otherwise it seems to work fine for me.

Next up : Setting the compilation Flag from a script.

Share and Enjoy:
  • Facebook
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Blogosphere News
  • email
  • LinkedIn
  • Print
  • Reddit
  • Slashdot
  • Add to favorites
  • RSS
  • Technorati
  • PDF

chown3d Part 2 – GTK+ and GLIB in your own home directory

ch0wned. adj. This is the state when you are a linux user and don't have root access.

For today’s installment we go over getting some basic libraries up to shape. If your Linux distro is old enough, you can’t use 3rd party binaries like Adobe Acrobat Reader (acroread), Firefox, and Flash because the GTI+ and GLIB libraries that they are compiled against are just too damned old. So we have to both install local copies, and have the applications find those copies instead of the system ones.

On Versions

It’s good to note that you can upgrade a newer version of most things, but don’t expect to always get the newest version. Instead you need to find the next newest version that still works on your old Linux distro while satisfying the prerequisites for your favorite applications.

GTK+ and GLIB and RHEL4

Here are the packages I installed in order to get GTK+ and GLIB up to date enough to use Firefox, Pidgin, Thunderbird, Acrobat, and some other goodies on Red Hat EL4 (Fedora 4 should be similar) :

  1. atk-1.25.2.tar.bz2 – Needed by Pidgin
  2. pixman-0.13.2.tar.gz
  3. libxml2-2.6.30.tar.bz2 – Needed by Pidgin, the EL4 version is horribly broken and Gtalk / Jabber end up w/ a very weird send-only behavior
  4. pkg-config-0.23.tar.gz – Needed by most everything. You will have a new package repository in $HOME/lib/pkg-config for your new libraries.
  5. cairo-1.8.6.tar.gz
  6. dbus-1.2.12.tar.gz
  7. dbus-glib-0.78.tar.gz
  8. glib-2.19.5.tar.bz2
  9. pango-1.22.4.tar.bz2
  10. zlib-1.2.3.tar.bz2 – RHEL4 version is crap.
  11. gtk+-2.14.7.tar.bz2

Order does count, but I don’t remember what order I compiled and installed these in. Trial and error will tell. Use config_gapp from Part 1 to compile.

You will need to do this on each of the above :

$ tar xvfj gtk+-2.14.7.tar.bz2
$ cd gtk+-2.14.7
$ ../config_gapp
$ make
$ make install

Remember this is installing these libraries into $HOME/lib using the config_gapp script.

Some of the libraries might take some extra args to make things happy.

  1. zlib – I need to add -fPIC to make mozilla happy
    $ CFLAGS=-fPIC ../config_gapp
  2. gtk+-2.14.7 – I had to add –without-libjasper
    $ ../config_gapp --without-libjasper

Some blood sweat and tears later, and now you should be able to run a binary version of Firefox if you are on a 32-bit RHEL4 machine.

Running Apps using the Libraries in your Home Directory

In order to have applications grab the libraries in your home directory instead of the system ones, I use a wrapper script that sets up a bunch of needed environment variables. I call this script “run_gapp” :

#!/bin/sh
#
# install apps using local versions of libraries for this platform
#
# This script is for an x86_64 machine
# Remove 64 anywhere below if you are on a 32-bit build
 
LOC_HOME=/home/me
 
export CPPFLAGS="-I${LOC_HOME}/include -I/usr/X11R6/include $CPPFLAGS"
export CFLAGS="-I${LOC_HOME}/include -I/usr/X11R6/include $CFLAGS"
export CXXFLAGS="-I${LOC_HOME}/include -I/usr/X11R6/include $CXXFLAGS"
export LDFLAGS="-L${LOC_HOME}/lib -L/usr/X11R6/lib -L/usr/lib64 $LDFLAGS"
export PKG_CONFIG_PATH="${LOC_HOME}/lib/pkgconfig:/usr/lib/pkgconfig:/usr/lib64/pkgconfig:/usr/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="${LOC_HOME}/lib:/usr/X11R6/lib64:/usr/lib64:$LD_LIBRARY_PATH"
 
exec "$@"

Now to run a binary we just use the wrapper

run_gapp /path/to/firefox

Next up we’ll explore building some applications like pidign, firefox, amarok, xine-lib and more.

Share and Enjoy:
  • Facebook
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Blogosphere News
  • email
  • LinkedIn
  • Print
  • Reddit
  • Slashdot
  • Add to favorites
  • RSS
  • Technorati
  • PDF

chown3d – A Linux distro in your home directory

I’m coining a new term here : chown3d (or ch0wn3d depending on how l33t you are).   

ch0wned. adj. This is the state when you are a linux user and don't have root access. 

This is the case for a lot of people working Corporate jobs as engineers, including me.   I realized chr00ted is a more appropriate term, but then I couldn’t work 0wned into it.

So this post is the first in a serious of HOWTOs about maintaining a Linux distro out of your home directory.  This allows you to download, compile, and use the latest software while being restricted to god-awful old version of Linux.   When I say old, I’m talking about my company just “upgraded” me from Red Hat Enterprise 3 (RHEL 3), circa 2003 to Red Hat Enterprise 4 (RHEL 4) circa 2006.   If I want to use a browser or e-mail client that has the latest security patches, forget it!

Compiling

About 90% of the open source apps out there use autoconf to setup compilation using gmake.   The first thing we need to do is tell it that we are going to install this directory into our home directory.

./configure --prefix=/home/me

However, if you happen to have a lot of dependency libraries installed in your home directory we will need to setup a few environment variables too. So instead I setup a shell script that sets-up the environment and calls configure. I call this script “config_gapp”

#!/bin/sh
#
# install apps using local versions of glib
# into home directory
#
# This version setup for x86_64 full 64-bit
# Remove "64" anywhere below for a 32-bit build.
 
LOCAL_HOME=/home/me
 
export PATH=$LOCAL_HOME/bin:$PATH
 
# I try not to maintain my own gcc, but sometimes you gotta :
# export CC="$LOCAL_HOME/bin/gcc"
# export GCC=$CC
 
export CPPFLAGS="-I$LOCAL_HOME/include -I/usr/X11R6/include $CPPFLAGS"
export CFLAGS="-I$LOCAL_HOME/include -I/usr/X11R6/include $CFLAGS"
export CXXFLAGS="-I$LOCAL_HOME/include -I/usr/X11R6/include  $CXXFLAGS"
export LDFLAGS="-L$LOCAL_HOME/lib -L/usr/lib64 -L/usr/X11R6/lib64 $LDFLAGS"
export PKG_CONFIG=$LOCAL_HOME/bin/pkg-config
export PKG_CONFIG_PATH="$LOCAL_HOME/lib/pkgconfig:/usr/lib64/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$LOCAL_HOME/lib:/usr/X11R6/lib64:/usr/lib64"
#export ACLOCAL_FLAGS="-I /home/maxb/share/aclocal"
 
./configure --prefix=$LOCAL_HOME \
  --x-includes=/usr/X11R6/include \
  --x-libraries=/usr/X11R6/lib "$@"

The astute reader will notice that I have already compiled and installed my own copy of pkg-config because the one on EL4 is too old for most things to use. I’ll cover that in the next post where I go over getting a somewhat modern version of the GTK+ and Glib libraries installed. These are required for most anything modern like firefox, thunderbird, acrobat, and flash.

Share and Enjoy:
  • Facebook
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Blogosphere News
  • email
  • LinkedIn
  • Print
  • Reddit
  • Slashdot
  • Add to favorites
  • RSS
  • Technorati
  • PDF

The free one-handed keyboard

One Handed Typing

After a recent mountain biking accident I found myself typing with my left hand only.   Well, not just typing but doing everything else really.

Figuring that there are plenty of people in this world who are in the same boat permanently or temporarily  I googled around for “the” solution.    The ironically long-named domain www.aboutonehandtyping.com seems to be the Google-elected source on the subject followed shortly by www.onehandedkeyboard.com, half-qwerty.com, and www.bltt.org.  There seems to be a number of hardware solutions like the $600 half-qwerty,  and some proposed soft solutions like turning on left-hand Dvorak.  However i was on the hunt for a free half-qwerty solution for Windows.

My Solution

Ultimately,  I found what I was looking for in a program called AutoHotKey.  This program inserts itself between the keyboard and Windows and allows for customization and scripting.   Best of all, its free and works well in XP and Vista.

I again struck gold to find out the hard part had already been done and a 1-handed layout was created in this discussion.  There are a number of different scripts to do the job in that thread, but I found the most useful one by a user named mbirth.   To use his solution you only need install AutoHotKey and download his script here (mirrored locally too).

Taking it a Step further

I found I wanted to tweak his setup a little to be more left-hand specific so I made these modifications to HalfKeyboard.ahk.

1. Put -_ where `~ is,  =+ where 6^ is, and ‘” where hH were.

Change

  original := "``" . "12345qwertasdfgzxcvb"   ; split up string for better
  mirrored := "'"  . "09876poiuy;lkjh/.,mn"   ; human readability

To

  original := "``" . "12345qwertasdfgzxcvbh6"   ; split up string for better
  mirrored := "-"  . "09876poiuy;lkjh/.,mn'="   ; human readability

2.  Add page-up and page-down as Ctrl-4 and Ctrl-5 by adding these two lines

^4::Send {PgUp}
^5::Send {PgDn}

Ghetto Hardware Solution

Take a much closer look at the keyboard above:

The final step was easy and fun: buy a $20 keyboard and swap the keys around.    I was able to do this 1-handed no problem.    Alternately, you can just hit “Space-F1″ with the above setup to get a map.  Of course changing the keys doesn’t actually do anything.  Its the program that does the work.

Share and Enjoy:
  • Facebook
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Blogosphere News
  • email
  • LinkedIn
  • Print
  • Reddit
  • Slashdot
  • Add to favorites
  • RSS
  • Technorati
  • PDF