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--intern/audaspace/intern/AUD_C-API.cpp63
-rw-r--r--intern/audaspace/intern/AUD_C-API.h13
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.cpp161
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.h45
-rw-r--r--source/blender/blenkernel/BKE_sound.h4
-rw-r--r--source/blender/blenkernel/intern/sequencer.c4
-rw-r--r--source/blender/blenkernel/intern/sound.c77
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/screen/screen_ops.c45
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c23
-rw-r--r--source/blender/windowmanager/intern/wm_files.c8
12 files changed, 372 insertions, 74 deletions
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 3c29b5d9e08..d2540d59eda 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -761,6 +761,69 @@ int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length)
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)
{
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index ce1791886de..a252ad904b6 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -52,6 +52,7 @@ typedef struct
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 void AUD_muteSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry,
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
diff --git a/intern/audaspace/jack/AUD_JackDevice.cpp b/intern/audaspace/jack/AUD_JackDevice.cpp
index dfb2a60d629..ae7725be81c 100644
--- a/intern/audaspace/jack/AUD_JackDevice.cpp
+++ b/intern/audaspace/jack/AUD_JackDevice.cpp
@@ -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 @@ void AUD_JackDevice::updateRingBuffers()
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 @@ void AUD_JackDevice::updateRingBuffers()
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 AUD_JackDevice::jack_mix(jack_nframes_t length, void *data)
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 @@ AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs, int buffersize)
// 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 @@ AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs, int buffersize)
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 @@ AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs, int buffersize)
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 @@ AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs, int buffersize)
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 @@ AUD_JackDevice::~AUD_JackDevice()
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 @@ void AUD_JackDevice::playing(bool playing)
{
// 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;
+}
diff --git a/intern/audaspace/jack/AUD_JackDevice.h b/intern/audaspace/jack/AUD_JackDevice.h
index 96388e1ee50..58e34978c1f 100644
--- a/intern/audaspace/jack/AUD_JackDevice.h
+++ b/intern/audaspace/jack/AUD_JackDevice.h
@@ -33,6 +33,8 @@ class AUD_Buffer;
#include <jack.h>
#include <ringbuffer.h>
+typedef void (*AUD_syncFunction)(void*, int, float);
+
/**
* This device plays back through Jack.
*/
@@ -56,6 +58,8 @@ private:
AUD_Buffer* m_deinterleavebuf;
+ jack_ringbuffer_t** m_ringbuffers;
+
/**
* Whether the device is valid.
*/
@@ -75,20 +79,40 @@ private:
*/
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;
/**
- * The streaming thread.
+ * External syncronisation callback function.
*/
- pthread_t m_thread;
+ AUD_syncFunction m_syncFunc;
- pthread_mutex_t m_lock;
+ /**
+ * Data for the sync function.
+ */
+ void* m_syncFuncData;
+
+ /**
+ * The mixing thread.
+ */
+ pthread_t m_mixingThread;
+
+ pthread_mutex_t m_mixingLock;
- pthread_cond_t m_condition;
+ pthread_cond_t m_mixingCondition;
+
+ static void* runMixingThread(void* device);
+
+ void updateRingBuffers();
protected:
virtual void playing(bool playing);
@@ -105,6 +129,13 @@ public:
* Closes the Jack client.
*/
virtual ~AUD_JackDevice();
+
+ void startPlayback();
+ void stopPlayback();
+ void seekPlayback(float time);
+ void setSyncCallback(AUD_syncFunction sync, void* data);
+ float getPlaybackPosition();
+ bool doesPlayback();
};
#endif //AUD_JACKDEVICE
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 97a2adb6e6b..fa035d62d62 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -38,7 +38,7 @@ struct ListBase;
struct Main;
struct Sequence;
-void sound_init();
+void sound_init(struct Main *main);
void sound_exit();
@@ -88,6 +88,8 @@ void sound_seek_scene(struct bContext *C);
float sound_sync_scene(struct Scene *scene);
+int sound_scene_playing(struct Scene *scene);
+
int sound_read_sound_buffer(struct bSound* sound, float* buffer, int length);
#endif
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 2ee913a6b6b..98dbf83f032 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -614,7 +614,7 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
}
seq->strip->len = seq->len;
} else if (seq->type == SEQ_SOUND) {
- seq->len = AUD_getInfo(seq->sound->playback_handle).length * FPS;
+ seq->len = ceil(AUD_getInfo(seq->sound->playback_handle).length * FPS);
seq->len -= seq->anim_startofs;
seq->len -= seq->anim_endofs;
if (seq->len < 0) {
@@ -3848,7 +3848,7 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
/* basic defaults */
seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
- strip->len = seq->len = (int) (info.length * FPS);
+ strip->len = seq->len = ceil(info.length * FPS);
strip->us= 1;
strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 4e08a52d992..a1a6880569b 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -39,6 +39,26 @@
static int force_device = -1;
+static void sound_sync_callback(void* data, int mode, float time)
+{
+ struct Main* main = (struct Main*)data;
+ struct Scene* scene;
+
+ scene = main->scene.first;
+ while(scene)
+ {
+ if(scene->audio.flag & AUDIO_SYNC)
+ {
+ if(mode)
+ sound_play_scene(scene);
+ else
+ sound_stop_scene(scene);
+ AUD_seek(scene->sound_scene_handle, time);
+ }
+ scene = scene->id.next;
+ }
+}
+
int sound_define_from_str(char *str)
{
if (BLI_strcaseeq(str, "NULL"))
@@ -58,7 +78,7 @@ void sound_force_device(int device)
force_device = device;
}
-void sound_init()
+void sound_init(struct Main *main)
{
AUD_DeviceSpecs specs;
int device, buffersize;
@@ -86,6 +106,7 @@ void sound_init()
if(!AUD_init(device, specs, buffersize))
AUD_init(AUD_NULL_DEVICE, specs, buffersize);
+ AUD_setSyncCallback(sound_sync_callback, main);
}
void sound_exit()
@@ -353,14 +374,24 @@ void sound_start_play_scene(struct Scene *scene)
void sound_play_scene(struct Scene *scene)
{
+ AUD_Status status;
AUD_lock();
- if(!scene->sound_scene_handle || AUD_getStatus(scene->sound_scene_handle) == AUD_STATUS_INVALID)
+ status = AUD_getStatus(scene->sound_scene_handle);
+
+ if(status == AUD_STATUS_INVALID)
sound_start_play_scene(scene);
- AUD_seek(scene->sound_scene_handle, CFRA / FPS);
AUD_setLoop(scene->sound_scene_handle, -1, -1);
- AUD_resume(scene->sound_scene_handle);
+
+ if(status != AUD_STATUS_PLAYING)
+ {
+ AUD_seek(scene->sound_scene_handle, CFRA / FPS);
+ AUD_resume(scene->sound_scene_handle);
+ }
+
+ if(scene->audio.flag & AUDIO_SYNC)
+ AUD_startPlayback();
AUD_unlock();
}
@@ -368,15 +399,21 @@ void sound_play_scene(struct Scene *scene)
void sound_stop_scene(struct Scene *scene)
{
AUD_pause(scene->sound_scene_handle);
+
+ if(scene->audio.flag & AUDIO_SYNC)
+ AUD_stopPlayback();
}
void sound_seek_scene(struct bContext *C)
{
struct Scene *scene = CTX_data_scene(C);
+ AUD_Status status;
AUD_lock();
- if(!scene->sound_scene_handle || AUD_getStatus(scene->sound_scene_handle) == AUD_STATUS_INVALID)
+ status = AUD_getStatus(scene->sound_scene_handle);
+
+ if(status == AUD_STATUS_INVALID)
{
sound_start_play_scene(scene);
AUD_pause(scene->sound_scene_handle);
@@ -385,21 +422,43 @@ void sound_seek_scene(struct bContext *C)
if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer)
{
AUD_setLoop(scene->sound_scene_handle, -1, 1 / FPS);
- AUD_seek(scene->sound_scene_handle, CFRA / FPS);
+ if(scene->audio.flag & AUDIO_SYNC)
+ AUD_seekSequencer(scene->sound_scene_handle, CFRA / FPS);
+ else
+ AUD_seek(scene->sound_scene_handle, CFRA / FPS);
AUD_resume(scene->sound_scene_handle);
}
else
- AUD_seek(scene->sound_scene_handle, CFRA / FPS);
+ {
+ if(scene->audio.flag & AUDIO_SYNC)
+ AUD_seekSequencer(scene->sound_scene_handle, CFRA / FPS);
+ else
+ {
+ if(status == AUD_STATUS_PLAYING)
+ AUD_seek(scene->sound_scene_handle, CFRA / FPS);
+ }
+ }
AUD_unlock();
}
float sound_sync_scene(struct Scene *scene)
{
- return AUD_getPosition(scene->sound_scene_handle);
+ if(scene->audio.flag & AUDIO_SYNC)
+ return AUD_getSequencerPosition(scene->sound_scene_handle);
+ else
+ return AUD_getPosition(scene->sound_scene_handle);
+}
+
+int sound_scene_playing(struct Scene *scene)
+{
+ if(scene->audio.flag & AUDIO_SYNC)
+ return AUD_doesPlayback();
+ else
+ return -1;
}
-int sound_read_sound_buffer(bSound* sound, float* buffer, int length)
+int sound_read_sound_buffer(struct bSound* sound, float* buffer, int length)
{
return AUD_readSound(sound->cache, buffer, length);
}
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 5121308c745..aae354b79fa 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -108,6 +108,7 @@ void ED_screen_new_window(struct bContext *C, struct rcti *position, int type);
/* anim */
void ED_update_for_newframe(const struct bContext *C, int mute);
void ED_refresh_viewport_fps(struct bContext *C);
+int ED_screen_animation_play(struct bContext *C, int sync, int mode);
/* screen keymaps */
void ED_operatortypes_screen(void);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index fae7e7b6c40..0c958654722 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -2537,11 +2537,11 @@ static void SCREEN_OT_animation_step(wmOperatorType *ot)
/* ****************** anim player, starts or ends timer ***************** */
/* toggle operator */
-static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event)
+int ED_screen_animation_play(bContext *C, int sync, int mode)
{
bScreen *screen= CTX_wm_screen(C);
struct Scene* scene = CTX_data_scene(C);
-
+
if(screen->animtimer) {
/* stop playback now */
ED_screen_animation_timer(C, 0, 0, 0);
@@ -2549,45 +2549,52 @@ static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event)
}
else {
ScrArea *sa= CTX_wm_area(C);
- int mode= (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1;
- int sync= -1;
+
if(mode == 1) // XXX only play audio forwards!?
sound_play_scene(scene);
-
- if(RNA_property_is_set(op->ptr, "sync"))
- sync= (RNA_boolean_get(op->ptr, "sync"));
-
+
/* timeline gets special treatment since it has it's own menu for determining redraws */
if ((sa) && (sa->spacetype == SPACE_TIME)) {
SpaceTime *stime= (SpaceTime *)sa->spacedata.first;
-
+
ED_screen_animation_timer(C, stime->redraws, sync, mode);
-
+
/* update region if TIME_REGION was set, to leftmost 3d window */
ED_screen_animation_timer_update(screen, stime->redraws);
}
else {
int redraws = TIME_REGION|TIME_ALL_3D_WIN;
-
+
/* XXX - would like a better way to deal with this situation - Campbell */
- if((sa) && (sa->spacetype == SPACE_SEQ)) {
+ if((!sa) || (sa->spacetype == SPACE_SEQ)) {
redraws |= TIME_SEQ;
}
-
+
ED_screen_animation_timer(C, redraws, sync, mode);
-
+
if(screen->animtimer) {
wmTimer *wt= screen->animtimer;
ScreenAnimData *sad= wt->customdata;
-
+
sad->ar= CTX_wm_region(C);
}
}
}
-
+
return OPERATOR_FINISHED;
}
+static int screen_animation_play_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ int mode= (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1;
+ int sync= -1;
+
+ if(RNA_property_is_set(op->ptr, "sync"))
+ sync= (RNA_boolean_get(op->ptr, "sync"));
+
+ return ED_screen_animation_play(C, sync, mode);
+}
+
static void SCREEN_OT_animation_play(wmOperatorType *ot)
{
/* identifiers */
@@ -2596,12 +2603,12 @@ static void SCREEN_OT_animation_play(wmOperatorType *ot)
ot->idname= "SCREEN_OT_animation_play";
/* api callbacks */
- ot->invoke= screen_animation_play;
+ ot->invoke= screen_animation_play_invoke;
ot->poll= ED_operator_screenactive;
RNA_def_boolean(ot->srna, "reverse", 0, "Play in Reverse", "Animation is played backwards");
- RNA_def_boolean(ot->srna, "sync", 0, "Sync", "Drop frames to maintain framerate and stay in sync with audio.");
+ RNA_def_boolean(ot->srna, "sync", 0, "Sync", "Drop frames to maintain framerate");
}
static int screen_animation_cancel(bContext *C, wmOperator *op, wmEvent *event)
@@ -2619,7 +2626,7 @@ static int screen_animation_cancel(bContext *C, wmOperator *op, wmEvent *event)
WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
/* call the other "toggling" operator to clean up now */
- return screen_animation_play(C, op, event);
+ return screen_animation_play_invoke(C, op, event);
}
return OPERATOR_PASS_THROUGH;
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 7cb7e69f047..ee2c96bcbd2 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -176,7 +176,7 @@ static PointerRNA rna_UserDef_system_get(PointerRNA *ptr)
static void rna_UserDef_audio_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- sound_init();
+ sound_init(bmain);
}
static void rna_UserDef_weight_color_update(Main *bmain, Scene *scene, PointerRNA *ptr)
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 4b07aa82239..74679ce89a6 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -50,6 +50,7 @@
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
+#include "BKE_sound.h"
#include "ED_fileselect.h"
#include "ED_info.h"
@@ -1530,6 +1531,28 @@ void wm_event_do_handlers(bContext *C)
if( win->screen==NULL )
wm_event_free_all(win);
+ else
+ {
+ if(win->screen->scene)
+ {
+ int playing = sound_scene_playing(win->screen->scene);
+ if(playing != -1)
+ {
+ if(((playing == 1) && (!win->screen->animtimer)) || ((playing == 0) && (win->screen->animtimer)))
+ {
+ CTX_wm_window_set(C, win);
+ CTX_wm_screen_set(C, win->screen);
+ CTX_data_scene_set(C, win->screen->scene);
+
+ ED_screen_animation_play(C, -1, 1);
+
+ CTX_data_scene_set(C, NULL);
+ CTX_wm_screen_set(C, NULL);
+ CTX_wm_window_set(C, NULL);
+ }
+ }
+ }
+ }
while( (event= win->queue.first) ) {
int action = WM_HANDLER_CONTINUE;
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index efa8aa7e819..16776517e40 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -236,11 +236,11 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist)
}
/* in case UserDef was read, we re-initialize all, and do versioning */
-static void wm_init_userdef()
+static void wm_init_userdef(bContext *C)
{
UI_init_userdef();
MEM_CacheLimiter_set_maximum(U.memcachelimit * 1024 * 1024);
- sound_init();
+ sound_init(CTX_data_main(C));
}
void WM_read_file(bContext *C, char *name, ReportList *reports)
@@ -269,7 +269,7 @@ void WM_read_file(bContext *C, char *name, ReportList *reports)
// XXX mainwindow_set_filename_to_title(G.main->name);
- if(retval==2) wm_init_userdef(); // in case a userdef is read from regular .blend
+ if(retval==2) wm_init_userdef(C); // in case a userdef is read from regular .blend
if (retval!=0) {
G.relbase_valid = 1;
@@ -338,7 +338,7 @@ int WM_read_homefile(bContext *C, wmOperator *op)
strcpy(G.sce, scestr); /* restore */
- wm_init_userdef();
+ wm_init_userdef(C);
/* When loading factory settings, the reset solid OpenGL lights need to be applied. */
if (!G.background) GPU_default_lights();