by Wojciech Sura

FMOD – great Sound library

A while ago I presented a way to write an mp3 player in 16 lines of code. Let’s try to do the same thing with a different sound library, FMOD. FMOD has an advantage over other sound libraries, because it has the same API for different platforms: Win32, Windows 8, Windows phone 8, Macintosh, iOS, Linux, Android, Blackberry and several gaming platforms, like PS3/4/PSP/Vita, Xbox 360/One, Wii etc.

FMOD comes as a native DLL library – fmodex.dll – which is required for the application to run properly. For convenience, we may add it to the project and set its Copy to Output Directory property to Copy always – Visual Studio will take care for copying that DLL for us.

fmod-1fmod-2

fmodes.dll is native, but fortunately FMOD team provides an almost-complete set of wrappers for C#, so we won’t have to P/Invoke our way to play a sound.

Let’s start with adding a few fields to our class.

[csharp] private FMOD.System system;
private FMOD.Sound sound;
private FMOD.Channel channel;[/csharp]

System is the core of FMOD – it creates sound objects, allows starting playback etc. Sound is a class representing the actual sound, being played. Finally, Channel is a class, which represents the actual playback process and allows modifying its aspects – for instance, the volume.

The System object can be created with aid of FMOD.Factory. We may create and initialize it in form’s constructor, as there’s usually no point in keeping several instances of System.

[csharp]public Form1()
{
InitializeComponent();

FMOD.Factory.System_Create(ref system);
system.init(1, FMOD.INITFLAGS.NORMAL, IntPtr.Zero);
}[/csharp]

Now we can implement the Open & Play button. Fortunately, System.createSound method accepts filename as its first parameter, so the process will be as easy as in case of NAudio.

[csharp]private void bPlay_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog()
{
Filter = "Sound files (*.mp3;*.wav;*.wma)|*.mp3;*.wav;*.wma"
};

if (dialog.ShowDialog() == DialogResult.OK)
{
system.createSound(dialog.FileName, FMOD.MODE.DEFAULT, ref sound);
system.playSound(FMOD.CHANNELINDEX.FREE, sound, false, ref channel);
}
}[/csharp]

Stopping playback is also quite an easy task – it’s only a matter of asking a Channel object to stop.

[csharp]private void bStop_Click(object sender, EventArgs e)
{
if (channel != null)
channel.stop();
}[/csharp]

And that’s all we need to play a sound. Keep in mind, that this example program does not provide any error checking – all FMOD methods return FMOD.Result, which informs about outcome of the operation.

by Wojciech Sura

Scheduled recording internet streams

I’m a big fan of jazz. I can listen to this kind of music for hours.

One of the biggest Polish jazz composers and players, Jan “Ptaszyn” Wróblewski runs a radio show called “three-quarters of jazz” (its played in 3rd program of Polish Radio, hence the name). Unfortunately, it’s aired at 11pm, which is a little bit outside my range of consciousness.

But hey, I have a few GHz at my disposal. Let’s make use of them and ask the computer to record the show for me (fortunately, 3rd program of Polish Radio is streamed through the Internet as well).

My program of choice is VLC Player. This inconspicuous program offers more than you might think. It’s free and you can download it from its homepage.

Let’s now prepare a batch command, which will ask VLC to record the show. It looks like the following:

[shell]cd "C:\Program Files\VideoLAN\VLC"
"C:\Program Files\VideoLAN\VLC\vlc.exe" mms://stream.polskieradio.pl/program3 –run-time=4200 –sout "#transcode{acodec=mp3}:std{access=file,dst=D:\Dokumenty\Muzyka\Trojka.mp3}" vlc://quit[/shell]

Let’s break it into parts.

  • mms://stream.polskieradio.pl/program3 – this is the URL to stream I want to record.
  • –run-time=4200 – time of recording in seconds. I record five preceeding and five following minutes (4200 = 1:10:00)
  • –sout – tells the VideoLan to stream the output. Following string informs about streaming details.
  • #transcode{acodec=mp3} – appends a filter on the output stream, which encodes it to MP3 format.
  • :std{access=file,dst=D:\Dokumenty\Muzyka\Trojka.mp3}” – appends a filter on the stream encoded to mp3, which simply saves it to a file.
  • vlc://quit – this is actually second item in the playlist. When you ask VLC player to play this file, it’ll simply close.

The rest is simply a matter of adding an entry to Windows Scheduler.

You can read more about configuring streaming in the command line in VLC documentation.

Bonus chatter: If you want the computer to shut down after recording the stream, add another (carefully timed) entry to Windows Scheduler and call:

[shell]shutdown /s /t 0[/shell]

by Wojciech Sura

How to write an MP3 player?

Impressing friends when you’re a programmer is actually quite a hard task. We have to accept the fact, that the overwhelming majority of the population associates the word “class” with a chalkboard and mostly probably won’t see the beauty of, for instance, virtual treeview control boosted up by item position cache, which is generated dynamically on request in a separate thread. Sigh.

So let’s try something simpler and easier to show our non-technical friends: we’ll write an mp3 player in just nice round 16 lines of code.

You’ll need NAudio package.

NAudio

Create an empty Windows Forms project and let’s write our 16 lines.  First of all, add two using’s to the code.
[csharp]using NAudio;
using NAudio.Wave;[/csharp]
You’ll have to add the following fields to the form class.
[csharp]private IWavePlayer waveOut;
private AudioFileReader reader;
[/csharp]
Then initialize the waveOut object in form’s constructor.
[csharp]public Form1()
{
InitializeComponent();
waveOut = new WaveOut();
}[/csharp]
Create two buttons on the form. Call first “Open and play” and second “Stop”. Now implement first button’s Click event:
[csharp]private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openDialog = new OpenFileDialog()
{
Filter = "Music files (*.mp3)|*.mp3"
};

if (openDialog.ShowDialog() == DialogResult.OK)
{
reader = new AudioFileReader(openDialog.FileName);
waveOut.Init(reader);
waveOut.Play();
}
}[/csharp]
Finally, implement second button’s Click event:
[csharp]private void button2_Click(object sender, EventArgs e)
{
waveOut.Stop();
}[/csharp]
And that’s all! Compile the application and run. Enjoy!

Tags: , ,