SoundSceneNode

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
RdR
Competition winner
Posts: 273
Joined: Tue Mar 29, 2011 2:58 pm
Contact:

SoundSceneNode

Post by RdR »

Hello All,

Here a SoundSceneNode we use in our TANK@WAR project.
It uses cAudio but can easily changed to another sound lib


SoundSceneNode.h

Code: Select all

 
/*
 * SoundSceneNode.h
 *
 * Tank @ War Project
 */
 
#ifndef SOUNDSCENENODE_H_
#define SOUNDSCENENODE_H_
 
#include <irrlicht.h>
#include <cAudio.h>
 
namespace irr {
namespace scene {
 
#ifdef MAKE_IRR_ID
const int SOUND_SCENE_NODE_ID = MAKE_IRR_ID('s','n','d','n');
#else
const int SOUND_SCENE_NODE_ID = 'sndn';
#endif // MAKE_IRR_ID
class SoundSceneNode: public scene::ISceneNode {
private:
    core::aabbox3df box;
    cAudio::IAudioSource* sound;
    cAudio::IAudioManager* soundManager;
    bool deleteWhenFinished;
    f32 soundVolume;
 
public:
    /**
     * Constructor of SoundSceneNode
     * @param sound
     * @param soundManager
     * @param parent
     * @param smgr
     */
    SoundSceneNode(cAudio::IAudioSource* sound, cAudio::IAudioManager* soundManager, scene::ISceneNode* parent, scene::ISceneManager* smgr);
 
    /**
     * Destructor
     */
    virtual ~SoundSceneNode();
 
    /**
     * Set delete when finished
     * @param deleteWhenFinished
     */
    void setDeleteWhenFinished(bool deleteWhenFinished);
 
    /**
     * On register scene node
     */
    virtual void OnRegisterSceneNode();
 
    /**
     * Render
     */
    virtual void render();
 
    /**
     * On Animate
     * @param timeMs
     */
    virtual void OnAnimate(u32 timeMs);
 
    /**
     * Get AA bounding box
     */
    virtual const core::aabbox3d<f32>& getBoundingBox() const;
 
    /**
     * Set bounding box
     * @param box
     */
    void setBoundingBox(const core::aabbox3df box);
 
    /**
     * Get type
     * @return type
     */
    virtual scene::ESCENE_NODE_TYPE getType() const;
 
    /**
     * Get sound source
     * @return sound
     */
    cAudio::IAudioSource* getSound() const;
 
    /**
     * Get sound volume
     * @return soundVolume
     */
    f32 getVolume() const;
 
    /**
     * Set sound volume
     * @param volume
     */
    void setVolume(const f32 volume);
 
    /**
     * Convert irrlicht to cAudio vector
     * @param v
     * @return vector
     */
    static cAudio::cVector3 irrlichtToCAudioVector(core::vector3df v);
 
    /**
     * Convert cAudio to irrlicht vector
     * @param v
     * @return vector
     */
    static core::vector3df cAudioToIrrlichtVector(cAudio::cVector3 v);
};
 
} // end namespace scene
 
} // end namespace irr
 
#endif /* SOUNDSCENENODE_H_ */
 
 
SoundSceneNode.cpp

Code: Select all

 
// (c) Tank @ War
 
#include "SoundSceneNode.h"
 
using namespace irr;
using namespace scene;
 
SoundSceneNode::SoundSceneNode(cAudio::IAudioSource* sound, cAudio::IAudioManager* soundManager, scene::ISceneNode* parent, scene::ISceneManager* smgr) :
        scene::ISceneNode(parent, smgr, -1) {
    this->sound = sound;
    this->soundManager = soundManager;
    deleteWhenFinished = true;
    box = core::aabbox3df(0, 0, 0, 0, 0, 0);
 
    if (sound) {
        // Play sound
        cAudio::cVector3 position = irrlichtToCAudioVector(getAbsolutePosition());
        sound->setPosition(position);
        soundVolume = sound->getVolume();
        if (sound->getVolume() == 0) {
            soundVolume = -1;
        }
 
        OnAnimate(0);
        sound->play3d(position, sound->getStrength(), sound->isLooping());
    }
}
 
SoundSceneNode::~SoundSceneNode() {
    if (sound) {
        if (sound->isPlaying()) {
            sound->stop();
        }
        soundManager->release(sound);
    }
}
 
void SoundSceneNode::setDeleteWhenFinished(bool deleteWhenFinished) {
    this->deleteWhenFinished = deleteWhenFinished;
}
 
void SoundSceneNode::OnRegisterSceneNode() {
    ISceneNode::OnRegisterSceneNode();
}
 
void SoundSceneNode::render() {
}
 
