Page 1 of 1

Playing audio files with irrKlang Using Visual C++ Express 2010

#1 eker676  Icon User is offline

  • Software Engineer
  • member icon

Reputation: 378
  • View blog
  • Posts: 1,833
  • Joined: 18-April 09

Posted 09 August 2010 - 05:47 PM

This tutorial will cover how to play audio files with the irrKlang audio library.

Note:
This only describes how to build and compile using Visual C++ Express 2010.
If you are using VS or a variant of VS then you should be fine.

irrKlang currently supports these audio formats:

.wav
.mp3
.ogg
.flac
.mod
.it
.s3d
.xm


The first thing needed is the actual irrKlang library which can be downloaded free (for non-commercial use) from the irrKlang website:
http://www.ambiera.c.../downloads.html


Once you have downloaded the library, unzip it to a place of your choosing.

Next open up Visual Studio and create a new empty Win32 Console Application. If you are unsure how to do that then look here:
Getting Started In Microsoft Visual Studio 2008

I named the project 'irrKlang_test'. The name doesn't matter.

Go to File-Save All and save your project. (Currently the project is temporary and no folders have been created)

Next, open up irrKlang folder that you extracted from before.

Copy the include folder from the library to your current project.

If you are unsure which folder to place include in then look at my folderpath.

Posted Image

Next go into the bin/win32-visualStudio folder and grab
ikpMP3.dll
irrKlang.dll

Posted Image

Move those files to your project as well.

Finally you need to copy the irrKlang.lib library from the irrKlang-1.3.0\lib\Win32-visualStudio folder to your project.


Go back to Visual Studio and add a .cpp file. I called mine "main.cpp" but it doesn't matter.

At this point your project folder should look something like this but without the .mp3 file.

Posted Image

Now open up the newly created cpp file and start coding.


===================================================
================== The Code =========================
===================================================


First we need the proper headers
#include <iostream>
#include <string>
#include <windows.h>
#include "include/irrKlang.h"


The string and windows headers are used for the audio file name and the Sleep() function.

In order to use anything in the irrKlang library you need to use its namespace, irrklang.
To get rid of a lot of typing just use the namespace. (NOTE: LOWERCASE 'K')
using namespace std;
using namespace irrklang;



After all the headers and namespaces have been taken care of we need to reference irrKlang.lib so we can actually use the library.

The easy way to do this is to include this line of code:
#pragma comment(lib, "irrKlang.lib")


Now define the main function and create the Sound Engine
int main()
{
  // Creates the Sound Engine with default parameters
  ISoundEngine* se = createIrrKlangDevice();
  return 0;
}



What if the sound engine wasn't created properly?
Well, use an if statement to check.
if(!se)
{
  cout << "Error: Sound Engine could not be created" << endl;
  return 0;
}


Your code should now look something similar to this:
#include <iostream>
#include <string>
#include <windows.h>
#include "include/irrKlang.h"

using namespace std;
using namespace irrklang;

#pragma comment(lib, "irrKlang.lib")

int main()
{
	// Create the sound engine
	ISoundEngine* se = createIrrKlangDevice();

	// check for errors with creation
	if(!se)
	{
		cout << "Error: Could not create Sound Engine" << endl;
		return 0;
	}

	return 0;
}


If all you wanted to do was play a file then you would call
// Note the '->' syntax, se is a pointer
se->play2D("somefile.wav");
Sleep(1000);


That code would play somefile.wav for 1 second and then the program would exit.

However, the method isn't very good. Who want's to hard code sleep times in for everything?

Nobody does so I've created an easy way of playing the entire file without having to "sleep" for the exact number of milliseconds.

This is where the <string> header comes in.

