Merged changes in the trunk up to revision 25863.
This commit is contained in:
@@ -412,31 +412,6 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
|||||||
// restore
|
// restore
|
||||||
collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
|
collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (collisionShape->isSoftBody()) {
|
|
||||||
btSoftBody* softBody = static_cast<btSoftBody*>(collisionObject);
|
|
||||||
btSoftBody::sRayCast softResult;
|
|
||||||
if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
|
|
||||||
{
|
|
||||||
btCollisionWorld::LocalShapeInfo shapeInfo;
|
|
||||||
shapeInfo.m_shapePart = 0;
|
|
||||||
shapeInfo.m_triangleIndex = softResult.index;
|
|
||||||
// get the normal
|
|
||||||
btVector3 normal = softBody->m_faces[softResult.index].m_normal;
|
|
||||||
btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin();
|
|
||||||
if (normal.dot(rayDir) > 0) {
|
|
||||||
// normal always point toward origin of the ray
|
|
||||||
normal = -normal;
|
|
||||||
}
|
|
||||||
btCollisionWorld::LocalRayResult rayResult
|
|
||||||
(collisionObject,
|
|
||||||
&shapeInfo,
|
|
||||||
normal,
|
|
||||||
softResult.fraction);
|
|
||||||
bool normalInWorldSpace = true;
|
|
||||||
resultCallback.addSingleResult(rayResult,normalInWorldSpace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -354,7 +354,7 @@ public:
|
|||||||
|
|
||||||
/// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
|
/// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
|
||||||
/// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
|
/// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
|
||||||
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
|
virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
|
||||||
|
|
||||||
// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
|
// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
|
||||||
// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
|
// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ subject to the following restrictions:
|
|||||||
#include "btSoftBodyHelpers.h"
|
#include "btSoftBodyHelpers.h"
|
||||||
|
|
||||||
|
|
||||||
|
//#define USE_BRUTEFORCE_RAYBROADPHASE 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -140,3 +141,140 @@ void btSoftRigidDynamicsWorld::debugDrawWorld()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct btSoftSingleRayCallback : public btBroadphaseRayCallback
|
||||||
|
{
|
||||||
|
btVector3 m_rayFromWorld;
|
||||||
|
btVector3 m_rayToWorld;
|
||||||
|
btTransform m_rayFromTrans;
|
||||||
|
btTransform m_rayToTrans;
|
||||||
|
btVector3 m_hitNormal;
|
||||||
|
|
||||||
|
const btSoftRigidDynamicsWorld* m_world;
|
||||||
|
btCollisionWorld::RayResultCallback& m_resultCallback;
|
||||||
|
|
||||||
|
btSoftSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btSoftRigidDynamicsWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
|
||||||
|
:m_rayFromWorld(rayFromWorld),
|
||||||
|
m_rayToWorld(rayToWorld),
|
||||||
|
m_world(world),
|
||||||
|
m_resultCallback(resultCallback)
|
||||||
|
{
|
||||||
|
m_rayFromTrans.setIdentity();
|
||||||
|
m_rayFromTrans.setOrigin(m_rayFromWorld);
|
||||||
|
m_rayToTrans.setIdentity();
|
||||||
|
m_rayToTrans.setOrigin(m_rayToWorld);
|
||||||
|
|
||||||
|
btVector3 rayDir = (rayToWorld-rayFromWorld);
|
||||||
|
|
||||||
|
rayDir.normalize ();
|
||||||
|
///what about division by zero? --> just set rayDirection[i] to INF/1e30
|
||||||
|
m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
|
||||||
|
m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
|
||||||
|
m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
|
||||||
|
m_signs[0] = m_rayDirectionInverse[0] < 0.0;
|
||||||
|
m_signs[1] = m_rayDirectionInverse[1] < 0.0;
|
||||||
|
m_signs[2] = m_rayDirectionInverse[2] < 0.0;
|
||||||
|
|
||||||
|
m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool process(const btBroadphaseProxy* proxy)
|
||||||
|
{
|
||||||
|
///terminate further ray tests, once the closestHitFraction reached zero
|
||||||
|
if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
|
||||||
|
|
||||||
|
//only perform raycast if filterMask matches
|
||||||
|
if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
|
||||||
|
{
|
||||||
|
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
|
||||||
|
//btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
|
||||||
|
#if 0
|
||||||
|
#ifdef RECALCULATE_AABB
|
||||||
|
btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
|
||||||
|
collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
|
||||||
|
#else
|
||||||
|
//getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
|
||||||
|
const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
|
||||||
|
const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
//btScalar hitLambda = m_resultCallback.m_closestHitFraction;
|
||||||
|
//culling already done by broadphase
|
||||||
|
//if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
|
||||||
|
{
|
||||||
|
m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
|
||||||
|
collisionObject,
|
||||||
|
collisionObject->getCollisionShape(),
|
||||||
|
collisionObject->getWorldTransform(),
|
||||||
|
m_resultCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void btSoftRigidDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
|
||||||
|
{
|
||||||
|
BT_PROFILE("rayTest");
|
||||||
|
/// use the broadphase to accelerate the search for objects, based on their aabb
|
||||||
|
/// and for each object with ray-aabb overlap, perform an exact ray test
|
||||||
|
btSoftSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
|
||||||
|
|
||||||
|
#ifndef USE_BRUTEFORCE_RAYBROADPHASE
|
||||||
|
m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
|
||||||
|
#else
|
||||||
|
for (int i=0;i<this->getNumCollisionObjects();i++)
|
||||||
|
{
|
||||||
|
rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
|
||||||
|
}
|
||||||
|
#endif //USE_BRUTEFORCE_RAYBROADPHASE
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void btSoftRigidDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
|
||||||
|
btCollisionObject* collisionObject,
|
||||||
|
const btCollisionShape* collisionShape,
|
||||||
|
const btTransform& colObjWorldTransform,
|
||||||
|
RayResultCallback& resultCallback)
|
||||||
|
{
|
||||||
|
if (collisionShape->isSoftBody()) {
|
||||||
|
btSoftBody* softBody = btSoftBody::upcast(collisionObject);
|
||||||
|
if (softBody) {
|
||||||
|
btSoftBody::sRayCast softResult;
|
||||||
|
if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
|
||||||
|
{
|
||||||
|
if (softResult.fraction<= resultCallback.m_closestHitFraction)
|
||||||
|
{
|
||||||
|
btCollisionWorld::LocalShapeInfo shapeInfo;
|
||||||
|
shapeInfo.m_shapePart = 0;
|
||||||
|
shapeInfo.m_triangleIndex = softResult.index;
|
||||||
|
// get the normal
|
||||||
|
btVector3 normal = softBody->m_faces[softResult.index].m_normal;
|
||||||
|
btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin();
|
||||||
|
if (normal.dot(rayDir) > 0) {
|
||||||
|
// normal must always point toward origin of the ray
|
||||||
|
normal = -normal;
|
||||||
|
}
|
||||||
|
btCollisionWorld::LocalRayResult rayResult
|
||||||
|
(collisionObject,
|
||||||
|
&shapeInfo,
|
||||||
|
normal,
|
||||||
|
softResult.fraction);
|
||||||
|
bool normalInWorldSpace = true;
|
||||||
|
resultCallback.addSingleResult(rayResult,normalInWorldSpace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,collisionObject,collisionShape,colObjWorldTransform,resultCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -77,6 +77,17 @@ public:
|
|||||||
return m_softBodies;
|
return m_softBodies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
|
||||||
|
|
||||||
|
/// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
|
||||||
|
/// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape.
|
||||||
|
/// This allows more customization.
|
||||||
|
static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
|
||||||
|
btCollisionObject* collisionObject,
|
||||||
|
const btCollisionShape* collisionShape,
|
||||||
|
const btTransform& colObjWorldTransform,
|
||||||
|
RayResultCallback& resultCallback);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //BT_SOFT_RIGID_DYNAMICS_WORLD_H
|
#endif //BT_SOFT_RIGID_DYNAMICS_WORLD_H
|
||||||
|
|||||||
49
intern/audaspace/FX/AUD_AccumulatorFactory.cpp
Normal file
49
intern/audaspace/FX/AUD_AccumulatorFactory.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_AccumulatorFactory.h"
|
||||||
|
#include "AUD_AccumulatorReader.h"
|
||||||
|
|
||||||
|
AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_IFactory* factory,
|
||||||
|
bool additive) :
|
||||||
|
AUD_EffectFactory(factory),
|
||||||
|
m_additive(additive) {}
|
||||||
|
|
||||||
|
AUD_AccumulatorFactory::AUD_AccumulatorFactory(bool additive) :
|
||||||
|
AUD_EffectFactory(0),
|
||||||
|
m_additive(additive) {}
|
||||||
|
|
||||||
|
AUD_IReader* AUD_AccumulatorFactory::createReader()
|
||||||
|
{
|
||||||
|
AUD_IReader* reader = getReader();
|
||||||
|
|
||||||
|
if(reader != 0)
|
||||||
|
{
|
||||||
|
reader = new AUD_AccumulatorReader(reader, m_additive);
|
||||||
|
AUD_NEW("reader")
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
59
intern/audaspace/FX/AUD_AccumulatorFactory.h
Normal file
59
intern/audaspace/FX/AUD_AccumulatorFactory.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_ACCUMULATORFACTORY
|
||||||
|
#define AUD_ACCUMULATORFACTORY
|
||||||
|
|
||||||
|
#include "AUD_EffectFactory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This factory creates an accumulator reader.
|
||||||
|
*/
|
||||||
|
class AUD_AccumulatorFactory : public AUD_EffectFactory
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Whether the accumulator is additive.
|
||||||
|
*/
|
||||||
|
bool m_additive;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new accumulator factory.
|
||||||
|
* \param factory The input factory.
|
||||||
|
* \param additive Whether the accumulator is additive.
|
||||||
|
*/
|
||||||
|
AUD_AccumulatorFactory(AUD_IFactory* factory, bool additive = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new accumulator factory.
|
||||||
|
* \param additive Whether the accumulator is additive.
|
||||||
|
*/
|
||||||
|
AUD_AccumulatorFactory(bool additive = false);
|
||||||
|
|
||||||
|
virtual AUD_IReader* createReader();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_ACCUMULATORFACTORY
|
||||||
99
intern/audaspace/FX/AUD_AccumulatorReader.cpp
Normal file
99
intern/audaspace/FX/AUD_AccumulatorReader.cpp
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_AccumulatorReader.h"
|
||||||
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#define CC specs.channels + channel
|
||||||
|
|
||||||
|
AUD_AccumulatorReader::AUD_AccumulatorReader(AUD_IReader* reader,
|
||||||
|
bool additive) :
|
||||||
|
AUD_EffectReader(reader),
|
||||||
|
m_additive(additive)
|
||||||
|
{
|
||||||
|
AUD_Specs specs = reader->getSpecs();
|
||||||
|
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||||
|
|
||||||
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
|
||||||
|
m_sums = new AUD_Buffer(samplesize); AUD_NEW("buffer")
|
||||||
|
memset(m_sums->getBuffer(), 0, samplesize);
|
||||||
|
|
||||||
|
m_prevs = new AUD_Buffer(samplesize); AUD_NEW("buffer")
|
||||||
|
memset(m_prevs->getBuffer(), 0, samplesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_AccumulatorReader::~AUD_AccumulatorReader()
|
||||||
|
{
|
||||||
|
delete m_buffer; AUD_DELETE("buffer")
|
||||||
|
delete m_sums; AUD_DELETE("buffer")
|
||||||
|
delete m_prevs; AUD_DELETE("buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_AccumulatorReader::read(int & length, sample_t* & buffer)
|
||||||
|
{
|
||||||
|
sample_t* buf;
|
||||||
|
sample_t* sums;
|
||||||
|
sample_t* prevs;
|
||||||
|
sums = m_sums->getBuffer();
|
||||||
|
prevs = m_prevs->getBuffer();
|
||||||
|
|
||||||
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
|
|
||||||
|
m_reader->read(length, buf);
|
||||||
|
if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||||
|
m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
|
||||||
|
|
||||||
|
buffer = m_buffer->getBuffer();
|
||||||
|
|
||||||
|
if(m_additive)
|
||||||
|
{
|
||||||
|
for(int channel = 0; channel < specs.channels; channel++)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
if(buf[i * CC] > prevs[channel])
|
||||||
|
sums[channel] += buf[i * CC] - prevs[channel];
|
||||||
|
buffer[i * CC] = sums[channel] + buf[i * CC];
|
||||||
|
prevs[channel] = buf[i * CC];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int channel = 0; channel < specs.channels; channel++)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < length * specs.channels; i++)
|
||||||
|
{
|
||||||
|
if(buf[i * CC] > prevs[channel])
|
||||||
|
sums[channel] += buf[i * CC] - prevs[channel];
|
||||||
|
buffer[i * CC] = sums[channel];
|
||||||
|
prevs[channel] = buf[i * CC];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
intern/audaspace/FX/AUD_AccumulatorReader.h
Normal file
75
intern/audaspace/FX/AUD_AccumulatorReader.h
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_ACCUMULATORREADER
|
||||||
|
#define AUD_ACCUMULATORREADER
|
||||||
|
|
||||||
|
#include "AUD_EffectReader.h"
|
||||||
|
class AUD_Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents an accumulator.
|
||||||
|
*/
|
||||||
|
class AUD_AccumulatorReader : public AUD_EffectReader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The playback buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sums of the specific channels.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_sums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The previous results of the specific channels.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_prevs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the accumulator is additive.
|
||||||
|
*/
|
||||||
|
bool m_additive;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new accumulator reader.
|
||||||
|
* \param reader The reader to read from.
|
||||||
|
* \param additive Whether the accumulator is additive.
|
||||||
|
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||||
|
*/
|
||||||
|
AUD_AccumulatorReader(AUD_IReader* reader, bool additive);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the reader.
|
||||||
|
*/
|
||||||
|
virtual ~AUD_AccumulatorReader();
|
||||||
|
|
||||||
|
virtual void read(int & length, sample_t* & buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_ACCUMULATORREADER
|
||||||
49
intern/audaspace/FX/AUD_ButterworthFactory.cpp
Normal file
49
intern/audaspace/FX/AUD_ButterworthFactory.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_ButterworthFactory.h"
|
||||||
|
#include "AUD_ButterworthReader.h"
|
||||||
|
|
||||||
|
AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory,
|
||||||
|
float frequency) :
|
||||||
|
AUD_EffectFactory(factory),
|
||||||
|
m_frequency(frequency) {}
|
||||||
|
|
||||||
|
AUD_ButterworthFactory::AUD_ButterworthFactory(float frequency) :
|
||||||
|
AUD_EffectFactory(0),
|
||||||
|
m_frequency(frequency) {}
|
||||||
|
|
||||||
|
AUD_IReader* AUD_ButterworthFactory::createReader()
|
||||||
|
{
|
||||||
|
AUD_IReader* reader = getReader();
|
||||||
|
|
||||||
|
if(reader != 0)
|
||||||
|
{
|
||||||
|
reader = new AUD_ButterworthReader(reader, m_frequency);
|
||||||
|
AUD_NEW("reader")
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
59
intern/audaspace/FX/AUD_ButterworthFactory.h
Normal file
59
intern/audaspace/FX/AUD_ButterworthFactory.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_BUTTERWORTHFACTORY
|
||||||
|
#define AUD_BUTTERWORTHFACTORY
|
||||||
|
|
||||||
|
#include "AUD_EffectFactory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This factory creates a butterworth filter reader.
|
||||||
|
*/
|
||||||
|
class AUD_ButterworthFactory : public AUD_EffectFactory
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The attack value in seconds.
|
||||||
|
*/
|
||||||
|
float m_frequency;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new butterworth factory.
|
||||||
|
* \param factory The input factory.
|
||||||
|
* \param frequency The cutoff frequency.
|
||||||
|
*/
|
||||||
|
AUD_ButterworthFactory(AUD_IFactory* factory, float frequency);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new butterworth factory.
|
||||||
|
* \param frequency The cutoff frequency.
|
||||||
|
*/
|
||||||
|
AUD_ButterworthFactory(float frequency);
|
||||||
|
|
||||||
|
virtual AUD_IReader* createReader();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_BUTTERWORTHFACTORY
|
||||||
124
intern/audaspace/FX/AUD_ButterworthReader.cpp
Normal file
124
intern/audaspace/FX/AUD_ButterworthReader.cpp
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_ButterworthReader.h"
|
||||||
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BWPB41 0.76536686473
|
||||||
|
#define BWPB42 1.84775906502
|
||||||
|
#define CC channels + channel
|
||||||
|
|
||||||
|
AUD_ButterworthReader::AUD_ButterworthReader(AUD_IReader* reader,
|
||||||
|
float frequency) :
|
||||||
|
AUD_EffectReader(reader)
|
||||||
|
{
|
||||||
|
AUD_Specs specs = reader->getSpecs();
|
||||||
|
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||||
|
|
||||||
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
|
||||||
|
m_outvalues = new AUD_Buffer(samplesize * 5); AUD_NEW("buffer")
|
||||||
|
memset(m_outvalues->getBuffer(), 0, samplesize * 5);
|
||||||
|
|
||||||
|
m_invalues = new AUD_Buffer(samplesize * 5); AUD_NEW("buffer")
|
||||||
|
memset(m_invalues->getBuffer(), 0, samplesize * 5);
|
||||||
|
|
||||||
|
m_position = 0;
|
||||||
|
|
||||||
|
// calculate coefficients
|
||||||
|
float omega = 2 * tan(frequency * M_PI / specs.rate);
|
||||||
|
float o2 = omega * omega;
|
||||||
|
float o4 = o2 * o2;
|
||||||
|
float x1 = o2 + 2 * BWPB41 * omega + 4;
|
||||||
|
float x2 = o2 + 2 * BWPB42 * omega + 4;
|
||||||
|
float y1 = o2 - 2 * BWPB41 * omega + 4;
|
||||||
|
float y2 = o2 - 2 * BWPB42 * omega + 4;
|
||||||
|
float o228 = 2 * o2 - 8;
|
||||||
|
float norm = x1 * x2;
|
||||||
|
m_coeff[0][0] = 0;
|
||||||
|
m_coeff[0][1] = (x1 + x2) * o228 / norm;
|
||||||
|
m_coeff[0][2] = (x1 * y2 + x2 * y1 + o228 * o228) / norm;
|
||||||
|
m_coeff[0][3] = (y1 + y2) * o228 / norm;
|
||||||
|
m_coeff[0][4] = y1 * y2 / norm;
|
||||||
|
m_coeff[1][4] = m_coeff[1][0] = o4 / norm;
|
||||||
|
m_coeff[1][3] = m_coeff[1][1] = 4 * o4 / norm;
|
||||||
|
m_coeff[1][2] = 6 * o4 / norm;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_ButterworthReader::~AUD_ButterworthReader()
|
||||||
|
{
|
||||||
|
delete m_buffer; AUD_DELETE("buffer")
|
||||||
|
|
||||||
|
delete m_outvalues; AUD_DELETE("buffer")
|
||||||
|
delete m_invalues; AUD_DELETE("buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_ButterworthReader::read(int & length, sample_t* & buffer)
|
||||||
|
{
|
||||||
|
sample_t* buf;
|
||||||
|
sample_t* outvalues;
|
||||||
|
sample_t* invalues;
|
||||||
|
|
||||||
|
outvalues = m_outvalues->getBuffer();
|
||||||
|
invalues = m_invalues->getBuffer();
|
||||||
|
|
||||||
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
|
|
||||||
|
m_reader->read(length, buf);
|
||||||
|
|
||||||
|
if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||||
|
m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
|
||||||
|
|
||||||
|
buffer = m_buffer->getBuffer();
|
||||||
|
int channels = specs.channels;
|
||||||
|
|
||||||
|
for(int channel = 0; channel < channels; channel++)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
invalues[m_position * CC] = buf[i * CC];
|
||||||
|
outvalues[m_position * CC] = 0;
|
||||||
|
|
||||||
|
for(int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
outvalues[m_position * CC] += m_coeff[1][j] *
|
||||||
|
invalues[((m_position + j) % 5) * CC] -
|
||||||
|
m_coeff[0][j] *
|
||||||
|
outvalues[((m_position + j) % 5) * CC];
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[i * CC] = outvalues[m_position * CC];
|
||||||
|
|
||||||
|
m_position = (m_position + 4) % 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
83
intern/audaspace/FX/AUD_ButterworthReader.h
Normal file
83
intern/audaspace/FX/AUD_ButterworthReader.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_BUTTERWORTHREADER
|
||||||
|
#define AUD_BUTTERWORTHREADER
|
||||||
|
|
||||||
|
#include "AUD_EffectReader.h"
|
||||||
|
class AUD_Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a butterworth filter.
|
||||||
|
*/
|
||||||
|
class AUD_ButterworthReader : public AUD_EffectReader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The playback buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last out values buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_outvalues;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last in values buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_invalues;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The position for buffer cycling.
|
||||||
|
*/
|
||||||
|
int m_position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter coefficients.
|
||||||
|
*/
|
||||||
|
float m_coeff[2][5];
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new butterworth reader.
|
||||||
|
* \param reader The reader to read from.
|
||||||
|
* \param attack The attack value in seconds.
|
||||||
|
* \param release The release value in seconds.
|
||||||
|
* \param threshold The threshold value.
|
||||||
|
* \param arthreshold The attack/release threshold value.
|
||||||
|
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||||
|
*/
|
||||||
|
AUD_ButterworthReader(AUD_IReader* reader, float frequency);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the reader.
|
||||||
|
*/
|
||||||
|
virtual ~AUD_ButterworthReader();
|
||||||
|
|
||||||
|
virtual void read(int & length, sample_t* & buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_BUTTERWORTHREADER
|
||||||
@@ -77,31 +77,26 @@ void AUD_DelayReader::read(int & length, sample_t* & buffer)
|
|||||||
{
|
{
|
||||||
if(m_remdelay > 0)
|
if(m_remdelay > 0)
|
||||||
{
|
{
|
||||||
int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
|
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||||
|
|
||||||
if(m_buffer->getSize() < length*samplesize)
|
if(m_buffer->getSize() < length * samplesize)
|
||||||
m_buffer->resize(length*samplesize);
|
m_buffer->resize(length * samplesize);
|
||||||
|
|
||||||
if(length > m_remdelay)
|
if(length > m_remdelay)
|
||||||
{
|
{
|
||||||
if(getSpecs().format == AUD_FORMAT_U8)
|
memset(m_buffer->getBuffer(), 0, m_remdelay * samplesize);
|
||||||
memset(m_buffer->getBuffer(), 0x80, m_remdelay*samplesize);
|
|
||||||
else
|
|
||||||
memset(m_buffer->getBuffer(), 0, m_remdelay*samplesize);
|
|
||||||
int len = length - m_remdelay;
|
int len = length - m_remdelay;
|
||||||
m_reader->read(len, buffer);
|
m_reader->read(len, buffer);
|
||||||
memcpy(m_buffer->getBuffer()+m_remdelay*samplesize,
|
memcpy(m_buffer->getBuffer() + m_remdelay * specs.channels,
|
||||||
buffer, len*samplesize);
|
buffer, len * samplesize);
|
||||||
if(len < length-m_remdelay)
|
if(len < length-m_remdelay)
|
||||||
length = m_remdelay + len;
|
length = m_remdelay + len;
|
||||||
m_remdelay = 0;
|
m_remdelay = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(getSpecs().format == AUD_FORMAT_U8)
|
memset(m_buffer->getBuffer(), 0, length * samplesize);
|
||||||
memset(m_buffer->getBuffer(), 0x80, length*samplesize);
|
|
||||||
else
|
|
||||||
memset(m_buffer->getBuffer(), 0, length*samplesize);
|
|
||||||
m_remdelay -= length;
|
m_remdelay -= length;
|
||||||
}
|
}
|
||||||
buffer = m_buffer->getBuffer();
|
buffer = m_buffer->getBuffer();
|
||||||
|
|||||||
@@ -137,15 +137,16 @@ void AUD_DoubleReader::read(int & length, sample_t* & buffer)
|
|||||||
m_reader1->read(len, buffer);
|
m_reader1->read(len, buffer);
|
||||||
if(len < length)
|
if(len < length)
|
||||||
{
|
{
|
||||||
int samplesize = AUD_SAMPLE_SIZE(m_reader1->getSpecs());
|
AUD_Specs specs = m_reader1->getSpecs();
|
||||||
|
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||||
if(m_buffer->getSize() < length * samplesize)
|
if(m_buffer->getSize() < length * samplesize)
|
||||||
m_buffer->resize(length * samplesize);
|
m_buffer->resize(length * samplesize);
|
||||||
memcpy(m_buffer->getBuffer(), buffer, len*samplesize);
|
memcpy(m_buffer->getBuffer(), buffer, len * samplesize);
|
||||||
len = length - len;
|
len = length - len;
|
||||||
length -= len;
|
length -= len;
|
||||||
m_reader2->read(len, buffer);
|
m_reader2->read(len, buffer);
|
||||||
memcpy(m_buffer->getBuffer() + length*samplesize,
|
memcpy(m_buffer->getBuffer() + length * specs.channels, buffer,
|
||||||
buffer, len*samplesize);
|
len * samplesize);
|
||||||
length += len;
|
length += len;
|
||||||
buffer = m_buffer->getBuffer();
|
buffer = m_buffer->getBuffer();
|
||||||
m_finished1 = true;
|
m_finished1 = true;
|
||||||
|
|||||||
58
intern/audaspace/FX/AUD_EnvelopeFactory.cpp
Normal file
58
intern/audaspace/FX/AUD_EnvelopeFactory.cpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_EnvelopeFactory.h"
|
||||||
|
#include "AUD_EnvelopeReader.h"
|
||||||
|
|
||||||
|
AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
|
||||||
|
float release, float threshold,
|
||||||
|
float arthreshold) :
|
||||||
|
AUD_EffectFactory(factory),
|
||||||
|
m_attack(attack),
|
||||||
|
m_release(release),
|
||||||
|
m_threshold(threshold),
|
||||||
|
m_arthreshold(arthreshold) {}
|
||||||
|
|
||||||
|
AUD_EnvelopeFactory::AUD_EnvelopeFactory(float attack, float release,
|
||||||
|
float threshold, float arthreshold) :
|
||||||
|
AUD_EffectFactory(0),
|
||||||
|
m_attack(attack),
|
||||||
|
m_release(release),
|
||||||
|
m_threshold(threshold),
|
||||||
|
m_arthreshold(arthreshold) {}
|
||||||
|
|
||||||
|
AUD_IReader* AUD_EnvelopeFactory::createReader()
|
||||||
|
{
|
||||||
|
AUD_IReader* reader = getReader();
|
||||||
|
|
||||||
|
if(reader != 0)
|
||||||
|
{
|
||||||
|
reader = new AUD_EnvelopeReader(reader, m_attack, m_release,
|
||||||
|
m_threshold, m_arthreshold);
|
||||||
|
AUD_NEW("reader")
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
82
intern/audaspace/FX/AUD_EnvelopeFactory.h
Normal file
82
intern/audaspace/FX/AUD_EnvelopeFactory.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_ENVELOPEFACTORY
|
||||||
|
#define AUD_ENVELOPEFACTORY
|
||||||
|
|
||||||
|
#include "AUD_EffectFactory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This factory creates an envelope follower reader.
|
||||||
|
*/
|
||||||
|
class AUD_EnvelopeFactory : public AUD_EffectFactory
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The attack value in seconds.
|
||||||
|
*/
|
||||||
|
float m_attack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The release value in seconds.
|
||||||
|
*/
|
||||||
|
float m_release;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The threshold value.
|
||||||
|
*/
|
||||||
|
float m_threshold;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attack/release threshold value.
|
||||||
|
*/
|
||||||
|
float m_arthreshold;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new envelope factory.
|
||||||
|
* \param factory The input factory.
|
||||||
|
* \param attack The attack value in seconds.
|
||||||
|
* \param release The release value in seconds.
|
||||||
|
* \param threshold The threshold value.
|
||||||
|
* \param arthreshold The attack/release threshold value.
|
||||||
|
*/
|
||||||
|
AUD_EnvelopeFactory(AUD_IFactory* factory, float attack, float release,
|
||||||
|
float threshold, float arthreshold);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new envelope factory.
|
||||||
|
* \param attack The attack value in seconds.
|
||||||
|
* \param release The release value in seconds.
|
||||||
|
* \param threshold The threshold value.
|
||||||
|
* \param arthreshold The attack/release threshold value.
|
||||||
|
*/
|
||||||
|
AUD_EnvelopeFactory(float attack, float release, float threshold,
|
||||||
|
float arthreshold);
|
||||||
|
|
||||||
|
virtual AUD_IReader* createReader();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_ENVELOPEFACTORY
|
||||||
86
intern/audaspace/FX/AUD_EnvelopeReader.cpp
Normal file
86
intern/audaspace/FX/AUD_EnvelopeReader.cpp
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_EnvelopeReader.h"
|
||||||
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
AUD_EnvelopeReader::AUD_EnvelopeReader(AUD_IReader* reader, float attack,
|
||||||
|
float release, float threshold,
|
||||||
|
float arthreshold) :
|
||||||
|
AUD_EffectReader(reader),
|
||||||
|
m_threshold(threshold)
|
||||||
|
{
|
||||||
|
AUD_Specs specs = reader->getSpecs();
|
||||||
|
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||||
|
|
||||||
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
|
||||||
|
m_envelopes = new AUD_Buffer(samplesize);
|
||||||
|
AUD_NEW("buffer")
|
||||||
|
memset(m_envelopes->getBuffer(), 0, samplesize);
|
||||||
|
|
||||||
|
m_bAttack = pow(arthreshold, 1.0f/(specs.rate * attack));
|
||||||
|
m_bRelease = pow(arthreshold, 1.0f/(specs.rate * release));
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_EnvelopeReader::~AUD_EnvelopeReader()
|
||||||
|
{
|
||||||
|
delete m_buffer; AUD_DELETE("buffer")
|
||||||
|
delete m_envelopes; AUD_DELETE("buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_EnvelopeReader::read(int & length, sample_t* & buffer)
|
||||||
|
{
|
||||||
|
sample_t* buf;
|
||||||
|
sample_t* envelopes;
|
||||||
|
envelopes = m_envelopes->getBuffer();
|
||||||
|
|
||||||
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
|
|
||||||
|
m_reader->read(length, buf);
|
||||||
|
if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||||
|
m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
|
||||||
|
|
||||||
|
buffer = m_buffer->getBuffer();
|
||||||
|
|
||||||
|
sample_t value;
|
||||||
|
|
||||||
|
for(int channel = 0; channel < specs.channels; channel++)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
value = fabs(buf[i * specs.channels + channel]);
|
||||||
|
if(value < m_threshold)
|
||||||
|
value = 0.0f;
|
||||||
|
|
||||||
|
buffer[i * specs.channels + channel] = envelopes[channel] =
|
||||||
|
((value > envelopes[channel]) ? m_bAttack : m_bRelease) *
|
||||||
|
(envelopes[channel] - value) + value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
84
intern/audaspace/FX/AUD_EnvelopeReader.h
Normal file
84
intern/audaspace/FX/AUD_EnvelopeReader.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_ENVELOPEREADER
|
||||||
|
#define AUD_ENVELOPEREADER
|
||||||
|
|
||||||
|
#include "AUD_EffectReader.h"
|
||||||
|
class AUD_Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents an envelope follower.
|
||||||
|
*/
|
||||||
|
class AUD_EnvelopeReader : public AUD_EffectReader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The playback buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last envelopes buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_envelopes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attack b value.
|
||||||
|
*/
|
||||||
|
float m_bAttack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release b value.
|
||||||
|
*/
|
||||||
|
float m_bRelease;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Threshold value.
|
||||||
|
*/
|
||||||
|
float m_threshold;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new envelope reader.
|
||||||
|
* \param reader The reader to read from.
|
||||||
|
* \param attack The attack value in seconds.
|
||||||
|
* \param release The release value in seconds.
|
||||||
|
* \param threshold The threshold value.
|
||||||
|
* \param arthreshold The attack/release threshold value.
|
||||||
|
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||||
|
*/
|
||||||
|
AUD_EnvelopeReader(AUD_IReader* reader, float attack, float release,
|
||||||
|
float threshold, float arthreshold);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the reader.
|
||||||
|
*/
|
||||||
|
virtual ~AUD_EnvelopeReader();
|
||||||
|
|
||||||
|
virtual void read(int & length, sample_t* & buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_ENVELOPEREADER
|
||||||
@@ -35,35 +35,6 @@ AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
|
|||||||
m_start(start),
|
m_start(start),
|
||||||
m_length(length)
|
m_length(length)
|
||||||
{
|
{
|
||||||
int bigendian = 1;
|
|
||||||
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
|
|
||||||
|
|
||||||
switch(m_reader->getSpecs().format)
|
|
||||||
{
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
m_adjust = AUD_volume_adjust<int16_t>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S32:
|
|
||||||
m_adjust = AUD_volume_adjust<int32_t>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT32:
|
|
||||||
m_adjust = AUD_volume_adjust<float>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT64:
|
|
||||||
m_adjust = AUD_volume_adjust<double>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_U8:
|
|
||||||
m_adjust = AUD_volume_adjust_u8;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S24:
|
|
||||||
m_adjust = bigendian ? AUD_volume_adjust_s24_be :
|
|
||||||
AUD_volume_adjust_s24_le;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
delete m_reader;
|
|
||||||
AUD_THROW(AUD_ERROR_READER);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,9 +64,7 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
|
|||||||
if(m_type != AUD_FADE_OUT)
|
if(m_type != AUD_FADE_OUT)
|
||||||
{
|
{
|
||||||
buffer = m_buffer->getBuffer();
|
buffer = m_buffer->getBuffer();
|
||||||
memset(buffer,
|
memset(buffer, 0, length * samplesize);
|
||||||
specs.format == AUD_FORMAT_U8 ? 0x80 : 0,
|
|
||||||
length * samplesize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(position / (float)specs.rate >= m_start+m_length)
|
else if(position / (float)specs.rate >= m_start+m_length)
|
||||||
@@ -103,9 +72,7 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
|
|||||||
if(m_type == AUD_FADE_OUT)
|
if(m_type == AUD_FADE_OUT)
|
||||||
{
|
{
|
||||||
buffer = m_buffer->getBuffer();
|
buffer = m_buffer->getBuffer();
|
||||||
memset(buffer,
|
memset(buffer, 0, length * samplesize);
|
||||||
specs.format == AUD_FORMAT_U8 ? 0x80 : 0,
|
|
||||||
length * samplesize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -113,19 +80,21 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
|
|||||||
sample_t* buf = m_buffer->getBuffer();
|
sample_t* buf = m_buffer->getBuffer();
|
||||||
float volume;
|
float volume;
|
||||||
|
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length * specs.channels; i++)
|
||||||
{
|
{
|
||||||
volume = (((position+i)/(float)specs.rate)-m_start) / m_length;
|
if(i % specs.channels == 0)
|
||||||
if(volume > 1.0f)
|
{
|
||||||
volume = 1.0f;
|
volume = (((position+i)/(float)specs.rate)-m_start) / m_length;
|
||||||
else if(volume < 0.0f)
|
if(volume > 1.0f)
|
||||||
volume = 0.0f;
|
volume = 1.0f;
|
||||||
|
else if(volume < 0.0f)
|
||||||
|
volume = 0.0f;
|
||||||
|
|
||||||
if(m_type == AUD_FADE_OUT)
|
if(m_type == AUD_FADE_OUT)
|
||||||
volume = 1.0f - volume;
|
volume = 1.0f - volume;
|
||||||
|
}
|
||||||
|
|
||||||
m_adjust(buf + i * samplesize, buffer + i * samplesize,
|
buf[i] = buffer[i] * volume;
|
||||||
specs.channels, volume);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = buf;
|
buffer = buf;
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
#define AUD_FADERREADER
|
#define AUD_FADERREADER
|
||||||
|
|
||||||
#include "AUD_EffectReader.h"
|
#include "AUD_EffectReader.h"
|
||||||
#include "AUD_ConverterFunctions.h"
|
|
||||||
class AUD_Buffer;
|
class AUD_Buffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,11 +57,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
float m_length;
|
float m_length;
|
||||||
|
|
||||||
/**
|
|
||||||
* Volume adjustment function.
|
|
||||||
*/
|
|
||||||
AUD_volume_adjust_f m_adjust;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates a new fader reader.
|
* Creates a new fader reader.
|
||||||
|
|||||||
51
intern/audaspace/FX/AUD_HighpassFactory.cpp
Normal file
51
intern/audaspace/FX/AUD_HighpassFactory.cpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_HighpassFactory.h"
|
||||||
|
#include "AUD_HighpassReader.h"
|
||||||
|
|
||||||
|
AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency,
|
||||||
|
float Q) :
|
||||||
|
AUD_EffectFactory(factory),
|
||||||
|
m_frequency(frequency),
|
||||||
|
m_Q(Q) {}
|
||||||
|
|
||||||
|
AUD_HighpassFactory::AUD_HighpassFactory(float frequency, float Q) :
|
||||||
|
AUD_EffectFactory(0),
|
||||||
|
m_frequency(frequency),
|
||||||
|
m_Q(Q) {}
|
||||||
|
|
||||||
|
AUD_IReader* AUD_HighpassFactory::createReader()
|
||||||
|
{
|
||||||
|
AUD_IReader* reader = getReader();
|
||||||
|
|
||||||
|
if(reader != 0)
|
||||||
|
{
|
||||||
|
reader = new AUD_HighpassReader(reader, m_frequency, m_Q);
|
||||||
|
AUD_NEW("reader")
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
66
intern/audaspace/FX/AUD_HighpassFactory.h
Normal file
66
intern/audaspace/FX/AUD_HighpassFactory.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_HIGHPASSFACTORY
|
||||||
|
#define AUD_HIGHPASSFACTORY
|
||||||
|
|
||||||
|
#include "AUD_EffectFactory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This factory creates a highpass filter reader.
|
||||||
|
*/
|
||||||
|
class AUD_HighpassFactory : public AUD_EffectFactory
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The attack value in seconds.
|
||||||
|
*/
|
||||||
|
float m_frequency;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Q factor.
|
||||||
|
*/
|
||||||
|
float m_Q;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new highpass factory.
|
||||||
|
* \param factory The input factory.
|
||||||
|
* \param frequency The cutoff frequency.
|
||||||
|
* \param Q The Q factor.
|
||||||
|
*/
|
||||||
|
AUD_HighpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new highpass factory.
|
||||||
|
* \param frequency The cutoff frequency.
|
||||||
|
* \param Q The Q factor.
|
||||||
|
*/
|
||||||
|
AUD_HighpassFactory(float frequency, float Q = 1.0f);
|
||||||
|
|
||||||
|
virtual AUD_IReader* createReader();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_HIGHPASSFACTORY
|
||||||
116
intern/audaspace/FX/AUD_HighpassReader.cpp
Normal file
116
intern/audaspace/FX/AUD_HighpassReader.cpp
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_HighpassReader.h"
|
||||||
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CC channels + channel
|
||||||
|
|
||||||
|
AUD_HighpassReader::AUD_HighpassReader(AUD_IReader* reader, float frequency,
|
||||||
|
float Q) :
|
||||||
|
AUD_EffectReader(reader)
|
||||||
|
{
|
||||||
|
AUD_Specs specs = reader->getSpecs();
|
||||||
|
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||||
|
|
||||||
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
|
||||||
|
m_outvalues = new AUD_Buffer(samplesize * AUD_HIGHPASS_ORDER);
|
||||||
|
AUD_NEW("buffer")
|
||||||
|
memset(m_outvalues->getBuffer(), 0, samplesize * AUD_HIGHPASS_ORDER);
|
||||||
|
|
||||||
|
m_invalues = new AUD_Buffer(samplesize * AUD_HIGHPASS_ORDER);
|
||||||
|
AUD_NEW("buffer")
|
||||||
|
memset(m_invalues->getBuffer(), 0, samplesize * AUD_HIGHPASS_ORDER);
|
||||||
|
|
||||||
|
m_position = 0;
|
||||||
|
|
||||||
|
// calculate coefficients
|
||||||
|
float w0 = 2 * M_PI * frequency / specs.rate;
|
||||||
|
float alpha = sin(w0) / (2 * Q);
|
||||||
|
float norm = 1 + alpha;
|
||||||
|
m_coeff[0][0] = 0;
|
||||||
|
m_coeff[0][1] = -2 * cos(w0) / norm;
|
||||||
|
m_coeff[0][2] = (1 - alpha) / norm;
|
||||||
|
m_coeff[1][2] = m_coeff[1][0] = (1 + cos(w0)) / (2 * norm);
|
||||||
|
m_coeff[1][1] = (-1 - cos(w0)) / norm;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_HighpassReader::~AUD_HighpassReader()
|
||||||
|
{
|
||||||
|
delete m_buffer; AUD_DELETE("buffer")
|
||||||
|
|
||||||
|
delete m_outvalues; AUD_DELETE("buffer")
|
||||||
|
delete m_invalues; AUD_DELETE("buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_HighpassReader::read(int & length, sample_t* & buffer)
|
||||||
|
{
|
||||||
|
sample_t* buf;
|
||||||
|
sample_t* outvalues;
|
||||||
|
sample_t* invalues;
|
||||||
|
|
||||||
|
outvalues = m_outvalues->getBuffer();
|
||||||
|
invalues = m_invalues->getBuffer();
|
||||||
|
|
||||||
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
|
|
||||||
|
m_reader->read(length, buf);
|
||||||
|
|
||||||
|
if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||||
|
m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
|
||||||
|
|
||||||
|
buffer = m_buffer->getBuffer();
|
||||||
|
int channels = specs.channels;
|
||||||
|
|
||||||
|
for(int channel = 0; channel < channels; channel++)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
invalues[m_position * CC] = buf[i * CC];
|
||||||
|
outvalues[m_position * CC] = 0;
|
||||||
|
|
||||||
|
for(int j = 0; j < AUD_HIGHPASS_ORDER; j++)
|
||||||
|
{
|
||||||
|
outvalues[m_position * CC] += m_coeff[1][j] *
|
||||||
|
invalues[((m_position + j) % AUD_HIGHPASS_ORDER) * CC] -
|
||||||
|
m_coeff[0][j] *
|
||||||
|
outvalues[((m_position + j) % AUD_HIGHPASS_ORDER) * CC];
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[i * CC] = outvalues[m_position * CC];
|
||||||
|
|
||||||
|
m_position = (m_position + AUD_HIGHPASS_ORDER-1) %
|
||||||
|
AUD_HIGHPASS_ORDER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
83
intern/audaspace/FX/AUD_HighpassReader.h
Normal file
83
intern/audaspace/FX/AUD_HighpassReader.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_HIGHPASSREADER
|
||||||
|
#define AUD_HIGHPASSREADER
|
||||||
|
|
||||||
|
#include "AUD_EffectReader.h"
|
||||||
|
class AUD_Buffer;
|
||||||
|
|
||||||
|
#define AUD_HIGHPASS_ORDER 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a highpass filter.
|
||||||
|
*/
|
||||||
|
class AUD_HighpassReader : public AUD_EffectReader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The playback buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last out values buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_outvalues;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last in values buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_invalues;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The position for buffer cycling.
|
||||||
|
*/
|
||||||
|
int m_position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter coefficients.
|
||||||
|
*/
|
||||||
|
float m_coeff[2][AUD_HIGHPASS_ORDER];
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new highpass reader.
|
||||||
|
* \param reader The reader to read from.
|
||||||
|
* \param frequency The cutoff frequency.
|
||||||
|
* \param Q The Q factor.
|
||||||
|
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||||
|
*/
|
||||||
|
AUD_HighpassReader(AUD_IReader* reader, float frequency, float Q);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the reader.
|
||||||
|
*/
|
||||||
|
virtual ~AUD_HighpassReader();
|
||||||
|
|
||||||
|
virtual void read(int & length, sample_t* & buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_HIGHPASSREADER
|
||||||
@@ -27,7 +27,6 @@
|
|||||||
#include "AUD_Buffer.h"
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) :
|
AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) :
|
||||||
AUD_EffectReader(reader), m_loop(loop)
|
AUD_EffectReader(reader), m_loop(loop)
|
||||||
@@ -62,7 +61,8 @@ bool AUD_LoopReader::notify(AUD_Message &message)
|
|||||||
|
|
||||||
void AUD_LoopReader::read(int & length, sample_t* & buffer)
|
void AUD_LoopReader::read(int & length, sample_t* & buffer)
|
||||||
{
|
{
|
||||||
int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
|
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||||
|
|
||||||
int len = length;
|
int len = length;
|
||||||
|
|
||||||
@@ -72,10 +72,10 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer)
|
|||||||
{
|
{
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
if(m_buffer->getSize() < length*samplesize)
|
if(m_buffer->getSize() < length * samplesize)
|
||||||
m_buffer->resize(length*samplesize);
|
m_buffer->resize(length * samplesize);
|
||||||
|
|
||||||
memcpy(m_buffer->getBuffer() + pos * samplesize,
|
memcpy(m_buffer->getBuffer() + pos * specs.channels,
|
||||||
buffer, len * samplesize);
|
buffer, len * samplesize);
|
||||||
|
|
||||||
pos += len;
|
pos += len;
|
||||||
@@ -93,7 +93,7 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer)
|
|||||||
if(!len)
|
if(!len)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
memcpy(m_buffer->getBuffer() + pos * samplesize,
|
memcpy(m_buffer->getBuffer() + pos * specs.channels,
|
||||||
buffer, len * samplesize);
|
buffer, len * samplesize);
|
||||||
|
|
||||||
pos += len;
|
pos += len;
|
||||||
|
|||||||
51
intern/audaspace/FX/AUD_LowpassFactory.cpp
Normal file
51
intern/audaspace/FX/AUD_LowpassFactory.cpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_LowpassFactory.h"
|
||||||
|
#include "AUD_LowpassReader.h"
|
||||||
|
|
||||||
|
AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency,
|
||||||
|
float Q) :
|
||||||
|
AUD_EffectFactory(factory),
|
||||||
|
m_frequency(frequency),
|
||||||
|
m_Q(Q) {}
|
||||||
|
|
||||||
|
AUD_LowpassFactory::AUD_LowpassFactory(float frequency, float Q) :
|
||||||
|
AUD_EffectFactory(0),
|
||||||
|
m_frequency(frequency),
|
||||||
|
m_Q(Q) {}
|
||||||
|
|
||||||
|
AUD_IReader* AUD_LowpassFactory::createReader()
|
||||||
|
{
|
||||||
|
AUD_IReader* reader = getReader();
|
||||||
|
|
||||||
|
if(reader != 0)
|
||||||
|
{
|
||||||
|
reader = new AUD_LowpassReader(reader, m_frequency, m_Q);
|
||||||
|
AUD_NEW("reader")
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
66
intern/audaspace/FX/AUD_LowpassFactory.h
Normal file
66
intern/audaspace/FX/AUD_LowpassFactory.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_LOWPASSFACTORY
|
||||||
|
#define AUD_LOWPASSFACTORY
|
||||||
|
|
||||||
|
#include "AUD_EffectFactory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This factory creates a lowpass filter reader.
|
||||||
|
*/
|
||||||
|
class AUD_LowpassFactory : public AUD_EffectFactory
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The attack value in seconds.
|
||||||
|
*/
|
||||||
|
float m_frequency;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Q factor.
|
||||||
|
*/
|
||||||
|
float m_Q;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new lowpass factory.
|
||||||
|
* \param factory The input factory.
|
||||||
|
* \param frequency The cutoff frequency.
|
||||||
|
* \param Q The Q factor.
|
||||||
|
*/
|
||||||
|
AUD_LowpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new lowpass factory.
|
||||||
|
* \param frequency The cutoff frequency.
|
||||||
|
* \param Q The Q factor.
|
||||||
|
*/
|
||||||
|
AUD_LowpassFactory(float frequency, float Q = 1.0f);
|
||||||
|
|
||||||
|
virtual AUD_IReader* createReader();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_LOWPASSFACTORY
|
||||||
115
intern/audaspace/FX/AUD_LowpassReader.cpp
Normal file
115
intern/audaspace/FX/AUD_LowpassReader.cpp
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_LowpassReader.h"
|
||||||
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CC channels + channel
|
||||||
|
|
||||||
|
AUD_LowpassReader::AUD_LowpassReader(AUD_IReader* reader, float frequency,
|
||||||
|
float Q) :
|
||||||
|
AUD_EffectReader(reader)
|
||||||
|
{
|
||||||
|
AUD_Specs specs = reader->getSpecs();
|
||||||
|
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||||
|
|
||||||
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
|
||||||
|
m_outvalues = new AUD_Buffer(samplesize * AUD_LOWPASS_ORDER);
|
||||||
|
AUD_NEW("buffer")
|
||||||
|
memset(m_outvalues->getBuffer(), 0, samplesize * AUD_LOWPASS_ORDER);
|
||||||
|
|
||||||
|
m_invalues = new AUD_Buffer(samplesize * AUD_LOWPASS_ORDER);
|
||||||
|
AUD_NEW("buffer")
|
||||||
|
memset(m_invalues->getBuffer(), 0, samplesize * AUD_LOWPASS_ORDER);
|
||||||
|
|
||||||
|
m_position = 0;
|
||||||
|
|
||||||
|
// calculate coefficients
|
||||||
|
float w0 = 2 * M_PI * frequency / specs.rate;
|
||||||
|
float alpha = sin(w0) / (2 * Q);
|
||||||
|
float norm = 1 + alpha;
|
||||||
|
m_coeff[0][0] = 0;
|
||||||
|
m_coeff[0][1] = -2 * cos(w0) / norm;
|
||||||
|
m_coeff[0][2] = (1 - alpha) / norm;
|
||||||
|
m_coeff[1][2] = m_coeff[1][0] = (1 - cos(w0)) / (2 * norm);
|
||||||
|
m_coeff[1][1] = (1 - cos(w0)) / norm;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_LowpassReader::~AUD_LowpassReader()
|
||||||
|
{
|
||||||
|
delete m_buffer; AUD_DELETE("buffer")
|
||||||
|
|
||||||
|
delete m_outvalues; AUD_DELETE("buffer")
|
||||||
|
delete m_invalues; AUD_DELETE("buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_LowpassReader::read(int & length, sample_t* & buffer)
|
||||||
|
{
|
||||||
|
sample_t* buf;
|
||||||
|
sample_t* outvalues;
|
||||||
|
sample_t* invalues;
|
||||||
|
|
||||||
|
outvalues = m_outvalues->getBuffer();
|
||||||
|
invalues = m_invalues->getBuffer();
|
||||||
|
|
||||||
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
|
|
||||||
|
m_reader->read(length, buf);
|
||||||
|
|
||||||
|
if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||||
|
m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
|
||||||
|
|
||||||
|
buffer = m_buffer->getBuffer();
|
||||||
|
int channels = specs.channels;
|
||||||
|
|
||||||
|
for(int channel = 0; channel < channels; channel++)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
invalues[m_position * CC] = buf[i * CC];
|
||||||
|
outvalues[m_position * CC] = 0;
|
||||||
|
|
||||||
|
for(int j = 0; j < AUD_LOWPASS_ORDER; j++)
|
||||||
|
{
|
||||||
|
outvalues[m_position * CC] += m_coeff[1][j] *
|
||||||
|
invalues[((m_position + j) % AUD_LOWPASS_ORDER) * CC] -
|
||||||
|
m_coeff[0][j] *
|
||||||
|
outvalues[((m_position + j) % AUD_LOWPASS_ORDER) * CC];
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[i * CC] = outvalues[m_position * CC];
|
||||||
|
|
||||||
|
m_position = (m_position + AUD_LOWPASS_ORDER-1) % AUD_LOWPASS_ORDER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
83
intern/audaspace/FX/AUD_LowpassReader.h
Normal file
83
intern/audaspace/FX/AUD_LowpassReader.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_LOWPASSREADER
|
||||||
|
#define AUD_LOWPASSREADER
|
||||||
|
|
||||||
|
#include "AUD_EffectReader.h"
|
||||||
|
class AUD_Buffer;
|
||||||
|
|
||||||
|
#define AUD_LOWPASS_ORDER 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a lowpass filter.
|
||||||
|
*/
|
||||||
|
class AUD_LowpassReader : public AUD_EffectReader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The playback buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last out values buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_outvalues;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last in values buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_invalues;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The position for buffer cycling.
|
||||||
|
*/
|
||||||
|
int m_position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter coefficients.
|
||||||
|
*/
|
||||||
|
float m_coeff[2][AUD_LOWPASS_ORDER];
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new lowpass reader.
|
||||||
|
* \param reader The reader to read from.
|
||||||
|
* \param frequency The cutoff frequency.
|
||||||
|
* \param Q The Q factor.
|
||||||
|
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||||
|
*/
|
||||||
|
AUD_LowpassReader(AUD_IReader* reader, float frequency, float Q);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the reader.
|
||||||
|
*/
|
||||||
|
virtual ~AUD_LowpassReader();
|
||||||
|
|
||||||
|
virtual void read(int & length, sample_t* & buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_LOWPASSREADER
|
||||||
@@ -45,7 +45,7 @@ public:
|
|||||||
* \param factory The input factory.
|
* \param factory The input factory.
|
||||||
* \param pitch The desired pitch.
|
* \param pitch The desired pitch.
|
||||||
*/
|
*/
|
||||||
AUD_PitchFactory(AUD_IFactory* factory = 0, float pitch = 1.0);
|
AUD_PitchFactory(AUD_IFactory* factory = 0, float pitch = 1.0f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new pitch factory.
|
* Creates a new pitch factory.
|
||||||
|
|||||||
@@ -26,39 +26,11 @@
|
|||||||
#include "AUD_RectifyReader.h"
|
#include "AUD_RectifyReader.h"
|
||||||
#include "AUD_Buffer.h"
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cmath>
|
||||||
|
|
||||||
AUD_RectifyReader::AUD_RectifyReader(AUD_IReader* reader) :
|
AUD_RectifyReader::AUD_RectifyReader(AUD_IReader* reader) :
|
||||||
AUD_EffectReader(reader)
|
AUD_EffectReader(reader)
|
||||||
{
|
{
|
||||||
int bigendian = 1;
|
|
||||||
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
|
|
||||||
|
|
||||||
switch(m_reader->getSpecs().format)
|
|
||||||
{
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
m_rectify = AUD_rectify<int16_t>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S32:
|
|
||||||
m_rectify = AUD_rectify<int32_t>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT32:
|
|
||||||
m_rectify = AUD_rectify<float>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT64:
|
|
||||||
m_rectify = AUD_rectify<double>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_U8:
|
|
||||||
m_rectify = AUD_rectify_u8;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S24:
|
|
||||||
m_rectify = bigendian ? AUD_rectify_s24_be : AUD_rectify_s24_le;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
delete m_reader;
|
|
||||||
AUD_THROW(AUD_ERROR_READER);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,10 +45,11 @@ void AUD_RectifyReader::read(int & length, sample_t* & buffer)
|
|||||||
AUD_Specs specs = m_reader->getSpecs();
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
|
|
||||||
m_reader->read(length, buf);
|
m_reader->read(length, buf);
|
||||||
if(m_buffer->getSize() < length*AUD_SAMPLE_SIZE(specs))
|
if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||||
m_buffer->resize(length*AUD_SAMPLE_SIZE(specs));
|
m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
|
||||||
|
|
||||||
buffer = m_buffer->getBuffer();
|
buffer = m_buffer->getBuffer();
|
||||||
|
|
||||||
m_rectify(buffer, buf, length * specs.channels);
|
for(int i = 0; i < length * specs.channels; i++)
|
||||||
|
buffer[i] = fabs(buf[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
#define AUD_RECTIFYREADER
|
#define AUD_RECTIFYREADER
|
||||||
|
|
||||||
#include "AUD_EffectReader.h"
|
#include "AUD_EffectReader.h"
|
||||||
#include "AUD_ConverterFunctions.h"
|
|
||||||
class AUD_Buffer;
|
class AUD_Buffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,11 +40,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
AUD_Buffer *m_buffer;
|
AUD_Buffer *m_buffer;
|
||||||
|
|
||||||
/**
|
|
||||||
* Rectifying function.
|
|
||||||
*/
|
|
||||||
AUD_rectify_f m_rectify;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates a new rectify reader.
|
* Creates a new rectify reader.
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ int AUD_ReverseReader::getPosition()
|
|||||||
void AUD_ReverseReader::read(int & length, sample_t* & buffer)
|
void AUD_ReverseReader::read(int & length, sample_t* & buffer)
|
||||||
{
|
{
|
||||||
// first correct the length
|
// first correct the length
|
||||||
if(m_position+length > m_length)
|
if(m_position + length > m_length)
|
||||||
length = m_length-m_position;
|
length = m_length-m_position;
|
||||||
|
|
||||||
if(length <= 0)
|
if(length <= 0)
|
||||||
@@ -74,7 +74,8 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int samplesize = AUD_SAMPLE_SIZE(getSpecs());
|
AUD_Specs specs = getSpecs();
|
||||||
|
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||||
|
|
||||||
// resize buffer if needed
|
// resize buffer if needed
|
||||||
if(m_buffer->getSize() < length * samplesize)
|
if(m_buffer->getSize() < length * samplesize)
|
||||||
@@ -86,23 +87,20 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
|
|||||||
int len = length;
|
int len = length;
|
||||||
|
|
||||||
// read from reader
|
// read from reader
|
||||||
m_reader->seek(m_length-m_position-len);
|
m_reader->seek(m_length - m_position - len);
|
||||||
m_reader->read(len, buf);
|
m_reader->read(len, buf);
|
||||||
|
|
||||||
// set null if reader didn't give enough data
|
// set null if reader didn't give enough data
|
||||||
if(len < length)
|
if(len < length)
|
||||||
{
|
{
|
||||||
if(getSpecs().format == AUD_FORMAT_U8)
|
memset(buffer, 0, (length - len) * samplesize);
|
||||||
memset(buffer, 0x80, (length-len)*samplesize);
|
buffer += (length - len) * specs.channels;
|
||||||
else
|
|
||||||
memset(buffer, 0, (length-len)*samplesize);
|
|
||||||
buffer += length-len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the samples reverted
|
// copy the samples reverted
|
||||||
for(int i = 0; i < len; i++)
|
for(int i = 0; i < len; i++)
|
||||||
memcpy(buffer + i * samplesize,
|
memcpy(buffer + i * specs.channels,
|
||||||
buf + (len - 1 - i) * samplesize,
|
buf + (len - 1 - i) * specs.channels,
|
||||||
samplesize);
|
samplesize);
|
||||||
|
|
||||||
m_position += length;
|
m_position += length;
|
||||||
|
|||||||
57
intern/audaspace/FX/AUD_SquareFactory.cpp
Normal file
57
intern/audaspace/FX/AUD_SquareFactory.cpp
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_SquareFactory.h"
|
||||||
|
#include "AUD_SquareReader.h"
|
||||||
|
|
||||||
|
AUD_SquareFactory::AUD_SquareFactory(AUD_IFactory* factory, float threshold) :
|
||||||
|
AUD_EffectFactory(factory),
|
||||||
|
m_threshold(threshold) {}
|
||||||
|
|
||||||
|
AUD_SquareFactory::AUD_SquareFactory(float threshold) :
|
||||||
|
AUD_EffectFactory(0),
|
||||||
|
m_threshold(threshold) {}
|
||||||
|
|
||||||
|
float AUD_SquareFactory::getThreshold()
|
||||||
|
{
|
||||||
|
return m_threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_SquareFactory::setThreshold(float threshold)
|
||||||
|
{
|
||||||
|
m_threshold = threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_IReader* AUD_SquareFactory::createReader()
|
||||||
|
{
|
||||||
|
AUD_IReader* reader = getReader();
|
||||||
|
|
||||||
|
if(reader != 0)
|
||||||
|
{
|
||||||
|
reader = new AUD_SquareReader(reader, m_threshold); AUD_NEW("reader")
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
@@ -23,54 +23,48 @@
|
|||||||
* ***** END LGPL LICENSE BLOCK *****
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef AUD_SDLMIXER
|
#ifndef AUD_SQUAREFACTORY
|
||||||
#define AUD_SDLMIXER
|
#define AUD_SQUAREFACTORY
|
||||||
|
|
||||||
#include "AUD_IMixer.h"
|
#include "AUD_EffectFactory.h"
|
||||||
class AUD_SDLMixerFactory;
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
struct AUD_SDLMixerBuffer
|
|
||||||
{
|
|
||||||
sample_t* buffer;
|
|
||||||
int length;
|
|
||||||
float volume;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is able to mix audiosignals with the help of SDL.
|
* This factory Transforms any signal to a square signal.
|
||||||
*/
|
*/
|
||||||
class AUD_SDLMixer : public AUD_IMixer
|
class AUD_SquareFactory : public AUD_EffectFactory
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* The mixer factory that prepares all readers for superposition.
|
* The threshold.
|
||||||
*/
|
*/
|
||||||
AUD_SDLMixerFactory* m_factory;
|
float m_threshold;
|
||||||
|
|
||||||
/**
|
|
||||||
* The list of buffers to superpose.
|
|
||||||
*/
|
|
||||||
std::list<AUD_SDLMixerBuffer> m_buffers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The size of an output sample.
|
|
||||||
*/
|
|
||||||
int m_samplesize;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates the mixer.
|
* Creates a new square factory.
|
||||||
|
* \param factory The input factory.
|
||||||
|
* \param threshold The threshold.
|
||||||
*/
|
*/
|
||||||
AUD_SDLMixer();
|
AUD_SquareFactory(AUD_IFactory* factory = 0, float threshold = 0.0f);
|
||||||
|
|
||||||
virtual ~AUD_SDLMixer();
|
/**
|
||||||
|
* Creates a new square factory.
|
||||||
|
* \param threshold The threshold.
|
||||||
|
*/
|
||||||
|
AUD_SquareFactory(float threshold);
|
||||||
|
|
||||||
virtual AUD_IReader* prepare(AUD_IReader* reader);
|
/**
|
||||||
virtual void setSpecs(AUD_Specs specs);
|
* Returns the threshold.
|
||||||
virtual void add(sample_t* buffer, AUD_Specs specs, int length,
|
*/
|
||||||
float volume);
|
float getThreshold();
|
||||||
virtual void superpose(sample_t* buffer, int length, float volume);
|
|
||||||
|
/**
|
||||||
|
* Sets the threshold.
|
||||||
|
* \param threshold The new threshold value. Should be between 0.0 and 1.0.
|
||||||
|
*/
|
||||||
|
void setThreshold(float threshold);
|
||||||
|
|
||||||
|
virtual AUD_IReader* createReader();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //AUD_SDLMIXER
|
#endif //AUD_SQUAREFACTORY
|
||||||
63
intern/audaspace/FX/AUD_SquareReader.cpp
Normal file
63
intern/audaspace/FX/AUD_SquareReader.cpp
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_SquareReader.h"
|
||||||
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
AUD_SquareReader::AUD_SquareReader(AUD_IReader* reader, float threshold) :
|
||||||
|
AUD_EffectReader(reader),
|
||||||
|
m_threshold(threshold)
|
||||||
|
{
|
||||||
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_SquareReader::~AUD_SquareReader()
|
||||||
|
{
|
||||||
|
delete m_buffer; AUD_DELETE("buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_SquareReader::read(int & length, sample_t* & buffer)
|
||||||
|
{
|
||||||
|
sample_t* buf;
|
||||||
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
|
|
||||||
|
m_reader->read(length, buf);
|
||||||
|
if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||||
|
m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
|
||||||
|
|
||||||
|
buffer = m_buffer->getBuffer();
|
||||||
|
|
||||||
|
for(int i = 0; i < length * specs.channels; i++)
|
||||||
|
{
|
||||||
|
if(buf[i] >= m_threshold)
|
||||||
|
buffer[i] = 1.0f;
|
||||||
|
else if(buf[i] <= -m_threshold)
|
||||||
|
buffer[i] = -1.0f;
|
||||||
|
else
|
||||||
|
buffer[i] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
65
intern/audaspace/FX/AUD_SquareReader.h
Normal file
65
intern/audaspace/FX/AUD_SquareReader.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_SQUAREREADER
|
||||||
|
#define AUD_SQUAREREADER
|
||||||
|
|
||||||
|
#include "AUD_EffectReader.h"
|
||||||
|
class AUD_Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class changes another signal into a square signal.
|
||||||
|
*/
|
||||||
|
class AUD_SquareReader : public AUD_EffectReader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The playback buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The threshold level.
|
||||||
|
*/
|
||||||
|
float m_threshold;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new square reader.
|
||||||
|
* \param reader The reader to read from.
|
||||||
|
* \param threshold The size of the buffer.
|
||||||
|
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||||
|
*/
|
||||||
|
AUD_SquareReader(AUD_IReader* reader, float threshold);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the reader.
|
||||||
|
*/
|
||||||
|
virtual ~AUD_SquareReader();
|
||||||
|
|
||||||
|
virtual void read(int & length, sample_t* & buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_SQUAREREADER
|
||||||
43
intern/audaspace/FX/AUD_SumFactory.cpp
Normal file
43
intern/audaspace/FX/AUD_SumFactory.cpp
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_SumFactory.h"
|
||||||
|
#include "AUD_SumReader.h"
|
||||||
|
|
||||||
|
AUD_SumFactory::AUD_SumFactory(AUD_IFactory* factory) :
|
||||||
|
AUD_EffectFactory(factory) {}
|
||||||
|
|
||||||
|
AUD_IReader* AUD_SumFactory::createReader()
|
||||||
|
{
|
||||||
|
AUD_IReader* reader = getReader();
|
||||||
|
|
||||||
|
if(reader != 0)
|
||||||
|
{
|
||||||
|
reader = new AUD_SumReader(reader);
|
||||||
|
AUD_NEW("reader")
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
@@ -23,23 +23,24 @@
|
|||||||
* ***** END LGPL LICENSE BLOCK *****
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef AUD_SDLMIXERFACTORY
|
#ifndef AUD_SUMFACTORY
|
||||||
#define AUD_SDLMIXERFACTORY
|
#define AUD_SUMFACTORY
|
||||||
|
|
||||||
#include "AUD_MixerFactory.h"
|
#include "AUD_EffectFactory.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This factory creates a resampling reader that uses SDL's resampling
|
* This factory creates a sum reader.
|
||||||
* functionality which unfortunately is very very very limited.
|
|
||||||
*/
|
*/
|
||||||
class AUD_SDLMixerFactory : public AUD_MixerFactory
|
class AUD_SumFactory : public AUD_EffectFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs);
|
/**
|
||||||
AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs);
|
* Creates a new sum factory.
|
||||||
AUD_SDLMixerFactory(AUD_Specs specs);
|
* \param factory The input factory.
|
||||||
|
*/
|
||||||
|
AUD_SumFactory(AUD_IFactory* factory = 0);
|
||||||
|
|
||||||
virtual AUD_IReader* createReader();
|
virtual AUD_IReader* createReader();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //AUD_SDLMIXERFACTORY
|
#endif //AUD_SUMFACTORY
|
||||||
68
intern/audaspace/FX/AUD_SumReader.cpp
Normal file
68
intern/audaspace/FX/AUD_SumReader.cpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_SumReader.h"
|
||||||
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#define CC specs.channels + channel
|
||||||
|
|
||||||
|
AUD_SumReader::AUD_SumReader(AUD_IReader* reader) :
|
||||||
|
AUD_EffectReader(reader)
|
||||||
|
{
|
||||||
|
AUD_Specs specs = reader->getSpecs();
|
||||||
|
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||||
|
|
||||||
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
|
||||||
|
m_sums = new AUD_Buffer(samplesize); AUD_NEW("buffer")
|
||||||
|
memset(m_sums->getBuffer(), 0, samplesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_SumReader::~AUD_SumReader()
|
||||||
|
{
|
||||||
|
delete m_buffer; AUD_DELETE("buffer")
|
||||||
|
delete m_sums; AUD_DELETE("buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_SumReader::read(int & length, sample_t* & buffer)
|
||||||
|
{
|
||||||
|
sample_t* buf;
|
||||||
|
sample_t* sums;
|
||||||
|
sums = m_sums->getBuffer();
|
||||||
|
|
||||||
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
|
|
||||||
|
m_reader->read(length, buf);
|
||||||
|
if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||||
|
m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
|
||||||
|
|
||||||
|
buffer = m_buffer->getBuffer();
|
||||||
|
|
||||||
|
for(int channel = 0; channel < specs.channels; channel++)
|
||||||
|
for(int i = 0; i < length * specs.channels; i++)
|
||||||
|
buffer[i * CC] = sums[channel] = sums[channel] + buf[i * CC];
|
||||||
|
}
|
||||||
64
intern/audaspace/FX/AUD_SumReader.h
Normal file
64
intern/audaspace/FX/AUD_SumReader.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_SUMREADER
|
||||||
|
#define AUD_SUMREADER
|
||||||
|
|
||||||
|
#include "AUD_EffectReader.h"
|
||||||
|
class AUD_Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents an summer.
|
||||||
|
*/
|
||||||
|
class AUD_SumReader : public AUD_EffectReader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The playback buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sums of the specific channels.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_sums;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new sum reader.
|
||||||
|
* \param reader The reader to read from.
|
||||||
|
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||||
|
*/
|
||||||
|
AUD_SumReader(AUD_IReader* reader);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the reader.
|
||||||
|
*/
|
||||||
|
virtual ~AUD_SumReader();
|
||||||
|
|
||||||
|
virtual void read(int & length, sample_t* & buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_SUMREADER
|
||||||
@@ -47,7 +47,7 @@ public:
|
|||||||
* \param factory The input factory.
|
* \param factory The input factory.
|
||||||
* \param volume The desired volume.
|
* \param volume The desired volume.
|
||||||
*/
|
*/
|
||||||
AUD_VolumeFactory(AUD_IFactory* factory = 0, float volume = 1.0);
|
AUD_VolumeFactory(AUD_IFactory* factory = 0, float volume = 1.0f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new volume factory.
|
* Creates a new volume factory.
|
||||||
|
|||||||
@@ -32,35 +32,6 @@ AUD_VolumeReader::AUD_VolumeReader(AUD_IReader* reader, float volume) :
|
|||||||
AUD_EffectReader(reader),
|
AUD_EffectReader(reader),
|
||||||
m_volume(volume)
|
m_volume(volume)
|
||||||
{
|
{
|
||||||
int bigendian = 1;
|
|
||||||
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
|
|
||||||
|
|
||||||
switch(m_reader->getSpecs().format)
|
|
||||||
{
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
m_adjust = AUD_volume_adjust<int16_t>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S32:
|
|
||||||
m_adjust = AUD_volume_adjust<int32_t>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT32:
|
|
||||||
m_adjust = AUD_volume_adjust<float>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT64:
|
|
||||||
m_adjust = AUD_volume_adjust<double>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_U8:
|
|
||||||
m_adjust = AUD_volume_adjust_u8;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S24:
|
|
||||||
m_adjust = bigendian ? AUD_volume_adjust_s24_be :
|
|
||||||
AUD_volume_adjust_s24_le;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
delete m_reader;
|
|
||||||
AUD_THROW(AUD_ERROR_READER);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,5 +64,6 @@ void AUD_VolumeReader::read(int & length, sample_t* & buffer)
|
|||||||
|
|
||||||
buffer = m_buffer->getBuffer();
|
buffer = m_buffer->getBuffer();
|
||||||
|
|
||||||
m_adjust(buffer, buf, length * specs.channels, m_volume);
|
for(int i = 0; i < length * specs.channels; i++)
|
||||||
|
buffer[i] = buf[i] * m_volume;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
#define AUD_VOLUMEREADER
|
#define AUD_VOLUMEREADER
|
||||||
|
|
||||||
#include "AUD_EffectReader.h"
|
#include "AUD_EffectReader.h"
|
||||||
#include "AUD_ConverterFunctions.h"
|
|
||||||
class AUD_Buffer;
|
class AUD_Buffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,11 +45,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
float m_volume;
|
float m_volume;
|
||||||
|
|
||||||
/**
|
|
||||||
* Volume adjustment function.
|
|
||||||
*/
|
|
||||||
AUD_volume_adjust_f m_adjust;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates a new volume reader.
|
* Creates a new volume reader.
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include "AUD_OpenALDevice.h"
|
#include "AUD_OpenALDevice.h"
|
||||||
#include "AUD_IReader.h"
|
#include "AUD_IReader.h"
|
||||||
#include "AUD_IMixer.h"
|
|
||||||
#include "AUD_ConverterFactory.h"
|
#include "AUD_ConverterFactory.h"
|
||||||
#include "AUD_SourceCaps.h"
|
#include "AUD_SourceCaps.h"
|
||||||
|
|
||||||
@@ -119,7 +118,7 @@ void AUD_OpenALDevice::updateStreams()
|
|||||||
sample_t* buffer;
|
sample_t* buffer;
|
||||||
|
|
||||||
ALint info;
|
ALint info;
|
||||||
AUD_Specs specs;
|
AUD_DeviceSpecs specs = m_specs;
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
@@ -145,7 +144,7 @@ void AUD_OpenALDevice::updateStreams()
|
|||||||
|
|
||||||
if(info)
|
if(info)
|
||||||
{
|
{
|
||||||
specs = sound->reader->getSpecs();
|
specs.specs = sound->reader->getSpecs();
|
||||||
|
|
||||||
// for all empty buffers
|
// for all empty buffers
|
||||||
while(info--)
|
while(info--)
|
||||||
@@ -177,8 +176,8 @@ void AUD_OpenALDevice::updateStreams()
|
|||||||
// fill with new data
|
// fill with new data
|
||||||
alBufferData(sound->buffers[sound->current],
|
alBufferData(sound->buffers[sound->current],
|
||||||
sound->format,
|
sound->format,
|
||||||
buffer,
|
buffer, length *
|
||||||
length * AUD_SAMPLE_SIZE(specs),
|
AUD_DEVICE_SAMPLE_SIZE(specs),
|
||||||
specs.rate);
|
specs.rate);
|
||||||
|
|
||||||
if(alGetError() != AL_NO_ERROR)
|
if(alGetError() != AL_NO_ERROR)
|
||||||
@@ -264,7 +263,7 @@ bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_OpenALDevice::AUD_OpenALDevice(AUD_Specs specs, int buffersize)
|
AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
|
||||||
{
|
{
|
||||||
// cannot determine how many channels or which format OpenAL uses, but
|
// cannot determine how many channels or which format OpenAL uses, but
|
||||||
// it at least is able to play 16 bit stereo audio
|
// it at least is able to play 16 bit stereo audio
|
||||||
@@ -289,14 +288,17 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_Specs specs, int buffersize)
|
|||||||
|
|
||||||
// check for specific formats and channel counts to be played back
|
// check for specific formats and channel counts to be played back
|
||||||
if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
|
if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
|
||||||
|
{
|
||||||
specs.format = AUD_FORMAT_FLOAT32;
|
specs.format = AUD_FORMAT_FLOAT32;
|
||||||
|
m_converter = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
|
||||||
|
|
||||||
m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
|
m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
|
||||||
|
|
||||||
alGetError();
|
alGetError();
|
||||||
|
|
||||||
m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
|
|
||||||
|
|
||||||
m_specs = specs;
|
m_specs = specs;
|
||||||
m_buffersize = buffersize;
|
m_buffersize = buffersize;
|
||||||
m_playing = false;
|
m_playing = false;
|
||||||
@@ -378,12 +380,13 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
|
|||||||
alcDestroyContext(m_context);
|
alcDestroyContext(m_context);
|
||||||
alcCloseDevice(m_device);
|
alcCloseDevice(m_device);
|
||||||
|
|
||||||
delete m_converter; AUD_DELETE("factory")
|
if(m_converter)
|
||||||
|
delete m_converter; AUD_DELETE("factory")
|
||||||
|
|
||||||
pthread_mutex_destroy(&m_mutex);
|
pthread_mutex_destroy(&m_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_Specs AUD_OpenALDevice::getSpecs()
|
AUD_DeviceSpecs AUD_OpenALDevice::getSpecs()
|
||||||
{
|
{
|
||||||
return m_specs;
|
return m_specs;
|
||||||
}
|
}
|
||||||
@@ -393,45 +396,8 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
|
|||||||
bool valid = true;
|
bool valid = true;
|
||||||
format = 0;
|
format = 0;
|
||||||
|
|
||||||
switch(specs.format)
|
switch(m_specs.format)
|
||||||
{
|
{
|
||||||
case AUD_FORMAT_U8:
|
|
||||||
switch(specs.channels)
|
|
||||||
{
|
|
||||||
case AUD_CHANNELS_MONO:
|
|
||||||
format = AL_FORMAT_MONO8;
|
|
||||||
break;
|
|
||||||
case AUD_CHANNELS_STEREO:
|
|
||||||
format = AL_FORMAT_STEREO8;
|
|
||||||
break;
|
|
||||||
case AUD_CHANNELS_SURROUND4:
|
|
||||||
if(m_useMC)
|
|
||||||
{
|
|
||||||
format = alGetEnumValue("AL_FORMAT_QUAD8");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AUD_CHANNELS_SURROUND51:
|
|
||||||
if(m_useMC)
|
|
||||||
{
|
|
||||||
format = alGetEnumValue("AL_FORMAT_51CHN8");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AUD_CHANNELS_SURROUND61:
|
|
||||||
if(m_useMC)
|
|
||||||
{
|
|
||||||
format = alGetEnumValue("AL_FORMAT_61CHN8");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AUD_CHANNELS_SURROUND71:
|
|
||||||
if(m_useMC)
|
|
||||||
{
|
|
||||||
format = alGetEnumValue("AL_FORMAT_71CHN8");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
valid = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S16:
|
case AUD_FORMAT_S16:
|
||||||
switch(specs.channels)
|
switch(specs.channels)
|
||||||
{
|
{
|
||||||
@@ -591,23 +557,16 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
|
|||||||
if(reader == NULL)
|
if(reader == NULL)
|
||||||
AUD_THROW(AUD_ERROR_READER);
|
AUD_THROW(AUD_ERROR_READER);
|
||||||
|
|
||||||
AUD_Specs specs;
|
AUD_DeviceSpecs specs = m_specs;
|
||||||
|
specs.specs = reader->getSpecs();
|
||||||
specs = reader->getSpecs();
|
|
||||||
|
|
||||||
// check format
|
// check format
|
||||||
bool valid = true;
|
bool valid = specs.channels != AUD_CHANNELS_INVALID;
|
||||||
|
|
||||||
if(specs.format == AUD_FORMAT_INVALID)
|
if(m_converter)
|
||||||
valid = false;
|
|
||||||
else if(specs.format == AUD_FORMAT_S24 ||
|
|
||||||
specs.format == AUD_FORMAT_S32 ||
|
|
||||||
specs.format == AUD_FORMAT_FLOAT32 ||
|
|
||||||
specs.format == AUD_FORMAT_FLOAT64)
|
|
||||||
{
|
{
|
||||||
m_converter->setReader(reader);
|
m_converter->setReader(reader);
|
||||||
reader = m_converter->createReader();
|
reader = m_converter->createReader();
|
||||||
specs = reader->getSpecs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the handle
|
// create the handle
|
||||||
@@ -618,7 +577,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
|
|||||||
sound->isBuffered = false;
|
sound->isBuffered = false;
|
||||||
sound->data_end = false;
|
sound->data_end = false;
|
||||||
|
|
||||||
valid &= getFormat(sound->format, specs);
|
valid &= getFormat(sound->format, specs.specs);
|
||||||
|
|
||||||
if(!valid)
|
if(!valid)
|
||||||
{
|
{
|
||||||
@@ -647,7 +606,8 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
|
|||||||
length = m_buffersize;
|
length = m_buffersize;
|
||||||
reader->read(length, buf);
|
reader->read(length, buf);
|
||||||
alBufferData(sound->buffers[i], sound->format, buf,
|
alBufferData(sound->buffers[i], sound->format, buf,
|
||||||
length * AUD_SAMPLE_SIZE(specs), specs.rate);
|
length * AUD_DEVICE_SAMPLE_SIZE(specs),
|
||||||
|
specs.rate);
|
||||||
if(alGetError() != AL_NO_ERROR)
|
if(alGetError() != AL_NO_ERROR)
|
||||||
AUD_THROW(AUD_ERROR_OPENAL);
|
AUD_THROW(AUD_ERROR_OPENAL);
|
||||||
}
|
}
|
||||||
@@ -875,14 +835,16 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
|
|||||||
{
|
{
|
||||||
sample_t* buf;
|
sample_t* buf;
|
||||||
int length;
|
int length;
|
||||||
AUD_Specs specs = alhandle->reader->getSpecs();
|
AUD_DeviceSpecs specs = m_specs;
|
||||||
|
specs.specs = alhandle->reader->getSpecs();
|
||||||
|
|
||||||
for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
|
for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
|
||||||
{
|
{
|
||||||
length = m_buffersize;
|
length = m_buffersize;
|
||||||
alhandle->reader->read(length, buf);
|
alhandle->reader->read(length, buf);
|
||||||
alBufferData(alhandle->buffers[i], alhandle->format,
|
alBufferData(alhandle->buffers[i], alhandle->format,
|
||||||
buf, length * AUD_SAMPLE_SIZE(specs),
|
buf,
|
||||||
|
length * AUD_DEVICE_SAMPLE_SIZE(specs),
|
||||||
specs.rate);
|
specs.rate);
|
||||||
|
|
||||||
if(alGetError() != AL_NO_ERROR)
|
if(alGetError() != AL_NO_ERROR)
|
||||||
@@ -906,7 +868,7 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
|
|||||||
|
|
||||||
float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
|
float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
|
||||||
{
|
{
|
||||||
float position = 0.0;
|
float position = 0.0f;
|
||||||
|
|
||||||
lock();
|
lock();
|
||||||
|
|
||||||
@@ -1021,6 +983,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
|
|||||||
// load the factory into an OpenAL buffer
|
// load the factory into an OpenAL buffer
|
||||||
if(factory)
|
if(factory)
|
||||||
{
|
{
|
||||||
|
// check if the factory is already buffered
|
||||||
lock();
|
lock();
|
||||||
for(AUD_BFIterator i = m_bufferedFactories->begin();
|
for(AUD_BFIterator i = m_bufferedFactories->begin();
|
||||||
i != m_bufferedFactories->end(); i++)
|
i != m_bufferedFactories->end(); i++)
|
||||||
@@ -1040,32 +1003,25 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
|
|||||||
if(reader == NULL)
|
if(reader == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
AUD_Specs specs;
|
AUD_DeviceSpecs specs = m_specs;
|
||||||
|
specs.specs = reader->getSpecs();
|
||||||
specs = reader->getSpecs();
|
|
||||||
|
|
||||||
// determine format
|
// determine format
|
||||||
bool valid = reader->getType() == AUD_TYPE_BUFFER;
|
bool valid = reader->getType() == AUD_TYPE_BUFFER;
|
||||||
|
|
||||||
if(valid)
|
if(valid)
|
||||||
{
|
{
|
||||||
if(specs.format == AUD_FORMAT_INVALID)
|
if(m_converter)
|
||||||
valid = false;
|
|
||||||
else if(specs.format == AUD_FORMAT_S24 ||
|
|
||||||
specs.format == AUD_FORMAT_S32 ||
|
|
||||||
specs.format == AUD_FORMAT_FLOAT32 ||
|
|
||||||
specs.format == AUD_FORMAT_FLOAT64)
|
|
||||||
{
|
{
|
||||||
m_converter->setReader(reader);
|
m_converter->setReader(reader);
|
||||||
reader = m_converter->createReader();
|
reader = m_converter->createReader();
|
||||||
specs = reader->getSpecs();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ALenum format;
|
ALenum format;
|
||||||
|
|
||||||
if(valid)
|
if(valid)
|
||||||
valid = getFormat(format, specs);
|
valid = getFormat(format, specs.specs);
|
||||||
|
|
||||||
if(!valid)
|
if(!valid)
|
||||||
{
|
{
|
||||||
@@ -1094,7 +1050,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
|
|||||||
|
|
||||||
reader->read(length, buf);
|
reader->read(length, buf);
|
||||||
alBufferData(bf->buffer, format, buf,
|
alBufferData(bf->buffer, format, buf,
|
||||||
length * AUD_SAMPLE_SIZE(specs),
|
length * AUD_DEVICE_SAMPLE_SIZE(specs),
|
||||||
specs.rate);
|
specs.rate);
|
||||||
if(alGetError() != AL_NO_ERROR)
|
if(alGetError() != AL_NO_ERROR)
|
||||||
AUD_THROW(AUD_ERROR_OPENAL);
|
AUD_THROW(AUD_ERROR_OPENAL);
|
||||||
@@ -1327,7 +1283,7 @@ bool AUD_OpenALDevice::setSourceSetting(AUD_Handle* handle,
|
|||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
case AUD_3DSS_IS_RELATIVE:
|
case AUD_3DSS_IS_RELATIVE:
|
||||||
alSourcei(source, AL_SOURCE_RELATIVE, value > 0.0);
|
alSourcei(source, AL_SOURCE_RELATIVE, value > 0.0f);
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
case AUD_3DSS_MAX_DISTANCE:
|
case AUD_3DSS_MAX_DISTANCE:
|
||||||
@@ -1385,7 +1341,7 @@ float AUD_OpenALDevice::getSourceSetting(AUD_Handle* handle,
|
|||||||
{
|
{
|
||||||
ALint i;
|
ALint i;
|
||||||
alGetSourcei(source, AL_SOURCE_RELATIVE, &i);
|
alGetSourcei(source, AL_SOURCE_RELATIVE, &i);
|
||||||
result = i ? 1.0 : 0.0;
|
result = i ? 1.0f : 0.0f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AUD_3DSS_MAX_DISTANCE:
|
case AUD_3DSS_MAX_DISTANCE:
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* The specification of the device.
|
* The specification of the device.
|
||||||
*/
|
*/
|
||||||
AUD_Specs m_specs;
|
AUD_DeviceSpecs m_specs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the device has the AL_EXT_MCFORMATS extension.
|
* Whether the device has the AL_EXT_MCFORMATS extension.
|
||||||
@@ -64,8 +64,8 @@ private:
|
|||||||
bool m_useMC;
|
bool m_useMC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The converter factory for readers with wrong input format.
|
* The converter factory for readers with wrong input format.
|
||||||
*/
|
*/
|
||||||
AUD_ConverterFactory* m_converter;
|
AUD_ConverterFactory* m_converter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,7 +118,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Gets the format according to the specs.
|
* Gets the format according to the specs.
|
||||||
* \param format The variable to put the format into.
|
* \param format The variable to put the format into.
|
||||||
* \param specs The specs to read the format from.
|
* \param specs The specs to read the channel count from.
|
||||||
* \return Whether the format is valid or not.
|
* \return Whether the format is valid or not.
|
||||||
*/
|
*/
|
||||||
bool getFormat(ALenum &format, AUD_Specs specs);
|
bool getFormat(ALenum &format, AUD_Specs specs);
|
||||||
@@ -132,7 +132,8 @@ public:
|
|||||||
* \note The buffersize will be multiplicated by three for this device.
|
* \note The buffersize will be multiplicated by three for this device.
|
||||||
* \exception AUD_Exception Thrown if the audio device cannot be opened.
|
* \exception AUD_Exception Thrown if the audio device cannot be opened.
|
||||||
*/
|
*/
|
||||||
AUD_OpenALDevice(AUD_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
|
AUD_OpenALDevice(AUD_DeviceSpecs specs,
|
||||||
|
int buffersize = AUD_DEFAULT_BUFFER_SIZE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Streaming thread main function.
|
* Streaming thread main function.
|
||||||
@@ -141,7 +142,7 @@ public:
|
|||||||
|
|
||||||
virtual ~AUD_OpenALDevice();
|
virtual ~AUD_OpenALDevice();
|
||||||
|
|
||||||
virtual AUD_Specs getSpecs();
|
virtual AUD_DeviceSpecs getSpecs();
|
||||||
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
|
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
|
||||||
virtual bool pause(AUD_Handle* handle);
|
virtual bool pause(AUD_Handle* handle);
|
||||||
virtual bool resume(AUD_Handle* handle);
|
virtual bool resume(AUD_Handle* handle);
|
||||||
|
|||||||
@@ -36,4 +36,7 @@ if env['WITH_BF_FFTW3']:
|
|||||||
incs += ' fftw ' + env['BF_FFTW3_INC']
|
incs += ' fftw ' + env['BF_FFTW3_INC']
|
||||||
defs.append('WITH_FFTW3')
|
defs.append('WITH_FFTW3')
|
||||||
|
|
||||||
|
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
|
||||||
|
incs += ' ' + env['BF_PTHREADS_INC']
|
||||||
|
|
||||||
env.BlenderLib ('bf_audaspace', sources, Split(incs), defs, libtype=['intern','player'], priority = [25,215] )
|
env.BlenderLib ('bf_audaspace', sources, Split(incs), defs, libtype=['intern','player'], priority = [25,215] )
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
* ***** END LGPL LICENSE BLOCK *****
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AUD_SDLMixer.h"
|
|
||||||
#include "AUD_SDLDevice.h"
|
#include "AUD_SDLDevice.h"
|
||||||
#include "AUD_IReader.h"
|
#include "AUD_IReader.h"
|
||||||
|
|
||||||
@@ -31,10 +30,10 @@ void AUD_SDLDevice::SDL_mix(void *data, Uint8* buffer, int length)
|
|||||||
{
|
{
|
||||||
AUD_SDLDevice* device = (AUD_SDLDevice*)data;
|
AUD_SDLDevice* device = (AUD_SDLDevice*)data;
|
||||||
|
|
||||||
device->mix((sample_t*)buffer, length/AUD_SAMPLE_SIZE(device->m_specs));
|
device->mix((data_t*)buffer,length/AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_SDLDevice::AUD_SDLDevice(AUD_Specs specs, int buffersize)
|
AUD_SDLDevice::AUD_SDLDevice(AUD_DeviceSpecs specs, int buffersize)
|
||||||
{
|
{
|
||||||
if(specs.channels == AUD_CHANNELS_INVALID)
|
if(specs.channels == AUD_CHANNELS_INVALID)
|
||||||
specs.channels = AUD_CHANNELS_STEREO;
|
specs.channels = AUD_CHANNELS_STEREO;
|
||||||
@@ -69,9 +68,6 @@ AUD_SDLDevice::AUD_SDLDevice(AUD_Specs specs, int buffersize)
|
|||||||
else
|
else
|
||||||
AUD_THROW(AUD_ERROR_SDL);
|
AUD_THROW(AUD_ERROR_SDL);
|
||||||
|
|
||||||
m_mixer = new AUD_SDLMixer(); AUD_NEW("mixer")
|
|
||||||
m_mixer->setSpecs(m_specs);
|
|
||||||
|
|
||||||
create();
|
create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ public:
|
|||||||
* \note The specification really used for opening the device may differ.
|
* \note The specification really used for opening the device may differ.
|
||||||
* \exception AUD_Exception Thrown if the audio device cannot be opened.
|
* \exception AUD_Exception Thrown if the audio device cannot be opened.
|
||||||
*/
|
*/
|
||||||
AUD_SDLDevice(AUD_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
|
AUD_SDLDevice(AUD_DeviceSpecs specs,
|
||||||
|
int buffersize = AUD_DEFAULT_BUFFER_SIZE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the SDL audio device.
|
* Closes the SDL audio device.
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
|
||||||
*
|
|
||||||
* Copyright 2009 Jörg Hermann Müller
|
|
||||||
*
|
|
||||||
* This file is part of AudaSpace.
|
|
||||||
*
|
|
||||||
* AudaSpace 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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* ***** END LGPL LICENSE BLOCK *****
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "AUD_SDLMixer.h"
|
|
||||||
#include "AUD_SDLMixerFactory.h"
|
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
|
|
||||||
AUD_SDLMixer::AUD_SDLMixer()
|
|
||||||
{
|
|
||||||
m_factory = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
AUD_SDLMixer::~AUD_SDLMixer()
|
|
||||||
{
|
|
||||||
if(m_factory)
|
|
||||||
{
|
|
||||||
delete m_factory; AUD_DELETE("factory")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AUD_IReader* AUD_SDLMixer::prepare(AUD_IReader* reader)
|
|
||||||
{
|
|
||||||
m_factory->setReader(reader);
|
|
||||||
return m_factory->createReader();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_SDLMixer::setSpecs(AUD_Specs specs)
|
|
||||||
{
|
|
||||||
m_samplesize = AUD_SAMPLE_SIZE(specs);
|
|
||||||
if(m_factory)
|
|
||||||
{
|
|
||||||
delete m_factory; AUD_DELETE("factory")
|
|
||||||
}
|
|
||||||
m_factory = new AUD_SDLMixerFactory(specs); AUD_NEW("factory")
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_SDLMixer::add(sample_t* buffer, AUD_Specs specs, int length,
|
|
||||||
float volume)
|
|
||||||
{
|
|
||||||
AUD_SDLMixerBuffer buf;
|
|
||||||
buf.buffer = buffer;
|
|
||||||
buf.length = length;
|
|
||||||
buf.volume = volume;
|
|
||||||
m_buffers.push_back(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_SDLMixer::superpose(sample_t* buffer, int length, float volume)
|
|
||||||
{
|
|
||||||
AUD_SDLMixerBuffer buf;
|
|
||||||
|
|
||||||
while(!m_buffers.empty())
|
|
||||||
{
|
|
||||||
buf = m_buffers.front();
|
|
||||||
m_buffers.pop_front();
|
|
||||||
SDL_MixAudio((Uint8*)buffer,
|
|
||||||
(Uint8*)buf.buffer,
|
|
||||||
buf.length * m_samplesize,
|
|
||||||
(int)(SDL_MIX_MAXVOLUME * volume * buf.volume));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,216 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
|
||||||
*
|
|
||||||
* Copyright 2009 Jörg Hermann Müller
|
|
||||||
*
|
|
||||||
* This file is part of AudaSpace.
|
|
||||||
*
|
|
||||||
* AudaSpace 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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* ***** END LGPL LICENSE BLOCK *****
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "AUD_SDLMixerReader.h"
|
|
||||||
#include "AUD_Buffer.h"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
inline Uint16 AUD_TO_SDL(AUD_SampleFormat format)
|
|
||||||
{
|
|
||||||
// SDL only supports 8 and 16 bit audio
|
|
||||||
switch(format)
|
|
||||||
{
|
|
||||||
case AUD_FORMAT_U8:
|
|
||||||
return AUDIO_U8;
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
return AUDIO_S16SYS;
|
|
||||||
default:
|
|
||||||
AUD_THROW(AUD_ERROR_SDL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// greatest common divisor
|
|
||||||
inline int gcd(int a, int b)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
|
|
||||||
// make sure a is the bigger
|
|
||||||
if(b > a)
|
|
||||||
{
|
|
||||||
c = b;
|
|
||||||
b = a;
|
|
||||||
a = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
// greetings from Euclides
|
|
||||||
while(b != 0)
|
|
||||||
{
|
|
||||||
c = a % b;
|
|
||||||
a = b;
|
|
||||||
b = c;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
AUD_SDLMixerReader::AUD_SDLMixerReader(AUD_IReader* reader,
|
|
||||||
AUD_Specs specs)
|
|
||||||
{
|
|
||||||
if(reader == NULL)
|
|
||||||
AUD_THROW(AUD_ERROR_READER);
|
|
||||||
|
|
||||||
m_reader = reader;
|
|
||||||
m_tspecs = specs;
|
|
||||||
m_sspecs = reader->getSpecs();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// SDL only supports 8 and 16 bit sample formats
|
|
||||||
if(SDL_BuildAudioCVT(&m_cvt,
|
|
||||||
AUD_TO_SDL(m_sspecs.format),
|
|
||||||
m_sspecs.channels,
|
|
||||||
m_sspecs.rate,
|
|
||||||
AUD_TO_SDL(specs.format),
|
|
||||||
specs.channels,
|
|
||||||
specs.rate) == -1)
|
|
||||||
AUD_THROW(AUD_ERROR_SDL);
|
|
||||||
}
|
|
||||||
catch(AUD_Exception)
|
|
||||||
{
|
|
||||||
delete m_reader; AUD_DELETE("reader")
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_eor = false;
|
|
||||||
m_rsposition = 0;
|
|
||||||
m_rssize = 0;
|
|
||||||
m_ssize = m_sspecs.rate / gcd(specs.rate, m_sspecs.rate);
|
|
||||||
m_tsize = m_tspecs.rate * m_ssize / m_sspecs.rate;
|
|
||||||
|
|
||||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
|
||||||
m_rsbuffer = new AUD_Buffer(); AUD_NEW("buffer")
|
|
||||||
}
|
|
||||||
|
|
||||||
AUD_SDLMixerReader::~AUD_SDLMixerReader()
|
|
||||||
{
|
|
||||||
delete m_reader; AUD_DELETE("reader")
|
|
||||||
delete m_buffer; AUD_DELETE("buffer")
|
|
||||||
delete m_rsbuffer; AUD_DELETE("buffer")
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AUD_SDLMixerReader::isSeekable()
|
|
||||||
{
|
|
||||||
return m_reader->isSeekable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_SDLMixerReader::seek(int position)
|
|
||||||
{
|
|
||||||
m_reader->seek(position * m_ssize / m_tsize);
|
|
||||||
m_eor = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AUD_SDLMixerReader::getLength()
|
|
||||||
{
|
|
||||||
return m_reader->getLength() * m_tsize / m_ssize;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AUD_SDLMixerReader::getPosition()
|
|
||||||
{
|
|
||||||
return m_reader->getPosition() * m_tsize / m_ssize;
|
|
||||||
}
|
|
||||||
|
|
||||||
AUD_Specs AUD_SDLMixerReader::getSpecs()
|
|
||||||
{
|
|
||||||
return m_tspecs;
|
|
||||||
}
|
|
||||||
|
|
||||||
AUD_ReaderType AUD_SDLMixerReader::getType()
|
|
||||||
{
|
|
||||||
return m_reader->getType();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AUD_SDLMixerReader::notify(AUD_Message &message)
|
|
||||||
{
|
|
||||||
return m_reader->notify(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_SDLMixerReader::read(int & length, sample_t* & buffer)
|
|
||||||
{
|
|
||||||
// sample count for the target buffer without getting a shift
|
|
||||||
int tns = length + m_tsize - length % m_tsize;
|
|
||||||
// sample count for the source buffer without getting a shift
|
|
||||||
int sns = tns * m_ssize / m_tsize;
|
|
||||||
// target sample size
|
|
||||||
int tss = AUD_SAMPLE_SIZE(m_tspecs);
|
|
||||||
// source sample size
|
|
||||||
int sss = AUD_SAMPLE_SIZE(m_sspecs);
|
|
||||||
|
|
||||||
// input is output buffer
|
|
||||||
int buf_size = AUD_MAX(tns*tss, sns*sss);
|
|
||||||
|
|
||||||
// resize if necessary
|
|
||||||
if(m_rsbuffer->getSize() < buf_size)
|
|
||||||
m_rsbuffer->resize(buf_size, true);
|
|
||||||
|
|
||||||
if(m_buffer->getSize() < length*tss)
|
|
||||||
m_buffer->resize(length*tss);
|
|
||||||
|
|
||||||
buffer = m_buffer->getBuffer();
|
|
||||||
int size;
|
|
||||||
int index = 0;
|
|
||||||
sample_t* buf;
|
|
||||||
|
|
||||||
while(index < length)
|
|
||||||
{
|
|
||||||
if(m_rsposition == m_rssize)
|
|
||||||
{
|
|
||||||
// no more data
|
|
||||||
if(m_eor)
|
|
||||||
length = index;
|
|
||||||
// mix
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// read from source
|
|
||||||
size = sns;
|
|
||||||
m_reader->read(size, buf);
|
|
||||||
|
|
||||||
// prepare
|
|
||||||
m_cvt.buf = m_rsbuffer->getBuffer();
|
|
||||||
m_cvt.len = size*sss;
|
|
||||||
memcpy(m_cvt.buf, buf, size*sss);
|
|
||||||
|
|
||||||
// convert
|
|
||||||
SDL_ConvertAudio(&m_cvt);
|
|
||||||
|
|
||||||
// end of reader
|
|
||||||
if(size < sns)
|
|
||||||
m_eor = true;
|
|
||||||
|
|
||||||
m_rsposition = 0;
|
|
||||||
m_rssize = size * m_tsize / m_ssize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// size to copy
|
|
||||||
size = AUD_MIN(m_rssize-m_rsposition, length-index);
|
|
||||||
|
|
||||||
// copy
|
|
||||||
memcpy(m_buffer->getBuffer() + index * tss,
|
|
||||||
m_rsbuffer->getBuffer() + m_rsposition * tss,
|
|
||||||
size*tss);
|
|
||||||
m_rsposition += size;
|
|
||||||
index += size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
|
||||||
*
|
|
||||||
* Copyright 2009 Jörg Hermann Müller
|
|
||||||
*
|
|
||||||
* This file is part of AudaSpace.
|
|
||||||
*
|
|
||||||
* AudaSpace 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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* ***** END LGPL LICENSE BLOCK *****
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef AUD_SDLMIXERREADER
|
|
||||||
#define AUD_SDLMIXERREADER
|
|
||||||
|
|
||||||
#include "AUD_IReader.h"
|
|
||||||
class AUD_Buffer;
|
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class mixes a sound source with help of the SDL library.
|
|
||||||
* Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as
|
|
||||||
* well as resampling only 2^n sample rate relationships where n is a natural
|
|
||||||
* number.
|
|
||||||
* \warning Although SDL can only resample 2^n sample rate relationships, this
|
|
||||||
* class doesn't check for compliance, so in case of other factors,
|
|
||||||
* the behaviour is undefined.
|
|
||||||
*/
|
|
||||||
class AUD_SDLMixerReader : public AUD_IReader
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* The reader that is being mixed.
|
|
||||||
*/
|
|
||||||
AUD_IReader* m_reader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current reading position in the resampling buffer.
|
|
||||||
*/
|
|
||||||
int m_rsposition;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The count of mixed samples in the resampling buffer.
|
|
||||||
*/
|
|
||||||
int m_rssize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The smallest count of source samples to get a fractionless resampling
|
|
||||||
* factor.
|
|
||||||
*/
|
|
||||||
int m_ssize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The smallest count of target samples to get a fractionless resampling
|
|
||||||
* factor.
|
|
||||||
*/
|
|
||||||
int m_tsize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The sound output buffer.
|
|
||||||
*/
|
|
||||||
AUD_Buffer *m_buffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The resampling buffer.
|
|
||||||
*/
|
|
||||||
AUD_Buffer *m_rsbuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The target specification.
|
|
||||||
*/
|
|
||||||
AUD_Specs m_tspecs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The sample specification of the source.
|
|
||||||
*/
|
|
||||||
AUD_Specs m_sspecs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves whether the end of the source has been reached.
|
|
||||||
*/
|
|
||||||
bool m_eor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The SDL_AudioCVT structure used for resampling.
|
|
||||||
*/
|
|
||||||
SDL_AudioCVT m_cvt;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Creates a resampling reader.
|
|
||||||
* \param reader The reader to mix.
|
|
||||||
* \param specs The target specification.
|
|
||||||
* \exception AUD_Exception Thrown if the source specification cannot be
|
|
||||||
* mixed to the target specification or if the reader is
|
|
||||||
* NULL.
|
|
||||||
*/
|
|
||||||
AUD_SDLMixerReader(AUD_IReader* reader, AUD_Specs specs);
|
|
||||||
/**
|
|
||||||
* Destroys the reader.
|
|
||||||
*/
|
|
||||||
~AUD_SDLMixerReader();
|
|
||||||
|
|
||||||
virtual bool isSeekable();
|
|
||||||
virtual void seek(int position);
|
|
||||||
virtual int getLength();
|
|
||||||
virtual int getPosition();
|
|
||||||
virtual AUD_Specs getSpecs();
|
|
||||||
virtual AUD_ReaderType getType();
|
|
||||||
virtual bool notify(AUD_Message &message);
|
|
||||||
virtual void read(int & length, sample_t* & buffer);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //AUD_SDLMIXERREADER
|
|
||||||
@@ -27,14 +27,14 @@
|
|||||||
#include "AUD_SRCResampleReader.h"
|
#include "AUD_SRCResampleReader.h"
|
||||||
|
|
||||||
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IReader* reader,
|
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IReader* reader,
|
||||||
AUD_Specs specs) :
|
AUD_DeviceSpecs specs) :
|
||||||
AUD_ResampleFactory(reader, specs) {}
|
AUD_ResampleFactory(reader, specs) {}
|
||||||
|
|
||||||
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IFactory* factory,
|
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IFactory* factory,
|
||||||
AUD_Specs specs) :
|
AUD_DeviceSpecs specs) :
|
||||||
AUD_ResampleFactory(factory, specs) {}
|
AUD_ResampleFactory(factory, specs) {}
|
||||||
|
|
||||||
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_Specs specs) :
|
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_DeviceSpecs specs) :
|
||||||
AUD_ResampleFactory(specs) {}
|
AUD_ResampleFactory(specs) {}
|
||||||
|
|
||||||
AUD_IReader* AUD_SRCResampleFactory::createReader()
|
AUD_IReader* AUD_SRCResampleFactory::createReader()
|
||||||
@@ -45,7 +45,7 @@ AUD_IReader* AUD_SRCResampleFactory::createReader()
|
|||||||
{
|
{
|
||||||
if(reader->getSpecs().rate != m_specs.rate)
|
if(reader->getSpecs().rate != m_specs.rate)
|
||||||
{
|
{
|
||||||
reader = new AUD_SRCResampleReader(reader, m_specs);
|
reader = new AUD_SRCResampleReader(reader, m_specs.specs);
|
||||||
AUD_NEW("reader")
|
AUD_NEW("reader")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,14 +31,13 @@
|
|||||||
/**
|
/**
|
||||||
* This factory creates a resampling reader that uses libsamplerate for
|
* This factory creates a resampling reader that uses libsamplerate for
|
||||||
* resampling.
|
* resampling.
|
||||||
* \note The format of the input must be float.
|
|
||||||
*/
|
*/
|
||||||
class AUD_SRCResampleFactory : public AUD_ResampleFactory
|
class AUD_SRCResampleFactory : public AUD_ResampleFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AUD_SRCResampleFactory(AUD_IReader* reader, AUD_Specs specs);
|
AUD_SRCResampleFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
|
||||||
AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_Specs specs);
|
AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
|
||||||
AUD_SRCResampleFactory(AUD_Specs specs);
|
AUD_SRCResampleFactory(AUD_DeviceSpecs specs);
|
||||||
|
|
||||||
virtual AUD_IReader* createReader();
|
virtual AUD_IReader* createReader();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,9 +26,9 @@
|
|||||||
#include "AUD_SRCResampleReader.h"
|
#include "AUD_SRCResampleReader.h"
|
||||||
#include "AUD_Buffer.h"
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
|
|
||||||
static long src_callback(void *cb_data, float **data)
|
static long src_callback(void *cb_data, float **data)
|
||||||
{
|
{
|
||||||
@@ -41,15 +41,8 @@ AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
|
|||||||
{
|
{
|
||||||
m_sspecs = reader->getSpecs();
|
m_sspecs = reader->getSpecs();
|
||||||
|
|
||||||
if(m_sspecs.format != AUD_FORMAT_FLOAT32)
|
|
||||||
{
|
|
||||||
delete m_reader; AUD_DELETE("reader")
|
|
||||||
AUD_THROW(AUD_ERROR_READER);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_tspecs = specs;
|
m_tspecs = specs;
|
||||||
m_tspecs.channels = m_sspecs.channels;
|
m_tspecs.channels = m_sspecs.channels;
|
||||||
m_tspecs.format = m_sspecs.format;
|
|
||||||
m_factor = (double)m_tspecs.rate / (double)m_sspecs.rate;
|
m_factor = (double)m_tspecs.rate / (double)m_sspecs.rate;
|
||||||
|
|
||||||
int error;
|
int error;
|
||||||
@@ -71,9 +64,9 @@ AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
|
|||||||
|
|
||||||
AUD_SRCResampleReader::~AUD_SRCResampleReader()
|
AUD_SRCResampleReader::~AUD_SRCResampleReader()
|
||||||
{
|
{
|
||||||
delete m_buffer; AUD_DELETE("buffer")
|
|
||||||
|
|
||||||
src_delete(m_src);
|
src_delete(m_src);
|
||||||
|
|
||||||
|
delete m_buffer; AUD_DELETE("buffer")
|
||||||
}
|
}
|
||||||
|
|
||||||
long AUD_SRCResampleReader::doCallback(float** data)
|
long AUD_SRCResampleReader::doCallback(float** data)
|
||||||
@@ -83,7 +76,7 @@ long AUD_SRCResampleReader::doCallback(float** data)
|
|||||||
|
|
||||||
m_reader->read(length, buffer);
|
m_reader->read(length, buffer);
|
||||||
|
|
||||||
*data = (float*)buffer;
|
*data = buffer;
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,10 +103,12 @@ AUD_Specs AUD_SRCResampleReader::getSpecs()
|
|||||||
|
|
||||||
void AUD_SRCResampleReader::read(int & length, sample_t* & buffer)
|
void AUD_SRCResampleReader::read(int & length, sample_t* & buffer)
|
||||||
{
|
{
|
||||||
if(m_buffer->getSize() < length * m_tspecs.channels * 4)
|
int size = length * AUD_SAMPLE_SIZE(m_tspecs);
|
||||||
m_buffer->resize(length * m_tspecs.channels * 4);
|
|
||||||
|
if(m_buffer->getSize() < size)
|
||||||
|
m_buffer->resize(size);
|
||||||
|
|
||||||
buffer = m_buffer->getBuffer();
|
buffer = m_buffer->getBuffer();
|
||||||
|
|
||||||
length = src_callback_read(m_src, m_factor, length, (float*)buffer);
|
length = src_callback_read(m_src, m_factor, length, buffer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,13 +32,7 @@ class AUD_Buffer;
|
|||||||
#include <samplerate.h>
|
#include <samplerate.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class mixes a sound source with help of the SDL library.
|
* This resampling reader uses libsamplerate for resampling.
|
||||||
* Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as
|
|
||||||
* well as resampling only 2^n sample rate relationships where n is a natural
|
|
||||||
* number.
|
|
||||||
* \warning Although SDL can only resample 2^n sample rate relationships, this
|
|
||||||
* class doesn't check for compliance, so in case of other factors,
|
|
||||||
* the behaviour is undefined.
|
|
||||||
*/
|
*/
|
||||||
class AUD_SRCResampleReader : public AUD_EffectReader
|
class AUD_SRCResampleReader : public AUD_EffectReader
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,26 +34,6 @@ extern "C" {
|
|||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function transforms a FFMPEG SampleFormat to our own sample format
|
|
||||||
static inline AUD_SampleFormat FFMPEG_TO_AUD(SampleFormat fmt)
|
|
||||||
{
|
|
||||||
switch(fmt)
|
|
||||||
{
|
|
||||||
case SAMPLE_FMT_U8:
|
|
||||||
return AUD_FORMAT_U8;
|
|
||||||
case SAMPLE_FMT_S16:
|
|
||||||
return AUD_FORMAT_S16;
|
|
||||||
case SAMPLE_FMT_S32:
|
|
||||||
return AUD_FORMAT_S32;
|
|
||||||
case SAMPLE_FMT_FLT:
|
|
||||||
return AUD_FORMAT_FLOAT32;
|
|
||||||
case SAMPLE_FMT_DBL:
|
|
||||||
return AUD_FORMAT_FLOAT64;
|
|
||||||
default:
|
|
||||||
return AUD_FORMAT_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
|
int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
|
||||||
{
|
{
|
||||||
// save packet parameters
|
// save packet parameters
|
||||||
@@ -78,11 +58,11 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
|
|||||||
// read samples from the packet
|
// read samples from the packet
|
||||||
data_size = buf_size - buf_pos;
|
data_size = buf_size - buf_pos;
|
||||||
/*read_length = avcodec_decode_audio3(m_codecCtx,
|
/*read_length = avcodec_decode_audio3(m_codecCtx,
|
||||||
(int16_t*)(buffer->getBuffer()+buf_pos),
|
(int16_t*)(((data_t*)buffer->getBuffer())+buf_pos),
|
||||||
&data_size,
|
&data_size,
|
||||||
packet);*/
|
packet);*/
|
||||||
read_length = avcodec_decode_audio2(m_codecCtx,
|
read_length = avcodec_decode_audio2(m_codecCtx,
|
||||||
(int16_t*)(buffer->getBuffer()+buf_pos),
|
(int16_t*)(((data_t*)buffer->getBuffer())+buf_pos),
|
||||||
&data_size,
|
&data_size,
|
||||||
audio_pkg_data,
|
audio_pkg_data,
|
||||||
audio_pkg_size);
|
audio_pkg_size);
|
||||||
@@ -101,10 +81,78 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
|
|||||||
return buf_pos;
|
return buf_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
|
void AUD_FFMPEGReader::init()
|
||||||
{
|
{
|
||||||
m_position = 0;
|
m_position = 0;
|
||||||
m_pkgbuf_left = 0;
|
m_pkgbuf_left = 0;
|
||||||
|
|
||||||
|
if(av_find_stream_info(m_formatCtx)<0)
|
||||||
|
AUD_THROW(AUD_ERROR_FFMPEG);
|
||||||
|
|
||||||
|
// find audio stream and codec
|
||||||
|
m_stream = -1;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
|
||||||
|
if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
|
||||||
|
&& (m_stream < 0))
|
||||||
|
{
|
||||||
|
m_stream=i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(m_stream == -1)
|
||||||
|
AUD_THROW(AUD_ERROR_FFMPEG);
|
||||||
|
|
||||||
|
m_codecCtx = m_formatCtx->streams[m_stream]->codec;
|
||||||
|
|
||||||
|
// get a decoder and open it
|
||||||
|
AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
|
||||||
|
if(!aCodec)
|
||||||
|
AUD_THROW(AUD_ERROR_FFMPEG);
|
||||||
|
|
||||||
|
if(avcodec_open(m_codecCtx, aCodec)<0)
|
||||||
|
AUD_THROW(AUD_ERROR_FFMPEG);
|
||||||
|
|
||||||
|
// XXX this prints file information to stdout:
|
||||||
|
//dump_format(m_formatCtx, 0, NULL, 0);
|
||||||
|
|
||||||
|
m_specs.channels = (AUD_Channels) m_codecCtx->channels;
|
||||||
|
|
||||||
|
switch(m_codecCtx->sample_fmt)
|
||||||
|
{
|
||||||
|
case SAMPLE_FMT_U8:
|
||||||
|
m_convert = AUD_convert_u8_float;
|
||||||
|
m_specs.format = AUD_FORMAT_U8;
|
||||||
|
break;
|
||||||
|
case SAMPLE_FMT_S16:
|
||||||
|
m_convert = AUD_convert_s16_float;
|
||||||
|
m_specs.format = AUD_FORMAT_S16;
|
||||||
|
break;
|
||||||
|
case SAMPLE_FMT_S32:
|
||||||
|
m_convert = AUD_convert_s32_float;
|
||||||
|
m_specs.format = AUD_FORMAT_S32;
|
||||||
|
break;
|
||||||
|
case SAMPLE_FMT_FLT:
|
||||||
|
m_convert = AUD_convert_copy<float>;
|
||||||
|
m_specs.format = AUD_FORMAT_FLOAT32;
|
||||||
|
break;
|
||||||
|
case SAMPLE_FMT_DBL:
|
||||||
|
m_convert = AUD_convert_double_float;
|
||||||
|
m_specs.format = AUD_FORMAT_FLOAT64;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AUD_THROW(AUD_ERROR_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
|
||||||
|
|
||||||
|
// last but not least if there hasn't been any error, create the buffers
|
||||||
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
|
||||||
|
AUD_NEW("buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
|
||||||
|
{
|
||||||
m_byteiocontext = NULL;
|
m_byteiocontext = NULL;
|
||||||
|
|
||||||
// open file
|
// open file
|
||||||
@@ -113,66 +161,28 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(av_find_stream_info(m_formatCtx)<0)
|
init();
|
||||||
AUD_THROW(AUD_ERROR_FFMPEG);
|
|
||||||
|
|
||||||
// find audio stream and codec
|
|
||||||
m_stream = -1;
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
|
|
||||||
if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
|
|
||||||
&& (m_stream < 0))
|
|
||||||
{
|
|
||||||
m_stream=i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(m_stream == -1)
|
|
||||||
AUD_THROW(AUD_ERROR_FFMPEG);
|
|
||||||
|
|
||||||
m_codecCtx = m_formatCtx->streams[m_stream]->codec;
|
|
||||||
|
|
||||||
// get a decoder and open it
|
|
||||||
AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
|
|
||||||
if(!aCodec)
|
|
||||||
AUD_THROW(AUD_ERROR_FFMPEG);
|
|
||||||
|
|
||||||
if(avcodec_open(m_codecCtx, aCodec)<0)
|
|
||||||
AUD_THROW(AUD_ERROR_FFMPEG);
|
|
||||||
|
|
||||||
// XXX this prints file information to stdout:
|
|
||||||
//dump_format(m_formatCtx, 0, filename, 0);
|
|
||||||
|
|
||||||
m_specs.channels = (AUD_Channels) m_codecCtx->channels;
|
|
||||||
m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
|
|
||||||
m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
|
|
||||||
}
|
}
|
||||||
catch(AUD_Exception)
|
catch(AUD_Exception)
|
||||||
{
|
{
|
||||||
av_close_input_file(m_formatCtx);
|
av_close_input_file(m_formatCtx);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
// last but not least if there hasn't been any error, create the buffers
|
|
||||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
|
||||||
m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
|
|
||||||
AUD_NEW("buffer")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
|
AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
|
||||||
{
|
{
|
||||||
m_position = 0;
|
|
||||||
m_pkgbuf_left = 0;
|
|
||||||
m_byteiocontext = (ByteIOContext*)av_mallocz(sizeof(ByteIOContext));
|
m_byteiocontext = (ByteIOContext*)av_mallocz(sizeof(ByteIOContext));
|
||||||
AUD_NEW("byteiocontext")
|
AUD_NEW("byteiocontext")
|
||||||
m_membuffer = buffer;
|
m_membuffer = buffer;
|
||||||
|
|
||||||
if(init_put_byte(m_byteiocontext, buffer.get()->getBuffer(), buffer.get()->getSize(), 0,
|
if(init_put_byte(m_byteiocontext, (data_t*)buffer.get()->getBuffer(),
|
||||||
NULL, NULL, NULL, NULL) != 0)
|
buffer.get()->getSize(), 0, NULL, NULL, NULL, NULL) != 0)
|
||||||
AUD_THROW(AUD_ERROR_FILE);
|
AUD_THROW(AUD_ERROR_FILE);
|
||||||
|
|
||||||
AVProbeData probe_data;
|
AVProbeData probe_data;
|
||||||
probe_data.filename = "";
|
probe_data.filename = "";
|
||||||
probe_data.buf = buffer.get()->getBuffer();
|
probe_data.buf = (data_t*)buffer.get()->getBuffer();
|
||||||
probe_data.buf_size = buffer.get()->getSize();
|
probe_data.buf_size = buffer.get()->getSize();
|
||||||
AVInputFormat* fmt = av_probe_input_format(&probe_data, 1);
|
AVInputFormat* fmt = av_probe_input_format(&probe_data, 1);
|
||||||
|
|
||||||
@@ -182,38 +192,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(av_find_stream_info(m_formatCtx)<0)
|
init();
|
||||||
AUD_THROW(AUD_ERROR_FFMPEG);
|
|
||||||
|
|
||||||
// find audio stream and codec
|
|
||||||
m_stream = -1;
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
|
|
||||||
if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
|
|
||||||
&& (m_stream < 0))
|
|
||||||
{
|
|
||||||
m_stream=i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(m_stream == -1)
|
|
||||||
AUD_THROW(AUD_ERROR_FFMPEG);
|
|
||||||
|
|
||||||
m_codecCtx = m_formatCtx->streams[m_stream]->codec;
|
|
||||||
|
|
||||||
// get a decoder and open it
|
|
||||||
AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
|
|
||||||
if(!aCodec)
|
|
||||||
AUD_THROW(AUD_ERROR_FFMPEG);
|
|
||||||
|
|
||||||
if(avcodec_open(m_codecCtx, aCodec)<0)
|
|
||||||
AUD_THROW(AUD_ERROR_FFMPEG);
|
|
||||||
|
|
||||||
// XXX this prints stream information to stdout:
|
|
||||||
//dump_format(m_formatCtx, 0, NULL, 0);
|
|
||||||
|
|
||||||
m_specs.channels = (AUD_Channels) m_codecCtx->channels;
|
|
||||||
m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
|
|
||||||
m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
|
|
||||||
}
|
}
|
||||||
catch(AUD_Exception)
|
catch(AUD_Exception)
|
||||||
{
|
{
|
||||||
@@ -221,11 +200,6 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
|
|||||||
av_free(m_byteiocontext); AUD_DELETE("byteiocontext")
|
av_free(m_byteiocontext); AUD_DELETE("byteiocontext")
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
// last but not least if there hasn't been any error, create the buffers
|
|
||||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
|
||||||
m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
|
|
||||||
AUD_NEW("buffer")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_FFMPEGReader::~AUD_FFMPEGReader()
|
AUD_FFMPEGReader::~AUD_FFMPEGReader()
|
||||||
@@ -316,7 +290,7 @@ int AUD_FFMPEGReader::getPosition()
|
|||||||
|
|
||||||
AUD_Specs AUD_FFMPEGReader::getSpecs()
|
AUD_Specs AUD_FFMPEGReader::getSpecs()
|
||||||
{
|
{
|
||||||
return m_specs;
|
return m_specs.specs;
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_ReaderType AUD_FFMPEGReader::getType()
|
AUD_ReaderType AUD_FFMPEGReader::getType()
|
||||||
@@ -336,11 +310,11 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
|
|||||||
int data_size = 0;
|
int data_size = 0;
|
||||||
int pkgbuf_pos;
|
int pkgbuf_pos;
|
||||||
int left = length;
|
int left = length;
|
||||||
int sample_size = AUD_SAMPLE_SIZE(m_specs);
|
int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
|
||||||
|
|
||||||
// resize output buffer if necessary
|
// resize output buffer if necessary
|
||||||
if(m_buffer->getSize() < length*sample_size)
|
if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(m_specs))
|
||||||
m_buffer->resize(length*sample_size);
|
m_buffer->resize(length * AUD_SAMPLE_SIZE(m_specs));
|
||||||
|
|
||||||
buffer = m_buffer->getBuffer();
|
buffer = m_buffer->getBuffer();
|
||||||
pkgbuf_pos = m_pkgbuf_left;
|
pkgbuf_pos = m_pkgbuf_left;
|
||||||
@@ -350,8 +324,9 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
|
|||||||
if(pkgbuf_pos > 0)
|
if(pkgbuf_pos > 0)
|
||||||
{
|
{
|
||||||
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
|
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
|
||||||
memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
|
m_convert((data_t*) buffer, (data_t*) m_pkgbuf->getBuffer(),
|
||||||
buffer += data_size;
|
data_size / AUD_FORMAT_SIZE(m_specs.format));
|
||||||
|
buffer += data_size / AUD_FORMAT_SIZE(m_specs.format);
|
||||||
left -= data_size/sample_size;
|
left -= data_size/sample_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,8 +341,9 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
|
|||||||
|
|
||||||
// copy to output buffer
|
// copy to output buffer
|
||||||
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
|
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
|
||||||
memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
|
m_convert((data_t*) buffer, (data_t*) m_pkgbuf->getBuffer(),
|
||||||
buffer += data_size;
|
data_size / AUD_FORMAT_SIZE(m_specs.format));
|
||||||
|
buffer += data_size / AUD_FORMAT_SIZE(m_specs.format);
|
||||||
left -= data_size/sample_size;
|
left -= data_size/sample_size;
|
||||||
}
|
}
|
||||||
av_free_packet(&packet);
|
av_free_packet(&packet);
|
||||||
@@ -376,7 +352,8 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
|
|||||||
if(pkgbuf_pos > data_size)
|
if(pkgbuf_pos > data_size)
|
||||||
{
|
{
|
||||||
m_pkgbuf_left = pkgbuf_pos-data_size;
|
m_pkgbuf_left = pkgbuf_pos-data_size;
|
||||||
memmove(m_pkgbuf->getBuffer(), m_pkgbuf->getBuffer()+data_size,
|
memmove(m_pkgbuf->getBuffer(),
|
||||||
|
((data_t*)m_pkgbuf->getBuffer())+data_size,
|
||||||
pkgbuf_pos-data_size);
|
pkgbuf_pos-data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#ifndef AUD_FFMPEGREADER
|
#ifndef AUD_FFMPEGREADER
|
||||||
#define AUD_FFMPEGREADER
|
#define AUD_FFMPEGREADER
|
||||||
|
|
||||||
|
#include "AUD_ConverterFunctions.h"
|
||||||
#include "AUD_IReader.h"
|
#include "AUD_IReader.h"
|
||||||
#include "AUD_Reference.h"
|
#include "AUD_Reference.h"
|
||||||
class AUD_Buffer;
|
class AUD_Buffer;
|
||||||
@@ -59,7 +60,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* The specification of the audio data.
|
* The specification of the audio data.
|
||||||
*/
|
*/
|
||||||
AUD_Specs m_specs;
|
AUD_DeviceSpecs m_specs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The buffer for package reading.
|
* The buffer for package reading.
|
||||||
@@ -91,6 +92,11 @@ private:
|
|||||||
*/
|
*/
|
||||||
int m_stream;
|
int m_stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converter function.
|
||||||
|
*/
|
||||||
|
AUD_convert_f m_convert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The memory file to read from, only saved to keep the buffer alive.
|
* The memory file to read from, only saved to keep the buffer alive.
|
||||||
*/
|
*/
|
||||||
@@ -104,6 +110,11 @@ private:
|
|||||||
*/
|
*/
|
||||||
int decode(AVPacket* packet, AUD_Buffer* buffer);
|
int decode(AVPacket* packet, AUD_Buffer* buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
*/
|
||||||
|
void init();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates a new reader.
|
* Creates a new reader.
|
||||||
|
|||||||
@@ -63,16 +63,8 @@ AUD_IReader* AUD_BandPassFactory::createReader()
|
|||||||
|
|
||||||
if(reader != 0)
|
if(reader != 0)
|
||||||
{
|
{
|
||||||
if(reader->getSpecs().format == AUD_FORMAT_FLOAT32)
|
reader = new AUD_BandPassReader(reader, m_low, m_high);
|
||||||
{
|
AUD_NEW("reader")
|
||||||
reader = new AUD_BandPassReader(reader, m_low, m_high);
|
|
||||||
AUD_NEW("reader")
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete reader; AUD_DELETE("reader")
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return reader;
|
return reader;
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ void AUD_BandPassReader::read(int & length, sample_t* & buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_length = length;
|
m_length = length;
|
||||||
printf("WINDOW: %d\n", m_length);
|
|
||||||
|
|
||||||
if(m_length * sizeof(double) > m_in->getSize())
|
if(m_length * sizeof(double) > m_in->getSize())
|
||||||
{
|
{
|
||||||
@@ -95,22 +94,21 @@ void AUD_BandPassReader::read(int & length, sample_t* & buffer)
|
|||||||
FFTW_ESTIMATE);
|
FFTW_ESTIMATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
float* source = (float*) buffer;
|
|
||||||
double* target = (double*) m_in->getBuffer();
|
double* target = (double*) m_in->getBuffer();
|
||||||
float* target2 = (float*) m_buffer->getBuffer();
|
sample_t* target2 = m_buffer->getBuffer();
|
||||||
fftw_complex* complex = (fftw_complex*) m_out->getBuffer();
|
fftw_complex* complex = (fftw_complex*) m_out->getBuffer();
|
||||||
float frequency;
|
float frequency;
|
||||||
|
|
||||||
for(int channel = 0; channel < specs.channels; channel++)
|
for(int channel = 0; channel < specs.channels; channel++)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < m_length; i++)
|
for(int i = 0; i < m_length; i++)
|
||||||
target[i] = source[i * specs.channels + channel];
|
target[i] = buffer[i * specs.channels + channel];
|
||||||
|
|
||||||
fftw_execute(m_forward);
|
fftw_execute(m_forward);
|
||||||
|
|
||||||
for(int i = 0; i < m_length / 2 + 1; i++)
|
for(int i = 0; i < m_length / 2 + 1; i++)
|
||||||
{
|
{
|
||||||
frequency = i * specs.rate / (m_length / 2.0 + 1.0);
|
frequency = i * specs.rate / (m_length / 2.0f + 1.0f);
|
||||||
if((frequency < m_low) || (frequency > m_high))
|
if((frequency < m_low) || (frequency > m_high))
|
||||||
complex[i][0] = complex[i][1] = 0.0;
|
complex[i][0] = complex[i][1] = 0.0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,14 +27,14 @@
|
|||||||
#include "AUD_Space.h"
|
#include "AUD_Space.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
#define AUD_ALIGN(a) (a + 16 - ((long)a & 15))
|
#define AUD_ALIGN(a) (a + 16 - ((long)a & 15))
|
||||||
|
|
||||||
AUD_Buffer::AUD_Buffer(int size)
|
AUD_Buffer::AUD_Buffer(int size)
|
||||||
{
|
{
|
||||||
m_size = size;
|
m_size = size;
|
||||||
m_buffer = (sample_t*) malloc(size+16); AUD_NEW("buffer")
|
m_buffer = (data_t*) malloc(size+16); AUD_NEW("buffer")
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_Buffer::~AUD_Buffer()
|
AUD_Buffer::~AUD_Buffer()
|
||||||
@@ -44,7 +44,7 @@ AUD_Buffer::~AUD_Buffer()
|
|||||||
|
|
||||||
sample_t* AUD_Buffer::getBuffer()
|
sample_t* AUD_Buffer::getBuffer()
|
||||||
{
|
{
|
||||||
return AUD_ALIGN(m_buffer);
|
return (sample_t*) AUD_ALIGN(m_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AUD_Buffer::getSize()
|
int AUD_Buffer::getSize()
|
||||||
@@ -54,7 +54,7 @@ int AUD_Buffer::getSize()
|
|||||||
|
|
||||||
void AUD_Buffer::resize(int size, bool keep)
|
void AUD_Buffer::resize(int size, bool keep)
|
||||||
{
|
{
|
||||||
sample_t* buffer = (sample_t*) malloc(size+16); AUD_NEW("buffer")
|
data_t* buffer = (data_t*) malloc(size+16); AUD_NEW("buffer")
|
||||||
|
|
||||||
// copy old data over if wanted
|
// copy old data over if wanted
|
||||||
if(keep)
|
if(keep)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ private:
|
|||||||
int m_size;
|
int m_size;
|
||||||
|
|
||||||
/// The pointer to the buffer memory.
|
/// The pointer to the buffer memory.
|
||||||
sample_t* m_buffer;
|
data_t* m_buffer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -79,11 +79,11 @@ void AUD_BufferReader::read(int & length, sample_t* & buffer)
|
|||||||
{
|
{
|
||||||
int sample_size = AUD_SAMPLE_SIZE(m_specs);
|
int sample_size = AUD_SAMPLE_SIZE(m_specs);
|
||||||
|
|
||||||
buffer = m_buffer.get()->getBuffer()+m_position*sample_size;
|
buffer = m_buffer.get()->getBuffer() + m_position * m_specs.channels;
|
||||||
|
|
||||||
// in case the end of the buffer is reached
|
// in case the end of the buffer is reached
|
||||||
if(m_buffer.get()->getSize() < (m_position+length)*sample_size)
|
if(m_buffer.get()->getSize() < (m_position + length) * sample_size)
|
||||||
length = m_buffer.get()->getSize()/sample_size-m_position;
|
length = m_buffer.get()->getSize() / sample_size - m_position;
|
||||||
|
|
||||||
if(length < 0)
|
if(length < 0)
|
||||||
length = 0;
|
length = 0;
|
||||||
|
|||||||
@@ -23,6 +23,9 @@
|
|||||||
* ***** END LGPL LICENSE BLOCK *****
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "AUD_NULLDevice.h"
|
#include "AUD_NULLDevice.h"
|
||||||
#include "AUD_I3DDevice.h"
|
#include "AUD_I3DDevice.h"
|
||||||
#include "AUD_FileFactory.h"
|
#include "AUD_FileFactory.h"
|
||||||
@@ -32,13 +35,21 @@
|
|||||||
#include "AUD_PingPongFactory.h"
|
#include "AUD_PingPongFactory.h"
|
||||||
#include "AUD_LoopFactory.h"
|
#include "AUD_LoopFactory.h"
|
||||||
#include "AUD_RectifyFactory.h"
|
#include "AUD_RectifyFactory.h"
|
||||||
|
#include "AUD_EnvelopeFactory.h"
|
||||||
|
#include "AUD_LinearResampleFactory.h"
|
||||||
|
#include "AUD_LowpassFactory.h"
|
||||||
|
#include "AUD_HighpassFactory.h"
|
||||||
|
#include "AUD_AccumulatorFactory.h"
|
||||||
|
#include "AUD_SumFactory.h"
|
||||||
|
#include "AUD_SquareFactory.h"
|
||||||
|
#include "AUD_ChannelMapperFactory.h"
|
||||||
|
#include "AUD_Buffer.h"
|
||||||
#include "AUD_ReadDevice.h"
|
#include "AUD_ReadDevice.h"
|
||||||
#include "AUD_SourceCaps.h"
|
#include "AUD_SourceCaps.h"
|
||||||
#include "AUD_IReader.h"
|
#include "AUD_IReader.h"
|
||||||
|
|
||||||
#ifdef WITH_SDL
|
#ifdef WITH_SDL
|
||||||
#include "AUD_SDLDevice.h"
|
#include "AUD_SDLDevice.h"
|
||||||
#include "AUD_FloatMixer.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_OPENAL
|
#ifdef WITH_OPENAL
|
||||||
@@ -55,7 +66,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
|
|
||||||
typedef AUD_IFactory AUD_Sound;
|
typedef AUD_IFactory AUD_Sound;
|
||||||
typedef AUD_ReadDevice AUD_Device;
|
typedef AUD_ReadDevice AUD_Device;
|
||||||
@@ -71,7 +82,7 @@ static AUD_IDevice* AUD_device = NULL;
|
|||||||
static int AUD_available_devices[4];
|
static int AUD_available_devices[4];
|
||||||
static AUD_I3DDevice* AUD_3ddevice = NULL;
|
static AUD_I3DDevice* AUD_3ddevice = NULL;
|
||||||
|
|
||||||
int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize)
|
int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
|
||||||
{
|
{
|
||||||
#ifdef WITH_FFMPEG
|
#ifdef WITH_FFMPEG
|
||||||
av_register_all();
|
av_register_all();
|
||||||
@@ -90,12 +101,8 @@ int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize)
|
|||||||
break;
|
break;
|
||||||
#ifdef WITH_SDL
|
#ifdef WITH_SDL
|
||||||
case AUD_SDL_DEVICE:
|
case AUD_SDL_DEVICE:
|
||||||
{
|
dev = new AUD_SDLDevice(specs, buffersize);
|
||||||
dev = new AUD_SDLDevice(specs, buffersize);
|
break;
|
||||||
AUD_FloatMixer* mixer = new AUD_FloatMixer();
|
|
||||||
((AUD_SDLDevice*)dev)->setMixer(mixer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_OPENAL
|
#ifdef WITH_OPENAL
|
||||||
case AUD_OPENAL_DEVICE:
|
case AUD_OPENAL_DEVICE:
|
||||||
@@ -177,9 +184,8 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
info.specs.channels = AUD_CHANNELS_INVALID;
|
info.specs.channels = AUD_CHANNELS_INVALID;
|
||||||
info.specs.format = AUD_FORMAT_INVALID;
|
|
||||||
info.specs.rate = AUD_RATE_INVALID;
|
info.specs.rate = AUD_RATE_INVALID;
|
||||||
info.length = 0.0;
|
info.length = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
@@ -424,7 +430,7 @@ float AUD_get3DSetting(AUD_3DSetting setting)
|
|||||||
catch(AUD_Exception)
|
catch(AUD_Exception)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
return 0.0;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data)
|
int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data)
|
||||||
@@ -480,7 +486,7 @@ float AUD_get3DSourceSetting(AUD_Handle* handle, AUD_3DSourceSetting setting)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0.0;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AUD_setSoundVolume(AUD_Handle* handle, float volume)
|
int AUD_setSoundVolume(AUD_Handle* handle, float volume)
|
||||||
@@ -519,7 +525,7 @@ int AUD_setSoundPitch(AUD_Handle* handle, float pitch)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_Device* AUD_openReadDevice(AUD_Specs specs)
|
AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -578,7 +584,7 @@ int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length)
|
int AUD_readDevice(AUD_Device* device, data_t* buffer, int length)
|
||||||
{
|
{
|
||||||
assert(device);
|
assert(device);
|
||||||
assert(buffer);
|
assert(buffer);
|
||||||
@@ -605,3 +611,55 @@ void AUD_closeReadDevice(AUD_Device* device)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float* AUD_readSoundBuffer(const char* filename, float low, float high,
|
||||||
|
float attack, float release, float threshold,
|
||||||
|
int accumulate, int additive, int square,
|
||||||
|
float sthreshold, int samplerate, int* length)
|
||||||
|
{
|
||||||
|
AUD_Buffer buffer;
|
||||||
|
AUD_DeviceSpecs specs;
|
||||||
|
specs.channels = AUD_CHANNELS_MONO;
|
||||||
|
specs.rate = (AUD_SampleRate)samplerate;
|
||||||
|
AUD_Sound* sound;
|
||||||
|
|
||||||
|
AUD_FileFactory file(filename);
|
||||||
|
AUD_ChannelMapperFactory mapper(&file, specs);
|
||||||
|
AUD_LowpassFactory lowpass(&mapper, high);
|
||||||
|
AUD_HighpassFactory highpass(&lowpass, low);
|
||||||
|
AUD_EnvelopeFactory envelope(&highpass, attack, release, threshold, 0.1f);
|
||||||
|
AUD_LinearResampleFactory resampler(&envelope, specs);
|
||||||
|
sound = &resampler;
|
||||||
|
AUD_SquareFactory squaref(sound, sthreshold);
|
||||||
|
if(square)
|
||||||
|
sound = &squaref;
|
||||||
|
AUD_AccumulatorFactory accumulator(sound, additive);
|
||||||
|
AUD_SumFactory sum(sound);
|
||||||
|
if(accumulate)
|
||||||
|
sound = &accumulator;
|
||||||
|
else if(additive)
|
||||||
|
sound = ∑
|
||||||
|
|
||||||
|
AUD_IReader* reader = sound->createReader();
|
||||||
|
|
||||||
|
if(reader == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
int len;
|
||||||
|
int position = 0;
|
||||||
|
sample_t* readbuffer;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
len = samplerate;
|
||||||
|
buffer.resize((position + len) * sizeof(float), true);
|
||||||
|
reader->read(len, readbuffer);
|
||||||
|
memcpy(buffer.getBuffer() + position, readbuffer, len * sizeof(float));
|
||||||
|
position += len;
|
||||||
|
} while(len != 0);
|
||||||
|
delete reader;
|
||||||
|
|
||||||
|
float* result = (float*)malloc(position * sizeof(float));
|
||||||
|
memcpy(result, buffer.getBuffer(), position * sizeof(float));
|
||||||
|
*length = position;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ typedef struct
|
|||||||
* \param buffersize The buffersize for the device.
|
* \param buffersize The buffersize for the device.
|
||||||
* \return Whether the device has been initialized.
|
* \return Whether the device has been initialized.
|
||||||
*/
|
*/
|
||||||
extern int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize);
|
extern int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a integer list with available sound devices. The last one is always
|
* Returns a integer list with available sound devices. The last one is always
|
||||||
@@ -304,7 +304,7 @@ extern int AUD_setSoundPitch(AUD_Handle* handle, float pitch);
|
|||||||
* \param specs The specification of the audio data.
|
* \param specs The specification of the audio data.
|
||||||
* \return A device handle.
|
* \return A device handle.
|
||||||
*/
|
*/
|
||||||
extern AUD_Device* AUD_openReadDevice(AUD_Specs specs);
|
extern AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the main volume of a device.
|
* Sets the main volume of a device.
|
||||||
@@ -342,7 +342,7 @@ extern int AUD_setDeviceSoundVolume(AUD_Device* device,
|
|||||||
* played back currently, in that case the buffer is filled with
|
* played back currently, in that case the buffer is filled with
|
||||||
* silence.
|
* silence.
|
||||||
*/
|
*/
|
||||||
extern int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length);
|
extern int AUD_readDevice(AUD_Device* device, data_t* buffer, int length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes a read device.
|
* Closes a read device.
|
||||||
@@ -350,6 +350,16 @@ extern int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length);
|
|||||||
*/
|
*/
|
||||||
extern void AUD_closeReadDevice(AUD_Device* device);
|
extern void AUD_closeReadDevice(AUD_Device* device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a sound file into a newly created float buffer.
|
||||||
|
* The sound is therefore bandpassed, rectified and resampled.
|
||||||
|
*/
|
||||||
|
extern float* AUD_readSoundBuffer(const char* filename, float low, float high,
|
||||||
|
float attack, float release, float threshold,
|
||||||
|
int accumulate, int additive, int square,
|
||||||
|
float sthreshold, int samplerate,
|
||||||
|
int* length);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -29,20 +29,20 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IReader* reader,
|
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IReader* reader,
|
||||||
AUD_Specs specs) :
|
AUD_DeviceSpecs specs) :
|
||||||
AUD_MixerFactory(reader, specs)
|
AUD_MixerFactory(reader, specs)
|
||||||
{
|
{
|
||||||
memset(m_mapping, 0, sizeof(m_mapping));
|
memset(m_mapping, 0, sizeof(m_mapping));
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IFactory* factory,
|
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IFactory* factory,
|
||||||
AUD_Specs specs) :
|
AUD_DeviceSpecs specs) :
|
||||||
AUD_MixerFactory(factory, specs)
|
AUD_MixerFactory(factory, specs)
|
||||||
{
|
{
|
||||||
memset(m_mapping, 0, sizeof(m_mapping));
|
memset(m_mapping, 0, sizeof(m_mapping));
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_Specs specs) :
|
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_DeviceSpecs specs) :
|
||||||
AUD_MixerFactory(specs)
|
AUD_MixerFactory(specs)
|
||||||
{
|
{
|
||||||
memset(m_mapping, 0, sizeof(m_mapping));
|
memset(m_mapping, 0, sizeof(m_mapping));
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ private:
|
|||||||
float **m_mapping[9];
|
float **m_mapping[9];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AUD_ChannelMapperFactory(AUD_IReader* reader, AUD_Specs specs);
|
AUD_ChannelMapperFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
|
||||||
AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_Specs specs);
|
AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
|
||||||
AUD_ChannelMapperFactory(AUD_Specs specs);
|
AUD_ChannelMapperFactory(AUD_DeviceSpecs specs);
|
||||||
|
|
||||||
virtual ~AUD_ChannelMapperFactory();
|
virtual ~AUD_ChannelMapperFactory();
|
||||||
|
|
||||||
|
|||||||
@@ -32,12 +32,6 @@ AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
|
|||||||
{
|
{
|
||||||
m_specs = reader->getSpecs();
|
m_specs = reader->getSpecs();
|
||||||
|
|
||||||
if(m_specs.format != AUD_FORMAT_FLOAT32)
|
|
||||||
{
|
|
||||||
delete m_reader; AUD_DELETE("reader")
|
|
||||||
AUD_THROW(AUD_ERROR_READER);
|
|
||||||
}
|
|
||||||
|
|
||||||
int channels = -1;
|
int channels = -1;
|
||||||
m_rch = m_specs.channels;
|
m_rch = m_specs.channels;
|
||||||
while(mapping[++channels] != 0);
|
while(mapping[++channels] != 0);
|
||||||
@@ -55,7 +49,8 @@ AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
|
|||||||
for(i=0; i < m_rch; i++)
|
for(i=0; i < m_rch; i++)
|
||||||
sum += mapping[channels][i];
|
sum += mapping[channels][i];
|
||||||
for(i=0; i < m_rch; i++)
|
for(i=0; i < m_rch; i++)
|
||||||
m_mapping[channels][i] = sum > 0.0 ? mapping[channels][i]/sum : 0.0;
|
m_mapping[channels][i] = sum > 0.0f ?
|
||||||
|
mapping[channels][i]/sum : 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
@@ -89,9 +84,9 @@ void AUD_ChannelMapperReader::read(int & length, sample_t* & buffer)
|
|||||||
if(m_buffer->getSize() < length * 4 * channels)
|
if(m_buffer->getSize() < length * 4 * channels)
|
||||||
m_buffer->resize(length * 4 * channels);
|
m_buffer->resize(length * 4 * channels);
|
||||||
|
|
||||||
float* in = (float*)buffer;
|
sample_t* in = buffer;
|
||||||
float* out = (float*)m_buffer->getBuffer();
|
sample_t* out = m_buffer->getBuffer();
|
||||||
float sum;
|
sample_t sum;
|
||||||
|
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,14 +27,14 @@
|
|||||||
#include "AUD_ConverterReader.h"
|
#include "AUD_ConverterReader.h"
|
||||||
|
|
||||||
AUD_ConverterFactory::AUD_ConverterFactory(AUD_IReader* reader,
|
AUD_ConverterFactory::AUD_ConverterFactory(AUD_IReader* reader,
|
||||||
AUD_Specs specs) :
|
AUD_DeviceSpecs specs) :
|
||||||
AUD_MixerFactory(reader, specs) {}
|
AUD_MixerFactory(reader, specs) {}
|
||||||
|
|
||||||
AUD_ConverterFactory::AUD_ConverterFactory(AUD_IFactory* factory,
|
AUD_ConverterFactory::AUD_ConverterFactory(AUD_IFactory* factory,
|
||||||
AUD_Specs specs) :
|
AUD_DeviceSpecs specs) :
|
||||||
AUD_MixerFactory(factory, specs) {}
|
AUD_MixerFactory(factory, specs) {}
|
||||||
|
|
||||||
AUD_ConverterFactory::AUD_ConverterFactory(AUD_Specs specs) :
|
AUD_ConverterFactory::AUD_ConverterFactory(AUD_DeviceSpecs specs) :
|
||||||
AUD_MixerFactory(specs) {}
|
AUD_MixerFactory(specs) {}
|
||||||
|
|
||||||
AUD_IReader* AUD_ConverterFactory::createReader()
|
AUD_IReader* AUD_ConverterFactory::createReader()
|
||||||
@@ -43,7 +43,7 @@ AUD_IReader* AUD_ConverterFactory::createReader()
|
|||||||
|
|
||||||
if(reader != 0)
|
if(reader != 0)
|
||||||
{
|
{
|
||||||
if(reader->getSpecs().format != m_specs.format)
|
if(m_specs.format != AUD_FORMAT_FLOAT32)
|
||||||
{
|
{
|
||||||
reader = new AUD_ConverterReader(reader, m_specs);
|
reader = new AUD_ConverterReader(reader, m_specs);
|
||||||
AUD_NEW("reader")
|
AUD_NEW("reader")
|
||||||
|
|||||||
@@ -35,9 +35,9 @@
|
|||||||
class AUD_ConverterFactory : public AUD_MixerFactory
|
class AUD_ConverterFactory : public AUD_MixerFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AUD_ConverterFactory(AUD_IReader* reader, AUD_Specs specs);
|
AUD_ConverterFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
|
||||||
AUD_ConverterFactory(AUD_IFactory* factory, AUD_Specs specs);
|
AUD_ConverterFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
|
||||||
AUD_ConverterFactory(AUD_Specs specs);
|
AUD_ConverterFactory(AUD_DeviceSpecs specs);
|
||||||
|
|
||||||
virtual AUD_IReader* createReader();
|
virtual AUD_IReader* createReader();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,21 +29,21 @@
|
|||||||
#define AUD_U8_0 0x80
|
#define AUD_U8_0 0x80
|
||||||
#define AUD_S16_MAX 0x7FFF
|
#define AUD_S16_MAX 0x7FFF
|
||||||
#define AUD_S16_MIN 0x8000
|
#define AUD_S16_MIN 0x8000
|
||||||
#define AUD_S16_FLT 32768.0
|
#define AUD_S16_FLT 32768.0f
|
||||||
#define AUD_S32_MAX 0x7FFFFFFF
|
#define AUD_S32_MAX 0x7FFFFFFF
|
||||||
#define AUD_S32_MIN 0x80000000
|
#define AUD_S32_MIN 0x80000000
|
||||||
#define AUD_S32_FLT 2147483648.0
|
#define AUD_S32_FLT 2147483648.0f
|
||||||
#define AUD_FLT_MAX 1.0
|
#define AUD_FLT_MAX 1.0f
|
||||||
#define AUD_FLT_MIN -1.0
|
#define AUD_FLT_MIN -1.0f
|
||||||
|
|
||||||
void AUD_convert_u8_s16(sample_t* target, sample_t* source, int length)
|
void AUD_convert_u8_s16(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* t = (int16_t*) target;
|
int16_t* t = (int16_t*) target;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
t[i] = (((int16_t)source[i]) - AUD_U8_0) << 8;
|
t[i] = (((int16_t)source[i]) - AUD_U8_0) << 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length)
|
void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
@@ -53,7 +53,7 @@ void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length)
|
void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
@@ -63,35 +63,35 @@ void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_u8_s32(sample_t* target, sample_t* source, int length)
|
void AUD_convert_u8_s32(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int32_t* t = (int32_t*) target;
|
int32_t* t = (int32_t*) target;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
t[i] = (((int32_t)source[i]) - AUD_U8_0) << 24;
|
t[i] = (((int32_t)source[i]) - AUD_U8_0) << 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_u8_float(sample_t* target, sample_t* source, int length)
|
void AUD_convert_u8_float(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
float* t = (float*) target;
|
float* t = (float*) target;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((float)AUD_U8_0);
|
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((float)AUD_U8_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_u8_double(sample_t* target, sample_t* source, int length)
|
void AUD_convert_u8_double(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
double* t = (double*) target;
|
double* t = (double*) target;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((double)AUD_U8_0);
|
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((double)AUD_U8_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s16_u8(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s16_u8(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* s = (int16_t*) source;
|
int16_t* s = (int16_t*) source;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
target[i] = (unsigned char)((s[i] >> 8) + AUD_U8_0);
|
target[i] = (unsigned char)((s[i] >> 8) + AUD_U8_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* s = (int16_t*) source;
|
int16_t* s = (int16_t*) source;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
@@ -102,7 +102,7 @@ void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* s = (int16_t*) source;
|
int16_t* s = (int16_t*) source;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
@@ -113,7 +113,7 @@ void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s16_s32(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* s = (int16_t*) source;
|
int16_t* s = (int16_t*) source;
|
||||||
int32_t* t = (int32_t*) target;
|
int32_t* t = (int32_t*) target;
|
||||||
@@ -121,7 +121,7 @@ void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length)
|
|||||||
t[i] = ((int32_t)s[i]) << 16;
|
t[i] = ((int32_t)s[i]) << 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s16_float(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s16_float(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* s = (int16_t*) source;
|
int16_t* s = (int16_t*) source;
|
||||||
float* t = (float*) target;
|
float* t = (float*) target;
|
||||||
@@ -129,7 +129,7 @@ void AUD_convert_s16_float(sample_t* target, sample_t* source, int length)
|
|||||||
t[i] = s[i] / AUD_S16_FLT;
|
t[i] = s[i] / AUD_S16_FLT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s16_double(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s16_double(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* s = (int16_t*) source;
|
int16_t* s = (int16_t*) source;
|
||||||
double* t = (double*) target;
|
double* t = (double*) target;
|
||||||
@@ -137,52 +137,52 @@ void AUD_convert_s16_double(sample_t* target, sample_t* source, int length)
|
|||||||
t[i] = s[i] / AUD_S16_FLT;
|
t[i] = s[i] / AUD_S16_FLT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s24_u8_be(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s24_u8_be(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
target[i] = source[i*3] ^ AUD_U8_0;
|
target[i] = source[i*3] ^ AUD_U8_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s24_u8_le(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s24_u8_le(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
target[i] = source[i*3+2] ^ AUD_U8_0;
|
target[i] = source[i*3+2] ^ AUD_U8_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s24_s16_be(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s24_s16_be(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* t = (int16_t*) target;
|
int16_t* t = (int16_t*) target;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
t[i] = source[i*3] << 8 | source[i*3+1];
|
t[i] = source[i*3] << 8 | source[i*3+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s24_s16_le(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s24_s16_le(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* t = (int16_t*) target;
|
int16_t* t = (int16_t*) target;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
t[i] = source[i*3+2] << 8 | source[i*3+1];
|
t[i] = source[i*3+2] << 8 | source[i*3+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s24_s24(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s24_s24(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
memcpy(target, source, length * 3);
|
memcpy(target, source, length * 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s24_s32_be(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int32_t* t = (int32_t*) target;
|
int32_t* t = (int32_t*) target;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
|
t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s24_s32_le(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int32_t* t = (int32_t*) target;
|
int32_t* t = (int32_t*) target;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
|
t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s24_float_be(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
float* t = (float*) target;
|
float* t = (float*) target;
|
||||||
int32_t s;
|
int32_t s;
|
||||||
@@ -193,7 +193,7 @@ void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s24_float_le(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
float* t = (float*) target;
|
float* t = (float*) target;
|
||||||
int32_t s;
|
int32_t s;
|
||||||
@@ -204,7 +204,7 @@ void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s24_double_be(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
double* t = (double*) target;
|
double* t = (double*) target;
|
||||||
int32_t s;
|
int32_t s;
|
||||||
@@ -215,7 +215,7 @@ void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s24_double_le(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
double* t = (double*) target;
|
double* t = (double*) target;
|
||||||
int32_t s;
|
int32_t s;
|
||||||
@@ -226,14 +226,14 @@ void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s32_u8(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s32_u8(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* s = (int16_t*) source;
|
int16_t* s = (int16_t*) source;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
target[i] = (unsigned char)((s[i] >> 24) + AUD_U8_0);
|
target[i] = (unsigned char)((s[i] >> 24) + AUD_U8_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s32_s16(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* t = (int16_t*) target;
|
int16_t* t = (int16_t*) target;
|
||||||
int32_t* s = (int32_t*) source;
|
int32_t* s = (int32_t*) source;
|
||||||
@@ -241,7 +241,7 @@ void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length)
|
|||||||
t[i] = s[i] >> 16;
|
t[i] = s[i] >> 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int32_t* s = (int32_t*) source;
|
int32_t* s = (int32_t*) source;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
@@ -252,7 +252,7 @@ void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* s = (int16_t*) source;
|
int16_t* s = (int16_t*) source;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
@@ -263,7 +263,7 @@ void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s32_float(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s32_float(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int32_t* s = (int32_t*) source;
|
int32_t* s = (int32_t*) source;
|
||||||
float* t = (float*) target;
|
float* t = (float*) target;
|
||||||
@@ -271,7 +271,7 @@ void AUD_convert_s32_float(sample_t* target, sample_t* source, int length)
|
|||||||
t[i] = s[i] / AUD_S32_FLT;
|
t[i] = s[i] / AUD_S32_FLT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_s32_double(sample_t* target, sample_t* source, int length)
|
void AUD_convert_s32_double(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int32_t* s = (int32_t*) source;
|
int32_t* s = (int32_t*) source;
|
||||||
double* t = (double*) target;
|
double* t = (double*) target;
|
||||||
@@ -279,7 +279,7 @@ void AUD_convert_s32_double(sample_t* target, sample_t* source, int length)
|
|||||||
t[i] = s[i] / AUD_S32_FLT;
|
t[i] = s[i] / AUD_S32_FLT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_float_u8(sample_t* target, sample_t* source, int length)
|
void AUD_convert_float_u8(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
float* s = (float*) source;
|
float* s = (float*) source;
|
||||||
float t;
|
float t;
|
||||||
@@ -295,7 +295,7 @@ void AUD_convert_float_u8(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_float_s16(sample_t* target, sample_t* source, int length)
|
void AUD_convert_float_s16(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* t = (int16_t*) target;
|
int16_t* t = (int16_t*) target;
|
||||||
float* s = (float*) source;
|
float* s = (float*) source;
|
||||||
@@ -310,7 +310,7 @@ void AUD_convert_float_s16(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length)
|
void AUD_convert_float_s24_be(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int32_t t;
|
int32_t t;
|
||||||
float* s = (float*) source;
|
float* s = (float*) source;
|
||||||
@@ -328,7 +328,7 @@ void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length)
|
void AUD_convert_float_s24_le(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int32_t t;
|
int32_t t;
|
||||||
float* s = (float*) source;
|
float* s = (float*) source;
|
||||||
@@ -346,7 +346,7 @@ void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_float_s32(sample_t* target, sample_t* source, int length)
|
void AUD_convert_float_s32(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int32_t* t = (int32_t*) target;
|
int32_t* t = (int32_t*) target;
|
||||||
float* s = (float*) source;
|
float* s = (float*) source;
|
||||||
@@ -361,7 +361,7 @@ void AUD_convert_float_s32(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_float_double(sample_t* target, sample_t* source, int length)
|
void AUD_convert_float_double(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
float* s = (float*) source;
|
float* s = (float*) source;
|
||||||
double* t = (double*) target;
|
double* t = (double*) target;
|
||||||
@@ -369,7 +369,7 @@ void AUD_convert_float_double(sample_t* target, sample_t* source, int length)
|
|||||||
t[i] = s[i];
|
t[i] = s[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_double_u8(sample_t* target, sample_t* source, int length)
|
void AUD_convert_double_u8(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
double* s = (double*) source;
|
double* s = (double*) source;
|
||||||
double t;
|
double t;
|
||||||
@@ -385,7 +385,7 @@ void AUD_convert_double_u8(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_double_s16(sample_t* target, sample_t* source, int length)
|
void AUD_convert_double_s16(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int16_t* t = (int16_t*) target;
|
int16_t* t = (int16_t*) target;
|
||||||
double* s = (double*) source;
|
double* s = (double*) source;
|
||||||
@@ -400,7 +400,7 @@ void AUD_convert_double_s16(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length)
|
void AUD_convert_double_s24_be(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int32_t t;
|
int32_t t;
|
||||||
double* s = (double*) source;
|
double* s = (double*) source;
|
||||||
@@ -418,7 +418,7 @@ void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length)
|
void AUD_convert_double_s24_le(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int32_t t;
|
int32_t t;
|
||||||
double* s = (double*) source;
|
double* s = (double*) source;
|
||||||
@@ -436,7 +436,7 @@ void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_double_s32(sample_t* target, sample_t* source, int length)
|
void AUD_convert_double_s32(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
int32_t* t = (int32_t*) target;
|
int32_t* t = (int32_t*) target;
|
||||||
double* s = (double*) source;
|
double* s = (double*) source;
|
||||||
@@ -451,92 +451,10 @@ void AUD_convert_double_s32(sample_t* target, sample_t* source, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_double_float(sample_t* target, sample_t* source, int length)
|
void AUD_convert_double_float(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
double* s = (double*) source;
|
double* s = (double*) source;
|
||||||
float* t = (float*) target;
|
float* t = (float*) target;
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
t[i] = s[i];
|
t[i] = s[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_volume_adjust_u8(sample_t* target, sample_t* source,
|
|
||||||
int count, float volume)
|
|
||||||
{
|
|
||||||
for(int i=0; i<count; i++)
|
|
||||||
target[i] = (unsigned char)((source[i]-0x0080) * volume + 0x80);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
|
|
||||||
int count, float volume)
|
|
||||||
{
|
|
||||||
count *= 3;
|
|
||||||
int value;
|
|
||||||
|
|
||||||
for(int i=0; i<count; i+=3)
|
|
||||||
{
|
|
||||||
value = source[i+2] << 16 | source[i+1] << 8 | source[i];
|
|
||||||
value |= (((value & 0x800000) >> 23) * 255) << 24;
|
|
||||||
value *= volume;
|
|
||||||
target[i+2] = value >> 16;
|
|
||||||
target[i+1] = value >> 8;
|
|
||||||
target[i] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
|
|
||||||
int count, float volume)
|
|
||||||
{
|
|
||||||
count *= 3;
|
|
||||||
int value;
|
|
||||||
|
|
||||||
for(int i=0; i < count; i+=3)
|
|
||||||
{
|
|
||||||
value = source[i] << 16 | source[i+1] << 8 | source[i+2];
|
|
||||||
value |= (((value & 0x800000) >> 23) * 255) << 24;
|
|
||||||
value *= volume;
|
|
||||||
target[i] = value >> 16;
|
|
||||||
target[i+1] = value >> 8;
|
|
||||||
target[i+2] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_rectify_u8(sample_t* target, sample_t* source, int count)
|
|
||||||
{
|
|
||||||
for(int i=0; i<count; i++)
|
|
||||||
target[i] = source[i] < 0x80 ? 0x0100 - source[i] : source[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_rectify_s24_le(sample_t* target, sample_t* source, int count)
|
|
||||||
{
|
|
||||||
count *= 3;
|
|
||||||
int value;
|
|
||||||
|
|
||||||
for(int i=0; i<count; i+=3)
|
|
||||||
{
|
|
||||||
value = source[i+2] << 16 | source[i+1] << 8 | source[i];
|
|
||||||
value |= (((value & 0x800000) >> 23) * 255) << 24;
|
|
||||||
if(value < 0)
|
|
||||||
value = -value;
|
|
||||||
target[i+2] = value >> 16;
|
|
||||||
target[i+1] = value >> 8;
|
|
||||||
target[i] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_rectify_s24_be(sample_t* target, sample_t* source, int count)
|
|
||||||
{
|
|
||||||
count *= 3;
|
|
||||||
int value;
|
|
||||||
|
|
||||||
for(int i=0; i < count; i+=3)
|
|
||||||
{
|
|
||||||
value = source[i] << 16 | source[i+1] << 8 | source[i+2];
|
|
||||||
value |= (((value & 0x800000) >> 23) * 255) << 24;
|
|
||||||
if(value < 0)
|
|
||||||
value = -value;
|
|
||||||
target[i] = value >> 16;
|
|
||||||
target[i+1] = value >> 8;
|
|
||||||
target[i+2] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,133 +41,94 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void (*AUD_convert_f)(sample_t* target, sample_t* source, int length);
|
typedef void (*AUD_convert_f)(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
typedef void (*AUD_volume_adjust_f)(sample_t* target, sample_t* source,
|
|
||||||
int count, float volume);
|
|
||||||
|
|
||||||
typedef void (*AUD_rectify_f)(sample_t* target, sample_t* source, int count);
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void AUD_convert_copy(sample_t* target, sample_t* source, int length)
|
void AUD_convert_copy(data_t* target, data_t* source, int length)
|
||||||
{
|
{
|
||||||
memcpy(target, source, length*sizeof(T));
|
memcpy(target, source, length*sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_convert_u8_s16(sample_t* target, sample_t* source, int length);
|
void AUD_convert_u8_s16(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length);
|
void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length);
|
void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_u8_s32(sample_t* target, sample_t* source, int length);
|
void AUD_convert_u8_s32(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_u8_float(sample_t* target, sample_t* source, int length);
|
void AUD_convert_u8_float(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_u8_double(sample_t* target, sample_t* source, int length);
|
void AUD_convert_u8_double(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s16_u8(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s16_u8(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s16_s32(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s16_float(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s16_float(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s16_double(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s16_double(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s24_u8_be(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s24_u8_be(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s24_u8_le(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s24_u8_le(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s24_s16_be(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s24_s16_be(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s24_s16_le(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s24_s16_le(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s24_s24(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s24_s24(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s24_s32_be(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s24_s32_le(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s24_float_be(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s24_float_le(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s24_double_be(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s24_double_le(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s32_u8(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s32_u8(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s32_s16(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s32_float(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s32_float(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_s32_double(sample_t* target, sample_t* source, int length);
|
void AUD_convert_s32_double(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_float_u8(sample_t* target, sample_t* source, int length);
|
void AUD_convert_float_u8(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_float_s16(sample_t* target, sample_t* source, int length);
|
void AUD_convert_float_s16(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length);
|
void AUD_convert_float_s24_be(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length);
|
void AUD_convert_float_s24_le(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_float_s32(sample_t* target, sample_t* source, int length);
|
void AUD_convert_float_s32(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_float_double(sample_t* target, sample_t* source, int length);
|
void AUD_convert_float_double(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_double_u8(sample_t* target, sample_t* source, int length);
|
void AUD_convert_double_u8(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_double_s16(sample_t* target, sample_t* source, int length);
|
void AUD_convert_double_s16(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length);
|
void AUD_convert_double_s24_be(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length);
|
void AUD_convert_double_s24_le(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_double_s32(sample_t* target, sample_t* source, int length);
|
void AUD_convert_double_s32(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
void AUD_convert_double_float(sample_t* target, sample_t* source, int length);
|
void AUD_convert_double_float(data_t* target, data_t* source, int length);
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void AUD_volume_adjust(sample_t* target, sample_t* source,
|
|
||||||
int count, float volume)
|
|
||||||
{
|
|
||||||
T* t = (T*)target;
|
|
||||||
T* s = (T*)source;
|
|
||||||
for(int i=0; i < count; i++)
|
|
||||||
t[i] = (T)(s[i] * volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_volume_adjust_u8(sample_t* target, sample_t* source,
|
|
||||||
int count, float volume);
|
|
||||||
|
|
||||||
void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
|
|
||||||
int count, float volume);
|
|
||||||
|
|
||||||
void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
|
|
||||||
int count, float volume);
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void AUD_rectify(sample_t* target, sample_t* source, int count)
|
|
||||||
{
|
|
||||||
T* t = (T*)target;
|
|
||||||
T* s = (T*)source;
|
|
||||||
for(int i=0; i < count; i++)
|
|
||||||
t[i] = s[i] < 0 ? -s[i] : s[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_rectify_u8(sample_t* target, sample_t* source, int count);
|
|
||||||
|
|
||||||
void AUD_rectify_s24_le(sample_t* target, sample_t* source, int count);
|
|
||||||
|
|
||||||
void AUD_rectify_s24_be(sample_t* target, sample_t* source, int count);
|
|
||||||
|
|
||||||
#endif //AUD_CONVERTERFUNCTIONS
|
#endif //AUD_CONVERTERFUNCTIONS
|
||||||
|
|||||||
@@ -26,205 +26,37 @@
|
|||||||
#include "AUD_ConverterReader.h"
|
#include "AUD_ConverterReader.h"
|
||||||
#include "AUD_Buffer.h"
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader, AUD_Specs specs) :
|
AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader,
|
||||||
|
AUD_DeviceSpecs specs) :
|
||||||
AUD_EffectReader(reader)
|
AUD_EffectReader(reader)
|
||||||
{
|
{
|
||||||
m_specs = reader->getSpecs();
|
m_specs.specs = reader->getSpecs();
|
||||||
|
|
||||||
int bigendian = 1;
|
int bigendian = 1;
|
||||||
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
|
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
|
||||||
|
|
||||||
switch(m_specs.format)
|
switch(specs.format)
|
||||||
{
|
{
|
||||||
case AUD_FORMAT_U8:
|
case AUD_FORMAT_U8:
|
||||||
switch(specs.format)
|
m_convert = AUD_convert_float_u8;
|
||||||
{
|
|
||||||
case AUD_FORMAT_U8:
|
|
||||||
m_convert = AUD_convert_copy<unsigned char>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
m_convert = AUD_convert_u8_s16;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S24:
|
|
||||||
if(bigendian)
|
|
||||||
m_convert = AUD_convert_u8_s24_be;
|
|
||||||
else
|
|
||||||
m_convert = AUD_convert_u8_s24_le;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S32:
|
|
||||||
m_convert = AUD_convert_u8_s32;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT32:
|
|
||||||
m_convert = AUD_convert_u8_float;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT64:
|
|
||||||
m_convert = AUD_convert_u8_double;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case AUD_FORMAT_S16:
|
case AUD_FORMAT_S16:
|
||||||
switch(specs.format)
|
m_convert = AUD_convert_float_s16;
|
||||||
{
|
|
||||||
case AUD_FORMAT_U8:
|
|
||||||
m_convert = AUD_convert_s16_u8;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
m_convert = AUD_convert_copy<int16_t>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S24:
|
|
||||||
if(bigendian)
|
|
||||||
m_convert = AUD_convert_s16_s24_be;
|
|
||||||
else
|
|
||||||
m_convert = AUD_convert_s16_s24_le;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S32:
|
|
||||||
m_convert = AUD_convert_s16_s32;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT32:
|
|
||||||
m_convert = AUD_convert_s16_float;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT64:
|
|
||||||
m_convert = AUD_convert_s16_double;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case AUD_FORMAT_S24:
|
case AUD_FORMAT_S24:
|
||||||
if(bigendian)
|
if(bigendian)
|
||||||
switch(specs.format)
|
m_convert = AUD_convert_float_s24_be;
|
||||||
{
|
|
||||||
case AUD_FORMAT_U8:
|
|
||||||
m_convert = AUD_convert_u8_s24_be;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
m_convert = AUD_convert_s16_s24_be;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S24:
|
|
||||||
m_convert = AUD_convert_s24_s24;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S32:
|
|
||||||
m_convert = AUD_convert_s32_s24_be;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT32:
|
|
||||||
m_convert = AUD_convert_float_s24_be;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT64:
|
|
||||||
m_convert = AUD_convert_double_s24_be;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
switch(specs.format)
|
m_convert = AUD_convert_float_s24_le;
|
||||||
{
|
|
||||||
case AUD_FORMAT_U8:
|
|
||||||
m_convert = AUD_convert_u8_s24_le;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
m_convert = AUD_convert_s16_s24_le;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S24:
|
|
||||||
m_convert = AUD_convert_s24_s24;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S32:
|
|
||||||
m_convert = AUD_convert_s32_s24_le;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT32:
|
|
||||||
m_convert = AUD_convert_float_s24_le;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT64:
|
|
||||||
m_convert = AUD_convert_double_s24_le;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case AUD_FORMAT_S32:
|
case AUD_FORMAT_S32:
|
||||||
switch(specs.format)
|
m_convert = AUD_convert_float_s32;
|
||||||
{
|
|
||||||
case AUD_FORMAT_U8:
|
|
||||||
m_convert = AUD_convert_s32_u8;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
m_convert = AUD_convert_s32_s16;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S24:
|
|
||||||
if(bigendian)
|
|
||||||
m_convert = AUD_convert_s32_s24_be;
|
|
||||||
else
|
|
||||||
m_convert = AUD_convert_s32_s24_le;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S32:
|
|
||||||
m_convert = AUD_convert_copy<int32_t>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT32:
|
|
||||||
m_convert = AUD_convert_s32_float;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT64:
|
|
||||||
m_convert = AUD_convert_s32_double;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case AUD_FORMAT_FLOAT32:
|
case AUD_FORMAT_FLOAT32:
|
||||||
switch(specs.format)
|
m_convert = AUD_convert_copy<float>;
|
||||||
{
|
|
||||||
case AUD_FORMAT_U8:
|
|
||||||
m_convert = AUD_convert_float_u8;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
m_convert = AUD_convert_float_s16;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S24:
|
|
||||||
if(bigendian)
|
|
||||||
m_convert = AUD_convert_float_s24_be;
|
|
||||||
else
|
|
||||||
m_convert = AUD_convert_float_s24_le;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S32:
|
|
||||||
m_convert = AUD_convert_float_s32;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT32:
|
|
||||||
m_convert = AUD_convert_copy<float>;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT64:
|
|
||||||
m_convert = AUD_convert_float_double;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case AUD_FORMAT_FLOAT64:
|
case AUD_FORMAT_FLOAT64:
|
||||||
switch(specs.format)
|
m_convert = AUD_convert_float_double;
|
||||||
{
|
|
||||||
case AUD_FORMAT_U8:
|
|
||||||
m_convert = AUD_convert_double_u8;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
m_convert = AUD_convert_double_s16;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S24:
|
|
||||||
if(bigendian)
|
|
||||||
m_convert = AUD_convert_double_s24_be;
|
|
||||||
else
|
|
||||||
m_convert = AUD_convert_double_s24_le;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S32:
|
|
||||||
m_convert = AUD_convert_double_s32;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT32:
|
|
||||||
m_convert = AUD_convert_double_float;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT64:
|
|
||||||
m_convert = AUD_convert_copy<double>;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -242,7 +74,7 @@ AUD_ConverterReader::~AUD_ConverterReader()
|
|||||||
|
|
||||||
AUD_Specs AUD_ConverterReader::getSpecs()
|
AUD_Specs AUD_ConverterReader::getSpecs()
|
||||||
{
|
{
|
||||||
return m_specs;
|
return m_specs.specs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_ConverterReader::read(int & length, sample_t* & buffer)
|
void AUD_ConverterReader::read(int & length, sample_t* & buffer)
|
||||||
@@ -254,7 +86,8 @@ void AUD_ConverterReader::read(int & length, sample_t* & buffer)
|
|||||||
if(m_buffer->getSize() < length*samplesize)
|
if(m_buffer->getSize() < length*samplesize)
|
||||||
m_buffer->resize(length*samplesize);
|
m_buffer->resize(length*samplesize);
|
||||||
|
|
||||||
m_convert(m_buffer->getBuffer(), buffer, length*m_specs.channels);
|
m_convert((data_t*)m_buffer->getBuffer(), (data_t*)buffer,
|
||||||
|
length * m_specs.channels);
|
||||||
|
|
||||||
buffer = m_buffer->getBuffer();
|
buffer = m_buffer->getBuffer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* The target specification.
|
* The target specification.
|
||||||
*/
|
*/
|
||||||
AUD_Specs m_specs;
|
AUD_DeviceSpecs m_specs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converter function.
|
* Converter function.
|
||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
* \param specs The target specification.
|
* \param specs The target specification.
|
||||||
* \exception AUD_Exception Thrown if the reader is NULL.
|
* \exception AUD_Exception Thrown if the reader is NULL.
|
||||||
*/
|
*/
|
||||||
AUD_ConverterReader(AUD_IReader* reader, AUD_Specs specs);
|
AUD_ConverterReader(AUD_IReader* reader, AUD_DeviceSpecs specs);
|
||||||
/**
|
/**
|
||||||
* Destroys the reader.
|
* Destroys the reader.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,100 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
|
||||||
*
|
|
||||||
* Copyright 2009 Jörg Hermann Müller
|
|
||||||
*
|
|
||||||
* This file is part of AudaSpace.
|
|
||||||
*
|
|
||||||
* AudaSpace 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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* ***** END LGPL LICENSE BLOCK *****
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef AUD_FLOATMIXER
|
|
||||||
#define AUD_FLOATMIXER
|
|
||||||
|
|
||||||
#include "AUD_IMixer.h"
|
|
||||||
#include "AUD_ConverterFunctions.h"
|
|
||||||
class AUD_ConverterFactory;
|
|
||||||
class AUD_SRCResampleFactory;
|
|
||||||
class AUD_ChannelMapperFactory;
|
|
||||||
class AUD_Buffer;
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
struct AUD_FloatMixerBuffer
|
|
||||||
{
|
|
||||||
sample_t* buffer;
|
|
||||||
int length;
|
|
||||||
float volume;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is able to mix two audiosignals with floats.
|
|
||||||
*/
|
|
||||||
class AUD_FloatMixer : public AUD_IMixer
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* The converter factory that converts all readers for superposition.
|
|
||||||
*/
|
|
||||||
AUD_ConverterFactory* m_converter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The resampling factory that resamples all readers for superposition.
|
|
||||||
*/
|
|
||||||
AUD_SRCResampleFactory* m_resampler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The channel mapper factory that maps all readers for superposition.
|
|
||||||
*/
|
|
||||||
AUD_ChannelMapperFactory* m_mapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The list of buffers to superpose.
|
|
||||||
*/
|
|
||||||
std::list<AUD_FloatMixerBuffer> m_buffers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The output specification.
|
|
||||||
*/
|
|
||||||
AUD_Specs m_specs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The temporary mixing buffer.
|
|
||||||
*/
|
|
||||||
AUD_Buffer* m_buffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converter function.
|
|
||||||
*/
|
|
||||||
AUD_convert_f m_convert;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Creates the mixer.
|
|
||||||
*/
|
|
||||||
AUD_FloatMixer();
|
|
||||||
|
|
||||||
virtual ~AUD_FloatMixer();
|
|
||||||
|
|
||||||
virtual AUD_IReader* prepare(AUD_IReader* reader);
|
|
||||||
virtual void setSpecs(AUD_Specs specs);
|
|
||||||
virtual void add(sample_t* buffer, AUD_Specs specs, int length,
|
|
||||||
float volume);
|
|
||||||
virtual void superpose(sample_t* buffer, int length, float volume);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //AUD_FLOATMIXER
|
|
||||||
@@ -53,7 +53,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Returns the specification of the device.
|
* Returns the specification of the device.
|
||||||
*/
|
*/
|
||||||
virtual AUD_Specs getSpecs()=0;
|
virtual AUD_DeviceSpecs getSpecs()=0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plays a sound source.
|
* Plays a sound source.
|
||||||
|
|||||||
@@ -23,42 +23,30 @@
|
|||||||
* ***** END LGPL LICENSE BLOCK *****
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AUD_SDLMixerFactory.h"
|
#include "AUD_LinearResampleFactory.h"
|
||||||
#include "AUD_SDLMixerReader.h"
|
#include "AUD_LinearResampleReader.h"
|
||||||
|
|
||||||
#include <cstring>
|
AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_IReader* reader,
|
||||||
|
AUD_DeviceSpecs specs) :
|
||||||
|
AUD_ResampleFactory(reader, specs) {}
|
||||||
|
|
||||||
AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs) :
|
AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_IFactory* factory,
|
||||||
AUD_MixerFactory(reader, specs) {}
|
AUD_DeviceSpecs specs) :
|
||||||
|
AUD_ResampleFactory(factory, specs) {}
|
||||||
|
|
||||||
AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs) :
|
AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_DeviceSpecs specs) :
|
||||||
AUD_MixerFactory(factory, specs) {}
|
AUD_ResampleFactory(specs) {}
|
||||||
|
|
||||||
AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_Specs specs) :
|
AUD_IReader* AUD_LinearResampleFactory::createReader()
|
||||||
AUD_MixerFactory(specs) {}
|
|
||||||
|
|
||||||
AUD_IReader* AUD_SDLMixerFactory::createReader()
|
|
||||||
{
|
{
|
||||||
AUD_IReader* reader = getReader();
|
AUD_IReader* reader = getReader();
|
||||||
|
|
||||||
if(reader != 0)
|
if(reader != 0)
|
||||||
{
|
{
|
||||||
AUD_Specs specs = reader->getSpecs();
|
if(reader->getSpecs().rate != m_specs.rate)
|
||||||
if(memcmp(&m_specs, &specs, sizeof(AUD_Specs)) != 0)
|
|
||||||
{
|
{
|
||||||
try
|
reader = new AUD_LinearResampleReader(reader, m_specs.specs);
|
||||||
{
|
AUD_NEW("reader")
|
||||||
reader = new AUD_SDLMixerReader(reader, m_specs);
|
|
||||||
AUD_NEW("reader")
|
|
||||||
}
|
|
||||||
catch(AUD_Exception e)
|
|
||||||
{
|
|
||||||
// return 0 in case SDL cannot mix the source
|
|
||||||
if(e.error != AUD_ERROR_SDL)
|
|
||||||
throw;
|
|
||||||
else
|
|
||||||
reader = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return reader;
|
return reader;
|
||||||
44
intern/audaspace/intern/AUD_LinearResampleFactory.h
Normal file
44
intern/audaspace/intern/AUD_LinearResampleFactory.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_LINEARRESAMPLEFACTORY
|
||||||
|
#define AUD_LINEARRESAMPLEFACTORY
|
||||||
|
|
||||||
|
#include "AUD_ResampleFactory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This factory creates a resampling reader that does simple linear resampling.
|
||||||
|
*/
|
||||||
|
class AUD_LinearResampleFactory : public AUD_ResampleFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AUD_LinearResampleFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
|
||||||
|
AUD_LinearResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
|
||||||
|
AUD_LinearResampleFactory(AUD_DeviceSpecs specs);
|
||||||
|
|
||||||
|
virtual AUD_IReader* createReader();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_LINEARRESAMPLEFACTORY
|
||||||
133
intern/audaspace/intern/AUD_LinearResampleReader.cpp
Normal file
133
intern/audaspace/intern/AUD_LinearResampleReader.cpp
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_LinearResampleReader.h"
|
||||||
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#define CC channels + channel
|
||||||
|
|
||||||
|
AUD_LinearResampleReader::AUD_LinearResampleReader(AUD_IReader* reader,
|
||||||
|
AUD_Specs specs) :
|
||||||
|
AUD_EffectReader(reader)
|
||||||
|
{
|
||||||
|
m_sspecs = reader->getSpecs();
|
||||||
|
|
||||||
|
m_tspecs = specs;
|
||||||
|
m_tspecs.channels = m_sspecs.channels;
|
||||||
|
m_factor = (float)m_tspecs.rate / (float)m_sspecs.rate;
|
||||||
|
|
||||||
|
m_position = 0;
|
||||||
|
m_sposition = 0;
|
||||||
|
|
||||||
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
m_cache = new AUD_Buffer(2 * AUD_SAMPLE_SIZE(specs)); AUD_NEW("buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_LinearResampleReader::~AUD_LinearResampleReader()
|
||||||
|
{
|
||||||
|
delete m_buffer; AUD_DELETE("buffer")
|
||||||
|
delete m_cache; AUD_DELETE("buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_LinearResampleReader::seek(int position)
|
||||||
|
{
|
||||||
|
m_position = position;
|
||||||
|
m_sposition = floor(position / m_factor);
|
||||||
|
m_reader->seek(m_sposition);
|
||||||
|
}
|
||||||
|
|
||||||
|
int AUD_LinearResampleReader::getLength()
|
||||||
|
{
|
||||||
|
return m_reader->getLength() * m_factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AUD_LinearResampleReader::getPosition()
|
||||||
|
{
|
||||||
|
return m_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_Specs AUD_LinearResampleReader::getSpecs()
|
||||||
|
{
|
||||||
|
return m_tspecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_LinearResampleReader::read(int & length, sample_t* & buffer)
|
||||||
|
{
|
||||||
|
int samplesize = AUD_SAMPLE_SIZE(m_tspecs);
|
||||||
|
int size = length * samplesize;
|
||||||
|
|
||||||
|
if(m_buffer->getSize() < size)
|
||||||
|
m_buffer->resize(size);
|
||||||
|
|
||||||
|
int need = ceil((m_position + length) / m_factor) + 1 - m_sposition;
|
||||||
|
int len = need;
|
||||||
|
sample_t* buf;
|
||||||
|
buffer = m_buffer->getBuffer();
|
||||||
|
|
||||||
|
m_reader->read(len, buf);
|
||||||
|
|
||||||
|
if(len < need)
|
||||||
|
length = floor((m_sposition + len - 1) * m_factor) - m_position;
|
||||||
|
|
||||||
|
float spos;
|
||||||
|
sample_t low, high;
|
||||||
|
int channels = m_sspecs.channels;
|
||||||
|
|
||||||
|
for(int channel = 0; channel < channels; channel++)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
spos = (m_position + i) / m_factor - m_sposition;
|
||||||
|
|
||||||
|
if(floor(spos) < 0)
|
||||||
|
{
|
||||||
|
low = m_cache->getBuffer()[(int)(floor(spos) + 2) * CC];
|
||||||
|
if(ceil(spos) < 0)
|
||||||
|
high = m_cache->getBuffer()[(int)(ceil(spos) + 2) * CC];
|
||||||
|
else
|
||||||
|
high = buf[(int)ceil(spos) * CC];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
low = buf[(int)floor(spos) * CC];
|
||||||
|
high = buf[(int)ceil(spos) * CC];
|
||||||
|
}
|
||||||
|
buffer[i * CC] = low + (spos - floor(spos)) * (high - low);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(len > 1)
|
||||||
|
memcpy(m_cache->getBuffer(),
|
||||||
|
buf + (len - 2) * channels,
|
||||||
|
2 * samplesize);
|
||||||
|
else if(len == 1)
|
||||||
|
memcpy(m_cache->getBuffer() + 1 * channels, buf, samplesize);
|
||||||
|
|
||||||
|
m_sposition += len;
|
||||||
|
m_position += length;
|
||||||
|
}
|
||||||
94
intern/audaspace/intern/AUD_LinearResampleReader.h
Normal file
94
intern/audaspace/intern/AUD_LinearResampleReader.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_LINEARRESAMPLEREADER
|
||||||
|
#define AUD_LINEARRESAMPLEREADER
|
||||||
|
|
||||||
|
#include "AUD_EffectReader.h"
|
||||||
|
class AUD_Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This resampling reader uses libsamplerate for resampling.
|
||||||
|
*/
|
||||||
|
class AUD_LinearResampleReader : public AUD_EffectReader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The resampling factor.
|
||||||
|
*/
|
||||||
|
float m_factor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current position.
|
||||||
|
*/
|
||||||
|
int m_position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current reading source position.
|
||||||
|
*/
|
||||||
|
int m_sposition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sound output buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The input caching buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The target specification.
|
||||||
|
*/
|
||||||
|
AUD_Specs m_tspecs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sample specification of the source.
|
||||||
|
*/
|
||||||
|
AUD_Specs m_sspecs;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a resampling reader.
|
||||||
|
* \param reader The reader to mix.
|
||||||
|
* \param specs The target specification.
|
||||||
|
* \exception AUD_Exception Thrown if the reader is NULL.
|
||||||
|
*/
|
||||||
|
AUD_LinearResampleReader(AUD_IReader* reader, AUD_Specs specs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the reader.
|
||||||
|
*/
|
||||||
|
~AUD_LinearResampleReader();
|
||||||
|
|
||||||
|
virtual void seek(int position);
|
||||||
|
virtual int getLength();
|
||||||
|
virtual int getPosition();
|
||||||
|
virtual AUD_Specs getSpecs();
|
||||||
|
virtual void read(int & length, sample_t* & buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_LINEARRESAMPLEREADER
|
||||||
@@ -23,8 +23,7 @@
|
|||||||
* ***** END LGPL LICENSE BLOCK *****
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AUD_FloatMixer.h"
|
#include "AUD_Mixer.h"
|
||||||
#include "AUD_ConverterFactory.h"
|
|
||||||
#include "AUD_SRCResampleFactory.h"
|
#include "AUD_SRCResampleFactory.h"
|
||||||
#include "AUD_ChannelMapperFactory.h"
|
#include "AUD_ChannelMapperFactory.h"
|
||||||
#include "AUD_IReader.h"
|
#include "AUD_IReader.h"
|
||||||
@@ -32,23 +31,19 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
AUD_FloatMixer::AUD_FloatMixer()
|
AUD_Mixer::AUD_Mixer()
|
||||||
{
|
{
|
||||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
|
||||||
m_converter = NULL;
|
|
||||||
m_resampler = NULL;
|
m_resampler = NULL;
|
||||||
m_mapper = NULL;
|
m_mapper = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_FloatMixer::~AUD_FloatMixer()
|
AUD_Mixer::~AUD_Mixer()
|
||||||
{
|
{
|
||||||
delete m_buffer; AUD_DELETE("buffer")
|
delete m_buffer; AUD_DELETE("buffer")
|
||||||
|
|
||||||
if(m_converter)
|
|
||||||
{
|
|
||||||
delete m_converter; AUD_DELETE("factory")
|
|
||||||
}
|
|
||||||
if(m_resampler)
|
if(m_resampler)
|
||||||
{
|
{
|
||||||
delete m_resampler; AUD_DELETE("factory")
|
delete m_resampler; AUD_DELETE("factory")
|
||||||
@@ -59,11 +54,8 @@ AUD_FloatMixer::~AUD_FloatMixer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_IReader* AUD_FloatMixer::prepare(AUD_IReader* reader)
|
AUD_IReader* AUD_Mixer::prepare(AUD_IReader* reader)
|
||||||
{
|
{
|
||||||
m_converter->setReader(reader);
|
|
||||||
reader = m_converter->createReader();
|
|
||||||
|
|
||||||
m_resampler->setReader(reader);
|
m_resampler->setReader(reader);
|
||||||
reader = m_resampler->createReader();
|
reader = m_resampler->createReader();
|
||||||
|
|
||||||
@@ -76,14 +68,10 @@ AUD_IReader* AUD_FloatMixer::prepare(AUD_IReader* reader)
|
|||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_FloatMixer::setSpecs(AUD_Specs specs)
|
void AUD_Mixer::setSpecs(AUD_DeviceSpecs specs)
|
||||||
{
|
{
|
||||||
m_specs = specs;
|
m_specs = specs;
|
||||||
|
|
||||||
if(m_converter)
|
|
||||||
{
|
|
||||||
delete m_converter; AUD_DELETE("factory")
|
|
||||||
}
|
|
||||||
if(m_resampler)
|
if(m_resampler)
|
||||||
{
|
{
|
||||||
delete m_resampler; AUD_DELETE("factory")
|
delete m_resampler; AUD_DELETE("factory")
|
||||||
@@ -93,9 +81,6 @@ void AUD_FloatMixer::setSpecs(AUD_Specs specs)
|
|||||||
delete m_mapper; AUD_DELETE("factory")
|
delete m_mapper; AUD_DELETE("factory")
|
||||||
}
|
}
|
||||||
|
|
||||||
specs.format = AUD_FORMAT_FLOAT32;
|
|
||||||
|
|
||||||
m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
|
|
||||||
m_resampler = new AUD_SRCResampleFactory(specs); AUD_NEW("factory")
|
m_resampler = new AUD_SRCResampleFactory(specs); AUD_NEW("factory")
|
||||||
m_mapper = new AUD_ChannelMapperFactory(specs); AUD_NEW("factory")
|
m_mapper = new AUD_ChannelMapperFactory(specs); AUD_NEW("factory")
|
||||||
|
|
||||||
@@ -130,27 +115,26 @@ void AUD_FloatMixer::setSpecs(AUD_Specs specs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_FloatMixer::add(sample_t* buffer, AUD_Specs specs, int length,
|
void AUD_Mixer::add(sample_t* buffer, int length, float volume)
|
||||||
float volume)
|
|
||||||
{
|
{
|
||||||
AUD_FloatMixerBuffer buf;
|
AUD_MixerBuffer buf;
|
||||||
buf.buffer = buffer;
|
buf.buffer = buffer;
|
||||||
buf.length = length;
|
buf.length = length;
|
||||||
buf.volume = volume;
|
buf.volume = volume;
|
||||||
m_buffers.push_back(buf);
|
m_buffers.push_back(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_FloatMixer::superpose(sample_t* buffer, int length, float volume)
|
void AUD_Mixer::superpose(data_t* buffer, int length, float volume)
|
||||||
{
|
{
|
||||||
AUD_FloatMixerBuffer buf;
|
AUD_MixerBuffer buf;
|
||||||
|
|
||||||
int channels = m_specs.channels;
|
int channels = m_specs.channels;
|
||||||
|
|
||||||
if(m_buffer->getSize() < length * channels * 4)
|
if(m_buffer->getSize() < length * channels * 4)
|
||||||
m_buffer->resize(length * channels * 4);
|
m_buffer->resize(length * channels * 4);
|
||||||
|
|
||||||
float* out = (float*)m_buffer->getBuffer();
|
sample_t* out = m_buffer->getBuffer();
|
||||||
float* in;
|
sample_t* in;
|
||||||
|
|
||||||
memset(out, 0, length * channels * 4);
|
memset(out, 0, length * channels * 4);
|
||||||
|
|
||||||
@@ -162,11 +146,11 @@ void AUD_FloatMixer::superpose(sample_t* buffer, int length, float volume)
|
|||||||
m_buffers.pop_front();
|
m_buffers.pop_front();
|
||||||
|
|
||||||
end = buf.length*channels;
|
end = buf.length*channels;
|
||||||
in = (float*) buf.buffer;
|
in = buf.buffer;
|
||||||
|
|
||||||
for(int i = 0; i < end; i++)
|
for(int i = 0; i < end; i++)
|
||||||
out[i] += in[i]*buf.volume * volume;
|
out[i] += in[i]*buf.volume * volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_convert(buffer, (sample_t*) out, length * channels);
|
m_convert(buffer, (data_t*) out, length * channels);
|
||||||
}
|
}
|
||||||
@@ -23,47 +23,95 @@
|
|||||||
* ***** END LGPL LICENSE BLOCK *****
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef AUD_IMIXER
|
#ifndef AUD_MIXER
|
||||||
#define AUD_IMIXER
|
#define AUD_MIXER
|
||||||
|
|
||||||
#include "AUD_Space.h"
|
#include "AUD_ConverterFunctions.h"
|
||||||
|
class AUD_ConverterFactory;
|
||||||
|
class AUD_SRCResampleFactory;
|
||||||
|
class AUD_ChannelMapperFactory;
|
||||||
|
class AUD_Buffer;
|
||||||
class AUD_IReader;
|
class AUD_IReader;
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
struct AUD_MixerBuffer
|
||||||
|
{
|
||||||
|
sample_t* buffer;
|
||||||
|
int length;
|
||||||
|
float volume;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is able to mix audiosignals of different format and channel count.
|
* This class is able to mix audiosignals of different channel count and sample
|
||||||
* \note This class doesn't do resampling!
|
* rate and convert it to a specific output format.
|
||||||
|
* It uses a default ChannelMapperFactory and a SRCResampleFactory for
|
||||||
|
* the perparation.
|
||||||
*/
|
*/
|
||||||
class AUD_IMixer
|
class AUD_Mixer
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The resampling factory that resamples all readers for superposition.
|
||||||
|
*/
|
||||||
|
AUD_SRCResampleFactory* m_resampler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel mapper factory that maps all readers for superposition.
|
||||||
|
*/
|
||||||
|
AUD_ChannelMapperFactory* m_mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of buffers to superpose.
|
||||||
|
*/
|
||||||
|
std::list<AUD_MixerBuffer> m_buffers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The output specification.
|
||||||
|
*/
|
||||||
|
AUD_DeviceSpecs m_specs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The temporary mixing buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer* m_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converter function.
|
||||||
|
*/
|
||||||
|
AUD_convert_f m_convert;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Creates the mixer.
|
||||||
|
*/
|
||||||
|
AUD_Mixer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys the mixer.
|
* Destroys the mixer.
|
||||||
*/
|
*/
|
||||||
virtual ~AUD_IMixer(){}
|
~AUD_Mixer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This funuction prepares a reader for playback.
|
* This funuction prepares a reader for playback.
|
||||||
* \param reader The reader to prepare.
|
* \param reader The reader to prepare.
|
||||||
* \return The reader that should be used for playback.
|
* \return The reader that should be used for playback.
|
||||||
*/
|
*/
|
||||||
virtual AUD_IReader* prepare(AUD_IReader* reader)=0;
|
AUD_IReader* prepare(AUD_IReader* reader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the target specification for superposing.
|
* Sets the target specification for superposing.
|
||||||
* \param specs The target specification.
|
* \param specs The target specification.
|
||||||
*/
|
*/
|
||||||
virtual void setSpecs(AUD_Specs specs)=0;
|
void setSpecs(AUD_DeviceSpecs specs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a buffer for superposition.
|
* Adds a buffer for superposition.
|
||||||
* \param buffer The buffer to superpose.
|
* \param buffer The buffer to superpose.
|
||||||
* \param specs The specification of the buffer.
|
|
||||||
* \param start The start sample of the buffer.
|
* \param start The start sample of the buffer.
|
||||||
* \param length The length of the buffer in samples.
|
* \param length The length of the buffer in samples.
|
||||||
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
|
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
|
||||||
*/
|
*/
|
||||||
virtual void add(sample_t* buffer, AUD_Specs specs, int length,
|
void add(sample_t* buffer, int length, float volume);
|
||||||
float volume)=0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Superposes all added buffers into an output buffer.
|
* Superposes all added buffers into an output buffer.
|
||||||
@@ -71,7 +119,7 @@ public:
|
|||||||
* \param length The length of the buffer in samples.
|
* \param length The length of the buffer in samples.
|
||||||
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
|
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
|
||||||
*/
|
*/
|
||||||
virtual void superpose(sample_t* buffer, int length, float volume)=0;
|
void superpose(data_t* buffer, int length, float volume);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //AUD_IMIXER
|
#endif //AUD_MIXER
|
||||||
@@ -49,7 +49,7 @@ AUD_IReader* AUD_MixerFactory::getReader()
|
|||||||
}
|
}
|
||||||
|
|
||||||
AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
|
AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
|
||||||
AUD_Specs specs)
|
AUD_DeviceSpecs specs)
|
||||||
{
|
{
|
||||||
m_specs = specs;
|
m_specs = specs;
|
||||||
m_reader = reader;
|
m_reader = reader;
|
||||||
@@ -57,14 +57,14 @@ AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
|
|||||||
}
|
}
|
||||||
|
|
||||||
AUD_MixerFactory::AUD_MixerFactory(AUD_IFactory* factory,
|
AUD_MixerFactory::AUD_MixerFactory(AUD_IFactory* factory,
|
||||||
AUD_Specs specs)
|
AUD_DeviceSpecs specs)
|
||||||
{
|
{
|
||||||
m_specs = specs;
|
m_specs = specs;
|
||||||
m_reader = 0;
|
m_reader = 0;
|
||||||
m_factory = factory;
|
m_factory = factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_MixerFactory::AUD_MixerFactory(AUD_Specs specs)
|
AUD_MixerFactory::AUD_MixerFactory(AUD_DeviceSpecs specs)
|
||||||
{
|
{
|
||||||
m_specs = specs;
|
m_specs = specs;
|
||||||
m_reader = 0;
|
m_reader = 0;
|
||||||
@@ -79,12 +79,12 @@ AUD_MixerFactory::~AUD_MixerFactory()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_Specs AUD_MixerFactory::getSpecs()
|
AUD_DeviceSpecs AUD_MixerFactory::getSpecs()
|
||||||
{
|
{
|
||||||
return m_specs;
|
return m_specs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_MixerFactory::setSpecs(AUD_Specs specs)
|
void AUD_MixerFactory::setSpecs(AUD_DeviceSpecs specs)
|
||||||
{
|
{
|
||||||
m_specs = specs;
|
m_specs = specs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ protected:
|
|||||||
/**
|
/**
|
||||||
* The target specification for resampling.
|
* The target specification for resampling.
|
||||||
*/
|
*/
|
||||||
AUD_Specs m_specs;
|
AUD_DeviceSpecs m_specs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the reader created out of the factory or taken from m_reader.
|
* Returns the reader created out of the factory or taken from m_reader.
|
||||||
@@ -63,20 +63,20 @@ public:
|
|||||||
* \param reader The reader to mix.
|
* \param reader The reader to mix.
|
||||||
* \param specs The target specification.
|
* \param specs The target specification.
|
||||||
*/
|
*/
|
||||||
AUD_MixerFactory(AUD_IReader* reader, AUD_Specs specs);
|
AUD_MixerFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new factory.
|
* Creates a new factory.
|
||||||
* \param factory The factory to create the readers to mix out of.
|
* \param factory The factory to create the readers to mix out of.
|
||||||
* \param specs The target specification.
|
* \param specs The target specification.
|
||||||
*/
|
*/
|
||||||
AUD_MixerFactory(AUD_IFactory* factory, AUD_Specs specs);
|
AUD_MixerFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new factory.
|
* Creates a new factory.
|
||||||
* \param specs The target specification.
|
* \param specs The target specification.
|
||||||
*/
|
*/
|
||||||
AUD_MixerFactory(AUD_Specs specs);
|
AUD_MixerFactory(AUD_DeviceSpecs specs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys the resampling factory.
|
* Destroys the resampling factory.
|
||||||
@@ -86,13 +86,13 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Returns the target specification for resampling.
|
* Returns the target specification for resampling.
|
||||||
*/
|
*/
|
||||||
AUD_Specs getSpecs();
|
AUD_DeviceSpecs getSpecs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the target specification for resampling.
|
* Sets the target specification for resampling.
|
||||||
* \param specs The specification.
|
* \param specs The specification.
|
||||||
*/
|
*/
|
||||||
void setSpecs(AUD_Specs specs);
|
void setSpecs(AUD_DeviceSpecs specs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the reader for resampling.
|
* Sets the reader for resampling.
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ AUD_NULLDevice::AUD_NULLDevice()
|
|||||||
m_specs.rate = AUD_RATE_INVALID;
|
m_specs.rate = AUD_RATE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_Specs AUD_NULLDevice::getSpecs()
|
AUD_DeviceSpecs AUD_NULLDevice::getSpecs()
|
||||||
{
|
{
|
||||||
return m_specs;
|
return m_specs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* The specs of the device.
|
* The specs of the device.
|
||||||
*/
|
*/
|
||||||
AUD_Specs m_specs;
|
AUD_DeviceSpecs m_specs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -45,7 +45,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
AUD_NULLDevice();
|
AUD_NULLDevice();
|
||||||
|
|
||||||
virtual AUD_Specs getSpecs();
|
virtual AUD_DeviceSpecs getSpecs();
|
||||||
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
|
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
|
||||||
virtual bool pause(AUD_Handle* handle);
|
virtual bool pause(AUD_Handle* handle);
|
||||||
virtual bool resume(AUD_Handle* handle);
|
virtual bool resume(AUD_Handle* handle);
|
||||||
|
|||||||
@@ -23,17 +23,17 @@
|
|||||||
* ***** END LGPL LICENSE BLOCK *****
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AUD_FloatMixer.h"
|
#include "AUD_Mixer.h"
|
||||||
#include "AUD_ReadDevice.h"
|
#include "AUD_ReadDevice.h"
|
||||||
#include "AUD_IReader.h"
|
#include "AUD_IReader.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
AUD_ReadDevice::AUD_ReadDevice(AUD_Specs specs)
|
AUD_ReadDevice::AUD_ReadDevice(AUD_DeviceSpecs specs)
|
||||||
{
|
{
|
||||||
m_specs = specs;
|
m_specs = specs;
|
||||||
|
|
||||||
m_mixer = new AUD_FloatMixer(); AUD_NEW("mixer")
|
m_mixer = new AUD_Mixer(); AUD_NEW("mixer")
|
||||||
m_mixer->setSpecs(m_specs);
|
m_mixer->setSpecs(m_specs);
|
||||||
|
|
||||||
m_playing = false;
|
m_playing = false;
|
||||||
@@ -46,15 +46,15 @@ AUD_ReadDevice::~AUD_ReadDevice()
|
|||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AUD_ReadDevice::read(sample_t* buffer, int length)
|
bool AUD_ReadDevice::read(data_t* buffer, int length)
|
||||||
{
|
{
|
||||||
if(m_playing)
|
if(m_playing)
|
||||||
mix(buffer, length);
|
mix(buffer, length);
|
||||||
else
|
else
|
||||||
if(m_specs.format == AUD_FORMAT_U8)
|
if(m_specs.format == AUD_FORMAT_U8)
|
||||||
memset(buffer, 0x80, length * AUD_SAMPLE_SIZE(m_specs));
|
memset(buffer, 0x80, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
|
||||||
else
|
else
|
||||||
memset(buffer, 0, length * AUD_SAMPLE_SIZE(m_specs));
|
memset(buffer, 0, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
|
||||||
return m_playing;
|
return m_playing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public:
|
|||||||
* Creates a new read device.
|
* Creates a new read device.
|
||||||
* \param specs The wanted audio specification.
|
* \param specs The wanted audio specification.
|
||||||
*/
|
*/
|
||||||
AUD_ReadDevice(AUD_Specs specs);
|
AUD_ReadDevice(AUD_DeviceSpecs specs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the device.
|
* Closes the device.
|
||||||
@@ -62,7 +62,7 @@ public:
|
|||||||
* played back currently, in that case the buffer is filled with
|
* played back currently, in that case the buffer is filled with
|
||||||
* silence.
|
* silence.
|
||||||
*/
|
*/
|
||||||
bool read(sample_t* buffer, int length);
|
bool read(data_t* buffer, int length);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //AUD_READDEVICE
|
#endif //AUD_READDEVICE
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#include "AUD_SinusReader.h"
|
#include "AUD_SinusReader.h"
|
||||||
#include "AUD_Buffer.h"
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
|
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
#define M_PI 3.14159265358979323846
|
#define M_PI 3.14159265358979323846
|
||||||
@@ -69,8 +69,7 @@ AUD_Specs AUD_SinusReader::getSpecs()
|
|||||||
{
|
{
|
||||||
AUD_Specs specs;
|
AUD_Specs specs;
|
||||||
specs.rate = m_sampleRate;
|
specs.rate = m_sampleRate;
|
||||||
specs.format = AUD_FORMAT_S16;
|
specs.channels = AUD_CHANNELS_MONO;
|
||||||
specs.channels = AUD_CHANNELS_STEREO;
|
|
||||||
return specs;
|
return specs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,18 +86,16 @@ bool AUD_SinusReader::notify(AUD_Message &message)
|
|||||||
void AUD_SinusReader::read(int & length, sample_t* & buffer)
|
void AUD_SinusReader::read(int & length, sample_t* & buffer)
|
||||||
{
|
{
|
||||||
// resize if necessary
|
// resize if necessary
|
||||||
if(m_buffer->getSize() < length*4)
|
if(m_buffer->getSize() < length * sizeof(sample_t))
|
||||||
m_buffer->resize(length*4);
|
m_buffer->resize(length * sizeof(sample_t));
|
||||||
|
|
||||||
// fill with sine data
|
// fill with sine data
|
||||||
short* buf = (short*) m_buffer->getBuffer();
|
buffer = m_buffer->getBuffer();
|
||||||
for(int i=0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
buf[i*2] = sin((m_position + i) * 2.0 * M_PI * m_frequency /
|
buffer[i] = sin((m_position + i) * 2.0f * M_PI * m_frequency /
|
||||||
(float)m_sampleRate) * 32700;
|
(float)m_sampleRate);
|
||||||
buf[i*2+1] = buf[i*2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = (sample_t*)buf;
|
|
||||||
m_position += length;
|
m_position += length;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include "AUD_SoftwareDevice.h"
|
#include "AUD_SoftwareDevice.h"
|
||||||
#include "AUD_IReader.h"
|
#include "AUD_IReader.h"
|
||||||
#include "AUD_IMixer.h"
|
#include "AUD_Mixer.h"
|
||||||
#include "AUD_IFactory.h"
|
#include "AUD_IFactory.h"
|
||||||
#include "AUD_SourceCaps.h"
|
#include "AUD_SourceCaps.h"
|
||||||
|
|
||||||
@@ -51,7 +51,9 @@ void AUD_SoftwareDevice::create()
|
|||||||
m_playingSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
|
m_playingSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
|
||||||
m_pausedSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
|
m_pausedSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
|
||||||
m_playback = false;
|
m_playback = false;
|
||||||
m_volume = 1.0;
|
m_volume = 1.0f;
|
||||||
|
m_mixer = new AUD_Mixer(); AUD_NEW("mixer")
|
||||||
|
m_mixer->setSpecs(m_specs);
|
||||||
|
|
||||||
pthread_mutexattr_t attr;
|
pthread_mutexattr_t attr;
|
||||||
pthread_mutexattr_init(&attr);
|
pthread_mutexattr_init(&attr);
|
||||||
@@ -90,7 +92,7 @@ void AUD_SoftwareDevice::destroy()
|
|||||||
pthread_mutex_destroy(&m_mutex);
|
pthread_mutex_destroy(&m_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
|
void AUD_SoftwareDevice::mix(data_t* buffer, int length)
|
||||||
{
|
{
|
||||||
lock();
|
lock();
|
||||||
|
|
||||||
@@ -98,7 +100,7 @@ void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
|
|||||||
AUD_SoftwareHandle* sound;
|
AUD_SoftwareHandle* sound;
|
||||||
int len;
|
int len;
|
||||||
sample_t* buf;
|
sample_t* buf;
|
||||||
int sample_size = AUD_SAMPLE_SIZE(m_specs);
|
int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
|
||||||
std::list<AUD_SoftwareHandle*> stopSounds;
|
std::list<AUD_SoftwareHandle*> stopSounds;
|
||||||
|
|
||||||
// for all sounds
|
// for all sounds
|
||||||
@@ -114,7 +116,7 @@ void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
|
|||||||
len = length;
|
len = length;
|
||||||
sound->reader->read(len, buf);
|
sound->reader->read(len, buf);
|
||||||
|
|
||||||
m_mixer->add(buf, sound->reader->getSpecs(), len, sound->volume);
|
m_mixer->add(buf, len, sound->volume);
|
||||||
|
|
||||||
// in case the end of the sound is reached
|
// in case the end of the sound is reached
|
||||||
if(len < length)
|
if(len < length)
|
||||||
@@ -159,14 +161,7 @@ bool AUD_SoftwareDevice::isValid(AUD_Handle* handle)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_SoftwareDevice::setMixer(AUD_IMixer* mixer)
|
AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs()
|
||||||
{
|
|
||||||
delete m_mixer; AUD_DELETE("mixer")
|
|
||||||
m_mixer = mixer;
|
|
||||||
mixer->setSpecs(m_specs);
|
|
||||||
}
|
|
||||||
|
|
||||||
AUD_Specs AUD_SoftwareDevice::getSpecs()
|
|
||||||
{
|
{
|
||||||
return m_specs;
|
return m_specs;
|
||||||
}
|
}
|
||||||
@@ -189,7 +184,7 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep)
|
|||||||
AUD_SoftwareHandle* sound = new AUD_SoftwareHandle; AUD_NEW("handle")
|
AUD_SoftwareHandle* sound = new AUD_SoftwareHandle; AUD_NEW("handle")
|
||||||
sound->keep = keep;
|
sound->keep = keep;
|
||||||
sound->reader = reader;
|
sound->reader = reader;
|
||||||
sound->volume = 1.0;
|
sound->volume = 1.0f;
|
||||||
|
|
||||||
lock();
|
lock();
|
||||||
m_playingSounds->push_back(sound);
|
m_playingSounds->push_back(sound);
|
||||||
@@ -426,10 +421,10 @@ bool AUD_SoftwareDevice::setCapability(int capability, void *value)
|
|||||||
case AUD_CAPS_VOLUME:
|
case AUD_CAPS_VOLUME:
|
||||||
lock();
|
lock();
|
||||||
m_volume = *((float*)value);
|
m_volume = *((float*)value);
|
||||||
if(m_volume > 1.0)
|
if(m_volume > 1.0f)
|
||||||
m_volume = 1.0;
|
m_volume = 1.0f;
|
||||||
else if(m_volume < 0.0)
|
else if(m_volume < 0.0f)
|
||||||
m_volume = 0.0;
|
m_volume = 0.0f;
|
||||||
unlock();
|
unlock();
|
||||||
return true;
|
return true;
|
||||||
case AUD_CAPS_SOURCE_VOLUME:
|
case AUD_CAPS_SOURCE_VOLUME:
|
||||||
@@ -440,10 +435,10 @@ bool AUD_SoftwareDevice::setCapability(int capability, void *value)
|
|||||||
{
|
{
|
||||||
AUD_SoftwareHandle* handle = (AUD_SoftwareHandle*)caps->handle;
|
AUD_SoftwareHandle* handle = (AUD_SoftwareHandle*)caps->handle;
|
||||||
handle->volume = caps->value;
|
handle->volume = caps->value;
|
||||||
if(handle->volume > 1.0)
|
if(handle->volume > 1.0f)
|
||||||
handle->volume = 1.0;
|
handle->volume = 1.0f;
|
||||||
else if(handle->volume < 0.0)
|
else if(handle->volume < 0.0f)
|
||||||
handle->volume = 0.0;
|
handle->volume = 0.0f;
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
unlock();
|
unlock();
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#include "AUD_IDevice.h"
|
#include "AUD_IDevice.h"
|
||||||
struct AUD_SoftwareHandle;
|
struct AUD_SoftwareHandle;
|
||||||
class AUD_IMixer;
|
class AUD_Mixer;
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
@@ -47,12 +47,12 @@ protected:
|
|||||||
/**
|
/**
|
||||||
* The specification of the device.
|
* The specification of the device.
|
||||||
*/
|
*/
|
||||||
AUD_Specs m_specs;
|
AUD_DeviceSpecs m_specs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The mixer. Will be deleted by the destroy function.
|
* The mixer.
|
||||||
*/
|
*/
|
||||||
AUD_IMixer* m_mixer;
|
AUD_Mixer* m_mixer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes member variables.
|
* Initializes member variables.
|
||||||
@@ -69,7 +69,7 @@ protected:
|
|||||||
* \param buffer The target buffer.
|
* \param buffer The target buffer.
|
||||||
* \param length The length in samples to be filled.
|
* \param length The length in samples to be filled.
|
||||||
*/
|
*/
|
||||||
void mix(sample_t* buffer, int length);
|
void mix(data_t* buffer, int length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function tells the device, to start or pause playback.
|
* This function tells the device, to start or pause playback.
|
||||||
@@ -111,13 +111,7 @@ private:
|
|||||||
bool isValid(AUD_Handle* handle);
|
bool isValid(AUD_Handle* handle);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
virtual AUD_DeviceSpecs getSpecs();
|
||||||
* Sets a new mixer.
|
|
||||||
* \param mixer The new mixer.
|
|
||||||
*/
|
|
||||||
void setMixer(AUD_IMixer* mixer);
|
|
||||||
|
|
||||||
virtual AUD_Specs getSpecs();
|
|
||||||
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
|
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
|
||||||
virtual bool pause(AUD_Handle* handle);
|
virtual bool pause(AUD_Handle* handle);
|
||||||
virtual bool resume(AUD_Handle* handle);
|
virtual bool resume(AUD_Handle* handle);
|
||||||
|
|||||||
@@ -28,8 +28,10 @@
|
|||||||
|
|
||||||
/// The size of a format in bytes.
|
/// The size of a format in bytes.
|
||||||
#define AUD_FORMAT_SIZE(format) (format & 0x0F)
|
#define AUD_FORMAT_SIZE(format) (format & 0x0F)
|
||||||
|
/// The size of a sample in the specified device format in bytes.
|
||||||
|
#define AUD_DEVICE_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
|
||||||
/// The size of a sample in the specified format in bytes.
|
/// The size of a sample in the specified format in bytes.
|
||||||
#define AUD_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
|
#define AUD_SAMPLE_SIZE(specs) (specs.channels * sizeof(sample_t))
|
||||||
/// Throws a AUD_Exception with the provided error code.
|
/// Throws a AUD_Exception with the provided error code.
|
||||||
#define AUD_THROW(exception) { AUD_Exception e; e.error = exception; throw e; }
|
#define AUD_THROW(exception) { AUD_Exception e; e.error = exception; throw e; }
|
||||||
|
|
||||||
@@ -233,22 +235,42 @@ typedef enum
|
|||||||
AUD_3DSS_CONE_OUTER_GAIN /// Cone outer gain.
|
AUD_3DSS_CONE_OUTER_GAIN /// Cone outer gain.
|
||||||
} AUD_3DSourceSetting;
|
} AUD_3DSourceSetting;
|
||||||
|
|
||||||
/// Sample pointer type.
|
/// Sample type.(float samples)
|
||||||
typedef unsigned char sample_t;
|
typedef float sample_t;
|
||||||
|
|
||||||
/// Specification of a sound source or device.
|
/// Sample data type (format samples)
|
||||||
|
typedef unsigned char data_t;
|
||||||
|
|
||||||
|
/// Specification of a sound source.
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/// Sample rate in Hz.
|
/// Sample rate in Hz.
|
||||||
AUD_SampleRate rate;
|
AUD_SampleRate rate;
|
||||||
|
|
||||||
/// Sample format.
|
|
||||||
AUD_SampleFormat format;
|
|
||||||
|
|
||||||
/// Channel count.
|
/// Channel count.
|
||||||
AUD_Channels channels;
|
AUD_Channels channels;
|
||||||
} AUD_Specs;
|
} AUD_Specs;
|
||||||
|
|
||||||
|
/// Specification of a sound device.
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/// Sample format.
|
||||||
|
AUD_SampleFormat format;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
/// Sample rate in Hz.
|
||||||
|
AUD_SampleRate rate;
|
||||||
|
|
||||||
|
/// Channel count.
|
||||||
|
AUD_Channels channels;
|
||||||
|
};
|
||||||
|
AUD_Specs specs;
|
||||||
|
};
|
||||||
|
} AUD_DeviceSpecs;
|
||||||
|
|
||||||
/// Exception structure.
|
/// Exception structure.
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_IFactory* factory)
|
|||||||
// read more
|
// read more
|
||||||
length = size-index;
|
length = size-index;
|
||||||
reader->read(length, buffer);
|
reader->read(length, buffer);
|
||||||
memcpy(m_buffer.get()->getBuffer()+index*sample_size,
|
memcpy(m_buffer.get()->getBuffer() + index * m_specs.channels,
|
||||||
buffer,
|
buffer,
|
||||||
length*sample_size);
|
length * sample_size);
|
||||||
size += AUD_BUFFER_RESIZE_BYTES / sample_size;
|
size += AUD_BUFFER_RESIZE_BYTES / sample_size;
|
||||||
index += length;
|
index += length;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
* ***** END LGPL LICENSE BLOCK *****
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AUD_FloatMixer.h"
|
#include "AUD_Mixer.h"
|
||||||
#include "AUD_JackDevice.h"
|
#include "AUD_JackDevice.h"
|
||||||
#include "AUD_IReader.h"
|
#include "AUD_IReader.h"
|
||||||
#include "AUD_Buffer.h"
|
#include "AUD_Buffer.h"
|
||||||
@@ -38,7 +38,7 @@ int AUD_JackDevice::jack_mix(jack_nframes_t length, void *data)
|
|||||||
unsigned int samplesize = AUD_SAMPLE_SIZE(device->m_specs);
|
unsigned int samplesize = AUD_SAMPLE_SIZE(device->m_specs);
|
||||||
if(device->m_buffer->getSize() < samplesize * length)
|
if(device->m_buffer->getSize() < samplesize * length)
|
||||||
device->m_buffer->resize(samplesize * length);
|
device->m_buffer->resize(samplesize * length);
|
||||||
device->mix(device->m_buffer->getBuffer(), length);
|
device->mix((data_t*)device->m_buffer->getBuffer(), length);
|
||||||
|
|
||||||
float* in = (float*) device->m_buffer->getBuffer();
|
float* in = (float*) device->m_buffer->getBuffer();
|
||||||
float* out;
|
float* out;
|
||||||
@@ -60,7 +60,7 @@ void AUD_JackDevice::jack_shutdown(void *data)
|
|||||||
device->m_valid = false;
|
device->m_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_JackDevice::AUD_JackDevice(AUD_Specs specs)
|
AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs)
|
||||||
{
|
{
|
||||||
if(specs.channels == AUD_CHANNELS_INVALID)
|
if(specs.channels == AUD_CHANNELS_INVALID)
|
||||||
specs.channels = AUD_CHANNELS_STEREO;
|
specs.channels = AUD_CHANNELS_STEREO;
|
||||||
@@ -123,9 +123,6 @@ AUD_JackDevice::AUD_JackDevice(AUD_Specs specs)
|
|||||||
free(ports);
|
free(ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mixer = new AUD_FloatMixer(); AUD_NEW("mixer")
|
|
||||||
m_mixer->setSpecs(m_specs);
|
|
||||||
|
|
||||||
m_valid = true;
|
m_valid = true;
|
||||||
|
|
||||||
create();
|
create();
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public:
|
|||||||
* \param specs The wanted audio specification, where only the channel count is important.
|
* \param specs The wanted audio specification, where only the channel count is important.
|
||||||
* \exception AUD_Exception Thrown if the audio device cannot be opened.
|
* \exception AUD_Exception Thrown if the audio device cannot be opened.
|
||||||
*/
|
*/
|
||||||
AUD_JackDevice(AUD_Specs specs);
|
AUD_JackDevice(AUD_DeviceSpecs specs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the Jack client.
|
* Closes the Jack client.
|
||||||
|
|||||||
@@ -393,14 +393,6 @@
|
|||||||
RelativePath="..\..\intern\AUD_FileFactory.h"
|
RelativePath="..\..\intern\AUD_FileFactory.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\intern\AUD_FloatMixer.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\intern\AUD_FloatMixer.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\intern\AUD_I3DDevice.h"
|
RelativePath="..\..\intern\AUD_I3DDevice.h"
|
||||||
>
|
>
|
||||||
@@ -414,11 +406,31 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\intern\AUD_IMixer.h"
|
RelativePath="..\..\intern\AUD_IReader.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\intern\AUD_IReader.h"
|
RelativePath="..\..\intern\AUD_LinearResampleFactory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\intern\AUD_LinearResampleFactory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\intern\AUD_LinearResampleReader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\intern\AUD_LinearResampleReader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\intern\AUD_Mixer.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\intern\AUD_Mixer.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
@@ -517,6 +529,38 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="FX"
|
Name="FX"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_AccumulatorFactory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_AccumulatorFactory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_AccumulatorReader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_AccumulatorReader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_ButterworthFactory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_ButterworthFactory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_ButterworthReader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_ButterworthReader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\FX\AUD_DelayFactory.cpp"
|
RelativePath="..\..\FX\AUD_DelayFactory.cpp"
|
||||||
>
|
>
|
||||||
@@ -557,6 +601,22 @@
|
|||||||
RelativePath="..\..\FX\AUD_EffectReader.h"
|
RelativePath="..\..\FX\AUD_EffectReader.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_EnvelopeFactory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_EnvelopeFactory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_EnvelopeReader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_EnvelopeReader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\FX\AUD_FaderFactory.cpp"
|
RelativePath="..\..\FX\AUD_FaderFactory.cpp"
|
||||||
>
|
>
|
||||||
@@ -573,6 +633,22 @@
|
|||||||
RelativePath="..\..\FX\AUD_FaderReader.h"
|
RelativePath="..\..\FX\AUD_FaderReader.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_HighpassFactory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_HighpassFactory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_HighpassReader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_HighpassReader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\FX\AUD_LimiterFactory.cpp"
|
RelativePath="..\..\FX\AUD_LimiterFactory.cpp"
|
||||||
>
|
>
|
||||||
@@ -605,6 +681,22 @@
|
|||||||
RelativePath="..\..\FX\AUD_LoopReader.h"
|
RelativePath="..\..\FX\AUD_LoopReader.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_LowpassFactory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_LowpassFactory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_LowpassReader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_LowpassReader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\FX\AUD_PingPongFactory.cpp"
|
RelativePath="..\..\FX\AUD_PingPongFactory.cpp"
|
||||||
>
|
>
|
||||||
@@ -661,6 +753,38 @@
|
|||||||
RelativePath="..\..\FX\AUD_ReverseReader.h"
|
RelativePath="..\..\FX\AUD_ReverseReader.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_SquareFactory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_SquareFactory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_SquareReader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_SquareReader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_SumFactory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_SumFactory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_SumReader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_SumReader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\FX\AUD_VolumeFactory.cpp"
|
RelativePath="..\..\FX\AUD_VolumeFactory.cpp"
|
||||||
>
|
>
|
||||||
@@ -701,30 +825,6 @@
|
|||||||
RelativePath="..\..\SDL\AUD_SDLDevice.h"
|
RelativePath="..\..\SDL\AUD_SDLDevice.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\SDL\AUD_SDLMixer.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\SDL\AUD_SDLMixer.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\SDL\AUD_SDLMixerFactory.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\SDL\AUD_SDLMixerFactory.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\SDL\AUD_SDLMixerReader.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\SDL\AUD_SDLMixerReader.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="SRC"
|
Name="SRC"
|
||||||
|
|||||||
@@ -28,31 +28,14 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
// This function transforms a SampleFormat to our own sample format
|
|
||||||
static inline AUD_SampleFormat SNDFILE_TO_AUD(int fmt)
|
|
||||||
{
|
|
||||||
switch(fmt & SF_FORMAT_SUBMASK)
|
|
||||||
{
|
|
||||||
// only read s16, s32 and double as they are
|
|
||||||
case SF_FORMAT_PCM_16:
|
|
||||||
return AUD_FORMAT_S16;
|
|
||||||
case SF_FORMAT_PCM_32:
|
|
||||||
return AUD_FORMAT_S32;
|
|
||||||
case SF_FORMAT_DOUBLE:
|
|
||||||
return AUD_FORMAT_FLOAT64;
|
|
||||||
// read all other formats as floats
|
|
||||||
default:
|
|
||||||
return AUD_FORMAT_FLOAT32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sf_count_t AUD_SndFileReader::vio_get_filelen(void *user_data)
|
sf_count_t AUD_SndFileReader::vio_get_filelen(void *user_data)
|
||||||
{
|
{
|
||||||
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
|
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
|
||||||
return reader->m_membuffer.get()->getSize();
|
return reader->m_membuffer.get()->getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence, void *user_data)
|
sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence,
|
||||||
|
void *user_data)
|
||||||
{
|
{
|
||||||
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
|
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
|
||||||
|
|
||||||
@@ -72,14 +55,16 @@ sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence, void *user
|
|||||||
return reader->m_memoffset;
|
return reader->m_memoffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count, void *user_data)
|
sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count,
|
||||||
|
void *user_data)
|
||||||
{
|
{
|
||||||
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
|
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
|
||||||
|
|
||||||
if(reader->m_memoffset + count > reader->m_membuffer.get()->getSize())
|
if(reader->m_memoffset + count > reader->m_membuffer.get()->getSize())
|
||||||
count = reader->m_membuffer.get()->getSize() - reader->m_memoffset;
|
count = reader->m_membuffer.get()->getSize() - reader->m_memoffset;
|
||||||
|
|
||||||
memcpy(ptr, reader->m_membuffer.get()->getBuffer() + reader->m_memoffset, count);
|
memcpy(ptr, ((data_t*)reader->m_membuffer.get()->getBuffer()) +
|
||||||
|
reader->m_memoffset, count);
|
||||||
reader->m_memoffset += count;
|
reader->m_memoffset += count;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@@ -103,27 +88,11 @@ AUD_SndFileReader::AUD_SndFileReader(const char* filename)
|
|||||||
AUD_THROW(AUD_ERROR_FILE);
|
AUD_THROW(AUD_ERROR_FILE);
|
||||||
|
|
||||||
m_specs.channels = (AUD_Channels) sfinfo.channels;
|
m_specs.channels = (AUD_Channels) sfinfo.channels;
|
||||||
m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
|
|
||||||
m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
|
m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
|
||||||
m_length = sfinfo.frames;
|
m_length = sfinfo.frames;
|
||||||
m_seekable = sfinfo.seekable;
|
m_seekable = sfinfo.seekable;
|
||||||
m_position = 0;
|
m_position = 0;
|
||||||
|
|
||||||
switch(m_specs.format)
|
|
||||||
{
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
m_read = (sf_read_f) sf_readf_short;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S32:
|
|
||||||
m_read = (sf_read_f) sf_readf_int;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT64:
|
|
||||||
m_read = (sf_read_f) sf_readf_double;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
m_read = (sf_read_f) sf_readf_float;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,27 +116,11 @@ AUD_SndFileReader::AUD_SndFileReader(AUD_Reference<AUD_Buffer> buffer)
|
|||||||
AUD_THROW(AUD_ERROR_FILE);
|
AUD_THROW(AUD_ERROR_FILE);
|
||||||
|
|
||||||
m_specs.channels = (AUD_Channels) sfinfo.channels;
|
m_specs.channels = (AUD_Channels) sfinfo.channels;
|
||||||
m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
|
|
||||||
m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
|
m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
|
||||||
m_length = sfinfo.frames;
|
m_length = sfinfo.frames;
|
||||||
m_seekable = sfinfo.seekable;
|
m_seekable = sfinfo.seekable;
|
||||||
m_position = 0;
|
m_position = 0;
|
||||||
|
|
||||||
switch(m_specs.format)
|
|
||||||
{
|
|
||||||
case AUD_FORMAT_S16:
|
|
||||||
m_read = (sf_read_f) sf_readf_short;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_S32:
|
|
||||||
m_read = (sf_read_f) sf_readf_int;
|
|
||||||
break;
|
|
||||||
case AUD_FORMAT_FLOAT64:
|
|
||||||
m_read = (sf_read_f) sf_readf_double;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
m_read = (sf_read_f) sf_readf_float;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +180,7 @@ void AUD_SndFileReader::read(int & length, sample_t* & buffer)
|
|||||||
|
|
||||||
buffer = m_buffer->getBuffer();
|
buffer = m_buffer->getBuffer();
|
||||||
|
|
||||||
length = m_read(m_sndfile, buffer, length);
|
length = sf_readf_float(m_sndfile, buffer, length);
|
||||||
|
|
||||||
m_position += length;
|
m_position += length;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,11 +70,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
SNDFILE* m_sndfile;
|
SNDFILE* m_sndfile;
|
||||||
|
|
||||||
/**
|
|
||||||
* The reading function.
|
|
||||||
*/
|
|
||||||
sf_read_f m_read;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The virtual IO structure for memory file reading.
|
* The virtual IO structure for memory file reading.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -162,6 +162,8 @@ extern void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,
|
|||||||
* @param height The height the window.
|
* @param height The height the window.
|
||||||
* @param state The state of the window when opened.
|
* @param state The state of the window when opened.
|
||||||
* @param type The type of drawing context installed in this window.
|
* @param type The type of drawing context installed in this window.
|
||||||
|
* @param stereoVisual Stereo visual for quad buffered stereo.
|
||||||
|
* @param numOfAASamples Number of samples used for AA (zero if no AA)
|
||||||
* @return A handle to the new window ( == NULL if creation failed).
|
* @return A handle to the new window ( == NULL if creation failed).
|
||||||
*/
|
*/
|
||||||
extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
||||||
@@ -172,7 +174,8 @@ extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
|||||||
GHOST_TUns32 height,
|
GHOST_TUns32 height,
|
||||||
GHOST_TWindowState state,
|
GHOST_TWindowState state,
|
||||||
GHOST_TDrawingContextType type,
|
GHOST_TDrawingContextType type,
|
||||||
const int stereoVisual);
|
const int stereoVisual,
|
||||||
|
const GHOST_TUns16 numOfAASamples);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the window user data.
|
* Returns the window user data.
|
||||||
|
|||||||
@@ -216,14 +216,15 @@ public:
|
|||||||
* Create a new window.
|
* Create a new window.
|
||||||
* The new window is added to the list of windows managed.
|
* The new window is added to the list of windows managed.
|
||||||
* Never explicitly delete the window, use disposeWindow() instead.
|
* Never explicitly delete the window, use disposeWindow() instead.
|
||||||
* @param title The name of the window (displayed in the title bar of the window if the OS supports it).
|
* @param title The name of the window (displayed in the title bar of the window if the OS supports it).
|
||||||
* @param left The coordinate of the left edge of the window.
|
* @param left The coordinate of the left edge of the window.
|
||||||
* @param top The coordinate of the top edge of the window.
|
* @param top The coordinate of the top edge of the window.
|
||||||
* @param width The width the window.
|
* @param width The width the window.
|
||||||
* @param height The height the window.
|
* @param height The height the window.
|
||||||
* @param state The state of the window when opened.
|
* @param state The state of the window when opened.
|
||||||
* @param type The type of drawing context installed in this window.
|
* @param type The type of drawing context installed in this window.
|
||||||
* @param stereoVisual Create a stereo visual for quad buffered stereo.
|
* @param stereoVisual Create a stereo visual for quad buffered stereo.
|
||||||
|
* @param numOfAASamples Number of samples used for AA (zero if no AA)
|
||||||
* @param parentWindow Parent (embedder) window
|
* @param parentWindow Parent (embedder) window
|
||||||
* @return The new window (or 0 if creation failed).
|
* @return The new window (or 0 if creation failed).
|
||||||
*/
|
*/
|
||||||
@@ -231,7 +232,8 @@ public:
|
|||||||
const STR_String& title,
|
const STR_String& title,
|
||||||
GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
|
GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
|
||||||
GHOST_TWindowState state, GHOST_TDrawingContextType type,
|
GHOST_TWindowState state, GHOST_TDrawingContextType type,
|
||||||
const bool stereoVisual,
|
const bool stereoVisual = false,
|
||||||
|
const GHOST_TUns16 numOfAASamples = 0,
|
||||||
const GHOST_TEmbedderWindowID parentWindow = 0) = 0;
|
const GHOST_TEmbedderWindowID parentWindow = 0) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user