forked from bartvdbraak/blender
3D Audio GSoC:
High quality resampling on mixdown, linear for playback. * Lots of improvements and fixes for the JOS resampler, now it works fine! * High quality filter coefficients for the JOS resampler (sorry for the 5 MB source file). * Fix for GE orientation bug. Note: moto uses x,y,z,w quaternion storage, while rest of blender uses w,x,y,z. * Minor changes/fixes.
This commit is contained in:
parent
cbbbf31315
commit
a458de88b6
@ -1182,7 +1182,7 @@ const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int lengt
|
||||
AUD_SequencerFactory* f = dynamic_cast<AUD_SequencerFactory*>(sound->get());
|
||||
|
||||
f->setSpecs(specs.specs);
|
||||
AUD_Reference<AUD_IReader> reader = f->createReader();
|
||||
AUD_Reference<AUD_IReader> reader = f->createQualityReader();
|
||||
reader->seek(start);
|
||||
AUD_Reference<AUD_IWriter> writer = AUD_FileWriter::createWriter(filename, specs, format, codec, bitrate);
|
||||
AUD_FileWriter::writeReader(reader, writer, length, buffersize);
|
||||
@ -1195,6 +1195,28 @@ const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int lengt
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, float start)
|
||||
{
|
||||
try
|
||||
{
|
||||
AUD_ReadDevice* device = new AUD_ReadDevice(specs);
|
||||
device->setQuality(true);
|
||||
device->setVolume(volume);
|
||||
|
||||
dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->setSpecs(specs.specs);
|
||||
|
||||
AUD_Handle handle = device->play(*sequencer);
|
||||
if(!handle.isNull())
|
||||
handle->seek(start);
|
||||
|
||||
return new AUD_Device(device);
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Reference<AUD_IDevice> AUD_getDevice()
|
||||
{
|
||||
return AUD_device;
|
||||
|
@ -527,6 +527,8 @@ extern void* AUD_getSet(void* set);
|
||||
|
||||
extern const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
|
||||
|
||||
extern AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, float start);
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
extern PyObject* AUD_getPythonFactory(AUD_Sound* sound);
|
||||
|
||||
|
@ -38,7 +38,6 @@
|
||||
#endif
|
||||
|
||||
#include "AUD_FileFactory.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
#include "AUD_IFactory.h"
|
||||
#include "AUD_Reference.h"
|
||||
class AUD_Buffer;
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -41,13 +41,11 @@
|
||||
class AUD_JOSResampleReader : public AUD_ResampleReader
|
||||
{
|
||||
private:
|
||||
static const unsigned int m_nL = 9;
|
||||
static const unsigned int m_nN = 23;
|
||||
static const unsigned int m_Nz = 32;
|
||||
static const unsigned int m_L = 1 << m_nL;
|
||||
static const unsigned int m_NN = 1 << m_nN;
|
||||
typedef void (AUD_JOSResampleReader::*AUD_resample_f)(double target_factor, int length, sample_t* buffer);
|
||||
|
||||
static const int m_len = 292874;
|
||||
static const int m_L = 2048;
|
||||
static const float m_coeff[];
|
||||
static const float m_diff[];
|
||||
|
||||
/**
|
||||
* The reader channels.
|
||||
@ -62,25 +60,44 @@ private:
|
||||
/**
|
||||
* The subsample position in the cache.
|
||||
*/
|
||||
unsigned int m_P;
|
||||
double m_P;
|
||||
|
||||
/**
|
||||
* The input data buffer.
|
||||
*/
|
||||
AUD_Buffer m_buffer;
|
||||
|
||||
/**
|
||||
* Double buffer for the sums.
|
||||
*/
|
||||
AUD_Buffer m_sums;
|
||||
|
||||
/**
|
||||
* How many samples in the cache are valid.
|
||||
*/
|
||||
int m_cache_valid;
|
||||
|
||||
/**
|
||||
* Resample function.
|
||||
*/
|
||||
AUD_resample_f m_resample;
|
||||
|
||||
/**
|
||||
* Last resampling factor.
|
||||
*/
|
||||
double m_last_factor;
|
||||
|
||||
// hide copy constructor and operator=
|
||||
AUD_JOSResampleReader(const AUD_JOSResampleReader&);
|
||||
AUD_JOSResampleReader& operator=(const AUD_JOSResampleReader&);
|
||||
|
||||
void reset();
|
||||
|
||||
void updateBuffer(int size, float factor, int samplesize);
|
||||
void updateBuffer(int size, double factor, int samplesize);
|
||||
|
||||
void resample(double target_factor, int length, sample_t* buffer);
|
||||
void resample_mono(double target_factor, int length, sample_t* buffer);
|
||||
void resample_stereo(double target_factor, int length, sample_t* buffer);
|
||||
|
||||
public:
|
||||
/**
|
||||
|
29295
intern/audaspace/intern/AUD_JOSResampleReaderCoeff.cpp
Normal file
29295
intern/audaspace/intern/AUD_JOSResampleReaderCoeff.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -196,3 +196,8 @@ AUD_Reference<AUD_IReader> AUD_SequencerFactory::createReader()
|
||||
{
|
||||
return new AUD_SequencerReader(this);
|
||||
}
|
||||
|
||||
AUD_Reference<AUD_IReader> AUD_SequencerFactory::createQualityReader()
|
||||
{
|
||||
return new AUD_SequencerReader(this, true);
|
||||
}
|
||||
|
@ -110,6 +110,8 @@ public:
|
||||
void remove(AUD_Reference<AUD_SequencerEntry> entry);
|
||||
|
||||
virtual AUD_Reference<AUD_IReader> createReader();
|
||||
|
||||
AUD_Reference<AUD_IReader> createQualityReader();
|
||||
};
|
||||
|
||||
#endif //AUD_SEQUENCERFACTORY
|
||||
|
@ -34,9 +34,10 @@
|
||||
typedef std::list<AUD_Reference<AUD_SequencerHandle> >::iterator AUD_HandleIterator;
|
||||
typedef std::list<AUD_Reference<AUD_SequencerEntry> >::iterator AUD_EntryIterator;
|
||||
|
||||
AUD_SequencerReader::AUD_SequencerReader(AUD_Reference<AUD_SequencerFactory> factory) :
|
||||
AUD_SequencerReader::AUD_SequencerReader(AUD_Reference<AUD_SequencerFactory> factory, bool quality) :
|
||||
m_position(0), m_device(factory->m_specs), m_factory(factory), m_status(0), m_entry_status(0)
|
||||
{
|
||||
m_device.setQuality(quality);
|
||||
}
|
||||
|
||||
AUD_SequencerReader::~AUD_SequencerReader()
|
||||
|
@ -73,7 +73,7 @@ public:
|
||||
* \param reader The reader to mix.
|
||||
* \param specs The target specification.
|
||||
*/
|
||||
AUD_SequencerReader(AUD_Reference<AUD_SequencerFactory> factory);
|
||||
AUD_SequencerReader(AUD_Reference<AUD_SequencerFactory> factory, bool quality = false);
|
||||
|
||||
/**
|
||||
* Destroys the reader.
|
||||
|
@ -33,11 +33,8 @@
|
||||
#include "AUD_IReader.h"
|
||||
#include "AUD_Mixer.h"
|
||||
#include "AUD_IFactory.h"
|
||||
#ifdef WITH_SAMPLERATE
|
||||
#include "AUD_SRCResampleReader.h"
|
||||
#else
|
||||
#include "AUD_JOSResampleReader.h"
|
||||
#include "AUD_LinearResampleReader.h"
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
@ -665,6 +662,7 @@ void AUD_SoftwareDevice::create()
|
||||
m_doppler_factor = 1.0f;
|
||||
m_distance_model = AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
|
||||
m_flags = 0;
|
||||
m_quality = false;
|
||||
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
@ -701,6 +699,7 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
|
||||
int pos;
|
||||
bool eos;
|
||||
std::list<AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> > stopSounds;
|
||||
std::list<AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> > pauseSounds;
|
||||
sample_t* buf = m_buffer.getBuffer();
|
||||
|
||||
m_mixer->clear(length);
|
||||
@ -752,7 +751,7 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
|
||||
sound->m_stop(sound->m_stop_data);
|
||||
|
||||
if(sound->m_keep)
|
||||
sound->pause();
|
||||
pauseSounds.push_back(sound);
|
||||
else
|
||||
stopSounds.push_back(sound);
|
||||
}
|
||||
@ -768,6 +767,13 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
|
||||
stopSounds.pop_front();
|
||||
sound->stop();
|
||||
}
|
||||
|
||||
while(!pauseSounds.empty())
|
||||
{
|
||||
sound = pauseSounds.front();
|
||||
pauseSounds.pop_front();
|
||||
sound->pause();
|
||||
}
|
||||
}
|
||||
|
||||
unlock();
|
||||
@ -779,6 +785,11 @@ void AUD_SoftwareDevice::setPanning(AUD_IHandle* handle, float pan)
|
||||
h->m_user_pan = pan;
|
||||
}
|
||||
|
||||
void AUD_SoftwareDevice::setQuality(bool quality)
|
||||
{
|
||||
m_quality = quality;
|
||||
}
|
||||
|
||||
void AUD_SoftwareDevice::setSpecs(AUD_Specs specs)
|
||||
{
|
||||
m_specs.specs = specs;
|
||||
@ -806,11 +817,10 @@ AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> r
|
||||
AUD_Reference<AUD_ResampleReader> resampler;
|
||||
|
||||
// resample
|
||||
#ifdef WITH_SAMPLERATE
|
||||
resampler = new AUD_SRCResampleReader(reader, m_specs.specs);
|
||||
#else
|
||||
if(m_quality)
|
||||
resampler = new AUD_JOSResampleReader(reader, m_specs.specs);
|
||||
else
|
||||
resampler = new AUD_LinearResampleReader(reader, m_specs.specs);
|
||||
#endif
|
||||
reader = AUD_Reference<AUD_IReader>(resampler);
|
||||
|
||||
// rechannel
|
||||
|
@ -203,6 +203,11 @@ protected:
|
||||
*/
|
||||
AUD_Reference<AUD_Mixer> m_mixer;
|
||||
|
||||
/**
|
||||
* Whether to do high or low quality resampling.
|
||||
*/
|
||||
bool m_quality;
|
||||
|
||||
/**
|
||||
* Initializes member variables.
|
||||
*/
|
||||
@ -283,6 +288,7 @@ private:
|
||||
public:
|
||||
|
||||
static void setPanning(AUD_IHandle* handle, float pan);
|
||||
void setQuality(bool quality);
|
||||
|
||||
virtual AUD_DeviceSpecs getSpecs() const;
|
||||
virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
|
||||
|
@ -31,7 +31,6 @@
|
||||
|
||||
#include "AUD_SndFileFactory.h"
|
||||
#include "AUD_SndFileReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
#include "AUD_IFactory.h"
|
||||
#include "AUD_Reference.h"
|
||||
class AUD_Buffer;
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -372,14 +372,7 @@ void sound_load(struct Main *bmain, struct bSound* sound)
|
||||
|
||||
AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume)
|
||||
{
|
||||
AUD_Device* mixdown = AUD_openReadDevice(specs);
|
||||
|
||||
AUD_setDeviceVolume(mixdown, volume);
|
||||
|
||||
AUD_setSequencerSpecs(scene->sound_scene, specs.specs);
|
||||
AUD_freeHandle(AUD_playDevice(mixdown, scene->sound_scene, start / FPS));
|
||||
|
||||
return mixdown;
|
||||
return AUD_openMixdownDevice(specs, scene->sound_scene, volume, start / FPS);
|
||||
}
|
||||
|
||||
void sound_create_scene(struct Scene *scene)
|
||||
|
@ -1016,15 +1016,15 @@ void KX_KetsjiEngine::DoSound(KX_Scene* scene)
|
||||
if(dev)
|
||||
{
|
||||
AUD_Vector3 v;
|
||||
AUD_Quaternion q;
|
||||
float q[4];
|
||||
cam->NodeGetWorldPosition().getValue(v.get());
|
||||
dev->setListenerLocation(v);
|
||||
|
||||
cam->GetLinearVelocity().getValue(v.get());
|
||||
dev->setListenerVelocity(v);
|
||||
|
||||
cam->NodeGetWorldOrientation().getRotation().getValue(q.get());
|
||||
dev->setListenerOrientation(q);
|
||||
cam->NodeGetWorldOrientation().getRotation().getValue(q);
|
||||
dev->setListenerOrientation(AUD_Quaternion(q[3], q[0], q[1], q[2]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,14 +224,14 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
|
||||
{
|
||||
KX_GameObject* obj = (KX_GameObject*)this->GetParent();
|
||||
AUD_Vector3 v;
|
||||
AUD_Quaternion q;
|
||||
float q[4];
|
||||
|
||||
obj->NodeGetWorldPosition().getValue(v.get());
|
||||
handle3d->setSourceLocation(v);
|
||||
obj->GetLinearVelocity().getValue(v.get());
|
||||
handle3d->setSourceVelocity(v);
|
||||
obj->NodeGetWorldOrientation().getRotation().getValue(q.get());
|
||||
handle3d->setSourceOrientation(q);
|
||||
obj->NodeGetWorldOrientation().getRotation().getValue(q);
|
||||
handle3d->setSourceOrientation(AUD_Quaternion(q[3], q[0], q[1], q[2]));
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user