* added irrKlang sound engine, as requested by exosk.

- to enable sound, set UseSound=1 in /conf/gui.conf
- For now, added a test music to the login screen.
* updated VC71/VC90 project files for windows. linux makefiles NOT yet updated!
This commit is contained in:
false_genesis 2008-08-21 15:11:50 +00:00
parent 2808ca7efe
commit 100125a093
50 changed files with 8380 additions and 149 deletions

View File

@ -23,6 +23,11 @@ shadows=1
// color depth; 16 or 32 bit
depth=32
// Use Sound? (experimental)
// 1: Yes
// 0: No (default)
UseSound=1
//================================================================================================
// Expert options: Renderer finetuning

Binary file not shown.

BIN
bin/ikpMP3.dll Normal file

Binary file not shown.

BIN
bin/ikpMP3.so Normal file

Binary file not shown.

BIN
bin/irrKlang.dll Normal file

Binary file not shown.

BIN
bin/libIrrKlang.so Normal file

Binary file not shown.

View File

@ -0,0 +1,42 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#include "CIrrKlangAudioStreamLoaderMP3.h"
#include "CIrrKlangAudioStreamMP3.h"
#include <string.h>
namespace irrklang
{
CIrrKlangAudioStreamLoaderMP3::CIrrKlangAudioStreamLoaderMP3()
{
}
//! Returns true if the file maybe is able to be loaded by this class.
bool CIrrKlangAudioStreamLoaderMP3::isALoadableFileExtension(const ik_c8* fileName)
{
return strstr(fileName, ".mp3") != 0;
}
//! Creates an audio file input stream from a file
IAudioStream* CIrrKlangAudioStreamLoaderMP3::createAudioStream(irrklang::IFileReader* file)
{
CIrrKlangAudioStreamMP3* stream = new CIrrKlangAudioStreamMP3(file);
if (stream && !stream->isOK())
{
stream->drop();
stream = 0;
}
return stream;
}
} // end namespace irrklang

View File

@ -0,0 +1,32 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __C_IRRKLANG_AUDIO_STREAM_LOADER_MP3_H_INCLUDED__
#define __C_IRRKLANG_AUDIO_STREAM_LOADER_MP3_H_INCLUDED__
#include "irrklang/ik_IAudioStreamLoader.h"
namespace irrklang
{
//! Class which is able to create an audio file stream from a file.
class CIrrKlangAudioStreamLoaderMP3 : public IAudioStreamLoader
{
public:
CIrrKlangAudioStreamLoaderMP3();
//! Returns true if the file maybe is able to be loaded by this class.
/** This decision should be based only on the file extension (e.g. ".wav") */
virtual bool isALoadableFileExtension(const ik_c8* fileName);
//! Creates an audio file input stream from a file
/** \return Pointer to the created audio stream. Returns 0 if loading failed.
If you no longer need the stream, you should call IAudioFileStream::drop().
See IRefCounted::drop() for more information. */
virtual IAudioStream* createAudioStream(irrklang::IFileReader* file);
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,397 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// Part of the code for this plugin for irrKlang is based on:
// MP3 input for Audiere by Matt Campbell <mattcampbell@pobox.com>, based on
// libavcodec from ffmpeg (http://ffmpeg.sourceforge.net/).
// See license.txt for license details of this plugin.
#include "CIrrKlangAudioStreamMP3.h"
#include <memory.h>
#include <stdlib.h> // free, malloc and realloc
#include <string.h>
namespace irrklang
{
CIrrKlangAudioStreamMP3::CIrrKlangAudioStreamMP3(IFileReader* file)
: File(file), TheMPAuDecContext(0), InputPosition(0), InputLength(0),
DecodeBuffer(0), FirstFrameRead(false), EndOfFileReached(0),
FileBegin(0), Position(0)
{
if (File)
{
File->grab();
TheMPAuDecContext = new MPAuDecContext();
if (!TheMPAuDecContext || mpaudec_init(TheMPAuDecContext) < 0)
{
File->drop();
File = 0;
delete TheMPAuDecContext;
TheMPAuDecContext = 0;
return;
}
// init, get format
DecodeBuffer = new ik_u8[MPAUDEC_MAX_AUDIO_FRAME_SIZE];
if (File->getSize()>0)
{
// seekable file, now parse file to get size
// (needed to make it possible for the engine to loop a stream correctly)
skipID3IfNecessary();
TheMPAuDecContext->parse_only = 1;
Format.FrameCount = 0;
while(!EndOfFileReached)
{
if (!decodeFrame())
break;
Format.FrameCount += TheMPAuDecContext->frame_size;
if (!EndOfFileReached /*&& File->isSeekable()*/ )
{
// to be able to seek in the stream, store offsets and sizes
SFramePositionData data;
data.size = TheMPAuDecContext->frame_size;
data.offset = File->getPos() - (InputLength - InputPosition) - TheMPAuDecContext->coded_frame_size;
FramePositionData.push_back(data);
}
}
TheMPAuDecContext->parse_only = 0;
setPosition(0);
}
else
decodeFrame(); // decode first frame to read audio format
if (!TheMPAuDecContext->channels ||
!TheMPAuDecContext->sample_rate )
{
File->drop();
File = 0;
delete TheMPAuDecContext;
TheMPAuDecContext = 0;
return;
}
}
}
CIrrKlangAudioStreamMP3::~CIrrKlangAudioStreamMP3()
{
if (File)
File->drop();
if (TheMPAuDecContext)
{
mpaudec_clear(TheMPAuDecContext);
delete TheMPAuDecContext;
}
delete [] DecodeBuffer;
}
//! returns format of the audio stream
SAudioStreamFormat CIrrKlangAudioStreamMP3::getFormat()
{
return Format;
}
//! tells the audio stream to read n audio frames into the specified buffer
ik_s32 CIrrKlangAudioStreamMP3::readFrames(void* target, ik_s32 frameCountToRead)
{
const int frameSize = Format.getFrameSize();
int framesRead = 0;
ik_u8* out = (ik_u8*)target;
while (framesRead < frameCountToRead)
{
// no more samples? ask the MP3 for more
if (DecodedQueue.getSize() < frameSize)
{
if (!decodeFrame() || EndOfFileReached)
return framesRead;
// if the buffer is still empty, we are done
if (DecodedQueue.getSize() < frameSize)
return framesRead;
}
const int framesLeft = frameCountToRead - framesRead;
const int dequeSize = DecodedQueue.getSize() / frameSize;
const int framesToRead = framesLeft < dequeSize ? framesLeft : dequeSize;
DecodedQueue.read(out, framesToRead * frameSize);
out += framesToRead * frameSize;
framesRead += framesToRead;
Position += framesToRead;
}
return framesRead;
}
bool CIrrKlangAudioStreamMP3::decodeFrame()
{
int outputSize = 0;
while (!outputSize)
{
if (InputPosition == InputLength)
{
InputPosition = 0;
InputLength = File->read(InputBuffer, IKP_MP3_INPUT_BUFFER_SIZE);
if (InputLength == 0)
{
EndOfFileReached = true;
return true;
}
}
int rv = mpaudec_decode_frame( TheMPAuDecContext, (ik_s16*)DecodeBuffer,
&outputSize,
(ik_u8*)InputBuffer + InputPosition,
InputLength - InputPosition);
if (rv < 0)
return false;
InputPosition += rv;
} // end while
if (!FirstFrameRead)
{
Format.ChannelCount = TheMPAuDecContext->channels;
Format.SampleRate = TheMPAuDecContext->sample_rate;
Format.SampleFormat = ESF_S16;
Format.FrameCount = -1; // unknown lenght
FirstFrameRead = true;
}
else
if (TheMPAuDecContext->channels != Format.ChannelCount ||
TheMPAuDecContext->sample_rate != Format.SampleRate)
{
// Can't handle format changes mid-stream.
return false;
}
if (!TheMPAuDecContext->parse_only)
{
if (outputSize < 0)
{
// Couldn't decode this frame. Too bad, already lost it.
// This should only happen when seeking.
outputSize = TheMPAuDecContext->frame_size;
memset(DecodeBuffer, 0, outputSize * Format.getFrameSize());
}
DecodedQueue.write(DecodeBuffer, outputSize);
}
return true;
}
//! sets the position of the audio stream.
/** For example to let the stream be read from the beginning of the file again,
setPosition(0) would be called. This is usually done be the sound engine to
loop a stream after if has reached the end. Return true if sucessful and 0 if not. */
bool CIrrKlangAudioStreamMP3::setPosition(ik_s32 pos)
{
if (!File || !TheMPAuDecContext)
return false;
if (pos == 0)
{
// usually done for looping, just reset to start
File->seek(FileBegin); // skip possible ID3 header
EndOfFileReached = false;
DecodedQueue.clear();
MPAuDecContext oldContext = *TheMPAuDecContext;
mpaudec_clear(TheMPAuDecContext);
mpaudec_init(TheMPAuDecContext);
TheMPAuDecContext->bit_rate = oldContext.bit_rate;
TheMPAuDecContext->channels = oldContext.channels;
TheMPAuDecContext->frame_size = oldContext.frame_size;
TheMPAuDecContext->sample_rate = oldContext.sample_rate;
InputPosition = 0;
InputLength = 0;
Position = 0;
CurrentFramePosition = 0;
return true;
}
else
{
// user wants to seek in the stream, so do this here
int scan_position = 0;
int target_frame = 0;
int frame_count = (int)FramePositionData.size();
while (target_frame < frame_count)
{
int frame_size = FramePositionData[target_frame].size;
if (pos <= scan_position + frame_size)
break;
else
{
scan_position += frame_size;
target_frame++;
}
}
const int MAX_FRAME_DEPENDENCY = 10;
target_frame = std::max(0, target_frame - MAX_FRAME_DEPENDENCY);
setPosition(0);
File->seek(FramePositionData[target_frame].offset, false);
int i;
for (i = 0; i < target_frame; i++)
{
if (i>=(int)FramePositionData.size())
{
// internal error
setPosition(0);
return false;
}
Position += FramePositionData[i].size;
}
if (!decodeFrame() || EndOfFileReached)
{
setPosition(0);
return false;
}
int frames_to_consume = pos - Position; // PCM frames now
if (frames_to_consume > 0)
{
ik_u8 *buf = new ik_u8[frames_to_consume * Format.getFrameSize()];
readFrames(buf, frames_to_consume);
delete[] buf;
}
return true;
}
return false;
}
CIrrKlangAudioStreamMP3::QueueBuffer::QueueBuffer()
{
Capacity = 256;
Size = 0;
Buffer = (ik_u8*)malloc(Capacity);
}
CIrrKlangAudioStreamMP3::QueueBuffer::~QueueBuffer()
{
free(Buffer);
}
int CIrrKlangAudioStreamMP3::QueueBuffer::getSize()
{
return Size;
}
void CIrrKlangAudioStreamMP3::QueueBuffer::write(const void* buffer, int size)
{
bool needRealloc = false;
while (size + Size > Capacity)
{
Capacity *= 2;
needRealloc = true;
}
if (needRealloc)
{
Buffer = (ik_u8*)realloc(Buffer, Capacity);
}
memcpy(Buffer + Size, buffer, size);
Size += size;
}
int CIrrKlangAudioStreamMP3::QueueBuffer::read(void* buffer, int size)
{
int toRead = size < Size ? size : Size;
memcpy(buffer, Buffer, toRead);
memmove(Buffer, Buffer + toRead, Size - toRead);
Size -= toRead;
return toRead;
}
void CIrrKlangAudioStreamMP3::QueueBuffer::clear()
{
Size = 0;
}
void CIrrKlangAudioStreamMP3::skipID3IfNecessary()
{
char header[10];
int read = File->read(&header, 10);
if (read == 10 &&
header[0] == 'I' && header[1] == 'D' && header[2] == '3')
{
int versionMajor = header[3];
int versionMinor = header[4];
int flags = header[5];
// IDv2 size looks like the following: ID3v2 size 4 * %0xxxxxxx.
// Sick, but that's how it works.
int size = 0;
size = (header[6] & 0x7f) << (3*7);
size |= (header[7] & 0x7f) << (2*7);
size |= (header[8] & 0x7f) << (1*7);
size |= (header[9] & 0x7f) ;
size += 10; // header size
FileBegin = size;
File->seek(FileBegin);
}
else
File->seek(0);
}
} // end namespace irrklang

View File

@ -0,0 +1,106 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// Part of the code for this plugin for irrKlang is based on:
// MP3 input for Audiere by Matt Campbell <mattcampbell@pobox.com>, based on
// libavcodec from ffmpeg (http://ffmpeg.sourceforge.net/).
// See license.txt for license details of this plugin.
#ifndef __C_IRRKLANG_AUDIO_STREAM_MP3_H_INCLUDED__
#define __C_IRRKLANG_AUDIO_STREAM_MP3_H_INCLUDED__
#include "irrklang/ik_IAudioStream.h"
#include "irrklang/ik_IFileReader.h"
#include <vector>
#include "decoder/mpaudec.h"
namespace irrklang
{
const int IKP_MP3_INPUT_BUFFER_SIZE = 4096;
//! Reads and decodes audio data into an usable audio stream for the ISoundEngine
/** To extend irrKlang with new audio format decoders, the only thing needed to do
is implementing the IAudioStream interface. All the code available in this class is only for
mp3 decoding and may make this class look a bit more complicated then it actually is. */
class CIrrKlangAudioStreamMP3 : public IAudioStream
{
public:
CIrrKlangAudioStreamMP3(IFileReader* file);
~CIrrKlangAudioStreamMP3();
//! returns format of the audio stream
virtual SAudioStreamFormat getFormat();
//! tells the audio stream to read n audio frames into the specified buffer
/** \param target: Target data buffer to the method will write the read frames into. The
specified buffer will be getFormat().getFrameSize()*frameCount big.
\param frameCount: amount of frames to be read.
\returns Returns amount of frames really read. Should be frameCountToRead in most cases. */
virtual ik_s32 readFrames(void* target, ik_s32 frameCountToRead);
//! sets the position of the audio stream.
/** For example to let the stream be read from the beginning of the file again,
setPosition(0) would be called. This is usually done be the sound engine to
loop a stream after if has reached the end. Return true if sucessful and 0 if not. */
virtual bool setPosition(ik_s32 pos);
// just for the CIrrKlangAudioStreamLoaderMP3 to let him know if loading worked
bool isOK() { return File != 0; }
protected:
ik_s32 readFrameForMP3(void* target, ik_s32 frameCountToRead, bool parseOnly=false);
bool decodeFrame();
void skipID3IfNecessary();
irrklang::IFileReader* File;
SAudioStreamFormat Format;
// mpaudec specific
MPAuDecContext* TheMPAuDecContext;
ik_u8 InputBuffer[IKP_MP3_INPUT_BUFFER_SIZE];
int InputPosition;
int InputLength;
int Position;
ik_u8* DecodeBuffer;
ik_s32 FileBegin;
ik_u32 CurrentFramePosition;
bool FirstFrameRead;
bool EndOfFileReached;
// helper class for managing the streaming decoded audio data
class QueueBuffer
{
public:
QueueBuffer();
~QueueBuffer();
int getSize();
void write(const void* buffer, int size);
int read(void* buffer, int size);
void clear();
private:
ik_u8* Buffer;
int Capacity;
int Size;
};
struct SFramePositionData
{
int offset;
int size;
};
std::vector<SFramePositionData> FramePositionData;
QueueBuffer DecodedQueue;
};
} // end namespace irrklang
#endif

View File

@ -45,7 +45,9 @@ PseuGUI::PseuGUI()
_guienv = NULL;
_scene = NULL;
_passtime = _lastpasstime = _passtimediff = 0;
}
_soundengine = NULL;
_usesound = false;
}
PseuGUI::~PseuGUI()
{
@ -131,6 +133,16 @@ void PseuGUI::_Init(void)
_smgr->addExternalMeshLoader(m2loader);
_throttle=0;
_initialized = true;
// initialize the sound engine
if(_usesound)
{
_soundengine = createIrrKlangDevice();
if(_soundengine)
logdetail("PseuGUI: Sound Driver: %s",_soundengine->getDriverName());
else
logerror("PseuGUI: Failed to initialize sound engine!");
}
}
void PseuGUI::Cancel(void)
@ -147,7 +159,11 @@ void PseuGUI::Cancel(void)
{
_device->drop();
_device = NULL;
}
if(_soundengine)
{
_soundengine->drop();
_soundengine = NULL;
}
_mustdie = true;
}

View File

@ -2,6 +2,7 @@
#define PSEUGUI_H
#include "irrlicht/irrlicht.h"
#include "irrklang/irrKlang.h"
#include "SceneData.h"
#include "DrawObjMgr.h"
#include "World.h"
@ -89,6 +90,7 @@ public:
void Cancel(void);
void Shutdown(void);
inline bool IsInitialized(void) { return _initialized && _device; }
inline void SetUseSound(bool b) { _usesound = b; }
inline bool MustDie(void) { return _mustdie; }
@ -112,11 +114,13 @@ private:
uint16 _xres,_yres,_colordepth;
bool _windowed,_vsync,_shadows;
bool _initialized,_mustdie;
bool _usesound;
irr::IrrlichtDevice *_device;
irr::video::IVideoDriver* _driver;
irr::scene::ISceneManager* _smgr;
irr::gui::IGUIEnvironment* _guienv;
irr::video::E_DRIVER_TYPE _driverType;
irrklang::ISoundEngine *_soundengine;
DrawObjMgr domgr;
PseuInstance *_instance;
SceneState _scenestate, _scenestate_new;

View File

@ -18,6 +18,8 @@ Scene::Scene(PseuGUI *g)
cursor->setOSCursorVisible(true);
cursor->setVisible(false);
cursor->render(); // apply above settings
soundengine = gui->_soundengine;
}
void Scene::OnDraw(void)

View File

@ -1,136 +1,138 @@
#ifndef _SCENE_H
#define _SCENE_H
#include "irrlicht/irrlicht.h"
#include "SceneData.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
class PseuGUI;
class CCursorController;
// base class
class Scene
{
friend class PseuGUI;
public:
Scene(PseuGUI *g);
~Scene();
core::stringw GetStringFromDB(u32 index, u32 entry);
inline void SetState(SceneState sc) { _scenestate = sc; }
inline SceneState GetState(void) { return _scenestate; }
virtual void OnUpdate(s32);
virtual void OnDraw(void);
virtual void OnDrawBegin(void);
virtual void OnDelete(void);
virtual video::SColor GetBackgroundColor(void);
virtual void SetData(uint32 index, uint32 value) { scenedata[index] = value; }
protected:
PseuInstance *instance;
PseuGUI *gui;
irr::IrrlichtDevice *device;
irr::video::IVideoDriver* driver;
irr::scene::ISceneManager* smgr;
irr::gui::IGUIEnvironment* guienv;
CCursorController *cursor;
SceneState _scenestate;
uint32 scenedata[SCENEDATA_SIZE]; // generic storage for anything the PseuInstance thread wants to tell us
SCPDatabase *textdb;
};
class SceneGuiStart : public Scene
{
public:
SceneGuiStart(PseuGUI *gui);
void OnDelete(void);
private:
IGUIImage *irrlogo, *driverlogo;
};
class GUIEventReceiver;
class SceneLogin : public Scene
{
public:
SceneLogin(PseuGUI *gui);
void OnUpdate(s32);
void OnDelete(void);
private:
gui::IGUIElement* root;
IGUIImage *irrlogo, *background;
GUIEventReceiver *eventrecv;
PseuGUI* _gui;
gui::IGUIElement *msgbox;
uint32 msgbox_textid;
};
class ShTlTerrainSceneNode;
class MCameraFPS;
class MCameraOrbit;
class MyEventReceiver;
class MapMgr;
class WorldSession;
class MovementMgr;
class MyCharacter;
class SceneWorld : public Scene
{
struct SceneNodeWithGridPos
{
scene::ISceneNode *scenenode;
uint32 gx,gy;
};
public:
SceneWorld(PseuGUI *gui);
void OnDraw(void);
void OnDrawBegin(void);
void OnDelete(void);
void OnUpdate(s32);
void UpdateTerrain(void);
void InitTerrain(void);
void RelocateCamera(void);
void RelocateCameraBehindChar(void);
void UpdateDoodads(void);
scene::ISceneNode *GetMyCharacterSceneNode(void);
video::SColor GetBackgroundColor(void);
WorldPosition GetWorldPosition(void);
private:
ShTlTerrainSceneNode *terrain;
MCameraFPS *camera;
MyEventReceiver *eventrecv;
ZThread::FastMutex mutex;
PseuGUI *gui;
uint32 map_gridX, map_gridY;
WorldSession *wsession;
World *world;
MapMgr *mapmgr;
IGUIStaticText *debugText;
bool debugmode;
std::map<uint32,SceneNodeWithGridPos> _doodads;
scene::ISceneNode *sky;
scene::ISceneNode *selectedNode, *oldSelectedNode, *focusedNode, *oldFocusedNode;
video::SColor envBasicColor;
MovementMgr *movemgr;
MyCharacter *mychar;
bool _freeCameraMove;
void _CalcXYMoveVect(float o);
core::vector2df xyCharMovement; // stores sin() and cos() values for current MyCharacter orientation, so that they need to be calculated only if the character turns around
bool mouse_pressed_left;
bool mouse_pressed_right;
float old_char_o;
};
#endif
#ifndef _SCENE_H
#define _SCENE_H
#include "irrlicht/irrlicht.h"
#include "SceneData.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
using namespace irrklang;
class PseuGUI;
class CCursorController;
// base class
class Scene
{
friend class PseuGUI;
public:
Scene(PseuGUI *g);
~Scene();
core::stringw GetStringFromDB(u32 index, u32 entry);
inline void SetState(SceneState sc) { _scenestate = sc; }
inline SceneState GetState(void) { return _scenestate; }
virtual void OnUpdate(s32);
virtual void OnDraw(void);
virtual void OnDrawBegin(void);
virtual void OnDelete(void);
virtual video::SColor GetBackgroundColor(void);
virtual void SetData(uint32 index, uint32 value) { scenedata[index] = value; }
protected:
PseuInstance *instance;
PseuGUI *gui;
irr::IrrlichtDevice *device;
irr::video::IVideoDriver* driver;
irr::scene::ISceneManager* smgr;
irr::gui::IGUIEnvironment* guienv;
irrklang::ISoundEngine *soundengine;
CCursorController *cursor;
SceneState _scenestate;
uint32 scenedata[SCENEDATA_SIZE]; // generic storage for anything the PseuInstance thread wants to tell us
SCPDatabase *textdb;
};
class SceneGuiStart : public Scene
{
public:
SceneGuiStart(PseuGUI *gui);
void OnDelete(void);
private:
IGUIImage *irrlogo, *driverlogo;
};
class GUIEventReceiver;
class SceneLogin : public Scene
{
public:
SceneLogin(PseuGUI *gui);
void OnUpdate(s32);
void OnDelete(void);
private:
gui::IGUIElement* root;
IGUIImage *irrlogo, *background;
GUIEventReceiver *eventrecv;
PseuGUI* _gui;
gui::IGUIElement *msgbox;
uint32 msgbox_textid;
};
class ShTlTerrainSceneNode;
class MCameraFPS;
class MCameraOrbit;
class MyEventReceiver;
class MapMgr;
class WorldSession;
class MovementMgr;
class MyCharacter;
class SceneWorld : public Scene
{
struct SceneNodeWithGridPos
{
scene::ISceneNode *scenenode;
uint32 gx,gy;
};
public:
SceneWorld(PseuGUI *gui);
void OnDraw(void);
void OnDrawBegin(void);
void OnDelete(void);
void OnUpdate(s32);
void UpdateTerrain(void);
void InitTerrain(void);
void RelocateCamera(void);
void RelocateCameraBehindChar(void);
void UpdateDoodads(void);
scene::ISceneNode *GetMyCharacterSceneNode(void);
video::SColor GetBackgroundColor(void);
WorldPosition GetWorldPosition(void);
private:
ShTlTerrainSceneNode *terrain;
MCameraFPS *camera;
MyEventReceiver *eventrecv;
ZThread::FastMutex mutex;
PseuGUI *gui;
uint32 map_gridX, map_gridY;
WorldSession *wsession;
World *world;
MapMgr *mapmgr;
IGUIStaticText *debugText;
bool debugmode;
std::map<uint32,SceneNodeWithGridPos> _doodads;
scene::ISceneNode *sky;
scene::ISceneNode *selectedNode, *oldSelectedNode, *focusedNode, *oldFocusedNode;
video::SColor envBasicColor;
MovementMgr *movemgr;
MyCharacter *mychar;
bool _freeCameraMove;
void _CalcXYMoveVect(float o);
core::vector2df xyCharMovement; // stores sin() and cos() values for current MyCharacter orientation, so that they need to be calculated only if the character turns around
bool mouse_pressed_left;
bool mouse_pressed_right;
float old_char_o;
};
#endif

View File

@ -70,6 +70,10 @@ SceneLogin::SceneLogin(PseuGUI *gui) : Scene(gui)
guienv->addButton(rect<s32>((scrn.Width*0.5f)-60, (scrn.Height*0.3f)+100, (scrn.Width*0.5f)+60, (scrn.Height*0.3f)+130), 0, 16, L"Logon");
msgbox = guienv->addStaticText(GetStringFromDB(ISCENE_LOGIN_CONN_STATUS,DSCENE_LOGIN_NOT_CONNECTED).c_str(),rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+150, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+180),true,true);
if(soundengine)
{
soundengine->play2D("data/misc/main_theme.ogg",true);
}
}
void SceneLogin::OnUpdate(s32 timepassed)
@ -114,6 +118,10 @@ void SceneLogin::OnUpdate(s32 timepassed)
void SceneLogin::OnDelete(void)
{
if(soundengine)
{
soundengine->stopAllSounds();
}
// not necessary to delete the images, because they are deleted by guienv->clear()
}

View File

