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:
-rw-r--r--CMakeLists.txt4
-rw-r--r--build_files/buildbot/config/user-config-glibc211-i686.py5
-rw-r--r--build_files/buildbot/config/user-config-glibc211-x86_64.py5
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-i686.py5
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-x86_64.py5
-rw-r--r--build_files/cmake/macros.cmake4
-rw-r--r--build_files/scons/tools/Blender.py6
-rw-r--r--build_files/scons/tools/btools.py5
-rw-r--r--intern/audaspace/CMakeLists.txt6
-rw-r--r--intern/audaspace/SConscript2
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp28
-rw-r--r--intern/audaspace/intern/AUD_C-API.h9
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.cpp66
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.h7
-rw-r--r--intern/audaspace/jack/AUD_JackLibrary.cpp116
-rw-r--r--intern/audaspace/jack/AUD_JackLibrary.h104
-rw-r--r--source/blender/blenkernel/BKE_sound.h3
-rw-r--r--source/blender/blenkernel/intern/sound.c15
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c64
19 files changed, 380 insertions, 79 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9c0e0ae6c9f..fe051db871f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -229,6 +229,9 @@ option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org
option(WITH_SDL "Enable SDL for sound and joystick support" ON)
option(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
option(WITH_JACK "Enable Jack Support (http://www.jackaudio.org)" OFF)
+if(UNIX AND NOT APPLE)
+ option(WITH_JACK_DYNLOAD "Enable runtime dynamic Jack libraries loading" OFF)
+endif()
# Compression
option(WITH_LZO "Enable fast LZO compression (used for pointcache)" ON)
@@ -2202,6 +2205,7 @@ if(FIRST_RUN)
info_cfg_option(WITH_OPENAL)
info_cfg_option(WITH_SDL)
info_cfg_option(WITH_JACK)
+ info_cfg_option(WITH_JACK_DYNLOAD)
info_cfg_option(WITH_CODEC_AVI)
info_cfg_option(WITH_CODEC_FFMPEG)
info_cfg_option(WITH_CODEC_SNDFILE)
diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py
index 540416ee1fb..616ddb94354 100644
--- a/build_files/buildbot/config/user-config-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-glibc211-i686.py
@@ -104,9 +104,8 @@ WITH_BF_FFTW3 = True
WITH_BF_STATICFFTW3 = True
# JACK
-WITH_BF_JACK = False
-WITH_BF_STATICJACK = True
-BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
+WITH_BF_JACK = True
+WITH_BF_JACK_DYNLOAD = True
# Cycles
WITH_BF_CYCLES = True
diff --git a/build_files/buildbot/config/user-config-glibc211-x86_64.py b/build_files/buildbot/config/user-config-glibc211-x86_64.py
index c0ba8060712..023eb2539fa 100644
--- a/build_files/buildbot/config/user-config-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py
@@ -104,9 +104,8 @@ WITH_BF_FFTW3 = True
WITH_BF_STATICFFTW3 = True
# JACK
-WITH_BF_JACK = False
-WITH_BF_STATICJACK = True
-BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
+WITH_BF_JACK = True
+WITH_BF_JACK_DYNLOAD = True
# Cycles
WITH_BF_CYCLES = True
diff --git a/build_files/buildbot/config/user-config-player-glibc211-i686.py b/build_files/buildbot/config/user-config-player-glibc211-i686.py
index a99337f03e6..9f345931684 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py
@@ -103,9 +103,8 @@ BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBP
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
-WITH_BF_JACK = False
-WITH_BF_STATICJACK = True
-BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
+WITH_BF_JACK = True
+WITH_BF_JACK_DYNLOAD = True
# Motion Tracking
WITH_BF_LIBMV = False
diff --git a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
index c17cff2893d..c58da9dcffb 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
@@ -103,9 +103,8 @@ BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBP
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
-WITH_BF_JACK = False
-WITH_BF_STATICJACK = True
-BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
+WITH_BF_JACK = True
+WITH_BF_JACK_DYNLOAD = True
# Motion Tracking
WITH_BF_LIBMV = False
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index 9fe76df20b9..2b5cfbc31cc 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -228,7 +228,7 @@ macro(SETUP_LIBDIRS)
if(WITH_OPENAL)
link_directories(${OPENAL_LIBPATH})
endif()
- if(WITH_JACK)
+ if(WITH_JACK AND NOT WITH_JACK_DYNLOAD)
link_directories(${JACK_LIBPATH})
endif()
if(WITH_CODEC_SNDFILE)
@@ -293,7 +293,7 @@ macro(setup_liblinks
if(WITH_FFTW3)
target_link_libraries(${target} ${FFTW3_LIBRARIES})
endif()
- if(WITH_JACK)
+ if(WITH_JACK AND NOT WITH_JACK_DYNLOAD)
target_link_libraries(${target} ${JACK_LIBRARIES})
endif()
if(WITH_CODEC_SNDFILE)
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py
index b3c3907129f..543def4e836 100644
--- a/build_files/scons/tools/Blender.py
+++ b/build_files/scons/tools/Blender.py
@@ -147,10 +147,8 @@ def setup_staticlibs(lenv):
libincs += Split(lenv['BF_PYTHON_LIBPATH'])
if lenv['WITH_BF_SDL']:
libincs += Split(lenv['BF_SDL_LIBPATH'])
- if lenv['WITH_BF_JACK']:
+ if lenv['WITH_BF_JACK'] and not lenv['WITH_BF_JACK_DYNLOAD']:
libincs += Split(lenv['BF_JACK_LIBPATH'])
- if lenv['WITH_BF_STATICJACK']:
- statlibs += Split(lenv['BF_JACK_LIB_STATIC'])
if lenv['WITH_BF_SNDFILE']:
libincs += Split(lenv['BF_SNDFILE_LIBPATH'])
if lenv['WITH_BF_OPENEXR']:
@@ -292,7 +290,7 @@ def setup_syslibs(lenv):
syslibs += Split(lenv['BF_FFMPEG_LIB'])
if lenv['WITH_BF_OGG']:
syslibs += Split(lenv['BF_OGG_LIB'])
- if lenv['WITH_BF_JACK'] and not lenv['WITH_BF_STATICJACK']:
+ if lenv['WITH_BF_JACK'] and not lenv['WITH_BF_JACK_DYNLOAD']:
syslibs += Split(lenv['BF_JACK_LIB'])
if lenv['WITH_BF_SNDFILE'] and not lenv['WITH_BF_STATICSNDFILE']:
syslibs += Split(lenv['BF_SNDFILE_LIB'])
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index ee6dd20ecc0..e35c28cedf0 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -99,7 +99,7 @@ def validate_arguments(args, bc):
'WITH_BF_PYTHON', 'WITH_BF_PYTHON_SAFETY', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'WITH_BF_STATICPYTHON', 'WITH_OSX_STATICPYTHON', 'BF_PYTHON_LIB_STATIC', 'BF_PYTHON_DLL', 'BF_PYTHON_ABI_FLAGS',
'WITH_BF_OPENAL', 'BF_OPENAL', 'BF_OPENAL_INC', 'BF_OPENAL_LIB', 'BF_OPENAL_LIBPATH', 'WITH_BF_STATICOPENAL', 'BF_OPENAL_LIB_STATIC',
'WITH_BF_SDL', 'BF_SDL', 'BF_SDL_INC', 'BF_SDL_LIB', 'BF_SDL_LIBPATH',
- 'WITH_BF_JACK', 'BF_JACK', 'BF_JACK_INC', 'BF_JACK_LIB', 'BF_JACK_LIBPATH', 'WITH_BF_STATICJACK', 'BF_JACK_LIB_STATIC',
+ 'WITH_BF_JACK', 'BF_JACK', 'BF_JACK_INC', 'BF_JACK_LIB', 'BF_JACK_LIBPATH', 'WITH_BF_JACK_DYNLOAD',
'WITH_BF_SNDFILE', 'BF_SNDFILE', 'BF_SNDFILE_INC', 'BF_SNDFILE_LIB', 'BF_SNDFILE_LIBPATH', 'WITH_BF_STATICSNDFILE', 'BF_SNDFILE_LIB_STATIC',
'BF_PTHREADS', 'BF_PTHREADS_INC', 'BF_PTHREADS_LIB', 'BF_PTHREADS_LIBPATH',
'WITH_BF_OPENEXR', 'BF_OPENEXR', 'BF_OPENEXR_INC', 'BF_OPENEXR_LIB', 'BF_OPENEXR_LIBPATH', 'WITH_BF_STATICOPENEXR', 'BF_OPENEXR_LIB_STATIC',
@@ -288,12 +288,11 @@ def read_opts(env, cfg, args):
('BF_SDL_LIBPATH', 'SDL library path', ''),
(BoolVariable('WITH_BF_JACK', 'Enable jack support if true', True)),
- (BoolVariable('WITH_BF_STATICJACK', 'Staticly link to jack', False)),
('BF_JACK', 'jack base path', ''),
('BF_JACK_INC', 'jack include path', ''),
('BF_JACK_LIB', 'jack library', ''),
('BF_JACK_LIBPATH', 'jack library path', ''),
- ('BF_JACK_LIB_STATIC', 'jack static library', ''),
+ (BoolVariable('WITH_BF_JACK_DYNLOAD', 'Enable runtime dynamic Jack libraries loading (works only on Linux)', False)),
(BoolVariable('WITH_BF_SNDFILE', 'Enable sndfile support if true', True)),
('BF_SNDFILE', 'sndfile base path', ''),
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
index ec66cffea3b..21a42553935 100644
--- a/intern/audaspace/CMakeLists.txt
+++ b/intern/audaspace/CMakeLists.txt
@@ -253,9 +253,15 @@ if(WITH_JACK)
)
list(APPEND SRC
jack/AUD_JackDevice.cpp
+ jack/AUD_JackLibrary.cpp
jack/AUD_JackDevice.h
+ jack/AUD_JackLibrary.h
)
+
+ if(WITH_JACK_DYNLOAD)
+ add_definitions(-DWITH_JACK_DYNLOAD)
+ endif()
endif()
if(WITH_CODEC_SNDFILE)
diff --git a/intern/audaspace/SConscript b/intern/audaspace/SConscript
index ba549530e64..cc338629c85 100644
--- a/intern/audaspace/SConscript
+++ b/intern/audaspace/SConscript
@@ -46,6 +46,8 @@ if env['WITH_BF_JACK']:
sources += env.Glob('jack/*.cpp')
incs += ' jack ' + env['BF_JACK_INC']
defs.append('WITH_JACK')
+ if env['WITH_BF_JACK_DYNLOAD']:
+ defs.append('WITH_JACK_DYNLOAD')
if env['WITH_BF_SNDFILE']:
sources += env.Glob('sndfile/*.cpp')
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index e15964151c9..42fd87e3b8d 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -79,6 +79,7 @@
#ifdef WITH_JACK
#include "AUD_JackDevice.h"
+#include "AUD_JackLibrary.h"
#endif
@@ -110,6 +111,16 @@ void AUD_initOnce()
#ifdef WITH_FFMPEG
av_register_all();
#endif
+#ifdef WITH_JACK
+ AUD_jack_init();
+#endif
+}
+
+void AUD_exitOnce()
+{
+#ifdef WITH_JACK
+ AUD_jack_exit();
+#endif
}
int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
@@ -144,14 +155,16 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
// No break, fall through to default, to return false
}
else
- {
#endif
+ if (!AUD_jack_supported()) {
+ printf("Warning: Jack cllient not installed\n");
+ // No break, fall through to default, to return false
+ }
+ else {
dev = boost::shared_ptr<AUD_IDevice>(new AUD_JackDevice("Blender", specs, buffersize));
break;
-#ifdef __APPLE__
}
#endif
-#endif
default:
return false;
}
@@ -1262,3 +1275,12 @@ AUD_I3DDevice *AUD_get3DDevice()
{
return AUD_3ddevice;
}
+
+int AUD_isJackSupported(void)
+{
+#ifdef WITH_JACK
+ return AUD_jack_supported();
+#else
+ return 0;
+#endif
+}
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index 9c6611fe04a..64a3d06bd5f 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -61,11 +61,16 @@ typedef struct
#endif
/**
- * Initializes FFMPEG if it is enabled.
+ * Initializes audio rutines (FFMPEG/Jack if it is enabled).
*/
extern void AUD_initOnce(void);
/**
+ * Unitinitializes an audio routines.
+ */
+extern void AUD_exitOnce(void);
+
+/**
* Initializes an audio device.
* \param device The device type that should be used.
* \param specs The audio specification to be used.
@@ -752,6 +757,8 @@ extern void *AUD_getPythonFactory(AUD_Sound *sound);
extern AUD_Sound *AUD_getPythonSound(void *sound);
#endif
+extern int AUD_isJackSupported(void);
+
#ifdef __cplusplus
}
diff --git a/intern/audaspace/jack/AUD_JackDevice.cpp b/intern/audaspace/jack/AUD_JackDevice.cpp
index a83098ac496..cfbf80ac110 100644
--- a/intern/audaspace/jack/AUD_JackDevice.cpp
+++ b/intern/audaspace/jack/AUD_JackDevice.cpp
@@ -56,17 +56,17 @@ void AUD_JackDevice::updateRingBuffers()
{
if(m_syncFunc)
{
- state = jack_transport_query(m_client, &position);
+ state = AUD_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]);
+ AUD_jack_ringbuffer_reset(m_ringbuffers[i]);
}
- size = jack_ringbuffer_write_space(m_ringbuffers[0]);
+ size = AUD_jack_ringbuffer_write_space(m_ringbuffers[0]);
for(i = 1; i < channels; i++)
- if((temp = jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
+ if((temp = AUD_jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
size = temp;
while(size > samplesize)
@@ -77,12 +77,12 @@ void AUD_JackDevice::updateRingBuffers()
{
for(j = 0; j < size; j++)
deinterleave[i * size + j] = buffer[i + j * channels];
- jack_ringbuffer_write(m_ringbuffers[i], (char*)(deinterleave + i * size), size * sizeof(float));
+ AUD_jack_ringbuffer_write(m_ringbuffers[i], (char*)(deinterleave + i * size), size * sizeof(float));
}
- size = jack_ringbuffer_write_space(m_ringbuffers[0]);
+ size = AUD_jack_ringbuffer_write_space(m_ringbuffers[0]);
for(i = 1; i < channels; i++)
- if((temp = jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
+ if((temp = AUD_jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
size = temp;
}
@@ -107,22 +107,22 @@ int AUD_JackDevice::jack_mix(jack_nframes_t length, void *data)
{
// 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));
+ memset(AUD_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]);
+ size_t readsamples = AUD_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)
+ if((temp = AUD_jack_ringbuffer_read_space(device->m_ringbuffers[i])) < readsamples)
readsamples = temp;
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));
+ buffer = (char*)AUD_jack_port_get_buffer(device->m_ports[i], length);
+ AUD_jack_ringbuffer_read(device->m_ringbuffers[i], buffer, readsamples * sizeof(float));
if(readsamples < length)
memset(buffer + readsamples * sizeof(float), 0, (length - readsamples) * sizeof(float));
}
@@ -193,14 +193,14 @@ AUD_JackDevice::AUD_JackDevice(std::string name, AUD_DeviceSpecs specs, int buff
jack_status_t status;
// open client
- m_client = jack_client_open(name.c_str(), options, &status);
+ m_client = AUD_jack_client_open(name.c_str(), options, &status);
if(m_client == NULL)
AUD_THROW(AUD_ERROR_JACK, clientopen_error);
// 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);
+ AUD_jack_set_process_callback(m_client, AUD_JackDevice::jack_mix, this);
+ AUD_jack_on_shutdown(m_client, AUD_JackDevice::jack_shutdown, this);
+ AUD_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];
@@ -211,7 +211,7 @@ AUD_JackDevice::AUD_JackDevice(std::string name, AUD_DeviceSpecs specs, int buff
for(int i = 0; i < m_specs.channels; i++)
{
sprintf(portname, "out %d", i+1);
- m_ports[i] = jack_port_register(m_client, portname,
+ m_ports[i] = AUD_jack_port_register(m_client, portname,
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
if(m_ports[i] == NULL)
@@ -220,17 +220,17 @@ AUD_JackDevice::AUD_JackDevice(std::string name, AUD_DeviceSpecs specs, int buff
}
catch(AUD_Exception&)
{
- jack_client_close(m_client);
+ AUD_jack_client_close(m_client);
delete[] m_ports;
throw;
}
- m_specs.rate = (AUD_SampleRate)jack_get_sample_rate(m_client);
+ m_specs.rate = (AUD_SampleRate)AUD_jack_get_sample_rate(m_client);
buffersize *= sizeof(sample_t);
m_ringbuffers = new jack_ringbuffer_t*[specs.channels];
for(unsigned int i = 0; i < specs.channels; i++)
- m_ringbuffers[i] = jack_ringbuffer_create(buffersize);
+ m_ringbuffers[i] = AUD_jack_ringbuffer_create(buffersize);
buffersize *= specs.channels;
m_deinterleavebuf.resize(buffersize);
m_buffer.resize(buffersize);
@@ -240,18 +240,18 @@ AUD_JackDevice::AUD_JackDevice(std::string name, AUD_DeviceSpecs specs, int buff
m_valid = true;
m_sync = 0;
m_syncFunc = NULL;
- m_nextState = m_state = jack_transport_query(m_client, NULL);
+ m_nextState = m_state = AUD_jack_transport_query(m_client, NULL);
pthread_mutex_init(&m_mixingLock, NULL);
pthread_cond_init(&m_mixingCondition, NULL);
// activate the client
- if(jack_activate(m_client))
+ if(AUD_jack_activate(m_client))
{
- jack_client_close(m_client);
+ AUD_jack_client_close(m_client);
delete[] m_ports;
for(unsigned int i = 0; i < specs.channels; i++)
- jack_ringbuffer_free(m_ringbuffers[i]);
+ AUD_jack_ringbuffer_free(m_ringbuffers[i]);
delete[] m_ringbuffers;
pthread_mutex_destroy(&m_mixingLock);
pthread_cond_destroy(&m_mixingCondition);
@@ -260,12 +260,12 @@ AUD_JackDevice::AUD_JackDevice(std::string name, AUD_DeviceSpecs specs, int buff
AUD_THROW(AUD_ERROR_JACK, activate_error);
}
- const char** ports = jack_get_ports(m_client, NULL, NULL,
+ const char** ports = AUD_jack_get_ports(m_client, NULL, NULL,
JackPortIsPhysical | JackPortIsInput);
if(ports != NULL)
{
for(int i = 0; i < m_specs.channels && ports[i]; i++)
- jack_connect(m_client, jack_port_name(m_ports[i]), ports[i]);
+ AUD_jack_connect(m_client, AUD_jack_port_name(m_ports[i]), ports[i]);
free(ports);
}
@@ -282,7 +282,7 @@ AUD_JackDevice::AUD_JackDevice(std::string name, AUD_DeviceSpecs specs, int buff
AUD_JackDevice::~AUD_JackDevice()
{
if(m_valid)
- jack_client_close(m_client);
+ AUD_jack_client_close(m_client);
m_valid = false;
delete[] m_ports;
@@ -295,7 +295,7 @@ AUD_JackDevice::~AUD_JackDevice()
pthread_cond_destroy(&m_mixingCondition);
pthread_mutex_destroy(&m_mixingLock);
for(unsigned int i = 0; i < m_specs.channels; i++)
- jack_ringbuffer_free(m_ringbuffers[i]);
+ AUD_jack_ringbuffer_free(m_ringbuffers[i]);
delete[] m_ringbuffers;
destroy();
@@ -308,20 +308,20 @@ void AUD_JackDevice::playing(bool playing)
void AUD_JackDevice::startPlayback()
{
- jack_transport_start(m_client);
+ AUD_jack_transport_start(m_client);
m_nextState = JackTransportRolling;
}
void AUD_JackDevice::stopPlayback()
{
- jack_transport_stop(m_client);
+ AUD_jack_transport_stop(m_client);
m_nextState = JackTransportStopped;
}
void AUD_JackDevice::seekPlayback(float time)
{
if(time >= 0.0f)
- jack_transport_locate(m_client, time * m_specs.rate);
+ AUD_jack_transport_locate(m_client, time * m_specs.rate);
}
void AUD_JackDevice::setSyncCallback(AUD_syncFunction sync, void* data)
@@ -333,13 +333,13 @@ void AUD_JackDevice::setSyncCallback(AUD_syncFunction sync, void* data)
float AUD_JackDevice::getPlaybackPosition()
{
jack_position_t position;
- jack_transport_query(m_client, &position);
+ AUD_jack_transport_query(m_client, &position);
return position.frame / (float) m_specs.rate;
}
bool AUD_JackDevice::doesPlayback()
{
- jack_transport_state_t state = jack_transport_query(m_client, NULL);
+ jack_transport_state_t state = AUD_jack_transport_query(m_client, NULL);
if(state != m_state)
m_nextState = m_state = state;
diff --git a/intern/audaspace/jack/AUD_JackDevice.h b/intern/audaspace/jack/AUD_JackDevice.h
index dc90c5249a2..a82a6bc5c38 100644
--- a/intern/audaspace/jack/AUD_JackDevice.h
+++ b/intern/audaspace/jack/AUD_JackDevice.h
@@ -36,12 +36,7 @@
#include <string>
-#if defined(__APPLE__) // always first include for jack weaklinking !
-#include <weakjack.h>
-#endif
-
-#include <jack.h>
-#include <ringbuffer.h>
+#include <AUD_JackLibrary.h>
typedef void (*AUD_syncFunction)(void*, int, float);
diff --git a/intern/audaspace/jack/AUD_JackLibrary.cpp b/intern/audaspace/jack/AUD_JackLibrary.cpp
new file mode 100644
index 00000000000..150d22b324c
--- /dev/null
+++ b/intern/audaspace/jack/AUD_JackLibrary.cpp
@@ -0,0 +1,116 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2013 Blender Foundation
+ *
+ * This file is part of AudaSpace.
+ *
+ * Audaspace is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/jack/AUD_JacLibrary.cpp
+ * \ingroup audjack
+ */
+
+#define AUD_JACK_LIBRARY_IMPL
+
+#include "AUD_JackLibrary.h"
+
+#ifdef WITH_JACK_DYNLOAD
+# include <dlfcn.h>
+# include <stdio.h>
+#endif
+
+#ifdef WITH_JACK_DYNLOAD
+static void *jack_handle = NULL;
+#endif
+
+static bool jack_supported = false;
+
+void AUD_jack_init(void)
+{
+#ifdef WITH_JACK_DYNLOAD
+ jack_handle = dlopen("libjack.so", RTLD_LAZY);
+
+ if (!jack_handle) {
+ fprintf(stderr, "%s\n", dlerror());
+ return;
+ }
+
+# define JACK_SYMBOL(sym) \
+ { \
+ char *error; \
+ *(void **) (&(AUD_##sym)) = dlsym(jack_handle, #sym); \
+ if ((error = dlerror()) != NULL) { \
+ fprintf(stderr, "%s\n", error); \
+ return; \
+ } \
+ } (void)0
+
+ dlerror(); /* Clear any existing error */
+#else // WITH_JACK_DYNLOAD
+# define JACK_SYMBOL(sym) AUD_##sym = sym
+#endif // WITH_JACK_DYNLOAD
+
+ JACK_SYMBOL(jack_transport_query);
+ JACK_SYMBOL(jack_transport_locate);
+
+ JACK_SYMBOL(jack_transport_start);
+ JACK_SYMBOL(jack_transport_stop);
+
+ JACK_SYMBOL(jack_ringbuffer_reset);
+ JACK_SYMBOL(jack_ringbuffer_write);
+ JACK_SYMBOL(jack_ringbuffer_write_space);
+ JACK_SYMBOL(jack_ringbuffer_write_advance);
+ JACK_SYMBOL(jack_ringbuffer_read);
+ JACK_SYMBOL(jack_ringbuffer_create);
+ JACK_SYMBOL(jack_ringbuffer_free);
+ JACK_SYMBOL(jack_ringbuffer_read_space);
+ JACK_SYMBOL(jack_set_sync_callback);
+
+ JACK_SYMBOL(jack_port_get_buffer);
+
+ JACK_SYMBOL(jack_client_open);
+ JACK_SYMBOL(jack_set_process_callback);
+ JACK_SYMBOL(jack_on_shutdown);
+ JACK_SYMBOL(jack_port_register);
+ JACK_SYMBOL(jack_client_close);
+ JACK_SYMBOL(jack_get_sample_rate);
+ JACK_SYMBOL(jack_activate);
+ JACK_SYMBOL(jack_get_ports);
+ JACK_SYMBOL(jack_port_name);
+ JACK_SYMBOL(jack_connect);
+
+ jack_supported = true;
+
+#undef JACK_SYMBOL
+}
+
+void AUD_jack_exit(void)
+{
+#ifdef WITH_JACK_DYNLOAD
+ if (jack_handle) {
+ dlclose(jack_handle);
+ }
+#endif
+ jack_supported = false;
+}
+
+bool AUD_jack_supported(void)
+{
+ return jack_supported;
+}
diff --git a/intern/audaspace/jack/AUD_JackLibrary.h b/intern/audaspace/jack/AUD_JackLibrary.h
new file mode 100644
index 00000000000..c4f50796381
--- /dev/null
+++ b/intern/audaspace/jack/AUD_JackLibrary.h
@@ -0,0 +1,104 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2013 Blender Foundation
+ *
+ * This file is part of AudaSpace.
+ *
+ * Audaspace is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/jack/AUD_JacLibrary.cpp
+ * \ingroup audjack
+ */
+
+#ifndef __AUD_JACKLIBRARY__
+#define __AUD_JACKLIBRARY__
+
+#if defined(__APPLE__) // always first include for jack weaklinking !
+#include <weakjack.h>
+#endif
+
+#include <jack.h>
+#include <ringbuffer.h>
+
+#ifdef AUD_JACK_LIBRARY_IMPL
+# define JACK_SYM
+#else
+# define JACK_SYM extern
+#endif
+
+/* All loadable Jack sumbols, prototypes from original jack.h */
+
+JACK_SYM jack_transport_state_t (*AUD_jack_transport_query) (
+ const jack_client_t *client,
+ jack_position_t *pos);
+
+JACK_SYM int (*AUD_jack_transport_locate) (jack_client_t *client,
+ jack_nframes_t frame);
+
+JACK_SYM void (*AUD_jack_transport_start) (jack_client_t *client);
+JACK_SYM void (*AUD_jack_transport_stop) (jack_client_t *client);
+
+JACK_SYM void (*AUD_jack_ringbuffer_reset) (jack_ringbuffer_t *rb);
+JACK_SYM size_t (*AUD_jack_ringbuffer_write) (jack_ringbuffer_t *rb,
+ const char *src, size_t cnt);
+JACK_SYM size_t (*AUD_jack_ringbuffer_write_space) (const jack_ringbuffer_t *rb);
+JACK_SYM void (*AUD_jack_ringbuffer_write_advance) (jack_ringbuffer_t *rb,
+ size_t cnt);
+JACK_SYM size_t (*AUD_jack_ringbuffer_read) (jack_ringbuffer_t *rb, char *dest,
+ size_t cnt);
+JACK_SYM jack_ringbuffer_t *(*AUD_jack_ringbuffer_create) (size_t sz);
+JACK_SYM void (*AUD_jack_ringbuffer_free) (jack_ringbuffer_t *rb);
+JACK_SYM size_t (*AUD_jack_ringbuffer_read_space) (const jack_ringbuffer_t *rb);
+JACK_SYM int (*AUD_jack_set_sync_callback) (jack_client_t *client,
+ JackSyncCallback sync_callback,
+ void *arg);
+
+JACK_SYM void *(*AUD_jack_port_get_buffer) (jack_port_t *, jack_nframes_t);
+
+JACK_SYM jack_client_t *(*AUD_jack_client_open) (const char *client_name,
+ jack_options_t options,
+ jack_status_t *status, ...);
+JACK_SYM int (*AUD_jack_set_process_callback) (jack_client_t *client,
+ JackProcessCallback process_callback, void *arg);
+JACK_SYM void (*AUD_jack_on_shutdown) (jack_client_t *client,
+ JackShutdownCallback function, void *arg);
+JACK_SYM jack_port_t *(*AUD_jack_port_register) (jack_client_t *client,
+ const char *port_name,
+ const char *port_type,
+ unsigned long flags,
+ unsigned long buffer_size);
+JACK_SYM int (*AUD_jack_client_close) (jack_client_t *client);
+JACK_SYM jack_nframes_t (*AUD_jack_get_sample_rate) (jack_client_t *);
+JACK_SYM int (*AUD_jack_activate) (jack_client_t *client);
+JACK_SYM const char **(*AUD_jack_get_ports) (jack_client_t *,
+ const char *port_name_pattern,
+ const char *type_name_pattern,
+ unsigned long flags);
+JACK_SYM const char *(*AUD_jack_port_name) (const jack_port_t *port);
+JACK_SYM int (*AUD_jack_connect) (jack_client_t *,
+ const char *source_port,
+ const char *destination_port);
+
+/* Public API */
+
+void AUD_jack_init(void);
+void AUD_jack_exit(void);
+bool AUD_jack_supported(void);
+
+#endif // __AUD_JACKLIBRARY__
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index ec1b6577469..64f0b97c3f0 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -47,6 +47,7 @@ typedef struct SoundWaveform {
} SoundWaveform;
void sound_init_once(void);
+void sound_exit_once(void);
void sound_init(struct Main *main);
@@ -139,4 +140,6 @@ void *sound_get_factory(void *sound);
float sound_get_length(struct bSound *sound);
+int sound_is_jack_supported(void);
+
#endif
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index af9d21d8cbc..feff8f95fd7 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -172,7 +172,7 @@ void sound_force_device(int device)
void sound_init_once(void)
{
AUD_initOnce();
- atexit(sound_exit);
+ atexit(sound_exit_once);
}
void sound_init(struct Main *bmain)
@@ -221,6 +221,12 @@ void sound_exit(void)
AUD_exit();
}
+void sound_exit_once(void)
+{
+ AUD_exit();
+ AUD_exitOnce();
+}
+
// XXX unused currently
#if 0
bSound *sound_new_buffer(struct Main *bmain, bSound *source)
@@ -766,6 +772,11 @@ float sound_get_length(bSound *sound)
return info.length;
}
+int sound_is_jack_supported(void)
+{
+ return AUD_isJackSupported();
+}
+
#else // WITH_AUDASPACE
#include "BLI_utildefines.h"
@@ -775,6 +786,7 @@ void sound_force_device(int UNUSED(device)) {}
void sound_init_once(void) {}
void sound_init(struct Main *UNUSED(bmain)) {}
void sound_exit(void) {}
+void sound_exit_once(void) {}
void sound_cache(struct bSound *UNUSED(sound)) { }
void sound_delete_cache(struct bSound *UNUSED(sound)) {}
void sound_load(struct Main *UNUSED(bmain), struct bSound *UNUSED(sound)) {}
@@ -807,4 +819,5 @@ void sound_set_scene_sound_pan(void *handle, float pan, char animated) { (void)h
void sound_set_scene_volume(struct Scene *scene, float volume) { (void)scene; (void)volume; }
void sound_set_scene_sound_pitch(void *handle, float pitch, char animated) { (void)handle; (void)pitch; (void)animated; }
float sound_get_length(struct bSound *sound) { (void)sound; return 0; }
+int sound_is_jack_supported(void) { return 0; }
#endif // WITH_AUDASPACE
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index d5fc3d2050d..a279ec375a9 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -58,6 +58,20 @@ static EnumPropertyItem compute_device_type_items[] = {
};
#endif
+static EnumPropertyItem audio_device_items[] = {
+ {0, "NONE", 0, "None", "Null device - there will be no audio output"},
+#ifdef WITH_SDL
+ {1, "SDL", 0, "SDL", "SDL device - simple direct media layer, recommended for sequencer usage"},
+#endif
+#ifdef WITH_OPENAL
+ {2, "OPENAL", 0, "OpenAL", "OpenAL device - supports 3D audio, recommended for game engine usage"},
+#endif
+#ifdef WITH_JACK
+ {3, "JACK", 0, "Jack", "JACK - Audio Connection Kit, recommended for pro audio users"},
+#endif
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
#include "DNA_object_types.h"
@@ -434,6 +448,41 @@ static EnumPropertyItem *rna_userdef_compute_device_itemf(bContext *UNUSED(C), P
}
#endif
+static EnumPropertyItem *rna_userdef_audio_device_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop), int *free)
+{
+#ifdef WITH_JACK
+ int jack_supported = sound_is_jack_supported();
+
+ if (jack_supported) {
+ return audio_device_items;
+ }
+ else {
+ int index = 0;
+ int totitem = 0;
+ EnumPropertyItem *item = NULL;
+
+ /* NONE */
+ RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
+
+#ifdef WITH_SDL
+ RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
+#endif
+
+#ifdef WITH_OPENAL
+ RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
+#endif
+
+ RNA_enum_item_end(&item, &totitem);
+ *free = 1;
+
+ return item;
+ }
+#else
+ return audio_device_items;
+#endif
+}
+
#ifdef WITH_INTERNATIONAL
static EnumPropertyItem *rna_lang_enum_properties_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop), int *free)
@@ -3234,20 +3283,6 @@ static void rna_def_userdef_system(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
- static EnumPropertyItem audio_device_items[] = {
- {0, "NONE", 0, "None", "Null device - there will be no audio output"},
-#ifdef WITH_SDL
- {1, "SDL", 0, "SDL", "SDL device - simple direct media layer, recommended for sequencer usage"},
-#endif
-#ifdef WITH_OPENAL
- {2, "OPENAL", 0, "OpenAL", "OpenAL device - supports 3D audio, recommended for game engine usage"},
-#endif
-#ifdef WITH_JACK
- {3, "JACK", 0, "Jack", "JACK - Audio Connection Kit, recommended for pro audio users"},
-#endif
- {0, NULL, 0, NULL, NULL}
- };
-
static EnumPropertyItem audio_rate_items[] = {
/* {8000, "RATE_8000", 0, "8 kHz", "Set audio sampling rate to 8000 samples per second"}, */
/* {11025, "RATE_11025", 0, "11.025 kHz", "Set audio sampling rate to 11025 samples per second"}, */
@@ -3524,6 +3559,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
prop = RNA_def_property(srna, "audio_device", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "audiodevice");
RNA_def_property_enum_items(prop, audio_device_items);
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_userdef_audio_device_itemf");
RNA_def_property_ui_text(prop, "Audio Device", "Audio output device");
RNA_def_property_update(prop, 0, "rna_UserDef_audio_update");