Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/blender.c5
-rw-r--r--source/blender/blenkernel/intern/library.c2
-rw-r--r--source/blender/blenkernel/intern/packedFile.c55
-rw-r--r--source/blender/blenkernel/intern/sca.c12
-rw-r--r--source/blender/blenkernel/intern/scene.c2
-rw-r--r--source/blender/blenkernel/intern/sequence.c66
-rw-r--r--source/blender/blenkernel/intern/sound.c515
-rw-r--r--source/blender/blenkernel/intern/writeavi.c2
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c29
-rw-r--r--source/blender/blenkernel/intern/writeframeserver.c2
10 files changed, 530 insertions, 160 deletions
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 2728aa30e6e..2e4e5596450 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -176,8 +176,6 @@ void pushpop_test()
void free_blender(void)
{
/* samples are in a global list..., also sets G.main->sound->sample NULL */
- sound_free_all_samples();
-
free_main(G.main);
G.main= NULL;
@@ -330,9 +328,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
MEM_freeN(bfd->user);
}
- /* samples is a global list... */
- sound_free_all_samples();
-
/* case G_FILE_NO_UI or no screens in file */
if(mode) {
/* leave entire context further unaltered? */
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index ff065fd4bf6..3c8bf9200f8 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -567,7 +567,7 @@ void free_libblock(ListBase *lb, void *idv)
//XXX free_script((Script *)id);
break;
case ID_SO:
- sound_free_sound((bSound *)id);
+ sound_free((bSound*)id);
break;
case ID_GR:
free_group((Group *)id);
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 590189fbd5d..8c77ed92aa1 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -123,7 +123,7 @@ int countPackedFiles(Main *bmain)
{
Image *ima;
VFont *vf;
- bSample *sample;
+ bSound *sound;
int count = 0;
// let's check if there are packed files...
@@ -135,10 +135,9 @@ int countPackedFiles(Main *bmain)
if(vf->packedfile)
count++;
- if(samples)
- for(sample=samples->first; sample; sample=sample->id.next)
- if(sample->packedfile)
- count++;
+ for(sound=bmain->sound.first; sound; sound=sound->id.next)
+ if(sound->packedfile)
+ count++;
return count;
}
@@ -208,8 +207,8 @@ void packAll(Main *bmain, ReportList *reports)
{
Image *ima;
VFont *vf;
- bSample *sample;
-
+ bSound *sound;
+
for(ima=bmain->image.first; ima; ima=ima->id.next)
if(ima->packedfile == NULL)
ima->packedfile = newPackedFile(reports, ima->name);
@@ -218,10 +217,9 @@ void packAll(Main *bmain, ReportList *reports)
if(vf->packedfile == NULL)
vf->packedfile = newPackedFile(reports, vf->name);
- if(samples)
- for(sample=samples->first; sample; sample=sample->id.next)
- if(sample->packedfile == NULL)
- sound_set_packedfile(sample, newPackedFile(reports, sample->name));
+ for(sound=bmain->sound.first; sound; sound=sound->id.next)
+ if(sound->packedfile == NULL)
+ sound->packedfile = newPackedFile(reports, sound->name);
}
@@ -456,28 +454,26 @@ int unpackVFont(ReportList *reports, VFont *vfont, int how)
return (ret_value);
}
-int unpackSample(ReportList *reports, bSample *sample, int how)
+int unpackSound(ReportList *reports, bSound *sound, int how)
{
char localname[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
char *newname;
int ret_value = RET_ERROR;
- PackedFile *pf;
-
- if (sample != NULL) {
- strcpy(localname, sample->name);
+
+ if (sound != NULL) {
+ strcpy(localname, sound->name);
BLI_splitdirstring(localname, fi);
- sprintf(localname, "//samples/%s", fi);
-
- newname = unpackFile(reports, sample->name, localname, sample->packedfile, how);
+ sprintf(localname, "//sounds/%s", fi);
+
+ newname = unpackFile(reports, sound->name, localname, sound->packedfile, how);
if (newname != NULL) {
- strcpy(sample->name, newname);
+ strcpy(sound->name, newname);
MEM_freeN(newname);
- pf = sample->packedfile;
- // because samples and sounds can point to the
- // same packedfile we have to check them all
- sound_set_packedfile(sample, NULL);
- freePackedFile(pf);
+ freePackedFile(sound->packedfile);
+ sound->packedfile = 0;
+
+ sound_load(sound);
ret_value = RET_OK;
}
@@ -515,7 +511,7 @@ void unpackAll(Main *bmain, ReportList *reports, int how)
{
Image *ima;
VFont *vf;
- bSample *sample;
+ bSound *sound;
for(ima=bmain->image.first; ima; ima=ima->id.next)
if(ima->packedfile)
@@ -525,9 +521,8 @@ void unpackAll(Main *bmain, ReportList *reports, int how)
if(vf->packedfile)
unpackVFont(reports, vf, how);
- if(samples)
- for(sample=samples->first; sample; sample=sample->id.next)
- if(sample->packedfile)
- unpackSample(reports, sample, how);
+ for(sound=bmain->sound.first; sound; sound=sound->id.next)
+ if(sound->packedfile)
+ unpackSound(reports, sound, how);
}
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index 74d2347ec39..9a66603fef0 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -35,6 +35,8 @@
#include <stdio.h>
#include <string.h>
+#include <float.h>
+
#include "MEM_guardedalloc.h"
#include "DNA_text_types.h"
@@ -410,6 +412,7 @@ void init_actuator(bActuator *act)
{
/* also use when actuator changes type */
bObjectActuator *oa;
+ bSoundActuator *sa;
if(act->data) MEM_freeN(act->data);
act->data= 0;
@@ -422,7 +425,14 @@ void init_actuator(bActuator *act)
break;
#endif
case ACT_SOUND:
- act->data= MEM_callocN(sizeof(bSoundActuator), "soundact");
+ sa = act->data= MEM_callocN(sizeof(bSoundActuator), "soundact");
+ sa->volume = 1.0f;
+ sa->sound3D.rolloff_factor = 1.0f;
+ sa->sound3D.reference_distance = 1.0f;
+ sa->sound3D.max_gain = 1.0f;
+ sa->sound3D.cone_inner_angle = 360.0f;
+ sa->sound3D.cone_outer_angle = 360.0f;
+ sa->sound3D.max_distance = FLT_MAX;
break;
case ACT_CD:
act->data= MEM_callocN(sizeof(bCDActuator), "cdact");
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index a44118d186b..0a93874f24e 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -140,7 +140,7 @@ void free_scene(Scene *sce)
/* do not free objects! */
BLI_freelistN(&sce->base);
- seq_free_editing(sce->ed);
+ seq_free_editing(sce);
BKE_free_animdata((ID *)sce);
BKE_keyingsets_free(&sce->keyingsets);
diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c
index 3b675a87e59..159a60ad3af 100644
--- a/source/blender/blenkernel/intern/sequence.c
+++ b/source/blender/blenkernel/intern/sequence.c
@@ -52,6 +52,10 @@
#include "BLI_threads.h"
#include <pthread.h>
+#include "BKE_context.h"
+#include "BKE_sound.h"
+#include "AUD_C-API.h"
+
#ifdef WIN32
#define snprintf _snprintf
#endif
@@ -178,12 +182,16 @@ void seq_free_strip(Strip *strip)
MEM_freeN(strip);
}
-void seq_free_sequence(Editing *ed, Sequence *seq)
+void seq_free_sequence(Scene *scene, Sequence *seq)
{
+ Editing *ed = scene->ed;
+
if(seq->strip) seq_free_strip(seq->strip);
if(seq->anim) IMB_free_anim(seq->anim);
- //XXX if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio);
+
+ if(seq->sound_handle)
+ sound_delete_handle(scene, seq->sound_handle);
if (seq->type & SEQ_EFFECT) {
struct SeqEffectHandle sh = get_sequence_effect(seq);
@@ -208,8 +216,9 @@ Editing *seq_give_editing(Scene *scene, int alloc)
return scene->ed;
}
-void seq_free_editing(Editing *ed)
+void seq_free_editing(Scene *scene)
{
+ Editing *ed = scene->ed;
MetaStack *ms;
Sequence *seq;
@@ -217,7 +226,7 @@ void seq_free_editing(Editing *ed)
return;
SEQ_BEGIN(ed, seq) {
- seq_free_sequence(ed, seq);
+ seq_free_sequence(scene, seq);
}
SEQ_END
@@ -444,6 +453,8 @@ void calc_sequence_disp(Sequence *seq)
else if(seq->enddisp-seq->startdisp > 250) {
seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
}
+
+ seq_update_sound(seq);
}
void calc_sequence(Sequence *seq)
@@ -515,8 +526,8 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
char str[FILE_MAXDIR+FILE_MAXFILE];
if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
- seq->type == SEQ_HD_SOUND || seq->type == SEQ_RAM_SOUND ||
- seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
+ seq->type == SEQ_SOUND ||
+ seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
return;
}
@@ -558,23 +569,8 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
seq->len = 0;
}
seq->strip->len = seq->len;
- } else if (seq->type == SEQ_HD_SOUND) {
-// XXX if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio);
-// seq->hdaudio = sound_open_hdaudio(str);
-
- if (!seq->hdaudio) {
- return;
- }
-
-// XXX seq->len = sound_hdaudio_get_duration(seq->hdaudio, FPS) - seq->anim_startofs - seq->anim_endofs;
- if (seq->len < 0) {
- seq->len = 0;
- }
- seq->strip->len = seq->len;
- } else if (seq->type == SEQ_RAM_SOUND) {
- seq->len = (int) ( ((float)(seq->sound->streamlen-1)/
- ((float)scene->audio.mixrate*4.0 ))
- * FPS);
+ } else if (seq->type == SEQ_SOUND) {
+ seq->len = AUD_getInfo(seq->sound->snd_sound).length * FPS;
seq->len -= seq->anim_startofs;
seq->len -= seq->anim_endofs;
if (seq->len < 0) {
@@ -693,8 +689,7 @@ char *give_seqname_by_type(int type)
case SEQ_IMAGE: return "Image";
case SEQ_SCENE: return "Scene";
case SEQ_MOVIE: return "Movie";
- case SEQ_RAM_SOUND: return "Audio (RAM)";
- case SEQ_HD_SOUND: return "Audio (HD)";
+ case SEQ_SOUND: return "Audio";
case SEQ_CROSS: return "Cross";
case SEQ_GAMCROSS: return "Gamma Cross";
case SEQ_ADD: return "Add";
@@ -1071,10 +1066,9 @@ int evaluate_seq_frame(Scene *scene, int cfra)
static int video_seq_is_rendered(Sequence * seq)
{
- return (seq
- && !(seq->flag & SEQ_MUTE)
- && seq->type != SEQ_RAM_SOUND
- && seq->type != SEQ_HD_SOUND);
+ return (seq
+ && !(seq->flag & SEQ_MUTE)
+ && seq->type != SEQ_SOUND);
}
static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
@@ -3309,7 +3303,7 @@ void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
}
/* sounds cannot be extended past their endpoints */
- if (seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) {
+ if (seq->type == SEQ_SOUND) {
seq->startstill= 0;
seq->endstill= 0;
}
@@ -3406,3 +3400,15 @@ int shuffle_seq(ListBase * seqbasep, Sequence *test)
return 1;
}
}
+
+void seq_update_sound(struct Sequence *seq)
+{
+ if(seq->type == SEQ_SOUND)
+ {
+ seq->sound_handle->startframe = seq->startdisp;
+ seq->sound_handle->endframe = seq->enddisp;
+ seq->sound_handle->frameskip = seq->startofs + seq->anim_startofs;
+ seq->sound_handle->mute = seq->flag & SEQ_MUTE ? 1 : 0;
+ seq->sound_handle->changed = -1;
+ }
+}
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 2c5b49246fb..347837d1dd0 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -1,6 +1,6 @@
/**
* sound.c (mar-2001 nzc)
- *
+ *
* $Id$
*/
@@ -14,125 +14,468 @@
#include "DNA_scene_types.h"
#include "DNA_sound_types.h"
#include "DNA_packedFile_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_userdef_types.h"
+
+#include "AUD_C-API.h"
#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_sound.h"
+#include "BKE_context.h"
+#include "BKE_library.h"
#include "BKE_packedFile.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-ListBase _samples = {0,0}, *samples = &_samples;
+void sound_init()
+{
+ AUD_Specs specs;
+ specs.channels = AUD_CHANNELS_STEREO;
+ specs.format = AUD_FORMAT_S16;
+ specs.rate = AUD_RATE_44100;
+
+ if(!AUD_init(AUD_SDL_DEVICE, specs, AUD_DEFAULT_BUFFER_SIZE))
+ if(!AUD_init(AUD_OPENAL_DEVICE, specs, AUD_DEFAULT_BUFFER_SIZE*4))
+ AUD_init(AUD_NULL_DEVICE, specs, AUD_DEFAULT_BUFFER_SIZE);
+}
-void sound_free_sound(bSound *sound)
+void sound_reinit(struct bContext *C)
{
- /* when sounds have been loaded, but not played, the packedfile was not copied
- to sample block and not freed otherwise */
- if(sound->sample==NULL) {
- if (sound->newpackedfile) {
- freePackedFile(sound->newpackedfile);
- sound->newpackedfile = NULL;
- }
+ AUD_Specs specs;
+ int device, buffersize;
+
+ device = U.audiodevice;
+ buffersize = U.mixbufsize;
+ specs.channels = U.audiochannels;
+ specs.format = U.audioformat;
+ specs.rate = U.audiorate;
+
+ if(buffersize < 128)
+ buffersize = AUD_DEFAULT_BUFFER_SIZE;
+
+ if(specs.rate < AUD_RATE_8000)
+ specs.rate = AUD_RATE_44100;
+
+ if(specs.format <= AUD_FORMAT_INVALID)
+ specs.format = AUD_FORMAT_S16;
+
+ if(specs.channels <= AUD_CHANNELS_INVALID)
+ specs.channels = AUD_CHANNELS_STEREO;
+
+ if(!AUD_init(device, specs, buffersize))
+ AUD_init(AUD_NULL_DEVICE, specs, buffersize);
+}
+
+void sound_exit()
+{
+ AUD_exit();
+}
+
+struct bSound* sound_new_file(struct Main *main, char* filename)
+{
+ bSound* sound = NULL;
+
+ char str[FILE_MAX];
+ int len;
+
+ strcpy(str, filename);
+ BLI_convertstringcode(str, G.sce);
+
+ len = strlen(filename);
+ while(len > 0 && filename[len-1] != '/' && filename[len-1] != '\\')
+ len--;
+
+ sound = alloc_libblock(&main->sound, ID_SO, filename+len);
+ strcpy(sound->name, filename);
+ sound->type = SOUND_TYPE_FILE;
+
+ sound_load(sound);
+
+ if(!sound->snd_sound)
+ {
+ free_libblock(&main->sound, sound);
+ sound = NULL;
+ }
+
+ return sound;
+}
+
+// XXX unused currently
+#if 0
+struct bSound* sound_new_buffer(struct bContext *C, struct bSound *source)
+{
+ bSound* sound = NULL;
+
+ char name[25];
+ strcpy(name, "buf_");
+ strcpy(name + 4, source->id.name);
+
+ sound = alloc_libblock(&CTX_data_main(C)->sound, ID_SO, name);
+
+ sound->child_sound = source;
+ sound->type = SOUND_TYPE_BUFFER;
+
+ sound_load(sound);
+
+ if(!sound->snd_sound)
+ {
+ free_libblock(&CTX_data_main(C)->sound, sound);
+ sound = NULL;
+ }
+
+ return sound;
+}
+
+struct bSound* sound_new_limiter(struct bContext *C, struct bSound *source, float start, float end)
+{
+ bSound* sound = NULL;
+
+ char name[25];
+ strcpy(name, "lim_");
+ strcpy(name + 4, source->id.name);
+
+ sound = alloc_libblock(&CTX_data_main(C)->sound, ID_SO, name);
+
+ sound->child_sound = source;
+ sound->start = start;
+ sound->end = end;
+ sound->type = SOUND_TYPE_LIMITER;
+
+ sound_load(sound);
+
+ if(!sound->snd_sound)
+ {
+ free_libblock(&CTX_data_main(C)->sound, sound);
+ sound = NULL;
+ }
+
+ return sound;
+}
+#endif
+
+void sound_delete(struct bContext *C, struct bSound* sound)
+{
+ if(sound)
+ {
+ sound_free(sound);
+
+ sound_unlink(C, sound);
+
+ free_libblock(&CTX_data_main(C)->sound, sound);
}
- if (sound->stream) free(sound->stream);
}
-void sound_free_sample(bSample *sample)
+void sound_cache(struct bSound* sound, int ignore)
+{
+ if(sound->cache && !ignore)
+ AUD_unload(sound->cache);
+
+ sound->cache = AUD_bufferSound(sound->snd_sound);
+}
+
+void sound_load(struct bSound* sound)
{
- if (sample) {
- if (sample->data != &sample->fakedata[0] && sample->data != NULL) {
- MEM_freeN(sample->data);
- sample->data = &sample->fakedata[0];
+ if(sound)
+ {
+ if(sound->snd_sound)
+ {
+ AUD_unload(sound->snd_sound);
+ sound->snd_sound = NULL;
}
-
- if (sample->packedfile) {
- freePackedFile(sample->packedfile); //FIXME: crashes sometimes
- sample->packedfile = NULL;
+
+ switch(sound->type)
+ {
+ case SOUND_TYPE_FILE:
+ {
+ char fullpath[FILE_MAX];
+ char *path;
+
+ /* load sound */
+ PackedFile* pf = sound->packedfile;
+
+ /* dont modify soundact->sound->name, only change a copy */
+ BLI_strncpy(fullpath, sound->name, sizeof(fullpath));
+
+ if(sound->id.lib)
+ path = sound->id.lib->filename;
+ else
+ path = G.sce;
+
+ BLI_convertstringcode(fullpath, path);
+
+ /* but we need a packed file then */
+ if (pf)
+ sound->snd_sound = AUD_loadBuffer((unsigned char*) pf->data, pf->size);
+ /* or else load it from disk */
+ else
+ sound->snd_sound = AUD_load(fullpath);
+ break;
}
-
- if (sample->alindex != SAMPLE_INVALID) {
-// AUD_free_sample(sample->snd_sample);
- sample->alindex = SAMPLE_INVALID;
+ case SOUND_TYPE_BUFFER:
+ if(sound->child_sound && sound->child_sound->snd_sound)
+ sound->snd_sound = AUD_bufferSound(sound->child_sound->snd_sound);
+ break;
+ case SOUND_TYPE_LIMITER:
+ if(sound->child_sound && sound->child_sound->snd_sound)
+ sound->snd_sound = AUD_limitSound(sound->child_sound, sound->start, sound->end);
+ break;
}
- sample->type = SAMPLE_INVALID;
+ if(sound->cache)
+ {
+
+ }
}
}
-/* this is called after file reading or undos */
-void sound_free_all_samples(void)
+void sound_free(struct bSound* sound)
{
- bSample *sample;
- bSound *sound;
-
- /* ensure no sample pointers exist, and check packedfile */
- for(sound= G.main->sound.first; sound; sound= sound->id.next) {
- if(sound->sample && sound->sample->packedfile==sound->newpackedfile)
- sound->newpackedfile= NULL;
- sound->sample= NULL;
+ if (sound->packedfile)
+ {
+ freePackedFile(sound->packedfile);
+ sound->packedfile = NULL;
}
-
- /* now free samples */
- for(sample= samples->first; sample; sample= sample->id.next)
- sound_free_sample(sample);
- BLI_freelistN(samples);
-
-}
-
-void sound_set_packedfile(bSample *sample, PackedFile *pf)
-{
- bSound *sound;
-
- if (sample) {
- sample->packedfile = pf;
- sound = G.main->sound.first;
- while (sound) {
- if (sound->sample == sample) {
- sound->newpackedfile = pf;
- if (pf == NULL) {
- strcpy(sound->name, sample->name);
+
+ if(sound->snd_sound)
+ {
+ AUD_unload(sound->snd_sound);
+ sound->snd_sound = NULL;
+ }
+}
+
+void sound_unlink(struct bContext *C, struct bSound* sound)
+{
+ bSound *snd;
+ Scene *scene;
+ SoundHandle *handle;
+
+ for(snd = CTX_data_main(C)->sound.first; snd; snd = snd->id.next)
+ {
+ if(snd->child_sound == sound)
+ {
+ snd->child_sound = NULL;
+ if(snd->snd_sound)
+ {
+ AUD_unload(sound->snd_sound);
+ snd->snd_sound = NULL;
+ }
+
+ sound_unlink(C, snd);
+ }
+ }
+
+ for(scene = CTX_data_main(C)->scene.first; scene; scene = scene->id.next)
+ {
+ for(handle = scene->sound_handles.first; handle; handle = handle->next)
+ {
+ if(handle->source == sound)
+ {
+ handle->source = NULL;
+ if(handle->handle)
+ AUD_stop(handle->handle);
+ }
+ }
+ }
+}
+
+struct SoundHandle* sound_new_handle(struct Scene *scene, struct bSound* sound, int startframe, int endframe, int frameskip)
+{
+ ListBase* handles = &scene->sound_handles;
+
+ SoundHandle* handle = MEM_callocN(sizeof(SoundHandle), "sound_handle");
+ handle->source = sound;
+ handle->startframe = startframe;
+ handle->endframe = endframe;
+ handle->frameskip = frameskip;
+ handle->state = AUD_STATUS_INVALID;
+ handle->volume = 1.0f;
+
+ BLI_addtail(handles, handle);
+
+ return handle;
+}
+
+void sound_delete_handle(struct Scene *scene, struct SoundHandle *handle)
+{
+ if(handle == NULL)
+ return;
+
+ if(handle->handle)
+ AUD_stop(handle->handle);
+
+ BLI_freelinkN(&scene->sound_handles, handle);
+}
+
+void sound_stop_all(struct bContext *C)
+{
+ SoundHandle *handle;
+
+ for(handle = CTX_data_scene(C)->sound_handles.first; handle; handle = handle->next)
+ {
+ if(handle->state == AUD_STATUS_PLAYING)
+ {
+ AUD_pause(handle->handle);
+ handle->state = AUD_STATUS_PAUSED;
+ }
+ }
+}
+
+#define SOUND_PLAYBACK_LAMBDA 1.0
+
+void sound_update_playing(struct bContext *C)
+{
+ SoundHandle *handle;
+ Scene* scene = CTX_data_scene(C);
+ int cfra = CFRA;
+ float fps = FPS;
+ int action;
+
+ AUD_lock();
+
+ for(handle = scene->sound_handles.first; handle; handle = handle->next)
+ {
+ if(cfra < handle->startframe || cfra >= handle->endframe || handle->mute)
+ {
+ if(handle->state == AUD_STATUS_PLAYING)
+ {
+ AUD_pause(handle->handle);
+ handle->state = AUD_STATUS_PAUSED;
+ }
+ }
+ else
+ {
+ action = 0;
+
+ if(handle->changed != handle->source->changed)
+ {
+ handle->changed = handle->source->changed;
+ action = 3;
+ if(handle->state != AUD_STATUS_INVALID)
+ {
+ AUD_stop(handle->handle);
+ handle->state = AUD_STATUS_INVALID;
+ }
+ }
+ else
+ {
+ if(handle->state != AUD_STATUS_PLAYING)
+ action = 3;
+ else
+ {
+ handle->state = AUD_getStatus(handle->handle);
+ if(handle->state != AUD_STATUS_PLAYING)
+ action = 3;
+ else
+ {
+ float diff = AUD_getPosition(handle->handle) - (cfra - handle->startframe) / fps;
+// AUD_XXX float diff = AUD_getPosition(handle->handle) * fps - cfra + handle->startframe
+ if(diff < 0.0)
+ diff = -diff;
+ if(diff > SOUND_PLAYBACK_LAMBDA)
+// AUD_XXX if(diff > 5.0f)
+ {
+ action = 2;
+ }
+ }
+ }
+ }
+
+ if(action & 1)
+ {
+ if(handle->state == AUD_STATUS_INVALID)
+ {
+ if(handle->source && handle->source->snd_sound)
+ {
+ AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->snd_sound, handle->frameskip / fps, (handle->frameskip + handle->endframe - handle->startframe)/fps);
+ handle->handle = AUD_play(limiter, 1);
+ AUD_unload(limiter);
+ if(handle->handle)
+ handle->state = AUD_STATUS_PLAYING;
+ if(cfra == handle->startframe)
+ action &= ~2;
+ }
}
+ else
+ if(AUD_resume(handle->handle))
+ handle->state = AUD_STATUS_PLAYING;
+ else
+ handle->state = AUD_STATUS_INVALID;
}
- sound = sound->id.next;
+
+ if(action & 2)
+ AUD_seek(handle->handle, (cfra - handle->startframe) / fps);
}
}
+
+ AUD_unlock();
}
-PackedFile* sound_find_packedfile(bSound *sound)
-{
- bSound *search;
- PackedFile *pf = NULL;
- char soundname[FILE_MAXDIR + FILE_MAXFILE], searchname[FILE_MAXDIR + FILE_MAXFILE];
-
- // convert sound->name to abolute filename
- strcpy(soundname, sound->name);
- BLI_convertstringcode(soundname, G.sce);
-
- search = G.main->sound.first;
- while (search) {
- if (search->sample && search->sample->packedfile) {
- strcpy(searchname, search->sample->name);
- BLI_convertstringcode(searchname, G.sce);
-
- if (BLI_streq(searchname, soundname)) {
- pf = search->sample->packedfile;
- break;
+void sound_scrub(struct bContext *C)
+{
+ SoundHandle *handle;
+ Scene* scene = CTX_data_scene(C);
+ int cfra = CFRA;
+ float fps = FPS;
+
+ if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer)
+ {
+ AUD_lock();
+
+ for(handle = scene->sound_handles.first; handle; handle = handle->next)
+ {
+ if(cfra >= handle->startframe && cfra < handle->endframe && !handle->mute)
+ {
+ if(handle->source && handle->source->snd_sound)
+ {
+ int frameskip = handle->frameskip + cfra - handle->startframe;
+ AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->snd_sound, frameskip / fps, (frameskip + 1)/fps);
+ AUD_play(limiter, 0);
+ AUD_unload(limiter);
+ }
}
- }
-
- if (search->newpackedfile) {
- strcpy(searchname, search->name);
- BLI_convertstringcode(searchname, G.sce);
- if (BLI_streq(searchname, soundname)) {
- pf = search->newpackedfile;
- break;
+ }
+
+ AUD_unlock();
+ }
+}
+
+AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end)
+{
+ AUD_Device* mixdown = AUD_openReadDevice(specs);
+ SoundHandle *handle;
+ float fps = FPS;
+ AUD_Sound *limiter, *delayer;
+ int frameskip, s, e;
+
+ end++;
+
+ for(handle = scene->sound_handles.first; handle; handle = handle->next)
+ {
+ if(start < handle->endframe && end > handle->startframe && !handle->mute && handle->source && handle->source->snd_sound)
+ {
+ frameskip = handle->frameskip;
+ s = handle->startframe - start;
+ e = handle->frameskip + AUD_MIN(handle->endframe, end) - handle->startframe;
+
+ if(s < 0)
+ {
+ frameskip -= s;
+ s = 0;
}
+
+ limiter = AUD_limitSound(handle->source->snd_sound, frameskip / fps, e / fps);
+ delayer = AUD_delaySound(limiter, s / fps);
+
+ AUD_playDevice(mixdown, delayer);
+
+ AUD_unload(delayer);
+ AUD_unload(limiter);
}
- search = search->id.next;
}
-
- return (pf);
+
+ return mixdown;
}
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index cfbe3f629d6..7c58a4f9499 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -127,7 +127,7 @@ void makeavistring (RenderData *rd, char *string)
}
}
-void start_avi(RenderData *rd, int rectx, int recty)
+void start_avi(struct Scene *scene, RenderData *rd, int rectx, int recty)
{
int x, y;
char name[256];
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 5e3c8024524..e7164dc4794 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -65,6 +65,10 @@
#include "DNA_scene_types.h"
+#include "AUD_C-API.h"
+#include "BKE_sound.h"
+#include "BKE_main.h"
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -96,6 +100,8 @@ static int audio_input_frame_size = 0;
static uint8_t* audio_output_buffer = 0;
static int audio_outbuf_size = 0;
+static AUD_Device* audio_mixdown_device = 0;
+
#define FFMPEG_AUTOSPLIT_SIZE 2000000000
/* Delete a picture buffer */
@@ -127,9 +133,8 @@ static int write_audio_frame(void)
c = get_codec_from_stream(audio_stream);
- //XXX audiostream_fill(audio_input_buffer,
- // audio_input_frame_size
- // * sizeof(short) * c->channels);
+ if(audio_mixdown_device)
+ AUD_readDevice(audio_mixdown_device, audio_input_buffer, audio_input_frame_size);
av_init_packet(&pkt);
@@ -827,11 +832,21 @@ static void makeffmpegstring(RenderData* rd, char* string) {
}
-void start_ffmpeg(RenderData *rd, int rectx, int recty)
+void start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty)
{
ffmpeg_autosplit_count = 0;
start_ffmpeg_impl(rd, rectx, recty);
+
+ if(ffmpeg_multiplex_audio && audio_stream)
+ {
+ AVCodecContext* c = get_codec_from_stream(audio_stream);
+ AUD_Specs specs;
+ specs.channels = c->channels;
+ specs.format = AUD_FORMAT_S16;
+ specs.rate = rd->audio.mixrate;
+ audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->efra);
+ }
}
void end_ffmpeg(void);
@@ -884,6 +899,12 @@ void end_ffmpeg(void)
if (audio_stream && video_stream) {
write_audio_frames();
}
+
+ if(audio_mixdown_device)
+ {
+ AUD_closeReadDevice(audio_mixdown_device);
+ audio_mixdown_device = 0;
+ }
if (outfile) {
av_write_trailer(outfile);
diff --git a/source/blender/blenkernel/intern/writeframeserver.c b/source/blender/blenkernel/intern/writeframeserver.c
index 2d3a2e6b883..0780cd0dc48 100644
--- a/source/blender/blenkernel/intern/writeframeserver.c
+++ b/source/blender/blenkernel/intern/writeframeserver.c
@@ -101,7 +101,7 @@ static int closesocket(int fd)
}
#endif
-void start_frameserver(RenderData *rd, int rectx, int recty)
+void start_frameserver(struct Scene *scene, RenderData *rd, int rectx, int recty)
{
struct sockaddr_in addr;
int arg = 1;