@ -368,7 +368,7 @@ void SceneWorld::OnUpdate(s32 timediff)
}
device->getCursorControl()->setPosition(mouse_pos);
// rotate character if right mpouse button pressed.
// rotate character if right mouse button pressed.
if(mouse_pressed_right)
{
mychar->GetPositionPtr()->o = PI*3/2 - DEG_TO_RAD(camera->getHeading());

View File

@ -0,0 +1,273 @@
/*
* Common bit i/o utils
* Copyright (c) 2000, 2001 Fabrice Bellard.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Modified by Matt Campbell <mattcampbell@pobox.com> for the stand-alone
* mpaudec library. Based on common.c from libavcodec.
*/
#include "internal.h"
/**
* init GetBitContext.
* @param buffer bitstream buffer
* @param bit_size the size of the buffer in bits
*/
void init_get_bits(GetBitContext *s,
const uint8_t *buffer, int bit_size)
{
s->buffer= buffer;
s->size_in_bits= bit_size;
s->index=0;
}
unsigned int show_bits(const GetBitContext *s, int n)
{
int i;
unsigned int result = 0;
assert(s->size_in_bits - s->index >= n);
for (i = s->index; i < s->index + n; i++) {
int byte_index = i / 8;
unsigned int right_shift = 7 - (i % 8);
uint8_t byte = s->buffer[byte_index];
uint8_t bit;
result <<= 1;
if (right_shift == 0)
bit = byte & 0x1;
else
bit = (byte >> right_shift) & 0x1;
result |= (unsigned int)bit;
}
return result;
}
void skip_bits(GetBitContext *s, int n)
{
s->index += n;
}
unsigned int get_bits(GetBitContext *s, int n)
{
unsigned int result = show_bits(s, n);
skip_bits(s, n);
return result;
}
int get_bits_count(const GetBitContext *s)
{
return s->index;
}
/* VLC decoding */
/*#define DEBUG_VLC*/
#define GET_DATA(v, table, i, wrap, size) \
{\
const uint8_t *ptr = (const uint8_t *)table + i * wrap;\
switch(size) {\
case 1:\
v = *(const uint8_t *)ptr;\
break;\
case 2:\
v = *(const uint16_t *)ptr;\
break;\
default:\
v = *(const uint32_t *)ptr;\
break;\
}\
}
static int alloc_table(VLC *vlc, int size)
{
int index;
index = vlc->table_size;
vlc->table_size += size;
if (vlc->table_size > vlc->table_allocated) {
vlc->table_allocated += (1 << vlc->bits);
vlc->table = realloc(vlc->table,
sizeof(VLC_TYPE) * 2 * vlc->table_allocated);
if (!vlc->table)
return -1;
}
return index;
}
static int build_table(VLC *vlc, int table_nb_bits,
int nb_codes,
const void *bits, int bits_wrap, int bits_size,
const void *codes, int codes_wrap, int codes_size,
uint32_t code_prefix, int n_prefix)
{
int i, j, k, n, table_size, table_index, nb, n1, index;
uint32_t code;
VLC_TYPE (*table)[2];
table_size = 1 << table_nb_bits;
table_index = alloc_table(vlc, table_size);
#ifdef DEBUG_VLC
printf("new table index=%d size=%d code_prefix=%x n=%d\n",
table_index, table_size, code_prefix, n_prefix);
#endif
if (table_index < 0)
return -1;
table = &vlc->table[table_index];
for(i=0;i<table_size;i++) {
table[i][1] = 0; /*bits*/
table[i][0] = -1; /*codes*/
}
/* first pass: map codes and compute auxillary table sizes */
for(i=0;i<nb_codes;i++) {
GET_DATA(n, bits, i, bits_wrap, bits_size);
GET_DATA(code, codes, i, codes_wrap, codes_size);
/* we accept tables with holes */
if (n <= 0)
continue;
#if defined(DEBUG_VLC) && 0
printf("i=%d n=%d code=0x%x\n", i, n, code);
#endif
/* if code matches the prefix, it is in the table */
n -= n_prefix;
if (n > 0 && (code >> n) == code_prefix) {
if (n <= table_nb_bits) {
/* no need to add another table */
j = (code << (table_nb_bits - n)) & (table_size - 1);
nb = 1 << (table_nb_bits - n);
for(k=0;k<nb;k++) {
#ifdef DEBUG_VLC
printf("%4x: code=%d n=%d\n",
j, i, n);
#endif
assert(table[j][1] /*bits*/ == 0);
table[j][1] = n; /*bits*/
table[j][0] = i; /*code*/
j++;
}
} else {
n -= table_nb_bits;
j = (code >> n) & ((1 << table_nb_bits) - 1);
#ifdef DEBUG_VLC
printf("%4x: n=%d (subtable)\n",
j, n);
#endif
/* compute table size */
n1 = -table[j][1]; /*bits*/
if (n > n1)
n1 = n;
table[j][1] = -n1; /*bits*/
}
}
}
/* second pass : fill auxillary tables recursively */
for(i=0;i<table_size;i++) {
n = table[i][1]; /*bits*/
if (n < 0) {
n = -n;
if (n > table_nb_bits) {
n = table_nb_bits;
table[i][1] = -n; /*bits*/
}
index = build_table(vlc, n, nb_codes,
bits, bits_wrap, bits_size,
codes, codes_wrap, codes_size,
(code_prefix << table_nb_bits) | i,
n_prefix + table_nb_bits);
if (index < 0)
return -1;
/* note: realloc has been done, so reload tables */
table = &vlc->table[table_index];
table[i][0] = index; /*code*/
}
}
return table_index;
}
/* Build VLC decoding tables suitable for use with get_vlc().
'nb_bits' set thee decoding table size (2^nb_bits) entries. The
bigger it is, the faster is the decoding. But it should not be too
big to save memory and L1 cache. '9' is a good compromise.
'nb_codes' : number of vlcs codes
'bits' : table which gives the size (in bits) of each vlc code.
'codes' : table which gives the bit pattern of of each vlc code.
'xxx_wrap' : give the number of bytes between each entry of the
'bits' or 'codes' tables.
'xxx_size' : gives the number of bytes of each entry of the 'bits'
or 'codes' tables.
'wrap' and 'size' allows to use any memory configuration and types
(byte/word/long) to store the 'bits' and 'codes' tables.
*/
int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
const void *bits, int bits_wrap, int bits_size,
const void *codes, int codes_wrap, int codes_size)
{
vlc->bits = nb_bits;
vlc->table = NULL;
vlc->table_allocated = 0;
vlc->table_size = 0;
#ifdef DEBUG_VLC
printf("build table nb_codes=%d\n", nb_codes);
#endif
if (build_table(vlc, nb_bits, nb_codes,
bits, bits_wrap, bits_size,
codes, codes_wrap, codes_size,
0, 0) < 0) {
free(vlc->table);
return -1;
}
return 0;
}
void free_vlc(VLC *vlc)
{
free(vlc->table);
}
int get_vlc(GetBitContext *s, const VLC *vlc)
{
int code = 0;
int depth = 0, max_depth = 3;
int n, index, bits = vlc->bits;
do {
index = show_bits(s, bits) + code;
code = vlc->table[index][0];
n = vlc->table[index][1];
depth++;
if (n < 0 && depth < max_depth) {
skip_bits(s, bits);
bits = -n;
}
} while (n < 0 && depth < max_depth);
skip_bits(s, n);
return code;
}

View File

@ -0,0 +1,86 @@
/* Based on common.h from libavcodec. Modified extensively by Matt Campbell
<mattcampbell@pobox.com> for the stand-alone mpaudec library. */
#ifndef INTERNAL_H
#define INTERNAL_H
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
# define CONFIG_WIN32
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stddef.h>
#include "mpaudec.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifdef CONFIG_WIN32
/* windows */
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
typedef signed char int8_t;
typedef signed int int32_t;
typedef signed __int64 int64_t;
# ifdef _DEBUG
# define DEBUG
# endif
/* CONFIG_WIN32 end */
#else
/* unix */
#include <inttypes.h>
#endif /* !CONFIG_WIN32 */
/* debug stuff */
#if !defined(DEBUG) && !defined(NDEBUG)
# define NDEBUG
#endif
#include <assert.h>
/* bit input */
typedef struct GetBitContext {
const uint8_t *buffer;
int index;
int size_in_bits;
} GetBitContext;
int get_bits_count(const GetBitContext *s);
#define VLC_TYPE int16_t
typedef struct VLC {
int bits;
VLC_TYPE (*table)[2];
int table_size, table_allocated;
} VLC;
unsigned int get_bits(GetBitContext *s, int n);
unsigned int show_bits(const GetBitContext *s, int n);
void skip_bits(GetBitContext *s, int n);
void init_get_bits(GetBitContext *s,
const uint8_t *buffer, int buffer_size);
int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
const void *bits, int bits_wrap, int bits_size,
const void *codes, int codes_wrap, int codes_size);
void free_vlc(VLC *vlc);
int get_vlc(GetBitContext *s, const VLC *vlc);
#endif /* INTERNAL_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
/* Portions based on avcodec.h from libavcodec. */
#ifndef MPAUDEC_H
#define MPAUDEC_H
#ifdef __cplusplus
extern "C" {
#endif
/* in bytes */
#define MPAUDEC_MAX_AUDIO_FRAME_SIZE 4608
typedef struct MPAuDecContext {
int bit_rate;
int layer;
int sample_rate;
int channels;
int frame_size;
void *priv_data;
int parse_only;
int coded_frame_size;
} MPAuDecContext;
int mpaudec_init(MPAuDecContext *mpctx);
int mpaudec_decode_frame(MPAuDecContext * mpctx,
void *data, int *data_size,
const unsigned char * buf, int buf_size);
void mpaudec_clear(MPAuDecContext *mpctx);
#ifdef __cplusplus
}
#endif
#endif /* MPAUDEC_H */

View File

