[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20805] trunk/blender/source/blender: == SEQUENCER ==

Peter Schlaile peter at schlaile.de
Thu Jun 11 13:44:47 CEST 2009


Revision: 20805
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20805
Author:   schlaile
Date:     2009-06-11 13:44:47 +0200 (Thu, 11 Jun 2009)

Log Message:
-----------
== SEQUENCER ==

This fixes 
* some issues with Scene strips containing audio by removing
  the curpos pointer from sequence structure. (the same scene
  strip can now be used in a row)

  That also makes the code a lot cleaner.
* fixed a corner case on the beginning of a strip, where audio was
  not mixed in, depending of current audio buffer state.
  
* Also: made some hardwired variables macros to enhance readability.

Problem remaining: mixing the same scene strip several times (read
put it into a stack instead of into a row) has
problems with HD-audio since the same HD-audio state structure is
used and therefore the system will seek permanently, which leads to
audio distortions...

Modified Paths:
--------------
    trunk/blender/source/blender/makesdna/DNA_sequence_types.h
    trunk/blender/source/blender/src/seqaudio.c

Modified: trunk/blender/source/blender/makesdna/DNA_sequence_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_sequence_types.h	2009-06-11 10:46:13 UTC (rev 20804)
+++ trunk/blender/source/blender/makesdna/DNA_sequence_types.h	2009-06-11 11:44:47 UTC (rev 20805)
@@ -159,7 +159,7 @@
 	struct bSound *sound;	/* the linked "bSound" object */
         struct hdaudio *hdaudio; /* external hdaudio object */
 	float level, pan;	/* level in dB (0=full), pan -1..1 */
-	int curpos;		/* last sample position in audio_fill() */
+	int scenenr;          /* for scene selection */
 	float strobe;
 
 	void *effectdata;	/* Struct pointer for effect settings */
@@ -170,8 +170,6 @@
 	int blend_mode;
 	float blend_opacity;
 
