[Bf-blender-cvs] [d7a3238] master: Audaspace: File handle management for audio sequencing

Jörg Müller noreply at git.blender.org
Mon Nov 24 22:48:42 CET 2014


Commit: d7a32383c0867a3f8b90792fd1fee01e13349481
Author: Jörg Müller
Date:   Tue Nov 25 10:45:31 2014 +1300
Branches: master
https://developer.blender.org/rBd7a32383c0867a3f8b90792fd1fee01e13349481

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.

===================================================================

M	intern/audaspace/intern/AUD_SequencerHandle.cpp
M	intern/audaspace/intern/AUD_SequencerHandle.h

===================================================================

diff --git a/intern/audaspace/intern/AUD_SequencerHandle.cpp b/intern/audaspace/intern/AUD_SequencerHandle.cpp
index 135c960..56cfa0d 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 881bbdd..306df4a 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__




More information about the Bf-blender-cvs mailing list