@ -0,0 +1,772 @@
/* Modified slightly by Matt Campbell <mattcampbell@pobox.com> for the
stand-alone mpaudec library. Based on mpegaudiodectab.h from libavcodec. */
static const uint16_t mpa_bitrate_tab[2][3][15] = {
{ {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } },
{ {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256},
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
}
};
static const uint16_t mpa_freq_tab[3] = { 44100, 48000, 32000 };
/*******************************************************/
/* half mpeg encoding window (full precision) */
static const int32_t mpa_enwindow[257] = {
0, -1, -1, -1, -1, -1, -1, -2,
-2, -2, -2, -3, -3, -4, -4, -5,
-5, -6, -7, -7, -8, -9, -10, -11,
-13, -14, -16, -17, -19, -21, -24, -26,
-29, -31, -35, -38, -41, -45, -49, -53,
-58, -63, -68, -73, -79, -85, -91, -97,
-104, -111, -117, -125, -132, -139, -147, -154,
-161, -169, -176, -183, -190, -196, -202, -208,
213, 218, 222, 225, 227, 228, 228, 227,
224, 221, 215, 208, 200, 189, 177, 163,
146, 127, 106, 83, 57, 29, -2, -36,
-72, -111, -153, -197, -244, -294, -347, -401,
-459, -519, -581, -645, -711, -779, -848, -919,
-991, -1064, -1137, -1210, -1283, -1356, -1428, -1498,
-1567, -1634, -1698, -1759, -1817, -1870, -1919, -1962,
-2001, -2032, -2057, -2075, -2085, -2087, -2080, -2063,
2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535,
1414, 1280, 1131, 970, 794, 605, 402, 185,
-45, -288, -545, -814, -1095, -1388, -1692, -2006,
-2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788,
-5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597,
-7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585,
-9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750,
-9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134,
6574, 5959, 5288, 4561, 3776, 2935, 2037, 1082,
70, -998, -2122, -3300, -4533, -5818, -7154, -8540,
-9975,-11455,-12980,-14548,-16155,-17799,-19478,-21189,
-22929,-24694,-26482,-28289,-30112,-31947,-33791,-35640,
-37489,-39336,-41176,-43006,-44821,-46617,-48390,-50137,
-51853,-53534,-55178,-56778,-58333,-59838,-61289,-62684,
-64019,-65290,-66494,-67629,-68692,-69679,-70590,-71420,
-72169,-72835,-73415,-73908,-74313,-74630,-74856,-74992,
75038,
};
/*******************************************************/
/* layer 2 tables */
static const int sblimit_table[5] = { 27 , 30 , 8, 12 , 30 };
static const int quant_steps[17] = {
3, 5, 7, 9, 15,
31, 63, 127, 255, 511,
1023, 2047, 4095, 8191, 16383,
32767, 65535
};
/* we use a negative value if grouped */
static const int quant_bits[17] = {
-5, -7, 3, -10, 4,
5, 6, 7, 8, 9,
10, 11, 12, 13, 14,
15, 16
};
/* encoding tables which give the quantization index. Note how it is
possible to store them efficiently ! */
static const unsigned char alloc_table_0[] = {
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
};
static const unsigned char alloc_table_1[] = {
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
};
static const unsigned char alloc_table_2[] = {
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
};
static const unsigned char alloc_table_3[] = {
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
};
static const unsigned char alloc_table_4[] = {
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
};
static const unsigned char *alloc_tables[5] =
{ alloc_table_0, alloc_table_1, alloc_table_2, alloc_table_3, alloc_table_4, };
/*******************************************************/
/* layer 3 tables */
/* layer3 scale factor size */
static const uint8_t slen_table[2][16] = {
{ 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 },
{ 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 },
};
/* number of lsf scale factors for a given size */
static const uint8_t lsf_nsf_table[6][3][4] = {
{ { 6, 5, 5, 5 }, { 9, 9, 9, 9 }, { 6, 9, 9, 9 } },
{ { 6, 5, 7, 3 }, { 9, 9, 12, 6 }, { 6, 9, 12, 6 } },
{ { 11, 10, 0, 0 }, { 18, 18, 0, 0 }, { 15, 18, 0, 0 } },
{ { 7, 7, 7, 0 }, { 12, 12, 12, 0 }, { 6, 15, 12, 0 } },
{ { 6, 6, 6, 3 }, { 12, 9, 9, 6 }, { 6, 12, 9, 6 } },
{ { 8, 8, 5, 0 }, { 15, 12, 9, 0 }, { 6, 18, 9, 0 } },
};
/* mpegaudio layer 3 huffman tables */
static const uint16_t mpa_huffcodes_1[4] = {
0x0001, 0x0001, 0x0001, 0x0000,
};
static const uint8_t mpa_huffbits_1[4] = {
1, 3, 2, 3,
};
static const uint16_t mpa_huffcodes_2[9] = {
0x0001, 0x0002, 0x0001, 0x0003, 0x0001, 0x0001, 0x0003, 0x0002,
0x0000,
};
static const uint8_t mpa_huffbits_2[9] = {
1, 3, 6, 3, 3, 5, 5, 5,
6,
};
static const uint16_t mpa_huffcodes_3[9] = {
0x0003, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0002,
0x0000,
};
static const uint8_t mpa_huffbits_3[9] = {
2, 2, 6, 3, 2, 5, 5, 5,
6,
};
static const uint16_t mpa_huffcodes_5[16] = {
0x0001, 0x0002, 0x0006, 0x0005, 0x0003, 0x0001, 0x0004, 0x0004,
0x0007, 0x0005, 0x0007, 0x0001, 0x0006, 0x0001, 0x0001, 0x0000,
};
static const uint8_t mpa_huffbits_5[16] = {
1, 3, 6, 7, 3, 3, 6, 7,
6, 6, 7, 8, 7, 6, 7, 8,
};
static const uint16_t mpa_huffcodes_6[16] = {
0x0007, 0x0003, 0x0005, 0x0001, 0x0006, 0x0002, 0x0003, 0x0002,
0x0005, 0x0004, 0x0004, 0x0001, 0x0003, 0x0003, 0x0002, 0x0000,
};
static const uint8_t mpa_huffbits_6[16] = {
3, 3, 5, 7, 3, 2, 4, 5,
4, 4, 5, 6, 6, 5, 6, 7,
};
static const uint16_t mpa_huffcodes_7[36] = {
0x0001, 0x0002, 0x000a, 0x0013, 0x0010, 0x000a, 0x0003, 0x0003,
0x0007, 0x000a, 0x0005, 0x0003, 0x000b, 0x0004, 0x000d, 0x0011,
0x0008, 0x0004, 0x000c, 0x000b, 0x0012, 0x000f, 0x000b, 0x0002,
0x0007, 0x0006, 0x0009, 0x000e, 0x0003, 0x0001, 0x0006, 0x0004,
0x0005, 0x0003, 0x0002, 0x0000,
};
static const uint8_t mpa_huffbits_7[36] = {
1, 3, 6, 8, 8, 9, 3, 4,
6, 7, 7, 8, 6, 5, 7, 8,
8, 9, 7, 7, 8, 9, 9, 9,
7, 7, 8, 9, 9, 10, 8, 8,
9, 10, 10, 10,
};
static const uint16_t mpa_huffcodes_8[36] = {
0x0003, 0x0004, 0x0006, 0x0012, 0x000c, 0x0005, 0x0005, 0x0001,
0x0002, 0x0010, 0x0009, 0x0003, 0x0007, 0x0003, 0x0005, 0x000e,
0x0007, 0x0003, 0x0013, 0x0011, 0x000f, 0x000d, 0x000a, 0x0004,
0x000d, 0x0005, 0x0008, 0x000b, 0x0005, 0x0001, 0x000c, 0x0004,
0x0004, 0x0001, 0x0001, 0x0000,
};
static const uint8_t mpa_huffbits_8[36] = {
2, 3, 6, 8, 8, 9, 3, 2,
4, 8, 8, 8, 6, 4, 6, 8,
8, 9, 8, 8, 8, 9, 9, 10,
8, 7, 8, 9, 10, 10, 9, 8,
9, 9, 11, 11,
};
static const uint16_t mpa_huffcodes_9[36] = {
0x0007, 0x0005, 0x0009, 0x000e, 0x000f, 0x0007, 0x0006, 0x0004,
0x0005, 0x0005, 0x0006, 0x0007, 0x0007, 0x0006, 0x0008, 0x0008,
0x0008, 0x0005, 0x000f, 0x0006, 0x0009, 0x000a, 0x0005, 0x0001,
0x000b, 0x0007, 0x0009, 0x0006, 0x0004, 0x0001, 0x000e, 0x0004,
0x0006, 0x0002, 0x0006, 0x0000,
};
static const uint8_t mpa_huffbits_9[36] = {
3, 3, 5, 6, 8, 9, 3, 3,
4, 5, 6, 8, 4, 4, 5, 6,
7, 8, 6, 5, 6, 7, 7, 8,
7, 6, 7, 7, 8, 9, 8, 7,
8, 8, 9, 9,
};
static const uint16_t mpa_huffcodes_10[64] = {
0x0001, 0x0002, 0x000a, 0x0017, 0x0023, 0x001e, 0x000c, 0x0011,
0x0003, 0x0003, 0x0008, 0x000c, 0x0012, 0x0015, 0x000c, 0x0007,
0x000b, 0x0009, 0x000f, 0x0015, 0x0020, 0x0028, 0x0013, 0x0006,
0x000e, 0x000d, 0x0016, 0x0022, 0x002e, 0x0017, 0x0012, 0x0007,
0x0014, 0x0013, 0x0021, 0x002f, 0x001b, 0x0016, 0x0009, 0x0003,
0x001f, 0x0016, 0x0029, 0x001a, 0x0015, 0x0014, 0x0005, 0x0003,
0x000e, 0x000d, 0x000a, 0x000b, 0x0010, 0x0006, 0x0005, 0x0001,
0x0009, 0x0008, 0x0007, 0x0008, 0x0004, 0x0004, 0x0002, 0x0000,
};
static const uint8_t mpa_huffbits_10[64] = {
1, 3, 6, 8, 9, 9, 9, 10,
3, 4, 6, 7, 8, 9, 8, 8,
6, 6, 7, 8, 9, 10, 9, 9,
7, 7, 8, 9, 10, 10, 9, 10,
8, 8, 9, 10, 10, 10, 10, 10,
9, 9, 10, 10, 11, 11, 10, 11,
8, 8, 9, 10, 10, 10, 11, 11,
9, 8, 9, 10, 10, 11, 11, 11,
};
static const uint16_t mpa_huffcodes_11[64] = {
0x0003, 0x0004, 0x000a, 0x0018, 0x0022, 0x0021, 0x0015, 0x000f,
0x0005, 0x0003, 0x0004, 0x000a, 0x0020, 0x0011, 0x000b, 0x000a,
0x000b, 0x0007, 0x000d, 0x0012, 0x001e, 0x001f, 0x0014, 0x0005,
0x0019, 0x000b, 0x0013, 0x003b, 0x001b, 0x0012, 0x000c, 0x0005,
0x0023, 0x0021, 0x001f, 0x003a, 0x001e, 0x0010, 0x0007, 0x0005,
0x001c, 0x001a, 0x0020, 0x0013, 0x0011, 0x000f, 0x0008, 0x000e,
0x000e, 0x000c, 0x0009, 0x000d, 0x000e, 0x0009, 0x0004, 0x0001,
0x000b, 0x0004, 0x0006, 0x0006, 0x0006, 0x0003, 0x0002, 0x0000,
};
static const uint8_t mpa_huffbits_11[64] = {
2, 3, 5, 7, 8, 9, 8, 9,
3, 3, 4, 6, 8, 8, 7, 8,
5, 5, 6, 7, 8, 9, 8, 8,
7, 6, 7, 9, 8, 10, 8, 9,
8, 8, 8, 9, 9, 10, 9, 10,
8, 8, 9, 10, 10, 11, 10, 11,
8, 7, 7, 8, 9, 10, 10, 10,
8, 7, 8, 9, 10, 10, 10, 10,
};
static const uint16_t mpa_huffcodes_12[64] = {
0x0009, 0x0006, 0x0010, 0x0021, 0x0029, 0x0027, 0x0026, 0x001a,
0x0007, 0x0005, 0x0006, 0x0009, 0x0017, 0x0010, 0x001a, 0x000b,
0x0011, 0x0007, 0x000b, 0x000e, 0x0015, 0x001e, 0x000a, 0x0007,
0x0011, 0x000a, 0x000f, 0x000c, 0x0012, 0x001c, 0x000e, 0x0005,
0x0020, 0x000d, 0x0016, 0x0013, 0x0012, 0x0010, 0x0009, 0x0005,
0x0028, 0x0011, 0x001f, 0x001d, 0x0011, 0x000d, 0x0004, 0x0002,
0x001b, 0x000c, 0x000b, 0x000f, 0x000a, 0x0007, 0x0004, 0x0001,
0x001b, 0x000c, 0x0008, 0x000c, 0x0006, 0x0003, 0x0001, 0x0000,
};
static const uint8_t mpa_huffbits_12[64] = {
4, 3, 5, 7, 8, 9, 9, 9,
3, 3, 4, 5, 7, 7, 8, 8,
5, 4, 5, 6, 7, 8, 7, 8,
6, 5, 6, 6, 7, 8, 8, 8,
7, 6, 7, 7, 8, 8, 8, 9,
8, 7, 8, 8, 8, 9, 8, 9,
8, 7, 7, 8, 8, 9, 9, 10,
9, 8, 8, 9, 9, 9, 9, 10,
};
static const uint16_t mpa_huffcodes_13[256] = {
0x0001, 0x0005, 0x000e, 0x0015, 0x0022, 0x0033, 0x002e, 0x0047,
0x002a, 0x0034, 0x0044, 0x0034, 0x0043, 0x002c, 0x002b, 0x0013,
0x0003, 0x0004, 0x000c, 0x0013, 0x001f, 0x001a, 0x002c, 0x0021,
0x001f, 0x0018, 0x0020, 0x0018, 0x001f, 0x0023, 0x0016, 0x000e,
0x000f, 0x000d, 0x0017, 0x0024, 0x003b, 0x0031, 0x004d, 0x0041,
0x001d, 0x0028, 0x001e, 0x0028, 0x001b, 0x0021, 0x002a, 0x0010,
0x0016, 0x0014, 0x0025, 0x003d, 0x0038, 0x004f, 0x0049, 0x0040,
0x002b, 0x004c, 0x0038, 0x0025, 0x001a, 0x001f, 0x0019, 0x000e,
0x0023, 0x0010, 0x003c, 0x0039, 0x0061, 0x004b, 0x0072, 0x005b,
0x0036, 0x0049, 0x0037, 0x0029, 0x0030, 0x0035, 0x0017, 0x0018,
0x003a, 0x001b, 0x0032, 0x0060, 0x004c, 0x0046, 0x005d, 0x0054,
0x004d, 0x003a, 0x004f, 0x001d, 0x004a, 0x0031, 0x0029, 0x0011,
0x002f, 0x002d, 0x004e, 0x004a, 0x0073, 0x005e, 0x005a, 0x004f,
0x0045, 0x0053, 0x0047, 0x0032, 0x003b, 0x0026, 0x0024, 0x000f,
0x0048, 0x0022, 0x0038, 0x005f, 0x005c, 0x0055, 0x005b, 0x005a,
0x0056, 0x0049, 0x004d, 0x0041, 0x0033, 0x002c, 0x002b, 0x002a,
0x002b, 0x0014, 0x001e, 0x002c, 0x0037, 0x004e, 0x0048, 0x0057,
0x004e, 0x003d, 0x002e, 0x0036, 0x0025, 0x001e, 0x0014, 0x0010,
0x0035, 0x0019, 0x0029, 0x0025, 0x002c, 0x003b, 0x0036, 0x0051,
0x0042, 0x004c, 0x0039, 0x0036, 0x0025, 0x0012, 0x0027, 0x000b,
0x0023, 0x0021, 0x001f, 0x0039, 0x002a, 0x0052, 0x0048, 0x0050,
0x002f, 0x003a, 0x0037, 0x0015, 0x0016, 0x001a, 0x0026, 0x0016,
0x0035, 0x0019, 0x0017, 0x0026, 0x0046, 0x003c, 0x0033, 0x0024,
0x0037, 0x001a, 0x0022, 0x0017, 0x001b, 0x000e, 0x0009, 0x0007,
0x0022, 0x0020, 0x001c, 0x0027, 0x0031, 0x004b, 0x001e, 0x0034,
0x0030, 0x0028, 0x0034, 0x001c, 0x0012, 0x0011, 0x0009, 0x0005,
0x002d, 0x0015, 0x0022, 0x0040, 0x0038, 0x0032, 0x0031, 0x002d,
0x001f, 0x0013, 0x000c, 0x000f, 0x000a, 0x0007, 0x0006, 0x0003,
0x0030, 0x0017, 0x0014, 0x0027, 0x0024, 0x0023, 0x0035, 0x0015,
0x0010, 0x0017, 0x000d, 0x000a, 0x0006, 0x0001, 0x0004, 0x0002,
0x0010, 0x000f, 0x0011, 0x001b, 0x0019, 0x0014, 0x001d, 0x000b,
0x0011, 0x000c, 0x0010, 0x0008, 0x0001, 0x0001, 0x0000, 0x0001,
};
static const uint8_t mpa_huffbits_13[256] = {
1, 4, 6, 7, 8, 9, 9, 10,
9, 10, 11, 11, 12, 12, 13, 13,
3, 4, 6, 7, 8, 8, 9, 9,
9, 9, 10, 10, 11, 12, 12, 12,
6, 6, 7, 8, 9, 9, 10, 10,
9, 10, 10, 11, 11, 12, 13, 13,
7, 7, 8, 9, 9, 10, 10, 10,
10, 11, 11, 11, 11, 12, 13, 13,
8, 7, 9, 9, 10, 10, 11, 11,
10, 11, 11, 12, 12, 13, 13, 14,
9, 8, 9, 10, 10, 10, 11, 11,
11, 11, 12, 11, 13, 13, 14, 14,
9, 9, 10, 10, 11, 11, 11, 11,
11, 12, 12, 12, 13, 13, 14, 14,
10, 9, 10, 11, 11, 11, 12, 12,
12, 12, 13, 13, 13, 14, 16, 16,
9, 8, 9, 10, 10, 11, 11, 12,
12, 12, 12, 13, 13, 14, 15, 15,
10, 9, 10, 10, 11, 11, 11, 13,
12, 13, 13, 14, 14, 14, 16, 15,
10, 10, 10, 11, 11, 12, 12, 13,
12, 13, 14, 13, 14, 15, 16, 17,
11, 10, 10, 11, 12, 12, 12, 12,
13, 13, 13, 14, 15, 15, 15, 16,
11, 11, 11, 12, 12, 13, 12, 13,
14, 14, 15, 15, 15, 16, 16, 16,
12, 11, 12, 13, 13, 13, 14, 14,
14, 14, 14, 15, 16, 15, 16, 16,
13, 12, 12, 13, 13, 13, 15, 14,
14, 17, 15, 15, 15, 17, 16, 16,
12, 12, 13, 14, 14, 14, 15, 14,
15, 15, 16, 16, 19, 18, 19, 16,
};
static const uint16_t mpa_huffcodes_15[256] = {
0x0007, 0x000c, 0x0012, 0x0035, 0x002f, 0x004c, 0x007c, 0x006c,
0x0059, 0x007b, 0x006c, 0x0077, 0x006b, 0x0051, 0x007a, 0x003f,
0x000d, 0x0005, 0x0010, 0x001b, 0x002e, 0x0024, 0x003d, 0x0033,
0x002a, 0x0046, 0x0034, 0x0053, 0x0041, 0x0029, 0x003b, 0x0024,
0x0013, 0x0011, 0x000f, 0x0018, 0x0029, 0x0022, 0x003b, 0x0030,
0x0028, 0x0040, 0x0032, 0x004e, 0x003e, 0x0050, 0x0038, 0x0021,
0x001d, 0x001c, 0x0019, 0x002b, 0x0027, 0x003f, 0x0037, 0x005d,
0x004c, 0x003b, 0x005d, 0x0048, 0x0036, 0x004b, 0x0032, 0x001d,
0x0034, 0x0016, 0x002a, 0x0028, 0x0043, 0x0039, 0x005f, 0x004f,
0x0048, 0x0039, 0x0059, 0x0045, 0x0031, 0x0042, 0x002e, 0x001b,
0x004d, 0x0025, 0x0023, 0x0042, 0x003a, 0x0034, 0x005b, 0x004a,
0x003e, 0x0030, 0x004f, 0x003f, 0x005a, 0x003e, 0x0028, 0x0026,
0x007d, 0x0020, 0x003c, 0x0038, 0x0032, 0x005c, 0x004e, 0x0041,
0x0037, 0x0057, 0x0047, 0x0033, 0x0049, 0x0033, 0x0046, 0x001e,
0x006d, 0x0035, 0x0031, 0x005e, 0x0058, 0x004b, 0x0042, 0x007a,
0x005b, 0x0049, 0x0038, 0x002a, 0x0040, 0x002c, 0x0015, 0x0019,
0x005a, 0x002b, 0x0029, 0x004d, 0x0049, 0x003f, 0x0038, 0x005c,
0x004d, 0x0042, 0x002f, 0x0043, 0x0030, 0x0035, 0x0024, 0x0014,
0x0047, 0x0022, 0x0043, 0x003c, 0x003a, 0x0031, 0x0058, 0x004c,
0x0043, 0x006a, 0x0047, 0x0036, 0x0026, 0x0027, 0x0017, 0x000f,
0x006d, 0x0035, 0x0033, 0x002f, 0x005a, 0x0052, 0x003a, 0x0039,
0x0030, 0x0048, 0x0039, 0x0029, 0x0017, 0x001b, 0x003e, 0x0009,
0x0056, 0x002a, 0x0028, 0x0025, 0x0046, 0x0040, 0x0034, 0x002b,
0x0046, 0x0037, 0x002a, 0x0019, 0x001d, 0x0012, 0x000b, 0x000b,
0x0076, 0x0044, 0x001e, 0x0037, 0x0032, 0x002e, 0x004a, 0x0041,
0x0031, 0x0027, 0x0018, 0x0010, 0x0016, 0x000d, 0x000e, 0x0007,
0x005b, 0x002c, 0x0027, 0x0026, 0x0022, 0x003f, 0x0034, 0x002d,
0x001f, 0x0034, 0x001c, 0x0013, 0x000e, 0x0008, 0x0009, 0x0003,
0x007b, 0x003c, 0x003a, 0x0035, 0x002f, 0x002b, 0x0020, 0x0016,
0x0025, 0x0018, 0x0011, 0x000c, 0x000f, 0x000a, 0x0002, 0x0001,
0x0047, 0x0025, 0x0022, 0x001e, 0x001c, 0x0014, 0x0011, 0x001a,
0x0015, 0x0010, 0x000a, 0x0006, 0x0008, 0x0006, 0x0002, 0x0000,
};
static const uint8_t mpa_huffbits_15[256] = {
3, 4, 5, 7, 7, 8, 9, 9,
9, 10, 10, 11, 11, 11, 12, 13,
4, 3, 5, 6, 7, 7, 8, 8,
8, 9, 9, 10, 10, 10, 11, 11,
5, 5, 5, 6, 7, 7, 8, 8,
8, 9, 9, 10, 10, 11, 11, 11,
6, 6, 6, 7, 7, 8, 8, 9,
9, 9, 10, 10, 10, 11, 11, 11,
7, 6, 7, 7, 8, 8, 9, 9,
9, 9, 10, 10, 10, 11, 11, 11,
8, 7, 7, 8, 8, 8, 9, 9,
9, 9, 10, 10, 11, 11, 11, 12,
9, 7, 8, 8, 8, 9, 9, 9,
9, 10, 10, 10, 11, 11, 12, 12,
9, 8, 8, 9, 9, 9, 9, 10,
10, 10, 10, 10, 11, 11, 11, 12,
9, 8, 8, 9, 9, 9, 9, 10,
10, 10, 10, 11, 11, 12, 12, 12,
9, 8, 9, 9, 9, 9, 10, 10,
10, 11, 11, 11, 11, 12, 12, 12,
10, 9, 9, 9, 10, 10, 10, 10,
10, 11, 11, 11, 11, 12, 13, 12,
10, 9, 9, 9, 10, 10, 10, 10,
11, 11, 11, 11, 12, 12, 12, 13,
11, 10, 9, 10, 10, 10, 11, 11,
11, 11, 11, 11, 12, 12, 13, 13,
11, 10, 10, 10, 10, 11, 11, 11,
11, 12, 12, 12, 12, 12, 13, 13,
12, 11, 11, 11, 11, 11, 11, 11,
12, 12, 12, 12, 13, 13, 12, 13,
12, 11, 11, 11, 11, 11, 11, 12,
12, 12, 12, 12, 13, 13, 13, 13,
};
static const uint16_t mpa_huffcodes_16[256] = {
0x0001, 0x0005, 0x000e, 0x002c, 0x004a, 0x003f, 0x006e, 0x005d,
0x00ac, 0x0095, 0x008a, 0x00f2, 0x00e1, 0x00c3, 0x0178, 0x0011,
0x0003, 0x0004, 0x000c, 0x0014, 0x0023, 0x003e, 0x0035, 0x002f,
0x0053, 0x004b, 0x0044, 0x0077, 0x00c9, 0x006b, 0x00cf, 0x0009,
0x000f, 0x000d, 0x0017, 0x0026, 0x0043, 0x003a, 0x0067, 0x005a,
0x00a1, 0x0048, 0x007f, 0x0075, 0x006e, 0x00d1, 0x00ce, 0x0010,
0x002d, 0x0015, 0x0027, 0x0045, 0x0040, 0x0072, 0x0063, 0x0057,
0x009e, 0x008c, 0x00fc, 0x00d4, 0x00c7, 0x0183, 0x016d, 0x001a,
0x004b, 0x0024, 0x0044, 0x0041, 0x0073, 0x0065, 0x00b3, 0x00a4,
0x009b, 0x0108, 0x00f6, 0x00e2, 0x018b, 0x017e, 0x016a, 0x0009,
0x0042, 0x001e, 0x003b, 0x0038, 0x0066, 0x00b9, 0x00ad, 0x0109,
0x008e, 0x00fd, 0x00e8, 0x0190, 0x0184, 0x017a, 0x01bd, 0x0010,
0x006f, 0x0036, 0x0034, 0x0064, 0x00b8, 0x00b2, 0x00a0, 0x0085,
0x0101, 0x00f4, 0x00e4, 0x00d9, 0x0181, 0x016e, 0x02cb, 0x000a,
0x0062, 0x0030, 0x005b, 0x0058, 0x00a5, 0x009d, 0x0094, 0x0105,
0x00f8, 0x0197, 0x018d, 0x0174, 0x017c, 0x0379, 0x0374, 0x0008,
0x0055, 0x0054, 0x0051, 0x009f, 0x009c, 0x008f, 0x0104, 0x00f9,
0x01ab, 0x0191, 0x0188, 0x017f, 0x02d7, 0x02c9, 0x02c4, 0x0007,
0x009a, 0x004c, 0x0049, 0x008d, 0x0083, 0x0100, 0x00f5, 0x01aa,
0x0196, 0x018a, 0x0180, 0x02df, 0x0167, 0x02c6, 0x0160, 0x000b,
0x008b, 0x0081, 0x0043, 0x007d, 0x00f7, 0x00e9, 0x00e5, 0x00db,
0x0189, 0x02e7, 0x02e1, 0x02d0, 0x0375, 0x0372, 0x01b7, 0x0004,
0x00f3, 0x0078, 0x0076, 0x0073, 0x00e3, 0x00df, 0x018c, 0x02ea,
0x02e6, 0x02e0, 0x02d1, 0x02c8, 0x02c2, 0x00df, 0x01b4, 0x0006,
0x00ca, 0x00e0, 0x00de, 0x00da, 0x00d8, 0x0185, 0x0182, 0x017d,
0x016c, 0x0378, 0x01bb, 0x02c3, 0x01b8, 0x01b5, 0x06c0, 0x0004,
0x02eb, 0x00d3, 0x00d2, 0x00d0, 0x0172, 0x017b, 0x02de, 0x02d3,
0x02ca, 0x06c7, 0x0373, 0x036d, 0x036c, 0x0d83, 0x0361, 0x0002,
0x0179, 0x0171, 0x0066, 0x00bb, 0x02d6, 0x02d2, 0x0166, 0x02c7,
0x02c5, 0x0362, 0x06c6, 0x0367, 0x0d82, 0x0366, 0x01b2, 0x0000,
0x000c, 0x000a, 0x0007, 0x000b, 0x000a, 0x0011, 0x000b, 0x0009,
0x000d, 0x000c, 0x000a, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003,
};
static const uint8_t mpa_huffbits_16[256] = {
1, 4, 6, 8, 9, 9, 10, 10,
11, 11, 11, 12, 12, 12, 13, 9,
3, 4, 6, 7, 8, 9, 9, 9,
10, 10, 10, 11, 12, 11, 12, 8,
6, 6, 7, 8, 9, 9, 10, 10,
11, 10, 11, 11, 11, 12, 12, 9,
8, 7, 8, 9, 9, 10, 10, 10,
11, 11, 12, 12, 12, 13, 13, 10,
9, 8, 9, 9, 10, 10, 11, 11,
11, 12, 12, 12, 13, 13, 13, 9,
9, 8, 9, 9, 10, 11, 11, 12,
11, 12, 12, 13, 13, 13, 14, 10,
10, 9, 9, 10, 11, 11, 11, 11,
12, 12, 12, 12, 13, 13, 14, 10,
10, 9, 10, 10, 11, 11, 11, 12,
12, 13, 13, 13, 13, 15, 15, 10,
10, 10, 10, 11, 11, 11, 12, 12,
13, 13, 13, 13, 14, 14, 14, 10,
11, 10, 10, 11, 11, 12, 12, 13,
13, 13, 13, 14, 13, 14, 13, 11,
11, 11, 10, 11, 12, 12, 12, 12,
13, 14, 14, 14, 15, 15, 14, 10,
12, 11, 11, 11, 12, 12, 13, 14,
14, 14, 14, 14, 14, 13, 14, 11,
12, 12, 12, 12, 12, 13, 13, 13,
13, 15, 14, 14, 14, 14, 16, 11,
14, 12, 12, 12, 13, 13, 14, 14,
14, 16, 15, 15, 15, 17, 15, 11,
13, 13, 11, 12, 14, 14, 13, 14,
14, 15, 16, 15, 17, 15, 14, 11,
9, 8, 8, 9, 9, 10, 10, 10,
11, 11, 11, 11, 11, 11, 11, 8,
};
static const uint16_t mpa_huffcodes_24[256] = {
0x000f, 0x000d, 0x002e, 0x0050, 0x0092, 0x0106, 0x00f8, 0x01b2,
0x01aa, 0x029d, 0x028d, 0x0289, 0x026d, 0x0205, 0x0408, 0x0058,
0x000e, 0x000c, 0x0015, 0x0026, 0x0047, 0x0082, 0x007a, 0x00d8,
0x00d1, 0x00c6, 0x0147, 0x0159, 0x013f, 0x0129, 0x0117, 0x002a,
0x002f, 0x0016, 0x0029, 0x004a, 0x0044, 0x0080, 0x0078, 0x00dd,
0x00cf, 0x00c2, 0x00b6, 0x0154, 0x013b, 0x0127, 0x021d, 0x0012,
0x0051, 0x0027, 0x004b, 0x0046, 0x0086, 0x007d, 0x0074, 0x00dc,
0x00cc, 0x00be, 0x00b2, 0x0145, 0x0137, 0x0125, 0x010f, 0x0010,
0x0093, 0x0048, 0x0045, 0x0087, 0x007f, 0x0076, 0x0070, 0x00d2,
0x00c8, 0x00bc, 0x0160, 0x0143, 0x0132, 0x011d, 0x021c, 0x000e,
0x0107, 0x0042, 0x0081, 0x007e, 0x0077, 0x0072, 0x00d6, 0x00ca,
0x00c0, 0x00b4, 0x0155, 0x013d, 0x012d, 0x0119, 0x0106, 0x000c,
0x00f9, 0x007b, 0x0079, 0x0075, 0x0071, 0x00d7, 0x00ce, 0x00c3,
0x00b9, 0x015b, 0x014a, 0x0134, 0x0123, 0x0110, 0x0208, 0x000a,
0x01b3, 0x0073, 0x006f, 0x006d, 0x00d3, 0x00cb, 0x00c4, 0x00bb,
0x0161, 0x014c, 0x0139, 0x012a, 0x011b, 0x0213, 0x017d, 0x0011,
0x01ab, 0x00d4, 0x00d0, 0x00cd, 0x00c9, 0x00c1, 0x00ba, 0x00b1,
0x00a9, 0x0140, 0x012f, 0x011e, 0x010c, 0x0202, 0x0179, 0x0010,
0x014f, 0x00c7, 0x00c5, 0x00bf, 0x00bd, 0x00b5, 0x00ae, 0x014d,
0x0141, 0x0131, 0x0121, 0x0113, 0x0209, 0x017b, 0x0173, 0x000b,
0x029c, 0x00b8, 0x00b7, 0x00b3, 0x00af, 0x0158, 0x014b, 0x013a,
0x0130, 0x0122, 0x0115, 0x0212, 0x017f, 0x0175, 0x016e, 0x000a,
0x028c, 0x015a, 0x00ab, 0x00a8, 0x00a4, 0x013e, 0x0135, 0x012b,
0x011f, 0x0114, 0x0107, 0x0201, 0x0177, 0x0170, 0x016a, 0x0006,
0x0288, 0x0142, 0x013c, 0x0138, 0x0133, 0x012e, 0x0124, 0x011c,
0x010d, 0x0105, 0x0200, 0x0178, 0x0172, 0x016c, 0x0167, 0x0004,
0x026c, 0x012c, 0x0128, 0x0126, 0x0120, 0x011a, 0x0111, 0x010a,
0x0203, 0x017c, 0x0176, 0x0171, 0x016d, 0x0169, 0x0165, 0x0002,
0x0409, 0x0118, 0x0116, 0x0112, 0x010b, 0x0108, 0x0103, 0x017e,
0x017a, 0x0174, 0x016f, 0x016b, 0x0168, 0x0166, 0x0164, 0x0000,
0x002b, 0x0014, 0x0013, 0x0011, 0x000f, 0x000d, 0x000b, 0x0009,
0x0007, 0x0006, 0x0004, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003,
};
static const uint8_t mpa_huffbits_24[256] = {
4, 4, 6, 7, 8, 9, 9, 10,
10, 11, 11, 11, 11, 11, 12, 9,
4, 4, 5, 6, 7, 8, 8, 9,
9, 9, 10, 10, 10, 10, 10, 8,
6, 5, 6, 7, 7, 8, 8, 9,
9, 9, 9, 10, 10, 10, 11, 7,
7, 6, 7, 7, 8, 8, 8, 9,
9, 9, 9, 10, 10, 10, 10, 7,
8, 7, 7, 8, 8, 8, 8, 9,
9, 9, 10, 10, 10, 10, 11, 7,
9, 7, 8, 8, 8, 8, 9, 9,
9, 9, 10, 10, 10, 10, 10, 7,
9, 8, 8, 8, 8, 9, 9, 9,
9, 10, 10, 10, 10, 10, 11, 7,
10, 8, 8, 8, 9, 9, 9, 9,
10, 10, 10, 10, 10, 11, 11, 8,
10, 9, 9, 9, 9, 9, 9, 9,
9, 10, 10, 10, 10, 11, 11, 8,
10, 9, 9, 9, 9, 9, 9, 10,
10, 10, 10, 10, 11, 11, 11, 8,
11, 9, 9, 9, 9, 10, 10, 10,
10, 10, 10, 11, 11, 11, 11, 8,
11, 10, 9, 9, 9, 10, 10, 10,
10, 10, 10, 11, 11, 11, 11, 8,
11, 10, 10, 10, 10, 10, 10, 10,
10, 10, 11, 11, 11, 11, 11, 8,
11, 10, 10, 10, 10, 10, 10, 10,
11, 11, 11, 11, 11, 11, 11, 8,
12, 10, 10, 10, 10, 10, 10, 11,
11, 11, 11, 11, 11, 11, 11, 8,
8, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 8, 8, 8, 8, 4,
};
static const HuffTable mpa_huff_tables[16] = {
{ 1, NULL, NULL },
{ 2, mpa_huffbits_1, mpa_huffcodes_1 },
{ 3, mpa_huffbits_2, mpa_huffcodes_2 },
{ 3, mpa_huffbits_3, mpa_huffcodes_3 },
{ 4, mpa_huffbits_5, mpa_huffcodes_5 },
{ 4, mpa_huffbits_6, mpa_huffcodes_6 },
{ 6, mpa_huffbits_7, mpa_huffcodes_7 },
{ 6, mpa_huffbits_8, mpa_huffcodes_8 },
{ 6, mpa_huffbits_9, mpa_huffcodes_9 },
{ 8, mpa_huffbits_10, mpa_huffcodes_10 },
{ 8, mpa_huffbits_11, mpa_huffcodes_11 },
{ 8, mpa_huffbits_12, mpa_huffcodes_12 },
{ 16, mpa_huffbits_13, mpa_huffcodes_13 },
{ 16, mpa_huffbits_15, mpa_huffcodes_15 },
{ 16, mpa_huffbits_16, mpa_huffcodes_16 },
{ 16, mpa_huffbits_24, mpa_huffcodes_24 },
};
static const uint8_t mpa_huff_data[32][2] = {
{ 0, 0 },
{ 1, 0 },
{ 2, 0 },
{ 3, 0 },
{ 0, 0 },
{ 4, 0 },
{ 5, 0 },
{ 6, 0 },
{ 7, 0 },
{ 8, 0 },
{ 9, 0 },
{ 10, 0 },
{ 11, 0 },
{ 12, 0 },
{ 0, 0 },
{ 13, 0 },
{ 14, 1 },
{ 14, 2 },
{ 14, 3 },
{ 14, 4 },
{ 14, 6 },
{ 14, 8 },
{ 14, 10 },
{ 14, 13 },
{ 15, 4 },
{ 15, 5 },
{ 15, 6 },
{ 15, 7 },
{ 15, 8 },
{ 15, 9 },
{ 15, 11 },
{ 15, 13 },
};
/* huffman tables for quadrules */
static uint8_t mpa_quad_codes[2][16] = {
{ 1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1, },
{ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, },
};
static uint8_t mpa_quad_bits[2][16] = {
{ 1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6, },
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, },
};
/* band size tables */
static const uint8_t band_size_long[9][22] = {
{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10,
12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158, }, /* 44100 */
{ 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10,
12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192, }, /* 48000 */
{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12,
16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26, }, /* 32000 */
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 22050 */
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
18, 22, 26, 32, 38, 46, 52, 64, 70, 76, 36, }, /* 24000 */
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 16000 */
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 11025 */
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 12000 */
{ 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32,
40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2, }, /* 8000 */
};
static const uint8_t band_size_short[9][13] = {
{ 4, 4, 4, 4, 6, 8, 10, 12, 14, 18, 22, 30, 56, }, /* 44100 */
{ 4, 4, 4, 4, 6, 6, 10, 12, 14, 16, 20, 26, 66, }, /* 48000 */
{ 4, 4, 4, 4, 6, 8, 12, 16, 20, 26, 34, 42, 12, }, /* 32000 */
{ 4, 4, 4, 6, 6, 8, 10, 14, 18, 26, 32, 42, 18, }, /* 22050 */
{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 32, 44, 12, }, /* 24000 */
{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 16000 */
{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 11025 */
{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 12000 */
{ 8, 8, 8, 12, 16, 20, 24, 28, 36, 2, 2, 2, 26, }, /* 8000 */
};
static const uint8_t mpa_pretab[2][22] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 },
};
/* table for alias reduction (XXX: store it as integer !) */
static const float ci_table[8] = {
-0.6f, -0.535f, -0.33f, -0.185f, -0.095f, -0.041f, -0.0142f, -0.0037f,
};

View File

@ -0,0 +1,17 @@
/* Modified slightly by Matt Campbell <mattcampbell@pobox.com> for the
stand-alone mpaudec library. Based on mpegaudio.h from libavcodec. */
/* max frame size, in samples */
#define MPA_FRAME_SIZE 1152
/* max compressed frame size */
#define MPA_MAX_CODED_FRAME_SIZE 1792
#define MPA_MAX_CHANNELS 2
#define SBLIMIT 32 /* number of subbands */
#define MPA_STEREO 0
#define MPA_JSTEREO 1
#define MPA_DUAL 2
#define MPA_MONO 3

41
src/Client/GUI/ikpMP3.cpp Normal file
View File

@ -0,0 +1,41 @@
#include "irrklang/irrKlang.h"
#include <stdio.h>
#include <string.h>
#include "CIrrKlangAudioStreamLoaderMP3.h"
using namespace irrklang;
// this is the only function needed to be implemented for the plugin, it gets
// called by irrKlang when loaded.
// In this plugin, we create an audiostream loader class and register
// it at the engine, but a plugin can do anything.
// Be sure to name the function 'irrKlangPluginInit' and let the dll start with 'ikp'.
#ifdef WIN32
// Windows version
__declspec(dllexport) void __stdcall irrKlangPluginInit(ISoundEngine* engine, const char* version)
#else
// Linux version
void irrKlangPluginInit(ISoundEngine* engine, const char* version)
#endif
{
// do some version security check to be sure that this plugin isn't begin used
// by some newer irrKlang version with changed interfaces which could possibily
// cause crashes.
if (strcmp(version, IRR_KLANG_VERSION))
{
printf("This MP3 plugin only supports irrKlang version %s, mp3 playback disabled.\n", IRR_KLANG_VERSION);
return;
}
// create and register the loader
CIrrKlangAudioStreamLoaderMP3* loader = new CIrrKlangAudioStreamLoaderMP3();
engine->registerAudioStreamLoader(loader);
loader->drop();
// that's it, that's all.
}

View File

@ -0,0 +1,551 @@
#include "irrKlangSceneNode.h"
// id for our scene node, 'ikng', short for 'irrklang'.
// If this line doesn't work, you are probably using irrlicht 1.3 or earlier.
// Then remove the MAKE_IRR_ID thing and replace it with a random number.
const int IRRKLANG_SCENE_NODE_ID = MAKE_IRR_ID('i','k','n','g');
// type name for our scene node
const char* irrKlangSceneNodeTypeName = "irrKlangSceneNode";
CIrrKlangSceneNode::CIrrKlangSceneNode(irrklang::ISoundEngine* soundEngine,
scene::ISceneNode* parent,
scene::ISceneManager* mgr, s32 id)
: scene::ISceneNode(parent, mgr, id), SoundEngine(soundEngine)
{
setAutomaticCulling(scene::EAC_OFF);
MinDistance = 20.0f; // a usual good value for irrlicht engine applications
MaxDistance = -1.0f;
PlayMode = EPM_RANDOM;
TimeMsDelayFinished = 0;
DeleteWhenFinished = false;
MaxTimeMsInterval = 5000;
MinTimeMsInterval = 1000;
Sound = 0;
PlayedCount = 0;
if (SoundEngine)
SoundEngine->grab();
}
CIrrKlangSceneNode::~CIrrKlangSceneNode()
{
stop();
if (SoundEngine)
SoundEngine->drop();
}
void CIrrKlangSceneNode::OnRegisterSceneNode()
{
if (IsVisible && DebugDataVisible!=0)
SceneManager->registerNodeForRendering(this, irr::scene::ESNRP_TRANSPARENT);
ISceneNode::OnRegisterSceneNode();
}
void CIrrKlangSceneNode::OnAnimate(u32 timeMs)
{
ISceneNode::OnAnimate(timeMs);
// play the sound
core::vector3df pos = getAbsolutePosition();
if (Sound)
Sound->setPosition(pos);
switch(PlayMode)
{
case EPM_NOTHING:
return;
case EPM_RANDOM:
{
if (Sound && Sound->isFinished())
{
Sound->drop();
Sound = 0;
// calculate next play time
s32 delta = MaxTimeMsInterval - MinTimeMsInterval;
if (delta < 2)
delta = 2;
TimeMsDelayFinished = timeMs + (rand()%delta) + MinTimeMsInterval;
}
else
if (!Sound && (!TimeMsDelayFinished || timeMs > TimeMsDelayFinished))
{
// play new sound
if (SoundFileName.size())
Sound = SoundEngine->play3D(SoundFileName.c_str(), pos, false, true, true);
if (Sound)
{
if (MinDistance > 0 )
Sound->setMinDistance(MinDistance);
if (MaxDistance > 0 )
Sound->setMaxDistance(MaxDistance);
Sound->setIsPaused(false);
}
}
}
break;
case EPM_LOOPING:
{
if (!Sound)
{
if (SoundFileName.size())
Sound = SoundEngine->play3D(SoundFileName.c_str(), pos, true, true, true);
if (Sound)
{
if (MinDistance > 0 )
Sound->setMinDistance(MinDistance);
if (MaxDistance > 0 )
Sound->setMaxDistance(MaxDistance);
Sound->setIsPaused(false);
}
else
{
// sound could not be loaded
stop();
}
}
}
break;
case EPM_ONCE:
{
if (PlayedCount)
{
// stop
if (Sound && Sound->isFinished())
{
stop();
if (DeleteWhenFinished)
SceneManager->addToDeletionQueue(this);
}
}
else
{
// start
if (SoundFileName.size())
Sound = SoundEngine->play3D(SoundFileName.c_str(), pos, false, true, true);
if (Sound)
{
if (MinDistance > 0 )
Sound->setMinDistance(MinDistance);
if (MaxDistance > 0 )
Sound->setMaxDistance(MaxDistance);
Sound->setIsPaused(false);
++PlayedCount;
}
else
{
// sound could not be loaded
stop();
}
}
}
break;
}
}
void CIrrKlangSceneNode::render()
{
// draw scene node as billboard when debug data is visible
if (!DebugDataVisible)
return;
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
scene::ICameraSceneNode* camera = SceneManager->getActiveCamera();
if (camera)
{
video::S3DVertex vertices[4];
u16 indices[6];
indices[0] = 0;
indices[1] = 2;
indices[2] = 1;
indices[3] = 0;
indices[4] = 3;
indices[5] = 2;
vertices[0].TCoords.set(0.0f, 1.0f);
vertices[1].TCoords.set(0.0f, 0.0f);
vertices[2].TCoords.set(1.0f, 0.0f);
vertices[3].TCoords.set(1.0f, 1.0f);
vertices[0].Color.set(128,255,255,255);
vertices[1].Color.set(128,255,255,255);
vertices[2].Color.set(128,255,255,255);
vertices[3].Color.set(128,255,255,255);
core::vector3df pos = getAbsolutePosition();
core::vector3df campos = camera->getAbsolutePosition();
core::vector3df target = camera->getTarget();
core::vector3df up = camera->getUpVector();
core::vector3df view = target - campos;
view.normalize();
core::vector3df horizontal = up.crossProduct(view);
horizontal.normalize();
core::vector3df vertical = horizontal.crossProduct(view);
vertical.normalize();
const f32 Size = 5.0f;
horizontal *= Size / 2.0f;
vertical *= Size / 2.0f;
vertices[0].Pos = pos + horizontal + vertical;
vertices[1].Pos = pos + horizontal - vertical;
vertices[2].Pos = pos - horizontal - vertical;
vertices[3].Pos = pos - horizontal + vertical;
view *= -1.0f;
for (s32 i=0; i<4; ++i)
vertices[i].Normal = view;
// draw billboard
video::SMaterial material;
material.Lighting = false;
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
material.MaterialTypeParam = 255;
material.TextureLayer[0].Texture = driver->getTexture("textures/editor_defaults/default_sound.png");
core::matrix4 mat;
driver->setTransform(video::ETS_WORLD, mat);
driver->setMaterial(material);
driver->drawIndexedTriangleList(vertices, 4, indices, 2);
}
}
const core::aabbox3d<f32>& CIrrKlangSceneNode::getBoundingBox() const
{
return Box;
}
const c8* const IrrKlangPlayModeNames[] =
{
"nothing", "random", "looping", "play_once", 0
};
//! Writes attributes of the scene node.
void CIrrKlangSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
{
if (!out)
return;
ISceneNode::serializeAttributes(out, options);
const char** soundNames = 0;
if ( SoundEngine && options && ( options->Flags & io::EARWF_FOR_EDITOR ) )
{
// show a list of all loaded sound files in editor
int count = SoundEngine->getSoundSourceCount();
soundNames = new const char*[count+3];
for (int i=0; i<count; ++i)
soundNames[i] = SoundEngine->getSoundSource(i)->getName();
soundNames[count] = "";
soundNames[count+1] = "<select>"; // editor file selector
soundNames[count+2] = 0;
out->addEnum("SoundFileName", SoundFileName.c_str(), soundNames);
delete [] soundNames;
}
else
{
// only store string of sound file if not in editor
out->addString("SoundFileName", SoundFileName.c_str());
}
// add play modes
out->addEnum("PlayMode", PlayMode, IrrKlangPlayModeNames);
out->addFloat("MinDistance", MinDistance);
out->addFloat("MaxDistance", MaxDistance);
// only save the necessary attributes
switch(PlayMode)
{
case EPM_ONCE:
out->addBool("DeleteWhenFinished", DeleteWhenFinished);
break;
case EPM_RANDOM:
out->addInt("MinTimeMsInterval", MinTimeMsInterval);
out->addInt("MaxTimeMsInterval", MaxTimeMsInterval);
break;
}
}
//! Reads attributes of the scene node.
void CIrrKlangSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
if (!in)
return;
ISceneNode::deserializeAttributes(in);
core::stringc oldFileName = SoundFileName;
SoundFileName = in->getAttributeAsString("SoundFileName");
EPlayMode newMode = (EPlayMode)in->getAttributeAsEnumeration("PlayMode", IrrKlangPlayModeNames);
f32 minDistance = in->getAttributeAsFloat("MinDistance");
f32 maxDistance = in->getAttributeAsFloat("MaxDistance");
setMinMaxSoundDistance(minDistance, maxDistance);
DeleteWhenFinished = in->getAttributeAsBool("DeleteWhenFinished");
if (in->existsAttribute("MinTimeMsInterval"))
MinTimeMsInterval = in->getAttributeAsInt("MinTimeMsInterval");
if (in->existsAttribute("MaxTimeMsInterval"))
MaxTimeMsInterval = in->getAttributeAsInt("MaxTimeMsInterval");
if (newMode != PlayMode || oldFileName != SoundFileName)
{
stop();
TimeMsDelayFinished = 0;
PlayMode = newMode;
}
}
//! Creates a clone of this scene node and its children.
ISceneNode* CIrrKlangSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
{
// this method is only implemented to let irrEdit be able to copy the
// scene node via CTRL+C, it's not necessary
if (!newParent) newParent = Parent;
if (!newManager) newManager = SceneManager;
CIrrKlangSceneNode* nb = new CIrrKlangSceneNode(SoundEngine, newParent, newManager, ID);
nb->cloneMembers(this, newManager);
nb->SoundFileName = SoundFileName;
nb->MinDistance = MinDistance;
nb->Box = Box;
nb->PlayMode = PlayMode;
nb->TimeMsDelayFinished = TimeMsDelayFinished;
nb->DeleteWhenFinished = DeleteWhenFinished;
nb->MaxTimeMsInterval = MaxTimeMsInterval;
nb->MinTimeMsInterval = MinTimeMsInterval;
nb->drop();
return nb;
}
//! Returns type of the scene node
ESCENE_NODE_TYPE CIrrKlangSceneNode::getType() const
{
return (ESCENE_NODE_TYPE)IRRKLANG_SCENE_NODE_ID;
}
void CIrrKlangSceneNode::stop()
{
PlayMode = EPM_NOTHING;
PlayedCount = 0;
if (Sound)
{
Sound->stop();
Sound->drop();
Sound = 0;
}
}
//! Sets the play mode to 'play once', a sound file is played once, and
//! the scene node deletes itself then, if wished.
void CIrrKlangSceneNode::setPlayOnceMode(bool deleteWhenFinished)
{
stop();
PlayMode = EPM_ONCE;
DeleteWhenFinished = deleteWhenFinished;
PlayedCount = 0;
}
//! Sets the play mode to 'looping stream', plays a looped sound over and over again.
void CIrrKlangSceneNode::setLoopingStreamMode()
{
stop();
PlayMode = EPM_LOOPING;
}
//! Sets the play mode to 'random'. Plays a sound with a variable, random interval
//! over and over again.
//! \param minTimeMs: Minimal wait time in milli seconds before the sound is played again.
//! \param maxTimeMs: Maximal wait time in milli seconds before the sound is played again.
void CIrrKlangSceneNode::setRandomMode(int minTimeMs, int maxTimeMs)
{
stop();
PlayMode = EPM_RANDOM;
MinTimeMsInterval = minTimeMs;
MaxTimeMsInterval = maxTimeMs;
}
//! Sets the sound filename to play
void CIrrKlangSceneNode::setSoundFileName(const char* soundFilename)
{
if (soundFilename)
SoundFileName = soundFilename;
else
SoundFileName = "";
}
//! Gets the sound filename to play
const char* CIrrKlangSceneNode::getSoundFileName() const
{
return SoundFileName.c_str();
}
//! Sets the minimal and maximal 3D sound distances
void CIrrKlangSceneNode::setMinMaxSoundDistance(f32 minDistance, f32 maxDistance)
{
MinDistance = minDistance;
MaxDistance = maxDistance;
if (Sound)
{
if (MinDistance > 0)
Sound->setMinDistance(MinDistance);
if (MaxDistance > 0)
Sound->setMaxDistance(MaxDistance);
}
}
// ------------------------------------------------------------------------
// Factory
// ------------------------------------------------------------------------
CIrrKlangSceneNodeFactory::CIrrKlangSceneNodeFactory(irrklang::ISoundEngine* sengine, ISceneManager* mgr)
: Manager(mgr), SoundEngine(sengine)
{
if (SoundEngine)
SoundEngine->grab();
// don't grab the manager here, to avoid cyclic references
}
CIrrKlangSceneNodeFactory::~CIrrKlangSceneNodeFactory()
{
if (SoundEngine)
SoundEngine->drop();
}
//! adds a scene node to the scene graph based on its type id
ISceneNode* CIrrKlangSceneNodeFactory::addSceneNode(ESCENE_NODE_TYPE type, ISceneNode* parent)
{
if (!parent)
parent = Manager->getRootSceneNode();
if (type == IRRKLANG_SCENE_NODE_ID)
{
CIrrKlangSceneNode* node = new CIrrKlangSceneNode(SoundEngine, parent, Manager, -1);
node->drop();
return node;
}
return 0;
}
//! adds a scene node to the scene graph based on its type name
ISceneNode* CIrrKlangSceneNodeFactory::addSceneNode(const c8* typeName, ISceneNode* parent)
{
return addSceneNode( getTypeFromName(typeName), parent );
}
//! returns amount of scene node types this factory is able to create
u32 CIrrKlangSceneNodeFactory::getCreatableSceneNodeTypeCount() const
{
return 1;
}
//! returns type of a createable scene node type
ESCENE_NODE_TYPE CIrrKlangSceneNodeFactory::getCreateableSceneNodeType(u32 idx) const
{
if (idx==0)
return (ESCENE_NODE_TYPE)IRRKLANG_SCENE_NODE_ID;
return ESNT_UNKNOWN;
}
//! returns type name of a createable scene node type
const c8* CIrrKlangSceneNodeFactory::getCreateableSceneNodeTypeName(u32 idx) const
{
if (idx==0)
return irrKlangSceneNodeTypeName;
return 0;
}
//! returns type name of a createable scene node type
const c8* CIrrKlangSceneNodeFactory::getCreateableSceneNodeTypeName(ESCENE_NODE_TYPE type) const
{
if (type == IRRKLANG_SCENE_NODE_ID)
return irrKlangSceneNodeTypeName;
return 0;
}
ESCENE_NODE_TYPE CIrrKlangSceneNodeFactory::getTypeFromName(const c8* name)
{
if (!strcmp(name, irrKlangSceneNodeTypeName))
return (ESCENE_NODE_TYPE)IRRKLANG_SCENE_NODE_ID;
return ESNT_UNKNOWN;
}

