Commit message and the brunt of the code courtesy of intrr, apologies for the
authorWouter van Heyst <larstiq-bforge@larstiq.dyndns.org>
Sun, 13 Jul 2003 20:16:56 +0000 (20:16 +0000)
committerWouter van Heyst <larstiq-bforge@larstiq.dyndns.org>
Sun, 13 Jul 2003 20:16:56 +0000 (20:16 +0000)
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.

25 files changed:
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/include/BSE_seqaudio.h [new file with mode: 0644]
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_sequence_types.h
source/blender/makesdna/DNA_sound_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/src/Makefile
source/blender/src/buttons.c
source/blender/src/drawseq.c
source/blender/src/drawview.c
source/blender/src/editipo.c
source/blender/src/editnla.c
source/blender/src/editseq.c
source/blender/src/editsound.c
source/blender/src/filesel.c
source/blender/src/headerbuttons.c
source/blender/src/renderwin.c
source/blender/src/seqaudio.c [new file with mode: 0644]
source/blender/src/sequence.c
source/blender/src/space.c
source/blender/src/usiblender.c
source/nan_definitions.mk
source/nan_link.mk

index 3f274aafb900e8bc06c7cc5c3675835dcb4f0a18..5aecd18b2311bf15c142f81032bf9bbc073d0910 100644 (file)
@@ -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! */
 }
index 640e53330230a6ef00461a0230570ac43e31ce68..9845899c7d9ce22b423880cb896ecf20949a0de7 100644 (file)
@@ -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 (file)
index 0000000..f395ac4
--- /dev/null
@@ -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
+
index c15b34def92f861322b622d13df62dbf72e9f1ce..7ce8447da6aaee93bc85ed3445822bbb5a590fd8 100644 (file)
@@ -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
index f3827f5e0b20c26bf6427f04f976935b0e11e2cc..efc145da8f6db7592f2ff4f40e5e701d4a7a021a 100644 (file)
@@ -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
index 41429a0217e493bb43f2924d5f332845be570333..8f91cb81e472d703bb7659c2a8d0088dbd916d8e 100644 (file)
@@ -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
index 59fa9e07604757e36893c9a57a10f81e13c3449f..a3b2e85741744289b07e740c593bf52c988f4808 100644 (file)
@@ -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 */
index 2d2ba593513cda8a0ba714b56b43ed4660f8ee20..5a32974970876dacd7a8b6b9514b40c2019a7d4d 100644 (file)
@@ -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;
index 35c29a8571ea36c54c048f006bb76552e583856d..6737d942eedfed3095d99e2321f2244bb6842ef3 100644 (file)
@@ -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
index 2f3efded78827f3c6da6c7d73f1e9c1d25696e1a..c6eef4b906fccb774db3e4043cf2bb5efedcb442 100644 (file)
 #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 *************************** */
index aa863e4b9923caa1b605ccdd6a24ecfc114ee630..bba768a894b98a58be299e76b790c3dcdab85d02 100644 (file)
@@ -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)
index 01fba8eb27f5920b9040380c386e751ae8df971c..a963285bb27c7ee182423c237b912e3b50197644 100644 (file)
@@ -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
index f8b34269eac950cbd8fc9133547998a57fd9840d..b0cf75ff7da00072f01f621722a7dfe5c5303865 100644 (file)
@@ -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;
index 3f66bd5724d100468331af00ea2de1e3840cefa8..781ddfe518dc4f78ad00a7b4422659514b87a474 100644 (file)
@@ -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);
 }      
index 54e63a1b42d54d431123aaf380e4182397131671..79db90154c6c94be6aef4fcc93b0f86da22144fb 100644 (file)
@@ -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"
 #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);
index 4099e665d7a9655f85ba1019b5f9272c17c52632..27a68a76153da29df42441f5ceb832fed6d815ed 100644 (file)
@@ -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 
 }
index 6d9c4904691bfcaf5653a69c487aa7f0c50ebe6f..9c4d54ba4942a6c4a46c5189af33233f50605e2a 100644 (file)
@@ -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);
index 74eacc4ad374b64fbe5c8d86165101c75ac36f5d..8e7f78962ab23085672b114d51486f8cf9fe19a4 100644 (file)
@@ -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;
                                        }
index 0a502b835d901b8511f0dd0255b4cde2cc275a06..a9b3604a199900d716c87d3f989c809096dbff8b 100644 (file)
@@ -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 (file)
index 0000000..fa43d3a
--- /dev/null
@@ -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 );
+}
+
index f30eff8119593e5275fbef85644b6f9ba4b015c8..76beb8743459bbd0fbcee4fd67dfb93002afa34b 100644 (file)
@@ -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;
 
 }
index 9c5f87076e04e94320521659b3191925c275f3e4..6425303a97aebb6fd3ee683407e04534da17f574 100644 (file)
@@ -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);
index 3bffcffb471da6af96c3584c163987d412994ce5..29f2b3d6a2844984c1005db4a44c565279f40c19 100644 (file)
@@ -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();
index f0c33cb80e6b67aa00eb56071c8d3778df956e04..ecd1623576cada0901096bf654bb4863a21b7085 100644 (file)
@@ -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:
index 67c4edf8f608a1c774996d182d5dda4689f39f49..7db3eebf8a9bbb4de4d02a8f36b8c243e294ed47 100644 (file)
@@ -150,3 +150,4 @@ ifeq ($(OS),windows)
        endif
 endif
 
+LLIBS += $(NAN_SDLLIBS)