Tagging songs

January 1st, 2011

Normally all of our songs are arranged in directory/folder structures (for eg. each folder contains all the songs of a particular movie, or of a singer, etc) on our computer. However when moving these songs to an MP3-player/iPod/mobile-phone, these systems do not understand folder structure; instead they expect the songs to be tagged correctly into separate albums so that one can play/repeat within an album.

While i would love if my MP3-player/iPod/mobile-phone understood that the folder really represents an album and that i want to cycle through all the songs within this folder, this is not to be. So the way to solve this problem is to tag all of my songs. But that’s a tedious task to edit the metadata of _all_ of my songs. Fortunately, 2 things come running to our help:

  1. Our songs are already _arranged_ in folders
  2. We’re on linux, and there are commands (tools/utilities) that we can loop through

Before i give the solution, there are a few assumptions:

  1. There are no spaces in any of the file/directory names, otherwise our loops might not work correctly. If that is the case, then please use some bulk file rename tool to convert all spaces to _ (underscore), or remove the spaces from the file/directory names completely
  2. The directory depth is zero or one only. That is, we are either inside a directory containing just songs, or inside a directory which contain directories which contain just songs. eg
    • Case 1: We are inside a ‘songs’ directory which contains only mp3 files, and no directories at all
    • Case 2:Or, we’re inside a ‘songs’ directory, which contains directories (only) like ‘a’, ‘b’, ‘c’, and so on. Each of ‘a’, ‘b’, ‘c’, … contain just mp3 files and no sub-directories
    • I hope that wasn’t too confusing ;)

  3. You’ve installed the id3ed tool
  4. The folder name (which contains the actual song files) is the same as the name of the album (with which you want to tag the song file)

Now the solution. Go to the ‘songs’ directory, and then:

  • Case 1: p=`pwd`; a=`basename $p`; for j in `find \*mp3`; do echo $j; id3ed -q -s $j -a $a $j; done
  • Case 2: for i in `ls`; do pushd $i; for j in `find \*mp3`; do echo $j; id3ed -q -s $j -a $i $j; done; popd; done

Now all of your song files have been tagged, and you may move them to your MP3-player/iPod/mobile-phone and play them as albums!

Enabling the ‘CapsLock’ key for colemak layout in linux

December 12th, 2010

Hello,

I’ve finally found the solution for enabling the ‘caps-lock’ key for colemak layout in linux after searching on the Internet for months. The solution is really so simple that i’m surprised I wasn’t able to find it even after spending hours online.

Now for the solution. How i enable colemak on my debian linux is by using the xmodmap.colemak file as follows

setxkbmap us; xmodmap colemak-1.0/xmodmap/xmodmap.colemak && xset r 66

as specified in http://colemak.com/Unix#Linux.2FUnix_in_graphical_mode_using_xmodmap

Now all one needs to do is edit the xmodmap.colemak file and comment out the (add an exclamation mark at the begining of the line) line which says

clear Lock
to make it as
!clear Lock

And thats it. Your caps lock will now work as expected!

Left arrow key on colemak

May 4th, 2010

I’ve been using the colemak keyboard layout for quite some time now. I’m still not sure if it is helping me or not, but now am not in a mood to re-learn qwerty.

Anyways, there’s one *big* problem with the colemak layout (atleast on linux systems, not sure if it occurs on other systems too) which is that the ‘left arrow key’ simply does not work. Searching online (quite a few number of times at different occasions) did not help at all. All I found were some occurrences saying that people were facing the issue (which meant that I was not the only one facing it). However, I did not find any solutions.

So, when, today, I did find out how to fix the issue, I thought that I should put it up on my blog; and give something back to the community ;)

The actual solution is very simple:-

Instead of running
setxkbmap us; xmodmap ~/downloads/colemak-1.0/xmodmap/xmodmap.colemak && xset r 66

as colemak suggests, we should run

setxkbmap us; xmodmap ~/downloads/colemak-1.0/xmodmap/xmodmap.colemak && xset r 66; xmodmap -e "keycode 113 = Left NoSymbol Left"

p11.lisp

March 28th, 2010