View File

@ -0,0 +1,152 @@
#ifndef __IRRKLANG_SCENE_NODE_H_INCLUDED__
#define __IRRKLANG_SCENE_NODE_H_INCLUDED__
// This file contains a scene node for the Irrlicht engine which is able to
// play back sounds and music in 3D. Just place it into 3d space and set
// what sound it should play.
// It uses the free irrKlang sound engine (http://www.ambiera.com/irrklang).
// This file also contains a sound engine factory, CIrrKlangSceneNodeFactory. Just
// register this factory in your scene manager, and you will be able to load and
// save irrKlang scene nodes from and into .irr files:
//
// irrklang::ISoundEngine* soundEngine = createIrrKlangDevice();
// CIrrKlangSceneNodeFactory* factory = new CIrrKlangSceneNodeFactory(soundEngine, sceneManager);
// sceneManager->registerSceneNodeFactory(factory);
// factory->drop();
#include "irrlicht/irrlicht.h"
#include "irrklang/irrKlang.h"
using namespace irr;
using namespace irrklang;
using namespace scene;
//! A scene node for playing 3d audio using the free irrKlang sound engine.
/** Use it like this:
\begincode
irrklang::ISoundEngine* soundEngine = irrklang::createIrrKlangDevice();
IrrlichtDevice* device = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(640, 480), 16, false);
scene::ISceneManager* smgr = device->getSceneManager();
// .. other code here
CIrrKlangSceneNode* soundNode =
new CIrrKlangSceneNode(soundEngine, smgr->getRootSceneNode(), smgr, 666);
soundNode->setSoundFilename("yourfile.wav");
soundNode->setMinMaxSoundDistance(30.0f); // influences the distance where the sound can be heard
soundNode->setRandomMode(1000, 5000); // plays sound multiple times with random interval
// other modes would be:
// soundNode->setLoopingStreamMode()
// or
// soundNode->setPlayOnceMode();
soundNode->drop();
\endcode
*/
class CIrrKlangSceneNode : public scene::ISceneNode
{
public:
CIrrKlangSceneNode(irrklang::ISoundEngine* soundEngine,
scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id);
~CIrrKlangSceneNode();
// play modes:
//! Sets the play mode to 'play once', a sound file is played once, and
//! the scene node deletes itself then, if wished.
void setPlayOnceMode(bool deleteWhenFinished=false);
//! Sets the play mode to 'looping stream', plays a looped sound over and over again.
void setLoopingStreamMode();
//! Sets the play mode to 'random'. Plays a sound with a variable, random interval
//! over and over again.
//! \param minTimeMsInterval: Minimal wait time in milli seconds before the sound is played again.
//! \param maxTimeMsInterval: Maximal wait time in milli seconds before the sound is played again.
void setRandomMode(int minTimeMsInterval=1000, int maxTimeMsInterval=5000);
// Sound parameters
//! Sets the sound filename to play
void setSoundFileName(const char* soundFilename);
//! Gets the sound filename to play
const char* getSoundFileName() const;
//! Sets the minimal and maximal 3D sound distances.
//! Set to negative values if you want to use the default values of the sound engine.
void setMinMaxSoundDistance(f32 minDistance=1.0f, f32 maxDistance=10000000.0f);
//! stops playback, releases sound, sets playmode to 'nothing'
void stop();
// rendering functions:
virtual void OnAnimate(u32 timeMs);
virtual void OnRegisterSceneNode();
virtual void render();
virtual const core::aabbox3d<f32>& getBoundingBox() const;
virtual ESCENE_NODE_TYPE getType() const;
ISceneNode* clone(ISceneNode* newParent, ISceneManager* newManager);
void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const;
void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options);
protected:
enum EPlayMode
{
EPM_NOTHING = 0,
EPM_RANDOM,
EPM_LOOPING,
EPM_ONCE
};
core::aabbox3d<f32> Box;
irrklang::ISoundEngine* SoundEngine;
irrklang::ISound* Sound;
core::stringc SoundFileName;
f32 MinDistance;
f32 MaxDistance;
EPlayMode PlayMode;
u32 TimeMsDelayFinished;
bool DeleteWhenFinished;
s32 MaxTimeMsInterval;
s32 MinTimeMsInterval;
s32 PlayedCount;
};
// own factory implementation to make it possible to load and save irrKlang scene
// nodes fomr and to .irr files. Create an instance of this and use
// ISceneManager::registerSceneNodeFactory() for this.
class CIrrKlangSceneNodeFactory : public ISceneNodeFactory
{
public:
CIrrKlangSceneNodeFactory(irrklang::ISoundEngine* soundEngine, ISceneManager* mgr);
~CIrrKlangSceneNodeFactory();
virtual ISceneNode* addSceneNode(ESCENE_NODE_TYPE type, ISceneNode* parent=0);
virtual ISceneNode* addSceneNode(const c8* typeName, ISceneNode* parent=0);
virtual u32 getCreatableSceneNodeTypeCount() const;
virtual const c8* getCreateableSceneNodeTypeName(u32 idx) const;
virtual ESCENE_NODE_TYPE getCreateableSceneNodeType(u32 idx) const;
virtual const c8* getCreateableSceneNodeTypeName(ESCENE_NODE_TYPE type) const;
private:
ESCENE_NODE_TYPE getTypeFromName(const c8* name);
ISceneManager* Manager;
irrklang::ISoundEngine* SoundEngine;
};
#endif

View File

@ -186,7 +186,7 @@ bool PseuInstance::InitGUI(void)
uint16 x,y,depth;
uint8 driver;
bool shadows,vsync,win;
bool shadows,vsync,win,usesound;
driver=(uint8)atoi(GetScripts()->variables.Get("GUI::DRIVER").c_str());
vsync=(bool)atoi(GetScripts()->variables.Get("GUI::VSYNC").c_str());
@ -195,7 +195,8 @@ bool PseuInstance::InitGUI(void)
y=(uint16)atoi(GetScripts()->variables.Get("GUI::RESY").c_str());
win=(bool)atoi(GetScripts()->variables.Get("GUI::WINDOWED").c_str());
shadows=(bool)atoi(GetScripts()->variables.Get("GUI::SHADOWS").c_str());
log("GUI settings: driver=%u, depth=%u, res=%ux%u, windowed=%u, shadows=%u",driver,depth,x,y,win,shadows);
usesound=(bool)atoi(GetScripts()->variables.Get("GUI::USESOUND").c_str());
log("GUI settings: driver=%u, depth=%u, res=%ux%u, windowed=%u, shadows=%u sound=%u",driver,depth,x,y,win,shadows,usesound);
if(x>0 && y>0 && (depth==16 || depth==32) && driver>0 && driver<=5)
{
PseuGUIRunnable *rgui = new PseuGUIRunnable();
@ -206,6 +207,7 @@ bool PseuInstance::InitGUI(void)
_gui->SetVSync(vsync);
_gui->UseShadows(shadows);
_gui->SetWindowed(win);
_gui->SetUseSound(usesound);
_guithread = new ZThread::Thread(rgui);
return true;
}

View File

@ -45,12 +45,12 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib WS2_32.LIB"
AdditionalDependencies="odbc32.lib odbccp32.lib WS2_32.LIB irrKlang.lib"
ShowProgress="0"
OutputFile="$(OutDir)/$(InputName).exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories=""
AdditionalLibraryDirectories="$(SolutionDir)\src\dep\lib\static"
IgnoreAllDefaultLibraries="FALSE"
IgnoreDefaultLibraryNames="libci.lib"
AssemblyDebug="0"
@ -113,11 +113,11 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib WS2_32.LIB"
AdditionalDependencies="odbc32.lib odbccp32.lib WS2_32.LIB irrKlang.lib"
OutputFile="$(OutDir)/$(InputName)_debug.exe"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories=""
AdditionalLibraryDirectories="$(SolutionDir)\src\dep\lib\static"
IgnoreDefaultLibraryNames="libci.lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(SolutionDir)/temp/$(ProjectName)/PseuWoW.pdb"
@ -492,6 +492,53 @@
<File
RelativePath=".\Client\Gui\TlTSector.h">
</File>
<Filter
Name="irrklang"
Filter="">
<File
RelativePath=".\Client\Gui\CIrrKlangAudioStreamLoaderMP3.cpp">
</File>
<File
RelativePath=".\Client\Gui\CIrrKlangAudioStreamLoaderMP3.h">
</File>
<File
RelativePath=".\Client\Gui\CIrrKlangAudioStreamMP3.cpp">
</File>
<File
RelativePath=".\Client\Gui\CIrrKlangAudioStreamMP3.h">
</File>
<File
RelativePath=".\Client\Gui\ikpMP3.cpp">
</File>
<File
RelativePath=".\Client\Gui\irrKlangSceneNode.cpp">
</File>
<File
RelativePath=".\Client\Gui\irrKlangSceneNode.h">
</File>
<Filter
Name="decoder"
Filter="">
<File
RelativePath=".\Client\Gui\decoder\bits.c">
</File>
<File
RelativePath=".\Client\Gui\decoder\internal.h">
</File>
<File
RelativePath=".\Client\Gui\decoder\mpaudec.c">
</File>
<File
RelativePath=".\Client\Gui\decoder\mpaudec.h">
</File>
<File
RelativePath=".\Client\Gui\decoder\mpaudectab.h">
</File>
<File
RelativePath=".\Client\Gui\decoder\mpegaudio.h">
</File>
</Filter>
</Filter>
</Filter>
</Filter>
<Filter

View File

@ -75,12 +75,12 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib WS2_32.LIB"
AdditionalDependencies="odbc32.lib odbccp32.lib WS2_32.LIB irrKlang.lib"
ShowProgress="0"
OutputFile="$(OutDir)/$(InputName).exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=""
AdditionalLibraryDirectories="$(SolutionDir)\src\dep\lib\static"
IgnoreAllDefaultLibraries="false"
IgnoreDefaultLibraryNames="libci.lib"
AssemblyDebug="0"
@ -170,11 +170,11 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib WS2_32.LIB"
AdditionalDependencies="odbc32.lib odbccp32.lib WS2_32.LIB irrKlang.lib"
OutputFile="$(OutDir)/$(InputName)_debug.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=""
AdditionalLibraryDirectories="$(SolutionDir)\src\dep\lib\static"
IgnoreDefaultLibraryNames="libci.lib"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(SolutionDir)/temp/$(ProjectName)/PseuWoW.pdb"
@ -656,6 +656,56 @@
RelativePath=".\Client\Gui\TlTMesh.h"
>
</File>
<File
RelativePath=".\Client\Gui\TlTSector.h">
</File>
<Filter
Name="irrklang"
Filter="">
<File
RelativePath=".\Client\Gui\CIrrKlangAudioStreamLoaderMP3.cpp">
</File>
<File
RelativePath=".\Client\Gui\CIrrKlangAudioStreamLoaderMP3.h">
</File>
<File
RelativePath=".\Client\Gui\CIrrKlangAudioStreamMP3.cpp">
</File>
<File
RelativePath=".\Client\Gui\CIrrKlangAudioStreamMP3.h">
</File>
<File
RelativePath=".\Client\Gui\ikpMP3.cpp">
</File>
<File
RelativePath=".\Client\Gui\irrKlangSceneNode.cpp">
</File>
<File
RelativePath=".\Client\Gui\irrKlangSceneNode.h">
</File>
<Filter
Name="decoder"
Filter="">
<File
RelativePath=".\Client\Gui\decoder\bits.c">
</File>
<File
RelativePath=".\Client\Gui\decoder\internal.h">
</File>
<File
RelativePath=".\Client\Gui\decoder\mpaudec.c">
</File>
<File
RelativePath=".\Client\Gui\decoder\mpaudec.h">
</File>
<File
RelativePath=".\Client\Gui\decoder\mpaudectab.h">
</File>
<File
RelativePath=".\Client\Gui\decoder\mpegaudio.h">
</File>
</Filter>
</Filter>
</Filter>
</Filter>
<Filter

View File

