merge with trunk/2.5 at r25907
This commit is contained in:
@@ -412,31 +412,6 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
||||
// restore
|
||||
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
|
||||
/// 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
|
||||
// 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"
|
||||
|
||||
|
||||
//#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;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -40,11 +40,6 @@ IF(WITH_OPENAL)
|
||||
SET(INC ${INC} OpenAL ${OPENAL_INCLUDE_DIR})
|
||||
FILE(GLOB OPENALSRC OpenAL/*.cpp)
|
||||
ADD_DEFINITIONS(-DWITH_OPENAL)
|
||||
|
||||
STRING(REGEX MATCH ".*ramework.*" FRAMEWORK ${OPENAL_INCLUDE_DIR})
|
||||
IF(FRAMEWORK)
|
||||
ADD_DEFINITIONS(-DAPPLE_FRAMEWORK_FIX)
|
||||
ENDIF(FRAMEWORK)
|
||||
ENDIF(WITH_OPENAL)
|
||||
|
||||
IF(WITH_JACK)
|
||||
@@ -59,6 +54,12 @@ IF(WITH_SNDFILE)
|
||||
ADD_DEFINITIONS(-DWITH_SNDFILE)
|
||||
ENDIF(WITH_SNDFILE)
|
||||
|
||||
SET(SRC ${SRC} ${FFMPEGSRC} ${SNDFILESRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC})
|
||||
IF(WITH_FFTW3)
|
||||
SET(INC ${INC} fftw ${FFTW3_INC})
|
||||
FILE(GLOB FFTW3SRC fftw/*.cpp)
|
||||
ADD_DEFINITIONS(-DWITH_FFTW3)
|
||||
ENDIF(WITH_FFTW3)
|
||||
|
||||
SET(SRC ${SRC} ${FFMPEGSRC} ${SNDFILESRC} ${FFTW3SRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC})
|
||||
|
||||
BLENDERLIB(bf_audaspace "${SRC}" "${INC}")
|
||||
|
||||
@@ -77,31 +77,26 @@ void AUD_DelayReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
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)
|
||||
m_buffer->resize(length*samplesize);
|
||||
if(m_buffer->getSize() < length * samplesize)
|
||||
m_buffer->resize(length * samplesize);
|
||||
|
||||
if(length > m_remdelay)
|
||||
{
|
||||
if(getSpecs().format == AUD_FORMAT_U8)
|
||||
memset(m_buffer->getBuffer(), 0x80, m_remdelay*samplesize);
|
||||
else
|
||||
memset(m_buffer->getBuffer(), 0, m_remdelay*samplesize);
|
||||
memset(m_buffer->getBuffer(), 0, m_remdelay * samplesize);
|
||||
int len = length - m_remdelay;
|
||||
m_reader->read(len, buffer);
|
||||
memcpy(m_buffer->getBuffer()+m_remdelay*samplesize,
|
||||
buffer, len*samplesize);
|
||||
memcpy(m_buffer->getBuffer() + m_remdelay * specs.channels,
|
||||
buffer, len * samplesize);
|
||||
if(len < length-m_remdelay)
|
||||
length = m_remdelay + len;
|
||||
m_remdelay = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(getSpecs().format == AUD_FORMAT_U8)
|
||||
memset(m_buffer->getBuffer(), 0x80, length*samplesize);
|
||||
else
|
||||
memset(m_buffer->getBuffer(), 0, length*samplesize);
|
||||
memset(m_buffer->getBuffer(), 0, length * samplesize);
|
||||
m_remdelay -= length;
|
||||
}
|
||||
buffer = m_buffer->getBuffer();
|
||||
|
||||
@@ -137,15 +137,16 @@ void AUD_DoubleReader::read(int & length, sample_t* & buffer)
|
||||
m_reader1->read(len, buffer);
|
||||
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)
|
||||
m_buffer->resize(length * samplesize);
|
||||
memcpy(m_buffer->getBuffer(), buffer, len*samplesize);
|
||||
memcpy(m_buffer->getBuffer(), buffer, len * samplesize);
|
||||
len = length - len;
|
||||
length -= len;
|
||||
m_reader2->read(len, buffer);
|
||||
memcpy(m_buffer->getBuffer() + length*samplesize,
|
||||
buffer, len*samplesize);
|
||||
memcpy(m_buffer->getBuffer() + length * specs.channels, buffer,
|
||||
len * samplesize);
|
||||
length += len;
|
||||
buffer = m_buffer->getBuffer();
|
||||
m_finished1 = true;
|
||||
|
||||
@@ -35,35 +35,6 @@ AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
|
||||
m_start(start),
|
||||
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")
|
||||
}
|
||||
|
||||
@@ -93,9 +64,7 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
|
||||
if(m_type != AUD_FADE_OUT)
|
||||
{
|
||||
buffer = m_buffer->getBuffer();
|
||||
memset(buffer,
|
||||
specs.format == AUD_FORMAT_U8 ? 0x80 : 0,
|
||||
length * samplesize);
|
||||
memset(buffer, 0, length * samplesize);
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
buffer = m_buffer->getBuffer();
|
||||
memset(buffer,
|
||||
specs.format == AUD_FORMAT_U8 ? 0x80 : 0,
|
||||
length * samplesize);
|
||||
memset(buffer, 0, length * samplesize);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -113,19 +80,21 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
|
||||
sample_t* buf = m_buffer->getBuffer();
|
||||
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(volume > 1.0f)
|
||||
volume = 1.0f;
|
||||
else if(volume < 0.0f)
|
||||
volume = 0.0f;
|
||||
if(i % specs.channels == 0)
|
||||
{
|
||||
volume = (((position+i)/(float)specs.rate)-m_start) / m_length;
|
||||
if(volume > 1.0f)
|
||||
volume = 1.0f;
|
||||
else if(volume < 0.0f)
|
||||
volume = 0.0f;
|
||||
|
||||
if(m_type == AUD_FADE_OUT)
|
||||
volume = 1.0f - volume;
|
||||
if(m_type == AUD_FADE_OUT)
|
||||
volume = 1.0f - volume;
|
||||
}
|
||||
|
||||
m_adjust(buf + i * samplesize, buffer + i * samplesize,
|
||||
specs.channels, volume);
|
||||
buf[i] = buffer[i] * volume;
|
||||
}
|
||||
|
||||
buffer = buf;
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#define AUD_FADERREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_ConverterFunctions.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
@@ -58,11 +57,6 @@ private:
|
||||
*/
|
||||
float m_length;
|
||||
|
||||
/**
|
||||
* Volume adjustment function.
|
||||
*/
|
||||
AUD_volume_adjust_f m_adjust;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new fader reader.
|
||||
|
||||
@@ -38,7 +38,7 @@ private:
|
||||
/**
|
||||
* The loop count.
|
||||
*/
|
||||
float m_loop;
|
||||
int m_loop;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
|
||||
AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int 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)
|
||||
{
|
||||
int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||
|
||||
int len = length;
|
||||
|
||||
@@ -72,10 +72,10 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
if(m_buffer->getSize() < length*samplesize)
|
||||
m_buffer->resize(length*samplesize);
|
||||
if(m_buffer->getSize() < length * samplesize)
|
||||
m_buffer->resize(length * samplesize);
|
||||
|
||||
memcpy(m_buffer->getBuffer() + pos * samplesize,
|
||||
memcpy(m_buffer->getBuffer() + pos * specs.channels,
|
||||
buffer, len * samplesize);
|
||||
|
||||
pos += len;
|
||||
@@ -93,7 +93,7 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer)
|
||||
if(!len)
|
||||
break;
|
||||
|
||||
memcpy(m_buffer->getBuffer() + pos * samplesize,
|
||||
memcpy(m_buffer->getBuffer() + pos * specs.channels,
|
||||
buffer, len * samplesize);
|
||||
|
||||
pos += len;
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
* \param factory The input factory.
|
||||
* \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.
|
||||
|
||||
@@ -26,39 +26,11 @@
|
||||
#include "AUD_RectifyReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
AUD_RectifyReader::AUD_RectifyReader(AUD_IReader* 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")
|
||||
}
|
||||
|
||||
@@ -73,10 +45,11 @@ void AUD_RectifyReader::read(int & length, sample_t* & buffer)
|
||||
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));
|
||||
if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||
m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
|
||||
|
||||
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
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_ConverterFunctions.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
@@ -41,11 +40,6 @@ private:
|
||||
*/
|
||||
AUD_Buffer *m_buffer;
|
||||
|
||||
/**
|
||||
* Rectifying function.
|
||||
*/
|
||||
AUD_rectify_f m_rectify;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new rectify reader.
|
||||
|
||||
@@ -65,7 +65,7 @@ int AUD_ReverseReader::getPosition()
|
||||
void AUD_ReverseReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
// first correct the length
|
||||
if(m_position+length > m_length)
|
||||
if(m_position + length > m_length)
|
||||
length = m_length-m_position;
|
||||
|
||||
if(length <= 0)
|
||||
@@ -74,7 +74,8 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
|
||||
return;
|
||||
}
|
||||
|
||||
int samplesize = AUD_SAMPLE_SIZE(getSpecs());
|
||||
AUD_Specs specs = getSpecs();
|
||||
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||
|
||||
// resize buffer if needed
|
||||
if(m_buffer->getSize() < length * samplesize)
|
||||
@@ -86,23 +87,20 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
|
||||
int len = length;
|
||||
|
||||
// read from reader
|
||||
m_reader->seek(m_length-m_position-len);
|
||||
m_reader->seek(m_length - m_position - len);
|
||||
m_reader->read(len, buf);
|
||||
|
||||
// set null if reader didn't give enough data
|
||||
if(len < length)
|
||||
{
|
||||
if(getSpecs().format == AUD_FORMAT_U8)
|
||||
memset(buffer, 0x80, (length-len)*samplesize);
|
||||
else
|
||||
memset(buffer, 0, (length-len)*samplesize);
|
||||
buffer += length-len;
|
||||
memset(buffer, 0, (length - len) * samplesize);
|
||||
buffer += (length - len) * specs.channels;
|
||||
}
|
||||
|
||||
// copy the samples reverted
|
||||
for(int i = 0; i < len; i++)
|
||||
memcpy(buffer + i * samplesize,
|
||||
buf + (len - 1 - i) * samplesize,
|
||||
memcpy(buffer + i * specs.channels,
|
||||
buf + (len - 1 - i) * specs.channels,
|
||||
samplesize);
|
||||
|
||||
m_position += length;
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
* \param factory The input factory.
|
||||
* \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.
|
||||
|
||||
@@ -32,35 +32,6 @@ AUD_VolumeReader::AUD_VolumeReader(AUD_IReader* reader, float volume) :
|
||||
AUD_EffectReader(reader),
|
||||
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")
|
||||
}
|
||||
|
||||
@@ -93,5 +64,6 @@ void AUD_VolumeReader::read(int & length, sample_t* & buffer)
|
||||
|
||||
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
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_ConverterFunctions.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
@@ -46,11 +45,6 @@ private:
|
||||
*/
|
||||
float m_volume;
|
||||
|
||||
/**
|
||||
* Volume adjustment function.
|
||||
*/
|
||||
AUD_volume_adjust_f m_adjust;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new volume reader.
|
||||
|
||||
@@ -56,6 +56,10 @@ ifeq ($(WITH_SNDFILE),true)
|
||||
DIRS += sndfile
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_FFTW3),true)
|
||||
DIRS += fftw
|
||||
endif
|
||||
|
||||
include nan_subdirs.mk
|
||||
|
||||
install: $(ALL_OR_DEBUG)
|
||||
@@ -80,6 +84,10 @@ ifeq ($(WITH_SNDFILE),true)
|
||||
@../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_sndfile.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_FFTW3),true)
|
||||
@../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_fftw.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
|
||||
endif
|
||||
|
||||
ifeq ($(OS),darwin)
|
||||
ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaudaspace.a
|
||||
ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_src.a
|
||||
@@ -102,5 +110,9 @@ ifeq ($(WITH_SNDFILE),true)
|
||||
ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_sndfile.a
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_FFTW3),true)
|
||||
ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_fftw.a
|
||||
endif
|
||||
|
||||
endif
|
||||
@../tools/cpifdiff.sh intern/*.h $(NAN_AUDASPACE)/include/
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#include "AUD_OpenALDevice.h"
|
||||
#include "AUD_IReader.h"
|
||||
#include "AUD_IMixer.h"
|
||||
#include "AUD_ConverterFactory.h"
|
||||
#include "AUD_SourceCaps.h"
|
||||
|
||||
@@ -119,7 +118,7 @@ void AUD_OpenALDevice::updateStreams()
|
||||
sample_t* buffer;
|
||||
|
||||
ALint info;
|
||||
AUD_Specs specs;
|
||||
AUD_DeviceSpecs specs = m_specs;
|
||||
|
||||
while(1)
|
||||
{
|
||||
@@ -145,7 +144,7 @@ void AUD_OpenALDevice::updateStreams()
|
||||
|
||||
if(info)
|
||||
{
|
||||
specs = sound->reader->getSpecs();
|
||||
specs.specs = sound->reader->getSpecs();
|
||||
|
||||
// for all empty buffers
|
||||
while(info--)
|
||||
@@ -177,8 +176,8 @@ void AUD_OpenALDevice::updateStreams()
|
||||
// fill with new data
|
||||
alBufferData(sound->buffers[sound->current],
|
||||
sound->format,
|
||||
buffer,
|
||||
length * AUD_SAMPLE_SIZE(specs),
|
||||
buffer, length *
|
||||
AUD_DEVICE_SAMPLE_SIZE(specs),
|
||||
specs.rate);
|
||||
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
@@ -264,7 +263,7 @@ bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
|
||||
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
|
||||
// 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
|
||||
if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
|
||||
{
|
||||
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;
|
||||
|
||||
alGetError();
|
||||
|
||||
m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
|
||||
|
||||
m_specs = specs;
|
||||
m_buffersize = buffersize;
|
||||
m_playing = false;
|
||||
@@ -378,12 +380,13 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
|
||||
alcDestroyContext(m_context);
|
||||
alcCloseDevice(m_device);
|
||||
|
||||
delete m_converter; AUD_DELETE("factory")
|
||||
if(m_converter)
|
||||
delete m_converter; AUD_DELETE("factory")
|
||||
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
}
|
||||
|
||||
AUD_Specs AUD_OpenALDevice::getSpecs()
|
||||
AUD_DeviceSpecs AUD_OpenALDevice::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
}
|
||||
@@ -393,45 +396,8 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
|
||||
bool valid = true;
|
||||
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:
|
||||
switch(specs.channels)
|
||||
{
|
||||
@@ -591,23 +557,16 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
|
||||
if(reader == NULL)
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
|
||||
AUD_Specs specs;
|
||||
|
||||
specs = reader->getSpecs();
|
||||
AUD_DeviceSpecs specs = m_specs;
|
||||
specs.specs = reader->getSpecs();
|
||||
|
||||
// check format
|
||||
bool valid = true;
|
||||
bool valid = specs.channels != AUD_CHANNELS_INVALID;
|
||||
|
||||
if(specs.format == AUD_FORMAT_INVALID)
|
||||
valid = false;
|
||||
else if(specs.format == AUD_FORMAT_S24 ||
|
||||
specs.format == AUD_FORMAT_S32 ||
|
||||
specs.format == AUD_FORMAT_FLOAT32 ||
|
||||
specs.format == AUD_FORMAT_FLOAT64)
|
||||
if(m_converter)
|
||||
{
|
||||
m_converter->setReader(reader);
|
||||
reader = m_converter->createReader();
|
||||
specs = reader->getSpecs();
|
||||
}
|
||||
|
||||
// create the handle
|
||||
@@ -618,7 +577,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
|
||||
sound->isBuffered = false;
|
||||
sound->data_end = false;
|
||||
|
||||
valid &= getFormat(sound->format, specs);
|
||||
valid &= getFormat(sound->format, specs.specs);
|
||||
|
||||
if(!valid)
|
||||
{
|
||||
@@ -647,7 +606,8 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
|
||||
length = m_buffersize;
|
||||
reader->read(length, 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)
|
||||
AUD_THROW(AUD_ERROR_OPENAL);
|
||||
}
|
||||
@@ -875,14 +835,16 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
|
||||
{
|
||||
sample_t* buf;
|
||||
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++)
|
||||
{
|
||||
length = m_buffersize;
|
||||
alhandle->reader->read(length, buf);
|
||||
alBufferData(alhandle->buffers[i], alhandle->format,
|
||||
buf, length * AUD_SAMPLE_SIZE(specs),
|
||||
buf,
|
||||
length * AUD_DEVICE_SAMPLE_SIZE(specs),
|
||||
specs.rate);
|
||||
|
||||
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 position = 0.0;
|
||||
float position = 0.0f;
|
||||
|
||||
lock();
|
||||
|
||||
@@ -1021,6 +983,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
|
||||
// load the factory into an OpenAL buffer
|
||||
if(factory)
|
||||
{
|
||||
// check if the factory is already buffered
|
||||
lock();
|
||||
for(AUD_BFIterator i = m_bufferedFactories->begin();
|
||||
i != m_bufferedFactories->end(); i++)
|
||||
@@ -1040,32 +1003,25 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
|
||||
if(reader == NULL)
|
||||
return false;
|
||||
|
||||
AUD_Specs specs;
|
||||
|
||||
specs = reader->getSpecs();
|
||||
AUD_DeviceSpecs specs = m_specs;
|
||||
specs.specs = reader->getSpecs();
|
||||
|
||||
// determine format
|
||||
bool valid = reader->getType() == AUD_TYPE_BUFFER;
|
||||
|
||||
if(valid)
|
||||
{
|
||||
if(specs.format == AUD_FORMAT_INVALID)
|
||||
valid = false;
|
||||
else if(specs.format == AUD_FORMAT_S24 ||
|
||||
specs.format == AUD_FORMAT_S32 ||
|
||||
specs.format == AUD_FORMAT_FLOAT32 ||
|
||||
specs.format == AUD_FORMAT_FLOAT64)
|
||||
if(m_converter)
|
||||
{
|
||||
m_converter->setReader(reader);
|
||||
reader = m_converter->createReader();
|
||||
specs = reader->getSpecs();
|
||||
}
|
||||
}
|
||||
|
||||
ALenum format;
|
||||
|
||||
if(valid)
|
||||
valid = getFormat(format, specs);
|
||||
valid = getFormat(format, specs.specs);
|
||||
|
||||
if(!valid)
|
||||
{
|
||||
@@ -1094,7 +1050,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
|
||||
|
||||
reader->read(length, buf);
|
||||
alBufferData(bf->buffer, format, buf,
|
||||
length * AUD_SAMPLE_SIZE(specs),
|
||||
length * AUD_DEVICE_SAMPLE_SIZE(specs),
|
||||
specs.rate);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
AUD_THROW(AUD_ERROR_OPENAL);
|
||||
@@ -1327,7 +1283,7 @@ bool AUD_OpenALDevice::setSourceSetting(AUD_Handle* handle,
|
||||
result = true;
|
||||
break;
|
||||
case AUD_3DSS_IS_RELATIVE:
|
||||
alSourcei(source, AL_SOURCE_RELATIVE, value > 0.0);
|
||||
alSourcei(source, AL_SOURCE_RELATIVE, value > 0.0f);
|
||||
result = true;
|
||||
break;
|
||||
case AUD_3DSS_MAX_DISTANCE:
|
||||
@@ -1385,7 +1341,7 @@ float AUD_OpenALDevice::getSourceSetting(AUD_Handle* handle,
|
||||
{
|
||||
ALint i;
|
||||
alGetSourcei(source, AL_SOURCE_RELATIVE, &i);
|
||||
result = i ? 1.0 : 0.0;
|
||||
result = i ? 1.0f : 0.0f;
|
||||
break;
|
||||
}
|
||||
case AUD_3DSS_MAX_DISTANCE:
|
||||
|
||||
@@ -56,7 +56,7 @@ private:
|
||||
/**
|
||||
* The specification of the device.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
AUD_DeviceSpecs m_specs;
|
||||
|
||||
/**
|
||||
* Whether the device has the AL_EXT_MCFORMATS extension.
|
||||
@@ -64,8 +64,8 @@ private:
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -118,7 +118,7 @@ private:
|
||||
/**
|
||||
* Gets the format according to the specs.
|
||||
* \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.
|
||||
*/
|
||||
bool getFormat(ALenum &format, AUD_Specs specs);
|
||||
@@ -132,7 +132,8 @@ public:
|
||||
* \note The buffersize will be multiplicated by three for this device.
|
||||
* \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.
|
||||
@@ -141,7 +142,7 @@ public:
|
||||
|
||||
virtual ~AUD_OpenALDevice();
|
||||
|
||||
virtual AUD_Specs getSpecs();
|
||||
virtual AUD_DeviceSpecs getSpecs();
|
||||
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
|
||||
virtual bool pause(AUD_Handle* handle);
|
||||
virtual bool resume(AUD_Handle* handle);
|
||||
|
||||
@@ -31,4 +31,12 @@ if env['WITH_BF_SNDFILE']:
|
||||
incs += ' sndfile ' + env['BF_SNDFILE_INC']
|
||||
defs.append('WITH_SNDFILE')
|
||||
|
||||
if env['WITH_BF_FFTW3']:
|
||||
sources += env.Glob('fftw/*.cpp')
|
||||
incs += ' fftw ' + env['BF_FFTW3_INC']
|
||||
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] )
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_SDLMixer.h"
|
||||
#include "AUD_SDLDevice.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;
|
||||
|
||||
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)
|
||||
specs.channels = AUD_CHANNELS_STEREO;
|
||||
@@ -69,9 +68,6 @@ AUD_SDLDevice::AUD_SDLDevice(AUD_Specs specs, int buffersize)
|
||||
else
|
||||
AUD_THROW(AUD_ERROR_SDL);
|
||||
|
||||
m_mixer = new AUD_SDLMixer(); AUD_NEW("mixer")
|
||||
m_mixer->setSpecs(m_specs);
|
||||
|
||||
create();
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,8 @@ public:
|
||||
* \note The specification really used for opening the device may differ.
|
||||
* \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.
|
||||
|
||||
@@ -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,76 +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_SDLMIXER
|
||||
#define AUD_SDLMIXER
|
||||
|
||||
#include "AUD_IMixer.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.
|
||||
*/
|
||||
class AUD_SDLMixer : public AUD_IMixer
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The mixer factory that prepares all readers for superposition.
|
||||
*/
|
||||
AUD_SDLMixerFactory* m_factory;
|
||||
|
||||
/**
|
||||
* The list of buffers to superpose.
|
||||
*/
|
||||
std::list<AUD_SDLMixerBuffer> m_buffers;
|
||||
|
||||
/**
|
||||
* The size of an output sample.
|
||||
*/
|
||||
int m_samplesize;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates the mixer.
|
||||
*/
|
||||
AUD_SDLMixer();
|
||||
|
||||
virtual ~AUD_SDLMixer();
|
||||
|
||||
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_SDLMIXER
|
||||
@@ -1,45 +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_SDLMIXERFACTORY
|
||||
#define AUD_SDLMIXERFACTORY
|
||||
|
||||
#include "AUD_MixerFactory.h"
|
||||
|
||||
/**
|
||||
* This factory creates a resampling reader that uses SDL's resampling
|
||||
* functionality which unfortunately is very very very limited.
|
||||
*/
|
||||
class AUD_SDLMixerFactory : public AUD_MixerFactory
|
||||
{
|
||||
public:
|
||||
AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs);
|
||||
AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs);
|
||||
AUD_SDLMixerFactory(AUD_Specs specs);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_SDLMIXERFACTORY
|
||||
@@ -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"
|
||||
|
||||
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IReader* reader,
|
||||
AUD_Specs specs) :
|
||||
AUD_DeviceSpecs specs) :
|
||||
AUD_ResampleFactory(reader, specs) {}
|
||||
|
||||
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IFactory* factory,
|
||||
AUD_Specs specs) :
|
||||
AUD_DeviceSpecs specs) :
|
||||
AUD_ResampleFactory(factory, specs) {}
|
||||
|
||||
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_Specs specs) :
|
||||
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_DeviceSpecs specs) :
|
||||
AUD_ResampleFactory(specs) {}
|
||||
|
||||
AUD_IReader* AUD_SRCResampleFactory::createReader()
|
||||
@@ -45,7 +45,7 @@ AUD_IReader* AUD_SRCResampleFactory::createReader()
|
||||
{
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,14 +31,13 @@
|
||||
/**
|
||||
* This factory creates a resampling reader that uses libsamplerate for
|
||||
* resampling.
|
||||
* \note The format of the input must be float.
|
||||
*/
|
||||
class AUD_SRCResampleFactory : public AUD_ResampleFactory
|
||||
{
|
||||
public:
|
||||
AUD_SRCResampleFactory(AUD_IReader* reader, AUD_Specs specs);
|
||||
AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_Specs specs);
|
||||
AUD_SRCResampleFactory(AUD_Specs specs);
|
||||
AUD_SRCResampleFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
|
||||
AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
|
||||
AUD_SRCResampleFactory(AUD_DeviceSpecs specs);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
#include "AUD_SRCResampleReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
|
||||
static long src_callback(void *cb_data, float **data)
|
||||
{
|
||||
@@ -41,15 +41,8 @@ AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
|
||||
{
|
||||
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.channels = m_sspecs.channels;
|
||||
m_tspecs.format = m_sspecs.format;
|
||||
m_factor = (double)m_tspecs.rate / (double)m_sspecs.rate;
|
||||
|
||||
int error;
|
||||
@@ -71,9 +64,9 @@ AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
|
||||
|
||||
AUD_SRCResampleReader::~AUD_SRCResampleReader()
|
||||
{
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
|
||||
src_delete(m_src);
|
||||
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
long AUD_SRCResampleReader::doCallback(float** data)
|
||||
@@ -83,7 +76,7 @@ long AUD_SRCResampleReader::doCallback(float** data)
|
||||
|
||||
m_reader->read(length, buffer);
|
||||
|
||||
*data = (float*)buffer;
|
||||
*data = buffer;
|
||||
return length;
|
||||
}
|
||||
|
||||
@@ -110,10 +103,12 @@ AUD_Specs AUD_SRCResampleReader::getSpecs()
|
||||
|
||||
void AUD_SRCResampleReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
if(m_buffer->getSize() < length * m_tspecs.channels * 4)
|
||||
m_buffer->resize(length * m_tspecs.channels * 4);
|
||||
int size = length * AUD_SAMPLE_SIZE(m_tspecs);
|
||||
|
||||
if(m_buffer->getSize() < size)
|
||||
m_buffer->resize(size);
|
||||
|
||||
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>
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* This resampling reader uses libsamplerate for resampling.
|
||||
*/
|
||||
class AUD_SRCResampleReader : public AUD_EffectReader
|
||||
{
|
||||
|
||||
@@ -34,26 +34,6 @@ extern "C" {
|
||||
#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)
|
||||
{
|
||||
// save packet parameters
|
||||
@@ -78,11 +58,11 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
|
||||
// read samples from the packet
|
||||
data_size = buf_size - buf_pos;
|
||||
/*read_length = avcodec_decode_audio3(m_codecCtx,
|
||||
(int16_t*)(buffer->getBuffer()+buf_pos),
|
||||
(int16_t*)(((data_t*)buffer->getBuffer())+buf_pos),
|
||||
&data_size,
|
||||
packet);*/
|
||||
read_length = avcodec_decode_audio2(m_codecCtx,
|
||||
(int16_t*)(buffer->getBuffer()+buf_pos),
|
||||
(int16_t*)(((data_t*)buffer->getBuffer())+buf_pos),
|
||||
&data_size,
|
||||
audio_pkg_data,
|
||||
audio_pkg_size);
|
||||
@@ -101,10 +81,78 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
|
||||
return buf_pos;
|
||||
}
|
||||
|
||||
AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
|
||||
void AUD_FFMPEGReader::init()
|
||||
{
|
||||
m_position = 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;
|
||||
|
||||
// open file
|
||||
@@ -113,66 +161,28 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
|
||||
|
||||
try
|
||||
{
|
||||
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, 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;
|
||||
init();
|
||||
}
|
||||
catch(AUD_Exception)
|
||||
{
|
||||
av_close_input_file(m_formatCtx);
|
||||
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)
|
||||
{
|
||||
m_position = 0;
|
||||
m_pkgbuf_left = 0;
|
||||
m_byteiocontext = (ByteIOContext*)av_mallocz(sizeof(ByteIOContext));
|
||||
AUD_NEW("byteiocontext")
|
||||
m_membuffer = buffer;
|
||||
|
||||
if(init_put_byte(m_byteiocontext, buffer.get()->getBuffer(), buffer.get()->getSize(), 0,
|
||||
NULL, NULL, NULL, NULL) != 0)
|
||||
if(init_put_byte(m_byteiocontext, (data_t*)buffer.get()->getBuffer(),
|
||||
buffer.get()->getSize(), 0, NULL, NULL, NULL, NULL) != 0)
|
||||
AUD_THROW(AUD_ERROR_FILE);
|
||||
|
||||
AVProbeData probe_data;
|
||||
probe_data.filename = "";
|
||||
probe_data.buf = buffer.get()->getBuffer();
|
||||
probe_data.buf = (data_t*)buffer.get()->getBuffer();
|
||||
probe_data.buf_size = buffer.get()->getSize();
|
||||
AVInputFormat* fmt = av_probe_input_format(&probe_data, 1);
|
||||
|
||||
@@ -182,38 +192,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
|
||||
|
||||
try
|
||||
{
|
||||
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 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;
|
||||
init();
|
||||
}
|
||||
catch(AUD_Exception)
|
||||
{
|
||||
@@ -221,11 +200,6 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
|
||||
av_free(m_byteiocontext); AUD_DELETE("byteiocontext")
|
||||
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()
|
||||
@@ -316,7 +290,7 @@ int AUD_FFMPEGReader::getPosition()
|
||||
|
||||
AUD_Specs AUD_FFMPEGReader::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
return m_specs.specs;
|
||||
}
|
||||
|
||||
AUD_ReaderType AUD_FFMPEGReader::getType()
|
||||
@@ -336,11 +310,11 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
|
||||
int data_size = 0;
|
||||
int pkgbuf_pos;
|
||||
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
|
||||
if(m_buffer->getSize() < length*sample_size)
|
||||
m_buffer->resize(length*sample_size);
|
||||
if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(m_specs))
|
||||
m_buffer->resize(length * AUD_SAMPLE_SIZE(m_specs));
|
||||
|
||||
buffer = m_buffer->getBuffer();
|
||||
pkgbuf_pos = m_pkgbuf_left;
|
||||
@@ -350,8 +324,9 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
|
||||
if(pkgbuf_pos > 0)
|
||||
{
|
||||
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
|
||||
memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
|
||||
buffer += data_size;
|
||||
m_convert((data_t*) buffer, (data_t*) m_pkgbuf->getBuffer(),
|
||||
data_size / AUD_FORMAT_SIZE(m_specs.format));
|
||||
buffer += data_size / AUD_FORMAT_SIZE(m_specs.format);
|
||||
left -= data_size/sample_size;
|
||||
}
|
||||
|
||||
@@ -366,8 +341,9 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
|
||||
|
||||
// copy to output buffer
|
||||
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
|
||||
memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
|
||||
buffer += data_size;
|
||||
m_convert((data_t*) buffer, (data_t*) m_pkgbuf->getBuffer(),
|
||||
data_size / AUD_FORMAT_SIZE(m_specs.format));
|
||||
buffer += data_size / AUD_FORMAT_SIZE(m_specs.format);
|
||||
left -= data_size/sample_size;
|
||||
}
|
||||
av_free_packet(&packet);
|
||||
@@ -376,7 +352,8 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
|
||||
if(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);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#ifndef AUD_FFMPEGREADER
|
||||
#define AUD_FFMPEGREADER
|
||||
|
||||
#include "AUD_ConverterFunctions.h"
|
||||
#include "AUD_IReader.h"
|
||||
#include "AUD_Reference.h"
|
||||
class AUD_Buffer;
|
||||
@@ -59,7 +60,7 @@ private:
|
||||
/**
|
||||
* The specification of the audio data.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
AUD_DeviceSpecs m_specs;
|
||||
|
||||
/**
|
||||
* The buffer for package reading.
|
||||
@@ -91,6 +92,11 @@ private:
|
||||
*/
|
||||
int m_stream;
|
||||
|
||||
/**
|
||||
* Converter function.
|
||||
*/
|
||||
AUD_convert_f m_convert;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Initializes the object.
|
||||
*/
|
||||
void init();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new reader.
|
||||
|
||||
@@ -23,43 +23,49 @@
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_SDLMixerFactory.h"
|
||||
#include "AUD_SDLMixerReader.h"
|
||||
#include "AUD_BandPassFactory.h"
|
||||
#include "AUD_BandPassReader.h"
|
||||
|
||||
#include <cstring>
|
||||
AUD_BandPassFactory::AUD_BandPassFactory(AUD_IFactory* factory, float low,
|
||||
float high) :
|
||||
AUD_EffectFactory(factory),
|
||||
m_low(low),
|
||||
m_high(high) {}
|
||||
|
||||
AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs) :
|
||||
AUD_MixerFactory(reader, specs) {}
|
||||
AUD_BandPassFactory::AUD_BandPassFactory(float low, float high) :
|
||||
AUD_EffectFactory(0),
|
||||
m_low(low),
|
||||
m_high(high) {}
|
||||
|
||||
AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs) :
|
||||
AUD_MixerFactory(factory, specs) {}
|
||||
float AUD_BandPassFactory::getLow()
|
||||
{
|
||||
return m_low;
|
||||
}
|
||||
|
||||
AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_Specs specs) :
|
||||
AUD_MixerFactory(specs) {}
|
||||
float AUD_BandPassFactory::getHigh()
|
||||
{
|
||||
return m_high;
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_SDLMixerFactory::createReader()
|
||||
void AUD_BandPassFactory::setLow(float low)
|
||||
{
|
||||
m_low = low;
|
||||
}
|
||||
|
||||
void AUD_BandPassFactory::setHigh(float high)
|
||||
{
|
||||
m_high = high;
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_BandPassFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
AUD_Specs specs = reader->getSpecs();
|
||||
if(memcmp(&m_specs, &specs, sizeof(AUD_Specs)) != 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
reader = new AUD_BandPassReader(reader, m_low, m_high);
|
||||
AUD_NEW("reader")
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
88
intern/audaspace/fftw/AUD_BandPassFactory.h
Normal file
88
intern/audaspace/fftw/AUD_BandPassFactory.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* $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_BANDPASSFACTORY
|
||||
#define AUD_BANDPASSFACTORY
|
||||
|
||||
#include "AUD_EffectFactory.h"
|
||||
|
||||
/**
|
||||
* This factory creates a band pass filter for a sound wave.
|
||||
*/
|
||||
class AUD_BandPassFactory : public AUD_EffectFactory
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The lowest frequency to be passed.
|
||||
*/
|
||||
float m_low;
|
||||
|
||||
/**
|
||||
* The highest frequency to be passed.
|
||||
*/
|
||||
float m_high;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new band pass factory.
|
||||
* \param factory The input factory.
|
||||
* \param low The lowest passed frequency.
|
||||
* \param high The highest passed frequency.
|
||||
*/
|
||||
AUD_BandPassFactory(AUD_IFactory* factory, float low, float high);
|
||||
|
||||
/**
|
||||
* Creates a new band pass factory.
|
||||
* \param low The lowest passed frequency.
|
||||
* \param high The highest passed frequency.
|
||||
*/
|
||||
AUD_BandPassFactory(float low, float high);
|
||||
|
||||
/**
|
||||
* Returns the lowest passed frequency.
|
||||
*/
|
||||
float getLow();
|
||||
|
||||
/**
|
||||
* Returns the highest passed frequency.
|
||||
*/
|
||||
float getHigh();
|
||||
|
||||
/**
|
||||
* Sets the lowest passed frequency.
|
||||
* \param low The lowest passed frequency.
|
||||
*/
|
||||
void setLow(float low);
|
||||
|
||||
/**
|
||||
* Sets the highest passed frequency.
|
||||
* \param high The highest passed frequency.
|
||||
*/
|
||||
void setHigh(float hight);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_BANDPASSFACTORY
|
||||
124
intern/audaspace/fftw/AUD_BandPassReader.cpp
Normal file
124
intern/audaspace/fftw/AUD_BandPassReader.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_BandPassReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
|
||||
AUD_BandPassReader::AUD_BandPassReader(AUD_IReader* reader, float low,
|
||||
float high) :
|
||||
AUD_EffectReader(reader), m_low(low), m_high(high)
|
||||
{
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
m_in = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
m_out = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
m_length = 0;
|
||||
}
|
||||
|
||||
AUD_BandPassReader::~AUD_BandPassReader()
|
||||
{
|
||||
if(m_length != 0)
|
||||
{
|
||||
fftw_destroy_plan(m_forward);
|
||||
fftw_destroy_plan(m_backward);
|
||||
}
|
||||
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
delete m_in; AUD_DELETE("buffer")
|
||||
delete m_out; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
AUD_ReaderType AUD_BandPassReader::getType()
|
||||
{
|
||||
return m_reader->getType();
|
||||
}
|
||||
|
||||
void AUD_BandPassReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
|
||||
m_reader->read(length, buffer);
|
||||
|
||||
if(length > 0)
|
||||
{
|
||||
if(length * AUD_SAMPLE_SIZE(specs) > m_buffer->getSize())
|
||||
m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
|
||||
|
||||
if(length != m_length)
|
||||
{
|
||||
if(m_length != 0)
|
||||
{
|
||||
fftw_destroy_plan(m_forward);
|
||||
fftw_destroy_plan(m_backward);
|
||||
}
|
||||
|
||||
m_length = length;
|
||||
|
||||
if(m_length * sizeof(double) > m_in->getSize())
|
||||
{
|
||||
m_in->resize(m_length * sizeof(double));
|
||||
m_out->resize((m_length / 2 + 1) * sizeof(fftw_complex));
|
||||
}
|
||||
|
||||
m_forward = fftw_plan_dft_r2c_1d(m_length,
|
||||
(double*)m_in->getBuffer(),
|
||||
(fftw_complex*)m_out->getBuffer(),
|
||||
FFTW_ESTIMATE);
|
||||
m_backward = fftw_plan_dft_c2r_1d(m_length,
|
||||
(fftw_complex*)m_out->getBuffer(),
|
||||
(double*)m_in->getBuffer(),
|
||||
FFTW_ESTIMATE);
|
||||
}
|
||||
|
||||
double* target = (double*) m_in->getBuffer();
|
||||
sample_t* target2 = m_buffer->getBuffer();
|
||||
fftw_complex* complex = (fftw_complex*) m_out->getBuffer();
|
||||
float frequency;
|
||||
|
||||
for(int channel = 0; channel < specs.channels; channel++)
|
||||
{
|
||||
for(int i = 0; i < m_length; i++)
|
||||
target[i] = buffer[i * specs.channels + channel];
|
||||
|
||||
fftw_execute(m_forward);
|
||||
|
||||
for(int i = 0; i < m_length / 2 + 1; i++)
|
||||
{
|
||||
frequency = i * specs.rate / (m_length / 2.0f + 1.0f);
|
||||
if((frequency < m_low) || (frequency > m_high))
|
||||
complex[i][0] = complex[i][1] = 0.0;
|
||||
}
|
||||
|
||||
fftw_execute(m_backward);
|
||||
|
||||
for(int i = 0; i < m_length; i++)
|
||||
target2[i * specs.channels + channel] = target[i] / m_length;
|
||||
}
|
||||
}
|
||||
|
||||
buffer = m_buffer->getBuffer();
|
||||
}
|
||||
99
intern/audaspace/fftw/AUD_BandPassReader.h
Normal file
99
intern/audaspace/fftw/AUD_BandPassReader.h
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 *****
|
||||
*/
|
||||
|
||||
#ifndef AUD_BANDPASSREADER
|
||||
#define AUD_BANDPASSREADER
|
||||
|
||||
#include <fftw3.h>
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
* This class only passes a specific frequency band of another reader.
|
||||
*/
|
||||
class AUD_BandPassReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer *m_buffer;
|
||||
|
||||
/**
|
||||
* The input buffer for fourier transformations.
|
||||
*/
|
||||
AUD_Buffer *m_in;
|
||||
|
||||
/**
|
||||
* The output buffer for fourier transformations.
|
||||
*/
|
||||
AUD_Buffer *m_out;
|
||||
|
||||
/**
|
||||
* The lowest passed frequency.
|
||||
*/
|
||||
float m_low;
|
||||
|
||||
/**
|
||||
* The highest passed frequency.
|
||||
*/
|
||||
float m_high;
|
||||
|
||||
/**
|
||||
* The fftw plan for forward transformation.
|
||||
*/
|
||||
fftw_plan m_forward;
|
||||
|
||||
/**
|
||||
* The fftw plan for backward transformation.
|
||||
*/
|
||||
fftw_plan m_backward;
|
||||
|
||||
/**
|
||||
* The length of the plans.
|
||||
*/
|
||||
int m_length;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new band pass reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param low The lowest passed frequency.
|
||||
* \param high The highest passed frequency.
|
||||
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||
*/
|
||||
AUD_BandPassReader(AUD_IReader* reader, float low, float high);
|
||||
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
virtual ~AUD_BandPassReader();
|
||||
|
||||
virtual AUD_ReaderType getType();
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_BANDPASSREADER
|
||||
42
intern/audaspace/fftw/Makefile
Normal file
42
intern/audaspace/fftw/Makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
#
|
||||
|
||||
LIBNAME = aud_fftw
|
||||
DIR = $(OCGDIR)/intern/audaspace
|
||||
|
||||
include nan_compile.mk
|
||||
|
||||
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
|
||||
|
||||
CPPFLAGS += -I../intern
|
||||
CPPFLAGS += -I../FX
|
||||
CPPFLAGS += -I..
|
||||
CPPFLAGS += -I.
|
||||
CPPFLAGS += -I$(BF_FFTW3)/include
|
||||
@@ -27,14 +27,14 @@
|
||||
#include "AUD_Space.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
|
||||
#define AUD_ALIGN(a) (a + 16 - ((long)a & 15))
|
||||
|
||||
AUD_Buffer::AUD_Buffer(int 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()
|
||||
@@ -44,7 +44,7 @@ AUD_Buffer::~AUD_Buffer()
|
||||
|
||||
sample_t* AUD_Buffer::getBuffer()
|
||||
{
|
||||
return AUD_ALIGN(m_buffer);
|
||||
return (sample_t*) AUD_ALIGN(m_buffer);
|
||||
}
|
||||
|
||||
int AUD_Buffer::getSize()
|
||||
@@ -54,7 +54,7 @@ int AUD_Buffer::getSize()
|
||||
|
||||
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
|
||||
if(keep)
|
||||
|
||||
@@ -39,7 +39,7 @@ private:
|
||||
int m_size;
|
||||
|
||||
/// The pointer to the buffer memory.
|
||||
sample_t* m_buffer;
|
||||
data_t* m_buffer;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -79,11 +79,11 @@ void AUD_BufferReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
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 reach
|
||||
if(m_buffer.get()->getSize() < (m_position+length)*sample_size)
|
||||
length = m_buffer.get()->getSize()/sample_size-m_position;
|
||||
// in case the end of the buffer is reached
|
||||
if(m_buffer.get()->getSize() < (m_position + length) * sample_size)
|
||||
length = m_buffer.get()->getSize() / sample_size - m_position;
|
||||
|
||||
if(length < 0)
|
||||
length = 0;
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "AUD_NULLDevice.h"
|
||||
#include "AUD_I3DDevice.h"
|
||||
#include "AUD_FileFactory.h"
|
||||
@@ -32,13 +35,21 @@
|
||||
#include "AUD_PingPongFactory.h"
|
||||
#include "AUD_LoopFactory.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_SourceCaps.h"
|
||||
#include "AUD_IReader.h"
|
||||
|
||||
#ifdef WITH_SDL
|
||||
#include "AUD_SDLDevice.h"
|
||||
#include "AUD_FloatMixer.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENAL
|
||||
@@ -55,7 +66,7 @@ extern "C" {
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <cassert>
|
||||
|
||||
typedef AUD_IFactory AUD_Sound;
|
||||
typedef AUD_ReadDevice AUD_Device;
|
||||
@@ -71,7 +82,7 @@ static AUD_IDevice* AUD_device = NULL;
|
||||
static int AUD_available_devices[4];
|
||||
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
|
||||
av_register_all();
|
||||
@@ -90,12 +101,8 @@ int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize)
|
||||
break;
|
||||
#ifdef WITH_SDL
|
||||
case AUD_SDL_DEVICE:
|
||||
{
|
||||
dev = new AUD_SDLDevice(specs, buffersize);
|
||||
AUD_FloatMixer* mixer = new AUD_FloatMixer();
|
||||
((AUD_SDLDevice*)dev)->setMixer(mixer);
|
||||
break;
|
||||
}
|
||||
dev = new AUD_SDLDevice(specs, buffersize);
|
||||
break;
|
||||
#endif
|
||||
#ifdef WITH_OPENAL
|
||||
case AUD_OPENAL_DEVICE:
|
||||
@@ -177,9 +184,8 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
|
||||
else
|
||||
{
|
||||
info.specs.channels = AUD_CHANNELS_INVALID;
|
||||
info.specs.format = AUD_FORMAT_INVALID;
|
||||
info.specs.rate = AUD_RATE_INVALID;
|
||||
info.length = 0.0;
|
||||
info.length = 0.0f;
|
||||
}
|
||||
|
||||
return info;
|
||||
@@ -424,7 +430,7 @@ float AUD_get3DSetting(AUD_3DSetting setting)
|
||||
catch(AUD_Exception)
|
||||
{
|
||||
}
|
||||
return 0.0;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -519,7 +525,7 @@ int AUD_setSoundPitch(AUD_Handle* handle, float pitch)
|
||||
return false;
|
||||
}
|
||||
|
||||
AUD_Device* AUD_openReadDevice(AUD_Specs specs)
|
||||
AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -578,7 +584,7 @@ int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle,
|
||||
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(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.
|
||||
* \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
|
||||
@@ -304,7 +304,7 @@ extern int AUD_setSoundPitch(AUD_Handle* handle, float pitch);
|
||||
* \param specs The specification of the audio data.
|
||||
* \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.
|
||||
@@ -342,7 +342,7 @@ extern int AUD_setDeviceSoundVolume(AUD_Device* device,
|
||||
* played back currently, in that case the buffer is filled with
|
||||
* 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.
|
||||
@@ -350,6 +350,16 @@ extern int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length);
|
||||
*/
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -29,20 +29,20 @@
|
||||
#include <cstring>
|
||||
|
||||
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IReader* reader,
|
||||
AUD_Specs specs) :
|
||||
AUD_DeviceSpecs specs) :
|
||||
AUD_MixerFactory(reader, specs)
|
||||
{
|
||||
memset(m_mapping, 0, sizeof(m_mapping));
|
||||
}
|
||||
|
||||
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IFactory* factory,
|
||||
AUD_Specs specs) :
|
||||
AUD_DeviceSpecs specs) :
|
||||
AUD_MixerFactory(factory, specs)
|
||||
{
|
||||
memset(m_mapping, 0, sizeof(m_mapping));
|
||||
}
|
||||
|
||||
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_Specs specs) :
|
||||
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_DeviceSpecs specs) :
|
||||
AUD_MixerFactory(specs)
|
||||
{
|
||||
memset(m_mapping, 0, sizeof(m_mapping));
|
||||
|
||||
@@ -41,9 +41,9 @@ private:
|
||||
float **m_mapping[9];
|
||||
|
||||
public:
|
||||
AUD_ChannelMapperFactory(AUD_IReader* reader, AUD_Specs specs);
|
||||
AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_Specs specs);
|
||||
AUD_ChannelMapperFactory(AUD_Specs specs);
|
||||
AUD_ChannelMapperFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
|
||||
AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
|
||||
AUD_ChannelMapperFactory(AUD_DeviceSpecs specs);
|
||||
|
||||
virtual ~AUD_ChannelMapperFactory();
|
||||
|
||||
|
||||
@@ -32,12 +32,6 @@ AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
|
||||
{
|
||||
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;
|
||||
m_rch = m_specs.channels;
|
||||
while(mapping[++channels] != 0);
|
||||
@@ -55,7 +49,8 @@ AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
|
||||
for(i=0; i < m_rch; i++)
|
||||
sum += mapping[channels][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")
|
||||
@@ -89,9 +84,9 @@ void AUD_ChannelMapperReader::read(int & length, sample_t* & buffer)
|
||||
if(m_buffer->getSize() < length * 4 * channels)
|
||||
m_buffer->resize(length * 4 * channels);
|
||||
|
||||
float* in = (float*)buffer;
|
||||
float* out = (float*)m_buffer->getBuffer();
|
||||
float sum;
|
||||
sample_t* in = buffer;
|
||||
sample_t* out = m_buffer->getBuffer();
|
||||
sample_t sum;
|
||||
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
|
||||
@@ -27,14 +27,14 @@
|
||||
#include "AUD_ConverterReader.h"
|
||||
|
||||
AUD_ConverterFactory::AUD_ConverterFactory(AUD_IReader* reader,
|
||||
AUD_Specs specs) :
|
||||
AUD_DeviceSpecs specs) :
|
||||
AUD_MixerFactory(reader, specs) {}
|
||||
|
||||
AUD_ConverterFactory::AUD_ConverterFactory(AUD_IFactory* factory,
|
||||
AUD_Specs specs) :
|
||||
AUD_DeviceSpecs specs) :
|
||||
AUD_MixerFactory(factory, specs) {}
|
||||
|
||||
AUD_ConverterFactory::AUD_ConverterFactory(AUD_Specs specs) :
|
||||
AUD_ConverterFactory::AUD_ConverterFactory(AUD_DeviceSpecs specs) :
|
||||
AUD_MixerFactory(specs) {}
|
||||
|
||||
AUD_IReader* AUD_ConverterFactory::createReader()
|
||||
@@ -43,7 +43,7 @@ AUD_IReader* AUD_ConverterFactory::createReader()
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
if(reader->getSpecs().format != m_specs.format)
|
||||
if(m_specs.format != AUD_FORMAT_FLOAT32)
|
||||
{
|
||||
reader = new AUD_ConverterReader(reader, m_specs);
|
||||
AUD_NEW("reader")
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
class AUD_ConverterFactory : public AUD_MixerFactory
|
||||
{
|
||||
public:
|
||||
AUD_ConverterFactory(AUD_IReader* reader, AUD_Specs specs);
|
||||
AUD_ConverterFactory(AUD_IFactory* factory, AUD_Specs specs);
|
||||
AUD_ConverterFactory(AUD_Specs specs);
|
||||
AUD_ConverterFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
|
||||
AUD_ConverterFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
|
||||
AUD_ConverterFactory(AUD_DeviceSpecs specs);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
@@ -29,21 +29,21 @@
|
||||
#define AUD_U8_0 0x80
|
||||
#define AUD_S16_MAX 0x7FFF
|
||||
#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_MIN 0x80000000
|
||||
#define AUD_S32_FLT 2147483648.0
|
||||
#define AUD_FLT_MAX 1.0
|
||||
#define AUD_FLT_MIN -1.0
|
||||
#define AUD_S32_FLT 2147483648.0f
|
||||
#define AUD_FLT_MAX 1.0f
|
||||
#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;
|
||||
for(int i = 0; i < length; i++)
|
||||
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++)
|
||||
{
|
||||
@@ -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++)
|
||||
{
|
||||
@@ -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;
|
||||
for(int i = 0; i < length; i++)
|
||||
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;
|
||||
for(int i = 0; i < length; i++)
|
||||
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;
|
||||
for(int i = 0; i < length; i++)
|
||||
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;
|
||||
for(int i = 0; i < length; i++)
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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++)
|
||||
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++)
|
||||
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;
|
||||
for(int i = 0; i < length; i++)
|
||||
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;
|
||||
for(int i = 0; i < length; i++)
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
for(int i = 0; i < length; i++)
|
||||
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;
|
||||
for(int i = 0; i < length; i++)
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
for(int i = 0; i < length; i++)
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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 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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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];
|
||||
}
|
||||
|
||||
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 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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
float* t = (float*) target;
|
||||
for(int i = 0; i < length; 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>
|
||||
#endif
|
||||
|
||||
typedef void (*AUD_convert_f)(sample_t* target, sample_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);
|
||||
typedef void (*AUD_convert_f)(data_t* target, data_t* source, int length);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
void AUD_convert_double_float(data_t* target, data_t* source, int length);
|
||||
|
||||
#endif //AUD_CONVERTERFUNCTIONS
|
||||
|
||||
@@ -26,205 +26,37 @@
|
||||
#include "AUD_ConverterReader.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)
|
||||
{
|
||||
m_specs = reader->getSpecs();
|
||||
m_specs.specs = reader->getSpecs();
|
||||
|
||||
int bigendian = 1;
|
||||
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
|
||||
|
||||
switch(m_specs.format)
|
||||
switch(specs.format)
|
||||
{
|
||||
case AUD_FORMAT_U8:
|
||||
switch(specs.format)
|
||||
{
|
||||
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;
|
||||
}
|
||||
m_convert = AUD_convert_float_u8;
|
||||
break;
|
||||
case AUD_FORMAT_S16:
|
||||
switch(specs.format)
|
||||
{
|
||||
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;
|
||||
}
|
||||
m_convert = AUD_convert_float_s16;
|
||||
break;
|
||||
case AUD_FORMAT_S24:
|
||||
if(bigendian)
|
||||
switch(specs.format)
|
||||
{
|
||||
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;
|
||||
}
|
||||
m_convert = AUD_convert_float_s24_be;
|
||||
else
|
||||
switch(specs.format)
|
||||
{
|
||||
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;
|
||||
}
|
||||
m_convert = AUD_convert_float_s24_le;
|
||||
break;
|
||||
case AUD_FORMAT_S32:
|
||||
switch(specs.format)
|
||||
{
|
||||
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;
|
||||
}
|
||||
m_convert = AUD_convert_float_s32;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
switch(specs.format)
|
||||
{
|
||||
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;
|
||||
}
|
||||
m_convert = AUD_convert_copy<float>;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT64:
|
||||
switch(specs.format)
|
||||
{
|
||||
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;
|
||||
}
|
||||
m_convert = AUD_convert_float_double;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -242,7 +74,7 @@ AUD_ConverterReader::~AUD_ConverterReader()
|
||||
|
||||
AUD_Specs AUD_ConverterReader::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
return m_specs.specs;
|
||||
}
|
||||
|
||||
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)
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ private:
|
||||
/**
|
||||
* The target specification.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
AUD_DeviceSpecs m_specs;
|
||||
|
||||
/**
|
||||
* Converter function.
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
* \param specs The target specification.
|
||||
* \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.
|
||||
*/
|
||||
|
||||
@@ -1,172 +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_FloatMixer.h"
|
||||
#include "AUD_ConverterFactory.h"
|
||||
#include "AUD_SRCResampleFactory.h"
|
||||
#include "AUD_ChannelMapperFactory.h"
|
||||
#include "AUD_IReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_FloatMixer::AUD_FloatMixer()
|
||||
{
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
|
||||
m_converter = NULL;
|
||||
m_resampler = NULL;
|
||||
m_mapper = NULL;
|
||||
}
|
||||
|
||||
AUD_FloatMixer::~AUD_FloatMixer()
|
||||
{
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
|
||||
if(m_converter)
|
||||
{
|
||||
delete m_converter; AUD_DELETE("factory")
|
||||
}
|
||||
if(m_resampler)
|
||||
{
|
||||
delete m_resampler; AUD_DELETE("factory")
|
||||
}
|
||||
if(m_mapper)
|
||||
{
|
||||
delete m_mapper; AUD_DELETE("factory")
|
||||
}
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_FloatMixer::prepare(AUD_IReader* reader)
|
||||
{
|
||||
m_converter->setReader(reader);
|
||||
reader = m_converter->createReader();
|
||||
|
||||
m_resampler->setReader(reader);
|
||||
reader = m_resampler->createReader();
|
||||
|
||||
if(reader->getSpecs().channels != m_specs.channels)
|
||||
{
|
||||
m_mapper->setReader(reader);
|
||||
reader = m_mapper->createReader();
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
void AUD_FloatMixer::setSpecs(AUD_Specs specs)
|
||||
{
|
||||
m_specs = specs;
|
||||
|
||||
if(m_converter)
|
||||
{
|
||||
delete m_converter; AUD_DELETE("factory")
|
||||
}
|
||||
if(m_resampler)
|
||||
{
|
||||
delete m_resampler; AUD_DELETE("factory")
|
||||
}
|
||||
if(m_mapper)
|
||||
{
|
||||
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_mapper = new AUD_ChannelMapperFactory(specs); AUD_NEW("factory")
|
||||
|
||||
int bigendian = 1;
|
||||
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
|
||||
|
||||
switch(m_specs.format)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_FloatMixer::add(sample_t* buffer, AUD_Specs specs, int length,
|
||||
float volume)
|
||||
{
|
||||
AUD_FloatMixerBuffer buf;
|
||||
buf.buffer = buffer;
|
||||
buf.length = length;
|
||||
buf.volume = volume;
|
||||
m_buffers.push_back(buf);
|
||||
}
|
||||
|
||||
void AUD_FloatMixer::superpose(sample_t* buffer, int length, float volume)
|
||||
{
|
||||
AUD_FloatMixerBuffer buf;
|
||||
|
||||
int channels = m_specs.channels;
|
||||
|
||||
if(m_buffer->getSize() < length * channels * 4)
|
||||
m_buffer->resize(length * channels * 4);
|
||||
|
||||
float* out = (float*)m_buffer->getBuffer();
|
||||
float* in;
|
||||
|
||||
memset(out, 0, length * channels * 4);
|
||||
|
||||
int end;
|
||||
|
||||
while(!m_buffers.empty())
|
||||
{
|
||||
buf = m_buffers.front();
|
||||
m_buffers.pop_front();
|
||||
|
||||
end = buf.length*channels;
|
||||
in = (float*) buf.buffer;
|
||||
|
||||
for(int i = 0; i < end; i++)
|
||||
out[i] += in[i]*buf.volume * volume;
|
||||
}
|
||||
|
||||
m_convert(buffer, (sample_t*) out, length * channels);
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
virtual AUD_Specs getSpecs()=0;
|
||||
virtual AUD_DeviceSpecs getSpecs()=0;
|
||||
|
||||
/**
|
||||
* Plays a sound source.
|
||||
|
||||
@@ -1,77 +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_IMIXER
|
||||
#define AUD_IMIXER
|
||||
|
||||
#include "AUD_Space.h"
|
||||
class AUD_IReader;
|
||||
|
||||
/**
|
||||
* This class is able to mix audiosignals of different format and channel count.
|
||||
* \note This class doesn't do resampling!
|
||||
*/
|
||||
class AUD_IMixer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Destroys the mixer.
|
||||
*/
|
||||
virtual ~AUD_IMixer(){}
|
||||
|
||||
/**
|
||||
* This funuction prepares a reader for playback.
|
||||
* \param reader The reader to prepare.
|
||||
* \return The reader that should be used for playback.
|
||||
*/
|
||||
virtual AUD_IReader* prepare(AUD_IReader* reader)=0;
|
||||
|
||||
/**
|
||||
* Sets the target specification for superposing.
|
||||
* \param specs The target specification.
|
||||
*/
|
||||
virtual void setSpecs(AUD_Specs specs)=0;
|
||||
|
||||
/**
|
||||
* Adds a buffer for superposition.
|
||||
* \param buffer The buffer to superpose.
|
||||
* \param specs The specification of the buffer.
|
||||
* \param start The start sample of the buffer.
|
||||
* \param length The length of the buffer in samples.
|
||||
* \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,
|
||||
float volume)=0;
|
||||
|
||||
/**
|
||||
* Superposes all added buffers into an output buffer.
|
||||
* \param buffer The target buffer for superposing.
|
||||
* \param length The length of the buffer in samples.
|
||||
* \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;
|
||||
};
|
||||
|
||||
#endif //AUD_IMIXER
|
||||
@@ -49,7 +49,7 @@ AUD_IReader* AUD_MixerFactory::getReader()
|
||||
}
|
||||
|
||||
AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
|
||||
AUD_Specs specs)
|
||||
AUD_DeviceSpecs specs)
|
||||
{
|
||||
m_specs = specs;
|
||||
m_reader = reader;
|
||||
@@ -57,14 +57,14 @@ AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
|
||||
}
|
||||
|
||||
AUD_MixerFactory::AUD_MixerFactory(AUD_IFactory* factory,
|
||||
AUD_Specs specs)
|
||||
AUD_DeviceSpecs specs)
|
||||
{
|
||||
m_specs = specs;
|
||||
m_reader = 0;
|
||||
m_factory = factory;
|
||||
}
|
||||
|
||||
AUD_MixerFactory::AUD_MixerFactory(AUD_Specs specs)
|
||||
AUD_MixerFactory::AUD_MixerFactory(AUD_DeviceSpecs specs)
|
||||
{
|
||||
m_specs = specs;
|
||||
m_reader = 0;
|
||||
@@ -79,12 +79,12 @@ AUD_MixerFactory::~AUD_MixerFactory()
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Specs AUD_MixerFactory::getSpecs()
|
||||
AUD_DeviceSpecs AUD_MixerFactory::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
}
|
||||
|
||||
void AUD_MixerFactory::setSpecs(AUD_Specs specs)
|
||||
void AUD_MixerFactory::setSpecs(AUD_DeviceSpecs specs)
|
||||
{
|
||||
m_specs = specs;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ protected:
|
||||
/**
|
||||
* 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.
|
||||
@@ -63,20 +63,20 @@ public:
|
||||
* \param reader The reader to mix.
|
||||
* \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.
|
||||
* \param factory The factory to create the readers to mix out of.
|
||||
* \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.
|
||||
* \param specs The target specification.
|
||||
*/
|
||||
AUD_MixerFactory(AUD_Specs specs);
|
||||
AUD_MixerFactory(AUD_DeviceSpecs specs);
|
||||
|
||||
/**
|
||||
* Destroys the resampling factory.
|
||||
@@ -86,13 +86,13 @@ public:
|
||||
/**
|
||||
* Returns the target specification for resampling.
|
||||
*/
|
||||
AUD_Specs getSpecs();
|
||||
AUD_DeviceSpecs getSpecs();
|
||||
|
||||
/**
|
||||
* Sets the target specification for resampling.
|
||||
* \param specs The specification.
|
||||
*/
|
||||
void setSpecs(AUD_Specs specs);
|
||||
void setSpecs(AUD_DeviceSpecs specs);
|
||||
|
||||
/**
|
||||
* Sets the reader for resampling.
|
||||
|
||||
@@ -34,7 +34,7 @@ AUD_NULLDevice::AUD_NULLDevice()
|
||||
m_specs.rate = AUD_RATE_INVALID;
|
||||
}
|
||||
|
||||
AUD_Specs AUD_NULLDevice::getSpecs()
|
||||
AUD_DeviceSpecs AUD_NULLDevice::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ private:
|
||||
/**
|
||||
* The specs of the device.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
AUD_DeviceSpecs m_specs;
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
*/
|
||||
AUD_NULLDevice();
|
||||
|
||||
virtual AUD_Specs getSpecs();
|
||||
virtual AUD_DeviceSpecs getSpecs();
|
||||
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
|
||||
virtual bool pause(AUD_Handle* handle);
|
||||
virtual bool resume(AUD_Handle* handle);
|
||||
|
||||
@@ -23,17 +23,17 @@
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_FloatMixer.h"
|
||||
#include "AUD_Mixer.h"
|
||||
#include "AUD_ReadDevice.h"
|
||||
#include "AUD_IReader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_ReadDevice::AUD_ReadDevice(AUD_Specs specs)
|
||||
AUD_ReadDevice::AUD_ReadDevice(AUD_DeviceSpecs 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_playing = false;
|
||||
@@ -46,15 +46,15 @@ AUD_ReadDevice::~AUD_ReadDevice()
|
||||
destroy();
|
||||
}
|
||||
|
||||
bool AUD_ReadDevice::read(sample_t* buffer, int length)
|
||||
bool AUD_ReadDevice::read(data_t* buffer, int length)
|
||||
{
|
||||
if(m_playing)
|
||||
mix(buffer, length);
|
||||
else
|
||||
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
|
||||
memset(buffer, 0, length * AUD_SAMPLE_SIZE(m_specs));
|
||||
memset(buffer, 0, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
|
||||
return m_playing;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
* Creates a new read device.
|
||||
* \param specs The wanted audio specification.
|
||||
*/
|
||||
AUD_ReadDevice(AUD_Specs specs);
|
||||
AUD_ReadDevice(AUD_DeviceSpecs specs);
|
||||
|
||||
/**
|
||||
* Closes the device.
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
* played back currently, in that case the buffer is filled with
|
||||
* silence.
|
||||
*/
|
||||
bool read(sample_t* buffer, int length);
|
||||
bool read(data_t* buffer, int length);
|
||||
};
|
||||
|
||||
#endif //AUD_READDEVICE
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "AUD_SinusReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
@@ -69,8 +69,7 @@ AUD_Specs AUD_SinusReader::getSpecs()
|
||||
{
|
||||
AUD_Specs specs;
|
||||
specs.rate = m_sampleRate;
|
||||
specs.format = AUD_FORMAT_S16;
|
||||
specs.channels = AUD_CHANNELS_STEREO;
|
||||
specs.channels = AUD_CHANNELS_MONO;
|
||||
return specs;
|
||||
}
|
||||
|
||||
@@ -87,18 +86,16 @@ bool AUD_SinusReader::notify(AUD_Message &message)
|
||||
void AUD_SinusReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
// resize if necessary
|
||||
if(m_buffer->getSize() < length*4)
|
||||
m_buffer->resize(length*4);
|
||||
if(m_buffer->getSize() < length * sizeof(sample_t))
|
||||
m_buffer->resize(length * sizeof(sample_t));
|
||||
|
||||
// fill with sine data
|
||||
short* buf = (short*) m_buffer->getBuffer();
|
||||
for(int i=0; i < length; i++)
|
||||
buffer = m_buffer->getBuffer();
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
buf[i*2] = sin((m_position + i) * 2.0 * M_PI * m_frequency /
|
||||
(float)m_sampleRate) * 32700;
|
||||
buf[i*2+1] = buf[i*2];
|
||||
buffer[i] = sin((m_position + i) * 2.0f * M_PI * m_frequency /
|
||||
(float)m_sampleRate);
|
||||
}
|
||||
|
||||
buffer = (sample_t*)buf;
|
||||
m_position += length;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "AUD_SoftwareDevice.h"
|
||||
#include "AUD_IReader.h"
|
||||
#include "AUD_IMixer.h"
|
||||
#include "AUD_Mixer.h"
|
||||
#include "AUD_IFactory.h"
|
||||
#include "AUD_SourceCaps.h"
|
||||
|
||||
@@ -51,7 +51,9 @@ void AUD_SoftwareDevice::create()
|
||||
m_playingSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
|
||||
m_pausedSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
|
||||
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_init(&attr);
|
||||
@@ -90,7 +92,7 @@ void AUD_SoftwareDevice::destroy()
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
}
|
||||
|
||||
void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
|
||||
void AUD_SoftwareDevice::mix(data_t* buffer, int length)
|
||||
{
|
||||
lock();
|
||||
|
||||
@@ -98,7 +100,7 @@ void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
|
||||
AUD_SoftwareHandle* sound;
|
||||
int len;
|
||||
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;
|
||||
|
||||
// for all sounds
|
||||
@@ -114,7 +116,7 @@ void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
|
||||
len = length;
|
||||
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
|
||||
if(len < length)
|
||||
@@ -159,14 +161,7 @@ bool AUD_SoftwareDevice::isValid(AUD_Handle* handle)
|
||||
return false;
|
||||
}
|
||||
|
||||
void AUD_SoftwareDevice::setMixer(AUD_IMixer* mixer)
|
||||
{
|
||||
delete m_mixer; AUD_DELETE("mixer")
|
||||
m_mixer = mixer;
|
||||
mixer->setSpecs(m_specs);
|
||||
}
|
||||
|
||||
AUD_Specs AUD_SoftwareDevice::getSpecs()
|
||||
AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs()
|
||||
{
|
||||
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")
|
||||
sound->keep = keep;
|
||||
sound->reader = reader;
|
||||
sound->volume = 1.0;
|
||||
sound->volume = 1.0f;
|
||||
|
||||
lock();
|
||||
m_playingSounds->push_back(sound);
|
||||
@@ -426,10 +421,10 @@ bool AUD_SoftwareDevice::setCapability(int capability, void *value)
|
||||
case AUD_CAPS_VOLUME:
|
||||
lock();
|
||||
m_volume = *((float*)value);
|
||||
if(m_volume > 1.0)
|
||||
m_volume = 1.0;
|
||||
else if(m_volume < 0.0)
|
||||
m_volume = 0.0;
|
||||
if(m_volume > 1.0f)
|
||||
m_volume = 1.0f;
|
||||
else if(m_volume < 0.0f)
|
||||
m_volume = 0.0f;
|
||||
unlock();
|
||||
return true;
|
||||
case AUD_CAPS_SOURCE_VOLUME:
|
||||
@@ -440,10 +435,10 @@ bool AUD_SoftwareDevice::setCapability(int capability, void *value)
|
||||
{
|
||||
AUD_SoftwareHandle* handle = (AUD_SoftwareHandle*)caps->handle;
|
||||
handle->volume = caps->value;
|
||||
if(handle->volume > 1.0)
|
||||
handle->volume = 1.0;
|
||||
else if(handle->volume < 0.0)
|
||||
handle->volume = 0.0;
|
||||
if(handle->volume > 1.0f)
|
||||
handle->volume = 1.0f;
|
||||
else if(handle->volume < 0.0f)
|
||||
handle->volume = 0.0f;
|
||||
result = true;
|
||||
}
|
||||
unlock();
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include "AUD_IDevice.h"
|
||||
struct AUD_SoftwareHandle;
|
||||
class AUD_IMixer;
|
||||
class AUD_Mixer;
|
||||
|
||||
#include <list>
|
||||
#include <pthread.h>
|
||||
@@ -47,12 +47,12 @@ protected:
|
||||
/**
|
||||
* 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.
|
||||
@@ -69,7 +69,7 @@ protected:
|
||||
* \param buffer The target buffer.
|
||||
* \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.
|
||||
@@ -111,13 +111,7 @@ private:
|
||||
bool isValid(AUD_Handle* handle);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Sets a new mixer.
|
||||
* \param mixer The new mixer.
|
||||
*/
|
||||
void setMixer(AUD_IMixer* mixer);
|
||||
|
||||
virtual AUD_Specs getSpecs();
|
||||
virtual AUD_DeviceSpecs getSpecs();
|
||||
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
|
||||
virtual bool pause(AUD_Handle* handle);
|
||||
virtual bool resume(AUD_Handle* handle);
|
||||
|
||||
@@ -28,8 +28,10 @@
|
||||
|
||||
/// The size of a format in bytes.
|
||||
#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.
|
||||
#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.
|
||||
#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_3DSourceSetting;
|
||||
|
||||
/// Sample pointer type.
|
||||
typedef unsigned char sample_t;
|
||||
/// Sample type.(float samples)
|
||||
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
|
||||
{
|
||||
/// Sample rate in Hz.
|
||||
AUD_SampleRate rate;
|
||||
|
||||
/// Sample format.
|
||||
AUD_SampleFormat format;
|
||||
|
||||
/// Channel count.
|
||||
AUD_Channels channels;
|
||||
} 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.
|
||||
typedef struct
|
||||
{
|
||||
|
||||
@@ -61,9 +61,9 @@ AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_IFactory* factory)
|
||||
// read more
|
||||
length = size-index;
|
||||
reader->read(length, buffer);
|
||||
memcpy(m_buffer.get()->getBuffer()+index*sample_size,
|
||||
memcpy(m_buffer.get()->getBuffer() + index * m_specs.channels,
|
||||
buffer,
|
||||
length*sample_size);
|
||||
length * sample_size);
|
||||
size += AUD_BUFFER_RESIZE_BYTES / sample_size;
|
||||
index += length;
|
||||
}
|
||||
|
||||
@@ -59,9 +59,10 @@ endif
|
||||
ifeq ($(WITH_SNDFILE),true)
|
||||
CPPFLAGS += -DWITH_SNDFILE
|
||||
CPPFLAGS += -I../sndfile
|
||||
CPPFLAGS += -I$(NAN_SNDFILE)/include
|
||||
endif
|
||||
|
||||
CPPFLAGS += -I$(LCGDIR)/samplerate/include/
|
||||
CPPFLAGS += -I$(NAN_SAMPLERATE)/include/
|
||||
CPPFLAGS += -I../ffmpeg
|
||||
CPPFLAGS += -I../FX
|
||||
CPPFLAGS += -I../SDL
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_FloatMixer.h"
|
||||
#include "AUD_Mixer.h"
|
||||
#include "AUD_JackDevice.h"
|
||||
#include "AUD_IReader.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);
|
||||
if(device->m_buffer->getSize() < 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* out;
|
||||
@@ -60,7 +60,7 @@ void AUD_JackDevice::jack_shutdown(void *data)
|
||||
device->m_valid = false;
|
||||
}
|
||||
|
||||
AUD_JackDevice::AUD_JackDevice(AUD_Specs specs)
|
||||
AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs)
|
||||
{
|
||||
if(specs.channels == AUD_CHANNELS_INVALID)
|
||||
specs.channels = AUD_CHANNELS_STEREO;
|
||||
@@ -123,9 +123,6 @@ AUD_JackDevice::AUD_JackDevice(AUD_Specs specs)
|
||||
free(ports);
|
||||
}
|
||||
|
||||
m_mixer = new AUD_FloatMixer(); AUD_NEW("mixer")
|
||||
m_mixer->setSpecs(m_specs);
|
||||
|
||||
m_valid = true;
|
||||
|
||||
create();
|
||||
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
* \param specs The wanted audio specification, where only the channel count is important.
|
||||
* \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.
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
|
||||
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include;..\..\..\..\..\lib\windows\fftw3\include"
|
||||
PreprocessorDefinitions="WIN32,NDEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
@@ -118,7 +118,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
|
||||
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include;..\..\..\..\..\lib\windows\fftw3\include"
|
||||
PreprocessorDefinitions="WIN32,_DEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
@@ -193,7 +193,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
InlineFunctionExpansion="2"
|
||||
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
|
||||
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include;..\..\..\..\..\lib\windows\fftw3\include"
|
||||
PreprocessorDefinitions="WIN32,NDEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
@@ -267,7 +267,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
|
||||
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include;..\..\..\..\..\lib\windows\fftw3\include"
|
||||
PreprocessorDefinitions="WIN32,_DEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
@@ -393,14 +393,6 @@
|
||||
RelativePath="..\..\intern\AUD_FileFactory.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\intern\AUD_FloatMixer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\intern\AUD_FloatMixer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\intern\AUD_I3DDevice.h"
|
||||
>
|
||||
@@ -414,11 +406,31 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\intern\AUD_IMixer.h"
|
||||
RelativePath="..\..\intern\AUD_IReader.h"
|
||||
>
|
||||
</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
|
||||
@@ -517,6 +529,38 @@
|
||||
<Filter
|
||||
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
|
||||
RelativePath="..\..\FX\AUD_DelayFactory.cpp"
|
||||
>
|
||||
@@ -557,6 +601,22 @@
|
||||
RelativePath="..\..\FX\AUD_EffectReader.h"
|
||||
>
|
||||
</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
|
||||
RelativePath="..\..\FX\AUD_FaderFactory.cpp"
|
||||
>
|
||||
@@ -573,6 +633,22 @@
|
||||
RelativePath="..\..\FX\AUD_FaderReader.h"
|
||||
>
|
||||
</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
|
||||
RelativePath="..\..\FX\AUD_LimiterFactory.cpp"
|
||||
>
|
||||
@@ -605,6 +681,22 @@
|
||||
RelativePath="..\..\FX\AUD_LoopReader.h"
|
||||
>
|
||||
</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
|
||||
RelativePath="..\..\FX\AUD_PingPongFactory.cpp"
|
||||
>
|
||||
@@ -629,6 +721,22 @@
|
||||
RelativePath="..\..\FX\AUD_PitchReader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\FX\AUD_RectifyFactory.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\FX\AUD_RectifyFactory.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\FX\AUD_RectifyReader.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\FX\AUD_RectifyReader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\FX\AUD_ReverseFactory.cpp"
|
||||
>
|
||||
@@ -645,6 +753,38 @@
|
||||
RelativePath="..\..\FX\AUD_ReverseReader.h"
|
||||
>
|
||||
</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
|
||||
RelativePath="..\..\FX\AUD_VolumeFactory.cpp"
|
||||
>
|
||||
@@ -685,30 +825,6 @@
|
||||
RelativePath="..\..\SDL\AUD_SDLDevice.h"
|
||||
>
|
||||
</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
|
||||
Name="SRC"
|
||||
@@ -762,6 +878,26 @@
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="fftw"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\fftw\AUD_BandPassFactory.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\fftw\AUD_BandPassFactory.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\fftw\AUD_BandPassReader.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\fftw\AUD_BandPassReader.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
|
||||
@@ -28,31 +28,14 @@
|
||||
|
||||
#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)
|
||||
{
|
||||
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
|
||||
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;
|
||||
|
||||
@@ -72,14 +55,16 @@ sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence, void *user
|
||||
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;
|
||||
|
||||
if(reader->m_memoffset + count > reader->m_membuffer.get()->getSize())
|
||||
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;
|
||||
|
||||
return count;
|
||||
@@ -103,27 +88,11 @@ AUD_SndFileReader::AUD_SndFileReader(const char* filename)
|
||||
AUD_THROW(AUD_ERROR_FILE);
|
||||
|
||||
m_specs.channels = (AUD_Channels) sfinfo.channels;
|
||||
m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
|
||||
m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
|
||||
m_length = sfinfo.frames;
|
||||
m_seekable = sfinfo.seekable;
|
||||
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")
|
||||
}
|
||||
|
||||
@@ -147,27 +116,11 @@ AUD_SndFileReader::AUD_SndFileReader(AUD_Reference<AUD_Buffer> buffer)
|
||||
AUD_THROW(AUD_ERROR_FILE);
|
||||
|
||||
m_specs.channels = (AUD_Channels) sfinfo.channels;
|
||||
m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
|
||||
m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
|
||||
m_length = sfinfo.frames;
|
||||
m_seekable = sfinfo.seekable;
|
||||
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")
|
||||
}
|
||||
|
||||
@@ -227,7 +180,7 @@ void AUD_SndFileReader::read(int & length, sample_t* & buffer)
|
||||
|
||||
buffer = m_buffer->getBuffer();
|
||||
|
||||
length = m_read(m_sndfile, buffer, length);
|
||||
length = sf_readf_float(m_sndfile, buffer, length);
|
||||
|
||||
m_position += length;
|
||||
}
|
||||
|
||||
@@ -70,11 +70,6 @@ private:
|
||||
*/
|
||||
SNDFILE* m_sndfile;
|
||||
|
||||
/**
|
||||
* The reading function.
|
||||
*/
|
||||
sf_read_f m_read;
|
||||
|
||||
/**
|
||||
* The virtual IO structure for memory file reading.
|
||||
*/
|
||||
|
||||
@@ -35,6 +35,7 @@ include nan_compile.mk
|
||||
|
||||
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
|
||||
|
||||
CPPFLAGS += -I$(NAN_SNDFILE)/include
|
||||
CPPFLAGS += -I../intern
|
||||
CPPFLAGS += -I..
|
||||
CPPFLAGS += -I.
|
||||
|
||||
@@ -162,6 +162,8 @@ extern void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,
|
||||
* @param height The height the window.
|
||||
* @param state The state of the window when opened.
|
||||
* @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).
|
||||
*/
|
||||
extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
||||
@@ -172,7 +174,8 @@ extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const int stereoVisual);
|
||||
const int stereoVisual,
|
||||
const GHOST_TUns16 numOfAASamples);
|
||||
|
||||
/**
|
||||
* Returns the window user data.
|
||||
|
||||
@@ -216,14 +216,15 @@ public:
|
||||
* Create a new window.
|
||||
* The new window is added to the list of windows managed.
|
||||
* 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 left The coordinate of the left edge of the window.
|
||||
* @param top The coordinate of the top edge of the window.
|
||||
* @param width The width the window.
|
||||
* @param height The height the window.
|
||||
* @param state The state of the window when opened.
|
||||
* @param type The type of drawing context installed in this window.
|
||||
* @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 top The coordinate of the top edge of the window.
|
||||
* @param width The width the window.
|
||||
* @param height The height the window.
|
||||
* @param state The state of the window when opened.
|
||||
* @param type The type of drawing context installed in this window.
|
||||
* @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
|
||||
* @return The new window (or 0 if creation failed).
|
||||
*/
|
||||
@@ -231,7 +232,8 @@ public:
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
|
||||
GHOST_TWindowState state, GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual,
|
||||
const bool stereoVisual = false,
|
||||
const GHOST_TUns16 numOfAASamples = 0,
|
||||
const GHOST_TEmbedderWindowID parentWindow = 0) = 0;
|
||||
|
||||
/**
|
||||
|
||||
@@ -151,6 +151,7 @@ typedef enum {
|
||||
GHOST_kEventButtonDown, /// Mouse button event
|
||||
GHOST_kEventButtonUp, /// Mouse button event
|
||||
GHOST_kEventWheel, /// Mouse wheel event
|
||||
GHOST_kEventTrackpad, /// Trackpad event
|
||||
|
||||
GHOST_kEventNDOFMotion, /// N degree of freedom device motion event
|
||||
GHOST_kEventNDOFButton, /// N degree of freedom device button event
|
||||
@@ -373,6 +374,28 @@ typedef struct {
|
||||
GHOST_TInt32 z;
|
||||
} GHOST_TEventWheelData;
|
||||
|
||||
typedef enum {
|
||||
GHOST_kTrackpadEventUnknown =0,
|
||||
GHOST_kTrackpadEventScroll,
|
||||
GHOST_kTrackpadEventRotate,
|
||||
GHOST_kTrackpadEventSwipe, /* Reserved, not used for now */
|
||||
GHOST_kTrackpadEventMagnify
|
||||
} GHOST_TTrackpadEventSubTypes;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/** The event subtype */
|
||||
GHOST_TTrackpadEventSubTypes subtype;
|
||||
/** The x-location of the trackpad event */
|
||||
GHOST_TInt32 x;
|
||||
/** The y-location of the trackpad event */
|
||||
GHOST_TInt32 y;
|
||||
/** The x-delta or value of the trackpad event */
|
||||
GHOST_TInt32 deltaX;
|
||||
/** The y-delta (currently only for scroll subtype) of the trackpad event */
|
||||
GHOST_TInt32 deltaY;
|
||||
} GHOST_TEventTrackpadData;
|
||||
|
||||
|
||||
typedef enum {
|
||||
GHOST_kDragnDropTypeUnknown =0,
|
||||
|
||||
@@ -140,7 +140,8 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const int stereoVisual)
|
||||
const int stereoVisual,
|
||||
const GHOST_TUns16 numOfAASamples)
|
||||
{
|
||||
GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
|
||||
bool bstereoVisual;
|
||||
@@ -151,7 +152,7 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
||||
bstereoVisual = false;
|
||||
|
||||
return (GHOST_WindowHandle) system->createWindow(title, left, top, width, height,
|
||||
state, type, bstereoVisual);
|
||||
state, type, bstereoVisual, numOfAASamples);
|
||||
}
|
||||
|
||||
GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle)
|
||||
|
||||
@@ -402,6 +402,7 @@ GHOST_IWindow* GHOST_SystemCarbon::createWindow(
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
bool stereoVisual,
|
||||
const GHOST_TUns16 numOfAASamples,
|
||||
const GHOST_TEmbedderWindowID parentWindow
|
||||
)
|
||||
{
|
||||
|
||||
@@ -115,6 +115,7 @@ public:
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual,
|
||||
const GHOST_TUns16 numOfAASamples = 0,
|
||||
const GHOST_TEmbedderWindowID parentWindow = 0
|
||||
);
|
||||
|
||||
|
||||
@@ -93,13 +93,15 @@ public:
|
||||
* Create a new window.
|
||||
* The new window is added to the list of windows managed.
|
||||
* 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 left The coordinate of the left edge of the window.
|
||||
* @param top The coordinate of the top edge of the window.
|
||||
* @param width The width the window.
|
||||
* @param height The height the window.
|
||||
* @param state The state of the window when opened.
|
||||
* @param type The type of drawing context installed in this window.
|
||||
* @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 top The coordinate of the top edge of the window.
|
||||
* @param width The width the window.
|
||||
* @param height The height the window.
|
||||
* @param state The state of the window when opened.
|
||||
* @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)
|
||||
* @param parentWindow Parent (embedder) window
|
||||
* @return The new window (or 0 if creation failed).
|
||||
*/
|
||||
@@ -111,7 +113,8 @@ public:
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual,
|
||||
const bool stereoVisual = false,
|
||||
const GHOST_TUns16 numOfAASamples = 0,
|
||||
const GHOST_TEmbedderWindowID parentWindow = 0
|
||||
);
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "GHOST_EventCursor.h"
|
||||
#include "GHOST_EventWheel.h"
|
||||
#include "GHOST_EventNDOF.h"
|
||||
#include "GHOST_EventTrackpad.h"
|
||||
#include "GHOST_EventDragnDrop.h"
|
||||
|
||||
#include "GHOST_TimerManager.h"
|
||||
@@ -374,6 +375,43 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar)
|
||||
}
|
||||
|
||||
|
||||
#pragma mark defines for 10.6 api not documented in 10.5
|
||||
#ifndef MAC_OS_X_VERSION_10_6
|
||||
enum {
|
||||
/* The following event types are available on some hardware on 10.5.2 and later */
|
||||
NSEventTypeGesture = 29,
|
||||
NSEventTypeMagnify = 30,
|
||||
NSEventTypeSwipe = 31,
|
||||
NSEventTypeRotate = 18,
|
||||
NSEventTypeBeginGesture = 19,
|
||||
NSEventTypeEndGesture = 20
|
||||
};
|
||||
|
||||
@interface NSEvent(GestureEvents)
|
||||
/* This message is valid for events of type NSEventTypeMagnify, on 10.5.2 or later */
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
|
||||
- (float)magnification; // change in magnification.
|
||||
#else
|
||||
- (CGFloat)magnification; // change in magnification.
|
||||
#endif
|
||||
@end
|
||||
|
||||
@interface NSEvent(SnowLeopardEvents)
|
||||
/* modifier keys currently down. This returns the state of devices combined
|
||||
with synthesized events at the moment, independent of which events
|
||||
have been delivered via the event stream. */
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
|
||||
+ (unsigned int)modifierFlags; //NSUInteger is defined only from 10.5
|
||||
#else
|
||||
+ (NSUInteger)modifierFlags;
|
||||
#endif
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#pragma mark Utility functions
|
||||
|
||||
#define FIRSTFILEBUFLG 512
|
||||
static bool g_hasFirstFile = false;
|
||||
static char g_firstFileBuf[512];
|
||||
@@ -577,7 +615,7 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
|
||||
}
|
||||
|
||||
[NSApp finishLaunching];
|
||||
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
return success;
|
||||
@@ -638,6 +676,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
bool stereoVisual,
|
||||
const GHOST_TUns16 numOfAASamples,
|
||||
const GHOST_TEmbedderWindowID parentWindow
|
||||
)
|
||||
{
|
||||
@@ -653,7 +692,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
|
||||
left = left > contentRect.origin.x ? left : contentRect.origin.x;
|
||||
top = top > contentRect.origin.y ? top : contentRect.origin.y;
|
||||
|
||||
window = new GHOST_WindowCocoa (this, title, left, top, width, height, state, type);
|
||||
window = new GHOST_WindowCocoa (this, title, left, top, width, height, state, type, stereoVisual, numOfAASamples);
|
||||
|
||||
if (window) {
|
||||
if (window->getValid()) {
|
||||
@@ -826,7 +865,9 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
|
||||
case NSScrollWheel:
|
||||
case NSOtherMouseDown:
|
||||
case NSOtherMouseUp:
|
||||
case NSOtherMouseDragged:
|
||||
case NSOtherMouseDragged:
|
||||
case NSEventTypeMagnify:
|
||||
case NSEventTypeRotate:
|
||||
handleMouseEvent(event);
|
||||
break;
|
||||
|
||||
@@ -835,11 +876,9 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
|
||||
handleTabletEvent(event,[event type]);
|
||||
break;
|
||||
|
||||
/* Trackpad features, will need OS X 10.6 for implementation
|
||||
/* Trackpad features, fired only from OS X 10.5.2
|
||||
case NSEventTypeGesture:
|
||||
case NSEventTypeMagnify:
|
||||
case NSEventTypeSwipe:
|
||||
case NSEventTypeRotate:
|
||||
case NSEventTypeBeginGesture:
|
||||
case NSEventTypeEndGesture:
|
||||
break; */
|
||||
@@ -883,11 +922,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
|
||||
#else
|
||||
//If build against an older SDK, check if running on 10.6 to use the correct function
|
||||
if ([NSEvent respondsToSelector:@selector(modifierFlags)]) {
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
|
||||
modifiers = (unsigned int)[NSEvent modifierFlags];
|
||||
#else
|
||||
modifiers = (NSUInteger)[NSEvent modifierFlags];
|
||||
#endif
|
||||
modifiers = [NSEvent modifierFlags];
|
||||
}
|
||||
else {
|
||||
//TODO: need to find a better workaround for the missing cocoa "getModifierFlag" function in 10.4/10.5
|
||||
@@ -1300,16 +1335,53 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
||||
|
||||
case NSScrollWheel:
|
||||
{
|
||||
GHOST_TInt32 delta;
|
||||
|
||||
double deltaF = [event deltaY];
|
||||
if (deltaF == 0.0) break; //discard trackpad delta=0 events
|
||||
|
||||
delta = deltaF > 0.0 ? 1 : -1;
|
||||
pushEvent(new GHOST_EventWheel([event timestamp]*1000, window, delta));
|
||||
/* Send Wheel event if sent from the mouse, trackpad event otherwise */
|
||||
if ([event subtype] == NSMouseEventSubtype) {
|
||||
GHOST_TInt32 delta;
|
||||
|
||||
double deltaF = [event deltaY];
|
||||
if (deltaF == 0.0) break; //discard trackpad delta=0 events
|
||||
|
||||
delta = deltaF > 0.0 ? 1 : -1;
|
||||
pushEvent(new GHOST_EventWheel([event timestamp]*1000, window, delta));
|
||||
}
|
||||
else {
|
||||
NSPoint mousePos = [event locationInWindow];
|
||||
double dx = [event deltaX];
|
||||
double dy = -[event deltaY];
|
||||
|
||||
const double deltaMax = 50.0;
|
||||
|
||||
if ((dx == 0) && (dy == 0)) break;
|
||||
|
||||
/* Quadratic acceleration */
|
||||
dx = dx*(fabs(dx)+0.5);
|
||||
if (dx<0.0) dx-=0.5; else dx+=0.5;
|
||||
if (dx< -deltaMax) dx= -deltaMax; else if (dx>deltaMax) dx=deltaMax;
|
||||
|
||||
dy = dy*(fabs(dy)+0.5);
|
||||
if (dy<0.0) dy-=0.5; else dy+=0.5;
|
||||
if (dy< -deltaMax) dy= -deltaMax; else if (dy>deltaMax) dy=deltaMax;
|
||||
|
||||
pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventScroll, mousePos.x, mousePos.y, dx, dy));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NSEventTypeMagnify:
|
||||
{
|
||||
NSPoint mousePos = [event locationInWindow];
|
||||
pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventMagnify, mousePos.x, mousePos.y,
|
||||
[event magnification]*250.0 + 0.1, 0));
|
||||
}
|
||||
break;
|
||||
|
||||
case NSEventTypeRotate:
|
||||
{
|
||||
NSPoint mousePos = [event locationInWindow];
|
||||
pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventRotate, mousePos.x, mousePos.y,
|
||||
-[event rotation] * 5.0, 0));
|
||||
}
|
||||
default:
|
||||
return GHOST_kFailure;
|
||||
break;
|
||||
|
||||
@@ -190,7 +190,7 @@ GHOST_IWindow* GHOST_SystemWin32::createWindow(
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
|
||||
GHOST_TWindowState state, GHOST_TDrawingContextType type,
|
||||
bool stereoVisual, const GHOST_TEmbedderWindowID parentWindow )
|
||||
bool stereoVisual, const GHOST_TUns16 numOfAASamples, const GHOST_TEmbedderWindowID parentWindow )
|
||||
{
|
||||
GHOST_Window* window = 0;
|
||||
window = new GHOST_WindowWin32 (this, title, left, top, width, height, state, type, stereoVisual);
|
||||
|
||||
@@ -110,6 +110,8 @@ public:
|
||||
* @param height The height the window.
|
||||
* @param state The state of the window when opened.
|
||||
* @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)
|
||||
* @param parentWindow Parent (embedder) window
|
||||
* @return The new window (or 0 if creation failed).
|
||||
*/
|
||||
@@ -117,7 +119,9 @@ public:
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
|
||||
GHOST_TWindowState state, GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual, const GHOST_TEmbedderWindowID parentWindow = 0 );
|
||||
const bool stereoVisual = false,
|
||||
const GHOST_TUns16 numOfAASamples = 0,
|
||||
const GHOST_TEmbedderWindowID parentWindow = 0 );
|
||||
|
||||
/***************************************************************************************
|
||||
** Event management functionality
|
||||
|
||||
@@ -228,6 +228,8 @@ getMainDisplayDimensions(
|
||||
* @param height The height the window.
|
||||
* @param state The state of the window when opened.
|
||||
* @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)
|
||||
* @param parentWindow Parent (embedder) window
|
||||
* @return The new window (or 0 if creation failed).
|
||||
*/
|
||||
@@ -242,6 +244,7 @@ createWindow(
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
bool stereoVisual,
|
||||
const GHOST_TUns16 numOfAASamples,
|
||||
const GHOST_TEmbedderWindowID parentWindow
|
||||
){
|
||||
GHOST_WindowX11 * window = 0;
|
||||
|
||||
@@ -127,6 +127,7 @@ public:
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual,
|
||||
const GHOST_TUns16 numOfAASamples = 0,
|
||||
const GHOST_TEmbedderWindowID parentWindow = 0
|
||||
);
|
||||
|
||||
|
||||
@@ -44,13 +44,15 @@ GHOST_Window::GHOST_Window(
|
||||
GHOST_TInt32 /*left*/, GHOST_TInt32 /*top*/, GHOST_TUns32 width, GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual)
|
||||
const bool stereoVisual,
|
||||
const GHOST_TUns16 numOfAASamples)
|
||||
:
|
||||
m_drawingContextType(type),
|
||||
m_cursorVisible(true),
|
||||
m_cursorGrab(GHOST_kGrabDisable),
|
||||
m_cursorShape(GHOST_kStandardCursorDefault),
|
||||
m_stereoVisual(stereoVisual)
|
||||
m_stereoVisual(stereoVisual),
|
||||
m_numOfAASamples(numOfAASamples)
|
||||
{
|
||||
m_isUnsavedChanges = false;
|
||||
m_canAcceptDragOperation = false;
|
||||
|
||||
@@ -75,14 +75,15 @@ public:
|
||||
* Constructor.
|
||||
* Creates a new window and opens it.
|
||||
* To check if the window was created properly, use the getValid() method.
|
||||
* @param title The text shown in the title bar 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 width The width the window.
|
||||
* @param heigh The height the window.
|
||||
* @param state The state the window is initially opened with.
|
||||
* @param type The type of drawing context installed in this window.
|
||||
* @param stereoVisual Stereo visual for quad buffered stereo.
|
||||
* @param title The text shown in the title bar 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 width The width the window.
|
||||
* @param heigh The height the window.
|
||||
* @param state The state the window is initially opened with.
|
||||
* @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)
|
||||
*/
|
||||
GHOST_Window(
|
||||
const STR_String& title,
|
||||
@@ -92,7 +93,8 @@ public:
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
|
||||
const bool stereoVisual = false);
|
||||
const bool stereoVisual = false,
|
||||
const GHOST_TUns16 numOfAASamples = 0);
|
||||
|
||||
/**
|
||||
* @section Interface inherited from GHOST_IWindow left for derived class
|
||||
@@ -319,6 +321,9 @@ protected:
|
||||
* the graphics h/w
|
||||
*/
|
||||
bool m_stereoVisual;
|
||||
|
||||
/** Number of samples used in anti-aliasing, set to 0 if no AA **/
|
||||
GHOST_TUns16 m_numOfAASamples;
|
||||
|
||||
/** Full-screen width */
|
||||
GHOST_TUns32 m_fullScreenWidth;
|
||||
|
||||
@@ -98,7 +98,8 @@ GHOST_WindowCarbon::GHOST_WindowCarbon(
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual
|
||||
const bool stereoVisual,
|
||||
const GHOST_TUns16 numOfAASamples
|
||||
) :
|
||||
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone),
|
||||
m_windowRef(0),
|
||||
|
||||
@@ -80,7 +80,8 @@ public:
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
|
||||
const bool stereoVisual = false
|
||||
const bool stereoVisual = false,
|
||||
const GHOST_TUns16 numOfAASamples = 0
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,15 +61,16 @@ public:
|
||||
* Constructor.
|
||||
* Creates a new window and opens it.
|
||||
* To check if the window was created properly, use the getValid() method.
|
||||
* @param systemCocoa The associated system class to forward events to
|
||||
* @param title The text shown in the title bar 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 width The width the window.
|
||||
* @param height The height the window.
|
||||
* @param state The state the window is initially opened with.
|
||||
* @param type The type of drawing context installed in this window.
|
||||
* @param stereoVisual Stereo visual for quad buffered stereo.
|
||||
* @param systemCocoa The associated system class to forward events to
|
||||
* @param title The text shown in the title bar 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 width The width the window.
|
||||
* @param height The height the window.
|
||||
* @param state The state the window is initially opened with.
|
||||
* @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)
|
||||
*/
|
||||
GHOST_WindowCocoa(
|
||||
GHOST_SystemCocoa *systemCocoa,
|
||||
@@ -80,7 +81,8 @@ public:
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
|
||||
const bool stereoVisual = false
|
||||
const bool stereoVisual = false,
|
||||
const GHOST_TUns16 numOfAASamples = 0
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,9 +34,11 @@
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
||||
#include <OpenGL/gl.h>
|
||||
/***** Multithreaded opengl code : uncomment for enabling
|
||||
#include <OpenGL/OpenGL.h>
|
||||
*/
|
||||
|
||||
|
||||
#include "GHOST_WindowCocoa.h"
|
||||
#include "GHOST_SystemCocoa.h"
|
||||
@@ -277,14 +279,15 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual
|
||||
const bool stereoVisual, const GHOST_TUns16 numOfAASamples
|
||||
) :
|
||||
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone, stereoVisual),
|
||||
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone, stereoVisual, numOfAASamples),
|
||||
m_customCursor(0)
|
||||
{
|
||||
NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[40];
|
||||
NSOpenGLPixelFormat *pixelFormat = nil;
|
||||
int i;
|
||||
|
||||
|
||||
m_systemCocoa = systemCocoa;
|
||||
m_fullScreen = false;
|
||||
|
||||
@@ -329,13 +332,52 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
|
||||
if (stereoVisual) pixelFormatAttrsWindow[i++] = NSOpenGLPFAStereo;
|
||||
|
||||
if (numOfAASamples>0) {
|
||||
// Multisample anti-aliasing
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFAMultisample;
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFASampleBuffers;
|
||||
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 1;
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFASamples;
|
||||
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) numOfAASamples;
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFANoRecovery;
|
||||
}
|
||||
|
||||
pixelFormatAttrsWindow[i] = (NSOpenGLPixelFormatAttribute) 0;
|
||||
|
||||
|
||||
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow];
|
||||
|
||||
|
||||
//Fall back to no multisampling if Antialiasing init failed
|
||||
if (pixelFormat == nil) {
|
||||
i=0;
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFADoubleBuffer;
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
|
||||
//pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize;
|
||||
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 32;
|
||||
|
||||
if (stereoVisual) pixelFormatAttrsWindow[i++] = NSOpenGLPFAStereo;
|
||||
|
||||
pixelFormatAttrsWindow[i] = (NSOpenGLPixelFormatAttribute) 0;
|
||||
|
||||
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow];
|
||||
|
||||
}
|
||||
|
||||
if (numOfAASamples>0) { //Set m_numOfAASamples to the actual value
|
||||
GLint gli;
|
||||
[pixelFormat getValues:&gli forAttribute:NSOpenGLPFASamples forVirtualScreen:0];
|
||||
if (m_numOfAASamples != (GHOST_TUns16)gli) {
|
||||
m_numOfAASamples = (GHOST_TUns16)gli;
|
||||
printf("GHOST_Window could be created with anti-aliasing of only %i samples\n",m_numOfAASamples);
|
||||
}
|
||||
}
|
||||
|
||||
//Creates the OpenGL View inside the window
|
||||
NSOpenGLPixelFormat *pixelFormat =
|
||||
[[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow];
|
||||
|
||||
m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect
|
||||
pixelFormat:pixelFormat];
|
||||
|
||||
@@ -398,14 +440,7 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
|
||||
|
||||
bool GHOST_WindowCocoa::getValid() const
|
||||
{
|
||||
bool valid;
|
||||
if (!m_fullScreen) {
|
||||
valid = (m_window != 0); //&& ::IsValidWindowPtr(m_windowRef);
|
||||
}
|
||||
else {
|
||||
valid = true;
|
||||
}
|
||||
return valid;
|
||||
return (m_window != 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -842,6 +877,9 @@ GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext()
|
||||
if (m_openGLContext != nil) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[m_openGLContext makeCurrentContext];
|
||||
|
||||
// Disable AA by default
|
||||
if (m_numOfAASamples > 0) glDisable(GL_MULTISAMPLE_ARB);
|
||||
[pool drain];
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
@@ -105,10 +105,11 @@ GHOST_WindowWin32::GHOST_WindowWin32(
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual)
|
||||
const bool stereoVisual,
|
||||
const GHOST_TUns16 numOfAASamples)
|
||||
:
|
||||
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone,
|
||||
stereoVisual),
|
||||
stereoVisual,numOfAASamples),
|
||||
m_system(system),
|
||||
m_hDC(0),
|
||||
m_hGlRc(0),
|
||||
|
||||
@@ -75,6 +75,7 @@ public:
|
||||
* @param state The state the window is initially opened with.
|
||||
* @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)
|
||||
*/
|
||||
GHOST_WindowWin32(
|
||||
GHOST_SystemWin32 * system,
|
||||
@@ -85,7 +86,8 @@ public:
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
|
||||
const bool stereoVisual = false
|
||||
const bool stereoVisual = false,
|
||||
const GHOST_TUns16 numOfAASamples = 0
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -153,9 +153,10 @@ GHOST_WindowX11(
|
||||
GHOST_TWindowState state,
|
||||
const GHOST_TEmbedderWindowID parentWindow,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual
|
||||
const bool stereoVisual,
|
||||
const GHOST_TUns16 numOfAASamples
|
||||
) :
|
||||
GHOST_Window(title,left,top,width,height,state,type,stereoVisual),
|
||||
GHOST_Window(title,left,top,width,height,state,type,stereoVisual,numOfAASamples),
|
||||
m_context(NULL),
|
||||
m_display(display),
|
||||
m_system (system),
|
||||
@@ -168,29 +169,54 @@ GHOST_WindowX11(
|
||||
// Set up the minimum atrributes that we require and see if
|
||||
// X can find us a visual matching those requirements.
|
||||
|
||||
int attributes[40], i = 0;
|
||||
int attributes[40], i, samples;
|
||||
Atom atoms[2];
|
||||
int natom;
|
||||
|
||||
if(m_stereoVisual)
|
||||
attributes[i++] = GLX_STEREO;
|
||||
int natom;
|
||||
int glxVersionMajor, glxVersionMinor; // As in GLX major.minor
|
||||
|
||||
attributes[i++] = GLX_RGBA;
|
||||
attributes[i++] = GLX_DOUBLEBUFFER;
|
||||
attributes[i++] = GLX_RED_SIZE; attributes[i++] = 1;
|
||||
attributes[i++] = GLX_BLUE_SIZE; attributes[i++] = 1;
|
||||
attributes[i++] = GLX_GREEN_SIZE; attributes[i++] = 1;
|
||||
attributes[i++] = GLX_DEPTH_SIZE; attributes[i++] = 1;
|
||||
attributes[i] = None;
|
||||
|
||||
m_visual = glXChooseVisual(m_display, DefaultScreen(m_display), attributes);
|
||||
|
||||
if (m_visual == NULL) {
|
||||
// barf : no visual meeting these requirements could be found.
|
||||
printf("%s:%d: X11 glxChooseVisual() failed for OpenGL, verify working openGL system!\n", __FILE__, __LINE__);
|
||||
if (!glXQueryVersion(m_display, &glxVersionMajor, &glxVersionMinor)) {
|
||||
printf("%s:%d: X11 glXQueryVersion() failed, verify working openGL system!\n", __FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Find the display with highest samples, starting at level requested */
|
||||
for (samples = m_numOfAASamples; samples >= 0; samples--) {
|
||||
i = 0; /* Reusing attributes array, so reset counter */
|
||||
|
||||
if(m_stereoVisual)
|
||||
attributes[i++] = GLX_STEREO;
|
||||
|
||||
attributes[i++] = GLX_RGBA;
|
||||
attributes[i++] = GLX_DOUBLEBUFFER;
|
||||
attributes[i++] = GLX_RED_SIZE; attributes[i++] = 1;
|
||||
attributes[i++] = GLX_BLUE_SIZE; attributes[i++] = 1;
|
||||
attributes[i++] = GLX_GREEN_SIZE; attributes[i++] = 1;
|
||||
attributes[i++] = GLX_DEPTH_SIZE; attributes[i++] = 1;
|
||||
/* GLX >= 1.4 required for multi-sample */
|
||||
if(samples && (glxVersionMajor >= 1) && (glxVersionMinor >= 4)) {
|
||||
attributes[i++] = GLX_SAMPLE_BUFFERS; attributes[i++] = 1;
|
||||
attributes[i++] = GLX_SAMPLES; attributes[i++] = samples;
|
||||
}
|
||||
attributes[i] = None;
|
||||
|
||||
m_visual = glXChooseVisual(m_display, DefaultScreen(m_display), attributes);
|
||||
|
||||
/* Any sample level or even zero, which means oversampling disabled, is good
|
||||
but we need a valid visual to continue */
|
||||
if (m_visual == NULL) {
|
||||
if (samples == 0) {
|
||||
/* All options exhausted, cannot continue */
|
||||
printf("%s:%d: X11 glXChooseVisual() failed, verify working openGL system!\n", __FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (m_numOfAASamples && (m_numOfAASamples > samples)) {
|
||||
printf("%s:%d: oversampling requested %i but using %i samples\n", __FILE__, __LINE__, m_numOfAASamples, samples);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&m_xtablet, 0, sizeof(m_xtablet));
|
||||
|
||||
// Create a bunch of attributes needed to create an X window.
|
||||
@@ -1226,10 +1252,7 @@ GHOST_WindowX11::
|
||||
if(m_xtablet.EraserDevice)
|
||||
XCloseDevice(m_display, m_xtablet.EraserDevice);
|
||||
|
||||
if (m_context) {
|
||||
if (m_context == s_firstContext) {
|
||||
s_firstContext = NULL;
|
||||
}
|
||||
if (m_context != s_firstContext) {
|
||||
glXDestroyContext(m_display, m_context);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ public:
|
||||
* @param parentWindow Parent (embedder) 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)
|
||||
*/
|
||||
GHOST_WindowX11(
|
||||
GHOST_SystemX11 *system,
|
||||
@@ -79,7 +80,8 @@ public:
|
||||
GHOST_TWindowState state,
|
||||
const GHOST_TEmbedderWindowID parentWindow,
|
||||
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
|
||||
const bool stereoVisual = false
|
||||
const bool stereoVisual = false,
|
||||
const GHOST_TUns16 numOfAASamples = 0
|
||||
);
|
||||
|
||||
bool
|
||||
|
||||
@@ -42,7 +42,7 @@ CCSRCS += GHOST_NDOFManager.cpp
|
||||
|
||||
ifeq ($(OS),$(findstring $(OS), "darwin"))
|
||||
ifeq ($(WITH_COCOA), true)
|
||||
OCSRCS += $(wildcard *Cocoa.mm)
|
||||
OCCSRCS += $(wildcard *Cocoa.mm)
|
||||
CPPFLAGS += -DGHOST_COCOA
|
||||
ifeq ($(WITH_QUICKTIME), true)
|
||||
CPPFLAGS += -DWITH_QUICKTIME
|
||||
|
||||
@@ -1071,6 +1071,10 @@
|
||||
RelativePath="..\..\..\source\blender\editors\object\object_add.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\object\object_bake.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\object\object_constraint.c"
|
||||
>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user