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:
authorJörg Müller <nexyon@gmail.com>2014-11-25 00:45:31 +0300
committerJörg Müller <nexyon@gmail.com>2014-11-25 00:48:23 +0300
commitd7a32383c0867a3f8b90792fd1fee01e13349481 (patch)
treeb33f1b9acad5e028bbd22aa10ed448032abb2ce3 /intern/audaspace
parente3b68dbaf809a2370926ecc5739c28f80c0c1310 (diff)
Audaspace: File handle management for audio sequencing
Fixes the problem that for big sequences too many file handles were open at the same time. Changes the playback handles that the audio sequencing code manages to be closed and reopened when needed. The metric used is the current playback position in relation to the strip. If the strip is more than 10 seconds (configurable) away from the playback cursor, the handle is released and reopened when needed. See D915.
Diffstat (limited to 'intern/audaspace')
-rw-r--r--intern/audaspace/intern/AUD_SequencerHandle.cpp253
-rw-r--r--intern/audaspace/intern/AUD_SequencerHandle.h18
2 files changed, 188 insertions, 83 deletions
diff --git a/intern/audaspace/intern/AUD_SequencerHandle.cpp b/intern/audaspace/intern/AUD_SequencerHandle.cpp
index 135c960471c..56cfa0de683 100644
--- a/intern/audaspace/intern/AUD_SequencerHandle.cpp
+++ b/intern/audaspace/intern/AUD_SequencerHandle.cpp
@@ -31,18 +31,92 @@
#include "AUD_ReadDevice.h"
#include "AUD_MutexLock.h"
+#define KEEP_TIME 10
+
+void AUD_SequencerHandle::start()
+{
+ // we already tried to start, aborting
+ if(!m_valid)
+ return;
+
+ // in case the sound is playing, we need to stop first
+ stop();
+
+ AUD_MutexLock lock(*m_entry);
+
+ // let's try playing
+ if(m_entry->m_sound.get())
+ {
+ m_handle = m_device.play(m_entry->m_sound, true);
+ m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle);
+
+ // after starting we have to set the properties, so let's ensure that
+ m_status--;
+ }
+
+ // if the sound could not be played, we invalidate
+ m_valid = m_handle.get();
+}
+
+bool AUD_SequencerHandle::updatePosition(float position)
+{
+ AUD_MutexLock lock(*m_entry);
+
+ if(m_handle.get())
+ {
+ // we currently have a handle, let's check where we are
+ if(position >= m_entry->m_end)
+ {
+ if(position >= m_entry->m_end + KEEP_TIME)
+ // far end, stopping
+ stop();
+ else
+ {
+ // close end, just pausing
+ m_handle->pause();
+ return true;
+ }
+ }
+ else if(position >= m_entry->m_begin)
+ {
+ // inside, resuming
+ m_handle->resume();
+ return true;
+ }
+ else
+ {
+ if(position < m_entry->m_begin - KEEP_TIME)
+ // far beginning, stopping
+ stop();
+ else
+ {
+ // close beginning, just pausing
+ m_handle->pause();
+ return true;
+ }
+ }
+ }
+ else
+ {
+ // we don't have a handle, let's start if we should be playing
+ if(position >= m_entry->m_begin && position <= m_entry->m_end)
+ {
+ start();
+ return m_valid;
+ }
+ }
+
+ return false;
+}
+
AUD_SequencerHandle::AUD_SequencerHandle(boost::shared_ptr<AUD_SequencerEntry> entry, AUD_ReadDevice& device) :
m_entry(entry),
+ m_valid(true),
m_status(0),
m_pos_status(0),
m_sound_status(0),
m_device(device)
{
- if(entry->m_sound.get())
- {
- m_handle = device.play(entry->m_sound, true);
- m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle);
- }
}
AUD_SequencerHandle::~AUD_SequencerHandle()
@@ -63,101 +137,116 @@ void AUD_SequencerHandle::stop()
{
if(m_handle.get())
m_handle->stop();
+ m_handle = boost::shared_ptr<AUD_IHandle>();
+ m_3dhandle = boost::shared_ptr<AUD_I3DHandle>();
}
void AUD_SequencerHandle::update(float position, float frame, float fps)
{
- if(m_handle.get())
+ if(m_sound_status != m_entry->m_sound_status)
{
- AUD_MutexLock lock(*m_entry);
- if(position >= m_entry->m_end)
- m_handle->pause();
- else if(position >= m_entry->m_begin)
- m_handle->resume();
-
- if(m_sound_status != m_entry->m_sound_status)
- {
- if(m_handle.get())
- m_handle->stop();
+ // if a new sound has been set, it's possible to get valid again!
+ m_sound_status = m_entry->m_sound_status;
+ m_valid = true;
- if(m_entry->m_sound.get())
- {
- m_handle = m_device.play(m_entry->m_sound, true);
- m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle);
- }
+ // stop whatever sound has been playing
+ stop();
- m_sound_status = m_entry->m_sound_status;
- m_pos_status--;
- m_status--;
- }
+ // seek starts and seeks to the correct position
+ if(!seek(position))
+ // no handle, aborting
+ return;
+ }
+ else
+ {
+ if(!m_valid)
+ // invalid, aborting
+ return;
- if(m_pos_status != m_entry->m_pos_status)
+ if(m_handle.get())
{
- seek(position);
-
- m_pos_status = m_entry->m_pos_status;
+ // we have a handle, let's update the position
+ if(!updatePosition(position))
+ // lost handle, aborting
+ return;
}
-
- if(m_status != m_entry->m_status)
+ else
{
- m_3dhandle->setRelative(m_entry->m_relative);
- m_3dhandle->setVolumeMaximum(m_entry->m_volume_max);
- m_3dhandle->setVolumeMinimum(m_entry->m_volume_min);
- m_3dhandle->setDistanceMaximum(m_entry->m_distance_max);
- m_3dhandle->setDistanceReference(m_entry->m_distance_reference);
- m_3dhandle->setAttenuation(m_entry->m_attenuation);
- m_3dhandle->setConeAngleOuter(m_entry->m_cone_angle_outer);
- m_3dhandle->setConeAngleInner(m_entry->m_cone_angle_inner);
- m_3dhandle->setConeVolumeOuter(m_entry->m_cone_volume_outer);
-
- m_status = m_entry->m_status;
+ // we don't have a handle, let's see if we can start
+ if(!seek(position))
+ return;
}
+ }
- float value;
-
- m_entry->m_volume.read(frame, &value);
- m_handle->setVolume(value);
- m_entry->m_pitch.read(frame, &value);
- m_handle->setPitch(value);
- m_entry->m_panning.read(frame, &value);
- AUD_SoftwareDevice::setPanning(m_handle.get(), value);
+ AUD_MutexLock lock(*m_entry);
+ if(m_pos_status != m_entry->m_pos_status)
+ {
+ m_pos_status = m_entry->m_pos_status;
- AUD_Vector3 v, v2;
- AUD_Quaternion q;
+ // position changed, need to seek
+ if(!seek(position))
+ // lost handle, aborting
+ return;
+ }
- m_entry->m_orientation.read(frame, q.get());
- m_3dhandle->setSourceOrientation(q);
- m_entry->m_location.read(frame, v.get());
- m_3dhandle->setSourceLocation(v);
- m_entry->m_location.read(frame + 1, v2.get());
- v2 -= v;
- m_3dhandle->setSourceVelocity(v2 * fps);
+ // so far everything alright and handle is there, let's keep going
- if(m_entry->m_muted)
- m_handle->setVolume(0);
+ if(m_status != m_entry->m_status)
+ {
+ m_status = m_entry->m_status;
+
+ m_3dhandle->setRelative(m_entry->m_relative);
+ m_3dhandle->setVolumeMaximum(m_entry->m_volume_max);
+ m_3dhandle->setVolumeMinimum(m_entry->m_volume_min);
+ m_3dhandle->setDistanceMaximum(m_entry->m_distance_max);
+ m_3dhandle->setDistanceReference(m_entry->m_distance_reference);
+ m_3dhandle->setAttenuation(m_entry->m_attenuation);
+ m_3dhandle->setConeAngleOuter(m_entry->m_cone_angle_outer);
+ m_3dhandle->setConeAngleInner(m_entry->m_cone_angle_inner);
+ m_3dhandle->setConeVolumeOuter(m_entry->m_cone_volume_outer);
}
+
+ float value;
+
+ m_entry->m_volume.read(frame, &value);
+ m_handle->setVolume(value);
+ m_entry->m_pitch.read(frame, &value);
+ m_handle->setPitch(value);
+ m_entry->m_panning.read(frame, &value);
+ AUD_SoftwareDevice::setPanning(m_handle.get(), value);
+
+ AUD_Vector3 v, v2;
+ AUD_Quaternion q;
+
+ m_entry->m_orientation.read(frame, q.get());
+ m_3dhandle->setSourceOrientation(q);
+ m_entry->m_location.read(frame, v.get());
+ m_3dhandle->setSourceLocation(v);
+ m_entry->m_location.read(frame + 1, v2.get());
+ v2 -= v;
+ m_3dhandle->setSourceVelocity(v2 * fps);
+
+ if(m_entry->m_muted)
+ m_handle->setVolume(0);
}
-void AUD_SequencerHandle::seek(float position)
+bool AUD_SequencerHandle::seek(float position)
{
- if(m_handle.get())
- {
- AUD_MutexLock lock(*m_entry);
- if(position >= m_entry->m_end)
- {
- m_handle->pause();
- return;
- }
-
- float seekpos = position - m_entry->m_begin;
- if(seekpos < 0)
- seekpos = 0;
- seekpos += m_entry->m_skip;
- m_handle->setPitch(1.0f);
- m_handle->seek(seekpos);
- if(position < m_entry->m_begin)
- m_handle->pause();
- else
- m_handle->resume();
- }
+ if(!m_valid)
+ // sound not valid, aborting
+ return false;
+
+ if(!updatePosition(position))
+ // no handle, aborting
+ return false;
+
+ AUD_MutexLock lock(*m_entry);
+ float seekpos = position - m_entry->m_begin;
+ if(seekpos < 0)
+ seekpos = 0;
+ seekpos += m_entry->m_skip;
+ m_handle->setPitch(1.0f);
+ m_handle->seek(seekpos);
+
+ return true;
}
diff --git a/intern/audaspace/intern/AUD_SequencerHandle.h b/intern/audaspace/intern/AUD_SequencerHandle.h
index 881bbdd43dc..306df4a84b9 100644
--- a/intern/audaspace/intern/AUD_SequencerHandle.h
+++ b/intern/audaspace/intern/AUD_SequencerHandle.h
@@ -51,6 +51,9 @@ private:
/// The 3D handle in the read device.
boost::shared_ptr<AUD_I3DHandle> m_3dhandle;
+ /// Whether the sound is playable.
+ bool m_valid;
+
/// The last read status from the entry.
int m_status;
@@ -63,6 +66,18 @@ private:
/// The read device this handle is played on.
AUD_ReadDevice& m_device;
+ /**
+ * Starts playing back the handle.
+ */
+ void start();
+
+ /**
+ * Updates the handle state depending on position.
+ * \param position Current playback position in seconds.
+ * \return Whether the handle is valid.
+ */
+ bool updatePosition(float position);
+
public:
/**
* Creates a new sequenced handle.
@@ -99,8 +114,9 @@ public:
/**
* Seeks the handle to a specific time position.
* \param position The time to seek to.
+ * \return Whether the handle is valid.
*/
- void seek(float position);
+ bool seek(float position);
};
#endif //__AUD_SEQUENCERHANDLE_H__