void SoundSceneNode::OnAnimate(u32 timeMs) {
    if (sound) {
        // Move to new position
        sound->move(irrlichtToCAudioVector(getAbsolutePosition()));
 
        // Get transformed bounding box
        const core::aabbox3df transformedBox = getTransformedBoundingBox();
        core::vector3df listenerPosition = cAudioToIrrlichtVector(soundManager->getListener()->getPosition());
 
        // Get distance from position
        f32 distance = 0;
        if (box.getVolume() == 0) {
            distance = listenerPosition.getDistanceFrom(getAbsolutePosition());
        }
        // Get distance from bounding box
        else if (!transformedBox.isPointInside(listenerPosition)) {
            irr::core::vector3df edges[8];
            transformedBox.getEdges(edges);
 
            // Create planes
            irr::core::plane3df planes[6];
            planes[0] = irr::core::plane3df(edges[3], edges[1], edges[0]); // Left plane
            planes[1] = irr::core::plane3df(edges[5], edges[7], edges[6]); // Right plane
            planes[2] = irr::core::plane3df(edges[1], edges[5], edges[4]); // Front plane
            planes[3] = irr::core::plane3df(edges[7], edges[3], edges[2]); // Back plane
            planes[4] = irr::core::plane3df(edges[3], edges[7], edges[5]); // Top plane
            planes[5] = irr::core::plane3df(edges[0], edges[4], edges[6]); // Bottom plane
 
            // Get distance to nearest plane
            core::vector3df center = transformedBox.getCenter();
            core::vector3df intersectionPosition;
 
            // Get distance to nearest plane
            for (u32 i = 0; i < 6; i++) {
                // Check if there is an intersection with this plane
                if (planes[i].getIntersectionWithLimitedLine(listenerPosition, center, intersectionPosition)) {
                    f32 distanceToPlane = planes[i].getDistanceTo(listenerPosition);
                    if (distance == 0) {
                        distance = distanceToPlane;
                    } else if (distanceToPlane > distance) {
                        distance = distanceToPlane;
                    }
                }
            }
        }
 
        // Set volume
        if (distance > sound->getMaxDistance() || soundVolume <= 0) {
            sound->setVolume(0);
        } else if (distance <= sound->getMinDistance()) {
            sound->setVolume(soundVolume);
        } else {
            f32 gain = (sound->getRolloffFactor() * (distance - sound->getMinDistance()) / (sound->getMaxDistance() - sound->getMinDistance()));
            sound->setVolume(soundVolume - (soundVolume * gain));
        }
 
        // Delete sound when not looping and finished playing
        if (deleteWhenFinished && !sound->isLooping() && sound->isStopped()) {
            SceneManager->addToDeletionQueue(this);
        }
    } else {
        SceneManager->addToDeletionQueue(this);
    }
 
    ISceneNode::OnAnimate(timeMs);
}
 
f32 SoundSceneNode::getVolume() const {
    return soundVolume;
}
 
void SoundSceneNode::setVolume(f32 volume) {
    soundVolume = volume;
    if (soundVolume == 0) {
        sound->setVolume(0);
        soundVolume = -1;
    }
}
 
const core::aabbox3d<f32>& SoundSceneNode::getBoundingBox() const {
    return box;
}
 
void SoundSceneNode::setBoundingBox(const core::aabbox3df box) {
    this->box = box;
}
 
scene::ESCENE_NODE_TYPE SoundSceneNode::getType() const {
    return (scene::ESCENE_NODE_TYPE) SOUND_SCENE_NODE_ID;
}
 
cAudio::IAudioSource* SoundSceneNode::getSound() const {
    return sound;
}
 
cAudio::cVector3 SoundSceneNode::irrlichtToCAudioVector(core::vector3df v) {
    return cAudio::cVector3(v.X, v.Y, v.Z);
}
 
core::vector3df SoundSceneNode::cAudioToIrrlichtVector(cAudio::cVector3 v) {
    return core::vector3df(v.x, v.y, v.z);
}
 
Example:

Code: Select all

 
irr::scene::SoundSceneNode* SoundController::createSoundNode(const irr::c8* filename, scene::ISceneNode* parent, const bool mute, const bool playLooped, const f32 minDist, const f32 maxDist) {
 
    cAudio::IAudioSource* sound = soundManager->create(filename, filename);
    if (sound) {
            if (mute) {
                    sound->setVolume(0);
            } else {
                    sound->setVolume(soundVolume);
            }
            sound->setMinDistance(minDist);
            sound->setMaxAttenuationDistance(maxDist);
            sound->loop(playLooped);
 
            scene::SoundSceneNode* soundNode = new scene::SoundSceneNode(sound, soundManager, parent, DeviceContainer::smgr);
            soundNode->drop();
            return soundNode;
    }
    return 0;
}
 
chronologicaldot
Competition winner
Posts: 685
Joined: Mon Sep 10, 2012 8:51 am

Re: SoundSceneNode

Post by chronologicaldot »

Nice
You said it could be modified for any library, so I take it that includes PortAudio? :D

-----
For those of you who are looking, CAudio files are here:
https://github.com/wildicv/cAudio
RdR
Competition winner
Posts: 273
Joined: Tue Mar 29, 2011 2:58 pm
Contact:

Re: SoundSceneNode

Post by RdR »

chronologicaldot wrote:Nice
You said it could be modified for any library, so I take it that includes PortAudio? :D

-----
For those of you who are looking, CAudio files are here:
https://github.com/wildicv/cAudio
Im not familiar with PortAudio, but I think its not hard to change the node so it works with PortAudio.
Post Reply