[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [27060] trunk/blender: 2.5 Audio:

Joerg Mueller nexyon at gmail.com
Sun Feb 21 19:01:41 CET 2010


Revision: 27060
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27060
Author:   nexyon
Date:     2010-02-21 19:01:41 +0100 (Sun, 21 Feb 2010)

Log Message:
-----------
2.5 Audio:

* Jack Transport support!
* Minor sequencer audio corrections.

Modified Paths:
--------------
    trunk/blender/intern/audaspace/intern/AUD_C-API.cpp
    trunk/blender/intern/audaspace/intern/AUD_C-API.h
    trunk/blender/intern/audaspace/jack/AUD_JackDevice.cpp
    trunk/blender/intern/audaspace/jack/AUD_JackDevice.h
    trunk/blender/source/blender/blenkernel/BKE_sound.h
    trunk/blender/source/blender/blenkernel/intern/sequencer.c
    trunk/blender/source/blender/blenkernel/intern/sound.c
    trunk/blender/source/blender/editors/include/ED_screen.h
    trunk/blender/source/blender/editors/screen/screen_ops.c
    trunk/blender/source/blender/makesrna/intern/rna_userdef.c
    trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
    trunk/blender/source/blender/windowmanager/intern/wm_files.c

Modified: trunk/blender/intern/audaspace/intern/AUD_C-API.cpp
===================================================================
--- trunk/blender/intern/audaspace/intern/AUD_C-API.cpp	2010-02-21 16:43:25 UTC (rev 27059)
+++ trunk/blender/intern/audaspace/intern/AUD_C-API.cpp	2010-02-21 18:01:41 UTC (rev 27060)
@@ -761,6 +761,69 @@
 	return length;
 }
 
