| Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members |
The irrKlang library is intended to be an easy-to-use 3d and 2d sound engine, so this documentation is an important part of it. If you have any questions or suggestions, please take a look into the ambiera.com forum or just send a mail.
#include <irrKlang.h> // ... // start up the engine irrklang::ISoundEngine* engine = irrklang::createIrrKlangDevice(); // ... // after finished, // close the engine again, similar as calling 'delete' engine->drop();
The createIrrKlangDevice() function also accepts several parameters, so that you can specify which sound driver should be used, if plugins should be used, if irrKlang should run in multithreaded mode, and similar.
engine->play2D("someSoundFile.wav");
This works with all supported file types. You can replace "someSoundFile.wav" with "someSoundFile.mp3", or "someSoundFile.ogg", for example.
To play a sound looped, set the second parameter to 'true':
engine->play2D("myMusic.mp3", true);
To stop this looping sound again, use engine->stopAllSounds() to stop all sounds, or irrklang::ISound::stop() if you only want to stop that single sound. Influencing Sounds during Playback shows how to get to that ISound interface.
irrklang::ISound* snd = engine->play2D("myMusic.mp3", true, false, true); // ... if (snd) snd->setVolume(someNewValue); // ... if (snd) { snd->drop(); // don't forget to release the pointer once it is no longer needed by you snd = 0; }
The irrklang::ISound interface can also be used to test if the sound has been finished, set event receivers, pause and unpause sounds and similar.
irrklang::ISoundSource* shootSound = engine->addSoundSourceFromFile("shoot.wav"); engine->play2D(shootSound); // note: you don't need to drop() the shootSound if you don't use it anymore
The advantage of using irrklang::ISoundSource is that it is possible to set default values for this source, such as volume or distances if it should be used as 3D sound:
irrklang::ISoundSource* shootSound = engine->addSoundSourceFromFile("shoot.wav"); shootSound->setDefaultVolume(0.5f); // shootSound will now be played with half its sound volume by default: engine->play2D(shootSound);
It is also possible to have multiple settings for the same sound file:
irrklang::ISoundSource* shootSound = engine->addSoundSourceFromFile("shoot.wav"); irrklang::ISoundSource* shootSound2 = engine->addSoundSourceAlias(shootSound, "silentShoot"); shootSound2->setDefaultVolume(0.1f); // shootSound will now be played with 100% of its sound volume by default, // shootSound2 will now be played 10% of its sound volume by default. It is // also possible to play it using engine->play("silentShoot"), now.
Using addSoundSourceFromMemory(), it is also possible to play sounds back directly from memory, without files. Of course, it is not necessary to use sound sources. Using irrklang::ISound, it is possible to change the settings of all sounds, too. But using sound sources, it is not necessary to do this every time a sound is played.
irrklang::vec3df position(23,70,90); engine->play3D("yourSound.wav", position);
But to make it sound realistic, you need to set a minimal sound distance: If your sound is caused by a bee, it will usually have a smaller sound radius than for example a jet engine. You can set default values using sound sources (see Using Sound Sources) or set these values after you have started the sound paused:
irrklang::vec3df position(23,70,90); // start the sound paused: irrklang::ISound* snd = engine->play3D("yourSound.wav", position, false, true); if (snd) { snd->setMinDistance(30.0f); // a loud sound snd->setIsPaused(false); // unpause the sound }
There is also the possibility to change the maxDistance, but it is only necessary to change this in very rare cicumstances. If the sound moves, it is also a good idea to update its position from time to time:
if (snd) snd->setPosition(newPosition);
And don't forget to drop() the sound after you don't need it anymore. If you do, it's nothing severe because irrKlang will still clean up the sounds resources after it has finished, but you still would waste some few bytes of memory:
if (snd) { snd->drop(); snd = 0; }
To update the position of yourself, the listener of the 3D sounds, use this from time to time:
irrklang::vec3df position(0,0,0); // position of the listener irrklang::vec3df lookDirection(10,0,10); // the direction the listener looks into irrklang::vec3df velPerSecond(0,0,0); // only relevant for doppler effects irrklang::vec3df upVector(0,1,0); // where 'up' is in your 3D scene engine->setListenerPosition(position, lookDirection, velPerSecond, upVector);
engine->removeAllSoundSources();
This will remove all sounds and also cause all sounds to be stopped. To remove single sounds from the engine, use:
engine->removeSoundSource(pointerToSomeSoundSource); // or: engine->removeSoundSource("nameOfASoundFile.wav");
Note: Only removing buffered sounds will reduce the amount of memory used by irrKlang, streamed sounds don't occupy a lot of memory when they are not played.
irrklang::ISound* snd = engine->play2D("speech.mp3", false, false, true); if (snd) snd->setSoundStopEventReceiver(yourEventReceiver, 0);
The optional second parameter of setSoundStopEventReceiver is a user pointer, set it to whatever you like. 'yourEventReceiver' must be an implementation of the irrklang::ISoundStopEventReceiver interface.
A whole implementation could look like this:
class MySoundEndReceiver : public irrklang::ISoundStopEventReceiver { public: virtual void OnSoundStopped (irrklang::ISound* sound, irrklang::E_STOP_EVENT_CAUSE reason, void* userData) { // called when the sound has ended playing printf("sound has ended"); } } // ... MySoundEndReceiver* myReceiver = new MySoundEndReceiver(); irrklang::ISound* snd = engine->play2D("speech.mp3", false, false, true); if (snd) snd->setSoundStopEventReceiver(myReceiver); myReceiver->drop(); // similar to delete
The irrklang::ISoundStopEventReceiver::OnSoundStopped() method is guaranteed to be called when a sound or sound stream has stopped, either because the sound reached its playback end, its sound source was removed, ISoundEngine::stopAllSounds() has been called or the whole engine was deleted.
engine->addSoundSourceFromMemory(pointerToMemory, memorySize, "nameforthesound.wav"); // play sound now engine->play2D("nameforthesound.wav");
Or using a sound source pointer:
irrklang::ISoundSource* snd = engine->addSoundSourceFromMemory(pointerToMemory, memorySize, "nameforthesound.wav"); // play sound now engine->play2D(snd);
Note: It is also possible to overwrite the file access directly, don't use this Memory Playback feature for this. See Overriding File Access for details.
Using the irrklang::ISound interface, you can optain the irrklang::ISoundEffectControl interface if the sound device supports sound effects and the last parameter ('enableSoundEffects') was set to true when calling play2D():
irrklang::ISound* snd = engine->play2D("sound.wav", true, false, true, ESM_AUTO_DETECT, true); if (snd) { irrklang::ISoundEffectControl* fx = snd->getSoundEffectControl(); if (fx) { // enable the echo sound effect for this sound fx->enableEchoSoundEffect(); } } snd->drop();
This enabled the echo sound effect for this sound. The method also supports a lot of parameters, and can be called multiple times to change those parameters over time if wished. There are a lot of other sound effects, see irrklang::ISoundEffectControl for details.
The only thing to do for this is to implement your own irrklang::IFileFactory, and set it in irrKlang using irrklang::ISoundEngine::addFileFactory():
// a class implementing the IFileFactory interface to override irrklang file access class CMyFileFactory : public irrklang::IFileFactory { public: // Opens a file for read access. Simply return 0 if file not found. virtual irrklang::IFileReader* createFileReader(const ik_c8* filename) { // return your own irrklang::IFileReader implementation here, for example like that: return new CMyReadFile(filename); } }; // ... CMyFileFactory* myFactory = new CMyFileFactory(); engine->addFileFactory(myFactory); myFactory->drop();
For a full example implementation, just take a look into the SDK in examples/04.OverrideFileAccess.
class NewAudioStreamLoader : public irrklang::IAudioStreamLoader { // ... returns NewAudioDecoder and the used file name suffices. }; class NewAudioDecoder : public irrklang::IAudioStream { public: // ... decodes the new file format }; // ... NewAudioDecoder* loader = new NewAudioDecoder(); engine->registerAudioStreamLoader(loader); loader->drop();
There is an example audio decoder and loader with full source in plugins/ikpMP3, which adds MP3 audio decoding capabilities to irrKlang.
The plugin only needs to contain the following function which will be called by irrKlang:
#ifdef WIN32 // Windows version __declspec(dllexport) void __stdcall irrKlangPluginInit(ISoundEngine* engine, const char* version) #else // Linux and Mac OS version void irrKlangPluginInit(ISoundEngine* engine, const char* version) #endif { // your implementation here }
In there, it is for example possible to extend irrKlang with new audio decoders, see Adding Audio Decoders for details.
There is an example plugin with full source in plugins/ikpMP3, which adds MP3 audio decoding capabilities to irrKlang.
To use irrKlang in this way, just define IRRKLANG_STATIC before including irrklang.h, like this:
#define IRRKLANG_STATIC #include <irrKlang.h>
Of course, IRRKLANG_STATIC can also simply be defined in the project/compiler settings instead of in the source file.
int main(int argc, const char** argv) { // enumerate devices irrklang::ISoundDeviceList* deviceList = createSoundDeviceList(); // ask user for a sound device printf("Devices available:\n\n"); for (int i=0; i<deviceList->getDeviceCount(); ++i) printf("%d: %s\n", i, deviceList->getDeviceDescription(i)); printf("\nselect a device using the number (or press any key to use default):\n\n"); int deviceNumber = getch() - '0'; // create device with the selected driver const char* deviceID = deviceList->getDeviceID(deviceNumber); ISoundEngine* engine = createIrrKlangDevice(irrklang::ESOD_AUTO_DETECT, irrklang::ESEO_DEFAULT_OPTIONS, deviceID); deviceList->drop(); // delete device list // ... use engine now }
In this way, it is also possible to play back sound using two devices at the same time: Simply create two irrKlang devices with each a different deviceID.
Note: createSoundDeviceList() takes a driver type parameter (such as irrklang::ESOD_DIRECT_SOUND8), which you have to set to the same value as the first parameter you want to use with createIrrKlangDevice(), if it is other than irrklang::ESOD_AUTO_DETECT.
int main(int argc, const char** argv) { irrklang::ISoundEngine* engine = irrklang::createIrrKlangDevice(); irrklang::IAudioRecorder* recorder = irrklang::createIrrKlangAudioRecorder(engine); if (!engine || !recorder) { printf("Could not create audio engine or audio recoder\n"); return 1; } printf("\nPress any key to start recording audio...\n"); getch(); // record some audio recorder->startRecordingBufferedAudio(); printf("\nRECORDING. Press any key to stop...\n"); getch(); recorder->stopRecordingAudio(); printf("\nRecording done, recorded %dms of audio.\n", recorder->getAudioFormat().FrameCount * 1000 / recorder->getAudioFormat().SampleRate ); printf("Press any key to play back recorded audio...\n"); getch(); // play the recorded audio recorder->addSoundSourceFromRecordedAudio("myRecordedVoice"); engine->play2D("myRecordedVoice", true); // wait until user presses a key printf("\nPress any key to quit..."); getch(); recorder->drop(); engine->drop(); // delete engine return 0; }
In order to select a specific audio capturing device for recording, it is necessary to enumerate the available devices. Simply replace the first to lines of code of the example above with code like this to list all devices and select one:
// enumerate recording devices and ask user to select one irrklang::ISoundDeviceList* deviceList = irrklang::createAudioRecorderDeviceList(); printf("Devices available:\n\n"); for (int i=0; i<deviceList->getDeviceCount(); ++i) printf("%d: %s\n", i, deviceList->getDeviceDescription(i)); printf("\nselect a device using the number (or press any key to use default):\n\n"); int deviceNumber = getch() - '0'; // create recording device with the selected driver const char* deviceID = deviceList->getDeviceID(deviceNumber); irrklang::ISoundEngine* engine = irrklang::createIrrKlangDevice(); irrklang::IAudioRecorder* recorder = irrklang::createIrrKlangAudioRecorder(engine, irrklang::ESOD_AUTO_DETECT, deviceID);
#include <iostream> #include <irrKlang.h> #pragma comment(lib, "irrKlang.lib") // link with irrKlang.dll int main(int argc, const char** argv) { irrklang::ISoundEngine* engine = irrklang::createIrrKlangDevice(); if (!engine) return 1; // could not start engine engine->play2D("someMusic.mp3", true); // play some mp3 file, looped std::cin.get(); // wait until user presses a key engine->drop(); // delete engine return 0; }
A mp3 file is being played until the user presses enter in this example. As you can see, irrKlang uses namespaces, all of the classes are located in the namespace irrklang. If you don't want to write this in front of every class and function you are using, simply write
using namespace irrklang;
#include <iostream> #include <irrKlang.h> using namespace irrklang; #pragma comment(lib, "irrKlang.lib") // link with irrKlang.dll int main(int argc, const char** argv) { // start the sound engine with default parameters ISoundEngine* engine = createIrrKlangDevice(); if (!engine) return 0; // error starting up the engine // play some sound stream, looped engine->play2D("../../media/helltroopers.ogg", true); std::cout << "\nHello World!\n"; char i = 0; while(i != 'q') { std::cout << "Press any key to play some sound, press 'q' to quit.\n"; // play a single sound engine->play2D("../../media/bell.wav"); std::cin >> i; // wait for user to press some key } engine->drop(); // delete engine return 0; }
| The irrKlang
Engine Documentation © 2003-2007 by Nikolaus Gebhardt. Generated
on Fri Jan 2 15:37:04 2009 by Doxygen
(1.5.4) |