-	int scenenr;          /* for scene selection */
-	int pad;
 } Sequence;
 
 typedef struct MetaStack {

Modified: trunk/blender/source/blender/src/seqaudio.c
===================================================================
--- trunk/blender/source/blender/src/seqaudio.c	2009-06-11 10:46:13 UTC (rev 20804)
+++ trunk/blender/source/blender/src/seqaudio.c	2009-06-11 11:44:47 UTC (rev 20805)
@@ -104,6 +104,10 @@
 #define AFRA2TIME(a)           ((((double) audio_scene->r.frs_sec_base) * (a)) / audio_scene->r.frs_sec)
 #define ATIME2FRA(a)           ((((double) audio_scene->r.frs_sec) * (a)) / audio_scene->r.frs_sec_base)
 
+/* we do currently stereo 16 bit mixing only */
+#define AUDIO_CHANNELS 2
+#define SAMPLE_SIZE (AUDIO_CHANNELS * sizeof(short))
+
 /////
 //
 /* local protos ------------------- */
@@ -149,7 +153,8 @@
 
 	strcpy(buf, "RIFFlengWAVEfmt fmln01ccRATEbsecBP16dataDLEN");
 	totframe = (EFRA - SFRA + 1);
-	totlen = (int) ( FRA2TIME(totframe) * (float)G.scene->audio.mixrate * 4.0);
+	totlen = (int) ( FRA2TIME(totframe) 
+			 * (float)G.scene->audio.mixrate * SAMPLE_SIZE);
 	printf(" totlen %d\n", totlen+36+8);
 	
 	totlen+= 36;	/* len is filesize-8 in WAV spec, total header is 44 bytes */
@@ -159,7 +164,7 @@
 	buf[16] = 0x10; buf[17] = buf[18] = buf[19] = 0; buf[20] = 1; buf[21] = 0;
 	buf[22] = 2; buf[23]= 0;
 	memcpy(buf+24, &G.scene->audio.mixrate, 4);
-	i = G.scene->audio.mixrate * 4;
+	i = G.scene->audio.mixrate * SAMPLE_SIZE;
 	memcpy(buf+28, &i, 4);
 	buf[32] = 4; buf[33] = 0; buf[34] = 16; buf[35] = 0;
 	i = totlen;
@@ -192,7 +197,8 @@
 		
 		memset(buf+i, 0, 64);
 		
-		CFRA=(int) ( ((float)(audio_pos-64)/( G.scene->audio.mixrate*4 ))*FPS );
+		CFRA=(int) ( ((float)(audio_pos-64)
+			      / ( G.scene->audio.mixrate*SAMPLE_SIZE ))*FPS );
 			
 		audio_fill(buf+i, NULL, 64);
 		if (G.order == B_ENDIAN) {
@@ -226,7 +232,7 @@
 #ifndef DISABLE_SDL
 	for (i = 0; i < len; i += 64) {
 		CFRA = (int) ( ((float)(audio_pos-64)
-				/( audio_scene->audio.mixrate*4 ))
+				/( audio_scene->audio.mixrate * SAMPLE_SIZE ))
 			       * FPS );
 
 		audio_fill(mixdown + i, NULL, 
@@ -251,7 +257,7 @@
 	
 	fac = pow(10.0, ((-(db+audio_scene->audio.main))/20.0));
 
-	for (i=0; i<len; i+=4) {
+	for (i = 0; i < len; i += SAMPLE_SIZE) {
 		float facf = facf_start + ((double) i) * m;
 		float f_l = facl / (fac / facf);
 		float f_r = facr / (fac / facf);
@@ -276,31 +282,52 @@
 		return;
 	}
 	ratio = (float)G.scene->audio.mixrate / (float)sound->sample->rate;
-	sound->streamlen = (int) ( (float)sound->sample->len * ratio * 2.0/((float)sound->sample->channels) );
+	sound->streamlen = (int) ( (float)sound->sample->len * ratio 
+				   * AUDIO_CHANNELS 
+				   / ((float)sound->sample->channels) );
 	sound->stream = malloc((int) ((float)sound->streamlen * 1.05));
 	if (sound->sample->rate == G.scene->audio.mixrate) {
-		if (sound->sample->channels == 2) {
-			memcpy(sound->stream, sound->sample->data, sound->streamlen);
+		if (sound->sample->channels == AUDIO_CHANNELS) {
+			memcpy(sound->stream, 
+			       sound->sample->data, sound->streamlen);
 		   	return;
-		} else {
+		} else if (sound->sample->channels == 1) {
 			for (source = (signed short*)(sound->sample->data),
 			     dest = (signed short*)(sound->stream),
 				 i=0;
-				 i<sound->streamlen/4;
-				 dest += 2, source++, i++) dest[0] = dest[1] = source[0];
+				 i<sound->streamlen/SAMPLE_SIZE;
+			     dest += 2, source++, i++) {
+				int j;
+				for (j = 0; j < AUDIO_CHANNELS; j++) {
+					dest[j] = source[0];
+				}
+			}
 			return;
+		} else {
+			fprintf(stderr, "audio_makestream: "
+				"FIXME: can't handle number of channels %d\n",
+				sound->sample->channels);
+			return;
 		}
 	}
 	if (sound->sample->channels == 1) {
-		for (dest=(signed short*)(sound->stream), i=0, source=(signed short*)(sound->sample->data); 
-		     i<(sound->streamlen/4); dest+=2, i++)
-			dest[0] = dest[1] = source[(int)((float)i/ratio)];
+		for (dest = (signed short*)(sound->stream), i=0, 
+			     source = (signed short*)(sound->sample->data); 
+		     i<(sound->streamlen/SAMPLE_SIZE); 
+		     dest += AUDIO_CHANNELS, i++) {
+			int j;
+			int s = source[(int)((float)i/ratio)];
+			for (j = 0; j < AUDIO_CHANNELS; j++) {
+				dest[j] = s;
+			}
+		}
 	}
 	else if (sound->sample->channels == 2) {
-		for (dest=(signed short*)(sound->stream), i=0, source=(signed short*)(sound->sample->data); 
-		     i<(sound->streamlen/2); dest+=2, i+=2) {
+		for (dest=(signed short*)(sound->stream), i=0, 
+			     source = (signed short*)(sound->sample->data); 
+		     i<(sound->streamlen / 2); dest += AUDIO_CHANNELS, i+=2) {
 			dest[1] = source[(int)((float)i/ratio)];
-			dest[0] = source[(int)((float)i/ratio)+1];			
+			dest[0] = source[(int)((float)i/ratio)+1];
 		}
 	}	
 }
@@ -315,24 +342,37 @@
 				  seq->anim_startofs))
 		       * ((float)audio_scene
 			  ->audio.mixrate)
-		       * 4 ));
+		       * SAMPLE_SIZE));
 }
 
 static int curpos2fra(Sequence * seq, int curpos)
 {
 	return ((int) floor(
 			ATIME2FRA(
-				((double) curpos) / 4 
+				((double) curpos) / SAMPLE_SIZE 
 				/audio_scene->audio.mixrate)))
 		- seq->anim_startofs + seq->start;
 }
 