P11 (*) Modified run-length encoding.
Modify the result of problem P10 in such a way that if an element has no duplicates it is simply copied into the result list. Only elements with duplicates are transferred as (N E) lists.

    Example:
    * (encode-modified '(a a a a b c c a a d e e e e))
    ((4 A) B (2 C) (2 A) D (4 E))

Solution:-

(defun group (lst)
  (cond ((eql (first lst)
              (first (rest lst)))
         (cons (first lst)
               (group (rest lst))))
        (t (list (first lst)))))
(defun from-k (lst k)
  (cond ((< k 0) nil)
        ((= k 0) lst)
        (t (from-k (rest lst) (decf k)))))
(defun modified-encode (lst)
  (cond ((null lst) nil)
        (t (let ((l (group lst)))
             (if (= 1 (length l))
                 (cons (first l)
                         (modified-encode (from-k lst (length l))))
                 (append (list (list (length l) (first l)))
                         (modified-encode (from-k lst (length l)))))))))

p10.lisp

March 28th, 2010

P10 (*) Run-length encoding of a list.
Use the result of problem P09 to implement the so-called run-length encoding data compression method. Consecutive duplicates of elements are encoded as lists (N E) where N is the number of duplicates of the element E.

    Example:
    * (encode '(a a a a b c c a a d e e e e))
    ((4 A) (1 B) (2 C) (2 A) (1 D)(4 E))

Solution:-

(defun group (lst)
  (cond ((eql (first lst)
              (first (rest lst)))
         (cons (first lst)
               (group (rest lst))))
        (t (list (first lst)))))
(defun from-k (lst k)
  (cond ((< k 0) nil)
        ((= k 0) lst)
        (t (from-k (rest lst) (decf k)))))
(defun encode (lst)
  (cond ((null lst) nil)
        (t (let ((l (group lst)))
             (append (list (list (length l) (first l)))
                     (encode (from-k lst (length l))))))))

p09.lisp

March 28th, 2010

P09 (**) Pack consecutive duplicates of list elements into sublists.
If a list contains repeated elements they should be placed in separate sublists.

    Example:
    * (pack '(a a a a b c c a a d e e e e))
    ((A A A A) (B) (C C) (A A) (D) (E E E E))

Solution:-

(defun group (lst)
  (cond ((eql (first lst)
              (first (rest lst)))
         (cons (first lst)
               (group (rest lst))))
        (t (list (first lst)))))
(defun from-k (lst k)
  (cond ((< k 0) nil)
        ((= k 0) lst)
        (t (from-k (rest lst) (decf k)))))
(defun pack (lst)
  (cond ((null lst) nil)
        (t (let ((l (group lst)))
             (append (list l) (pack (from-k lst (length l))))))))

p08.lisp

March 28th, 2010

P08 (**) Eliminate consecutive duplicates of list elements.
If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed.

    Example:
    * (compress '(a a a a b c c a a d e e e e))
    (A B C A D E)

Solution:-

(defun rem-dup (char lst)
  (cond ((null lst) nil)
        ((= (length lst) 1) lst)
        ((eql char (first lst))
         (rem-dup char (rest lst)))
        (t (append (list char)
                   (rem-dup (first lst) (rest lst))))))
(defun compress-1 (lst)
  (rem-dup (first lst) (rest lst)))

Solution-2

(defun compress-2 (lst)
  (cond ((null lst) nil)
        ((null (rest lst)) lst)
        ((eql (first lst) (first (rest lst)))
         (compress-2 (rest lst)))
        (t (cons (first lst) (compress-2 (rest lst))))))

p07.lisp

March 21st, 2010

P07 (**) Flatten a nested list structure.
Transform a list, possibly holding lists as elements into a `flat’ list by replacing each list with its elements (recursively).

Example:
* (my-flatten ‘(a (b (c d) e)))
(A B C D E)

Hint: Use the predefined functions list and append.

Solution

(defun my-flatten (lst)
  (cond ((null lst) nil)
        ((typep (first lst) 'list) (append (my-flatten (first lst))
                                           (my-flatten (rest lst))))
        (t (append (list (first lst))
                   (my-flatten (rest lst))))))

p06.lisp

March 21st, 2010

P06 (*) Find out whether a list is a palindrome.
A palindrome can be read forward or backward; e.g. (x a m a x).

Solution

(defun rev (lst)
  (if (null lst)
      nil
      (append (rev (rest lst)) (list (first lst)))))
(defun is-palindrom (lst)
  (equal lst (rev lst)))

p05.lisp

March 21st, 2010

P05 (*) Reverse a list.

Solution

(defun rev (lst)
  (if (null lst)
      nil
      (append (rev (rest lst)) (list (first lst)))))