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:
Wouter van Heyst 2003-07-13 20:16:56 +00:00
parent 9cb79c6534
commit 4f27386740
25 changed files with 956 additions and 123 deletions

View 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! */
}

View 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;

View 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

View 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

View 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

View 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

View 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 */

View 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;

View 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

View File

@ -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 *************************** */

View 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)

View 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

View 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;

View 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);
}

View 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"
@ -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);

View 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
}

View 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);

View 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;
}

View 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);

View 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 );
}

View 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;
}

View 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);

View 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();

View 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:

View File

@ -150,3 +150,4 @@ ifeq ($(OS),windows)
endif
endif
LLIBS += $(NAN_SDLLIBS)