Tuesday 14 September 2010

Converting from ogg to mp3 in Matroska (mkv) files

NB, this is very vague. Please do not just copy and paste, it probably won't work and will most likely cause you to lose the file you are working on. This is an example and you'll need
to alter it to your specific mkv file:


You'll need mkvtoolnix, and lame installed.

First, get information about the video file:

mkvinfo file.mkv

extract the video and audio files you want to convert:

mkvextract tracks 1:file.vid
mkvextract tracks 2:file.en.ogg

convert (just ogg to mp3 for me)

oggdec file.eng.ogg -R -b 16 -o - | lame -s 48 -b 16 -m s -x -r - -q 2 -b 128 file.eng.mp3

Merge back into the mkv container:


mkvmerge -o file.2.mkv file.vid file.eng.mp3

You can now check file.2.mkv to see if it works correct.

Tuesday 17 August 2010

Spread and Perl

If you are here, you have most likely run into the problem of message passing, or interprocess communications, of some form or another.

You want applications to be able to talk to each other ... without writing code that (should) scare you.

The Spread Toolkit is, to quote its homepage, an open source toolkit that provides a high performance messaging service that is resilient to faults across local and wide area networks

Now, that description is perhaps not buzzword, rad fuelled 'boom' sockets on steroids, but Spread has been around for a while, and Ubuntu and Debian comes with packages out of the box. Things I like.

Spread also has bindings for a host of languages, including C, Perl, Ruby and Python. So, as an alternative to 0mq, rabbitmq, etc, possibly requiring less commitment, it may be worth a look.

I'll go through running the daemon on Ubuntu, and a Perl script. It is dead simple, though the Perl Module documentation may obscure that a bit.

Install the Spread daemon


As root (or using sudo)

apt-get install spread libspread-perl

At least in Ubuntu 10.04 LTS, there is a problem with the package at the time of writing where the maintainer has specified the configuration file location incorrectly. Also, since the config file binds to localhost, you need to set the process name with the -n switch for it to run. If not it quits with an error message similar to:

[Tue 17 Aug 2010 14:59:41] Conf_init: My proc id (127.0.1.1) is not in configuration
 Exit caused by Alarm(EXIT)

There is a Ubuntu bug report, but here is a quick
rundown on how to fix this:

  • update /etc/init.d/spread

    change the line:
    DOPTIONS="-c /etc/spread.conf"
    
    to
    DOPTIONS="-c /etc/spread/spread.conf"
    
  • update the /etc/default/spread file to:

    # Change to enable spread
    ENABLED=1
    
    # Options, see spread.1 for list
    OPTIONS="-n localhost"
    
That should be that. You can now start the daemon with
/etc/init.d/spread start

Spread on Perl

The simplest demo I could create was as follows:
1 #!/usr/bin/perl
  2
  3 use strict;
  4 use warnings;
  5
  6 use Spread;
  7
  8 # connect
  9 my ( $mbox, $private_group ) = Spread::connect( {
 10         spread_name  => '4803@localhost',
 11         private_name => 'myname',
 12         group_membership => 0 # we don't want to hear who joins/leaves groups
 13         });
 14 die 'Unable to connect' unless (defined($mbox));
 15
 16 # join a group
 17 Spread::join($mbox, 'mygroup') or die 'Failed to join group';
 18
 19 # multicast message to group
 20 Spread::multicast( $mbox, AGREED_MESS, 'mygroup', 0, "this is your message" );
 21
 22 # poll for messages
 23 my ($messsize);
 24 while ($messsize = Spread::poll($mbox)) {
 25     print "--Next message: $messsize bytes\n";
 26     my ( $service_type, $sender, $groups, $mess_type, $endian, $message ) = Spread::receive($mbox);
 27     print "\tsender : $sender\n";
 28     print "\tgroups : " . join(',', @$groups) . "\n";
 29     print "\tmessage : [$message]\n";
 30 }
 31
 32 Spread::disconnect($mbox);
This should give you the following output:
--Next message: 100 bytes
        sender : #myname#localhost
        groups : mygroup
        message : [this is your message]
