forked from bartvdbraak/blender
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.
This commit is contained in:
parent
9cb79c6534
commit
4f27386740
@ -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! */
|
||||
}
|
||||
|
@ -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;
|
||||
|
52
source/blender/include/BSE_seqaudio.h
Normal file
52
source/blender/include/BSE_seqaudio.h
Normal file
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 *************************** */
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
392
source/blender/src/seqaudio.c
Normal file
392
source/blender/src/seqaudio.c
Normal file
@ -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 );
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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:
|
||||
|
@ -150,3 +150,4 @@ ifeq ($(OS),windows)
|
||||
endif
|
||||
endif
|
||||
|
||||
LLIBS += $(NAN_SDLLIBS)
|
||||
|
Loading…
Reference in New Issue
Block a user