+static int get_curpos(Sequence * seq, int cfra)
+{
+	return audio_pos + 
+		(((int)((FRA2TIME(((double) cfra) 
+				 - ((double) audio_scene->r.cfra)
+				 - ((double) seq->start) 
+				 + ((double) seq->anim_startofs))
+			* ((float)audio_scene->audio.mixrate)
+			* SAMPLE_SIZE )))
+		 & (~(SAMPLE_SIZE - 1))); /* has to be sample aligned! */
+}
+
 static void do_audio_seq_ipo(Sequence * seq, int len, float * facf_start,
-			     float * facf_end)
+			     float * facf_end, int cfra)
 {
-	int cfra_start = curpos2fra(seq, seq->curpos);
+	int seq_curpos = get_curpos(seq, cfra);
+	int cfra_start = curpos2fra(seq, seq_curpos);
 	int cfra_end = cfra_start + 1;
-	int ipo_curpos_start = fra2curpos(seq, curpos2fra(seq, seq->curpos));
+	int ipo_curpos_start = fra2curpos(seq, curpos2fra(seq, seq_curpos));
 	int ipo_curpos_end = fra2curpos(seq, cfra_end);
 	double ipo_facf_start;
 	double ipo_facf_end;
@@ -346,8 +386,8 @@
 
 	m = (ipo_facf_end- ipo_facf_start)/(ipo_curpos_end - ipo_curpos_start);
 	
-	*facf_start = ipo_facf_start + (seq->curpos - ipo_curpos_start) * m;
-	*facf_end = ipo_facf_start + (seq->curpos + len-ipo_curpos_start) * m;
+	*facf_start = ipo_facf_start + (seq_curpos - ipo_curpos_start) * m;
+	*facf_end = ipo_facf_start + (seq_curpos + len-ipo_curpos_start) * m;
 }
 
 #endif
@@ -361,20 +401,30 @@
 	bSound* sound;
 	float facf_start;
 	float facf_end;
+	int seq_curpos = get_curpos(seq, cfra);
 
+	/* catch corner case at the beginning of strip */
+	if (seq_curpos < 0 && (seq_curpos + len > 0)) {
+		seq_curpos *= -1;
+		len -= seq_curpos;
+		sstream += seq_curpos;
+		seq_curpos = 0;
+	}
+
 	sound = seq->sound;
 	audio_makestream(sound);