If you want to also have a look at the Message join/leave/etc messages, here's the same example slightly modified:
1 #!/usr/bin/perl
  2
  3 use strict;
  4 use warnings;
  5 use Data::Dumper;
  6 use Spread qw(:MESS);
  7
  8 my %types = (
  9     0x00000001 => 'UNRELIABLE_MESS',
 10     0x00000002 => 'RELIABLE_MESS',
 11     0x00000004 => 'FIFO_MESS',
 12     0x00000008 => 'CAUSAL_MESS',
 13     0x00000010 => 'AGREED_MESS',
 14     0x00000020 => 'SAFE_MESS',
 15     0x0000003f => 'REGULAR_MESS',
 16     0x00000040 => 'SELF_DISCARD',
 17     0x00000100 => 'CAUSED_BY_JOIN',
 18     0x00000200 => 'CAUSED_BY_LEAVE',
 19     0x00000400 => 'CAUSED_BY_DISCONNECT',
 20     0x00000800 => 'CAUSED_BY_NETWORK',
 21     0x00001000 => 'REG_MEMB_MESS',
 22     0x00002000 => 'TRANSITION_MESS',
 23     0x00003f00 => 'MEMBERSHIP_MESS',
 24     0x003fc000 => 'RESERVED',
 25     0x00400000 => 'REJECT_MESS',
 26     0x01000000 => 'DROP_RECV',
 27     0x80000080 => 'ENDIAN_RESERVED',
 28            );
 29
 30 # connect
 31 my ( $mbox, $private_group ) = Spread::connect( {
 32         spread_name  => '4803@localhost',
 33         private_name => 'myname',
 34         group_membership => 1
 35         });
 36 die 'Unable to connect' unless (defined($mbox));
 37
 38 # join a group
 39 Spread::join($mbox, 'mygroup') or die 'Failed to join group';
 40
 41 # multicast to group
 42 Spread::multicast( $mbox, AGREED_MESS, 'mygroup', 0, "this is your message" );
 43
 44 # Poll mailbox
 45 my ($messsize);
 46 while ($messsize = Spread::poll($mbox)) {
 47     print "--Next message: $messsize bytes\n";
 48     my ( $service_type, $sender, $groups, $mess_type, $endian, $message ) = Spread::receive($mbox);
 49     print "\tservice_type: $service_type (" .
 50         join('|', map { $types{$_} }  grep { $_ & $service_type } ( keys %types ) ) .
 51         ")\n";
 52     print "\tsender : $sender\n";
 53     print "\tgroups : " . Dumper($groups);
 54     print "\tmess_type : $mess_type\n";
 55     print "\tendian : $endian\n";
 56     $message =~ s/[^[:print:]]/./g;
 57     print "\tmessage : [$message]\n";
 58 }
 59
 60 Spread::disconnect($mbox);
Which outputs
--Next message: 228 bytes
        service_type: 4352 (MEMBERSHIP_MESS|REG_MEMB_MESS|CAUSED_BY_JOIN)
        sender : mygroup
        groups : $VAR1 = [
          '#myname#localhost'
        ];
        mess_type : 0
        endian :
        message : [......jL........#myname#localhost...............]
--Next message: 100 bytes
        service_type: 16 (REGULAR_MESS|AGREED_MESS)
        sender : #myname#localhost
        groups : $VAR1 = [
          'mygroup'
        ];
        mess_type : 0
        endian :
        message : [this is your message]

Note there is binary in the message returned, not handled by the Perl wrapper.

Have fun.

Sunday 2 May 2010

How to get Canon's Digital Photo Professional (dpp) to work under Linux

DPP can be made to work reasonably well under wine in Linux by using the version
under revision control, revert a patch, and apply another:

  1. Make sure you have git installed

    If you are running Debian you can do so with apt-get install git-core

  2. Get the build dependencies for wine.

    If you are using Debian, the simplest way is to add a sources list to /etc/apt/sources.list, and do:
    apt-get update
    apt-get build-dep wine
    

    I did not need everything for all the features, so I just installed some of these packages.
  3. Get wine from revision control:

    git clone git://source.winehq.org/git/wine.git wine-git
    

  4. Fix DPP wine issues

    The issues with DPP under wine are covered on http://appdb.winehq.org/, specifically, at the time of this writing: http://appdb.winehq.org/objectManager.php?sClass=version&iId=7813 Here you'll find problems and solutions. I only had 2 problems:

    12001 chemsketch won't display
    13344 DPP 3.4.1.1 - Images with "Fit to window" corrupted
     

    Follow the instructions on these pages to resolve the issues. For me, on git branch master 93f9c32, this was:

    git revert accfce21d3e042638a5eac8a8379eda2964fcd0a
    get http://www.winehq.org/pipermail/wine-patches/attachments/20100426/2c75de0d/attachment-0003.asc
    .. strip out just the first patch. Basically you want the bit starting with ---a/dlls/gdi32/dib.c till
    just before the next line starting with ---
    Save this as /tmp/patchfile, and then from the wine-git directory, do:
    cat /tmp/patchfile | patch -p1
    

    This should tell you it patched the file.

  5. Compile
    ./configure
    make
    

  6. Run from wine-git, or install system wide
    I have a script, called dpp, which checks for a locally modified wine. If it finds it under my home directory it runs dpp with that wine. This saves me from installing wine-git system wide:
    #!/bin/sh
    
    if [ -d /home/yourname/dl/w/wine-git ]
    then
            echo "Found locally compiled wine. Setting path."
            export PATH="/home/yourname/dl/w/wine-git:/home/yourname/dl/w/wine-git/tools$PATH"
    fi
    
    wine ~/.wine/drive_c/Program\ Files/Canon/Digital\ Photo\ Professional/DPPViewer.exe $1
    
    
    If you want to install wine system wide, do
    sudo make install
    

Friday 19 February 2010

New York 2009/10

These are some of the images from our visit to NY over new year.

Scenes of yellow cabs and street with mists rising from manhole covers reminisce of movies. It was cold and windy though ... so the mist was quickly blown away. I managed to get a shot or two of it though.





This was taken from The Top of the Rock, 30 Rockefeller Plaza.


A nice and grainy shot as we came up to the statue of liberty



Beautiful sky, leaving for Ellis Island



View from Ellis Island, towards Manhattan



Back on the boat



Whirlwind through the Museum of Natural History, and Central Park





Gold rush?




Dusk at the top of the Empire State



On the streets of New York, and under