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:
authorWouter van Heyst <larstiq-bforge@larstiq.dyndns.org>2003-07-14 00:16:56 +0400
committerWouter van Heyst <larstiq-bforge@larstiq.dyndns.org>2003-07-14 00:16:56 +0400
commit4f273867403672b3970ff8879afe8459827f172a (patch)
tree75476eed3e2e70481dcc38a2f10c51805b8ab305
parent9cb79c6534ae4a1c51571d59fe93d41706cd2dc3 (diff)
Commit message and the brunt of the code courtesy of intrr, apologies for the
size of this; Finally, the Sequencer audio support and global audio/animation sync stuff! (See http://intrr.org/blender/audiosequencer.html) Stuff that has been done: ./source/blender/blenloader/intern/writefile.c ./source/blender/blenloader/intern/readfile.c Added code to make it handle sounds used by audio strips, and to convert Scene data from older (<2.28) versions to init Scene global audio settings (Scene->audio) to defaults. ./source/blender/include/BSE_seqaudio.h ./source/blender/src/seqaudio.c The main audio routines that start/stop/scrub the audio stream at a certain frame position, provide the frame reference for the current stream position, mix the audio, convert the audio, mixdown the audio into a file. ./source/blender/makesdna/DNA_sound_types.h Introduced new variables in the bSound struct to accomodate the sample data after converted to the scene's global mixing format (stream, streamlen). Also added a new flag SOUND_FLAGS_SEQUENCE that gets set if the Sound belongs to a sequence strip. ./source/blender/makesdna/DNA_scene_types.h Added AudioData struct, which holds scene-global audio settings. ./source/blender/makesdna/DNA_sequence_types.h Added support for audio strips. Some variables to hold Panning/Attenuation information, position information, reference to the sample, and some flags. ./source/blender/makesdna/DNA_userdef_types.h ./source/blender/src/usiblender.c Added a "Mixing buffer size" userpref. Made the versions stuff initialize it to a default for versions <2.28. ./source/blender/makesdna/DNA_space_types.h ./source/blender/src/filesel.c Added a Cyan dot to .WAV files. Any other suggestions on a better color? :) ./source/blender/src/editsound.c Changes (fixes) to the WAV file loader, re-enabled some gameengine code that is needed for dealing with bSounds and bSamples. ./source/blender/src/editipo.c ./source/blender/src/drawseq.c ./source/blender/src/editnla.c ./source/blender/src/space.c ./source/blender/src/drawview.c ./source/blender/src/renderwin.c ./source/blender/src/headerbuttons.c - Created two different wrappers for update_for_newframe(), one which scrubs the audio, one which doesn't. - Replaced some of the occurences of update_for_newframe() with update_for_newframe_muted(), which doesn't scrub the audio. - In drawview.c: Changed the synchronization scheme to get the current audio position from the audio engine, and use that as a reference for setting CFRA. Implements a/v sync and framedrop. - In editipo.c: Changed handling of Fac IPOs to be usable for audio strips as volume envelopes. - In space.c: Added the mixing buffer size Userpref, enabled audio scrubbing (update_for_newframe()) for moving the sequence editor framebar. ./source/blender/src/editseq.c Added support for audio strips and a default directory for WAV files which gets saved from the last Shift-A operation. ./source/blender/src/buttons.c Added Scene-global audio sequencer settings in Sound buttons. ./source/blender/src/sequence.c Various stuff that deals with handling audio strips differently than usual strips.
-rw-r--r--source/blender/blenloader/intern/readfile.c35
-rw-r--r--source/blender/blenloader/intern/writefile.c2
-rw-r--r--source/blender/include/BSE_seqaudio.h52
-rw-r--r--source/blender/makesdna/DNA_scene_types.h12
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h12
-rw-r--r--source/blender/makesdna/DNA_sound_types.h9
-rw-r--r--source/blender/makesdna/DNA_space_types.h1
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h1
-rw-r--r--source/blender/src/Makefile1
-rw-r--r--source/blender/src/buttons.c94
-rw-r--r--source/blender/src/drawseq.c87
-rw-r--r--source/blender/src/drawview.c20
-rw-r--r--source/blender/src/editipo.c4
-rw-r--r--source/blender/src/editnla.c10
-rw-r--r--source/blender/src/editseq.c224
-rw-r--r--source/blender/src/editsound.c67
-rw-r--r--source/blender/src/filesel.c7
-rw-r--r--source/blender/src/headerbuttons.c16
-rw-r--r--source/blender/src/renderwin.c2
-rw-r--r--source/blender/src/seqaudio.c392
-rw-r--r--source/blender/src/sequence.c13
-rw-r--r--source/blender/src/space.c11
-rw-r--r--source/blender/src/usiblender.c4
-rw-r--r--source/nan_definitions.mk2
-rw-r--r--source/nan_link.mk1
25 files changed, 956 insertions, 123 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 3f274aafb90..5aecd18b231 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2244,6 +2244,13 @@ static void lib_link_scene(FileData *fd, Main *main)
WHILE_SEQ(ed->seqbasep) {
if(seq->ipo) seq->ipo= newlibadr_us(fd, sce->id.lib, seq->ipo);
if(seq->scene) seq->scene= newlibadr(fd, sce->id.lib, seq->scene);
+ if(seq->sound) {
+ seq->sound= newlibadr(fd, sce->id.lib, seq->sound);
+ if (seq->sound) {
+ seq->sound->id.us++;
+ seq->sound->flags |= SOUND_FLAGS_SEQUENCE;
+ }
+ }
seq->anim= 0;
}
END_SEQ
@@ -2350,6 +2357,24 @@ static void direct_link_scene(FileData *fd, Scene *sce)
}
}
}
+ else if(seq->type==SEQ_SOUND) {
+ /* only first stripelem is in file */
+ se= newdataadr(fd, seq->strip->stripdata);
+
+ if(se) {
+ seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
+ *seq->strip->stripdata= *se;
+ MEM_freeN(se);
+
+ se= seq->strip->stripdata;
+
+ for(a=0; a<seq->strip->len; a++, se++) {
+ se->ok= 2; /* why? */
+ se->ibuf= 0;
+ se->nr= a + 1;
+ }
+ }
+ }
else if(seq->len>0)
seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
@@ -2576,11 +2601,11 @@ static void lib_link_sound(FileData *fd, Main *main)
if(sound->id.flag & LIB_NEEDLINK) {
sound->id.flag -= LIB_NEEDLINK;
sound->ipo= newlibadr_us(fd, sound->id.lib, sound->ipo);
+ sound->stream = 0;
}
sound= sound->id.next;
}
}
-
/* ***************** READ GROUP *************** */
static void direct_link_group(FileData *fd, Group *group)
@@ -3669,6 +3694,14 @@ static void do_versions(Main *main)
}
}
}
+ if(main->versionfile <= 227) {
+ Scene *sce;
+
+ for (sce= main->scene.first; sce; sce= sce->id.next) {
+ sce->audio.mixrate = 44100;
+ sce->audio.flag |= (AUDIO_SYNC + AUDIO_SCRUB);
+ }
+ }
/* don't forget to set version number in blender.c! */
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 640e5333023..9845899c7d9 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1147,7 +1147,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
if(seq->type==SEQ_IMAGE)
writestruct(wd, DATA, "StripElem", strip->len, strip->stripdata);
- else if(seq->type==SEQ_MOVIE)
+ else if(seq->type==SEQ_MOVIE || seq->type==SEQ_SOUND)
writestruct(wd, DATA, "StripElem", 1, strip->stripdata);
strip->done= 1;
diff --git a/source/blender/include/BSE_seqaudio.h b/source/blender/include/BSE_seqaudio.h
new file mode 100644
index 00000000000..f395ac4b90e
--- /dev/null
+++ b/source/blender/include/BSE_seqaudio.h
@@ -0,0 +1,52 @@
+/**
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2003 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ *
+ */
+
+#ifndef BSE_SEQAUDIO_H
+#define BSE_SEQAUDIO_H
+
+#include "SDL.h"
+/* muha, we don't init (no SDL_main)! */
+#ifdef main
+# undef main
+#endif
+
+#include "DNA_sound_types.h"
+
+void audio_mixdown();
+void audio_makestream(bSound *sound);
+void audiostream_play(Uint32 startframe, Uint32 duration, int mixdown);
+void audiostream_start(Uint32 frame);
+void audiostream_scrub(Uint32 frame);
+void audiostream_stop(void);
+int audiostream_pos(void);
+
+#endif
+
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index c15b34def92..7ce8447da6a 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -92,6 +92,12 @@ typedef struct QuicktimeCodecData {
char qtcodecname[128];
} QuicktimeCodecData;
+typedef struct AudioData {
+ int mixrate;
+ float main; /* Main mix in dB */
+ short flag;
+ short pad[3];
+} AudioData;
typedef struct RenderData {
struct AviCodecData *avicodecdata;
@@ -243,6 +249,7 @@ typedef struct Scene {
/* migrate or replace? depends on some internal things... */
/* no, is on the right place (ton) */
struct RenderData r;
+ struct AudioData audio;
ScriptLink scriptlink;
} Scene;
@@ -354,6 +361,11 @@ typedef struct Scene {
#define F_SET 2
#define F_DUPLI 3
+/* audio->flag */
+#define AUDIO_MUTE 1
+#define AUDIO_SYNC 2
+#define AUDIO_SCRUB 4
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index f3827f5e0b2..efc145da8f6 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -36,6 +36,9 @@
#include "DNA_listBase.h"
+/* needed for sound support */
+#include "DNA_sound_types.h"
+
struct Ipo;
struct Scene;
@@ -111,9 +114,12 @@ typedef struct Sequence {
/* meta */
ListBase seqbase;
+ struct bSound *sound; /* the linked "bSound" object */
+ float level, pan; /* level in dB (0=full), pan -1..1 */
+ int curpos; /* last sample position in audio_fill() */
+ int pad;
+
} Sequence;
-
-
#
#
typedef struct MetaStack {
@@ -137,12 +143,14 @@ typedef struct Editing {
#define SEQ_RIGHTSEL 4
#define SEQ_OVERLAP 8
#define SEQ_FILTERY 16
+#define SEQ_MUTE 32
/* seq->type WATCH IT: BIT 3!!! */
#define SEQ_IMAGE 0
#define SEQ_META 1
#define SEQ_SCENE 2
#define SEQ_MOVIE 3
+#define SEQ_SOUND 4
#define SEQ_EFFECT 8
#define SEQ_CROSS 8
diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h
index 41429a0217e..8f91cb81e47 100644
--- a/source/blender/makesdna/DNA_sound_types.h
+++ b/source/blender/makesdna/DNA_sound_types.h
@@ -73,6 +73,7 @@ typedef struct bSound {
ID id;
char name[160];
struct bSample *sample;
+ void *stream;
struct PackedFile *packedfile;
struct PackedFile *newpackedfile;
void *snd_sound;
@@ -101,12 +102,12 @@ typedef struct bSound {
*/
float distance;
int flags;
+ int streamlen;
// unsigned int loopstart;
// unsigned int loopend;
char channels;
char highprio;
- char pad[6];
-
+ char pad[10];
} bSound;
typedef struct bSoundListener {
@@ -169,7 +170,8 @@ enum SOUND_FLAGS_BITS {
SOUND_FLAGS_FIXED_PANNING_BIT,
SOUND_FLAGS_3D_BIT,
SOUND_FLAGS_BIDIRECTIONAL_LOOP_BIT,
- SOUND_FLAGS_PRIORITY_BIT
+ SOUND_FLAGS_PRIORITY_BIT,
+ SOUND_FLAGS_SEQUENCE_BIT
};
#define SOUND_FLAGS_LOOP (1 << SOUND_FLAGS_LOOP_BIT)
@@ -178,6 +180,7 @@ enum SOUND_FLAGS_BITS {
#define SOUND_FLAGS_3D (1 << SOUND_FLAGS_3D_BIT)
#define SOUND_FLAGS_BIDIRECTIONAL_LOOP (1 << SOUND_FLAGS_BIDIRECTIONAL_LOOP_BIT)
#define SOUND_FLAGS_PRIORITY (1 << SOUND_FLAGS_PRIORITY_BIT)
+#define SOUND_FLAGS_SEQUENCE (1 << SOUND_FLAGS_SEQUENCE_BIT)
enum SAMPLE_FLAGS_BITS {
SAMPLE_NEEDS_SAVE_BIT = 0
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 59fa9e07604..a3b2e857417 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -396,6 +396,7 @@ typedef struct SpaceImaSel {
#define MOVIEFILE 32
#define PYSCRIPTFILE 64
#define FTFONTFILE 128
+#define SOUNDFILE 256
#define SCROLLH 16 /* height scrollbar */
#define SCROLLB 16 /* width scrollbar */
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 2d2ba593513..5a329749708 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -53,6 +53,7 @@ typedef struct UserDef {
int userpref;
short console_buffer; //console vars here for tuhopuu compat, --phase
short console_out;
+ int mixbufsize;
int fontsize;
short encoding;
short transopts;
diff --git a/source/blender/src/Makefile b/source/blender/src/Makefile
index 35c29a8571e..6737d942eed 100644
--- a/source/blender/src/Makefile
+++ b/source/blender/src/Makefile
@@ -86,6 +86,7 @@ CPPFLAGS += -I$(NAN_BSP)/include
CPPFLAGS += -I../readstreamglue
CPPFLAGS += -I../include
+CPPFLAGS += -I$(NAN_SDL)/include/SDL
ifdef NAN_BUILDINFO
CPPFLAGS += -DNAN_BUILDINFO
diff --git a/source/blender/src/buttons.c b/source/blender/src/buttons.c
index 2f3efded788..c6eef4b906f 100644
--- a/source/blender/src/buttons.c
+++ b/source/blender/src/buttons.c
@@ -128,6 +128,7 @@
#include "BSE_trans_types.h"
#include "BSE_view.h"
#include "BSE_buttons.h"
+#include "BSE_seqaudio.h"
#include "BIF_gl.h"
#include "BIF_editarmature.h"
@@ -542,7 +543,10 @@ enum B_SOUND_BUTTONS {
B_SOUND_COPY_SOUND,
B_SOUND_LOOPSTART,
B_SOUND_LOOPEND,
- B_SOUND_BIDIRECTIONAL
+ B_SOUND_BIDIRECTIONAL,
+ B_SOUND_RECALC,
+ B_SOUND_RATECHANGED,
+ B_SOUND_MIXDOWN
};
/* *********************** */
@@ -4543,6 +4547,32 @@ void do_soundbuts(unsigned short event)
}
break;
}
+ case B_SOUND_RECALC:
+ {
+ waitcursor(1);
+ sound = G.main->sound.first;
+ while (sound)
+ {
+ MEM_freeN(sound->stream);
+ sound->stream = 0;
+ audio_makestream(sound);
+ sound = (bSound *) sound->id.next;
+ }
+ waitcursor(0);
+ allqueue(REDRAWSEQ, 0);
+ break;
+ }
+ case B_SOUND_RATECHANGED:
+ {
+ allqueue(REDRAWBUTSSOUND, 0);
+ allqueue(REDRAWSEQ, 0);
+ break;
+ }
+ case B_SOUND_MIXDOWN:
+ {
+ audio_mixdown();
+ break;
+ }
case B_SOUND_LOOPSTART:
{
#ifdef SOUND_UNDER_DEVELOPMENT
@@ -4590,23 +4620,24 @@ void soundbuts(void)
int mixrate;
sound = G.buts->lockpoin;
+ if ((sound) && (sound->flags & SOUND_FLAGS_SEQUENCE)) sound = 0;
yco = 195;
+ xco = xcostart;
+ sprintf(str, "buttonswin %d", curarea->win);
+ block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win);
+
if (sound)
{
sound_initialize_sample(sound);
sample = sound->sample;
- xco = xcostart;
- sprintf(str, "buttonswin %d", curarea->win);
- block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win);
-
uiSetButLock(sound->id.lib!=0, "Can't edit library data");
/* sound settings ------------------------------------------------------------------ */
- uiDefBut(block, LABEL, 0, "Sound settings:",xco,yco,195,20, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Game sounds",xco,yco,195,20, 0, 0, 0, 0, 0, "");
yco -= 30;
uiBlockSetCol(block, BUTGREEN);
@@ -4627,7 +4658,7 @@ void soundbuts(void)
uiDefBut(block, LABEL, 0, "Sample: ",xco,yco,195,20, 0, 0, 0, 0, 0, "");
xco +=55;
- sprintf(sampleinfo, "%s, %d bit, %d Hz, %d samples", ch, sound->sample->bits, sound->sample->rate, sound->sample->len);
+ sprintf(sampleinfo, "%s, %d bit, %d Hz, %d samples", ch, sound->sample->bits, sound->sample->rate, (sound->sample->len/(sound->sample->bits/8)/sound->sample->channels));
uiDefBut(block, LABEL, 0, sampleinfo,xco,yco,295,20, 0, 0, 0, 0, 0, "");
}
else
@@ -4691,7 +4722,7 @@ void soundbuts(void)
xco = xcostart;
yco -= 45;
- uiDefBut(block, LABEL, 0, "Parameter settings:",xco,yco,195,20, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Game sound settings:",xco,yco,195,20, 0, 0, 0, 0, 0, "");
yco -= 30;
uiBlockSetCol(block, BUTGREY);
@@ -4776,19 +4807,19 @@ void soundbuts(void)
yco = 195;
uiBlockSetCol(block, BUTGREY);
mixrate = sound_get_mixrate();
- sprintf(mixrateinfo, "Mixrate: %d Hz", mixrate);
+ sprintf(mixrateinfo, "Game Mixrate: %d Hz", mixrate);
uiDefBut(block, LABEL, 0, mixrateinfo, xco,yco,295,20, 0, 0, 0, 0, 0, "");
yco -= 30;
- uiDefBut(block, LABEL, 0, "Listener settings:",xco,yco,195,20, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Game listener settings:",xco,yco,195,20, 0, 0, 0, 0, 0, "");
yco -= 30;
uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Volume: ",
xco,yco,195,24,&G.listener->gain, 0.0, 1.0, 1.0, 0, "Sets the maximum volume for the overall sound");
yco -= 30;
- uiDefBut(block, LABEL, 0, "Doppler effect settings:",xco,yco,195,20, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Game Doppler effect settings:",xco,yco,195,20, 0, 0, 0, 0, 0, "");
/*
yco -= 30;
uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Scale: ",
@@ -4820,6 +4851,47 @@ void soundbuts(void)
*/
uiDrawBlock(block);
}
+ /* audio sequence engine settings ------------------------------------------------------------------ */
+
+ draw_buttons_edge(curarea->win, 1000);
+
+ xco = xcostart + 1010;
+ yco = 195;
+
+ uiDefBut(block, LABEL, 0, "Audio sequencer settings", xco,yco,295,20, 0, 0, 0, 0, 0, "");
+
+ yco -= 25;
+ sprintf(mixrateinfo, "Mixing/Sync (latency: %d ms)", (int)( (((float)U.mixbufsize)/(float)G.scene->audio.mixrate)*1000.0 ) );
+ uiDefBut(block, LABEL, 0, mixrateinfo, xco,yco,295,20, 0, 0, 0, 0, 0, "");
+
+ yco -= 25;
+ uiBlockSetCol(block, BUTGREY);
+ uiDefButI(block, ROW, B_SOUND_RATECHANGED, "44.1 kHz", xco,yco,75,20, &G.scene->audio.mixrate, 2.0, 44100.0, 0, 0, "Mix at 44.1 kHz");
+ uiDefButI(block, ROW, B_SOUND_RATECHANGED, "48.0 kHz", xco+80,yco,75,20, &G.scene->audio.mixrate, 2.0, 48000.0, 0, 0, "Mix at 48 kHz");
+ uiBlockSetCol(block, BUTSALMON);
+ uiDefBut(block, BUT, B_SOUND_RECALC, "Recalc", xco+160,yco,75,20, 0, 0, 0, 0, 0, "Recalculate samples");
+
+ yco -= 25;
+ uiBlockSetCol(block, BUTGREEN);
+ uiDefButS(block, TOG|BIT|1, B_SOUND_CHANGED, "Sync", xco,yco,115,20, &G.scene->audio.flag, 0, 0, 0, 0, "Use sample clock for animation sync");
+ uiDefButS(block, TOG|BIT|2, B_SOUND_CHANGED, "Scrub", xco+120,yco,115,20, &G.scene->audio.flag, 0, 0, 0, 0, "Scrub when changing frames");
+
+ yco -= 25;
+ uiDefBut(block, LABEL, 0, "Main mix", xco,yco,295,20, 0, 0, 0, 0, 0, "");
+
+ yco -= 25;
+ uiBlockSetCol(block, BUTGREY);
+ uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Main (dB): ",
+ xco,yco,235,24,&G.scene->audio.main, -24.0, 6.0, 0, 0, "Set the audio master gain/attenuation in dB");
+
+ yco -= 25;
+ uiDefButS(block, TOG|BIT|0, 0, "Mute", xco,yco,235,24, &G.scene->audio.flag, 0, 0, 0, 0, "Mute audio from sequencer");
+
+ yco -= 35;
+ uiBlockSetCol(block, BUTSALMON);
+ uiDefBut(block, BUT, B_SOUND_MIXDOWN, "MIXDOWN", xco,yco,235,24, 0, 0, 0, 0, 0, "Create WAV file from sequenced audio");
+
+ uiDrawBlock(block);
}
/* ************************ LAMP *************************** */
diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c
index aa863e4b992..bba768a894b 100644
--- a/source/blender/src/drawseq.c
+++ b/source/blender/src/drawseq.c
@@ -70,6 +70,7 @@
#include "BSE_view.h"
#include "BSE_drawipo.h"
#include "BSE_sequence.h"
+#include "BSE_seqaudio.h"
int no_rightbox=0, no_leftbox= 0;
@@ -99,6 +100,7 @@ static char *give_seqname(Sequence *seq)
}
else if(seq->type==SEQ_SCENE) return "SCENE";
else if(seq->type==SEQ_MOVIE) return "MOVIE";
+ else if(seq->type==SEQ_SOUND) return "AUDIO";
else if(seq->type<SEQ_EFFECT) return seq->strip->dir;
else if(seq->type==SEQ_CROSS) return "CROSS";
else if(seq->type==SEQ_GAMCROSS) return "GAMMA CROSS";
@@ -115,7 +117,6 @@ static char *give_seqname(Sequence *seq)
else return "EFFECT";
}
-
static void draw_cfra_seq(void)
{
glColor3ub(0x30, 0x90, 0x50);
@@ -155,12 +156,13 @@ static unsigned int seq_color(Sequence *seq)
return 0x5080B0;
case SEQ_PLUGIN:
return 0x906000;
+ case SEQ_SOUND:
+ if(seq->flag & SEQ_MUTE) return 0x707060; else return 0x787850;
default:
return 0x906060;
}
}
-
static void drawmeta_contents(Sequence *seqm, float x1, float y1, float x2, float y2)
{
Sequence *seq;
@@ -184,6 +186,32 @@ static void drawmeta_contents(Sequence *seqm, float x1, float y1, float x2, floa
END_SEQ
}
+void drawseqwave(Sequence *seq, float x1, float y1, float x2, float y2)
+{
+ float f, height, midy;
+ int offset, sofs, eofs;
+ signed short* s;
+ bSound *sound;
+
+ audio_makestream(seq->sound);
+ if (seq->flag & SEQ_MUTE) glColor3ub(0x70, 0x80, 0x80); else glColor3ub(0x70, 0xc0, 0xc0);
+ sound = seq->sound;
+ sofs = ((int)( (((float)(seq->startdisp-seq->start))/(float)G.scene->r.frs_sec)*(float)G.scene->audio.mixrate*4.0 )) & (~3);
+ eofs = ((int)( (((float)(seq->enddisp-seq->start))/(float)G.scene->r.frs_sec)*(float)G.scene->audio.mixrate*4.0 )) & (~3);
+
+ for (f=x1; f<=x2; f+=0.2) {
+ offset = (int) ((float)sofs + ((f-x1)/(x2-x1)) * (float)(eofs-sofs)) & (~3);
+ if (offset >= sound->streamlen) offset = sound->streamlen-1;
+ s = (signed short*)(((Uint8*)sound->stream) + offset);
+ midy = (y1+y2)/2;
+ height = ( ( ((float)s[0]/32768 + (float)s[1]/32768)/2 ) * (y2-y1) )/2;
+ glBegin(GL_LINES);
+ glVertex2f(f, midy-height);
+ glVertex2f(f, midy+height);
+ glEnd();
+ }
+}
+
void drawseq(Sequence *seq)
{
float v1[2], v2[2], x1, x2, y1, y2;
@@ -217,6 +245,7 @@ void drawseq(Sequence *seq)
cpack(body);
glRectf(x1, y1, x2, y2);
+ if (seq->type == SEQ_SOUND) drawseqwave(seq, x1, y1, x2, y2);
EmbossBoxf(x1, y1, x2, y2, seq->flag & 1, dark, light);
v1[1]= y1;
@@ -288,7 +317,13 @@ void drawseq(Sequence *seq)
sprintf(str, "%d %s: %d-%d", seq->len, give_seqname(seq), seq->seq1->machine, seq->seq2->machine);
}
else if(seq->name[2]) sprintf(str, "%s", seq->name+2);
- else sprintf(str, "%d %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
+ else {
+ if (seq->type == SEQ_SOUND) {
+ sprintf(str, "%d %s", seq->len, seq->strip->stripdata->name);
+ } else {
+ sprintf(str, "%d %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
+ }
+ }
strp= str;
@@ -309,17 +344,15 @@ void drawseq(Sequence *seq)
}
if(seq->type < SEQ_EFFECT) {
-
/* decoration: triangles */
x1= seq->startdisp;
x2= seq->enddisp;
-
+
body+= 0x101010;
dark= 0x202020;
light= 0xB0B0B0;
/* left triangle */
-
if(seq->flag & SEQ_LEFTSEL) {
cpack(body+0x20);
if(G.moving) {
@@ -346,16 +379,17 @@ void drawseq(Sequence *seq)
cpack(dark);
glVertex2fv(v1);
glEnd();
+ }
- if(G.moving || (seq->flag & SEQ_LEFTSEL)) {
- cpack(0xFFFFFF);
- glRasterPos3f(x1, y1+0.2, 0.0);
- sprintf(str, "%d", seq->startdisp);
- BMF_DrawString(G.font, str);
- }
+ if(G.moving || (seq->flag & SEQ_LEFTSEL)) {
+ cpack(0xFFFFFF);
+ glRasterPos3f(x1, y1+0.2, 0.0);
+ sprintf(str, "%d", seq->startdisp);
+ BMF_DrawString(G.font, str);
+ }
/* right triangle */
-
+ if(seq->type < SEQ_EFFECT) {
dark= 0x202020;
light= 0xB0B0B0;
@@ -383,15 +417,13 @@ void drawseq(Sequence *seq)
cpack(light);
glVertex2fv(v2);
glEnd();
+ }
- if(G.moving || (seq->flag & SEQ_RIGHTSEL)) {
- cpack(0xFFFFFF);
- glRasterPos3f(x2-seq->handsize/2, y1+0.2, 0.0);
- sprintf(str, "%d", seq->enddisp-1);
- BMF_DrawString(G.font, str);
- }
-
-
+ if(G.moving || (seq->flag & SEQ_RIGHTSEL)) {
+ cpack(0xFFFFFF);
+ glRasterPos3f(x2-seq->handsize/2, y1+0.2, 0.0);
+ sprintf(str, "%d", seq->enddisp-1);
+ BMF_DrawString(G.font, str);
}
}
@@ -530,6 +562,19 @@ static void draw_extra_seqinfo(void)
glRasterPos3f(xco, 0.3, 0.0);
BMF_DrawString(G.font, str);
}
+ else if(last_seq->type==SEQ_SOUND) {
+
+ sta= last_seq->startofs;
+ end= last_seq->len-1-last_seq->endofs;
+
+ sprintf(str, "%s %s%s First: %d at %d Last: %d at %d Cur: %d Gain: %.2f dB Pan: %.2f",
+ last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name,
+ sta, last_seq->startdisp, end, last_seq->enddisp-1, (G.scene->r.cfra)-last_seq->startdisp,
+ last_seq->level, last_seq->pan);
+
+ glRasterPos3f(xco, 0.3, 0.0);
+ BMF_DrawString(G.font, str);
+ }
}
void drawseqspace(ScrArea *sa, void *spacedata)
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index 01fba8eb27f..a963285bb27 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -97,6 +97,8 @@
#include "BSE_view.h"
#include "BSE_drawview.h"
#include "BSE_headerbuttons.h"
+#include "BSE_seqaudio.h"
+
#include "RE_renderconverter.h"
@@ -1192,6 +1194,8 @@ int update_time(void)
static double ltime;
double time;
+ if ((U.mixbufsize)&&(audiostream_pos() != CFRA)&&(G.scene->audio.flag & AUDIO_SYNC)) return 0;
+
time = PIL_check_seconds_timer();
tottime += (time - ltime);
@@ -1566,12 +1570,17 @@ void inner_play_anim_loop(int init, int mode)
tottime -= swaptime;
while (update_time()) PIL_sleep_ms(1);
- if(CFRA==EFRA) {
+ if(CFRA>=EFRA) {
if (tottime > 0.0) tottime = 0.0;
CFRA= SFRA;
+ audiostream_stop();
+ audiostream_start( CFRA );
}
- else CFRA++;
-
+ else
+ {
+ if (U.mixbufsize && (G.scene->audio.flag & AUDIO_SYNC)) CFRA = audiostream_pos();
+ else CFRA++;
+ };
}
int play_anim(int mode)
@@ -1594,6 +1603,8 @@ int play_anim(int mode)
cfraont= CFRA;
oldsa= curarea;
+
+ audiostream_start( CFRA );
inner_play_anim_loop(1, mode); /* 1==init */
@@ -1649,6 +1660,7 @@ int play_anim(int mode)
do_all_actions();
do_all_ikas();
+ audiostream_stop();
if(oldsa!=curarea) areawinset(oldsa->win);
@@ -1668,7 +1680,7 @@ int play_anim(int mode)
allqueue(REDRAWNLA, 0);
allqueue (REDRAWACTION, 0);
/* for the time being */
- update_for_newframe();
+ update_for_newframe_muted();
#ifdef NAN_LINEAR_PHYSICS
end_anim_sumo();
#endif
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index f8b34269eac..b0cf75ff7da 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -1915,12 +1915,12 @@ static Ipo *get_ipo(ID *from, short type, int make)
else if( type==ID_SEQ) {
seq= (Sequence *)from;
- if(seq->type & SEQ_EFFECT) {
+ if((seq->type & SEQ_EFFECT)||(seq->type == SEQ_SOUND)) {
ipo= seq->ipo;
if(make && ipo==0) ipo= seq->ipo= add_ipo("SeqIpo", ID_SEQ);
}
else return 0;
- }
+ }
else if( type==ID_CU) {
cu= (Curve *)from;
if(cu->id.lib) return 0;
diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c
index 3f66bd5724d..781ddfe518d 100644
--- a/source/blender/src/editnla.c
+++ b/source/blender/src/editnla.c
@@ -140,7 +140,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case DKEY:
if (G.qual & LR_SHIFTKEY && mval[0]>=NLAWIDTH){
duplicate_nlachannel_keys();
- update_for_newframe();
+ update_for_newframe_muted();
}
break;
case DELKEY:
@@ -149,17 +149,17 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
delete_nlachannel_keys ();
else
delete_nlachannels();
- update_for_newframe();
+ update_for_newframe_muted();
break;
case GKEY:
if (mval[0]>=NLAWIDTH)
transform_nlachannel_keys ('g');
- update_for_newframe();
+ update_for_newframe_muted();
break;
case SKEY:
if (mval[0]>=NLAWIDTH)
transform_nlachannel_keys ('s');
- update_for_newframe();
+ update_for_newframe_muted();
break;
case BKEY:
borderselect_nla();
@@ -1566,7 +1566,7 @@ void clever_numbuts_nla(void){
strip->blendout = (strip->end-strip->start-strip->blendin);
- update_for_newframe();
+ update_for_newframe_muted();
allqueue (REDRAWNLA, 0);
allqueue (REDRAWVIEW3D, 0);
}
diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c
index 54e63a1b42d..79db90154c6 100644
--- a/source/blender/src/editseq.c
+++ b/source/blender/src/editseq.c
@@ -63,6 +63,7 @@
#include "DNA_sequence_types.h"
#include "DNA_view2d_types.h"
#include "DNA_userdef_types.h"
+#include "DNA_sound_types.h"
#include "BKE_utildefines.h"
#include "BKE_plugin_types.h"
@@ -81,11 +82,13 @@
#include "BIF_writemovie.h"
#include "BIF_editview.h"
#include "BIF_scrarea.h"
+#include "BIF_editsound.h"
#include "BSE_edit.h"
#include "BSE_sequence.h"
#include "BSE_filesel.h"
#include "BSE_drawipo.h"
+#include "BSE_seqaudio.h"
#include "BDR_editobject.h"
@@ -95,6 +98,7 @@
Sequence *last_seq=0;
char last_imagename[80]= "/";
+char last_sounddir[80]= "";
/* void transform_seq(int mode); already in BIF_editseq.h */
@@ -268,7 +272,7 @@ static void shuffle_seq(Sequence *test)
ed= G.scene->ed;
if(ed==0) return;
- /* als er meerdere select zijn: alleen y shuffelen */
+ /* is there more than 1 select: only shuffle y */
a=0;
seq= ed->seqbasep->first;
while(seq) {
@@ -351,7 +355,7 @@ void swap_select_seq(void)
END_SEQ
WHILE_SEQ(ed->seqbasep) {
- /* alles voor zekerheid altijd deselecteren */
+ /* always deselect all to be sure */
seq->flag &= SEQ_DESEL;
if(sel==0) seq->flag |= SELECT;
}
@@ -372,8 +376,15 @@ void mouse_select_seq(void)
if(seq) {
last_seq= seq;
- if ELEM(seq->type, SEQ_IMAGE, SEQ_MOVIE) {
- if(seq->strip) strcpy(last_imagename, seq->strip->dir);
+ if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) {
+ if(seq->strip) {
+ strcpy(last_imagename, seq->strip->dir);
+ }
+ } else
+ if (seq->type == SEQ_SOUND) {
+ if(seq->strip) {
+ strcpy(last_sounddir, seq->strip->dir);
+ }
}
if(G.qual==0) {
@@ -438,7 +449,7 @@ static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int
StripElem *se;
int totsel, a;
- /* zijn er geselecteerde files? */
+ /* are there selected files? */
totsel= 0;
for(a=0; a<sfile->totfile; a++) {
if(sfile->filelist[a].flags & ACTIVE) {
@@ -449,13 +460,13 @@ static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int
}
if(last) {
- /* of anders een aangegeven file? */
+ /* if not, a file handed to us? */
if(totsel==0 && sfile->file[0]) totsel= 1;
}
if(totsel==0) return 0;
- /* seq maken */
+ /* make seq */
seq= alloc_sequence(cfra, machine);
seq->len= totsel;
@@ -466,7 +477,7 @@ static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int
calc_sequence(seq);
- /* strip en stripdata */
+ /* strip and stripdata */
seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
strip->len= totsel;
strip->us= 1;
@@ -482,13 +493,13 @@ static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int
}
}
}
- /* geen geselecteerde file: */
+ /* no selected file: */
if(totsel==1 && se==strip->stripdata) {
strcpy(se->name, sfile->file);
se->ok= 1;
}
- /* laatste aktieve naam */
+ /* last active name */
strcpy(last_imagename, seq->strip->dir);
return seq;
@@ -508,7 +519,7 @@ static void sfile_to_mv_sequence(SpaceFile *sfile, int cfra, int machine)
strcpy(str, sfile->dir);
strcat(str, sfile->file);
- /* is er sprake van een movie */
+ /* is it a movie? */
anim = openanim(str, IB_rect);
if(anim==0) {
error("Not a movie");
@@ -517,7 +528,7 @@ static void sfile_to_mv_sequence(SpaceFile *sfile, int cfra, int machine)
totframe= IMB_anim_get_duration(anim);
- /* seq maken */
+ /* make seq */
seq= alloc_sequence(cfra, machine);
seq->len= totframe;
seq->type= SEQ_MOVIE;
@@ -525,14 +536,14 @@ static void sfile_to_mv_sequence(SpaceFile *sfile, int cfra, int machine)
calc_sequence(seq);
- /* strip en stripdata */
+ /* strip and stripdata */
seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
strip->len= totframe;
strip->us= 1;
strcpy(strip->dir, sfile->dir);
strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
- /* naam movie in eerste strip */
+ /* name movie in first strip */
strcpy(se->name, sfile->file);
for(a=1; a<=totframe; a++, se++) {
@@ -540,10 +551,70 @@ static void sfile_to_mv_sequence(SpaceFile *sfile, int cfra, int machine)
se->nr= a;
}
- /* laatste aktieve naam */
+ /* last active name */
strcpy(last_imagename, seq->strip->dir);
}
+static Sequence *sfile_to_snd_sequence(SpaceFile *sfile, int cfra, int machine)
+{
+ Sequence *seq;
+ bSound *sound;
+ Strip *strip;
+ StripElem *se;
+ double totframe;
+ int a;
+ char str[256];
+
+ totframe= 0.0;
+
+ strcpy(str, sfile->dir);
+ strcat(str, sfile->file);
+
+ sound= sound_new_sound(str);
+ if (!sound || sound->sample->type == SAMPLE_INVALID) {
+ error("Unsupported audio format");
+ return 0;
+ }
+ if (sound->sample->bits != 16) {
+ error("Only 16 bit audio supported");
+ return 0;
+ }
+ sound->id.us=1;
+ sound->flags |= SOUND_FLAGS_SEQUENCE;
+ audio_makestream(sound);
+
+ totframe= (int) ( ((float)(sound->streamlen-1)/( (float)G.scene->audio.mixrate*4.0 ))* (float)G.scene->r.frs_sec);
+
+ /* make seq */
+ seq= alloc_sequence(cfra, machine);
+ seq->len= totframe;
+ seq->type= SEQ_SOUND;
+ seq->sound = sound;
+
+ calc_sequence(seq);
+
+ /* strip and stripdata */
+ seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
+ strip->len= totframe;
+ strip->us= 1;
+ strcpy(strip->dir, sfile->dir);
+ strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
+
+ /* name sound in first strip */
+ strcpy(se->name, sfile->file);
+
+ for(a=1; a<=totframe; a++, se++) {
+ se->ok= 2; /* why? */
+ se->ibuf= 0;
+ se->nr= a;
+ }
+
+ /* last active name */
+ strcpy(last_sounddir, seq->strip->dir);
+
+ return seq;
+}
+
static void add_image_strips(char *name)
{
SpaceFile *sfile;
@@ -639,6 +710,74 @@ static void add_movie_strip(char *name)
}
+static void add_sound_strip(char *name)
+{
+ SpaceFile *sfile;
+ float x, y;
+ int cfra, machine;
+ short mval[2];
+
+ deselect_all_seq();
+
+ sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
+ if (sfile==0) return;
+
+ /* where will it be */
+ getmouseco_areawin(mval);
+ areamouseco_to_ipoco(G.v2d, mval, &x, &y);
+ cfra= (int)(x+0.5);
+ machine= (int)(y+0.5);
+
+ waitcursor(1);
+
+ sfile_to_snd_sequence(sfile, cfra, machine);
+
+ waitcursor(0);
+
+ transform_seq('g');
+}
+
+static void reload_sound_strip(char *name)
+{
+ Editing *ed;
+ Sequence *seq, *seqact;
+ SpaceFile *sfile;
+
+ ed= G.scene->ed;
+
+ if(last_seq==0 || last_seq->type!=SEQ_SOUND) return;
+ seqact= last_seq; /* last_seq changes in alloc_sequence */
+
+ /* search sfile */
+ sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
+ if(sfile==0) return;
+
+ waitcursor(1);
+
+ seq = sfile_to_snd_sequence(sfile, seqact->start, seqact->machine);
+ printf("seq->type: %i\n", seq->type);
+ if(seq && seq!=seqact) {
+ /* i'm not sure about this one, seems to work without it -- sgefant */
+ free_strip(seqact->strip);
+
+ seqact->strip= seq->strip;
+
+ seqact->len= seq->len;
+ calc_sequence(seqact);
+
+ seq->strip= 0;
+ free_sequence(seq);
+ BLI_remlink(ed->seqbasep, seq);
+
+ seq= ed->seqbasep->first;
+
+ }
+
+ waitcursor(0);
+
+ allqueue(REDRAWSEQ, 0);
+}
+
static void reload_image_strip(char *name)
{
Editing *ed;
@@ -718,6 +857,7 @@ static int add_seq_effect(int type)
seq= ed->seqbasep->first;
while(seq) {
if(seq->flag & SELECT) {
+ if (seq->type == SEQ_SOUND) { error("Cannot apply effects to audio sequence"); return 0; }
if(seq != seq2) {
if(seq1==0) seq1= seq;
else if(seq3==0) seq3= seq;
@@ -812,7 +952,7 @@ void add_sequence(int type)
short nr, event, mval[2];
char *str;
- event= pupmenu("Add sequence%t|Images%x1|Movie%x102|Scene%x101|Plugin%x10|Cross%x2|GammaCross%x3|Add%x4|Sub%x5|Mul%x6|AlphaOver%x7|AlphaUnder%x8|AlphaOverDrop%x9");
+ event= pupmenu("Add sequence%t|Images%x1|Movie%x102|Audio%x103|Scene%x101|Plugin%x10|Cross%x2|GammaCross%x3|Add%x4|Sub%x5|Mul%x6|AlphaOver%x7|AlphaUnder%x8|AlphaOverDrop%x9");
if(event<1) return;
@@ -891,7 +1031,11 @@ void add_sequence(int type)
}
break;
- }
+ case 103:
+ if (!last_sounddir[0]) strcpy(last_sounddir, U.sounddir);
+ activate_fileselect(FILE_SPECIAL, "SELECT WAV", last_sounddir, add_sound_strip);
+ break;
+ }
}
void change_sequence(void)
@@ -974,6 +1118,7 @@ static void recurs_del_seq(ListBase *lb)
while(seq) {
seqn= seq->next;
if(seq->flag & SELECT) {
+ if(seq->type==SEQ_SOUND && seq->sound) seq->sound->id.us--;
BLI_remlink(lb, seq);
if(seq==last_seq) last_seq= 0;
if(seq->type==SEQ_META) recurs_del_seq(&seq->seqbase);
@@ -1100,6 +1245,30 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
seq->flag &= SEQ_DESEL;
seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
}
+ else if(seq->type == SEQ_SOUND) {
+ seqn= MEM_dupallocN(seq);
+ seq->newseq= seqn;
+ BLI_addtail(new, seqn);
+
+ seqn->strip= MEM_dupallocN(seq->strip);
+ seqn->anim= 0;
+ seqn->sound->id.us++;
+
+ if(seqn->len>0) {
+ seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
+ /* copy first elem */
+ *seqn->strip->stripdata= *seq->strip->stripdata;
+ se= seqn->strip->stripdata;
+ a= seq->len;
+ while(a--) {
+ se->ok= 1;
+ se++;
+ }
+ }
+
+ seq->flag &= SEQ_DESEL;
+ seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
+ }
else if(seq->type < SEQ_EFFECT) {
seqn= MEM_dupallocN(seq);
seq->newseq= seqn;
@@ -1274,7 +1443,10 @@ void make_meta(void)
tot= 0;
seq= ed->seqbasep->first;
while(seq) {
- if(seq->flag & SELECT) tot++;
+ if(seq->flag & SELECT) {
+ tot++;
+ if (seq->type == SEQ_SOUND) { error("Cannot make Meta from audio"); return; }
+ }
seq= seq->next;
}
if(tot < 2) return;
@@ -1552,7 +1724,7 @@ void transform_seq(int mode)
seq->startofs= ix;
seq->startstill= 0;
}
- else {
+ else if (seq->type != SEQ_SOUND) {
seq->startstill= -ix;
seq->startofs= 0;
}
@@ -1575,7 +1747,7 @@ void transform_seq(int mode)
seq->endofs= -ix;
seq->endstill= 0;
}
- else {
+ else if (seq->type != SEQ_SOUND) {
seq->endstill= ix;
seq->endofs= 0;
}
@@ -1751,6 +1923,18 @@ void clever_numbuts_seq(void)
allqueue(REDRAWSEQ, 0);
}
}
+ else if(last_seq->type==SEQ_SOUND) {
+
+ add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0);
+ add_numbut(1, NUM|FLO, "Gain (dB):", -96.0, 6.0, &last_seq->level, 0);
+ add_numbut(2, NUM|FLO, "Pan:", -1.0, 1.0, &last_seq->pan, 0);
+ add_numbut(3, TOG|SHO|BIT|5, "Mute", 0.0, 1.0, &last_seq->flag, 0);
+
+ if( do_clever_numbuts("Audio", 4, REDRAW) ) {
+ se= last_seq->curelem;
+ allqueue(REDRAWSEQ, 0);
+ }
+ }
else if(last_seq->type==SEQ_META) {
add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0);
diff --git a/source/blender/src/editsound.c b/source/blender/src/editsound.c
index 4099e665d7a..27a68a76153 100644
--- a/source/blender/src/editsound.c
+++ b/source/blender/src/editsound.c
@@ -175,7 +175,6 @@ void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
void sound_initialize_sounds(void)
{
-#if GAMEBLENDER == 1
bSound* sound;
/* clear the soundscene */
@@ -189,7 +188,6 @@ void sound_initialize_sounds(void)
sound_sample_is_null(sound);
sound = (bSound *) sound->id.next;
}
-#endif
}
@@ -197,7 +195,6 @@ void sound_initialize_sounds(void)
bSound* sound_make_copy(bSound* originalsound)
{
bSound* sound = NULL;
-#if GAMEBLENDER == 1
char name[160];
int len;
@@ -240,7 +237,6 @@ bSound* sound_make_copy(bSound* originalsound)
sound->flags &= ~SOUND_FLAGS_3D;
}
-#endif
return sound;
}
@@ -253,7 +249,6 @@ void sound_initialize_sample(bSound* sound)
}
-
void sound_read_wav_data(bSound* sound, PackedFile* pf)
{
int i, temp;
@@ -267,22 +262,22 @@ void sound_read_wav_data(bSound* sound, PackedFile* pf)
/* prepare for the worst... */
sound->sample->type = SAMPLE_INVALID;
-
+
rewindPackedFile(pf);
-
+
/* check to see if it is a file in "RIFF WAVE fmt" format */
if (readPackedFile(pf, buffer, 16) != 16)
{
if (G.f & G_DEBUG) printf("File too short\n");
return;
}
-
+
if(!(memcmp(buffer, "RIFF", 4) && memcmp(&(buffer[8]), "WAVEfmt ", 8)))
{
readPackedFile(pf, &i, 4);// start of data
if(G.order==B_ENDIAN)
SWITCH_INT(i);
-
+
/* read the sampleformat */
readPackedFile(pf, &shortbuf, 2);
if(G.order==B_ENDIAN)
@@ -294,9 +289,10 @@ void sound_read_wav_data(bSound* sound, PackedFile* pf)
p_i[0]= p_i[1];
p_i[1]= s_i;
}
-
+
/* read the number of channels */
readPackedFile(pf, &shortbuf, 2);
+
if(G.order==B_ENDIAN)
{
/* was SWITCH_SHORT before */
@@ -306,7 +302,7 @@ void sound_read_wav_data(bSound* sound, PackedFile* pf)
p_i[0]= p_i[1];
p_i[1]= s_i;
}
-
+
/* check the number of channels */
if(shortbuf != 1 && shortbuf != 2)
{
@@ -317,6 +313,8 @@ void sound_read_wav_data(bSound* sound, PackedFile* pf)
/* read the samplerate */
readPackedFile(pf, &longbuf, 4);
+
+
if(G.order==B_ENDIAN)
SWITCH_INT(longbuf);
rate = longbuf;
@@ -324,6 +322,7 @@ void sound_read_wav_data(bSound* sound, PackedFile* pf)
/* read the bitrate */
// Ton's way
readPackedFile(pf, &temp, 4);
+
if(G.order==B_ENDIAN)
SWITCH_INT(temp);
@@ -331,6 +330,7 @@ void sound_read_wav_data(bSound* sound, PackedFile* pf)
bits= 8*temp/(rate * channels);
// Frank's way
+
readPackedFile(pf, &shortbuf, 2);
readPackedFile(pf, &shortbuf, 2);
if(G.order==B_ENDIAN)
@@ -346,7 +346,6 @@ void sound_read_wav_data(bSound* sound, PackedFile* pf)
seekPackedFile(pf, i-16, SEEK_CUR);
readPackedFile(pf, buffer, 4);
-
/* check if we have a 'data' chunk */
while(memcmp(buffer, "data", 4)!=0)
{
@@ -357,7 +356,6 @@ void sound_read_wav_data(bSound* sound, PackedFile* pf)
SWITCH_INT(i);
seekPackedFile(pf, i, SEEK_CUR);
-
if (readPackedFile(pf, buffer, 4) != 4)
break;
}
@@ -374,17 +372,18 @@ void sound_read_wav_data(bSound* sound, PackedFile* pf)
if(G.order==B_ENDIAN) SWITCH_INT(longbuf);
/* handle 8 and 16 bit samples differently */
- if (bits == 8)
- data = (char *)MEM_mallocN(2 * longbuf, "sample data");
- else if (bits == 16)
+ /* intrr: removed, longbuf is length in bytes, not samples */
+ if (bits == 16)
data = (char *)MEM_mallocN(longbuf, "sample data");
+ else
+ data = (char *)MEM_mallocN(longbuf*2, "sample data");
- len = longbuf;
+ len = longbuf /*/ 4.0*/; /* for some strange reason the sample length is off by a factor of 4... */
+ /* intrr's comment: Funny eh, how one 16-bit stereo sample is 4 bytes? :-) */
if(data)
{
readPackedFile(pf, data, len);
-
/* data is only used to draw! */
if (bits == 8)
{
@@ -397,19 +396,9 @@ void sound_read_wav_data(bSound* sound, PackedFile* pf)
{
if(G.order==B_ENDIAN)
{
- temps= (short *)data;
- for(i=0; i< len / 2; i++, temps++)
- {
- /* was SWITCH_SHORT before */
- char s_i, *p_i;
- p_i= (char *)&(temps);
- s_i= p_i[0];
- p_i[0]= p_i[1];
- p_i[1]= s_i;
- }
+ swab(data, data, len);
}
}
-
/* fill the sound with the found data */
sample = sound->sample;
sample->channels = channels;
@@ -434,7 +423,6 @@ void sound_read_wav_data(bSound* sound, PackedFile* pf)
int sound_get_filetype_from_header(bSound* sound, PackedFile* pf)
{
int filetype = SAMPLE_INVALID;
-#if GAMEBLENDER == 1
int i;
char buffer[25];
short shortbuf;
@@ -509,7 +497,6 @@ int sound_get_filetype_from_header(bSound* sound, PackedFile* pf)
if (G.f & G_DEBUG) printf("Unsupported sound format: %s\n", sound->name);
}
-#endif
return filetype;
}
@@ -574,7 +561,6 @@ int check_filetype(bSound* sound, PackedFile* pf)
int sound_load_sample(bSound* sound)
{
int result = FALSE;
-#if GAMEBLENDER == 1
PackedFile* pf;
int freePF = FALSE;
int buffer = -1;
@@ -652,8 +638,6 @@ int sound_load_sample(bSound* sound)
result = TRUE;
}
-#endif
-
return result;
}
@@ -662,10 +646,10 @@ int sound_load_sample(bSound* sound)
bSound* sound_new_sound(char* name)
{
bSound *sound = NULL;
-#if GAMEBLENDER == 1
int len, file;
char str[FILE_MAXDIR+FILE_MAXFILE];
-
+
+ if (!G.scene->audio.mixrate) G.scene->audio.mixrate = 44100;
/* convert the name to absolute path */
strcpy(str, name);
BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
@@ -677,6 +661,7 @@ bSound* sound_new_sound(char* name)
{
close(file);
+
/* do some name magic */
len = strlen(name);
while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\')
@@ -707,7 +692,6 @@ bSound* sound_new_sound(char* name)
}
}
-#endif
return (sound);
}
@@ -716,7 +700,6 @@ bSound* sound_new_sound(char* name)
int sound_set_sample(bSound *sound, bSample *sample)
{
int result = TRUE;
-#if GAMEBLENDER == 1
/* decrease the usernumber for this sample */
if (sound->sample)
sound->sample->id.us--;
@@ -753,8 +736,6 @@ int sound_set_sample(bSound *sound, bSample *sample)
}
}
-#endif
-
return result;
}
@@ -999,7 +980,6 @@ static void sound_init_listener(void)
void sound_init_audio(void)
{
-#if GAMEBLENDER == 1
int noaudio;
SYS_SystemHandle hSystem = NULL;
ghAudioDeviceInterface = NULL;
@@ -1007,14 +987,13 @@ void sound_init_audio(void)
hSystem = SYS_GetSystem();
noaudio = SYS_GetCommandLineInt(hSystem,"noaudio",0);
- if (noaudio)
+ if (1)/*(noaudio) intrr: disable game engine audio (openal) */
SND_SetDeviceType(snd_e_dummydevice);
ghAudioDeviceInterface = SND_GetAudioDevice();
ghSoundScene = SND_CreateScene(ghAudioDeviceInterface);
sound_init_listener();
-#endif
}
@@ -1035,9 +1014,7 @@ static void sound_exit_listener(void)
void sound_exit_audio(void)
{
-#if GAMEBLENDER == 1
SND_DeleteScene(ghSoundScene);
SND_ReleaseDevice();
sound_exit_listener();
-#endif
}
diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c
index 6d9c4904691..9c4d54ba494 100644
--- a/source/blender/src/filesel.c
+++ b/source/blender/src/filesel.c
@@ -595,6 +595,9 @@ void test_flags_file(SpaceFile *sfile)
|| BLI_testextensie(file->relname, ".mv")) {
file->flags |= MOVIEFILE;
}
+ else if(BLI_testextensie(file->relname, ".wav")) {
+ file->flags |= SOUNDFILE;
+ }
}
}
}
@@ -943,6 +946,10 @@ static void printregel(SpaceFile *sfile, struct direntry *files, int x, int y)
cpack(0x4477dd);
glRects(x-14, y, x-8, y+7);
}
+ else if(files->flags & SOUNDFILE) {
+ cpack(0xa0a000);
+ glRects(x-14, y, x-8, y+7);
+ }
else if(files->flags & FTFONTFILE) {
cpack(0xff2371);
glRects(x-14, y, x-8, y+7);
diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c
index 74eacc4ad37..8e7f78962ab 100644
--- a/source/blender/src/headerbuttons.c
+++ b/source/blender/src/headerbuttons.c
@@ -497,7 +497,7 @@ static int std_libbuttons(uiBlock *block, int xco, int pin, short *pinpoin, int
return xco;
}
-void update_for_newframe(void)
+void do_update_for_newframe(int mute)
{
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION,0);
@@ -518,6 +518,18 @@ void update_for_newframe(void)
do_all_ikas();
test_all_displists();
+
+ if ( (CFRA>1) && (!mute) && (G.scene->audio.flag & AUDIO_SCRUB)) audiostream_scrub( CFRA );
+}
+
+void update_for_newframe(void)
+{
+ do_update_for_newframe(0);
+}
+
+void update_for_newframe_muted(void)
+{
+ do_update_for_newframe(1);
}
static void show_splash(void)
@@ -1057,7 +1069,7 @@ void do_global_buttons(unsigned short event)
}
else if(ipo->blocktype==ID_SEQ) {
seq= (Sequence *)from;
- if(seq->type & SEQ_EFFECT) {
+ if((seq->type & SEQ_EFFECT)||(seq->type == SEQ_SOUND)) {
id_us_plus(idtest);
seq->ipo= ipo;
}
diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c
index 0a502b835d9..a9b3604a199 100644
--- a/source/blender/src/renderwin.c
+++ b/source/blender/src/renderwin.c
@@ -801,7 +801,7 @@ static void do_render(View3D *ogl_render_view3d, int anim, int force_dispwin)
RE_initrender(ogl_render_view3d);
}
- if(anim) update_for_newframe(); // only when anim, causes redraw event which frustrates dispview
+ if(anim) update_for_newframe_muted(); // only when anim, causes redraw event which frustrates dispview
R.flag= 0;
if (render_win) window_set_cursor(render_win->win, CURSOR_STD);
diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c
new file mode 100644
index 00000000000..fa43d3a6c39
--- /dev/null
+++ b/source/blender/src/seqaudio.c
@@ -0,0 +1,392 @@
+/**
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): intrr
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#include "BLI_winstuff.h"
+#endif
+
+#include <fcntl.h>
+#include <stdio.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "PIL_time.h"
+
+#include "BMF_Api.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_editVert.h"
+
+#include "DNA_screen_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_sequence_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_ipo_types.h"
+
+#include "BKE_utildefines.h"
+#include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_blender.h"
+#include "BKE_main.h"
+#include "BKE_ipo.h"
+
+#include "BIF_gl.h"
+#include "BIF_graphics.h"
+#include "BIF_keyval.h"
+#include "BIF_mainqueue.h"
+#include "BIF_resources.h"
+#include "BIF_screen.h"
+#include "BIF_toolbox.h"
+#include "BIF_mywindow.h"
+#include "BIF_space.h"
+#include "BIF_glutil.h"
+#include "BIF_interface.h"
+
+#include "BSE_view.h"
+#include "BSE_seqaudio.h"
+
+#include "mydevice.h"
+#include "interface.h"
+#include "blendef.h"
+
+void audio_fill(void *mixdown, Uint8 *sstream, int len);
+/* ************ GLOBALS ************* */
+
+int audio_pos;
+SDL_AudioSpec wav_spec;
+int audio_scrub=0;
+int audio_playing=0;
+/////
+//
+
+
+void makewavstring (char *string)
+{
+ char txt[64];
+
+ if (string==0) return;
+
+ strcpy(string, G.scene->r.pic);
+ BLI_convertstringcode(string, G.sce, G.scene->r.cfra);
+
+ RE_make_existing_file(string);
+
+ if (strcasecmp(string + strlen(string) - 4, ".wav")) {
+ sprintf(txt, "%04d_%04d.wav", (G.scene->r.sfra) , (G.scene->r.efra) );
+ strcat(string, txt);
+ }
+}
+
+void audio_mixdown()
+{
+ int file, c, totlen, totframe, i, oldcfra, cfra2;
+ char *buf;
+
+ buf = MEM_mallocN(65536, "audio_mixdown");
+ makewavstring(buf);
+
+ file = open(buf, O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
+
+ if(file == -1)
+ {
+ error("Cannot open output file!");
+ return;
+ }
+
+ strcpy(buf, "RIFFlengWAVEfmt fmln01ccRATEbsecBP16dataDLEN");
+ totframe = (EFRA - SFRA + 1);
+ totlen = (int) ( ((float)totframe / (float)G.scene->r.frs_sec) * (float)G.scene->audio.mixrate * 4.0);
+ printf("totlen %x\n", totlen);
+ memcpy(buf+4, &totlen, 4);
+ 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;
+ memcpy(buf+28, &i, 4);
+ buf[32] = 4; buf[33] = 0; buf[34] = 16; buf[35] = 0;
+ i = totlen;
+ memcpy(buf+40, &i, 4);
+
+ if (G.order == B_ENDIAN) {
+ /* swap the four ints to little endian */
+
+ /* length */
+ SWITCH_INT(buf[4]);
+
+ /* audio rate */
+ SWITCH_INT(buf[24]);
+
+ /* audio mixrate * 4 */
+ SWITCH_INT(buf[28]);
+
+ /* length */
+ SWITCH_INT(buf[40]);
+ }
+
+ c = write(file, buf, 44);
+
+ oldcfra = CFRA;
+ audiostream_play(SFRA, 0, 1);
+ for (CFRA = SFRA, i = 0; (CFRA<=EFRA);
+ CFRA=(int) ( ((float)(audio_pos-64)/( G.scene->audio.mixrate*4 ))*(float)G.scene->r.frs_sec )) {
+ if (cfra2 != CFRA) {
+ cfra2 = CFRA;
+ set_timecursor(CFRA);
+ }
+ memset(buf+i, 0, 64);
+ audio_fill(buf+i, NULL, 64);
+ if (G.order == B_ENDIAN) {
+ swab(buf+i, buf+i, 64);
+ }
+ if (i == (65536-64)) {
+ i=0;
+ write(file, buf, 65536);
+ } else i+=64;
+ }
+ write(file, buf, i);
+ waitcursor(0);
+ CFRA = oldcfra;
+ close(file);
+ MEM_freeN(buf);
+
+ return;
+}
+
+void audio_levels(Uint8 *buf, int len, float db, float facf, float pan)
+{
+ int i;
+ 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+G.scene->audio.main))/20.0)) / facf;
+ facl /= fac;
+ facr /= fac;
+
+ for (i=0; i<len; i+=4) {
+ sample = (signed short*)(buf+i);
+ sample[1] = (short) ((float)sample[0] * facl);
+ sample[0] = (short) ((float)sample[1] * facr);
+/* if (G.order==B_ENDIAN) {
+ sample[0] = ((((sample[0]) & 0xff00) >> 8) | ((sample[0]) & 0x00ff) << 8);
+ sample[1] = ((((sample[1]) & 0xff00) >> 8) | ((sample[1]) & 0x00ff) << 8);
+ }*/
+ }
+}
+
+/* convert mono/stereo and sampling rate, alloc a buffer for
+ * sound->stream to contain the new sample, and set sound->streamlen
+ * accordingly.
+ */
+void audio_makestream(bSound *sound)
+{
+ signed short *source, *dest;
+ float ratio;
+ int i;
+
+ if ( (!sound)||(sound->stream)||(!sound->sample)||(!G.scene) ) {
+ 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->stream = MEM_mallocN((int) ((float)sound->streamlen * 1.05), "stream");
+ if (sound->sample->rate == G.scene->audio.mixrate) {
+ if (sound->sample->channels == 2) {
+ memcpy(sound->stream, sound->sample->data, sound->streamlen);
+ return;
+ } else {
+ 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];
+ 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)];
+ }
+ 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) {
+ dest[1] = source[(int)((float)i/ratio)];
+ dest[0] = source[(int)((float)i/ratio)+1];
+ }
+ }
+}
+
+void audio_fill(void *mixdown, Uint8 *sstream, int len)
+{
+ static Editing *ed;
+ static Sequence *seq;
+ static Uint8* cvtbuf;
+ static bSound* sound;
+ static float facf;
+
+
+ ed= G.scene->ed;
+ if((ed) && (!(G.scene->audio.flag & AUDIO_MUTE))) {
+ seq= ed->seqbasep->first;
+ while(seq) {
+ if ( (seq->type == SEQ_SOUND) &&
+ (seq->sound) &&
+ (!(seq->flag & SEQ_MUTE)))
+ {
+ sound = seq->sound;
+ audio_makestream(sound);
+ if ((seq->curpos<sound->streamlen -len) && (seq->curpos>=0) &&
+ (seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA))
+ {
+ if(seq->ipo && seq->ipo->curve.first) facf = seq->facf0; else facf = 1.0;
+ cvtbuf = MEM_callocN(len, "cvtbuf");
+ memcpy(cvtbuf, ((Uint8*)sound->stream)+(seq->curpos & (~3)), len);
+ audio_levels(cvtbuf, len, seq->level, facf, seq->pan);
+ if (!mixdown) {
+ SDL_MixAudio(sstream, cvtbuf, len, SDL_MIX_MAXVOLUME);
+ } else {
+ SDL_MixAudio((Uint8*)mixdown, cvtbuf, len, SDL_MIX_MAXVOLUME);
+ }
+ MEM_freeN(cvtbuf);
+ }
+ seq->curpos += len;
+ }
+ seq= seq->next;
+ }
+ }
+
+
+ audio_pos += len;
+ if (audio_scrub) {
+ audio_scrub--;
+ if (!audio_scrub) {
+ audiostream_stop();
+ }
+ }
+}
+
+int audio_init(SDL_AudioSpec *desired)
+{
+ SDL_AudioSpec *obtained, *hardware_spec;
+
+ SDL_CloseAudio();
+
+ obtained = (SDL_AudioSpec*)MEM_mallocN(sizeof(SDL_AudioSpec), "SDL_AudioSpec");
+
+ desired->callback=audio_fill;
+
+ if ( SDL_OpenAudio(desired, obtained) < 0 ){
+ fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
+ return 0;
+ }
+ hardware_spec=obtained;
+
+ MEM_freeN(obtained);
+
+ SDL_PauseAudio(1);
+ return 1;
+}
+
+void audiostream_play(Uint32 startframe, Uint32 duration, int mixdown)
+{
+ static SDL_AudioSpec desired;
+ Editing *ed;
+ Sequence *seq;
+ bSound *sound;
+
+ ed= G.scene->ed;
+ if(ed) {
+ seq= ed->seqbasep->first;
+ while(seq) {
+ if ((seq->type == SEQ_SOUND) && (seq->sound))
+ {
+ sound = ((bSound*)seq->sound);
+ seq->curpos = (int)( (((float)((float)startframe-(float)seq->start)/(float)G.scene->r.frs_sec)*((float)G.scene->audio.mixrate)*4 ));
+ }
+ seq= seq->next;
+ }
+ }
+
+ if (!(duration + mixdown)) {
+ desired.freq=G.scene->audio.mixrate;
+ desired.format=AUDIO_S16SYS;
+ desired.channels=2;
+ desired.samples=U.mixbufsize;
+ desired.userdata=0;
+ if (audio_init(&desired)==0) {
+ U.mixbufsize = 0; /* no audio */
+ }
+ }
+ audio_pos = ( ((int)( (((float)startframe)/(float)G.scene->r.frs_sec)*(G.scene->audio.mixrate)*4 )) & (~3) );
+
+ audio_scrub = duration;
+ if (!mixdown) {
+ SDL_PauseAudio(0);
+ audio_playing++;
+ }
+}
+
+void audiostream_start(Uint32 frame)
+{
+ audiostream_play(frame, 0, 0);
+}
+
+void audiostream_scrub(Uint32 frame)
+{
+ if (U.mixbufsize) audiostream_play(frame, 4096/U.mixbufsize, 0);
+}
+
+void audiostream_stop(void)
+{
+ SDL_PauseAudio(1);
+ audio_playing=0;
+}
+
+int audiostream_pos(void)
+{
+ int pos;
+
+ pos = (int) ( ((float)(audio_pos-U.mixbufsize)/( G.scene->audio.mixrate*4 ))*(float)G.scene->r.frs_sec );
+ if (pos<1) pos=1;
+ return ( pos );
+}
+
diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c
index f30eff81195..76beb874345 100644
--- a/source/blender/src/sequence.c
+++ b/source/blender/src/sequence.c
@@ -1234,6 +1234,9 @@ void do_build_seqar_cfra(ListBase *seqbase, Sequence ***seqar, int cfra)
/* set at zero because free_imbuf_seq... */
seq->curelem= 0;
+
+ if ((seq->type == SEQ_SOUND) && (seq->ipo)
+ &&(seq->startdisp<=cfra+2) && (seq->enddisp>cfra)) do_seq_ipo(seq);
if(seq->startdisp <=cfra && seq->enddisp > cfra) {
@@ -1256,6 +1259,9 @@ void do_build_seqar_cfra(ListBase *seqbase, Sequence ***seqar, int cfra)
se->ibuf= se->se1->ibuf;
}
}
+ else if(seq->type == SEQ_SOUND) {
+ se->ok= 2;
+ }
else if(seq->type & SEQ_EFFECT) {
/* test if image is too small: reload */
@@ -1371,7 +1377,7 @@ void do_build_seqar_cfra(ListBase *seqbase, Sequence ***seqar, int cfra)
RE_initrender(NULL);
if (!G.background) {
- if(R.r.mode & R_FIELDS) update_for_newframe();
+ if(R.r.mode & R_FIELDS) update_for_newframe_muted();
R.flag= 0;
free_filesel_spec(G.scene->r.pic);
@@ -1476,7 +1482,7 @@ ImBuf *give_ibuf_seq(int cfra)
seq= seqar[seqnr];
se= seq->curelem;
- if(se) {
+ if((seq->type != SEQ_SOUND) && (se)) {
if(seq->type==SEQ_META) {
/* bottom strip! */
@@ -1508,7 +1514,8 @@ ImBuf *give_ibuf_seq(int cfra)
MEM_freeN(seqar);
- if(seqfirst->curelem==0) return 0;
+ if(!seqfirst) return 0;
+ if(!seqfirst->curelem==0) return 0;
return seqfirst->curelem->ibuf;
}
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 9c5f87076e0..6425303a97a 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -1780,7 +1780,7 @@ void drawinfospace(ScrArea *sa, void *spacedata)
#ifdef _WIN32
uiDefBut(block, LABEL,0,"Win Codecs:",
- (xpos+edgespace+(2*midspace)+(2*medprefbut)),y3label,medprefbut,buth,
+ (xpos+edgespace+(1*midspace)+(1*medprefbut)),y3label,medprefbut,buth,
0, 0, 0, 0, 0, "");
uiDefButS(block, TOG|BIT|8, 0, "Enable all codecs",
@@ -1828,6 +1828,14 @@ void drawinfospace(ScrArea *sa, void *spacedata)
(xpos+edgespace+(5*medprefbut)+(5*midspace)),y1,medprefbut,buth,
&(U.gameflags), 0, 0, 0, 0, "Toggles between vertex arrays on (less reliable) and off (more reliable)");
+ uiDefBut(block, LABEL,0,"Audio:",
+ (xpos+edgespace+(2*midspace)+(2*medprefbut)),y3label,medprefbut,buth,
+ 0, 0, 0, 0, 0, "");
+
+ uiDefButI(block, ROW, 0, "Mixing buffer 256", (xpos+edgespace+(2*midspace)+(2*medprefbut)),y2,medprefbut,buth, &U.mixbufsize, 2.0, 256.0, 0, 0, "Set audio buffer size to 256 samples");
+ uiDefButI(block, ROW, 0, "512", (xpos+edgespace+(2*midspace)+(2*medprefbut)),y1,61,buth, &U.mixbufsize, 2.0, 512.0, 0, 0, "Set audio buffer size to 512 samples");
+ uiDefButI(block, ROW, 0, "1024", (xpos+edgespace+(2*midspace)+(2*medprefbut))+61+midspace,y1,61,buth, &U.mixbufsize, 2.0, 1024.0, 0, 0, "Set audio buffer size to 1024 samples");
+ uiDefButI(block, ROW, 0, "2048", (xpos+edgespace+(2*midspace)+(2*medprefbut))+2*(61+midspace),y1,61,buth, &U.mixbufsize, 2.0, 2048.0, 0, 0, "Set audio buffer size to 2048 samples");
} else if(U.userpref == 5) { /* file paths */
@@ -2132,6 +2140,7 @@ void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
CFRA= cfra;
force_draw();
+ update_for_newframe(); /* for audio scrubbing */
}
} while(get_mbut()&L_MOUSE);
diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c
index 3bffcffb471..29f2b3d6a28 100644
--- a/source/blender/src/usiblender.c
+++ b/source/blender/src/usiblender.c
@@ -230,7 +230,9 @@ int BIF_read_homefile(void)
U.transopts |= TR_ALL;
}
#endif
-
+ if (G.main->versionfile <= 227) {
+ U.mixbufsize= 2048;
+ }
space_set_commmandline_options();
reset_autosave();
diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk
index f0c33cb80e6..ecd1623576c 100644
--- a/source/nan_definitions.mk
+++ b/source/nan_definitions.mk
@@ -79,6 +79,8 @@ all debug::
else
export NAN_FTGL ?= $(LCGDIR)/ftgl
endif
+ export NAN_SDLLIBS ?= $(shell sdl-config --libs)
+ export NAN_SDLCFLAGS ?= $(shell sdl-config --cflags)
# Platform Dependent settings go below:
diff --git a/source/nan_link.mk b/source/nan_link.mk
index 67c4edf8f60..7db3eebf8a9 100644
--- a/source/nan_link.mk
+++ b/source/nan_link.mk
@@ -150,3 +150,4 @@ ifeq ($(OS),windows)
endif
endif
+LLIBS += $(NAN_SDLLIBS)