-	if ((seq->curpos<sound->streamlen -len) && (seq->curpos>=0) &&
+	if ((seq_curpos < sound->streamlen -len) && (seq_curpos >= 0) &&
 	    (seq->startdisp <= cfra) && ((seq->enddisp) > cfra))
 	{
 		if(seq->ipo && seq->ipo->curve.first) {
-			do_audio_seq_ipo(seq, len, &facf_start, &facf_end);
+			do_audio_seq_ipo(seq, len, &facf_start, &facf_end,
+					 cfra);
 		} else {
 			facf_start = 1.0;
 			facf_end = 1.0;
 		}
 		cvtbuf = malloc(len);					
-		memcpy(cvtbuf, ((uint8_t*)sound->stream)+(seq->curpos & (~3)), len);
+		memcpy(cvtbuf, ((uint8_t*)sound->stream)+(seq_curpos), len);
 		audio_levels(cvtbuf, len, seq->level, facf_start, facf_end, 
 			     seq->pan);
 		if (!mixdown) {
@@ -384,7 +434,6 @@
 		}
 		free(cvtbuf);
 	}
-	seq->curpos += len;
 }
 #endif
 
@@ -396,12 +445,22 @@
 	uint8_t* cvtbuf;
 	float facf_start;
 	float facf_end;
+	int seq_curpos = get_curpos(seq, cfra);
 
-	if ((seq->curpos >= 0) &&
+	/* catch corner case at the beginning of strip */
+	if (seq_curpos < 0 && (seq_curpos + len > 0)) {
+		seq_curpos *= -1;
+		len -= seq_curpos;
+		sstream += seq_curpos;
+		seq_curpos = 0;
+	}
+
+	if ((seq_curpos >= 0) &&
 	    (seq->startdisp <= cfra) && ((seq->enddisp) > cfra))
 	{
 		if(seq->ipo && seq->ipo->curve.first) {
-			do_audio_seq_ipo(seq, len, &facf_start, &facf_end);
+			do_audio_seq_ipo(seq, len, &facf_start, &facf_end,
+					 cfra);
 		} else {
 			facf_start = 1.0;
 			facf_end = 1.0;
@@ -409,10 +468,10 @@
 		cvtbuf = malloc(len);
 		
 		sound_hdaudio_extract(seq->hdaudio, (short*) cvtbuf,
-				      seq->curpos / 4,
+				      seq_curpos / SAMPLE_SIZE,
 				      audio_scene->audio.mixrate,
-				      2,
-				      len / 4);
+				      AUDIO_CHANNELS,
+				      len / SAMPLE_SIZE);
 		audio_levels(cvtbuf, len, seq->level, facf_start, facf_end,
 			     seq->pan);
 		if (!mixdown) {
@@ -424,18 +483,15 @@
 		}
 		free(cvtbuf);
 	}
-	seq->curpos += len;
 }
 #endif
 
 #ifndef DISABLE_SDL
 static void audio_fill_seq(Sequence * seq, void * mixdown,
-			   uint8_t *sstream, int len, int cfra,
-			   int advance_only);
+			   uint8_t *sstream, int len, int cfra);
 
 static void audio_fill_scene_strip(Sequence * seq, void * mixdown,
-				   uint8_t *sstream, int len, int cfra,
-				   int advance_only)
+				   uint8_t *sstream, int len, int cfra)
 {
 	Editing *ed;
 
@@ -450,8 +506,7 @@
 
 		audio_fill_seq(ed->seqbasep->first,
 			       mixdown,
-			       sstream, len, sce_cfra,
-			       advance_only);
+			       sstream, len, sce_cfra);
 	}
 	
 	/* restore */
@@ -461,8 +516,7 @@
 
 #ifndef DISABLE_SDL
 static void audio_fill_seq(Sequence * seq, void * mixdown,
-			   uint8_t *sstream, int len, int cfra,
-			   int advance_only)
+			   uint8_t *sstream, int len, int cfra)
 {
 	while(seq) {
 		if (seq->type == SEQ_META &&
@@ -470,11 +524,7 @@
 			if (seq->startdisp <= cfra && seq->enddisp > cfra) {
 				audio_fill_seq(seq->seqbase.first,

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list