+void AUD_startPlayback()
+{
+#ifdef WITH_JACK
+	AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+	if(device)
+		device->startPlayback();
+#endif
+}
+
+void AUD_stopPlayback()
+{
+#ifdef WITH_JACK
+	AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+	if(device)
+		device->stopPlayback();
+#endif
+}
+
+void AUD_seekSequencer(AUD_Handle* handle, float time)
+{
+#ifdef WITH_JACK
+	AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+	if(device)
+		device->seekPlayback(time);
+	else
+#endif
+	{
+		AUD_device->seek(handle, time);
+	}
+}
+
+float AUD_getSequencerPosition(AUD_Handle* handle)
+{
+#ifdef WITH_JACK
+	AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+	if(device)
+		return device->getPlaybackPosition();
+	else
+#endif
+	{
+		return AUD_device->getPosition(handle);
+	}
+}
+
+void AUD_setSyncCallback(AUD_syncFunction function, void* data)
+{
+#ifdef WITH_JACK
+	AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+	if(device)
+		device->setSyncCallback(function, data);
+#endif
+}
+
+int AUD_doesPlayback()
+{
+#ifdef WITH_JACK
+	AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+	if(device)
+		return device->doesPlayback();
+#endif
+	return -1;
+}
+
 #ifdef AUD_DEBUG_MEMORY
 int AUD_References(int count, const char* text)
 {

Modified: trunk/blender/intern/audaspace/intern/AUD_C-API.h
===================================================================
--- trunk/blender/intern/audaspace/intern/AUD_C-API.h	2010-02-21 16:43:25 UTC (rev 27059)
+++ trunk/blender/intern/audaspace/intern/AUD_C-API.h	2010-02-21 18:01:41 UTC (rev 27060)
@@ -52,6 +52,7 @@
 	typedef void AUD_Device;
 	typedef void AUD_SequencerEntry;
 	typedef float (*AUD_volumeFunction)(void*, void*, float);
+	typedef void (*AUD_syncFunction)(void*, int, float);
 #endif
 
 /**
@@ -383,6 +384,18 @@
 
 extern int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length);
 
+extern void AUD_startPlayback();
+
+extern void AUD_stopPlayback();
+
+extern void AUD_seekSequencer(AUD_Handle* handle, float time);
+
+extern float AUD_getSequencerPosition(AUD_Handle* handle);
+
+extern void AUD_setSyncCallback(AUD_syncFunction function, void* data);
+
+extern int AUD_doesPlayback();
+
 #ifdef __cplusplus
 }
 #endif

Modified: trunk/blender/intern/audaspace/jack/AUD_JackDevice.cpp
===================================================================
--- trunk/blender/intern/audaspace/jack/AUD_JackDevice.cpp	2010-02-21 16:43:25 UTC (rev 27059)
+++ trunk/blender/intern/audaspace/jack/AUD_JackDevice.cpp	2010-02-21 18:01:41 UTC (rev 27060)
@@ -31,7 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-void* AUD_JackDevice::runThread(void* device)
+void* AUD_JackDevice::runMixingThread(void* device)
 {
 	((AUD_JackDevice*)device)->updateRingBuffers();
 	return NULL;
@@ -45,10 +45,24 @@
 	unsigned int channels = m_specs.channels;
 	sample_t* buffer = m_buffer->getBuffer();
 	float* deinterleave = m_deinterleavebuf->getBuffer();
+	jack_transport_state_t state;
+	jack_position_t position;
 
-	pthread_mutex_lock(&m_lock);
+	pthread_mutex_lock(&m_mixingLock);
 	while(m_valid)
 	{
+		if(m_sync > 1)
+		{
+			if(m_syncFunc)
+			{
+				state = jack_transport_query(m_client, &position);
+				m_syncFunc(m_syncFuncData, state != JackTransportStopped, position.frame / (float) m_specs.rate);
+			}
+
+			for(i = 0; i < channels; i++)
+				jack_ringbuffer_reset(m_ringbuffers[i]);
+		}
+
 		size = jack_ringbuffer_write_space(m_ringbuffers[0]);
 		for(i = 1; i < channels; i++)
 			if((temp = jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
@@ -71,9 +85,14 @@
 					size = temp;
 		}
 
-		pthread_cond_wait(&m_condition, &m_lock);
+		if(m_sync > 1)
+		{
+			m_sync = 3;
+		}
+
+		pthread_cond_wait(&m_mixingCondition, &m_mixingLock);
 	}
-	pthread_mutex_unlock(&m_lock);
+	pthread_mutex_unlock(&m_mixingLock);
 }
 
 int AUD_JackDevice::jack_mix(jack_nframes_t length, void *data)
@@ -83,27 +102,67 @@
 	int count = device->m_specs.channels;
 	char* buffer;
 
-	size_t temp;
-	size_t readsamples = jack_ringbuffer_read_space(device->m_ringbuffers[0]);
-	for(i = 1; i < count; i++)
-		if((temp = jack_ringbuffer_read_space(device->m_ringbuffers[i])) < readsamples)
-			readsamples = temp;
+	if(device->m_sync)
+	{
+		// play silence while syncing
+		for(unsigned int i = 0; i < count; i++)
+			memset(jack_port_get_buffer(device->m_ports[i], length), 0, length * sizeof(float));
+	}
+	else
+	{
+		size_t temp;
+		size_t readsamples = jack_ringbuffer_read_space(device->m_ringbuffers[0]);
+		for(i = 1; i < count; i++)
+			if((temp = jack_ringbuffer_read_space(device->m_ringbuffers[i])) < readsamples)
+				readsamples = temp;
 
-	readsamples = AUD_MIN(readsamples / sizeof(float), length);
+		readsamples = AUD_MIN(readsamples / sizeof(float), length);
 
-	for(unsigned int i = 0; i < count; i++)
-	{
-		buffer = (char*)jack_port_get_buffer(device->m_ports[i], length);
-		jack_ringbuffer_read(device->m_ringbuffers[i], buffer, readsamples * sizeof(float));
-		if(readsamples < length)
-			memset(buffer + readsamples * sizeof(float), 0, (length - readsamples) * sizeof(float));
+		for(unsigned int i = 0; i < count; i++)
+		{
+			buffer = (char*)jack_port_get_buffer(device->m_ports[i], length);
+			jack_ringbuffer_read(device->m_ringbuffers[i], buffer, readsamples * sizeof(float));
+			if(readsamples < length)
+				memset(buffer + readsamples * sizeof(float), 0, (length - readsamples) * sizeof(float));
+		}
+
+		if(pthread_mutex_trylock(&(device->m_mixingLock)) == 0)
+		{
+			pthread_cond_signal(&(device->m_mixingCondition));
+			pthread_mutex_unlock(&(device->m_mixingLock));
+		}
 	}
 
-	if(pthread_mutex_trylock(&(device->m_lock)) == 0)
+	return 0;
+}
+
+int AUD_JackDevice::jack_sync(jack_transport_state_t state, jack_position_t* pos, void* data)
+{
+	AUD_JackDevice* device = (AUD_JackDevice*)data;
+
+	if(state == JackTransportStopped)
+		return 1;
+
+	if(pthread_mutex_trylock(&(device->m_mixingLock)) == 0)
 	{
-		pthread_cond_signal(&(device->m_condition));
-		pthread_mutex_unlock(&(device->m_lock));
+		if(device->m_sync > 2)
+		{
+			if(device->m_sync == 3)
+			{
+				device->m_sync = 0;
+				pthread_mutex_unlock(&(device->m_mixingLock));
+				return 1;
+			}
+		}
+		else
+		{
+			device->m_sync = 2;
+			pthread_cond_signal(&(device->m_mixingCondition));
+		}
+		pthread_mutex_unlock(&(device->m_mixingLock));
 	}
+	else if(!device->m_sync)
+		device->m_sync = 1;
 
 	return 0;
 }
@@ -134,6 +193,7 @@
 	// set callbacks
 	jack_set_process_callback(m_client, AUD_JackDevice::jack_mix, this);
 	jack_on_shutdown(m_client, AUD_JackDevice::jack_shutdown, this);
+	jack_set_sync_callback(m_client, AUD_JackDevice::jack_sync, this);
 
 	// register our output channels which are called ports in jack
 	m_ports = new jack_port_t*[m_specs.channels]; AUD_NEW("jack_port")
@@ -170,6 +230,14 @@
 
 	create();
 
+	m_valid = true;
+	m_playing = false;
+	m_sync = 0;
+	m_syncFunc = NULL;
+
+	pthread_mutex_init(&m_mixingLock, NULL);
+	pthread_cond_init(&m_mixingCondition, NULL);
+
 	try
 	{
 		// activate the client
@@ -185,6 +253,8 @@
 		for(unsigned int i = 0; i < specs.channels; i++)
 			jack_ringbuffer_free(m_ringbuffers[i]);
 		delete[] m_ringbuffers; AUD_DELETE("jack_buffers")
+		pthread_mutex_destroy(&m_mixingLock);
+		pthread_cond_destroy(&m_mixingCondition);
 		destroy();
 		throw;
 	}
@@ -199,16 +269,11 @@
 		free(ports);
 	}
 
-	m_valid = true;
-
-	pthread_mutex_init(&m_lock, NULL);
-	pthread_cond_init(&m_condition, NULL);
-
 	pthread_attr_t attr;
 	pthread_attr_init(&attr);
 	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
 
-	pthread_create(&m_thread, &attr, runThread, this);
+	pthread_create(&m_mixingThread, &attr, runMixingThread, this);
 
 	pthread_attr_destroy(&attr);
 }
@@ -221,13 +286,13 @@
 
 	delete[] m_ports; AUD_DELETE("jack_port")
 
-	pthread_mutex_lock(&m_lock);
-	pthread_cond_signal(&m_condition);
-	pthread_mutex_unlock(&m_lock);
-	pthread_join(m_thread, NULL);
+	pthread_mutex_lock(&m_mixingLock);
+	pthread_cond_signal(&m_mixingCondition);
+	pthread_mutex_unlock(&m_mixingLock);
+	pthread_join(m_mixingThread, NULL);
 
-	pthread_cond_destroy(&m_condition);
-	pthread_mutex_destroy(&m_lock);
+	pthread_cond_destroy(&m_mixingCondition);
+	pthread_mutex_destroy(&m_mixingLock);
 	delete m_buffer; AUD_DELETE("buffer");
 	delete m_deinterleavebuf; AUD_DELETE("buffer");
 	for(unsigned int i = 0; i < m_specs.channels; i++)
@@ -241,3 +306,37 @@
 {
 	// Do nothing.
 }
+
+void AUD_JackDevice::startPlayback()
+{
+	jack_transport_start(m_client);
+}
+
+void AUD_JackDevice::stopPlayback()
+{
+	jack_transport_stop(m_client);
+}
+
+void AUD_JackDevice::seekPlayback(float time)
+{
+	if(time >= 0.0f)
+		jack_transport_locate(m_client, time * m_specs.rate);
+}
+
+void AUD_JackDevice::setSyncCallback(AUD_syncFunction sync, void* data)
+{
+	m_syncFunc = sync;
+	m_syncFuncData = data;
+}
+
+float AUD_JackDevice::getPlaybackPosition()
+{
+	jack_position_t position;
+	jack_transport_query(m_client, &position);
+	return position.frame / (float) m_specs.rate;
+}
+
+bool AUD_JackDevice::doesPlayback()
+{
+	return jack_transport_query(m_client, NULL) != JackTransportStopped;
+}

Modified: trunk/blender/intern/audaspace/jack/AUD_JackDevice.h
===================================================================
--- trunk/blender/intern/audaspace/jack/AUD_JackDevice.h	2010-02-21 16:43:25 UTC (rev 27059)
+++ trunk/blender/intern/audaspace/jack/AUD_JackDevice.h	2010-02-21 18:01:41 UTC (rev 27060)
@@ -33,6 +33,8 @@
 #include <jack.h>
 #include <ringbuffer.h>
 
+typedef void (*AUD_syncFunction)(void*, int, float);
+
 /**
  * This device plays back through Jack.
  */
@@ -56,6 +58,8 @@
 
 	AUD_Buffer* m_deinterleavebuf;
 
+	jack_ringbuffer_t** m_ringbuffers;
+
 	/**
 	 * Whether the device is valid.
 	 */
@@ -75,21 +79,41 @@
 	 */
 	static int jack_mix(jack_nframes_t length, void *data);
 
-	static void* runThread(void* device);
+	static int jack_sync(jack_transport_state_t state, jack_position_t* pos, void* data);
 
-	void updateRingBuffers();
+	/**
+	 * Last Jack Transport playing state.
+	 */
+	bool m_playing;
 
-	jack_ringbuffer_t** m_ringbuffers;
+	/**
+	 * Syncronisation state.
+	 */
+	int m_sync;
 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list