Sister Act – I will follow him

Today I read a post on facebook of my friend. She shares a small clip of film sister act. I like this song and would like to share it with you. You can download mp3 version “I will follow him” or take a look at video below.

Lyrics:

-I will follow Him
Follow Him wherever He may go,
And near Him, I always will be
For nothing can keep me away,
He is my destiny.

I will follow Him,
Ever since He touched my heart I knew,
There isn’t an ocean too deep,
A mountain so high it can keep,
Keep me away, away from His love.

I love Him, I love Him, I love Him,
And where He goes,
I’ll follow, I’ll follow, I’ll follow.
he’ll always be my true love, my true love, my true love
from now until forever, forever, forever

I will follow Him,
Follow Him wherever He may go,
There isn’t an ocean too deep,
A mountain so high it can keep,
Keep me away, away from His love…

We will follow Him,
Follow Him wherever He may go,
There isn’t an ocean too deep,
A mountain so high it can keep,
Keep us away, away from His love…

I love Him
(Oh yes I love Him)
I’ll follow
(I’m gonna follow)
True love
(He’ll always be my true, true love)
Forever
(Now until forever)
I love Him, I love Him, I love Him,
And where He goes,
I’ll follow, I’ll follow, I’ll follow,
He’ll always be my true love,
My true love, my true love,
From now until forever,
Forever, forever…

There isn’t an ocean too deep,
A mountain so high it can keep,
Keep me away, away from His love

C# – How to read MP3 header?

Today i am trying to write a small application to merge some mp3 files into one. Owing to the fact that I am listening to some audio books. You know a book is always categorized into many chapters and is very long. Therefore the audio version is splitted into many parts too. I don’t like that because i can easily lose one of them and when I hear them I must sort them into exact order. Because of the above points I would like to write a small tool to merge all files into one.

As I start my project I know it must be pretty complex because Mp3 format was invented long time ago and it has different versions since its first publishcation. So I made a search to MP3 file format specification and I found that it is badly documented and the website is not professionally designed. I thought I went into wrong link but after more searching I think that is may be the best one (???).  I started to read the documentation and found this interesting paragraph

An MPEG audio file is built up from smaller parts called frames. Generally, frames are independent items. Each frame has its own header and audio informations. As there is no file header, you can cut any part of MPEG file and play it correctly

Ah ha, I thought I can simply join two mp3 files and they will work like a charm.


FileStream fs0001 = File.Open("D:\\Downloads\\0001.mp3", FileMode.Append);
FileStream fs0002 = File.Open("D:\\Downloads\\0002.mp3", FileMode.Open);
byte[] baOut = new byte[fs0002.Length];
fs0002.Read(baOut, 0, (int)baOut.Length);
fs0001.Write(baOut, 0, (int)baOut.Length);
fs0001.Close();
fs0002.Close();

After running the code above, the output file can be played with WMP11. I thought I was successfull. But you know, life is not easy as we hope. Although WMP11 can play the whole output file but the information of file was wrong. For example I merged a 3-minutes length mp3 files with a 2-minutes length one but the duration of output was only 3-minutes.  That means it takes the duration of first file for the new one and it is of course wrong. So I manage to rewrite the duration of output file .I make another search for a library working with ID3 Tag. Writing an own one must be a big work. There are a lot of kinds of this library, I chose to use TagLib Sharp because I think this library will be continuously developed in future. Below is a small code snippet for reading ID3 Tag from a mp3 file.


TagLib.File fiMp3 = TagLib.File.Create("D:\\Downloads\\0001.mp3");
Console.WriteLine(fiMp3.Tag.Performers[0].ToString());
Console.WriteLine(fiMp3.Properties.Duration);

However until now I can still NOT to edit the duration of the output file. I am reading the mp3 documentation forward and hope that I can find a way.

UPDATE 17.03.2012
If you want to read or write the picture of album cover of the mp3 files you can use listing below

private static void Main(string[] args)
{
	TagLib.File file = TagLib.File.Create("UMTD.mp3");
	Console.WriteLine("Current picture count: " + file.Tag.Pictures.Length);

	file.Tag.Pictures = new Picture[] { new Picture("Pic.png") };
	file.Save();

	Console.WriteLine("New picture count: " + file.Tag.Pictures.Length);
	Console.ReadLine();
}

Source : http://hintdesk.com/Web/Source/How%20to%20read%20MP3%20header.zip

C# – How to enable SeDebugPrivilege?

I’m writing a small application to recognize which processes are using a define file. The reason to start this project is sometimes I can not delete some folder because it was accessed by any program. I can not figure out which program are accessing that folder. It makes me really annoyed so it is good if I can find out which application are trying to access my folder and terminate it or close its access.To achieve this idea I must enable SeDebugPrivilege for my tool.

By setting the SeDebugPrivilege privilege on the running process, you can obtain the process handle of any running application. When obtaining the handle to a process, you can then specify the PROCESS_ALL_ACCESS flag, which will allow the calling of various Win32 APIs upon that process handle, which you normally could not do.

It is pretty easy to enable SeDebugPrivilege with help of Pinvoke.net. However I would like to share it for anyone who needs it.


IntPtr hToken;
LUID luidSEDebugNameValue;
TOKEN_PRIVILEGES tkpPrivileges;

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken))
{
Console.WriteLine("OpenProcessToken() failed, error = {0} . SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
return;
}
else
{
Console.WriteLine("OpenProcessToken() successfully");
}

if (!LookupPrivilegeValue(null, SE_DEBUG_NAME, out luidSEDebugNameValue))
{
Console.WriteLine("LookupPrivilegeValue() failed, error = {0} .SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
CloseHandle(hToken);
return;
}
else
{
Console.WriteLine("LookupPrivilegeValue() successfully");
}

tkpPrivileges.PrivilegeCount = 1;
tkpPrivileges.Luid = luidSEDebugNameValue;
tkpPrivileges.Attributes = SE_PRIVILEGE_ENABLED;

if (!AdjustTokenPrivileges(hToken,false,ref tkpPrivileges, 0,IntPtr.Zero,IntPtr.Zero))
{
Console.WriteLine("LookupPrivilegeValue() failed, error = {0} .SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
}
else
{
Console.WriteLine("SeDebugPrivilege is now available");
}
CloseHandle(hToken);
Console.ReadLine();

As you can see, there are 3 steps to enable SeDebugPrivilege. First we need to get the token of current process, then we use this token handle to query its debug name and at last we adjust it with the new one. For a complete working source code you cand find at this c# file How to enable SeDebugPrivilege source code.