QText 3.50

It is time for new QText again.

Nothing much happened, just some maintenance. I added support for few more keyboard shortcuts (zoom and plain-text clipboard) and some minor bug-fixing was done.

As always, you can download new version directly from www.medo64.com or use built-in upgrade menu.

PS: If you are curious what exactly was changed and/or you want to use new features as I create them, you can check source code repository at BitBucket. There I will put latest pre-release binaries.

Inline Sorting

Sort is something that is almost mandatory when dealing with user-facing data. Everybody is so used to have items sorted that unsorted list really sticks out.

Assuming that we have list named myList, sorting is really easy to implement. Just call myList.Sort(). This method will search for IComparable interface (somewhat simplified view) and use it to compare elements. But what if we want order other than one defined in IComparable? And what can be done if there is no way to implement such interface (e.g. no source code for class)?

You can count on our friend delegate and Sort overload. Assuming that we want to do sort according to property DisplayName, code is:

drivers.Sort(
    delegate(MyClass item1, MyClass item2) {
        return string.Compare(item1.DisplayName, item2.DisplayName);
    });

Yes, I know that code is old fashioned and that Linq is sooooo much better. However, this code will work on .NET Framework 2.0. And it doesn’t look that bad. :)

Movie Maker and Mp4 Audio Sync

It all started when I used Microsoft’s LifeCam under Windows 8 to record a bit of video. At the end of this quite easy process I was greeted with MP4 file. All that I had to do is to import it in Movie Maker to do some processing. How hard can that be?

Well, quite hard actually. As I imported video in Movie Maker, I noticed that sound was not in sync with video. At first I was thinking that input video had an error but every video player worked correctly. For some reason only video editing software had an issue. What followed was few hours of swimming through Internet and learning everything possible about variable frame rate and how it can make your life a misery. Here is how I got this mess sorted out.

First tool I used was a GraphStudioNext. Once I opened my video this tool showed me processing graph my video goes through. I just went in and deleted last step in audio processing (Default WaveOut Device). That left AC3Filter with unconnected out pin. I used File -> Save As Graph to get MyVideo.grf.

Next in line was AviSynth. Once it got installed, I created file MyVideo.avs with following content:

video=DirectShowSource("C:\MyVideo.mp4", audio=false, fps=29.97, convertfps=true)
audio=DirectShowSource("C:\MyVideo.grf", video=false)
audio=AssumeSampleRate(audio, 44100)
audio=TimeStretch(audio, pitch=108.8435)
AudioDub(video,audio) 
EnsureVBRMP3Sync()

This deserves a bit of explaining. First line loads video with constant frame rate of 29.97 which coincides with my camera’s output. After that it loads audio (sampled at 48 kHz). And no, I could not use DirectShowSource to open both audio and video together because audio would sped up for some reason. To get everything back in sync, next line assumes that audio is 44.1 kHz. Notice that this is not true and it will make voice sound very deep. However, it will fix sync. TimeStretch will bring back pitch of our voice while preserving sample rate (value 108.84 is simply 48000/44100*100).

File MyVideo.avs can now be loaded in any video player. Only program that refuses to load this file is Movie Maker. It was time to cheat a bit. I used VirtualDub to open MyVideo.avs and and then I just exported audio (File -> Save WAV).

Last step was to load original video in Movie Maker and mute video volume. Then I used Add music to insert MyVideo.wav as a track. And with that Movie Maker had everything it needed to export final video.

Visual Studio 2012 - Update 2

After long time in CTP, Visual Studio 2012 finally got its second update.

Quite a lot of changes touch agile workflows and this alone will make it worthwhile. Unlike update 1, there are actually quite a few changes related to development so this is definitely update to install.

Update is cumulative so you don’t need anything other than base Visual Studio 2012 installation. Go forth and download.

PS: My favorite new feature is grouping of unit tests by class name and possibility to add them in playlists.

PPS: Feature that I wish I had is new Code Map. Unfortunately it is not available on Visual Studio 2012 Professional and below. :(

From One to Two Processors in Windows XP

I used to have physical machine running XP that could not be upgraded (don’t let me start about reasons… :/). Since having old machine around gets annoying quite quickly, I used Sysinternals disk2vhd in order to have it work in VirtualBox. And it worked flawlessly. Or so I thought.

Few days ago I tried to run a bit higher load on this virtual machine and I was surprised to learn that only single processor was used regardless of two virtual ones that were available. Task manager simply reported one processor while it was clear from Device Manager that there were two available. This curiosity probably had lot to do with detected Advanced Configuration and Power Interface (ACPI) PC which actually has no multiprocessor support.

When I checked boot.ini its content was:

[boot loader]
timeout=3
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect /KERNEL=ntkrpuni.exe /HAL=halacpi.dll

Notice how there uniprocessor HAL is forced by using /KERNEL=ntkrpuni.exe /HAL=halacpi.dll. This happens when you use disk2vhd to do physical to virtual conversion. In order to make it more compatible, it will restrict it to single processor. To have any chance of detecting second processor you must remove both /KERNEL and /HAL arguments completely.

Next step is to actually replace HAL. Official way of doing this is Windows recovery but there is also a possibility of using devcon.exe command-line tool. Its example code page lists Forcibly update the HAL as example 44. This sounds exactly as something we would need.

Procedure is simple:

> devcon sethwid @ROOT\ACPI_HAL\0000 := +acpiapic_mp !acpipic_up
ROOT\ACPI_HAL\0000 : acpiapic_mp
Modified 1 hardware ID(s).

> devcon update c:\WINDOWS\inf\hal.inf acpiapic_mp
Updating drivers for acpiapic_mp from c:\WINDOWS\inf\hal.inf.
Drivers updated successfully.

If everything went ok, you will need to restart. And then restart once more when asked to. After second boot your Windows XP system will (hopefully) use both processors.

PS: If you ever want to get back to using single processor, it is even simpler - just re-add /KERNEL=ntkrpuni.exe /HAL=halacpi.dll to your boot.ini entry.

PPS: Do not forget to backup your virtual machine before doing this stuff.