Skip to content
Snippets Groups Projects
Commit c53f80ae authored by Joerg Mueller's avatar Joerg Mueller
Browse files

Fix for [#37362] Audio strips sometimes are evaluated incorrectly.

For details see bug comments. The problem was that blender's animation system didn't update the audio animation system anymore due to an optimization. Fixed this in a complex but proper way in the audio animation system, so that it can handle gaps of missing values.
parent 8db4f875
No related branches found
No related tags found
No related merge requests found
...@@ -47,6 +47,15 @@ AUD_AnimateableProperty::AUD_AnimateableProperty(int count) : ...@@ -47,6 +47,15 @@ AUD_AnimateableProperty::AUD_AnimateableProperty(int count) :
pthread_mutexattr_destroy(&attr); pthread_mutexattr_destroy(&attr);
} }
void AUD_AnimateableProperty::updateUnknownCache(int start, int end)
{
float* buf = getBuffer();
for(int i = start; i <= end; i++)
// TODO: maybe first instead of zero order interpolation?
memcpy(buf + i * m_count, buf + (start - 1) * m_count, m_count * sizeof(float));
}
AUD_AnimateableProperty::~AUD_AnimateableProperty() AUD_AnimateableProperty::~AUD_AnimateableProperty()
{ {
pthread_mutex_destroy(&m_mutex); pthread_mutex_destroy(&m_mutex);
...@@ -67,6 +76,7 @@ void AUD_AnimateableProperty::write(const float* data) ...@@ -67,6 +76,7 @@ void AUD_AnimateableProperty::write(const float* data)
AUD_MutexLock lock(*this); AUD_MutexLock lock(*this);
m_isAnimated = false; m_isAnimated = false;
m_unknown.clear();
memcpy(getBuffer(), data, m_count * sizeof(float)); memcpy(getBuffer(), data, m_count * sizeof(float));
} }
...@@ -74,18 +84,85 @@ void AUD_AnimateableProperty::write(const float* data, int position, int count) ...@@ -74,18 +84,85 @@ void AUD_AnimateableProperty::write(const float* data, int position, int count)
{ {
AUD_MutexLock lock(*this); AUD_MutexLock lock(*this);
m_isAnimated = true;
int pos = getSize() / (sizeof(float) * m_count); int pos = getSize() / (sizeof(float) * m_count);
if(!m_isAnimated)
pos = 0;
m_isAnimated = true;
assureSize((count + position) * m_count * sizeof(float), true); assureSize((count + position) * m_count * sizeof(float), true);
float* buf = getBuffer(); float* buf = getBuffer();
memcpy(buf + position * m_count, data, count * m_count * sizeof(float)); memcpy(buf + position * m_count, data, count * m_count * sizeof(float));
for(int i = pos; i < position; i++) // have to fill up space between?
memcpy(buf + i * m_count, buf + (pos - 1) * m_count, m_count * sizeof(float)); if(pos < position)
{
m_unknown.push_back(Unknown(pos, position - 1));
if(pos == 0)
{
memset(buf, 0, position * m_count * sizeof(float));
}
else
updateUnknownCache(pos, position - 1);
}
// otherwise it's not at the end, let's check if some unknown part got filled
else
{
for(std::list<Unknown>::iterator it = m_unknown.begin(); it != m_unknown.end(); it++)
{
// unknown area before position
if(it->end < position)
continue;
// we're after the new area, let's stop
if(it->start >= position + count)
break;
// we have an intersection, now 4 cases:
// the start is included
if(position <= it->start)
{
// the end is included
if(position + count > it->end)
{
// simply delete
std::list<Unknown>::iterator it2 = it;
it++;
m_unknown.erase(it2);
}
// the end is excluded, a second part remains
else
{
// update second part
it->start = position + count;
updateUnknownCache(it->start, it->end);
break;
}
}
// start is excluded, a first part remains
else
{
// the end is included
if(position + count > it->end)
{
// update first part
it->end = position - 1;
}
// the end is excluded, a second part remains
else
{
// add another item and update both parts
m_unknown.insert(it, Unknown(it->start, position - 1));
it->start = position + count;
updateUnknownCache(it->start, it->end);
}
}
}
}
} }
void AUD_AnimateableProperty::read(float position, float* out) void AUD_AnimateableProperty::read(float position, float* out)
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "AUD_ILockable.h" #include "AUD_ILockable.h"
#include <pthread.h> #include <pthread.h>
#include <list>
/** /**
* This class saves animation data for float properties. * This class saves animation data for float properties.
...@@ -41,6 +42,14 @@ ...@@ -41,6 +42,14 @@
class AUD_AnimateableProperty : private AUD_Buffer, public AUD_ILockable class AUD_AnimateableProperty : private AUD_Buffer, public AUD_ILockable
{ {
private: private:
struct Unknown {
int start;
int end;
Unknown(int start, int end) :
start(start), end(end) {}
};
/// The count of floats for a single property. /// The count of floats for a single property.
const int m_count; const int m_count;
...@@ -50,10 +59,15 @@ private: ...@@ -50,10 +59,15 @@ private:
/// The mutex for locking. /// The mutex for locking.
pthread_mutex_t m_mutex; pthread_mutex_t m_mutex;
/// The list of unknown buffer areas.
std::list<Unknown> m_unknown;
// hide copy constructor and operator= // hide copy constructor and operator=
AUD_AnimateableProperty(const AUD_AnimateableProperty&); AUD_AnimateableProperty(const AUD_AnimateableProperty&);
AUD_AnimateableProperty& operator=(const AUD_AnimateableProperty&); AUD_AnimateableProperty& operator=(const AUD_AnimateableProperty&);
void updateUnknownCache(int start, int end);
public: public:
/** /**
* Creates a new animateable property. * Creates a new animateable property.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment