diff options
author | Peter Schlaile <peter@schlaile.de> | 2009-05-23 11:37:02 +0400 |
---|---|---|
committer | Peter Schlaile <peter@schlaile.de> | 2009-05-23 11:37:02 +0400 |
commit | 443df708e22e772965c098a93842083dc20cfbac (patch) | |
tree | 06e73f31cf78a20e9d9f29be075d22c71f040498 | |
parent | 3820e4f3db2ca23f7eeed7c3121cc41b0e12db25 (diff) |
== Sequencer ==
This fixes:
[#18373] WAV with IPO CURVE: Clicking in playback
by adding linear interpolation between frames. (Old IPOs were only calculated
once per frame which will lead to clicking on steep curves)
-rw-r--r-- | source/blender/src/seqaudio.c | 92 |
1 files changed, 75 insertions, 17 deletions
diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c index 078750ca118..92264605380 100644 --- a/source/blender/src/seqaudio.c +++ b/source/blender/src/seqaudio.c @@ -101,6 +101,9 @@ static Scene * audio_scene = 0; /* we can't use G.scene, since called while we have G.scene changed!) */ +#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) + ///// // /* local protos ------------------- */ @@ -235,23 +238,27 @@ void audiostream_fill(uint8_t *mixdown, int len) } -static void audio_levels(uint8_t *buf, int len, float db, float facf, float pan) +static void audio_levels(uint8_t *buf, int len, float db, + float facf_start, float facf_end, float pan) { int i; + double m = (facf_end - facf_start) / len; float facl, facr, fac; signed short *sample; if (pan>=0) { facr = 1.0; facl = 1.0-pan; } else { facr = pan+1.0; facl = 1.0; } - fac = pow(10.0, ((-(db+audio_scene->audio.main))/20.0)) / facf; - facl /= fac; - facr /= fac; - + fac = pow(10.0, ((-(db+audio_scene->audio.main))/20.0)); + for (i=0; i<len; i+=4) { + float facf = facf_start + ((double) i) * m; + float f_l = facl / (fac / facf); + float f_r = facr / (fac / facf); + sample = (signed short*)(buf+i); - sample[0] = (short) ((float)sample[0] * facl); - sample[1] = (short) ((float)sample[1] * facr); + sample[0] = (short) ((float)sample[0] * f_l); + sample[1] = (short) ((float)sample[1] * f_r); } } @@ -299,13 +306,61 @@ void audio_makestream(bSound *sound) } #ifndef DISABLE_SDL + +static int fra2curpos(Sequence * seq, int cfra) +{ + return (int)( (AFRA2TIME(((double) cfra) - + ((double) seq->start) + + ((double) + seq->anim_startofs)) + * ((float)audio_scene + ->audio.mixrate) + * 4 )); +} + +static int curpos2fra(Sequence * seq, int curpos) +{ + return ((int) floor( + ATIME2FRA( + ((double) curpos) / 4 + /audio_scene->audio.mixrate))) + - seq->anim_startofs + seq->start; +} + +static void do_audio_seq_ipo(Sequence * seq, int len, float * facf_start, + float * facf_end) +{ + 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_end = fra2curpos(seq, cfra_end); + double ipo_facf_start; + double ipo_facf_end; + double m; + + do_seq_ipo(seq, cfra_start); + ipo_facf_start = seq->facf0; + + do_seq_ipo(seq, cfra_end); + ipo_facf_end = seq->facf0; + + 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; +} + +#endif + +#ifndef DISABLE_SDL static void audio_fill_ram_sound(Sequence *seq, void * mixdown, uint8_t * sstream, int len, int cfra) { uint8_t* cvtbuf; bSound* sound; - float facf; + float facf_start; + float facf_end; sound = seq->sound; audio_makestream(sound); @@ -313,14 +368,15 @@ static void audio_fill_ram_sound(Sequence *seq, void * mixdown, (seq->startdisp <= cfra) && ((seq->enddisp) > cfra)) { if(seq->ipo && seq->ipo->curve.first) { - do_seq_ipo(seq, cfra); - facf = seq->facf0; + do_audio_seq_ipo(seq, len, &facf_start, &facf_end); } else { - facf = 1.0; + facf_start = 1.0; + facf_end = 1.0; } cvtbuf = malloc(len); memcpy(cvtbuf, ((uint8_t*)sound->stream)+(seq->curpos & (~3)), len); - audio_levels(cvtbuf, len, seq->level, facf, seq->pan); + audio_levels(cvtbuf, len, seq->level, facf_start, facf_end, + seq->pan); if (!mixdown) { SDL_MixAudio(sstream, cvtbuf, len, SDL_MIX_MAXVOLUME); } else { @@ -338,16 +394,17 @@ static void audio_fill_hd_sound(Sequence *seq, int len, int cfra) { uint8_t* cvtbuf; - float facf; + float facf_start; + float facf_end; if ((seq->curpos >= 0) && (seq->startdisp <= cfra) && ((seq->enddisp) > cfra)) { if(seq->ipo && seq->ipo->curve.first) { - do_seq_ipo(seq, cfra); - facf = seq->facf0; + do_audio_seq_ipo(seq, len, &facf_start, &facf_end); } else { - facf = 1.0; + facf_start = 1.0; + facf_end = 1.0; } cvtbuf = malloc(len); @@ -356,7 +413,8 @@ static void audio_fill_hd_sound(Sequence *seq, audio_scene->audio.mixrate, 2, len / 4); - audio_levels(cvtbuf, len, seq->level, facf, seq->pan); + audio_levels(cvtbuf, len, seq->level, facf_start, facf_end, + seq->pan); if (!mixdown) { SDL_MixAudio(sstream, cvtbuf, len, SDL_MIX_MAXVOLUME); |