@ -0,0 +1,78 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __E_IRRKLANG_SOUND_ENGINE_OPTIONS_H_INCLUDED__
#define __E_IRRKLANG_SOUND_ENGINE_OPTIONS_H_INCLUDED__
namespace irrklang
{
//! An enumeration for all options for starting up the sound engine
/** When using createIrrKlangDevice, use a combination of this these
as 'options' parameter to start up the engine. By default, irrKlang
uses ESEO_DEFAULT_OPTIONS, which is set to the combination
ESEO_MULTI_THREADED | ESEO_LOAD_PLUGINS | ESEO_USE_3D_BUFFERS | ESEO_PRINT_DEBUG_INFO_TO_DEBUGGER | ESEO_PRINT_DEBUG_INFO_TO_STDOUT. */
enum E_SOUND_ENGINE_OPTIONS
{
//! If specified (default), it will make irrKlang run in a separate thread.
/** Using this flag, irrKlang will update
all streams, sounds, 3d positions and whatever automaticly. You also don't need to call ISoundEngine::update()
if irrKlang is running multithreaded. However, if you want to run irrKlang in the same thread
as your application (for easier debugging for example), don't set this. But you need to call ISoundEngine::update()
as often as you can (at least about 2-3 times per second) to make irrKlang update everything correctly then. */
ESEO_MULTI_THREADED = 0x01,
//! If the window of the application doesn't have the focus, irrKlang will be silent if this has been set.
/** This will only work when irrKlang is using the DirectSound output driver. */
ESEO_MUTE_IF_NOT_FOCUSED = 0x02,
//! Automaticly loads external plugins when starting up.
/** Plugins usually are .dll, .so or .dylib
files named for example ikpMP3.dll (= short for irrKlangPluginMP3) which are executed
after the startup of the sound engine and modify it for example to make it possible
to play back mp3 files. Plugins are being loaded from the current working directory
as well as from the position where the .exe using the irrKlang library resides.
It is also possible to load the plugins after the engine has started up using
ISoundEngine::loadPlugins(). */
ESEO_LOAD_PLUGINS = 0x04,
//! Uses 3D sound buffers instead of emulating them when playing 3d sounds (default).
/** If this flag is not specified, all buffers will by created
in 2D only and 3D positioning will be emulated in software, making the engine run
faster if hardware 3d audio is slow on the system. */
ESEO_USE_3D_BUFFERS = 0x08,
//! Prints debug messages to the debugger window.
/** irrKlang will print debug info and status messages to any windows debugger supporting
OutputDebugString() (like VisualStudio).
This is useful if your application does not capture any console output (see ESEO_PRINT_DEBUG_INFO_TO_STDOUT). */
ESEO_PRINT_DEBUG_INFO_TO_DEBUGGER = 0x10,
//! Prints debug messages to stdout (the ConsoleWindow).
/** irrKlang will print debug info and status messages stdout, the console window in Windows. */
ESEO_PRINT_DEBUG_INFO_TO_STDOUT = 0x20,
//! Uses linear rolloff for 3D sound.
/** If specified, instead of the default logarithmic one, irrKlang will
use a linear rolloff model which influences the attenuation
of the sounds over distance. The volume is interpolated linearly between the MinDistance
and MaxDistance, making it possible to adjust sounds more easily although this is not
physically correct.
Note that this option may not work when used together with the ESEO_USE_3D_BUFFERS
option when using Direct3D for example, irrKlang will then turn off ESEO_USE_3D_BUFFERS
automaticly to be able to use this option and write out a warning. */
ESEO_LINEAR_ROLLOFF = 0x40,
//! Default parameters when starting up the engine.
ESEO_DEFAULT_OPTIONS = ESEO_MULTI_THREADED | ESEO_LOAD_PLUGINS | ESEO_USE_3D_BUFFERS | ESEO_PRINT_DEBUG_INFO_TO_DEBUGGER | ESEO_PRINT_DEBUG_INFO_TO_STDOUT,
//! Never used, it only forces the compiler to compile these enumeration values to 32 bit.
/** Don't use this. */
ESEO_FORCE_32_BIT = 0x7fffffff
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,56 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __E_IRRKLANG_SOUND_OUTPUT_DRIVERS_H_INCLUDED__
#define __E_IRRKLANG_SOUND_OUTPUT_DRIVERS_H_INCLUDED__
namespace irrklang
{
//! An enumeration for all types of supported sound drivers
/** Values of this enumeration can be used as parameter when calling createIrrKlangDevice(). */
enum E_SOUND_OUTPUT_DRIVER
{
//! Autodetects the best sound driver for the system
ESOD_AUTO_DETECT = 0,
//! DirectSound8 sound output driver, windows only.
/** In contrast to ESOD_DIRECT_SOUND, this supports sophisticated sound effects
but may not be available on old windows versions. It behaves very similar
to ESOD_DIRECT_SOUND but also supports DX8 sound effects.*/
ESOD_DIRECT_SOUND_8,
//! DirectSound sound output driver, windows only.
/* This uses DirectSound 3 or above, if available. If DX8 sound effects
are needed, use ESOD_DIRECT_SOUND_8 instead. The
ESOD_DIRECT_SOUND driver may be available on more and older windows
versions than ESOD_DIRECT_SOUND_8.*/
ESOD_DIRECT_SOUND,
//! WinMM sound output driver, windows only.
ESOD_WIN_MM,
//! ALSA sound output driver, linux only.
/* When using ESOD_ALSA in createIrrKlangDevice(), it is possible to set the third parameter,
'deviceID' to the name of specific ALSA pcm device, to the irrKlang force to use this one.
Set it to 'default', or 'plug:hw' or whatever you need it to be.*/
ESOD_ALSA,
//! Core Audio sound output driver, mac os only.
ESOD_CORE_AUDIO,
//! Null driver, creating no sound output
ESOD_NULL,
//! Amount of built-in sound output drivers
ESOD_COUNT,
//! This enumeration literal is never used, it only forces the compiler to
//! compile these enumeration values to 32 bit.
ESOD_FORCE_32_BIT = 0x7fffffff
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,31 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __E_IRRKLANG_STREAM_MODES_H_INCLUDED__
#define __E_IRRKLANG_STREAM_MODES_H_INCLUDED__
namespace irrklang
{
//! An enumeration for all types of supported stream modes
enum E_STREAM_MODE
{
//! Autodetects the best stream mode for a specified audio data.
ESM_AUTO_DETECT = 0,
//! Streams the audio data when needed.
ESM_STREAMING,
//! Loads the whole audio data into the memory.
ESM_NO_STREAMING,
//! This enumeration literal is never used, it only forces the compiler to
//! compile these enumeration values to 32 bit.
ESM_FORCE_32_BIT = 0x7fffffff
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,104 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_AUDIO_RECORDER_H_INCLUDED__
#define __I_IRRKLANG_AUDIO_RECORDER_H_INCLUDED__
#include "ik_IRefCounted.h"
#include "ik_ISoundSource.h"
namespace irrklang
{
class ICapturedAudioDataReceiver;
//! Interface to an audio recorder. Create it using the createIrrKlangAudioRecorder() function.
/** It creates sound sources into an ISoundEngine which then can be played there.
See @ref recordingAudio for an example on how to use this. */
class IAudioRecorder : public virtual IRefCounted
{
public:
//! Starts recording audio.
/** Clears all possibly previously recorded buffered audio data and starts to record.
When finished recording audio data, call stopRecordingAudio().
All recorded audio data gets stored into an internal audio buffer, which
can then be accessed for example using addSoundSourceFromRecordedAudio() or
getRecordedAudioData(). For recording audio data not into an internal audio
buffer, use startRecordingCustomHandledAudio().
\param sampleRate: Sample rate of the recorded audio.
\param sampleFormat: Sample format of the recorded audio.
\return Returns true if successfully started recording and false if not.*/
virtual bool startRecordingBufferedAudio(ik_s32 sampleRate=22000, ESampleFormat sampleFormat=ESF_S16) = 0;
//! Starts recording audio.
/** Clears all possibly previously recorded buffered audio data and starts to record
audio data, which is delivered to a custom user callback interface.
When finished recording audio data, call stopRecordingAudio(). If instead of
recording the data to the receiver interface recording into a managed buffer
is wished, use startRecordingBufferedAudio() instead.
\param receiver: Interface to be implemented by the user, gets called once for each
captured audio data chunk.
\param sampleRate: Sample rate of the recorded audio.
\param sampleFormat: Sample format of the recorded audio.
\return Returns true if successfully started recording and false if not. */
virtual bool startRecordingCustomHandledAudio(ICapturedAudioDataReceiver* receiver,
ik_s32 sampleRate=22000, ESampleFormat sampleFormat=ESF_S16) = 0;
//! Stops recording audio.
virtual void stopRecordingAudio() = 0;
//! Creates a sound source for the recorded audio data.
/** The returned sound source pointer then can be used to play back the recorded audio data
using ISoundEngine::play2D(). This method only will succeed if the audio was recorded using
startRecordingBufferedAudio() and audio recording is currently stopped.
\param soundName Name of the virtual sound file (e.g. "someRecordedAudio"). You can also use this
name when calling play3D() or play2D(). */
virtual ISoundSource* addSoundSourceFromRecordedAudio(const char* soundName) = 0;
//! Clears recorded audio data buffer, freeing memory.
/** This method will only succeed if audio recording is currently stopped. */
virtual void clearRecordedAudioDataBuffer() = 0;
//! Returns if the recorder is currently recording audio.
virtual bool isRecording() = 0;
//! Returns the audio format of the recorded audio data.
/** Also contains informations about the length of the recorded audio stream. */
virtual SAudioStreamFormat getAudioFormat() = 0;
//! Returns a pointer to the recorded audio data.
/** This method will only succeed if audio recording is currently stopped and
something was recorded previously using startRecordingBufferedAudio().
The lenght of the buffer can be retrieved using
getAudioFormat().getSampleDataSize(). Note that the pointer is only valid
as long as not clearRecordedAudioDataBuffer() is called or another sample is
recorded.*/
virtual void* getRecordedAudioData() = 0;
//! returns the name of the sound driver, like 'ALSA' for the alsa device.
/** Possible returned strings are "NULL", "ALSA", "CoreAudio", "winMM",
"DirectSound" and "DirectSound8". */
virtual const char* getDriverName() = 0;
};
//! Interface to be implemented by the user if access to the recorded audio data is needed.
/** Is used as parameter in IAudioRecorder::startRecordingCustomHandledAudio. */
class ICapturedAudioDataReceiver : public IRefCounted
{
public:
//! Gets called once for each captured audio data chunk.
/** See IAudioRecorder::startRecordingCustomHandledAudio for details.
\param audioData: Pointer to a part of the recorded audio data
\param lengthInBytes: Amount of bytes in the audioData buffer.*/
virtual void OnReceiveAudioDataStreamChunk(unsigned char* audioData, unsigned long lengthInBytes) = 0;
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,49 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_AUDIO_STREAM_H_INCLUDED__
#define __I_IRRKLANG_AUDIO_STREAM_H_INCLUDED__
#include "ik_IRefCounted.h"
#include "ik_SAudioStreamFormat.h"
namespace irrklang
{
//! Reads and decodes audio data into an usable audio stream for the ISoundEngine
class IAudioStream : public IRefCounted
{
public:
//! destructor
virtual ~IAudioStream() {};
//! returns format of the audio stream
virtual SAudioStreamFormat getFormat() = 0;
//! sets the position of the audio stream.
/** For example to let the stream be read from the beginning of the file again,
setPosition(0) would be called. This is usually done be the sound engine to
loop a stream after if has reached the end. Return true if sucessful and 0 if not.
\param pos: Position in frames.*/
virtual bool setPosition(ik_s32 pos) = 0;
//! returns true if the audio stream is seekable
/* Some file formats like (MODs) don't support seeking */
virtual bool getIsSeekingSupported() { return true; }
//! tells the audio stream to read frameCountToRead audio frames into the specified buffer
/** \param target: Target data buffer to the method will write the read frames into. The
specified buffer will be at least getFormat().getFrameSize()*frameCountToRead bytes big.
\param frameCountToRead: amount of frames to be read.
\returns Returns amount of frames really read. Should be frameCountToRead in most cases. */
virtual ik_s32 readFrames(void* target, ik_s32 frameCountToRead) = 0;
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,40 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_AUDIO_STREAM_LOADER_H_INCLUDED__
#define __I_IRRKLANG_AUDIO_STREAM_LOADER_H_INCLUDED__
#include "ik_IRefCounted.h"
#include "ik_IFileReader.h"
namespace irrklang
{
class IAudioStream;
//! Class which is able to create an audio file stream from a file.
class IAudioStreamLoader : public IRefCounted
{
public:
//! destructor
virtual ~IAudioStreamLoader() {};
//! Returns true if the file maybe is able to be loaded by this class.
/** This decision should be based only on the file extension (e.g. ".wav"). The given
filename string is guaranteed to be lower case. */
virtual bool isALoadableFileExtension(const ik_c8* fileName) = 0;
//! Creates an audio file input stream from a file
/** \return Pointer to the created audio stream. Returns 0 if loading failed.
If you no longer need the stream, you should call IAudioFileStream::drop().
See IRefCounted::drop() for more information. */
virtual IAudioStream* createAudioStream(IFileReader* file) = 0;
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,41 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_FILE_FACTORY_H_INCLUDED__
#define __I_IRRKLANG_FILE_FACTORY_H_INCLUDED__
#include "ik_IRefCounted.h"
namespace irrklang
{
class IFileReader;
//! Interface to overwrite file access in irrKlang.
/** Derive your own class from IFileFactory, overwrite the createFileReader()
method and return your own implemented IFileReader to overwrite file access of irrKlang.
Use ISoundEngine::addFileFactory() to let irrKlang know about your class.
Example code can be found in the tutorial 04.OverrideFileAccess.
*/
class IFileFactory : public virtual IRefCounted
{
public:
virtual ~IFileFactory() {};
//! Opens a file for read access.
/** Derive your own class from IFileFactory, overwrite this
method and return your own implemented IFileReader to overwrite file access of irrKlang.
Use ISoundEngine::addFileFactory() to let irrKlang know about your class.
Example code can be found in the tutorial 04.OverrideFileAccess.
\param filename Name of file to open.
\return Returns a pointer to the created file interface.
The returned pointer should be dropped when no longer needed.
See IRefCounted::drop() for more information. Returns 0 if file cannot be opened. */
virtual IFileReader* createFileReader(const ik_c8* filename) = 0;
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,50 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_READ_FILE_H_INCLUDED__
#define __I_IRRKLANG_READ_FILE_H_INCLUDED__
#include "ik_IRefCounted.h"
namespace irrklang
{
//! Interface providing read acess to a file.
class IFileReader : public virtual IRefCounted
{
public:
virtual ~IFileReader() {};
//! Reads an amount of bytes from the file.
//! \param buffer: Pointer to buffer where to read bytes will be written to.
//! \param sizeToRead: Amount of bytes to read from the file.
//! \return Returns how much bytes were read.
virtual ik_s32 read(void* buffer, ik_u32 sizeToRead) = 0;
//! Changes position in file, returns true if successful.
//! \param finalPos: Destination position in the file.
//! \param relativeMovement: If set to true, the position in the file is
//! changed relative to current position. Otherwise the position is changed
//! from beginning of file.
//! \return Returns true if successful, otherwise false.
virtual bool seek(ik_s32 finalPos, bool relativeMovement = false) = 0;
//! Returns size of file.
//! \return Returns the size of the file in bytes.
virtual ik_s32 getSize() = 0;
//! Returns the current position in the file.
//! \return Returns the current position in the file in bytes.
virtual ik_s32 getPos() = 0;
//! Returns name of file.
//! \return Returns the file name as zero terminated character string.
virtual const ik_c8* getFileName() = 0;
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,131 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_IREFERENCE_COUNTED_H_INCLUDED__
#define __I_IRRKLANG_IREFERENCE_COUNTED_H_INCLUDED__
#include "ik_irrKlangTypes.h"
namespace irrklang
{
//! Base class of most objects of the irrKlang.
/** This class provides reference counting through the methods grab() and drop().
It also is able to store a debug string for every instance of an object.
Most objects of irrKlang are derived from IRefCounted, and so they are reference counted.
When you create an object in irrKlang, calling a method
which starts with 'create', an object is created, and you get a pointer
to the new object. If you no longer need the object, you have
to call drop(). This will destroy the object, if grab() was not called
in another part of you program, because this part still needs the object.
Note, that you only need to call drop() to the object, if you created it,
and the method had a 'create' in it.
A simple example:
If you want to create a texture, you may want to call an imaginable method
IDriver::createTexture. You call
ITexture* texture = driver->createTexture(128, 128);
If you no longer need the texture, call texture->drop().
If you want to load a texture, you may want to call imaginable method
IDriver::loadTexture. You do this like
ITexture* texture = driver->loadTexture("example.jpg");
You will not have to drop the pointer to the loaded texture, because
the name of the method does not start with 'create'. The texture
is stored somewhere by the driver.
*/
class IRefCounted
{
public:
//! Constructor.
IRefCounted()
: ReferenceCounter(1)
{
}
//! Destructor.
virtual ~IRefCounted()
{
}
//! Grabs the object. Increments the reference counter by one.
//! Someone who calls grab() to an object, should later also call
//! drop() to it. If an object never gets as much drop() as grab()
//! calls, it will never be destroyed.
//! The IRefCounted class provides a basic reference counting mechanism
//! with its methods grab() and drop(). Most objects of irrklang
//! are derived from IRefCounted, and so they are reference counted.
//!
//! When you create an object in irrKlang, calling a method
//! which starts with 'create', an object is created, and you get a pointer
//! to the new object. If you no longer need the object, you have
//! to call drop(). This will destroy the object, if grab() was not called
//! in another part of you program, because this part still needs the object.
//! Note, that you only need to call drop() to the object, if you created it,
//! and the method had a 'create' in it.
//!
//! A simple example:
//!
//! If you want to create a texture, you may want to call an imaginable method
//! IDriver::createTexture. You call
//! ITexture* texture = driver->createTexture(128, 128);
//! If you no longer need the texture, call texture->drop().
//! If you want to load a texture, you may want to call imaginable method
//! IDriver::loadTexture. You do this like
//! ITexture* texture = driver->loadTexture("example.jpg");
//! You will not have to drop the pointer to the loaded texture, because
//! the name of the method does not start with 'create'. The texture
//! is stored somewhere by the driver.
void grab() { ++ReferenceCounter; }
//! Drops the object. Decrements the reference counter by one.
//! Returns true, if the object was deleted.
//! The IRefCounted class provides a basic reference counting mechanism
//! with its methods grab() and drop(). Most objects of irrKlang
//! Engine are derived from IRefCounted, and so they are reference counted.
//!
//! When you create an object in irrKlang, calling a method
//! which starts with 'create', an object is created, and you get a pointer
//! to the new object. If you no longer need the object, you have
//! to call drop(). This will destroy the object, if grab() was not called
//! in another part of you program, because this part still needs the object.
//! Note, that you only need to call drop() to the object, if you created it,
//! and the method had a 'create' in it.
//!
//! A simple example:
//!
//! If you want to create a texture, you may want to call an imaginable method
//! IDriver::createTexture. You call
//! ITexture* texture = driver->createTexture(128, 128);
//! If you no longer need the texture, call texture->drop().
//! If you want to load a texture, you may want to call imaginable method
//! IDriver::loadTexture. You do this like
//! ITexture* texture = driver->loadTexture("example.jpg");
//! You will not have to drop the pointer to the loaded texture, because
//! the name of the method does not start with 'create'. The texture
//! is stored somewhere by the driver.
bool drop()
{
--ReferenceCounter;
if (!ReferenceCounter)
{
delete this;
return true;
}
return false;
}
private:
ik_s32 ReferenceCounter;
};
} // end namespace irr
#endif

View File

@ -0,0 +1,193 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_SOUND_H_INCLUDED__
#define __I_IRRKLANG_SOUND_H_INCLUDED__
#include "ik_IVirtualRefCounted.h"
#include "ik_ISoundEffectControl.h"
#include "ik_vec3d.h"
namespace irrklang
{
class ISoundSource;
class ISoundStopEventReceiver;
//! Represents a sound which is currently played.
/** The sound can be stopped, its volume or pan changed, effects added/removed
and similar using this interface.
Creating sounds is done using ISoundEngine::play2D() or ISoundEngine::play3D().
More informations about the source of a sound can be obtained from the ISoundSource
interface. */
class ISound : public IVirtualRefCounted
{
public:
//! returns source of the sound which stores the filename and other informations about that sound
/** \return Returns the sound source poitner of this sound. May return 0 if the sound source
has been removed.*/
virtual ISoundSource* getSoundSource() = 0;
//! returns if the sound is paused
virtual void setIsPaused( bool paused = true) = 0;
//! returns if the sound is paused
virtual bool getIsPaused() = 0;
//! Will stop the sound and free its resources.
/** If you just want to pause the sound, use setIsPaused().
After calling stop(), isFinished() will usually return true. */
virtual void stop() = 0;
//! returns volume of the sound, a value between 0 (mute) and 1 (full volume).
/** (this volume gets multiplied with the master volume of the sound engine
and other parameters like distance to listener when played as 3d sound) */
virtual ik_f32 getVolume() = 0;
//! sets the volume of the sound, a value between 0 (mute) and 1 (full volume).
/** This volume gets multiplied with the master volume of the sound engine
and other parameters like distance to listener when played as 3d sound. */
virtual void setVolume(ik_f32 volume) = 0;
//! sets the pan of the sound. Takes a value between -1 and 1, 0 is center.
virtual void setPan(ik_f32 pan) = 0;
//! returns the pan of the sound. Takes a value between -1 and 1, 0 is center.
virtual ik_f32 getPan() = 0;
//! returns if the sound has been started to play looped
virtual bool isLooped() = 0;
//! changes the loop mode of the sound.
/** If the sound is playing looped and it is changed to not-looped, then it
will stop playing after the loop has finished.
If it is not looped and changed to looped, the sound will start repeating to be
played when it reaches its end.
Invoking this method will not have an effect when the sound already has stopped. */
virtual void setIsLooped(bool looped) = 0;
//! returns if the sound has finished playing.
/** Don't mix this up with isPaused(). isFinished() returns if the sound has been
finished playing. If it has, is maybe already have been removed from the playing list of the
sound engine and calls to any other of the methods of ISound will not have any result.
If you call stop() to a playing sound will result that this function will return true
when invoked. */
virtual bool isFinished() = 0;
//! Sets the minimal distance if this is a 3D sound.
/** Changes the distance at which the 3D sound stops getting louder. This works
like this: As a listener approaches a 3D sound source, the sound gets louder.
Past a certain point, it is not reasonable for the volume to continue to increase.
Either the maximum (zero) has been reached, or the nature of the sound source
imposes a logical limit. This is the minimum distance for the sound source.
Similarly, the maximum distance for a sound source is the distance beyond
which the sound does not get any quieter.
The default minimum distance is 1, the default max distance is a huge number like 1000000000.0f. */
virtual void setMinDistance(ik_f32 min) = 0;
//! Returns the minimal distance if this is a 3D sound.
/** See setMinDistance() for details. */
virtual ik_f32 getMinDistance() = 0;
//! Sets the maximal distance if this is a 3D sound.
/** Changing this value is usually not necessary. Use setMinDistance() instead.
Don't change this value if you don't know what you are doing: This value causes the sound
to stop attenuating after it reaches the max distance. Most people think that this sets the
volume of the sound to 0 after this distance, but this is not true. Only change the
minimal distance (using for example setMinDistance()) to influence this.
The maximum distance for a sound source is the distance beyond which the sound does not get any quieter.
The default minimum distance is 1, the default max distance is a huge number like 1000000000.0f. */
virtual void setMaxDistance(ik_f32 max) = 0;
//! Returns the maximal distance if this is a 3D sound.
/** See setMaxDistance() for details. */
virtual ik_f32 getMaxDistance() = 0;
//! sets the position of the sound in 3d space
virtual void setPosition(vec3df position) = 0;
//! returns the position of the sound in 3d space
virtual vec3df getPosition() = 0;
//! sets the position of the sound in 3d space, needed for Doppler effects.
/** To use doppler effects use ISound::setVelocity to set a sounds velocity,
ISoundEngine::setListenerPosition() to set the listeners velocity and
ISoundEngine::setDopplerEffectParameters() to adjust two parameters influencing
the doppler effects intensity. */
virtual void setVelocity(vec3df vel) = 0;
//! returns the velocity of the sound in 3d space, needed for Doppler effects.
/** To use doppler effects use ISound::setVelocity to set a sounds velocity,
ISoundEngine::setListenerPosition() to set the listeners velocity and
ISoundEngine::setDopplerEffectParameters() to adjust two parameters influencing
the doppler effects intensity. */
virtual vec3df getVelocity() = 0;
//! returns the current play position of the sound in milliseconds.
/** \return Returns -1 if not implemented or possible for this sound for example
because it already has been stopped and freed internally or similar. */
virtual ik_u32 getPlayPosition() = 0;
//! sets the current play position of the sound in milliseconds.
/** \param pos Position in milliseconds. Must be between 0 and the value returned
by getPlayPosition().
\return Returns true successful. False is returned for example if the sound already finished
playing and is stopped or the audio source is not seekable, for example if it
is an internet stream or a a file format not supporting seeking (a .MOD file for example).
A file can be tested if it can bee seeking using ISoundSource::getIsSeekingSupported(). */
virtual bool setPlayPosition(ik_u32 pos) = 0;
//! Sets the playback speed (frequency) of the sound.
/** Plays the sound at a higher or lower speed, increasing or decreasing its
frequency which makes it sound lower or higher.
Note that this feature is not available on all sound output drivers (it is on the
DirectSound drivers at least), and it does not work together with the
'enableSoundEffects' parameter of ISoundEngine::play2D and ISoundEngine::play3D when
using DirectSound.
\param speed Factor of the speed increase or decrease. 2 is twice as fast,
0.5 is only half as fast. The default is 1.0.
\return Returns true if sucessful, false if not. The current sound driver might not
support changing the playBack speed, or the sound was started with the
'enableSoundEffects' parameter. */
virtual bool setPlaybackSpeed(ik_f32 speed = 1.0f) = 0;
//! Returns the playback speed set by setPlaybackSpeed(). Default: 1.0f.
/** See setPlaybackSpeed() for details */
virtual ik_f32 getPlaybackSpeed() = 0;
//! returns the play length of the sound in milliseconds.
/** Returns -1 if not known for this sound for example because its decoder
does not support length reporting or it is a file stream of unknown size.
Note: You can also use ISoundSource::getPlayLength() to get the length of
a sound without actually needing to play it. */
virtual ik_u32 getPlayLength() = 0;
//! Returns the sound effect control interface for this sound.
/** Sound effects such as Chorus, Distorsions, Echo, Reverb and similar can
be controlled using this. The interface pointer is only valid as long as the ISound pointer is valid.
If the ISound pointer gets dropped (IVirtualRefCounted::drop()), the ISoundEffects
may not be used any more.
\return Returns a pointer to the sound effects interface if available. The sound
has to be started via ISoundEngine::play2D() or ISoundEngine::play3D(),
with the flag enableSoundEffects=true, otherwise 0 will be returned. Note that
if the output driver does not support sound effects, 0 will be returned as well.*/
virtual ISoundEffectControl* getSoundEffectControl() = 0;
//! Sets the sound stop event receiver, an interface which gets called if a sound has finished playing.
/** This event is guaranteed to be called when the sound or sound stream is finished,
either because the sound reached its playback end, its sound source was removed,
ISoundEngine::stopAllSounds() has been called or the whole engine was deleted.
There is an example on how to use events in irrklang at @ref events .
\param receiver Interface to a user implementation of the sound receiver. This interface
should be as long valid as the sound exists or another stop event receiver is set.
Set this to null to set no sound stop event receiver.
\param userData: A iser data pointer, can be null. */
virtual void setSoundStopEventReceiver(ISoundStopEventReceiver* reciever, void* userData=0) = 0;
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,41 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_SOUND_DEVICE_LIST_H_INCLUDED__
#define __I_IRRKLANG_SOUND_DEVICE_LIST_H_INCLUDED__
#include "ik_IRefCounted.h"
namespace irrklang
{
//! A list of sound devices for a sound driver. Use irrklang::createSoundDeviceList() to create this list.
/** The function createIrrKlangDevice() has a parameter 'deviceID' which takes the value returned by
ISoundDeviceList::getDeviceID() and uses that device then.
The list of devices in ISoundDeviceList usually also includes the default device which is the first
entry and has an empty deviceID string ("") and the description "default device".
There is some example code on how to use the ISoundDeviceList in @ref enumeratingDevices.*/
class ISoundDeviceList : public IRefCounted
{
public:
//! Returns amount of enumerated devices in the list.
virtual ik_s32 getDeviceCount() = 0;
//! Returns the ID of the device. Use this string to identify this device in createIrrKlangDevice().
/** \param index Index of the device, a value between 0 and ISoundDeviceList::getDeviceCount()-1.
\return Returns a pointer to a string identifying the device. The string will only as long valid
as long as the ISoundDeviceList exists. */
virtual const char* getDeviceID(ik_s32 index) = 0;
//! Returns description of the device.
/** \param index Index of the device, a value between 0 and ISoundDeviceList::getDeviceCount()-1. */
virtual const char* getDeviceDescription(ik_s32 index) = 0;
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,243 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_SOUND_EFFECT_CONTROL_H_INCLUDED__
#define __I_IRRKLANG_SOUND_EFFECT_CONTROL_H_INCLUDED__
#include "ik_IVirtualRefCounted.h"
#include "ik_vec3d.h"
namespace irrklang
{
//! Interface to control the active sound effects (echo, reverb,...) of an ISound object, a playing sound.
/** Sound effects such as chorus, distorsions, echo, reverb and similar can
be controlled using this. An instance of this interface can be obtained via
ISound::getSoundEffectControl(). The sound containing this interface has to be started via
ISoundEngine::play2D() or ISoundEngine::play3D() with the flag enableSoundEffects=true,
otherwise no acccess to this interface will be available.
For the DirectSound driver, these are effects available since DirectSound8. For most
effects, sounds should have a sample rate of 44 khz and should be at least
150 milli seconds long for optimal quality when using the DirectSound driver.
Note that the interface pointer is only valid as long as
the ISound pointer is valid. If the ISound pointer gets dropped (IVirtualRefCounted::drop()),
the ISoundEffects may not be used any more. */
class ISoundEffectControl
{
public:
//! Disables all active sound effects
virtual void disableAllEffects() = 0;
//! Enables the chorus sound effect or adjusts its values.
/** Chorus is a voice-doubling effect created by echoing the
original sound with a slight delay and slightly modulating the delay of the echo.
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
\param fWetDryMix Ratio of wet (processed) signal to dry (unprocessed) signal. Minimal Value:0, Maximal Value:100.0f;
\param fDepth Percentage by which the delay time is modulated by the low-frequency oscillator, in hundredths of a percentage point. Minimal Value:0, Maximal Value:100.0f;
\param fFeedback Percentage of output signal to feed back into the effect's input. Minimal Value:-99, Maximal Value:99.0f;
\param fFrequency Frequency of the LFO. Minimal Value:0, Maximal Value:10.0f;
\param sinusWaveForm True for sinus wave form, false for triangle.
\param fDelay Number of milliseconds the input is delayed before it is played back. Minimal Value:0, Maximal Value:20.0f;
\param lPhase Phase differential between left and right LFOs. Possible values:
-180, -90, 0, 90, 180
\return Returns true if successful. */
virtual bool enableChorusSoundEffect(ik_f32 fWetDryMix = 50,
ik_f32 fDepth = 10,
ik_f32 fFeedback = 25,
ik_f32 fFrequency = 1.1,
bool sinusWaveForm = true,
ik_f32 fDelay = 16,
ik_s32 lPhase = 90) = 0;
//! removes the sound effect from the sound
virtual void disableChorusSoundEffect() = 0;
//! returns if the sound effect is active on the sound
virtual bool isChorusSoundEffectEnabled() = 0;
//! Enables the Compressor sound effect or adjusts its values.
/** Compressor is a reduction in the fluctuation of a signal above a certain amplitude.
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
\param fGain Output gain of signal after Compressor. Minimal Value:-60, Maximal Value:60.0f;
\param fAttack Time before Compressor reaches its full value. Minimal Value:0.01, Maximal Value:500.0f;
\param fRelease Speed at which Compressor is stopped after input drops below fThreshold. Minimal Value:50, Maximal Value:3000.0f;
\param fThreshold Point at which Compressor begins, in decibels. Minimal Value:-60, Maximal Value:0.0f;
\param fRatio Compressor ratio. Minimal Value:1, Maximal Value:100.0f;
\param fPredelay Time after lThreshold is reached before attack phase is started, in milliseconds. Minimal Value:0, Maximal Value:4.0f;
\return Returns true if successful. */
virtual bool enableCompressorSoundEffect( ik_f32 fGain = 0,
ik_f32 fAttack = 10,
ik_f32 fRelease = 200,
ik_f32 fThreshold = -20,
ik_f32 fRatio = 3,
ik_f32 fPredelay = 4) = 0;
//! removes the sound effect from the sound
virtual void disableCompressorSoundEffect() = 0;
//! returns if the sound effect is active on the sound
virtual bool isCompressorSoundEffectEnabled() = 0;
//! Enables the Distortion sound effect or adjusts its values.
/** Distortion is achieved by adding harmonics to the signal in such a way that,
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
as the level increases, the top of the waveform becomes squared off or clipped.
\param fGain Amount of signal change after distortion. Minimal Value:-60, Maximal Value:0;
\param fEdge Percentage of distortion intensity. Minimal Value:0, Maximal Value:100;
\param fPostEQCenterFrequency Center frequency of harmonic content addition. Minimal Value:100, Maximal Value:8000;
\param fPostEQBandwidth Width of frequency band that determines range of harmonic content addition. Minimal Value:100, Maximal Value:8000;
\param fPreLowpassCutoff Filter cutoff for high-frequency harmonics attenuation. Minimal Value:100, Maximal Value:8000;
\return Returns true if successful. */
virtual bool enableDistortionSoundEffect(ik_f32 fGain = -18,
ik_f32 fEdge = 15,
ik_f32 fPostEQCenterFrequency = 2400,
ik_f32 fPostEQBandwidth = 2400,
ik_f32 fPreLowpassCutoff = 8000) = 0;
//! removes the sound effect from the sound
virtual void disableDistortionSoundEffect() = 0;
//! returns if the sound effect is active on the sound
virtual bool isDistortionSoundEffectEnabled() = 0;
//! Enables the Echo sound effect or adjusts its values.
/** An echo effect causes an entire sound to be repeated after a fixed delay.
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
\param fWetDryMix Ratio of wet (processed) signal to dry (unprocessed) signal. Minimal Value:0, Maximal Value:100.0f;
\param fFeedback Percentage of output fed back into input. Minimal Value:0, Maximal Value:100.0f;
\param fLeftDelay Delay for left channel, in milliseconds. Minimal Value:1, Maximal Value:2000.0f;
\param fRightDelay Delay for right channel, in milliseconds. Minimal Value:1, Maximal Value:2000.0f;
\param lPanDelay Value that specifies whether to swap left and right delays with each successive echo. Minimal Value:0, Maximal Value:1;
\return Returns true if successful. */
virtual bool enableEchoSoundEffect(ik_f32 fWetDryMix = 50,
ik_f32 fFeedback = 50,
ik_f32 fLeftDelay = 500,
ik_f32 fRightDelay = 500,
ik_s32 lPanDelay = 0) = 0;
//! removes the sound effect from the sound
virtual void disableEchoSoundEffect() = 0;
//! returns if the sound effect is active on the sound
virtual bool isEchoSoundEffectEnabled() = 0;
//! Enables the Flanger sound effect or adjusts its values.
/** Flange is an echo effect in which the delay between the original
signal and its echo is very short and varies over time. The result is
sometimes referred to as a sweeping sound. The term flange originated
with the practice of grabbing the flanges of a tape reel to change the speed.
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
\param fWetDryMix Ratio of wet (processed) signal to dry (unprocessed) signal. Minimal Value:0, Maximal Value:100.0f;
\param fDepth Percentage by which the delay time is modulated by the low-frequency oscillator, in hundredths of a percentage point. Minimal Value:0, Maximal Value:100.0f;
\param fFeedback Percentage of output signal to feed back into the effect's input. Minimal Value:-99, Maximal Value:99.0f;
\param fFrequency Frequency of the LFO. Minimal Value:0, Maximal Value:10.0f;
\param triangleWaveForm True for triangle wave form, false for square.
\param fDelay Number of milliseconds the input is delayed before it is played back. Minimal Value:0, Maximal Value:20.0f;
\param lPhase Phase differential between left and right LFOs. Possible values:
-180, -90, 0, 90, 180
\return Returns true if successful. */
virtual bool enableFlangerSoundEffect(ik_f32 fWetDryMix = 50,
ik_f32 fDepth = 100,
ik_f32 fFeedback = -50,
ik_f32 fFrequency = 0.25f,
bool triangleWaveForm = true,
ik_f32 fDelay = 2,
ik_s32 lPhase = 0) = 0;
//! removes the sound effect from the sound
virtual void disableFlangerSoundEffect() = 0;
//! returns if the sound effect is active on the sound
virtual bool isFlangerSoundEffectEnabled() = 0;
//! Enables the Gargle sound effect or adjusts its values.
/** The gargle effect modulates the amplitude of the signal.
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
\param rateHz Rate of modulation, in Hertz. Minimal Value:1, Maximal Value:1000
\param sinusWaveForm True for sinus wave form, false for triangle.
\return Returns true if successful. */
virtual bool enableGargleSoundEffect(ik_s32 rateHz = 20, bool sinusWaveForm = true) = 0;
//! removes the sound effect from the sound
virtual void disableGargleSoundEffect() = 0;
//! returns if the sound effect is active on the sound
virtual bool isGargleSoundEffectEnabled() = 0;
//! Enables the Interactive 3D Level 2 reverb sound effect or adjusts its values.
/** An implementation of the listener properties in the I3DL2 specification. Source properties are not supported.
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
\param lRoom Attenuation of the room effect, in millibels (mB). Interval: [-10000, 0] Default: -1000 mB
\param lRoomHF Attenuation of the room high-frequency effect. Interval: [-10000, 0] default: 0 mB
\param flRoomRolloffFactor Rolloff factor for the reflected signals. Interval: [0.0, 10.0] default: 0.0
\param flDecayTime Decay time, in seconds. Interval: [0.1, 20.0] default: 1.49s
\param flDecayHFRatio Ratio of the decay time at high frequencies to the decay time at low frequencies. Interval: [0.1, 2.0] default: 0.83
\param lReflections Attenuation of early reflections relative to lRoom. Interval: [-10000, 1000] default: -2602 mB
\param flReflectionsDelay Delay time of the first reflection relative to the direct path in seconds. Interval: [0.0, 0.3] default: 0.007 s
\param lReverb Attenuation of late reverberation relative to lRoom, in mB. Interval: [-10000, 2000] default: 200 mB
\param flReverbDelay Time limit between the early reflections and the late reverberation relative to the time of the first reflection. Interval: [0.0, 0.1] default: 0.011 s
\param flDiffusion Echo density in the late reverberation decay in percent. Interval: [0.0, 100.0] default: 100.0 %
\param flDensity Modal density in the late reverberation decay, in percent. Interval: [0.0, 100.0] default: 100.0 %
\param flHFReference Reference high frequency, in hertz. Interval: [20.0, 20000.0] default: 5000.0 Hz
\return Returns true if successful. */
virtual bool enableI3DL2ReverbSoundEffect(ik_s32 lRoom = -1000,
ik_s32 lRoomHF = -100,
ik_f32 flRoomRolloffFactor = 0,
ik_f32 flDecayTime = 1.49f,
ik_f32 flDecayHFRatio = 0.83f,
ik_s32 lReflections = -2602,
ik_f32 flReflectionsDelay = 0.007f,
ik_s32 lReverb = 200,
ik_f32 flReverbDelay = 0.011f,
ik_f32 flDiffusion = 100.0f,
ik_f32 flDensity = 100.0f,
ik_f32 flHFReference = 5000.0f ) = 0;
//! removes the sound effect from the sound
virtual void disableI3DL2ReverbSoundEffect() = 0;
//! returns if the sound effect is active on the sound
virtual bool isI3DL2ReverbSoundEffectEnabled() = 0;
//! Enables the ParamEq sound effect or adjusts its values.
/** Parametric equalizer amplifies or attenuates signals of a given frequency.
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
\param fCenter Center frequency, in hertz, The default value is 8000. Minimal Value:80, Maximal Value:16000.0f
\param fBandwidth Bandwidth, in semitones, The default value is 12. Minimal Value:1.0f, Maximal Value:36.0f
\param fGain Gain, default value is 0. Minimal Value:-15.0f, Maximal Value:15.0f
\return Returns true if successful. */
virtual bool enableParamEqSoundEffect(ik_f32 fCenter = 8000,
ik_f32 fBandwidth = 12,
ik_f32 fGain = 0) = 0;
//! removes the sound effect from the sound
virtual void disableParamEqSoundEffect() = 0;
//! returns if the sound effect is active on the sound
virtual bool isParamEqSoundEffectEnabled() = 0;
//! Enables the Waves Reverb sound effect or adjusts its values.
/** \param fInGain Input gain of signal, in decibels (dB). Min/Max: [-96.0,0.0] Default: 0.0 dB.
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
\param fReverbMix Reverb mix, in dB. Min/Max: [-96.0,0.0] Default: 0.0 dB
\param fReverbTime Reverb time, in milliseconds. Min/Max: [0.001,3000.0] Default: 1000.0 ms
\param fHighFreqRTRatio High-frequency reverb time ratio. Min/Max: [0.001,0.999] Default: 0.001
\return Returns true if successful. */
virtual bool enableWavesReverbSoundEffect(ik_f32 fInGain = 0,
ik_f32 fReverbMix = 0,
ik_f32 fReverbTime = 1000,
ik_f32 fHighFreqRTRatio = 0.001f) = 0;
//! removes the sound effect from the sound
virtual void disableWavesReverbSoundEffect() = 0;
//! returns if the sound effect is active on the sound
virtual bool isWavesReverbSoundEffectEnabled() = 0;
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,395 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_SOUND_ENGINE_H_INCLUDED__
#define __I_IRRKLANG_SOUND_ENGINE_H_INCLUDED__
#include "ik_IRefCounted.h"
#include "ik_vec3d.h"
#include "ik_ISoundSource.h"
#include "ik_ISound.h"
#include "ik_EStreamModes.h"
#include "ik_IFileFactory.h"
namespace irrklang
{
class IAudioStreamLoader;
//! Interface to the sound engine, for playing 3d and 2d sound and music.
/** This is the main interface of irrKlang. You usually would create this using
the createIrrKlangDevice() function.
*/
class ISoundEngine : public virtual irrklang::IRefCounted
{
public:
//! returns the name of the sound driver, like 'ALSA' for the alsa device
/** Possible returned strings are "NULL", "ALSA", "CoreAudio", "winMM",
"DirectSound" and "DirectSound8". */
virtual const char* getDriverName() = 0;
//! loads a sound source (if not loaded already) from a file and plays it.
/** \param sourceFileName Filename of sound, like "sounds/test.wav" or "foobar.ogg".
\param playLooped plays the sound in loop mode. If set to 'false', the sound is played once, then stopped and deleted from the internal playing list. Calls to
ISound have no effect after such a non looped sound has been stopped automaticly.
\param startPaused starts the sound paused. This implies that track=true. Use this if you want to modify some of the playing
parameters before the sound actually plays. Usually you would set this parameter to true, then use the ISound interface to
modify some of the sound parameters and then call ISound::setPaused(false);
Note: You need to call ISound::drop() when setting this parameter to true and you don't need the ISound
object anymore. See 'return' for details.
\param track Makes it possible to track the sound. Causes the method to return an ISound interface. See 'return' for details.
\param streamMode Specifies if the file should be streamed or loaded completely into memory for playing.
ESM_AUTO_DETECT sets this to autodetection. Note: if the sound has been loaded or played before into the
engine, this parameter has no effect.
\param enableSoundEffects Makes it possible to use sound effects such as chorus, distorsions, echo,
reverb and similar for this sound. Sound effects can then be controlled via ISound::getSoundEffectControl().
Only enable if necessary.
\return Only returns a pointer to an ISound if the parameters 'track', 'startPaused' or
'enableSoundEffects' have been set to true. Note: if this method returns an ISound as result,
you HAVE to call ISound::drop() after you don't need the ISound interface anymore. Otherwise this
will cause memory waste. This method also may return 0 altough 'track', 'startPaused' or
'enableSoundEffects' have been set to true, if the sound could not be played.*/
virtual ISound* play2D(const char* soundFileName,
bool playLooped = false,
bool startPaused = false,
bool track = false,
E_STREAM_MODE streamMode = ESM_AUTO_DETECT,
bool enableSoundEffects = false) = 0;
//! Plays a sound source as 2D sound with its default settings stored in ISoundSource.
/** An ISoundSource object will be created internally when playing a sound the first time,
or can be added with getSoundSource().
\param source The sound source, specifiying sound file source and default settings for this file.
Use the other ISoundEngine::play2D() overloads if you want to specify a filename string instead of this.
\param playLooped plays the sound in loop mode. If set to 'false', the sound is played once, then stopped and deleted from the internal playing list. Calls to
ISound have no effect after such a non looped sound has been stopped automaticly.
\param startPaused starts the sound paused. This implies that track=true. Use this if you want to modify some of the playing
parameters before the sound actually plays. Usually you would set this parameter to true, then use the ISound interface to
modify some of the sound parameters and then call ISound::setPaused(false);
Note: You need to call ISound::drop() when setting this parameter to true and you don't need the ISound
object anymore. See 'return' for details.
\param track Makes it possible to track the sound. Causes the method to return an ISound interface. See 'return' for details.
\param enableSoundEffects Makes it possible to use sound effects such as chorus, distorsions, echo,
reverb and similar for this sound. Sound effects can then be controlled via ISound::getSoundEffectControl().
Only enable if necessary.
\return Only returns a pointer to an ISound if the parameters 'track', 'startPaused' or
'enableSoundEffects' have been set to true. Note: if this method returns an ISound as result,
you HAVE to call ISound::drop() after you don't need the ISound interface anymore. Otherwise this
will cause memory waste. This method also may return 0 altough 'track', 'startPaused' or
'enableSoundEffects' have been set to true, if the sound could not be played.*/
virtual ISound* play2D(ISoundSource* source,
bool playLooped = false,
bool startPaused = false,
bool track = false,
bool enableSoundEffects = false) = 0;
//! Loads a sound source (if not loaded already) from a file and plays it as 3D sound.
/** There is some example code on how to work with 3D sound at @ref sound3d.
\param sourceFileName Filename of sound, like "sounds/test.wav" or "foobar.ogg".
\param pos Position of the 3D sound.
\param playLooped plays the sound in loop mode. If set to 'false', the sound is played once, then stopped and deleted from the internal playing list. Calls to
ISound have no effect after such a non looped sound has been stopped automaticly.
\param startPaused starts the sound paused. This implies that track=true. Use this if you want to modify some of the playing
parameters before the sound actually plays. Usually you would set this parameter to true, then use the ISound interface to
modify some of the sound parameters and then call ISound::setPaused(false);
Note: You need to call ISound::drop() when setting this parameter to true and you don't need the ISound
object anymore. See 'return' for details.
\param track Makes it possible to track the sound. Causes the method to return an ISound interface. See 'return' for details.
\param streamMode Specifies if the file should be streamed or loaded completely into memory for playing.
ESM_AUTO_DETECT sets this to autodetection. Note: if the sound has been loaded or played before into the
engine, this parameter has no effect.
\param enableSoundEffects Makes it possible to use sound effects such as chorus, distorsions, echo,
reverb and similar for this sound. Sound effects can then be controlled via ISound::getSoundEffectControl().
Only enable if necessary.
\return Only returns a pointer to an ISound if the parameters 'track', 'startPaused' or
'enableSoundEffects' have been set to true. Note: if this method returns an ISound as result,
you HAVE to call ISound::drop() after you don't need the ISound interface anymore. Otherwise this
will cause memory waste. This method also may return 0 altough 'track', 'startPaused' or
'enableSoundEffects' have been set to true, if the sound could not be played.*/
virtual ISound* play3D(const char* soundFileName, vec3df pos,
bool playLooped = false,
bool startPaused = false,
bool track = false,
E_STREAM_MODE streamMode = ESM_AUTO_DETECT,
bool enableSoundEffects = false) = 0;
//! Plays a sound source as 3D sound with its default settings stored in ISoundSource.
/** An ISoundSource object will be created internally when playing a sound the first time,
or can be added with getSoundSource(). There is some example code on how to work with 3D sound @ref sound3d.
\param source The sound source, specifiying sound file source and default settings for this file.
Use the other ISoundEngine::play2D() overloads if you want to specify a filename string instead of this.
\param pos Position of the 3D sound.
\param playLooped plays the sound in loop mode. If set to 'false', the sound is played once, then stopped and deleted from the internal playing list. Calls to
ISound have no effect after such a non looped sound has been stopped automaticly.
\param startPaused starts the sound paused. This implies that track=true. Use this if you want to modify some of the playing
parameters before the sound actually plays. Usually you would set this parameter to true, then use the ISound interface to
modify some of the sound parameters and then call ISound::setPaused(false);
Note: You need to call ISound::drop() when setting this parameter to true and you don't need the ISound
object anymore. See 'return' for details.
\param track Makes it possible to track the sound. Causes the method to return an ISound interface. See 'return' for details.
\param enableSoundEffects Makes it possible to use sound effects such as chorus, distorsions, echo,
reverb and similar for this sound. Sound effects can then be controlled via ISound::getSoundEffectControl().
Only enable if necessary.
\return Only returns a pointer to an ISound if the parameters 'track', 'startPaused' or
'enableSoundEffects' have been set to true. Note: if this method returns an ISound as result,
you HAVE to call ISound::drop() after you don't need the ISound interface anymore. Otherwise this
will cause memory waste. This method also may return 0 altough 'track', 'startPaused' or
'enableSoundEffects' have been set to true, if the sound could not be played.*/
virtual ISound* play3D(ISoundSource* source, vec3df pos,
bool playLooped = false,
bool startPaused = false,
bool track = false,
bool enableSoundEffects = false) = 0;
//! Stops all currently playing sounds.
virtual void stopAllSounds() = 0;
//! Pauses or unpauses all currently playing sounds.
virtual void setAllSoundsPaused( bool bPaused = true ) = 0;
//! Gets a sound source by sound name. Adds the sound source as file into the sound engine if not loaded already.
/** Please note: For performance reasons most ISoundEngine implementations will
not try to load the sound when calling this method, but only when play() is called
with this sound source as parameter.
\param addIfNotFound if 'true' adds the sound source to the list and returns the interface to it
if it cannot be found in the sound source list. If 'false', returns 0 if the sound
source is not in the list and does not modify the list. Default value: true.
\return Returns the sound source or 0 if not available.
Note: Don't call drop() to this pointer, it will be managed by irrKlang and
exist as long as you don't delete irrKlang or call removeSoundSource(). However,
you are free to call grab() if you want and drop() it then later of course. */
virtual ISoundSource* getSoundSource(const ik_c8* soundName, bool addIfNotFound=true) = 0;
//! Returns a sound source by index.
/** \param idx: Index of the loaded sound source, must by smaller than getSoundSourceCount().
\return Returns the sound source or 0 if not available.
Note: Don't call drop() to this pointer, it will be managed by irrKlang and
exist as long as you don't delete irrKlang or call removeSoundSource(). However,
you are free to call grab() if you want and drop() it then later of course. */
virtual ISoundSource* getSoundSource(ik_s32 index) = 0;
//! Returns amount of loaded sound sources.
virtual ik_s32 getSoundSourceCount() = 0;
//! Adds sound source into the sound engine as file.
/** \param fileName Name of the sound file (e.g. "sounds/something.mp3"). You can also use this
name when calling play3D() or play2D().
\param mode Streaming mode for this sound source
\param preload If this flag is set to false (which is default) the sound engine will
not try to load the sound file when calling this method, but only when play() is called
with this sound source as parameter. Otherwise the sound will be preloaded.
\return Returns the pointer to the added sound source or 0 if not sucessful because for
example a sound already existed with that name. If not successful, the reason will be printed
into the log. Note: Don't call drop() to this pointer, it will be managed by irrKlang and
exist as long as you don't delete irrKlang or call removeSoundSource(). However,
you are free to call grab() if you want and drop() it then later of course. */
virtual ISoundSource* addSoundSourceFromFile(const ik_c8* fileName, E_STREAM_MODE mode=ESM_AUTO_DETECT,
bool preload=false) = 0;
//! Adds a sound source into the sound engine as memory source.
/** Note: This method only accepts a file (.wav, .ogg, etc) which is totally loaded into memory.
If you want to add a sound source from decoded plain PCM data in memory, use addSoundSourceFromPCMData() instead.
\param memory Pointer to the memory to be treated as loaded sound file.
\param sizeInBytes Size of the memory chunk, in bytes.
\param soundName Name of the virtual sound file (e.g. "sounds/something.mp3"). You can also use this
name when calling play3D() or play2D(). Hint: If you include the extension of the original file
like .ogg, .mp3 or .wav at the end of the filename, irrKlang will be able to decide better what
file format it is and might be able to start playback faster.
\param copyMemory If set to true which is default, the memory block is copied
and stored in the engine, after calling addSoundSourceFromMemory() the memory pointer can be deleted
savely. If set to true, the memory is not copied and the user takes the responsibility that
the memory block pointed to remains there as long as the sound engine or at least this sound
source exists.
\return Returns the pointer to the added sound source or 0 if not sucessful because for
example a sound already existed with that name. If not successful, the reason will be printed
into the log. */
virtual ISoundSource* addSoundSourceFromMemory(void* memory, ik_s32 sizeInBytes, const ik_c8* soundName,
bool copyMemory=true) = 0;
//! Adds a sound source into the sound engine from plain PCM data in memory.
/** \param memory Pointer to the memory to be treated as loaded sound file.
\param sizeInBytes Size of the memory chunk, in bytes.
\param soundName Name of the virtual sound file (e.g. "sounds/something.mp3"). You can also use this
name when calling play3D() or play2D().
\param copyMemory If set to true which is default, the memory block is copied
and stored in the engine, after calling addSoundSourceFromPCMData() the memory pointer can be deleted
savely. If set to true, the memory is not copied and the user takes the responsibility that
the memory block pointed to remains there as long as the sound engine or at least this sound
source exists.
\return Returns the pointer to the added sound source or 0 if not sucessful because for
example a sound already existed with that name. If not successful, the reason will be printed
into the log. */
virtual ISoundSource* addSoundSourceFromPCMData(void* memory, ik_s32 sizeInBytes,
const ik_c8* soundName, SAudioStreamFormat format,
bool copyMemory=true) = 0;
//! Adds a sound source as alias for an existing sound source, but with a different name or optional different default settings.
/** This is useful if you want to play multiple sounds but each sound isn't necessarily one single file.
Also useful if you want to or play the same sound using different names, volumes or min and max 3D distances.
\param baseSource The sound source where this sound source should be based on. This sound
source will use the baseSource as base to access the file and similar, but it will have its
own name and its own default settings.
\param soundName Name of the new sound source to be added.
\return Returns the pointer to the added sound source or 0 if not sucessful because for
example a sound already existed with that name. If not successful, the reason will be printed
into the log.*/
virtual ISoundSource* addSoundSourceAlias(ISoundSource* baseSource, const ik_c8* soundName) = 0;
//! Removes a sound source from the engine, freeing the memory it occupies.
/** This will also cause all currently playing sounds of this source to be stopped.
Also note that if the source has been removed successfully, the value returned
by getSoundSourceCount() will have been decreased by one.
Removing sound sources is only necessary if you know you won't use a lot of non-streamed
sounds again. Sound sources of streamed sounds do not cost a lot of memory.*/
virtual void removeSoundSource(ISoundSource* source) = 0;
//! Removes a sound source from the engine, freeing the memory it occupies.
/** This will also cause all currently playing sounds of this source to be stopped.
Also note that if the source has been removed successfully, the value returned
by getSoundSourceCount() will have been decreased by one.
Removing sound sources is only necessary if you know you won't use a lot of non-streamed
sounds again. Sound sources of streamed sounds do not cost a lot of memory. */
virtual void removeSoundSource(const ik_c8* name) = 0;
//! Removes all sound sources from the engine
/** This will also cause all sounds to be stopped.
Removing sound sources is only necessary if you know you won't use a lot of non-streamed
sounds again. Sound sources of streamed sounds do not cost a lot of memory. */
virtual void removeAllSoundSources() = 0;
//! Sets master sound volume. This value is multiplied with all sounds played.
/** \param volume 0 (silent) to 1.0f (full volume) */
virtual void setSoundVolume(ik_f32 volume) = 0;
//! Returns master sound volume.
/* A value between 0.0 and 1.0. Default is 1.0. Can be changed using setSoundVolume(). */
virtual ik_f32 getSoundVolume() = 0;
//! Sets the current listener 3d position.
/** When playing sounds in 3D, updating the position of the listener every frame should be
done using this function.
\param pos Position of the camera or listener.
\param lookdir Direction vector where the camera or listener is looking into. If you have a
camera position and a target 3d point where it is looking at, this would be cam->getTarget() - cam->getAbsolutePosition().
\param velPerSecond The velocity per second describes the speed of the listener and
is only needed for doppler effects.
\param upvector Vector pointing 'up', so the engine can decide where is left and right.
This vector is usually (0,1,0).*/
virtual void setListenerPosition(const vec3df& pos,
const vec3df& lookdir,
const vec3df& velPerSecond = vec3df(0,0,0),
const vec3df& upVector = vec3df(0,1,0)) = 0;
//! Updates the audio engine. This should be called several times per frame if irrKlang was started in single thread mode.
/** This updates the 3d positions of the sounds as well as their volumes, effects,
streams and other stuff. Call this several times per frame (the more the better) if you
specified irrKlang to run single threaded. Otherwise it is not necessary to use this method.
This method is being called by the scene manager automaticly if you are using one, so
you might want to ignore this. */
virtual void update() = 0;
//! Returns if a sound with the specified name is currently playing.
virtual bool isCurrentlyPlaying(const char* soundName) = 0;
//! Returns if a sound with the specified source is currently playing.
virtual bool isCurrentlyPlaying(ISoundSource* source) = 0;
//! Registers a new audio stream loader in the sound engine.
/** Use this to enhance the audio engine to support other or new file formats.
To do this, implement your own IAudioStreamLoader interface and register it
with this method */
virtual void registerAudioStreamLoader(IAudioStreamLoader* loader) = 0;
//! Returns if irrKlang is running in the same thread as the application or is using multithreading.
/** This basicly returns the flag set by the user when creating the sound engine.*/
virtual bool isMultiThreaded() const = 0;
//! Adds a file factory to the sound engine, making it possible to override file access of the sound engine.
/** Derive your own class from IFileFactory, overwrite the createFileReader()
method and return your own implemented IFileReader to overwrite file access of irrKlang. */
virtual void addFileFactory(IFileFactory* fileFactory) = 0;
//! Sets the default minimal distance for 3D sounds.
/** This value influences how loud a sound is heard based on its distance.
See ISound::setMinDistance() for details about what the min distance is.
It is also possible to influence this default value for every sound file
using ISoundSource::setDefaultMinDistance().
This method only influences the initial distance value of sounds. For changing the
distance after the sound has been started to play, use ISound::setMinDistance() and ISound::setMaxDistance().
\param minDistance Default minimal distance for 3d sounds. The default value is 1.0f.*/
virtual void setDefault3DSoundMinDistance(ik_f32 minDistance) = 0;
//! Returns the default minimal distance for 3D sounds.
/** This value influences how loud a sound is heard based on its distance.
You can change it using setDefault3DSoundMinDistance().
See ISound::setMinDistance() for details about what the min distance is.
It is also possible to influence this default value for every sound file
using ISoundSource::setDefaultMinDistance().
\return Default minimal distance for 3d sounds. The default value is 1.0f. */
virtual ik_f32 getDefault3DSoundMinDistance() = 0;
//! Sets the default maximal distance for 3D sounds.
/** Changing this value is usually not necessary. Use setDefault3DSoundMinDistance() instead.
Don't change this value if you don't know what you are doing: This value causes the sound
to stop attenuating after it reaches the max distance. Most people think that this sets the
volume of the sound to 0 after this distance, but this is not true. Only change the
minimal distance (using for example setDefault3DSoundMinDistance()) to influence this.
See ISound::setMaxDistance() for details about what the max distance is.
It is also possible to influence this default value for every sound file
using ISoundSource::setDefaultMaxDistance().
This method only influences the initial distance value of sounds. For changing the
distance after the sound has been started to play, use ISound::setMinDistance() and ISound::setMaxDistance().
\param maxDistance Default maximal distance for 3d sounds. The default value is 1000000000.0f. */
virtual void setDefault3DSoundMaxDistance(ik_f32 maxDistance) = 0;
//! Returns the default maximal distance for 3D sounds.
/** This value influences how loud a sound is heard based on its distance.
You can change it using setDefault3DSoundmaxDistance(), but
changing this value is usually not necessary. This value causes the sound
to stop attenuating after it reaches the max distance. Most people think that this sets the
volume of the sound to 0 after this distance, but this is not true. Only change the
minimal distance (using for example setDefault3DSoundMinDistance()) to influence this.
See ISound::setMaxDistance() for details about what the max distance is.
It is also possible to influence this default value for every sound file
using ISoundSource::setDefaultMaxDistance().
\return Default maximal distance for 3d sounds. The default value is 1000000000.0f. */
virtual ik_f32 getDefault3DSoundMaxDistance() = 0;
//! Sets a rolloff factor which influences the amount of attenuation that is applied to 3D sounds.
/** The rolloff factor can range from 0.0 to 10.0, where 0 is no rolloff. 1.0 is the default
rolloff factor set, the value which we also experience in the real world. A value of 2 would mean
twice the real-world rolloff. */
virtual void setRolloffFactor(ik_f32 rolloff) = 0;
//! Sets parameters affecting the doppler effect.
/** \param dopplerFactor is a value between 0 and 10 which multiplies the doppler
effect. Default value is 1.0, which is the real world doppler effect, and 10.0f
would be ten times the real world doppler effect.
\param distanceFactor is the number of meters in a vector unit. The default value
is 1.0. Doppler effects are calculated in meters per second, with this parameter,
this can be changed, all velocities and positions are influenced by this. If
the measurement should be in foot instead of meters, set this value to 0.3048f
for example.*/
virtual void setDopplerEffectParameters(ik_f32 dopplerFactor=1.0f, ik_f32 distanceFactor=1.0f) = 0;
//! Loads irrKlang plugins from a custom path.
/** Plugins usually are .dll, .so or .dylib
files named for example ikpMP3.dll (= short for irrKlangPluginMP3) which
make it possible to play back mp3 files. Plugins are being
loaded from the current working directory at startup of the sound engine
if the parameter ESEO_LOAD_PLUGINS is set (which it is by default), but
using this method, it is possible to load plugins from a custom path in addition.
\param path Path to the plugin directory, like "C:\games\somegamegame\irrklangplugins".
\return returns true if sucessful or fals if not, for example because the path could
not be found. */
virtual bool loadPlugins(const ik_c8* path) = 0;
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,167 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_IRR_SOUND_SOURCE_H_INCLUDED__
#define __I_IRRKLANG_IRR_SOUND_SOURCE_H_INCLUDED__
#include "ik_IVirtualRefCounted.h"
#include "ik_vec3d.h"
#include "ik_EStreamModes.h"
#include "ik_SAudioStreamFormat.h"
namespace irrklang
{
//! A sound source describes an input file (.ogg, .mp3, .wav or similar) and its default settings.
/** It provides some informations about the sound source like the play lenght and
can have default settings for volume, distances for 3d etc. There is some example code on how
to use Sound sources at @ref soundSources.*/
class ISoundSource : public IVirtualRefCounted
{
public:
//! Returns the name of the sound source (usually, this is the file name)
virtual const ik_c8* getName() = 0;
//! Sets the stream mode which should be used for a sound played from this source.
/** Note that if this is set to ESM_NO_STREAMING, the engine still might decide
to stream the sound if it is too big. The threashold for this can be
adjusted using ISoundSource::setForcedStreamingThreshold(). */
virtual void setStreamMode(E_STREAM_MODE mode) = 0;
//! Returns the detected or set type of the sound with wich the sound will be played.
/** Note: If the returned type is ESM_AUTO_DETECT, this mode will change after the
sound has been played the first time. */
virtual E_STREAM_MODE getStreamMode() = 0;
//! Returns the play length of the sound in milliseconds.
/** Returns -1 if not known for this sound for example because its decoder
does not support lenght reporting or it is a file stream of unknown size.
Note: If the sound never has been played before, the sound engine will have to open
the file and try to get the play lenght from there, so this call could take a bit depending
on the type of file. */
virtual ik_u32 getPlayLength() = 0;
//! Returns informations about the sound source: channel count (mono/stereo), frame count, sample rate, etc.
/** \return Returns the structure filled with 0 or negative values if not known for this sound for example because
because the file could not be opened or similar.
Note: If the sound never has been played before, the sound engine will have to open
the file and try to get the play lenght from there, so this call could take a bit depending
on the type of file. */
virtual SAudioStreamFormat getAudioFormat() = 0;
//! Returns if sounds played from this source will support seeking via ISound::setPlayPosition().
/* If a sound is seekable depends on the file type and the audio format. For example MOD files
cannot be seeked currently.
\return Returns true of the sound source supports setPlayPosition() and false if not.
Note: If the sound never has been played before, the sound engine will have to open
the file and try to get the information from there, so this call could take a bit depending
on the type of file. */
virtual bool getIsSeekingSupported() = 0;
//! Sets the default volume for a sound played from this source.
/** The default value of this is 1.0f.
Note that the default volume is being multiplied with the master volume
of ISoundEngine, change this via ISoundEngine::setSoundVolume().
//! \param volume 0 (silent) to 1.0f (full volume). Default value is 1.0f. */
virtual void setDefaultVolume(ik_f32 volume=1.0f) = 0;
//! Returns the default volume for a sound played from this source.
/** You can influence this default volume value using setDefaultVolume().
Note that the default volume is being multiplied with the master volume
of ISoundEngine, change this via ISoundEngine::setSoundVolume().
//! \return 0 (silent) to 1.0f (full volume). Default value is 1.0f. */
virtual ik_f32 getDefaultVolume() = 0;
//! sets the default minimal distance for 3D sounds played from this source.
/** This value influences how loud a sound is heard based on its distance.
See ISound::setMinDistance() for details about what the min distance is.
This method only influences the initial distance value of sounds. For changing the
distance while the sound is playing, use ISound::setMinDistance() and ISound::setMaxDistance().
\param minDistance: Default minimal distance for 3D sounds from this source. Set it to a negative
value to let sounds of this source use the engine level default min distance, which
can be set via ISoundEngine::setDefault3DSoundMinDistance(). Default value is -1, causing
the default min distance of the sound engine to take effect. */
virtual void setDefaultMinDistance(ik_f32 minDistance) = 0;
//! Returns the default minimal distance for 3D sounds played from this source.
/** This value influences how loud a sound is heard based on its distance.
See ISound::setMinDistance() for details about what the minimal distance is.
\return Default minimal distance for 3d sounds from this source. If setDefaultMinDistance()
was set to a negative value, it will return the default value set in the engine,
using ISoundEngine::setDefault3DSoundMinDistance(). Default value is -1, causing
the default min distance of the sound engine to take effect. */
virtual ik_f32 getDefaultMinDistance() = 0;
//! Sets the default maximal distance for 3D sounds played from this source.
/** Changing this value is usually not necessary. Use setDefaultMinDistance() instead.
Don't change this value if you don't know what you are doing: This value causes the sound
to stop attenuating after it reaches the max distance. Most people think that this sets the
volume of the sound to 0 after this distance, but this is not true. Only change the
minimal distance (using for example setDefaultMinDistance()) to influence this.
See ISound::setMaxDistance() for details about what the max distance is.
This method only influences the initial distance value of sounds. For changing the
distance while the sound is played, use ISound::setMinDistance()
and ISound::setMaxDistance().
\param maxDistance Default maximal distance for 3D sounds from this source. Set it to a negative
value to let sounds of this source use the engine level default max distance, which
can be set via ISoundEngine::setDefault3DSoundMaxDistance(). Default value is -1, causing
the default max distance of the sound engine to take effect. */
virtual void setDefaultMaxDistance(ik_f32 maxDistance) = 0;
//! returns the default maxmial distance for 3D sounds played from this source.
/** This value influences how loud a sound is heard based on its distance.
Changing this value is usually not necessary. Use setDefaultMinDistance() instead.
Don't change this value if you don't know what you are doing: This value causes the sound
to stop attenuating after it reaches the max distance. Most people think that this sets the
volume of the sound to 0 after this distance, but this is not true. Only change the
minimal distance (using for example setDefaultMinDistance()) to influence this.
See ISound::setMaxDistance() for details about what the max distance is.
\return Default maximal distance for 3D sounds from this source. If setDefaultMaxDistance()
was set to a negative value, it will return the default value set in the engine,
using ISoundEngine::setDefault3DSoundMaxDistance(). Default value is -1, causing
the default max distance of the sound engine to take effect. */
virtual ik_f32 getDefaultMaxDistance() = 0;
//! Forces the sound to be reloaded at next replay.
/** Sounds which are not played as streams are buffered to make it possible to
replay them without much overhead. If the sound file is altered after the sound
has been played the first time, the engine won't play the changed file then.
Calling this method makes the engine reload the file before the file is played
the next time.*/
virtual void forceReloadAtNextUse() = 0;
//! Sets the threshold size where irrKlang decides to force streaming a file independent of the user specified setting.
/** When specifying ESM_NO_STREAMING for playing back a sound file, irrKlang will
ignore this setting if the file is bigger than this threshold and stream the file
anyway. Please note that if an audio format loader is not able to return the
size of a sound source and returns -1 as length, this will be ignored as well
and streaming has to be forced.
\param threshold: New threshold. The value is specified in uncompressed bytes and its default value is
about one Megabyte. Set to 0 or a negative value to disable stream forcing. */
virtual void setForcedStreamingThreshold(ik_s32 thresholdBytes) = 0;
//! Returns the threshold size where irrKlang decides to force streaming a file independent of the user specified setting.
/** The value is specified in uncompressed bytes and its default value is
about one Megabyte. See setForcedStreamingThreshold() for details. */
virtual ik_s32 getForcedStreamingForceThreshold() = 0;
//! Returns a pointer to the loaded and decoded sample data.
/** \return Returns a pointer to the sample data. The data is provided in decoded PCM data. The
exact format can be retrieved using getAudioFormat(). Use getAudioFormat().getSampleDataSize()
for getting the amount of bytes. The returned pointer will only be valid as long as the sound
source exists.
This function will only return a pointer to the data if the
audio file is not streamed, namely ESM_NO_STREAMING. Otherwise this function will return 0.
Note: If the sound never has been played before, the sound engine will have to open
the file and decode audio data from there, so this call could take a bit depending
on the type of the file.*/
virtual void* getSampleData() = 0;
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,72 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_SOUND_STOP_EVENT_RECEIVER_H_INCLUDED__
#define __I_IRRKLANG_SOUND_STOP_EVENT_RECEIVER_H_INCLUDED__
#include "ik_IRefCounted.h"
#include "ik_SAudioStreamFormat.h"
namespace irrklang
{
//! An enumeration listing all reasons for a fired sound stop event
enum E_STOP_EVENT_CAUSE
{
//! The sound stop event was fired because the sound finished playing
ESEC_SOUND_FINISHED_PLAYING = 0,
//! The sound stop event was fired because the sound was stopped by the user, calling ISound::stop().
ESEC_SOUND_STOPPED_BY_USER,
//! The sound stop event was fired because the source of the sound was removed, for example
//! because irrKlang was shut down or the user called ISoundEngine::removeSoundSource().
ESEC_SOUND_STOPPED_BY_SOURCE_REMOVAL,
//! This enumeration literal is never used, it only forces the compiler to
//! compile these enumeration values to 32 bit.
ESEC_FORCE_32_BIT = 0x7fffffff
};
//! Interface to be implemented by the user, which recieves sound stop events.
/** The interface has only one method to be implemented by the user: OnSoundStopped().
Implement this interface and set it via ISound::setSoundStopEventReceiver().
The sound stop event is guaranteed to be called when a sound or sound stream is finished,
either because the sound reached its playback end, its sound source was removed,
ISoundEngine::stopAllSounds() has been called or the whole engine was deleted. */
class ISoundStopEventReceiver
{
public:
//! destructor
virtual ~ISoundStopEventReceiver() {};
//! Called when a sound has stopped playing.
/** This is the only method to be implemented by the user.
The sound stop event is guaranteed to be called when a sound or sound stream is finished,
either because the sound reached its playback end, its sound source was removed,
ISoundEngine::stopAllSounds() has been called or the whole engine was deleted.
Please note: Sound events will occur in a different thread when the engine runs in
multi threaded mode (default). In single threaded mode, the event will happen while
the user thread is calling ISoundEngine::update().
\param sound: Sound which has been stopped.
\param reason: The reason why the sound stop event was fired. Usually, this will be ESEC_SOUND_FINISHED_PLAYING.
When the sound was aborded by calling ISound::stop() or ISoundEngine::stopAllSounds();, this would be
ESEC_SOUND_STOPPED_BY_USER. If irrKlang was deleted or the sound source was removed, the value is
ESEC_SOUND_STOPPED_BY_SOURCE_REMOVAL.
\param userData: userData pointer set by the user when registering the interface
via ISound::setSoundStopEventReceiver(). */
virtual void OnSoundStopped(ISound* sound, E_STOP_EVENT_CAUSE reason, void* userData) = 0;
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,48 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __I_IRRKLANG_VIRTUAL_UNKNOWN_H_INCLUDED__
#define __I_IRRKLANG_VIRTUAL_UNKNOWN_H_INCLUDED__
#include "ik_irrKlangTypes.h"
namespace irrklang
{
//! Reference counting base class for objects in the Irrlicht Engine similar to IRefCounted.
/** See IRefCounted for the basics of this class.
The difference to IRefCounted is that the class has to implement reference counting
for itself.
*/
class IVirtualRefCounted
{
public:
//! Destructor.
virtual ~IVirtualRefCounted()
{
}
//! Grabs the object. Increments the reference counter by one.
/** To be implemented by the derived class. If you don't want to
implement this, use the class IRefCounted instead. See IRefCounted::grab() for details
of this method. */
virtual void grab() = 0;
//! Drops the object. Decrements the reference counter by one.
/** To be implemented by the derived class. If you don't want to
implement this, use the class IRefCounted instead. See IRefCounted::grab() for details
of this method. */
virtual bool drop() = 0;
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,71 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __S_IRRKLANG_AUDIO_STREAM_FORMAT_H_INCLUDED__
#define __S_IRRKLANG_AUDIO_STREAM_FORMAT_H_INCLUDED__
#include "ik_IRefCounted.h"
namespace irrklang
{
//! audio sample data format enumeration for supported formats
enum ESampleFormat
{
//! one unsigned byte (0;255)
ESF_U8,
//! 16 bit, signed (-32k;32k)
ESF_S16
};
//! structure describing an audio stream format with helper functions
struct SAudioStreamFormat
{
//! channels, 1 for mono, 2 for stereo
ik_s32 ChannelCount;
//! amount of frames in the sample data or stream.
/** If the stream has an unknown lenght, this is -1 */
ik_s32 FrameCount;
//! samples per second
ik_s32 SampleRate;
//! format of the sample data
ESampleFormat SampleFormat;
//! returns the size of a sample of the data described by the stream data in bytes
inline ik_s32 getSampleSize() const
{
return (SampleFormat == ESF_U8) ? 1 : 2;
}
//! returns the frame size of the stream data in bytes
inline ik_s32 getFrameSize() const
{
return ChannelCount * getSampleSize();
}
//! returns the size of the sample data in bytes
/* Returns an invalid negative value when the stream has an unknown lenght */
inline ik_s32 getSampleDataSize() const
{
return getFrameSize() * FrameCount;
}
//! returns amount of bytes per second
inline ik_s32 getBytesPerSecond() const
{
return getFrameSize() * SampleRate;
}
};
} // end namespace irrklang
#endif

View File

@ -0,0 +1,78 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __IRRKLANG_TYPES_H_INCLUDED__
#define __IRRKLANG_TYPES_H_INCLUDED__
namespace irrklang
{
//! 8 bit unsigned variable.
/** This is a typedef for unsigned char, it ensures portability of the engine. */
typedef unsigned char ik_u8;
//! 8 bit signed variable.
/** This is a typedef for signed char, it ensures portability of the engine. */
typedef signed char ik_s8;
//! 8 bit character variable.
/** This is a typedef for char, it ensures portability of the engine. */
typedef char ik_c8;
//! 16 bit unsigned variable.
/** This is a typedef for unsigned short, it ensures portability of the engine. */
typedef unsigned short ik_u16;
//! 16 bit signed variable.
/** This is a typedef for signed short, it ensures portability of the engine. */
typedef signed short ik_s16;
//! 32 bit unsigned variable.
/** This is a typedef for unsigned int, it ensures portability of the engine. */
typedef unsigned int ik_u32;
//! 32 bit signed variable.
/** This is a typedef for signed int, it ensures portability of the engine. */
typedef signed int ik_s32;
//! 32 bit floating point variable.
/** This is a typedef for float, it ensures portability of the engine. */
typedef float ik_f32;
//! 64 bit floating point variable.
/** This is a typedef for double, it ensures portability of the engine. */
typedef double ik_f64;
// some constants
const ik_f32 IK_ROUNDING_ERROR_32 = 0.000001f;
const ik_f64 IK_PI64 = 3.1415926535897932384626433832795028841971693993751;
const ik_f32 IK_PI32 = 3.14159265359f;
const ik_f32 IK_RADTODEG = 180.0f / IK_PI32;
const ik_f32 IK_DEGTORAD = IK_PI32 / 180.0f;
const ik_f64 IK_RADTODEG64 = 180.0 / IK_PI64;
const ik_f64 IK_DEGTORAD64 = IK_PI64 / 180.0;
//! returns if a float equals the other one, taking floating
//! point rounding errors into account
inline bool equalsfloat(const ik_f32 a, const ik_f32 b, const ik_f32 tolerance = IK_ROUNDING_ERROR_32)
{
return (a + tolerance > b) && (a - tolerance < b);
}
} // end namespace
#endif // __IRR_TYPES_H_INCLUDED__

View File

@ -0,0 +1,261 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "irrKlang" library.
// For conditions of distribution and use, see copyright notice in irrKlang.h
#ifndef __IRR_IRRKLANG_VEC_3D_H_INCLUDED__
#define __IRR_IRRKLANG_VEC_3D_H_INCLUDED__
#include <math.h>
#include "ik_irrKlangTypes.h"
namespace irrklang
{
//! a 3d vector template class for representing vectors and points in 3d
template <class T>
class vec3d
{
public:
vec3d(): X(0), Y(0), Z(0) {};
vec3d(T nx, T ny, T nz) : X(nx), Y(ny), Z(nz) {};
vec3d(const vec3d<T>& other) :X(other.X), Y(other.Y), Z(other.Z) {};
//! constructor creating an irrklang vec3d from an irrlicht vector.
#ifdef __IRR_POINT_3D_H_INCLUDED__
template<class B>
vec3d(const B& other) :X(other.X), Y(other.Y), Z(other.Z) {};
#endif // __IRR_POINT_3D_H_INCLUDED__
// operators
vec3d<T> operator-() const { return vec3d<T>(-X, -Y, -Z); }
vec3d<T>& operator=(const vec3d<T>& other) { X = other.X; Y = other.Y; Z = other.Z; return *this; }
vec3d<T> operator+(const vec3d<T>& other) const { return vec3d<T>(X + other.X, Y + other.Y, Z + other.Z); }
vec3d<T>& operator+=(const vec3d<T>& other) { X+=other.X; Y+=other.Y; Z+=other.Z; return *this; }
vec3d<T> operator-(const vec3d<T>& other) const { return vec3d<T>(X - other.X, Y - other.Y, Z - other.Z); }
vec3d<T>& operator-=(const vec3d<T>& other) { X-=other.X; Y-=other.Y; Z-=other.Z; return *this; }
vec3d<T> operator*(const vec3d<T>& other) const { return vec3d<T>(X * other.X, Y * other.Y, Z * other.Z); }
vec3d<T>& operator*=(const vec3d<T>& other) { X*=other.X; Y*=other.Y; Z*=other.Z; return *this; }
vec3d<T> operator*(const T v) const { return vec3d<T>(X * v, Y * v, Z * v); }
vec3d<T>& operator*=(const T v) { X*=v; Y*=v; Z*=v; return *this; }
vec3d<T> operator/(const vec3d<T>& other) const { return vec3d<T>(X / other.X, Y / other.Y, Z / other.Z); }
vec3d<T>& operator/=(const vec3d<T>& other) { X/=other.X; Y/=other.Y; Z/=other.Z; return *this; }
vec3d<T> operator/(const T v) const { T i=(T)1.0/v; return vec3d<T>(X * i, Y * i, Z * i); }
vec3d<T>& operator/=(const T v) { T i=(T)1.0/v; X*=i; Y*=i; Z*=i; return *this; }
bool operator<=(const vec3d<T>&other) const { return X<=other.X && Y<=other.Y && Z<=other.Z;};
bool operator>=(const vec3d<T>&other) const { return X>=other.X && Y>=other.Y && Z>=other.Z;};
bool operator==(const vec3d<T>& other) const { return other.X==X && other.Y==Y && other.Z==Z; }
bool operator!=(const vec3d<T>& other) const { return other.X!=X || other.Y!=Y || other.Z!=Z; }
// functions
//! returns if this vector equalsfloat the other one, taking floating point rounding errors into account
bool equals(const vec3d<T>& other)
{
return equalsfloat(X, other.X) &&
equalsfloat(Y, other.Y) &&
equalsfloat(Z, other.Z);
}
void set(const T nx, const T ny, const T nz) {X=nx; Y=ny; Z=nz; }
void set(const vec3d<T>& p) { X=p.X; Y=p.Y; Z=p.Z;}
//! Returns length of the vector.
ik_f64 getLength() const { return sqrt(X*X + Y*Y + Z*Z); }
//! Returns squared length of the vector.
/** This is useful because it is much faster then
getLength(). */
ik_f64 getLengthSQ() const { return X*X + Y*Y + Z*Z; }
//! Returns the dot product with another vector.
T dotProduct(const vec3d<T>& other) const
{
return X*other.X + Y*other.Y + Z*other.Z;
}
//! Returns distance from an other point.
/** Here, the vector is interpreted as point in 3 dimensional space. */
ik_f64 getDistanceFrom(const vec3d<T>& other) const
{
ik_f64 vx = X - other.X; ik_f64 vy = Y - other.Y; ik_f64 vz = Z - other.Z;
return sqrt(vx*vx + vy*vy + vz*vz);
}
//! Returns squared distance from an other point.
/** Here, the vector is interpreted as point in 3 dimensional space. */
ik_f32 getDistanceFromSQ(const vec3d<T>& other) const
{
ik_f32 vx = X - other.X; ik_f32 vy = Y - other.Y; ik_f32 vz = Z - other.Z;
return (vx*vx + vy*vy + vz*vz);
}
//! Calculates the cross product with another vector
vec3d<T> crossProduct(const vec3d<T>& p) const
{
return vec3d<T>(Y * p.Z - Z * p.Y, Z * p.X - X * p.Z, X * p.Y - Y * p.X);
}
//! Returns if this vector interpreted as a point is on a line between two other points.
/** It is assumed that the point is on the line. */
bool isBetweenPoints(const vec3d<T>& begin, const vec3d<T>& end) const
{
ik_f32 f = (ik_f32)(end - begin).getLengthSQ();
return (ik_f32)getDistanceFromSQ(begin) < f &&
(ik_f32)getDistanceFromSQ(end) < f;
}
//! Normalizes the vector.
vec3d<T>& normalize()
{
T l = (T)getLength();
if (l == 0)
return *this;
l = (T)1.0 / l;
X *= l;
Y *= l;
Z *= l;
return *this;
}
//! Sets the lenght of the vector to a new value
void setLength(T newlength)
{
normalize();
*this *= newlength;
}
//! Inverts the vector.
void invert()
{
X *= -1.0f;
Y *= -1.0f;
Z *= -1.0f;
}
//! Rotates the vector by a specified number of degrees around the Y
//! axis and the specified center.
//! \param degrees: Number of degrees to rotate around the Y axis.
//! \param center: The center of the rotation.
void rotateXZBy(ik_f64 degrees, const vec3d<T>& center)
{
degrees *= IK_DEGTORAD64;
T cs = (T)cos(degrees);
T sn = (T)sin(degrees);
X -= center.X;
Z -= center.Z;
set(X*cs - Z*sn, Y, X*sn + Z*cs);
X += center.X;
Z += center.Z;
}
//! Rotates the vector by a specified number of degrees around the Z
//! axis and the specified center.
//! \param degrees: Number of degrees to rotate around the Z axis.
//! \param center: The center of the rotation.
void rotateXYBy(ik_f64 degrees, const vec3d<T>& center)
{
degrees *= IK_DEGTORAD64;
T cs = (T)cos(degrees);
T sn = (T)sin(degrees);
X -= center.X;
Y -= center.Y;
set(X*cs - Y*sn, X*sn + Y*cs, Z);
X += center.X;
Y += center.Y;
}
//! Rotates the vector by a specified number of degrees around the X
//! axis and the specified center.
//! \param degrees: Number of degrees to rotate around the X axis.
//! \param center: The center of the rotation.
void rotateYZBy(ik_f64 degrees, const vec3d<T>& center)
{
degrees *= IK_DEGTORAD64;
T cs = (T)cos(degrees);
T sn = (T)sin(degrees);
Z -= center.Z;
Y -= center.Y;
set(X, Y*cs - Z*sn, Y*sn + Z*cs);
Z += center.Z;
Y += center.Y;
}
//! Returns interpolated vector.
/** \param other: other vector to interpolate between
\param d: value between 0.0f and 1.0f. */
vec3d<T> getInterpolated(const vec3d<T>& other, ik_f32 d) const
{
ik_f32 inv = 1.0f - d;
return vec3d<T>(other.X*inv + X*d,
other.Y*inv + Y*d,
other.Z*inv + Z*d);
}
//! Gets the Y and Z rotations of a vector.
/** Thanks to Arras on the Irrlicht forums to add this method.
\return A vector representing the rotation in degrees of
this vector. The Z component of the vector will always be 0. */
vec3d<T> getHorizontalAngle()
{
vec3d<T> angle;
angle.Y = (T)atan2(X, Z);
angle.Y *= (ik_f32)IK_RADTODEG;
if (angle.Y < 0.0f) angle.Y += 360.0f;
if (angle.Y >= 360.0f) angle.Y -= 360.0f;
ik_f32 z1 = (T)sqrt(X*X + Z*Z);
angle.X = (T)atan2(z1, Y);
angle.X *= (ik_f32)IK_RADTODEG;
angle.X -= 90.0f;
if (angle.X < 0.0f) angle.X += 360.0f;
if (angle.X >= 360) angle.X -= 360.0f;
return angle;
}
//! Fills an array of 4 values with the vector data (usually floats).
/** Useful for setting in shader constants for example. The fourth value
will always be 0. */
void getAs4Values(T* array)
{
array[0] = X;
array[1] = Y;
array[2] = Z;
array[3] = 0;
}
// member variables
T X, Y, Z;
};
//! Typedef for a ik_f32 3d vector, a vector using floats for X, Y and Z
typedef vec3d<ik_f32> vec3df;
//! Typedef for an integer 3d vector, a vector using ints for X, Y and Z
typedef vec3d<ik_s32> vec3di;
template<class S, class T> vec3d<T> operator*(const S scalar, const vec3d<T>& vector) { return vector*scalar; }
} // end namespace irrklang
#endif

View File

@ -0,0 +1,966 @@
/* irrKlang.h -- interface of the 'irrKlang' library
Copyright (C) 2002-2007 Nikolaus Gebhardt
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
*/
#ifndef __IRR_KLANG_H_INCLUDED__
#define __IRR_KLANG_H_INCLUDED__
#include "ik_irrKlangTypes.h"
#include "ik_vec3d.h"
#include "ik_IRefCounted.h"
#include "ik_IVirtualRefCounted.h"
#include "ik_ESoundOutputDrivers.h"
#include "ik_ESoundEngineOptions.h"
#include "ik_EStreamModes.h"
#include "ik_SAudioStreamFormat.h"
#include "ik_ISoundEngine.h"
#include "ik_ISoundSource.h"
#include "ik_ISound.h"
#include "ik_IAudioStream.h"
#include "ik_IAudioStreamLoader.h"
#include "ik_ISoundEffectControl.h"
#include "ik_ISoundStopEventReceiver.h"
#include "ik_IFileFactory.h"
#include "ik_IFileReader.h"
#include "ik_ISoundDeviceList.h"
#include "ik_IAudioRecorder.h"
//! irrKlang Version
#define IRR_KLANG_VERSION "1.1.0"
/*! \mainpage irrKlang 1.1.0 API documentation
*
* <div align="center"><img src="logobig.png" ></div>
* \section contents Contents
* General:<br/>
* @ref intro <br/>
* @ref features <br/>
* @ref links <br/>
* <br/>
* Programming irrKlang:<br/>
* @ref concept <br/>
* @ref playingSounds <br/>
* @ref changingSounds <br/>
* @ref soundSources <br/>
* @ref sound3d <br/>
* @ref removingSounds <br/>
* @ref events <br/>
* @ref memoryPlayback <br/>
* @ref effects <br/>
* @ref fileOverriding <br/>
* @ref audioDecoders <br/>
* @ref plugins <br/>
* @ref staticLib <br/>
* @ref enumeratingDevices <br/>
* @ref recordingAudio <br/>
* <br/>
* Short full examples:<br/>
* @ref quickstartexample <br/>
* @ref quickstartexample2 <br/>
* <br/>
* <br/>
*
* \section intro Introduction
*
* Welcome to the irrKlang API documentation. This page should give you a short overview
* over irrKlang, the high level audio library.
* In this documentation files you'll find any information you'll need to develop applications with
* irrKlang using C++. If you are looking for a tutorial on how to start, you'll
* find some on the homepage of irrKlang at
* <A HREF="http://www.ambiera.com/irrklang" >http://www.ambiera.com/irrklang</A>
* or inside the SDK in the directory \examples.
*
* 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.
*
* <br/>
* <br/>
*
*
* \section features Features of irrKlang
*
* irrKlang is a high level 2D and 3D
* cross platform sound engine and audio library.
* It has a very simply object orientated interface and was designed to be used
* in games, scientific simulations, architectural visualizations and similar.
* irrKlang plays several file formats such as
* <ul>
* <li>RIFF WAVE (*.wav)</li>
* <li>Ogg Vorbis (*.ogg)</li>
* <li>MPEG-1 Audio Layer 3 (*.mp3)</li>
* <li>Amiga Modules (*.mod)</li>
* <li>Impulse Tracker (*.it)</li>
* <li>Scream Tracker 3 (*.s3d)</li>
* <li>Fast Tracker 2 (*.xm)</li>
* </ul>
* It is also able to run on different operating systems and use several output drivers:
*<ul>
* <li>Windows 98, ME, NT 4, 2000, XP, Vista</li>
* <ul>
* <li>DirectSound</li>
* <li>DirectSound8</li>
* <li>WinMM</li>
* </ul>
* <li>Linux / *nix</li>
* <ul>
* <li>ALSA</li>
* </ul>
* <li>MacOSX (x86 and PPC)</li>
* <ul>
* <li>CoreAudio</li>
* </ul>
* </ul>
* <br/>
* <br/>
* <br/>
*
*
*
* \section links Links into the API documentation
*
* irrklang::ISoundEngine: The main class of irrKlang.<br/>
* <A HREF="annotated.html">Class list</A>: List of all classes with descriptions.<BR/>
* <A HREF="functions.html">Class members</A>: Good place to find forgotten features.<BR/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section concept Starting up the Engine
*
* irrKlang is designed so that it is very easy to achieve everything, its interface should
* be very simple to use. The @ref quickstartexample shows how to play and mp3 file, and there
* is another example, @ref quickstartexample2, showing some few more details.<br/>
* To start up the sound engine, you simply need to call createIrrKlangDevice(). To shut it down,
* call IRefCounted::drop():
*
* \code
* #include <irrKlang.h>
*
* // ...
*
* // start up the engine
* irrklang::ISoundEngine* engine = irrklang::createIrrKlangDevice();
*
* // ...
*
* // after finished,
* // close the engine again, similar as calling 'delete'
* engine->drop();
* \endcode
*
* 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.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section playingSounds Playing Sounds
*
* Once you have irrKlang running (like in @ref concept), you can start playing sounds:
*
* \code
* engine->play2D("someSoundFile.wav");
* \endcode
*
* This works with all supported file types. You can replace "someSoundFile.wav" with
* "someSoundFile.mp3", or "someSoundFile.ogg", for example.<br/>
* To play a sound looped, set the second parameter to 'true':
*
* \code
* engine->play2D("myMusic.mp3", true);
* \endcode
*
* To stop this looping sound again, use engine->\link irrklang::ISoundEngine::stopAllSounds stopAllSounds()\endlink to stop all sounds, or
* irrklang::ISound::stop() if you only want to stop that single sound. @ref changingSounds
* shows how to get to that ISound interface.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
* \section changingSounds Influencing Sounds during Playback
* To influence parameters of the sound such as pan, volume or playback speed during runtime,
* to get the play position or stop playback of single playing sounds,
* you can use the irrklang::ISound interface.
* irrklang::ISoundEngine::play2D (but also play3D) returns
* a pointer to this interface when its third ('startPaused') or fourth ('track') parameter
* was set to true:
*
* \code
* 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;
* }
* \endcode
*
* 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.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
* \section soundSources Using Sound Sources
*
* To be more flexible playing back sounds, irrKlang uses the concept of sound sources.
* A sound source can be simply the name of a sound file, such as "sound.wav". It is possible
* to add "sound.wav" as sound source to irrKlang, and play it using the sound source pointer:
*
* \code
* 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
* \endcode
*
* 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:
*
* \code
* 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);
* \endcode
*
* It is also possible to have multiple settings for the same sound file:
*
* \code
* 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.
* \endcode
*
* 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.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section sound3d 3D Sound
*
* There is nothing difficult in playing sounds in 3D using irrKlang: Instead of using
* irrklang::ISoundEngine::play2D(), just use irrklang::ISoundEngine::play3D(), which
* takes a 3D position as additional parameter:
*
* \code
* irrklang::vec3df position(23,70,90);
* engine->play3D("yourSound.wav", position);
* \endcode
*
* 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 @ref soundSources) or set these values after you have started the sound paused:
*
* \code
* 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
* }
* \endcode
*
* 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:
*
* \code
* if (snd)
* snd->setPosition(newPosition);
* \endcode
*
* 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:
*
* \code
* if (snd)
* {
* snd->drop();
* snd = 0;
* }
* \endcode
*
* To update the position of yourself, the listener of the 3D sounds, use this from
* time to time:
*
* \code
* 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);
* \endcode
*
* <br/>
* <br/>
* <br/>
* <br/>
*
*
* \section removingSounds Removing Sounds
*
* irrKlang manages the memory usage of sounds by itself, so usually, you don't have
* to care about memory management. But if you know you need to reduce the
* amount of used memory at a certain point in your program, you can do this:
*
* \code
* engine->removeAllSoundSources();
* \endcode
*
* This will remove all sounds and also cause all sounds to be stopped. To remove single
* sounds from the engine, use:
*
* \code
* engine->removeSoundSource(pointerToSomeSoundSource);
* // or:
* engine->removeSoundSource("nameOfASoundFile.wav");
* \endcode
*
* 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.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section events Using Sound Events
*
* In order to wait for a sound to be finished, it is simply possible to
* poll irrklang::ISound::isFinished(). Another way would be to constantly use
* irrklang::ISoundEngine::isCurrentlyPlaying to test wether a sound with that name or source
* is currently playing. But of course, an event based approach is a lot nicer. That's why irrKlang
* supports sound events.<br/>
* The key to sound events is the method
* \link irrklang::ISound::setSoundStopEventReceiver setSoundStopEventReceiver \endlink
* of the irrklang::ISound interface
* (See @ref changingSounds on how to get the ISound interface):
*
* \code
* irrklang::ISound* snd = engine->play2D("speech.mp3", false, false, true);
* if (snd)
* snd->setSoundStopEventReceiver(yourEventReceiver, 0);
* \endcode
*
* 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.<br/>
* A whole implementation could look like this:
*
* \code
* 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
* \endcode
*
* 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.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section memoryPlayback Memory Playback
*
* Using irrKlang, it is easily possible to play sounds directly from memory instead out of
* files. There is an example project showing this: In the SDK, in /examples/03.MemoryPlayback.
* But in short, it simply works by adding the memory as sound source (See @ref soundSources for
* details about sound sources):
*
* \code
* engine->addSoundSourceFromMemory(pointerToMemory, memorySize, "nameforthesound.wav");
*
* // play sound now
* engine->play2D("nameforthesound.wav");
* \endcode
*
* Or using a sound source pointer:
*
* \code
* irrklang::ISoundSource* snd =
* engine->addSoundSourceFromMemory(pointerToMemory, memorySize, "nameforthesound.wav");
*
* // play sound now
* engine->play2D(snd);
* \endcode
*
* Note: It is also possible to overwrite the file access directly, don't use this Memory Playback
* feature for this. See @ref fileOverriding for details.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section effects Sound Effects
*
* irrKlang supports the effects Chorus, Compressor, Distortion, Echo, Flanger
* Gargle, 3DL2Reverb, ParamEq and WavesReverb, when using the sound driver
* irrklang::ESOD_DIRECT_SOUND_8, which selected by default when using Windows.<br/>
*
* 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():
*
* \code
* 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();
* \endcode
*
* 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.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section fileOverriding Overriding File Access
*
* It is possible to let irrKlang use your own file access functions.
* This is useful if you want to read sounds from other sources than
* just files, for example from custom internet streams or
* an own encypted archive format. There is an example in the SDK in
* examples/04.OverrideFileAccess which shows this as well.<br/>
*
* The only thing to do for this is to implement your own irrklang::IFileFactory,
* and set it in irrKlang using irrklang::ISoundEngine::addFileFactory():
*
* \code
* // 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();
* \endcode
*
* For a full example implementation, just take a look into the SDK in examples/04.OverrideFileAccess.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section audioDecoders Adding Audio Decoders
*
* To add support for new file formats, it is possible to add new audio decoders
* to irrKlang.
* The only thing to do for this is to implement your own irrklang::IAudioStreamLoader,
* and irrklang::IAudioStream, and set it in irrKlang using
* irrklang::ISoundEngine::registerAudioStreamLoader():
*
* \code
* 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();
* \endcode
*
* There is an example audio decoder and loader with full source in plugins/ikpMP3, which
* adds MP3 audio decoding capabilities to irrKlang.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section plugins Creating irrKlang Plugins
*
* irrKlang plugins are ikp*.dll (Windows), ikp*.so (Unix) or ikp*.dylib (MacOS)
* files which are loaded by irrKlang at startup when the
* irrklang::ESEO_LOAD_PLUGINS was set (which is default) or
* irrklang::ISoundEngine::loadPlugins() was called. <br/>
*
* The plugin only needs to contain the following function which will be called by irrKlang:
*
* \code
* #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
* }
* \endcode
*
* In there, it is for example possible to extend irrKlang with new audio decoders,
* see @ref audioDecoders for details. <br/>
*
* There is an example plugin with full source in plugins/ikpMP3, which
* adds MP3 audio decoding capabilities to irrKlang.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section staticLib Using irrKlang as static Lib
*
* If you don't want to use the irrKlang.DLL file and link irrKlang statically, you can do this
* by simply linking to the irrKlang.lib in the bin/win32-visualstudio_lib folder. This folder
* will only available in the pro versions of irrKlang, which you get when purchasing an irrKlang
* license.
*
* To use irrKlang in this way, just define IRRKLANG_STATIC before including irrklang.h, like this:
*
* \code
* #define IRRKLANG_STATIC
* #include <irrKlang.h>
* \endcode
*
* Of course, IRRKLANG_STATIC can also simply be defined in the project/compiler settings instead of
* in the source file.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section enumeratingDevices Enumerating sound devices
*
* irrKlang uses the default sound device when playing sound when started without parameters. But if you want
* irrKlang to playback sound on one specific sound device, you may want to enumerate the available
* sound devices on your system and select one of them. Use irrklang::createSoundDeviceList() for this.
* This example code shows how to print a list of all available sound devices on the current system and lets
* the user choose one of them:
*
* \code
* 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
* }
* \endcode
*
* 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.<br/>
* 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.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section recordingAudio Recording Audio
*
* irrKlang is able to record audio from sound capturing devices such as microphones (currently only
* supported in windows). Use the irrklang::IAudioRecorder interface to do this. The following example shows how
* to record some audio and play it back again using the engine:
*
* \code
* 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;
* }
* \endcode
*
* 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:
*
* \code
* // 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);
*
* \endcode
*
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
*
* \section quickstartexample Quick Start Example
*
* To simply start the engine and play a mp3 file, use code like this:
*
* \code
* #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;
* }
* \endcode
*
* A mp3 file is being played until the user presses enter in this example.
* As you can see, irrKlang uses <A HREF="namespaces.html">namespaces</A>, 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
*
* \code
* using namespace irrklang;
* \endcode
* in front of your code, as also shown in the next example.
* <br/>
* <br/>
* <br/>
* <br/>
*
*
*
* \section quickstartexample2 Quick Start Example 2
*
* The following is a simple interactive application, starting up the sound engine and
* playing some streaming .ogg music file and a .wav sound effect every time the user
* presses a key.
*
* \code
* #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;
* }
*
* \endcode
*/
#if defined(IRRKLANG_STATIC)
#define IRRKLANG_API
#else
#if (defined(WIN32) || defined(WIN64) || defined(_MSC_VER))
#ifdef IRRKLANG_EXPORTS
#define IRRKLANG_API __declspec(dllexport)
#else
#define IRRKLANG_API __declspec(dllimport)
#endif // IRRKLANG_EXPORT
#else
#define IRRKLANG_API __attribute__((visibility("default")))
#endif // defined(WIN32) || defined(WIN64)
#endif // IRRKLANG_STATIC
#if defined(_STDCALL_SUPPORTED)
#define IRRKLANGCALLCONV __stdcall // Declare the calling convention.
#else
#define IRRKLANGCALLCONV
#endif // STDCALL_SUPPORTED
//! Everything in the irrKlang Sound Engine can be found in this namespace.
namespace irrklang
{
//! Creates an irrKlang device. The irrKlang device is the root object for using the sound engine.
/** \param driver The sound output driver to be used for sound output. Use irrklang::ESOD_AUTO_DETECT
to let irrKlang decide which driver will be best.
\param options A combination of irrklang::E_SOUND_ENGINE_OPTIONS literals. Default value is
irrklang::ESEO_DEFAULT_OPTIONS.
\param deviceID Some additional optional deviceID for the audio driver. If not needed, simple
set this to 0.
This can be used for example to set a specific ALSA output pcm device for output
("default" or "hw", for example). For most driver types, available deviceIDs can be
enumerated using createSoundDeviceList().
See @ref enumeratingDevices for an example or ISoundDeviceList or details.
\param sdk_version_do_not_use Don't use or change this parameter. Always set it to
IRRKLANG_SDK_VERSION, which is done by default. This is needed for sdk version checks.
\return Returns pointer to the created irrKlang device or null if the
device could not be created. If you don't need the device, use ISoundEngine::drop() to
delete it. See IRefCounted::drop() for details.
*/
IRRKLANG_API ISoundEngine* IRRKLANGCALLCONV createIrrKlangDevice(
E_SOUND_OUTPUT_DRIVER driver = ESOD_AUTO_DETECT,
int options = ESEO_DEFAULT_OPTIONS,
const char* deviceID = 0,
const char* sdk_version_do_not_use = IRR_KLANG_VERSION);
//! Creates a list of available sound devices for the driver type.
/** The device IDs in this list can be used as parameter to createIrrKlangDevice() to
make irrKlang use a special sound device. See @ref enumeratingDevices for an example on how
to use this.
\param driver The sound output driver of which the list is generated. Set it irrklang::ESOD_AUTO_DETECT
to let this function use the same device as createIrrKlangDevice() would choose.
\param sdk_version_do_not_use Don't use or change this parameter. Always set it to
IRRKLANG_SDK_VERSION, which is done by default. This is needed for sdk version checks.
\return Returns a pointer to the list of enumerated sound devices for the selected sound driver.
The device IDs in this list can be used as parameter to createIrrKlangDevice() to
make irrKlang use a special sound device.
After you don't need the list anymore, call ISoundDeviceList::drop() in order to free its memory. */
IRRKLANG_API ISoundDeviceList* IRRKLANGCALLCONV createSoundDeviceList(
E_SOUND_OUTPUT_DRIVER driver = ESOD_AUTO_DETECT,
const char* sdk_version_do_not_use = IRR_KLANG_VERSION);
//! Creates an irrKlang audio recording device. The IAudioRecorder is the root object for recording audio.
/** If you want to play back recorded audio as well, create the ISoundEngine first using
createIrrKlangDevice() and then the IAudioRecorder using createIrrKlangAudioRecorder(), where
you set the ISoundEngine as first parameter. See @ref recordingAudio for an example on how to use this.
Note: audio recording is a very new feature a still beta in irrKlang. It currently only works in Windows
and with DirectSound (subject to change).
\param irrKlangDeviceForPlayback A pointer to the already existing sound device used for playback
of audio. Sound sources recorded with the IAudioRecorder will be added into that device so that
they can be played back there.
\param driver The sound output driver to be used for recording audio. Use irrklang::ESOD_AUTO_DETECT
to let irrKlang decide which driver will be best.
\param deviceID Some additional optional deviceID for the audio driver. If not needed, simple
set this to 0. Use createAudioRecorderDeviceList() to get a list of all deviceIDs.
\param sdk_version_do_not_use Don't use or change this parameter. Always set it to
IRRKLANG_SDK_VERSION, which is done by default. This is needed for sdk version checks.
\return Returns pointer to the created irrKlang device or null if the
device could not be created. If you don't need the device, use ISoundEngine::drop() to
delete it. See IRefCounted::drop() for details.
*/
IRRKLANG_API IAudioRecorder* IRRKLANGCALLCONV createIrrKlangAudioRecorder(
ISoundEngine* irrKlangDeviceForPlayback,
E_SOUND_OUTPUT_DRIVER driver = ESOD_AUTO_DETECT,
const char* deviceID = 0,
const char* sdk_version_do_not_use = IRR_KLANG_VERSION);
//! Creates a list of available recording devices for the driver type.
/** The device IDs in this list can be used as parameter to createIrrKlangAudioRecorder() to
make irrKlang use a special recording device.
\param driver The sound output driver of which the list is generated. Set it irrklang::ESOD_AUTO_DETECT
to let this function use the same device as createIrrKlangDevice() would choose.
\param sdk_version_do_not_use Don't use or change this parameter. Always set it to
IRRKLANG_SDK_VERSION, which is done by default. This is needed for sdk version checks.
\return Returns a pointer to the list of enumerated recording devices for the selected sound driver.
The device IDs in this list can be used as parameter to createIrrKlangAudioRecorder() to
make irrKlang use a special sound device.
After you don't need the list anymore, call ISoundDeviceList::drop() in order to free its memory. */
IRRKLANG_API ISoundDeviceList* IRRKLANGCALLCONV createAudioRecorderDeviceList(
E_SOUND_OUTPUT_DRIVER driver = ESOD_AUTO_DETECT,
const char* sdk_version_do_not_use = IRR_KLANG_VERSION);
} // end namespace irrklang
/*! \file irrKlang.h
\brief Main header file of the irrKlang sound library, the only file needed to include.
*/
#endif

Binary file not shown.

Binary file not shown.