[Bf-blender-cvs] [d10e80f] gooseberry: Attempted fix for OpenAL synchronization.

Antony Riakiotakis noreply at git.blender.org
Fri Mar 6 17:23:06 CET 2015


Commit: d10e80fe792c1c8f00c9c7ce4409002a4515570d
Author: Antony Riakiotakis
Date:   Fri Mar 6 17:22:54 2015 +0100
Branches: gooseberry
https://developer.blender.org/rBd10e80fe792c1c8f00c9c7ce4409002a4515570d

Attempted fix for OpenAL synchronization.

This hit animators already, basically when using sound sync we can
hit negative frames. This happens because we always subtracted the full
range of the triple buffer size from the timing, even when buffers were
flushed.

Also, old code read the offset from the offset of the reader. The
problem here, is that due to threading there is a time offset between
the when this offset is set and when it is offloaded to the buffers,
which means that we could get quite some variance between time
reporting.

Now sounds keep a private byte offset which is incremented right before
invalidating old buffers. This should make the combination of OpenAL
time report + byte offset more accurate. For even more accuracy we might
spinlock while updating those values but for now left it as is for fear
of the lock interfering with frame update performance. We can try to be
smarter here, storing old value while update is happening, and use
trylock and the old values if it fails but for now commit the simple
version.

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

M	intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
M	intern/audaspace/OpenAL/AUD_OpenALDevice.h
M	source/blender/blenkernel/intern/sound.c

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

diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index d055c13..434928c 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -97,7 +97,7 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::pause(bool keep)
 	return false;}
 
 AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, boost::shared_ptr<AUD_IReader> reader, bool keep) :
-	m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format), m_current(0),
+	m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format), m_current(0), m_bytepos(0),
 	m_eos(false), m_loopcount(0), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING),
 	m_device(device)
 {
@@ -208,6 +208,8 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::stop()
 	if(!m_isBuffered)
 		alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
 
+	m_bytepos = 0;
+
 	for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
 	{
 		if(it->get() == this)
@@ -269,7 +271,8 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position)
 		alSourcef(m_source, AL_SEC_OFFSET, position);
 	else
 	{
-		m_reader->seek((int)(position * m_reader->getSpecs().rate));
+		int offset = (int)(position * m_reader->getSpecs().rate);
+		m_reader->seek(offset);
 		m_eos = false;
 
 		ALint info;
@@ -315,10 +318,14 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position)
 					m_eos = false;
 
 				alSourceQueueBuffers(m_source, CYCLE_BUFFERS, m_buffers);
+				m_bytepos = offset;
 			}
 
 			alSourceRewind(m_source);
 		}
+		else {
+			m_bytepos = offset;
+		}
 	}
 
 	if(m_status == AUD_STATUS_STOPPED)
@@ -344,8 +351,7 @@ float AUD_OpenALDevice::AUD_OpenALHandle::getPosition()
 	if(!m_isBuffered)
 	{
 		AUD_Specs specs = m_reader->getSpecs();
-		position += (m_reader->getPosition() - m_device->m_buffersize *
-					 CYCLE_BUFFERS) / (float)specs.rate;
+		position += (m_bytepos) / specs.rate;
 	}
 
 	return position;
@@ -950,6 +956,7 @@ void AUD_OpenALDevice::updateStreams()
 
 								// unqueue buffer (warning: this might fail for slow early returning sources (none exist so far) if the buffer was not queued due to recent changes - has to be tested)
 								alSourceUnqueueBuffers(sound->m_source, 1, &sound->m_buffers[sound->m_current]);
+								sound->m_bytepos += length;
 								ALenum err;
 								if((err = alGetError()) != AL_NO_ERROR)
 								{
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
index f0e4782..142d482 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
@@ -75,6 +75,8 @@ private:
 		/// The first buffer to be read next.
 		int m_current;
 
+		/// Amount of buffers already passed to OpenAL for processing. Used for proper timing
+		unsigned int m_bytepos;
 		/// Whether the stream doesn't return any more data.
 		bool m_eos;
 
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index b9d7066..6acd727 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -621,7 +621,7 @@ void sound_seek_scene(struct Main *bmain, struct Scene *scene)
 		}
 	}
 
-	if (scene->audio.flag & AUDIO_SCRUB && !animation_playing) {
+	if ((scene->audio.flag & AUDIO_SCRUB) && !animation_playing) {
 		if (scene->audio.flag & AUDIO_SYNC) {
 			AUD_seek(scene->sound_scene_handle, cur_time);
 			AUD_seekSequencer(scene->sound_scene_handle, cur_time);




More information about the Bf-blender-cvs mailing list