Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2013-11-12 22:29:08 +0400
committerJoerg Mueller <nexyon@gmail.com>2013-11-12 22:29:08 +0400
commitc53f80aeed256874c1e2bc683400f816ed80e469 (patch)
treeeae6a91ef9d032cb07b16cb55cc42d1b9de629e3 /intern/audaspace
parent8db4f87546e74c407d3f6eeae73522c9c5996d7a (diff)
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.
Diffstat (limited to 'intern/audaspace')
-rw-r--r--intern/audaspace/intern/AUD_AnimateableProperty.cpp85
-rw-r--r--intern/audaspace/intern/AUD_AnimateableProperty.h14
2 files changed, 95 insertions, 4 deletions
diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.cpp b/intern/audaspace/intern/AUD_AnimateableProperty.cpp
index 0b333e687ff..6d1a307d868 100644
--- a/intern/audaspace/intern/AUD_AnimateableProperty.cpp
+++ b/intern/audaspace/intern/AUD_AnimateableProperty.cpp
@@ -47,6 +47,15 @@ AUD_AnimateableProperty::AUD_AnimateableProperty(int count) :
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()
{
pthread_mutex_destroy(&m_mutex);
@@ -67,6 +76,7 @@ void AUD_AnimateableProperty::write(const float* data)
AUD_MutexLock lock(*this);
m_isAnimated = false;
+ m_unknown.clear();
memcpy(getBuffer(), data, m_count * sizeof(float));
}
@@ -74,18 +84,85 @@ void AUD_AnimateableProperty::write(const float* data, int position, int count)
{
AUD_MutexLock lock(*this);
- m_isAnimated = true;
-
int pos = getSize() / (sizeof(float) * m_count);
+ if(!m_isAnimated)
+ pos = 0;
+
+ m_isAnimated = true;
+
assureSize((count + position) * m_count * sizeof(float), true);
float* buf = getBuffer();
memcpy(buf + position * m_count, data, count * m_count * sizeof(float));
- for(int i = pos; i < position; i++)
- memcpy(buf + i * m_count, buf + (pos - 1) * m_count, m_count * sizeof(float));
+ // have to fill up space between?
+ 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)
diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.h b/intern/audaspace/intern/AUD_AnimateableProperty.h
index 322748ad571..37eb8f84550 100644
--- a/intern/audaspace/intern/AUD_AnimateableProperty.h
+++ b/intern/audaspace/intern/AUD_AnimateableProperty.h
@@ -34,6 +34,7 @@
#include "AUD_ILockable.h"
#include <pthread.h>
+#include <list>
/**
* This class saves animation data for float properties.
@@ -41,6 +42,14 @@
class AUD_AnimateableProperty : private AUD_Buffer, public AUD_ILockable
{
private:
+ struct Unknown {
+ int start;
+ int end;
+
+ Unknown(int start, int end) :
+ start(start), end(end) {}
+ };
+
/// The count of floats for a single property.
const int m_count;
@@ -50,10 +59,15 @@ private:
/// The mutex for locking.
pthread_mutex_t m_mutex;
+ /// The list of unknown buffer areas.
+ std::list<Unknown> m_unknown;
+
// hide copy constructor and operator=
AUD_AnimateableProperty(const AUD_AnimateableProperty&);
AUD_AnimateableProperty& operator=(const AUD_AnimateableProperty&);
+ void updateUnknownCache(int start, int end);
+
public:
/**
* Creates a new animateable property.