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
path: root/source
diff options
context:
space:
mode:
authorPeter Schlaile <peter@schlaile.de>2009-05-21 14:25:40 +0400
committerPeter Schlaile <peter@schlaile.de>2009-05-21 14:25:40 +0400
commit5fc6afe2405833b9a4963bf66829b736998eec73 (patch)
tree5184bbd7934b7438bf6b6818650669d6a2c3dc92 /source
parent3f584de8ecf76ad084b15eb4fb1e78e827ab1328 (diff)
== Sequencer ==
This fixes: [#18007] Audio playback of a scene strip containing audio is broken. (needed a different recursion protection than video render code, since video and audio render can be called simultaneously because of SDL audio thread callbacks) Also: we don't display a wait cursor, if the scene strip has DOSEQ enabled. (no need to wait, it is the sequencer which is realtime by definition :)
Diffstat (limited to 'source')
-rw-r--r--source/blender/include/BSE_seqaudio.h6
-rw-r--r--source/blender/makesdna/DNA_scene_types.h1
-rw-r--r--source/blender/src/seqaudio.c166
-rw-r--r--source/blender/src/sequence.c9
4 files changed, 139 insertions, 43 deletions
diff --git a/source/blender/include/BSE_seqaudio.h b/source/blender/include/BSE_seqaudio.h
index 64aa50c661d..1886b3e8771 100644
--- a/source/blender/include/BSE_seqaudio.h
+++ b/source/blender/include/BSE_seqaudio.h
@@ -43,10 +43,10 @@
void audio_mixdown();
void audio_makestream(bSound *sound);
-void audiostream_play(uint32_t startframe, uint32_t duration, int mixdown);
+void audiostream_play(int startframe, uint32_t duration, int mixdown);
void audiostream_fill(uint8_t* mixdown, int len);
-void audiostream_start(uint32_t frame);
-void audiostream_scrub(uint32_t frame);
+void audiostream_start(int frame);
+void audiostream_scrub(int frame);
void audiostream_stop(void);
int audiostream_pos(void);
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 36df11ac2e8..a885cbeb2af 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -668,6 +668,7 @@ typedef struct Scene {
#define R_STAMP_INFO 0x4000
#define R_FULL_SAMPLE 0x8000
#define R_COMP_RERENDER 0x10000
+#define R_RECURS_PROTECTION 0x20000
/* r->stamp */
#define R_STAMP_TIME 0x0001
diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c
index 0bc40674350..078750ca118 100644
--- a/source/blender/src/seqaudio.c
+++ b/source/blender/src/seqaudio.c
@@ -95,6 +95,12 @@ static int audio_playing=0;
static int audio_initialised=0;
static int audio_startframe=0;
static double audio_starttime = 0.0;
+static Scene * audio_scene = 0; /* we can't use G.scene, since
+ Sequence Scene strips can change G.scene
+ (and SDL-audio-fill callback can be
+ called while we have G.scene changed!)
+ */
+
/////
//
/* local protos ------------------- */
@@ -217,7 +223,7 @@ void audiostream_fill(uint8_t *mixdown, int len)
#ifndef DISABLE_SDL
for (i = 0; i < len; i += 64) {
CFRA = (int) ( ((float)(audio_pos-64)
- /( G.scene->audio.mixrate*4 ))
+ /( audio_scene->audio.mixrate*4 ))
* FPS );
audio_fill(mixdown + i, NULL,
@@ -238,7 +244,7 @@ static void audio_levels(uint8_t *buf, int len, float db, float facf, float pan)
if (pan>=0) { facr = 1.0; facl = 1.0-pan; }
else { facr = pan+1.0; facl = 1.0; }
- fac = pow(10.0, ((-(db+G.scene->audio.main))/20.0)) / facf;
+ fac = pow(10.0, ((-(db+audio_scene->audio.main))/20.0)) / facf;
facl /= fac;
facr /= fac;
@@ -294,7 +300,8 @@ void audio_makestream(bSound *sound)
#ifndef DISABLE_SDL
static void audio_fill_ram_sound(Sequence *seq, void * mixdown,
- uint8_t * sstream, int len)
+ uint8_t * sstream, int len,
+ int cfra)
{
uint8_t* cvtbuf;
bSound* sound;
@@ -303,10 +310,10 @@ static void audio_fill_ram_sound(Sequence *seq, void * mixdown,
sound = seq->sound;
audio_makestream(sound);
if ((seq->curpos<sound->streamlen -len) && (seq->curpos>=0) &&
- (seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA))
+ (seq->startdisp <= cfra) && ((seq->enddisp) > cfra))
{
if(seq->ipo && seq->ipo->curve.first) {
- do_seq_ipo(seq, CFRA);
+ do_seq_ipo(seq, cfra);
facf = seq->facf0;
} else {
facf = 1.0;
@@ -328,16 +335,16 @@ static void audio_fill_ram_sound(Sequence *seq, void * mixdown,
#ifndef DISABLE_SDL
static void audio_fill_hd_sound(Sequence *seq,
void * mixdown, uint8_t * sstream,
- int len)
+ int len, int cfra)
{
uint8_t* cvtbuf;
float facf;
if ((seq->curpos >= 0) &&
- (seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA))
+ (seq->startdisp <= cfra) && ((seq->enddisp) > cfra))
{
if(seq->ipo && seq->ipo->curve.first) {
- do_seq_ipo(seq, CFRA);
+ do_seq_ipo(seq, cfra);
facf = seq->facf0;
} else {
facf = 1.0;
@@ -346,7 +353,7 @@ static void audio_fill_hd_sound(Sequence *seq,
sound_hdaudio_extract(seq->hdaudio, (short*) cvtbuf,
seq->curpos / 4,
- G.scene->audio.mixrate,
+ audio_scene->audio.mixrate,
2,
len / 4);
audio_levels(cvtbuf, len, seq->level, facf, seq->pan);
@@ -365,19 +372,66 @@ static void audio_fill_hd_sound(Sequence *seq,
#ifndef DISABLE_SDL
static void audio_fill_seq(Sequence * seq, void * mixdown,
- uint8_t *sstream, int len, int advance_only)
+ uint8_t *sstream, int len, int cfra,
+ int advance_only);
+
+static void audio_fill_scene_strip(Sequence * seq, void * mixdown,
+ uint8_t *sstream, int len, int cfra,
+ int advance_only)
+{
+ Editing *ed;
+
+ /* prevent eternal loop */
+ seq->scene->r.scemode |= R_RECURS_PROTECTION;
+
+ ed = seq->scene->ed;
+
+ if (ed) {
+ int sce_cfra = seq->sfra + seq->anim_startofs
+ + cfra - seq->startdisp;
+
+ audio_fill_seq(ed->seqbasep->first,
+ mixdown,
+ sstream, len, sce_cfra,
+ advance_only);
+ }
+
+ /* restore */
+ seq->scene->r.scemode &= ~R_RECURS_PROTECTION;
+}
+#endif
+
+#ifndef DISABLE_SDL
+static void audio_fill_seq(Sequence * seq, void * mixdown,
+ uint8_t *sstream, int len, int cfra,
+ int advance_only)
{
while(seq) {
if (seq->type == SEQ_META &&
(!(seq->flag & SEQ_MUTE))) {
- if (seq->startdisp <= CFRA && seq->enddisp > CFRA) {
+ if (seq->startdisp <= cfra && seq->enddisp > cfra) {
audio_fill_seq(seq->seqbase.first,
mixdown, sstream, len,
- advance_only);
+ cfra, advance_only);
} else {
audio_fill_seq(seq->seqbase.first,
mixdown, sstream, len,
- 1);
+ cfra, 1);
+ }
+ }
+ if (seq->type == SEQ_SCENE
+ && (!(seq->flag & SEQ_MUTE))
+ && seq->scene
+ && (seq->scene->r.scemode & R_DOSEQ)
+ && !(seq->scene->r.scemode & R_RECURS_PROTECTION)) {
+ if (seq->startdisp <= cfra && seq->enddisp > cfra) {
+ audio_fill_scene_strip(
+ seq, mixdown, sstream, len,
+ cfra, advance_only);
+ } else {
+ audio_fill_scene_strip(
+ seq, mixdown, sstream, len,
+ cfra, 1);
}
}
if ( (seq->type == SEQ_RAM_SOUND) &&
@@ -387,7 +441,8 @@ static void audio_fill_seq(Sequence * seq, void * mixdown,
seq->curpos += len;
} else {
audio_fill_ram_sound(
- seq, mixdown, sstream, len);
+ seq, mixdown, sstream, len,
+ cfra);
}
}
if ( (seq->type == SEQ_HD_SOUND) &&
@@ -405,7 +460,8 @@ static void audio_fill_seq(Sequence * seq, void * mixdown,
}
if (seq->hdaudio) {
audio_fill_hd_sound(seq, mixdown,
- sstream, len);
+ sstream, len,
+ cfra);
}
}
}
@@ -420,10 +476,15 @@ static void audio_fill(void *mixdown, uint8_t *sstream, int len)
Editing *ed;
Sequence *seq;
- ed = G.scene->ed;
- if((ed) && (!(G.scene->audio.flag & AUDIO_MUTE))) {
+ if (!audio_scene) {
+ return;
+ }
+
+ ed = audio_scene->ed;
+ if((ed) && (!(audio_scene->audio.flag & AUDIO_MUTE))) {
seq = ed->seqbasep->first;
- audio_fill_seq(seq, mixdown, sstream, len, 0);
+ audio_fill_seq(seq, mixdown, sstream, len,
+ audio_scene->r.cfra, 0);
}
audio_pos += len;
@@ -463,7 +524,7 @@ static int audio_init(SDL_AudioSpec *desired)
}
#endif
-static int audiostream_play_seq(Sequence * seq, uint32_t startframe)
+static int audiostream_play_seq(Sequence * seq, int startframe)
{
char name[FILE_MAXDIR+FILE_MAXFILE];
int have_sound = 0;
@@ -475,14 +536,38 @@ static int audiostream_play_seq(Sequence * seq, uint32_t startframe)
have_sound = 1;
}
}
+ if (seq->type == SEQ_SCENE
+ && seq->scene
+ && (seq->scene->r.scemode & R_DOSEQ)
+ && !(seq->scene->r.scemode & R_RECURS_PROTECTION)) {
+ Editing *ed;
+
+ /* prevent eternal loop */
+ seq->scene->r.scemode |= R_RECURS_PROTECTION;
+
+ ed = seq->scene->ed;
+
+ if (ed) {
+ int sce_cfra = seq->sfra + seq->anim_startofs
+ + startframe - seq->startdisp;
+
+ if (audiostream_play_seq(ed->seqbasep->first,
+ sce_cfra)) {
+ have_sound = 1;
+ }
+ }
+
+ /* restore */
+ seq->scene->r.scemode &= ~R_RECURS_PROTECTION;
+ }
if ((seq->type == SEQ_RAM_SOUND) && (seq->sound)) {
have_sound = 1;
- seq->curpos = (int)( (FRA2TIME(
- (double) startframe -
- (double) seq->start +
- (double)
- seq->anim_startofs)
- * ((float)G.scene->audio.mixrate)
+ seq->curpos = (int)( (FRA2TIME(((double) startframe) -
+ ((double) seq->start) +
+ ((double)
+ seq->anim_startofs))
+ * ((float)audio_scene
+ ->audio.mixrate)
* 4 ));
}
if ((seq->type == SEQ_HD_SOUND)) {
@@ -494,11 +579,13 @@ static int audiostream_play_seq(Sequence * seq, uint32_t startframe)
seq->hdaudio = sound_open_hdaudio(name);
}
- seq->curpos = (int)( (FRA2TIME((double) startframe -
- (double) seq->start +
- (double)
- seq->anim_startofs)
- * ((float)G.scene->audio.mixrate)
+
+ seq->curpos = (int)( (FRA2TIME(((double) startframe) -
+ ((double) seq->start) +
+ ((double)
+ seq->anim_startofs))
+ * ((float)audio_scene
+ ->audio.mixrate)
* 4 ));
}
seq= seq->next;
@@ -506,14 +593,16 @@ static int audiostream_play_seq(Sequence * seq, uint32_t startframe)
return have_sound;
}
-void audiostream_play(uint32_t startframe, uint32_t duration, int mixdown)
+void audiostream_play(int startframe, uint32_t duration, int mixdown)
{
#ifndef DISABLE_SDL
static SDL_AudioSpec desired;
Editing *ed;
int have_sound = 0;
- ed= G.scene->ed;
+ audio_scene = G.scene;
+
+ ed= audio_scene->ed;
if(ed) {
have_sound =
audiostream_play_seq(ed->seqbasep->first, startframe);
@@ -525,7 +614,7 @@ void audiostream_play(uint32_t startframe, uint32_t duration, int mixdown)
}
if (U.mixbufsize && !audio_initialised && !mixdown) {
- desired.freq=G.scene->audio.mixrate;
+ desired.freq=audio_scene->audio.mixrate;
desired.format=AUDIO_S16SYS;
desired.channels=2;
desired.samples=U.mixbufsize;
@@ -538,7 +627,7 @@ void audiostream_play(uint32_t startframe, uint32_t duration, int mixdown)
audio_startframe = startframe;
audio_pos = ( ((int)( FRA2TIME(startframe)
- *(G.scene->audio.mixrate)*4 )) & (~3) );
+ *(audio_scene->audio.mixrate)*4 )) & (~3) );
audio_starttime = PIL_check_seconds_timer();
/* if audio already is playing, just reseek, otherwise
@@ -553,12 +642,12 @@ void audiostream_play(uint32_t startframe, uint32_t duration, int mixdown)
#endif
}
-void audiostream_start(uint32_t frame)
+void audiostream_start(int frame)
{
audiostream_play(frame, 0, 0);
}
-void audiostream_scrub(uint32_t frame)
+void audiostream_scrub(int frame)
{
if (U.mixbufsize) audiostream_play(frame, 4096/U.mixbufsize, 0);
}
@@ -568,6 +657,7 @@ void audiostream_stop(void)
#ifndef DISABLE_SDL
SDL_PauseAudio(1);
audio_playing=0;
+ audio_scene=0;
#endif
}
@@ -575,9 +665,9 @@ int audiostream_pos(void)
{
int pos;
- if (U.mixbufsize) {
+ if (U.mixbufsize && audio_scene) {
pos = (int) (((double)(audio_pos-U.mixbufsize)
- / ( G.scene->audio.mixrate*4 ))
+ / ( audio_scene->audio.mixrate*4 ))
* FPS );
} else { /* fallback to seconds_timer when no audio available */
pos = (int) ((PIL_check_seconds_timer() - audio_starttime)
diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c
index cd42c3d4085..edc68d016a1 100644
--- a/source/blender/src/sequence.c
+++ b/source/blender/src/sequence.c
@@ -1884,7 +1884,10 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
if (!sce_valid) {
se->ok = STRIPELEM_FAILED;
} else if (se->ibuf==NULL && sce_valid) {
- waitcursor(1);
+ /* no need to display a waitcursor on sequencer
+ scene strips */
+ if (!(sce->r.scemode & R_DOSEQ))
+ waitcursor(1);
/* Hack! This function can be called from do_render_seq(), in that case
the seq->scene can already have a Render initialized with same name,
@@ -1935,7 +1938,9 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
/* restore */
G.scene->r.scemode |= doseq;
- if((G.f & G_PLAYANIM)==0) /* bad, is set on do_render_seq */
+ if((G.f & G_PLAYANIM)==0 /* bad, is set on do_render_seq */
+ && !(sce->r.scemode & R_DOSEQ))
+
waitcursor(0);
CFRA = oldcfra;
set_last_seq(oldseq);