Create a new string variable and initialize it to a media file name.
(You could get input from the user here but I didn't)

Now, play the sound. Here is where another what-if comes into play. What if the file name is invalid? Well we can check for that too.

// play2D returns 0 if it is successfully playing
if(se->play2D(soundFile.c_str()) != 0)
{
  cout << "Error: Could not play file" << endl;
  return 0;
}



Well now the file is playing but the program will exit in another millisecond.

So lets check and see if the file is still playing
while(se->isCurrentlyPlaying(soundFile.c_str()))
  Sleep(100);


isCurrentlyPlaying() returns true if the file passed in is currently playing and false otherwise.

That's it your done. Who would have thought all it takes to play music is a short 39 lines of code?

If you want to play something other than motor_bikes.mp3 then substitute the file name in or get input from the enduser.

If you have any questions just ask.

The complete code:
#include <iostream>
#include <string>
#include <windows.h>
#include "include/irrKlang.h"

using namespace std;
using namespace irrklang;

#pragma comment(lib, "irrKlang.lib")

int main()
{
	// Create the sound engine
	ISoundEngine* se = createIrrKlangDevice();

	// check for errors with creation
	if(!se)
	{
		cout << "Error: Could not create Sound Engine" << endl;
		return 0;
	}


	string soundFile = "motor_bikes.mp3";

	// Play some sound
	
	if(se->play2D(soundFile.c_str()) != 0)
	{
		cout << "Error: Could not play file" << endl;
		return 0;
	}

	// Keep playing until song/sound has ended
	while(se->isCurrentlyPlaying(soundFile.c_str()))
		Sleep(100);

	se->drop();
	return 0;
}



To download the complete Visual C++ solution click here
Attached File  irrKlang_test.zip (1020.34K)
Number of downloads: 651

Is This A Good Question/Topic? 1
  • +

Replies To: Playing audio files with irrKlang

#2 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1009
  • View blog
  • Posts: 4,209
  • Joined: 14-February 08

Posted 14 August 2010 - 10:33 AM

Nicely written tutorial, IrrKlang would be an ideal candidate to wrap up into a nice reusable class. Have you attempted anything like that?
Was This Post Helpful? 0
  • +
  • -

#3 eker676  Icon User is offline

  • Software Engineer
  • member icon

Reputation: 378
  • View blog
  • Posts: 1,833
  • Joined: 18-April 09

Posted 14 August 2010 - 01:32 PM

I haven't but I thought about it. I'll see if I can't whip one up right now and post it.

You still have to set up irrKlang using the method shown in the tutorial but you can now use/add onto this class. Just copy/paste the AudioPlayer.h and AudioPlayer.cpp into your project and start listening. There is also an example of a console based media player.

To see what functions are available look at AudioPlayer.h. It's much neater and there are a few comments. If you want to extend the functionality, feel free to do so. However, the implementation code is messy because it was just a quick out of the blue writeup.


AudioPlayer.h
#ifndef _AUDIOPLAYER_
#define _AUDIOPLAYER_

#include <iostream>
#include <string>

#include "include/irrKlang.h"
#pragma comment(lib, "irrklang.lib")

using namespace std;
using namespace irrklang;

class AudioPlayer
{
private:
	ISoundEngine* soundEngine;
	ISound* currentSound;
	string fileName;
	int volume;
	int position;

public:
	AudioPlayer();
	AudioPlayer(string soundFile); // Doesn't play sound, only initializes fileName
	~AudioPlayer();

	/* All play functions STOP execution of the program except
	* playSoundThreaded(). Note: It isn't really multi-threaded.
	*/

	void playSound(); // Plays entire sound file
	void playSound(int milliseconds); // Plays for X number of milliseconds
	void playSound(string soundFile); // Play entire specified sound file
	void playSound(string soundFile, int milliseconds);
	void playSoundThreaded(); // Starts playing sound but program continues
	bool isSoundPlaying(); // True = music is playing

	// Pause/Resume, works like any other media player
	void pause();
	void resume();

	// Set/get sound file to be played/playing
	void setFileName(string soundFile);
	string getFileName();

	// Volume controls
	void setVolume(int newVolume);
	void increaseVolume();
	void increaseVolume(int increment);
	void decreaseVolume();
	void decreaseVolume(int increment);
	int getCurrentVolume();
		
};

#endif


AudioPlayer.cpp
#include <iostream>
#include <cstdlib>
#include <string>
#include <windows.h>

#include "include/irrKlang.h"
#include "AudioPlayer.h"

using namespace irrklang;
using namespace std;

/*******************************
CONSTRUCTORS
*******************************/
AudioPlayer::AudioPlayer()
{
	soundEngine = createIrrKlangDevice();
	currentSound = 0;
		
	if(!soundEngine)
	{
		cout << "Error: Could not create sound engine" << endl;
		exit(0);
	}

	fileName = "\0";
	volume = 50;
	position = 0;
	soundEngine->setSoundVolume(1);
}

AudioPlayer::AudioPlayer(string soundFile)
{
	soundEngine = createIrrKlangDevice();
	currentSound = 0;

	if(!soundEngine)
	{
		cout << "Error: Could not create sound engine" << endl;
		exit(0);
	}

	fileName = soundFile;
	volume = 50;
	position = 0;
	soundEngine->setSoundVolume(1);
}

/*****************************
DESTRUCTOR
*****************************/
AudioPlayer::~AudioPlayer()
{
	soundEngine->drop();
	currentSound->drop();
}


/***************************
PLAY FUNCTIONS
***************************/
void AudioPlayer::playSound()
{
	if(fileName == "\0")
	{
		cout << "Error: No sound file selected" << endl;
		return;
	}

	currentSound = soundEngine->play2D(fileName.c_str(),false, false, true);
	
	if(!currentSound)
	{
		cout << "Error: Could not play file" << endl;
		exit(0);
	}

	while(!currentSound->isFinished())
		Sleep(100);

	position = currentSound->getPlayPosition();
}

void AudioPlayer::playSound(int milliseconds)
{
	if(fileName == "\0")
	{
		cout << "Error: No sound file selected" << endl;
		return;
	}

	currentSound = soundEngine->play2D(fileName.c_str(),false, false, true);

	if(!currentSound)
	{
		cout << "Error: Could not play file" << endl;
		exit(0);
	}

	Sleep(milliseconds);

	pause();
}

void AudioPlayer::playSound(string soundFile)
{
	setFileName(soundFile);

	currentSound = soundEngine->play2D(fileName.c_str(),false, false, true);

	if(!currentSound)
	{
		cout << "Error: Could not play file" << endl;
		exit(0);
	}

	
	while(!currentSound->isFinished())
		Sleep(100);

	position = currentSound->getPlayPosition();
}

void AudioPlayer::playSound(string soundFile, int milliseconds)
{
	setFileName(soundFile);

	currentSound = soundEngine->play2D(fileName.c_str(),false, false, true);

	if(!currentSound)
	{
		cout << "Error: Could not play file" << endl;
		exit(0);
	}

	Sleep(milliseconds);
	pause();
}

void AudioPlayer::playSoundThreaded()
{
	currentSound = soundEngine->play2D(fileName.c_str(),false, false, true);
	if(!currentSound)
	{
		cout << "Error: Could not play file" << endl;
		exit(0);
	}
}

bool AudioPlayer::isSoundPlaying()
{
	return !currentSound->isFinished();
}

/************************
PAUSE/RESUME
************************/
void AudioPlayer::pause()
{
	position = currentSound->getPlayPosition();
	soundEngine->setAllSoundsPaused();
}

void AudioPlayer::resume()
{
	currentSound = soundEngine->play2D(fileName.c_str(), false, false, true);
	
	if(position != -1)
		currentSound->setPlayPosition(position);
}


/************************
GET/SET FILENAME
************************/
void AudioPlayer::setFileName(string soundFile)
{
	if(soundFile != "")
		fileName = soundFile;
}

string AudioPlayer::getFileName()
{
	return fileName;
}


/***************************
VOLUME CONTROL
***************************/
void AudioPlayer::setVolume(int newVolume)
{
	if(newVolume < 0 || newVolume > 100)
		volume = 50;
	else
		volume = newVolume;

	currentSound->setVolume(volume/100.0);
}

void AudioPlayer::increaseVolume()
{
	volume += 10;

	if(volume > 100)
		volume = 100;
	currentSound->setVolume(volume/100.0);
}

void AudioPlayer::increaseVolume(int increment)
{	
	volume += increment;

	if(volume > 100)
		volume = 100;
	currentSound->setVolume(volume/100.0);
}

void AudioPlayer::decreaseVolume()
{
	volume -= 10;

	if(volume < 0)
		volume = 0;
	currentSound->setVolume(volume/100.0);
}

void AudioPlayer::decreaseVolume(int increment)
{
	volume -= increment;

	if(volume < 0)
		volume = 0;
	currentSound->setVolume(volume/100.0);
}

int AudioPlayer::getCurrentVolume()
{
	return volume;
}



And then an example using the "threaded" play function:
#include <iostream>
#include <string>
#include <windows.h>
#include "AudioPlayer.h"

using namespace std;

void help();

int main()
{
	AudioPlayer sound;

	string soundfile;
	cout << endl << endl;
	cout << "Enter sound file name: ";
	getline(cin, soundfile);

	sound.setFileName(soundfile);

	sound.playSoundThreaded();

	char selection = '\0';
	cout << endl << endl;	
	cout << "Media Player" << endl;
	
	help();

	while(sound.isSoundPlaying())
	{
		cout << "Option: (\'h\' for help) : ";
		cin >> selection;

		switch(selection)
		{
			case '+':
				sound.increaseVolume();
				break;

			case '-':
				sound.decreaseVolume();
				break;

			case 'g':
				cout << "Current Volume: " << sound.getCurrentVolume() << endl;
				break;

			case 'p':
				cout << "Paused" << endl;
				sound.pause();
				break;

			case 'r':
				sound.resume();
				break;

			case 'q':
				return 0;
				break;

			default:
				help();
		}
	}

	return 0;
}

void help()
{
	cout << "+ Increase Volume" << endl
		<< "- Decrease Volume" << endl
		<< "g Get Current Volume" << endl
		<< "p Pause" << endl
		<< "r Resume" << endl
		<< "q Quit" << endl;
}

This post has been edited by eker676: 14 August 2010 - 04:00 PM

Was This Post Helpful? 1
  • +
  • -

#4 CyberGate  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 03-September 11

Posted 03 September 2011 - 08:51 PM

Thank you :)
Was This Post Helpful? 0
  • +
  • -

#5 CyberGate  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 03-September 11

Posted 03 September 2011 - 09:13 PM

How do I do this with Dev-C++?

I keep getting an error message. ><
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1