From 9827a3e9eac70f68db6dc16d03016c51b7ece3f0 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sun, 7 Feb 2010 23:41:17 +0000 Subject: 2.5 Audio: - recode of the whole sequencer audio handling - encode audio flag removed, instead you choose None as audio codec, added None for video codec too - ffmpeg formats/codecs: enabled: theora, ogg, vorbis; added: matroska, flac (not working, who can fix?), mp3, wav - sequencer wave drawing - volume animation (now also working when mixing down to a file!) - made sequencer strip position and length values unanimatable --- source/blender/blenkernel/BKE_sequencer.h | 8 +- source/blender/blenkernel/BKE_sound.h | 27 +- source/blender/blenkernel/BKE_writeffmpeg.h | 2 + source/blender/blenkernel/intern/scene.c | 7 + source/blender/blenkernel/intern/sequencer.c | 90 +++---- source/blender/blenkernel/intern/sound.c | 293 ++++++--------------- source/blender/blenkernel/intern/writeffmpeg.c | 170 ++++++------ source/blender/blenloader/intern/readfile.c | 18 +- source/blender/editors/animation/anim_ops.c | 2 +- source/blender/editors/screen/screen_ops.c | 14 +- source/blender/editors/sound/sound_ops.c | 4 +- source/blender/editors/space_graph/graph_ops.c | 2 +- .../editors/space_sequencer/sequencer_add.c | 8 +- .../editors/space_sequencer/sequencer_draw.c | 38 ++- .../editors/space_sequencer/sequencer_edit.c | 74 +++--- .../editors/transform/transform_conversions.c | 14 +- source/blender/makesdna/DNA_scene_types.h | 5 +- source/blender/makesdna/DNA_sequence_types.h | 4 +- source/blender/makesdna/DNA_sound_types.h | 25 +- source/blender/makesrna/intern/rna_scene.c | 33 +-- source/blender/makesrna/intern/rna_sequencer.c | 24 +- 21 files changed, 388 insertions(+), 474 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 0c84d729d47..49afe201c92 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -150,8 +150,8 @@ struct ImBuf *give_ibuf_seq(struct Scene *scene, int rectx, int recty, int cfra, struct ImBuf *give_ibuf_seq_threaded(struct Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size); struct ImBuf *give_ibuf_seq_direct(struct Scene *scene, int rectx, int recty, int cfra, int render_size, struct Sequence *seq); void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown, int render_size); -void calc_sequence(struct Sequence *seq); -void calc_sequence_disp(struct Sequence *seq); +void calc_sequence(struct Scene *scene, struct Sequence *seq); +void calc_sequence_disp(struct Scene *scene, struct Sequence *seq); void new_tstripdata(struct Sequence *seq); void reload_sequence_new_file(struct Scene *scene, struct Sequence * seq); void sort_seq(struct Scene *scene); @@ -191,8 +191,8 @@ int shuffle_seq_time(ListBase * seqbasep, struct Scene *evil_scene); int seqbase_isolated_sel_check(struct ListBase *seqbase); void free_imbuf_seq(struct Scene *scene, struct ListBase * seqbasep, int check_mem_usage); -void seq_update_sound(struct Sequence *seq); -void seq_update_muting(struct Editing *ed); +void seq_update_sound(struct Scene* scene, struct Sequence *seq); +void seq_update_muting(struct Scene* scene, struct Editing *ed); void seqbase_sound_reload(Scene *scene, ListBase *seqbase); void clear_scene_in_allseqs(struct Scene *sce); diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h index 82ef525ba91..1c9a7db03c3 100644 --- a/source/blender/blenkernel/BKE_sound.h +++ b/source/blender/blenkernel/BKE_sound.h @@ -36,6 +36,7 @@ struct bSound; struct bContext; struct ListBase; struct Main; +struct Sequence; void sound_init(); @@ -63,20 +64,28 @@ void sound_load(struct Main *main, struct bSound* sound); void sound_free(struct bSound* sound); -void sound_unlink(struct bContext *C, struct bSound* sound); +#ifdef AUD_CAPI +AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume); +#endif -struct SoundHandle* sound_new_handle(struct Scene *scene, struct bSound* sound, int startframe, int endframe, int frameskip); +void sound_create_scene(struct Scene *scene); -void sound_delete_handle(struct Scene *scene, struct SoundHandle *handle); +void sound_destroy_scene(struct Scene *scene); -void sound_update_playing(struct bContext *C); +void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip); -void sound_scrub(struct bContext *C); +void sound_remove_scene_sound(struct Scene *scene, void* handle); -#ifdef AUD_CAPI -AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, int end, float volume); -#endif +void sound_mute_scene_sound(struct Scene *scene, void* handle, char mute); + +void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, int endframe, int frameskip); + +void sound_play_scene(struct Scene *scene); + +void sound_stop_scene(struct Scene *scene); + +void sound_seek_scene(struct bContext *C); -void sound_stop_all(struct bContext *C); +int sound_read_sound_buffer(struct bSound* sound, float* buffer, int length); #endif diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h index 98c385ea2e1..20c5b2fd46f 100644 --- a/source/blender/blenkernel/BKE_writeffmpeg.h +++ b/source/blender/blenkernel/BKE_writeffmpeg.h @@ -45,6 +45,8 @@ extern "C" { #define FFMPEG_FLV 8 #define FFMPEG_MKV 9 #define FFMPEG_OGG 10 +#define FFMPEG_WAV 11 +#define FFMPEG_MP3 12 #define FFMPEG_PRESET_NONE 0 #define FFMPEG_PRESET_DVD 1 diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index b80f22a05c2..780ded2a941 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -83,6 +83,7 @@ #include "BKE_sequencer.h" #include "BKE_world.h" #include "BKE_utildefines.h" +#include "BKE_sound.h" //XXX #include "BIF_previewrender.h" //XXX #include "BIF_editseq.h" @@ -233,6 +234,8 @@ Scene *copy_scene(Main *bmain, Scene *sce, int type) } } + sound_create_scene(scen); + return scen; } @@ -315,6 +318,8 @@ void free_scene(Scene *sce) if(sce->stats) MEM_freeN(sce->stats); + + sound_destroy_scene(sce); } Scene *add_scene(char *name) @@ -480,6 +485,8 @@ Scene *add_scene(char *name) sce->gm.flag = GAME_DISPLAY_LISTS; sce->gm.matmode = GAME_MAT_MULTITEX; + sound_create_scene(sce); + return sce; } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 9fde0730011..8c119eb753b 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -233,8 +233,8 @@ void seq_free_sequence(Scene *scene, Sequence *seq) if (ed->act_seq==seq) ed->act_seq= NULL; - if(seq->sound_handle) - sound_delete_handle(scene, seq->sound_handle); + if(seq->scene_sound) + sound_remove_scene_sound(scene, seq->scene_sound); } MEM_freeN(seq); @@ -484,7 +484,7 @@ void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq, } -void calc_sequence_disp(Sequence *seq) +void calc_sequence_disp(Scene *scene, Sequence *seq) { if(seq->startofs && seq->startstill) seq->startstill= 0; if(seq->endofs && seq->endstill) seq->endstill= 0; @@ -500,10 +500,10 @@ void calc_sequence_disp(Sequence *seq) seq->handsize= (float)((seq->enddisp-seq->startdisp)/25); } - seq_update_sound(seq); + seq_update_sound(scene, seq); } -void calc_sequence(Sequence *seq) +void calc_sequence(Scene *scene, Sequence *seq) { Sequence *seqm; int min, max; @@ -511,7 +511,7 @@ void calc_sequence(Sequence *seq) /* check all metas recursively */ seqm= seq->seqbase.first; while(seqm) { - if(seqm->seqbase.first) calc_sequence(seqm); + if(seqm->seqbase.first) calc_sequence(scene, seqm); seqm= seqm->next; } @@ -534,7 +534,7 @@ void calc_sequence(Sequence *seq) seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp); seq->len= seq->enddisp - seq->startdisp; } else { - calc_sequence_disp(seq); + calc_sequence_disp(scene, seq); } if(seq->strip && seq->len!=seq->strip->len) { @@ -563,7 +563,7 @@ void calc_sequence(Sequence *seq) } } } - calc_sequence_disp(seq); + calc_sequence_disp(scene, seq); } } @@ -614,7 +614,7 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq) } seq->strip->len = seq->len; } else if (seq->type == SEQ_SOUND) { - seq->len = AUD_getInfo(seq->sound->handle).length * FPS; + seq->len = AUD_getInfo(seq->sound->playback_handle).length * FPS; seq->len -= seq->anim_startofs; seq->len -= seq->anim_endofs; if (seq->len < 0) { @@ -653,7 +653,7 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq) free_proxy_seq(seq); - calc_sequence(seq); + calc_sequence(scene, seq); } void sort_seq(Scene *scene) @@ -3189,7 +3189,7 @@ static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *chan } if(len_change) - calc_sequence(seq); + calc_sequence(scene, seq); } return free_imbuf; @@ -3239,23 +3239,6 @@ static void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo) } #endif -static int seq_sound_reload_cb(Sequence *seq, void *arg_pt) -{ - if (seq->type==SEQ_SOUND && seq->sound) { - Scene *scene= (Scene *)arg_pt; - if(seq->sound_handle) - sound_delete_handle(scene, seq->sound_handle); - - seq->sound_handle = sound_new_handle(scene, seq->sound, seq->start, seq->start + seq->strip->len, 0); - return 0; - } - return 1; /* recurse meta's */ -} -void seqbase_sound_reload(Scene *scene, ListBase *seqbase) -{ - seqbase_recursive_apply(seqbase, seq_sound_reload_cb, (void *)scene); -} - /* seq funcs's for transforming internally notice the difference between start/end and left/right. @@ -3463,7 +3446,7 @@ static void seq_translate(Scene *evil_scene, Sequence *seq, int delta) } } - calc_sequence_disp(seq); + calc_sequence_disp(evil_scene, seq); } /* return 0 if there werent enough space */ @@ -3471,13 +3454,13 @@ int shuffle_seq(ListBase * seqbasep, Sequence *test, Scene *evil_scene) { int orig_machine= test->machine; test->machine++; - calc_sequence(test); + calc_sequence(evil_scene, test); while( seq_test_overlap(seqbasep, test) ) { if(test->machine >= MAXSEQ) { break; } test->machine++; - calc_sequence(test); // XXX - I dont think this is needed since were only moving vertically, Campbell. + calc_sequence(evil_scene, test); // XXX - I dont think this is needed since were only moving vertically, Campbell. } @@ -3497,7 +3480,7 @@ int shuffle_seq(ListBase * seqbasep, Sequence *test, Scene *evil_scene) new_frame = new_frame + (test->start-test->startdisp); /* adjust by the startdisp */ seq_translate(evil_scene, test, new_frame - test->start); - calc_sequence(test); + calc_sequence(evil_scene, test); return 0; } else { return 1; @@ -3526,7 +3509,7 @@ static int shuffle_seq_time_offset_test(ListBase * seqbasep, char dir) return offset; } -static int shuffle_seq_time_offset(ListBase * seqbasep, char dir) +static int shuffle_seq_time_offset(Scene* scene, ListBase * seqbasep, char dir) { int ofs= 0; int tot_ofs= 0; @@ -3545,7 +3528,7 @@ static int shuffle_seq_time_offset(ListBase * seqbasep, char dir) for(seq= seqbasep->first; seq; seq= seq->next) { if(seq->tmp) - calc_sequence_disp(seq); /* corrects dummy startdisp/enddisp values */ + calc_sequence_disp(scene, seq); /* corrects dummy startdisp/enddisp values */ } return tot_ofs; @@ -3557,8 +3540,8 @@ int shuffle_seq_time(ListBase * seqbasep, Scene *evil_scene) Sequence *seq; - int offset_l = shuffle_seq_time_offset(seqbasep, 'L'); - int offset_r = shuffle_seq_time_offset(seqbasep, 'R'); + int offset_l = shuffle_seq_time_offset(evil_scene, seqbasep, 'L'); + int offset_r = shuffle_seq_time_offset(evil_scene, seqbasep, 'R'); int offset = (-offset_l < offset_r) ? offset_l:offset_r; if(offset) { @@ -3573,19 +3556,16 @@ int shuffle_seq_time(ListBase * seqbasep, Scene *evil_scene) return offset? 0:1; } -void seq_update_sound(Sequence *seq) +void seq_update_sound(Scene* scene, Sequence *seq) { - if(seq->type == SEQ_SOUND && seq->sound_handle) + if(seq->scene_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->changed = -1; + sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); /* mute is set in seq_update_muting_recursive */ } } -static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute) +static void seq_update_muting_recursive(Scene *scene, ListBase *seqbasep, Sequence *metaseq, int mute) { Sequence *seq; int seqmute; @@ -3601,27 +3581,26 @@ static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, i if(seq == metaseq) seqmute= 0; - seq_update_muting_recursive(&seq->seqbase, metaseq, seqmute); + seq_update_muting_recursive(scene, &seq->seqbase, metaseq, seqmute); } else if(seq->type == SEQ_SOUND) { - if(seq->sound_handle && seqmute != seq->sound_handle->mute) { - seq->sound_handle->mute = seqmute; - seq->sound_handle->changed = -1; + if(seq->scene_sound) { + sound_mute_scene_sound(scene, seq->scene_sound, seqmute); } } } } -void seq_update_muting(Editing *ed) +void seq_update_muting(Scene *scene, Editing *ed) { if(ed) { /* mute all sounds up to current metastack list */ MetaStack *ms= ed->metastack.last; if(ms) - seq_update_muting_recursive(&ed->seqbase, ms->parseq, 1); + seq_update_muting_recursive(scene, &ed->seqbase, ms->parseq, 1); else - seq_update_muting_recursive(&ed->seqbase, NULL, 0); + seq_update_muting_recursive(scene, &ed->seqbase, NULL, 0); } } @@ -3744,6 +3723,7 @@ Sequence *alloc_sequence(ListBase *lb, int cfra, int machine) seq->machine= machine; seq->mul= 1.0; seq->blend_opacity = 100.0; + seq->volume = 1.0f; return seq; } @@ -3793,13 +3773,13 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo sound = sound_new_file(CTX_data_main(C), seq_load->path); - if (sound==NULL || sound->handle == NULL) { + if (sound==NULL || sound->playback_handle == NULL) { //if(op) // BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); return NULL; } - info = AUD_getInfo(sound->handle); + info = AUD_getInfo(sound->playback_handle); if (info.specs.channels == AUD_CHANNELS_INVALID) { sound_delete(C, sound); @@ -3824,9 +3804,9 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo BLI_split_dirfile_basic(seq_load->path, strip->dir, se->name); - seq->sound_handle = sound_new_handle(scene, sound, seq_load->start_frame, seq_load->start_frame + strip->len, 0); + seq->scene_sound = sound_add_scene_sound(scene, seq, seq_load->start_frame, seq_load->start_frame + strip->len, 0); - calc_sequence_disp(seq); + calc_sequence_disp(scene, seq); /* last active name */ strncpy(ed->act_sounddir, strip->dir, FILE_MAXDIR-1); @@ -3868,7 +3848,7 @@ Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo BLI_split_dirfile_basic(seq_load->path, strip->dir, se->name); - calc_sequence_disp(seq); + calc_sequence_disp(scene, seq); if(seq_load->flag & SEQ_LOAD_MOVIE_SOUND) { diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 1be59529cc7..7b451bd5a98 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -12,6 +12,7 @@ #include "BLI_blenlib.h" #include "DNA_scene_types.h" +#include "DNA_sequence_types.h" #include "DNA_sound_types.h" #include "DNA_packedFile_types.h" #include "DNA_screen_types.h" @@ -26,6 +27,9 @@ #include "BKE_context.h" #include "BKE_library.h" #include "BKE_packedFile.h" +#include "BKE_fcurve.h" + +#include "RNA_access.h" #ifdef HAVE_CONFIG_H #include @@ -107,7 +111,7 @@ struct bSound* sound_new_file(struct Main *main, char* filename) sound_load(main, sound); - if(!sound->handle) + if(!sound->playback_handle) { free_libblock(&main->sound, sound); sound = NULL; @@ -133,7 +137,7 @@ struct bSound* sound_new_buffer(struct bContext *C, struct bSound *source) sound_load(CTX_data_main(C), sound); - if(!sound->handle) + if(!sound->playback_handle) { free_libblock(&CTX_data_main(C)->sound, sound); sound = NULL; @@ -159,7 +163,7 @@ struct bSound* sound_new_limiter(struct bContext *C, struct bSound *source, floa sound_load(CTX_data_main(C), sound); - if(!sound->handle) + if(!sound->playback_handle) { free_libblock(&CTX_data_main(C)->sound, sound); sound = NULL; @@ -175,8 +179,6 @@ void sound_delete(struct bContext *C, struct bSound* sound) { sound_free(sound); - sound_unlink(C, sound); - free_libblock(&CTX_data_main(C)->sound, sound); } } @@ -187,7 +189,7 @@ void sound_cache(struct bSound* sound, int ignore) AUD_unload(sound->cache); sound->cache = AUD_bufferSound(sound->handle); - sound->changed++; + sound->playback_handle = sound->cache; } void sound_delete_cache(struct bSound* sound) @@ -196,6 +198,7 @@ void sound_delete_cache(struct bSound* sound) { AUD_unload(sound->cache); sound->cache = NULL; + sound->playback_handle = sound->handle; } } @@ -207,6 +210,7 @@ void sound_load(struct Main *main, struct bSound* sound) { AUD_unload(sound->handle); sound->handle = NULL; + sound->playback_handle = NULL; } // XXX unused currently @@ -253,7 +257,10 @@ void sound_load(struct Main *main, struct bSound* sound) break; } #endif - sound->changed++; + if(sound->cache) + sound->playback_handle = sound->cache; + else + sound->playback_handle = sound->handle; } } @@ -269,243 +276,115 @@ void sound_free(struct bSound* sound) { AUD_unload(sound->handle); sound->handle = NULL; + sound->playback_handle = NULL; } } -void sound_unlink(struct bContext *C, struct bSound* sound) +static float sound_get_volume(Scene* scene, Sequence* sequence, float time) { - Scene *scene; - SoundHandle *handle; - -// XXX unused currently -#if 0 - bSound *snd; - for(snd = CTX_data_main(C)->sound.first; snd; snd = snd->id.next) - { - if(snd->child_sound == sound) - { - snd->child_sound = NULL; - if(snd->handle) - { - AUD_unload(sound->handle); - snd->handle = NULL; - } - - sound_unlink(C, snd); - } - } -#endif - - 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 FCurve* fcu = id_data_find_fcurve(scene, sequence, &RNA_Sequence, "volume", 0); + if(fcu) + return evaluate_fcurve(fcu, time * FPS); + else + return sequence->volume; } -struct SoundHandle* sound_new_handle(struct Scene *scene, struct bSound* sound, int startframe, int endframe, int frameskip) +AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume) { - ListBase* handles = &scene->sound_handles; + AUD_Device* mixdown = AUD_openReadDevice(specs); + + AUD_setDeviceVolume(mixdown, volume); - 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; + AUD_playDevice(mixdown, scene->sound_scene, start / FPS); - BLI_addtail(handles, handle); + return mixdown; +} - return handle; +void sound_create_scene(struct Scene *scene) +{ + scene->sound_scene = AUD_createSequencer(scene, (AUD_volumeFunction)&sound_get_volume); } -void sound_delete_handle(struct Scene *scene, struct SoundHandle *handle) +void sound_destroy_scene(struct Scene *scene) { - if(handle == NULL) - return; + if(scene->sound_scene_handle) + AUD_stop(scene->sound_scene_handle); + if(scene->sound_scene) + AUD_destroySequencer(scene->sound_scene); +} - if(handle->handle) - AUD_stop(handle->handle); +void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip) +{ + return AUD_addSequencer(scene->sound_scene, &(sequence->sound->playback_handle), startframe / FPS, endframe / FPS, frameskip / FPS, sequence); +} - BLI_freelinkN(&scene->sound_handles, handle); +void sound_remove_scene_sound(struct Scene *scene, void* handle) +{ + AUD_removeSequencer(scene->sound_scene, handle); } -void sound_stop_all(struct bContext *C) +void sound_mute_scene_sound(struct Scene *scene, void* handle, char mute) { - SoundHandle *handle; + AUD_muteSequencer(scene->sound_scene, handle, mute); +} - 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; - } - } +void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, int endframe, int frameskip) +{ + AUD_moveSequencer(scene->sound_scene, handle, startframe / FPS, endframe / FPS, frameskip / FPS); } -void sound_update_playing(struct bContext *C) +void sound_start_play_scene(struct Scene *scene) { - SoundHandle *handle; - Scene* scene = CTX_data_scene(C); - int cfra = CFRA; - float fps = FPS; - int action; + AUD_Sound* sound; + sound = AUD_loopSound(scene->sound_scene); + scene->sound_scene_handle = AUD_play(sound, 1); + AUD_unload(sound); +} +void sound_play_scene(struct Scene *scene) +{ AUD_lock(); - for(handle = scene->sound_handles.first; handle; handle = handle->next) - { - if(cfra < handle->startframe || cfra >= handle->endframe || handle->mute || (scene->audio.flag & AUDIO_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) * fps - cfra + handle->startframe; - if(diff < 0.0) - diff = -diff; - if(diff > FPS/2.0) - { - action = 2; - } - } - } - } - - AUD_setSoundVolume(handle->handle, handle->volume); - - if(action & 1) - { - if(handle->state == AUD_STATUS_INVALID) - { - if(handle->source && handle->source->handle) - { - AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->handle, 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; - } - - if(action & 2) - AUD_seek(handle->handle, (cfra - handle->startframe) / fps); - } - } + if(!scene->sound_scene_handle || AUD_getStatus(scene->sound_scene_handle) == AUD_STATUS_INVALID) + sound_start_play_scene(scene); + + AUD_seek(scene->sound_scene_handle, CFRA / FPS); + AUD_setLoop(scene->sound_scene_handle, -1, -1); + AUD_resume(scene->sound_scene_handle); AUD_unlock(); } -void sound_scrub(struct bContext *C) +void sound_stop_scene(struct Scene *scene) { - 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->handle) - { - int frameskip = handle->frameskip + cfra - handle->startframe; - AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->handle, frameskip / fps, (frameskip + 1)/fps); - AUD_play(limiter, 0); - AUD_unload(limiter); - } - } - } - - AUD_unlock(); - } + AUD_pause(scene->sound_scene_handle); } -AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, int end, float volume) +void sound_seek_scene(struct bContext *C) { - AUD_Device* mixdown = AUD_openReadDevice(specs); - SoundHandle *handle; - float fps = FPS; - AUD_Sound *limiter, *delayer; - int frameskip, s, e; + struct Scene *scene = CTX_data_scene(C); - end++; + AUD_lock(); - AUD_setDeviceVolume(mixdown, volume); + if(!scene->sound_scene_handle || AUD_getStatus(scene->sound_scene_handle) == AUD_STATUS_INVALID) + { + sound_start_play_scene(scene); + AUD_pause(scene->sound_scene_handle); + } - for(handle = scene->sound_handles.first; handle; handle = handle->next) + if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer) { - if(start < handle->endframe && end > handle->startframe && !handle->mute && handle->source && handle->source->handle) - { - frameskip = handle->frameskip; - s = handle->startframe - start; - e = handle->frameskip + AUD_MIN(handle->endframe, end) - handle->startframe; - - if(s < 0) - { - frameskip -= s; - s = 0; - } - - AUD_setSoundVolume(handle->handle, handle->volume); - - limiter = AUD_limitSound(handle->source->handle, frameskip / fps, e / fps); - delayer = AUD_delaySound(limiter, s / fps); - - AUD_playDevice(mixdown, delayer); - - AUD_unload(delayer); - AUD_unload(limiter); - } + AUD_setLoop(scene->sound_scene_handle, -1, 1 / FPS); + AUD_seek(scene->sound_scene_handle, CFRA / FPS); + AUD_resume(scene->sound_scene_handle); } + else + AUD_seek(scene->sound_scene_handle, CFRA / FPS); - return mixdown; + AUD_unlock(); +} + +int sound_read_sound_buffer(bSound* sound, float* buffer, int length) +{ + AUD_readSound(sound->cache, buffer, length); } diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 9c38f84aa26..3aca9ffb4e7 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -15,7 +15,6 @@ * */ - #ifdef WITH_FFMPEG #include #include @@ -78,11 +77,10 @@ extern void do_init_ffmpeg(); static int ffmpeg_type = 0; static int ffmpeg_codec = CODEC_ID_MPEG4; -static int ffmpeg_audio_codec = CODEC_ID_MP2; +static int ffmpeg_audio_codec = CODEC_ID_NONE; static int ffmpeg_video_bitrate = 1150; static int ffmpeg_audio_bitrate = 128; static int ffmpeg_gop_size = 12; -static int ffmpeg_multiplex_audio = 1; static int ffmpeg_autosplit = 0; static int ffmpeg_autosplit_count = 0; @@ -99,6 +97,7 @@ static uint8_t* audio_input_buffer = 0; static int audio_input_frame_size = 0; static uint8_t* audio_output_buffer = 0; static int audio_outbuf_size = 0; +static double audio_time = 0.0f; static AUD_Device* audio_mixdown_device = 0; @@ -130,30 +129,43 @@ static int write_audio_frame(void) { AVCodecContext* c = NULL; AVPacket pkt; + AVStream* str = audio_stream; c = get_codec_from_stream(audio_stream); - if(audio_mixdown_device) - AUD_readDevice(audio_mixdown_device, audio_input_buffer, audio_input_frame_size); - av_init_packet(&pkt); + pkt.size = 0; + + AUD_readDevice(audio_mixdown_device, audio_input_buffer, audio_input_frame_size); + audio_time += (double) audio_input_frame_size / (double) c->sample_rate; pkt.size = avcodec_encode_audio(c, audio_output_buffer, - audio_outbuf_size, + audio_outbuf_size, (short*) audio_input_buffer); + + if(pkt.size <= 0) + { + // XXX error("Error writing audio packet"); + return -1; + } + pkt.data = audio_output_buffer; + + if(c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE) + { #ifdef FFMPEG_CODEC_TIME_BASE - pkt.pts = av_rescale_q(c->coded_frame->pts, - c->time_base, audio_stream->time_base); + pkt.pts = av_rescale_q(c->coded_frame->pts, + c->time_base, audio_stream->time_base); #else - pkt.pts = c->coded_frame->pts; + pkt.pts = c->coded_frame->pts; #endif - fprintf(stderr, "Audio Frame PTS: %d\n", (int)pkt.pts); + fprintf(stderr, "Audio Frame PTS: %d\n", (int)pkt.pts); + } pkt.stream_index = audio_stream->index; pkt.flags |= PKT_FLAG_KEY; if (av_interleaved_write_frame(outfile, &pkt) != 0) { - //XXX error("Error writing audio packet"); + // XXX error("Error writing audio packet"); return -1; } return 0; @@ -233,6 +245,14 @@ static const char** get_file_extensions(int format) static const char * rv[] = { ".ogg", ".ogv", NULL }; return rv; } + case FFMPEG_MP3: { + static const char * rv[] = { ".mp3", NULL }; + return rv; + } + case FFMPEG_WAV: { + static const char * rv[] = { ".wav", NULL }; + return rv; + } default: return NULL; } @@ -563,6 +583,7 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex c->sample_rate = rd->ffcodecdata.audio_mixrate; c->bit_rate = ffmpeg_audio_bitrate*1000; + c->sample_fmt = SAMPLE_FMT_S16; c->channels = 2; codec = avcodec_find_encoder(c->codec_id); if (!codec) { @@ -577,40 +598,22 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex return NULL; } - /* FIXME: Should be user configurable */ - if (ffmpeg_type == FFMPEG_DV) { - /* this is a hack around the poor ffmpeg dv multiplexer. */ - /* only fixes PAL for now - (NTSC is a lot more complicated here...)! */ - audio_outbuf_size = 7680; - } else { - audio_outbuf_size = 10000; - } + audio_outbuf_size = FF_MIN_BUFFER_SIZE; + audio_output_buffer = (uint8_t*)MEM_mallocN( audio_outbuf_size, "FFMPEG audio encoder input buffer"); - /* ugly hack for PCM codecs */ - - if (c->frame_size <= 1) { - audio_input_frame_size = audio_outbuf_size / c->channels; - switch(c->codec_id) { - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_U16LE: - case CODEC_ID_PCM_U16BE: - audio_input_frame_size >>= 1; - break; - default: - break; - } - } else { + if((c->codec_id >= CODEC_ID_PCM_S16LE) && (c->codec_id <= CODEC_ID_PCM_DVD)) + audio_input_frame_size = audio_outbuf_size * 8 / c->bits_per_coded_sample / c->channels; + else audio_input_frame_size = c->frame_size; - } audio_input_buffer = (uint8_t*)MEM_mallocN( - audio_input_frame_size * sizeof(short) * c->channels, + audio_input_frame_size * c->channels * sizeof(int16_t), "FFMPEG audio encoder output buffer"); + audio_time = 0.0f; + return st; } /* essential functions -- start, append, end */ @@ -629,8 +632,6 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report ffmpeg_video_bitrate = rd->ffcodecdata.video_bitrate; ffmpeg_audio_bitrate = rd->ffcodecdata.audio_bitrate; ffmpeg_gop_size = rd->ffcodecdata.gop_size; - ffmpeg_multiplex_audio = rd->ffcodecdata.flags - & FFMPEG_MULTIPLEX_AUDIO; ffmpeg_autosplit = rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT; @@ -641,12 +642,11 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report fprintf(stderr, "Starting output to %s(ffmpeg)...\n" " Using type=%d, codec=%d, audio_codec=%d,\n" " video_bitrate=%d, audio_bitrate=%d,\n" - " gop_size=%d, multiplex=%d, autosplit=%d\n" + " gop_size=%d, autosplit=%d\n" " render width=%d, render height=%d\n", name, ffmpeg_type, ffmpeg_codec, ffmpeg_audio_codec, ffmpeg_video_bitrate, ffmpeg_audio_bitrate, - ffmpeg_gop_size, ffmpeg_multiplex_audio, - ffmpeg_autosplit, rectx, recty); + ffmpeg_gop_size, ffmpeg_autosplit, rectx, recty); exts = get_file_extensions(ffmpeg_type); if (!exts) { @@ -667,7 +667,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report of->oformat = fmt; of->packet_size= rd->ffcodecdata.mux_packet_size; - if (ffmpeg_multiplex_audio) { + if (ffmpeg_audio_codec != CODEC_ID_NONE) { of->mux_rate = rd->ffcodecdata.mux_rate; } else { of->mux_rate = 0; @@ -676,6 +676,8 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report of->preload = (int)(0.5*AV_TIME_BASE); of->max_delay = (int)(0.7*AV_TIME_BASE); + fmt->audio_codec = ffmpeg_audio_codec; + snprintf(of->filename, sizeof(of->filename), "%s", name); /* set the codec to the user's selection */ switch(ffmpeg_type) { @@ -703,6 +705,11 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report case FFMPEG_FLV: fmt->video_codec = CODEC_ID_FLV1; break; + case FFMPEG_MP3: + fmt->audio_codec = CODEC_ID_MP3; + case FFMPEG_WAV: + fmt->video_codec = CODEC_ID_NONE; + break; case FFMPEG_MPEG4: default: fmt->video_codec = CODEC_ID_MPEG4; @@ -723,30 +730,29 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report } } - fmt->audio_codec = ffmpeg_audio_codec; - if (ffmpeg_type == FFMPEG_DV) { fmt->audio_codec = CODEC_ID_PCM_S16LE; - if (ffmpeg_multiplex_audio && rd->ffcodecdata.audio_mixrate != 48000) { + if (ffmpeg_audio_codec != CODEC_ID_NONE && rd->ffcodecdata.audio_mixrate != 48000) { BKE_report(reports, RPT_ERROR, "FFMPEG only supports 48khz / stereo audio for DV!"); return 0; } } - video_stream = alloc_video_stream(rd, fmt->video_codec, of, rectx, recty); - printf("alloc video stream %p\n", video_stream); - if (!video_stream) { - BKE_report(reports, RPT_ERROR, "Error initializing video stream."); - return 0; + if (fmt->video_codec != CODEC_ID_NONE) { + video_stream = alloc_video_stream(rd, fmt->video_codec, of, rectx, recty); + printf("alloc video stream %p\n", video_stream); + if (!video_stream) { + BKE_report(reports, RPT_ERROR, "Error initializing video stream."); + return 0; + } } - - if (ffmpeg_multiplex_audio) { + + if (ffmpeg_audio_codec != CODEC_ID_NONE) { audio_stream = alloc_audio_stream(rd, fmt->audio_codec, of); if (!audio_stream) { BKE_report(reports, RPT_ERROR, "Error initializing audio stream."); return 0; } - //XXX audiostream_play(SFRA, 0, 1); } if (av_set_parameters(of, NULL) < 0) { BKE_report(reports, RPT_ERROR, "Error setting output parameters."); @@ -818,14 +824,14 @@ int start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty, Repo success = start_ffmpeg_impl(rd, rectx, recty, reports); - if(ffmpeg_multiplex_audio && audio_stream) + if(audio_stream) { AVCodecContext* c = get_codec_from_stream(audio_stream); AUD_DeviceSpecs specs; specs.channels = c->channels; specs.format = AUD_FORMAT_S16; specs.rate = rd->ffcodecdata.audio_mixrate; - audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->efra, rd->ffcodecdata.audio_volume); + audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->ffcodecdata.audio_volume); } return success; @@ -833,21 +839,13 @@ int start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty, Repo void end_ffmpeg(void); -static void write_audio_frames() +static void write_audio_frames(double to_pts) { int finished = 0; - while (ffmpeg_multiplex_audio && !finished) { - double a_pts = ((double)audio_stream->pts.val - * audio_stream->time_base.num - / audio_stream->time_base.den); - double v_pts = ((double)video_stream->pts.val - * video_stream->time_base.num - / video_stream->time_base.den); - - if (a_pts < v_pts) { - write_audio_frame(); - } else { + while (audio_stream && !finished) { + if((audio_time >= to_pts) || + (write_audio_frame())) { finished = 1; } } @@ -856,25 +854,31 @@ static void write_audio_frames() int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports) { AVFrame* avframe; - int success; + int success = 1; fprintf(stderr, "Writing frame %i, " "render width=%d, render height=%d\n", frame, rectx, recty); - write_audio_frames(); +// why is this done before writing the video frame and again at end_ffmpeg? +// write_audio_frames(frame / (((double)rd->frs_sec) / rd->frs_sec_base)); - avframe= generate_video_frame((unsigned char*) pixels, reports); - success= (avframe && write_video_frame(rd, avframe, reports)); - - if (ffmpeg_autosplit) { - if (url_ftell(OUTFILE_PB) > FFMPEG_AUTOSPLIT_SIZE) { - end_ffmpeg(); - ffmpeg_autosplit_count++; - success &= start_ffmpeg_impl(rd, rectx, recty, reports); + if(video_stream) + { + avframe= generate_video_frame((unsigned char*) pixels, reports); + success= (avframe && write_video_frame(rd, avframe, reports)); + + if (ffmpeg_autosplit) { + if (url_ftell(OUTFILE_PB) > FFMPEG_AUTOSPLIT_SIZE) { + end_ffmpeg(); + ffmpeg_autosplit_count++; + success &= start_ffmpeg_impl(rd, rectx, recty, reports); + } } } + write_audio_frames(frame / (((double)rd->frs_sec) / rd->frs_sec_base)); + return success; } @@ -885,9 +889,9 @@ void end_ffmpeg(void) fprintf(stderr, "Closing ffmpeg...\n"); - if (audio_stream && video_stream) { +/* if (audio_stream) { SEE UPPER write_audio_frames(); - } + }*/ if(audio_mixdown_device) { @@ -1259,8 +1263,8 @@ void ffmpeg_verify_image_type(RenderData *rd) } } - if(audio && rd->ffcodecdata.audio_codec <= 0) { - rd->ffcodecdata.audio_codec = CODEC_ID_MP2; + if(audio && rd->ffcodecdata.audio_codec < 0) { + rd->ffcodecdata.audio_codec = CODEC_ID_NONE; rd->ffcodecdata.audio_bitrate = 128; } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ed551e56fe9..5938f9e6e2a 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4138,14 +4138,14 @@ static void lib_link_scene(FileData *fd, Main *main) 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_handle= NULL; + seq->scene_sound = NULL; if(seq->type == SEQ_HD_SOUND) seq->type = SEQ_SOUND; else seq->sound= newlibadr(fd, sce->id.lib, seq->sound); if (seq->sound) { seq->sound->id.us++; - seq->sound_handle= sound_new_handle(sce, seq->sound, seq->startdisp, seq->enddisp, seq->startofs); + seq->scene_sound = sound_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs); } } seq->anim= 0; @@ -4161,7 +4161,7 @@ static void lib_link_scene(FileData *fd, Main *main) #endif if(sce->ed) - seq_update_muting(sce->ed); + seq_update_muting(sce, sce->ed); if(sce->nodetree) { lib_link_ntree(fd, &sce->id, sce->nodetree); @@ -4217,7 +4217,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->obedit= NULL; sce->stats= 0; - memset(&sce->sound_handles, 0, sizeof(sce->sound_handles)); + sound_create_scene(sce); /* set users to one by default, not in lib-link, this will increase it for compo nodes */ sce->id.us= 1; @@ -5200,6 +5200,7 @@ static void fix_relpaths_library(const char *basepath, Main *main) static void direct_link_sound(FileData *fd, bSound *sound) { sound->handle = NULL; + sound->playback_handle = NULL; sound->packedfile = direct_link_packedfile(fd, sound->packedfile); sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile); @@ -10565,6 +10566,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* put 2.50 compatibility code here until next subversion bump */ { Scene *sce; + Sequence *seq; /* initialize to sane default so toggling on border shows something */ for(sce = main->scene.first; sce; sce = sce->id.next) { @@ -10575,6 +10577,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main) sce->r.border.xmax= 1.0f; sce->r.border.ymax= 1.0f; } + + if((sce->r.ffcodecdata.flags & FFMPEG_MULTIPLEX_AUDIO) == 0) + sce->r.ffcodecdata.audio_codec = 0x0; // CODEC_ID_NONE + + SEQ_BEGIN(sce->ed, seq) { + seq->volume = 1.0f; + } + SEQ_END } /* sequencer changes */ diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 82a2b615681..8ac2bd5753a 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -83,7 +83,7 @@ static void change_frame_apply(bContext *C, wmOperator *op) CFRA= RNA_int_get(op->ptr, "frame"); /* do updates */ - sound_scrub(C); + sound_seek_scene(C); WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index f7aeee14cb7..53cd34c46f5 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1513,9 +1513,11 @@ static int frame_offset_exec(bContext *C, wmOperator *op) int delta; delta = RNA_int_get(op->ptr, "delta"); - + CTX_data_scene(C)->r.cfra += delta; + sound_seek_scene(C); + WM_event_add_notifier(C, NC_SCENE|ND_FRAME, CTX_data_scene(C)); return OPERATOR_FINISHED; @@ -2473,12 +2475,13 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event) } } + if(sad->flag & ANIMPLAY_FLAG_JUMPED) + sound_seek_scene(C); + /* since we follow drawflags, we can't send notifier but tag regions ourselves */ ED_update_for_newframe(C, 1); - sound_update_playing(C); - for(sa= screen->areabase.first; sa; sa= sa->next) { ARegion *ar; for(ar= sa->regionbase.first; ar; ar= ar->next) { @@ -2521,16 +2524,19 @@ static void SCREEN_OT_animation_step(wmOperatorType *ot) static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event) { bScreen *screen= CTX_wm_screen(C); + struct Scene* scene = CTX_data_scene(C); if(screen->animtimer) { /* stop playback now */ ED_screen_animation_timer(C, 0, 0, 0); - sound_stop_all(C); + sound_stop_scene(scene); } else { ScrArea *sa= CTX_wm_area(C); int mode= (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1; int sync= -1; + if(mode == 1) // XXX only play audio forwards!? + sound_play_scene(scene); if(RNA_property_is_set(op->ptr, "sync")) sync= (RNA_boolean_get(op->ptr, "sync")); diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 064baafbd95..7398017a267 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -74,12 +74,12 @@ static int open_exec(bContext *C, wmOperator *op) sound = sound_new_file(CTX_data_main(C), path); - if (sound==NULL || sound->handle == NULL) { + if (sound==NULL || sound->playback_handle == NULL) { BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); return OPERATOR_CANCELLED; } - info = AUD_getInfo(sound->handle); + info = AUD_getInfo(sound->playback_handle); if (info.specs.channels == AUD_CHANNELS_INVALID) { sound_delete(C, sound); diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 648a162890d..f8a12c566df 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -77,7 +77,7 @@ static void graphview_cursor_apply(bContext *C, wmOperator *op) * NOTE: sync this part of the code with ANIM_OT_change_frame */ CFRA= RNA_int_get(op->ptr, "frame"); - sound_scrub(C); + sound_seek_scene(C); /* set the cursor value */ sipo->cursorVal= RNA_float_get(op->ptr, "value"); diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 359082c470a..566abaa18c3 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -215,7 +215,7 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op) else strcpy(seq->name+2, sce_seq->id.name+2); - calc_sequence_disp(seq); + calc_sequence_disp(scene, seq); sort_seq(scene); if (RNA_boolean_get(op->ptr, "replace_sel")) { @@ -303,7 +303,7 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad } sort_seq(scene); - seq_update_muting(ed); + seq_update_muting(scene, ed); WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); @@ -428,7 +428,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) } } - calc_sequence_disp(seq); + calc_sequence_disp(scene, seq); sort_seq(scene); @@ -530,7 +530,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op) seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE; - calc_sequence(seq); + calc_sequence(scene, seq); /* basic defaults */ seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index b3682681fd7..5339acf74d9 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -49,7 +49,8 @@ #include "BKE_sequencer.h" #include "BKE_scene.h" #include "BKE_utildefines.h" - +#include "BKE_sound.h" + #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -172,6 +173,38 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, char *col) } } +static void drawseqwave(Sequence *seq, float x1, float y1, float x2, float y2, float stepsize) +{ + /* + x1 is the starting x value to draw the wave, + x2 the end x value, same for y1 and y2 + stepsize is width of a pixel. + */ + if(seq->sound->cache) + { + int i; + int length = floor((x2-x1)/stepsize)+1; + float ymid = (y1+y2)/2; + float yscale = (y2-y1)/2; + float* samples = malloc(length * sizeof(float) * 2); + if(!samples) + return; + if(sound_read_sound_buffer(seq->sound, samples, length) != length) + { + free(samples); + return; + } + glBegin(GL_LINES); + for(i = 0; i < length; i++) + { + glVertex2f(x1+i*stepsize, ymid + samples[i * 2] * yscale); + glVertex2f(x1+i*stepsize, ymid + samples[i * 2 + 1] * yscale); + } + glEnd(); + free(samples); + } +} + static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2) { /* Note, this used to use WHILE_SEQ, but it messes up the seq->depth value, (needed by transform when doing overlap checks) @@ -557,6 +590,9 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, SpaceSeq *sseq, Sequence * x1= seq->startdisp; x2= seq->enddisp; + /* draw sound wave */ + if(seq->type == SEQ_SOUND) drawseqwave(seq, x1, y1, x2, y2, (ar->v2d.cur.xmax - ar->v2d.cur.xmin)/ar->winx); + get_seq_color3ubv(scene, seq, col); if (G.moving && (seq->flag & SELECT)) { if(seq->flag & SEQ_OVERLAP) { diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index fb8f3b37683..4f19cfa86af 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -479,7 +479,7 @@ static void reload_sound_strip(Scene *scene, char *name) seqact->strip= seq->strip; seqact->len= seq->len; - calc_sequence(seqact); + calc_sequence(scene, seqact); seq->strip= 0; seq_free_sequence(scene, seq); @@ -519,7 +519,7 @@ static void reload_image_strip(Scene *scene, char *name) seqact->strip= seq->strip; seqact->len= seq->len; - calc_sequence(seqact); + calc_sequence(scene, seqact); seq->strip= 0; seq_free_sequence(scene, seq); @@ -857,8 +857,8 @@ static Sequence *dupli_seq(struct Scene *scene, Sequence *seq) } else if(seq->type == SEQ_SOUND) { seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); - if(seq->sound_handle) - seqn->sound_handle = sound_new_handle(scene, seqn->sound, seq->sound_handle->startframe, seq->sound_handle->endframe, seq->sound_handle->frameskip); + if(seq->scene_sound) + seqn->scene_sound = sound_add_scene_sound(scene, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); seqn->sound->id.us++; } else if(seq->type == SEQ_IMAGE) { @@ -983,7 +983,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence * seq, int cutframe) } reload_sequence_new_file(scene, seq); - calc_sequence(seq); + calc_sequence(scene, seq); if (!skip_dup) { /* Duplicate AFTER the first change */ @@ -1022,7 +1022,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence * seq, int cutframe) } reload_sequence_new_file(scene, seqn); - calc_sequence(seqn); + calc_sequence(scene, seqn); } return seqn; } @@ -1072,7 +1072,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence * seq, int cutframe) } } - calc_sequence(seq); + calc_sequence(scene, seq); if (!skip_dup) { /* Duplicate AFTER the first change */ @@ -1107,7 +1107,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence * seq, int cutframe) seqn->startstill = 0; } - calc_sequence(seqn); + calc_sequence(scene, seqn); } return seqn; } @@ -1161,7 +1161,7 @@ int insert_gap(Scene *scene, int gap, int cfra) SEQP_BEGIN(ed, seq) { if(seq->startdisp >= cfra) { seq->start+= gap; - calc_sequence(seq); + calc_sequence(scene, seq); done= 1; } } @@ -1336,7 +1336,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) } seq_tx_handle_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL); } - calc_sequence(seq); + calc_sequence(scene, seq); } } SEQ_END @@ -1351,11 +1351,11 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) } else if(seq->type & SEQ_EFFECT) { if(seq->seq1 && (seq->seq1->flag & SELECT)) - calc_sequence(seq); + calc_sequence(scene, seq); else if(seq->seq2 && (seq->seq2->flag & SELECT)) - calc_sequence(seq); + calc_sequence(scene, seq); else if(seq->seq3 && (seq->seq3->flag & SELECT)) - calc_sequence(seq); + calc_sequence(scene, seq); } } SEQ_END; @@ -1425,7 +1425,7 @@ static int sequencer_mute_exec(bContext *C, wmOperator *op) } } - seq_update_muting(ed); + seq_update_muting(scene, ed); WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -1476,7 +1476,7 @@ static int sequencer_unmute_exec(bContext *C, wmOperator *op) } } - seq_update_muting(ed); + seq_update_muting(scene, ed); WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -1623,8 +1623,6 @@ static int sequencer_refresh_all_exec(bContext *C, wmOperator *op) free_imbuf_seq(scene, &ed->seqbase, FALSE); - seqbase_sound_reload(scene, &ed->seqbase); - WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -1840,7 +1838,7 @@ static int sequencer_delete_exec(bContext *C, wmOperator *op) /* updates lengths etc */ seq= ed->seqbasep->first; while(seq) { - calc_sequence(seq); + calc_sequence(scene, seq); seq= seq->next; } @@ -1848,7 +1846,7 @@ static int sequencer_delete_exec(bContext *C, wmOperator *op) ms= ed->metastack.last; while(ms) { ms->parseq->strip->len= 0; /* force new alloc */ - calc_sequence(ms->parseq); + calc_sequence(scene, ms->parseq); ms= ms->prev; } @@ -1923,7 +1921,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) /* new stripdata */ strip_new->stripdata= se_new= MEM_callocN(sizeof(StripElem)*1, "stripelem"); strncpy(se_new->name, se->name, FILE_MAXFILE-1); - calc_sequence(seq_new); + calc_sequence(scene, seq_new); seq_new->flag &= ~SEQ_OVERLAP; if (seq_test_overlap(ed->seqbasep, seq_new)) { shuffle_seq(ed->seqbasep, seq_new, scene); @@ -2011,7 +2009,7 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *op) /* recalc all: the meta can have effects connected to it */ for(seq= ed->seqbasep->first; seq; seq= seq->next) - calc_sequence(seq); + calc_sequence(scene, seq); active_seq_set(scene, ms->parseq); @@ -2022,7 +2020,7 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *op) } - seq_update_muting(ed); + seq_update_muting(scene, ed); WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -2081,7 +2079,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) seq= next; } seqm->machine= channel_max; - calc_sequence(seqm); + calc_sequence(scene, seqm); seqm->strip= MEM_callocN(sizeof(Strip), "metastrip"); seqm->strip->len= seqm->len; @@ -2091,7 +2089,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) if( seq_test_overlap(ed->seqbasep, seqm) ) shuffle_seq(ed->seqbasep, seqm, scene); - seq_update_muting(ed); + seq_update_muting(scene, ed); seqUniqueName(scene->ed->seqbasep, seqm); @@ -2165,7 +2163,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *op) SEQ_END; sort_seq(scene); - seq_update_muting(ed); + seq_update_muting(scene, ed); WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); @@ -2521,13 +2519,13 @@ void SEQUENCER_OT_previous_edit(wmOperatorType *ot) /* properties */ } -static void swap_sequence(Sequence* seqa, Sequence* seqb) +static void swap_sequence(Scene* scene, Sequence* seqa, Sequence* seqb) { int gap = seqb->startdisp - seqa->enddisp; seqb->start = seqa->start; - calc_sequence(seqb); + calc_sequence(scene, seqb); seqa->start = seqb->enddisp + gap; - calc_sequence(seqa); + calc_sequence(scene, seqa); } static Sequence* sequence_find_parent(Scene* scene, Sequence* child) @@ -2571,17 +2569,17 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op) switch (side) { case SEQ_SIDE_LEFT: - swap_sequence(seq, active_seq); + swap_sequence(scene, seq, active_seq); break; case SEQ_SIDE_RIGHT: - swap_sequence(active_seq, seq); + swap_sequence(scene, active_seq, seq); break; } // XXX - should be a generic function for(iseq= scene->ed->seqbasep->first; iseq; iseq= iseq->next) { if((iseq->type & SEQ_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { - calc_sequence(iseq); + calc_sequence(scene, iseq); } } @@ -2682,9 +2680,9 @@ static void seq_del_sound(Scene *scene, Sequence *seq) seq_del_sound(scene, iseq); } } - else if(seq->sound_handle) { - sound_delete_handle(scene, seq->sound_handle); - seq->sound_handle= NULL; + else if(seq->scene_sound) { + sound_remove_scene_sound(scene, seq->scene_sound); + seq->scene_sound = NULL; } } @@ -2733,19 +2731,19 @@ void SEQUENCER_OT_copy(wmOperatorType *ot) /* properties */ } -static void seq_offset(Sequence *seq, int ofs) +static void seq_offset(Scene *scene, Sequence *seq, int ofs) { if(seq->type == SEQ_META) { Sequence *iseq; for(iseq= seq->seqbase.first; iseq; iseq= iseq->next) { - seq_offset(iseq, ofs); + seq_offset(scene, iseq, ofs); } } else { seq->start += ofs; } - calc_sequence_disp(seq); + calc_sequence_disp(scene, seq); } static int sequencer_paste_exec(bContext *C, wmOperator *op) @@ -2764,7 +2762,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) /* transform pasted strips before adding */ if(ofs) { for(iseq= new.first; iseq; iseq= iseq->next) { - seq_offset(iseq, ofs); + seq_offset(scene, iseq, ofs); } } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 15b812dc1f2..e93e9c42e10 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2369,10 +2369,10 @@ void flushTransSeq(TransInfo *t) /* Calculate this strip and all nested strips * children are ALWAYS transformed first * so we dont need to do this in another loop. */ - calc_sequence(seq); + calc_sequence(t->scene, seq); } else { - calc_sequence_disp(seq); + calc_sequence_disp(t->scene, seq); } } seq_prev= seq; @@ -2404,7 +2404,7 @@ void flushTransSeq(TransInfo *t) while(seq) { if (seq->type == SEQ_META && seq->flag & SELECT) - calc_sequence(seq); + calc_sequence(t->scene, seq); seq= seq->next; } } @@ -4105,9 +4105,9 @@ static void freeSeqData(TransInfo *t) for(seq= seqbasep->first; seq; seq= seq->next) { /* We might want to build a list of effects that need to be updated during transform */ if(seq->type & SEQ_EFFECT) { - if (seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(seq); - else if (seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(seq); - else if (seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(seq); + if (seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(t->scene, seq); + else if (seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(t->scene, seq); + else if (seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(t->scene, seq); } } @@ -4118,7 +4118,7 @@ static void freeSeqData(TransInfo *t) for(a=0; atotal; a++, td++) { seq= ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev) && (seq->depth==0)) { - calc_sequence_disp(seq); + calc_sequence_disp(t->scene, seq); } seq_prev= seq; } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 63d3e764263..204af647b3a 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -758,7 +758,8 @@ typedef struct Scene { ListBase markers; ListBase transform_spaces; - ListBase sound_handles; + void *sound_scene; + void *sound_scene_handle; /* none of the dependancy graph vars is mean to be saved */ struct DagForest *theDag; @@ -1078,7 +1079,7 @@ typedef struct Scene { #define AUDIO_SYNC 2 #define AUDIO_SCRUB 4 -#define FFMPEG_MULTIPLEX_AUDIO 1 +#define FFMPEG_MULTIPLEX_AUDIO 1 /* deprecated, you can choose none as audiocodec now */ #define FFMPEG_AUTOSPLIT_OUTPUT 2 /* Paint.flags */ diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 0b45d62e347..c93625e9c27 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -161,7 +161,9 @@ typedef struct Sequence { ListBase seqbase; /* list of strips for metastrips */ struct bSound *sound; /* the linked "bSound" object */ - struct SoundHandle *sound_handle; + void *scene_sound; + float volume, pad; + float level, pan; /* level in dB (0=full), pan -1..1 */ int scenenr; /* for scene selection */ float strobe; diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h index 55b48e4aacd..c0b8657618d 100644 --- a/source/blender/makesdna/DNA_sound_types.h +++ b/source/blender/makesdna/DNA_sound_types.h @@ -41,21 +41,6 @@ struct Ipo; struct PackedFile; struct SpaceLink; -// runtime only - no saving -typedef struct SoundHandle { - struct SoundHandle *next, *prev; - struct bSound *source; - void *handle; - int state; - int startframe; - int endframe; - int frameskip; - int mute; - int changed; - float volume; - float pad; -} SoundHandle; - typedef struct Sound3D { float min_gain; @@ -98,19 +83,21 @@ typedef struct bSound { float max_gain; float distance; int flags; + int pad; /** currently int type; struct bSound *child_sound;*/ /** - * Whether the sound has been changed and must be restarted if playing. + * The audaspace handle for cache. */ - int changed; + void *cache; /** - * The audaspace handle for cache. + * The audaspace handle that should actually be played back. + * Should be cache if cache != NULL; otherwise it's handle */ - void *cache; + void *playback_handle; /** XXX unused currently // SOUND_TYPE_LIMITER float start, end;*/ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 11aff7922c7..452745ba364 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -107,6 +107,7 @@ EnumPropertyItem snap_element_items[] = { #include "BKE_depsgraph.h" #include "BKE_image.h" #include "BKE_mesh.h" +#include "BKE_sound.h" #include "BLI_threads.h" #include "BLI_editVert.h" @@ -287,10 +288,11 @@ static void rna_Scene_preview_range_end_frame_set(PointerRNA *ptr, int value) data->r.pefra= value; } -static void rna_Scene_frame_update(Main *bmain, Scene *unused, PointerRNA *ptr) +static void rna_Scene_frame_update(bContext *C, PointerRNA *ptr) { //Scene *scene= ptr->id.data; //ED_update_for_newframe(C); + sound_seek_scene(C); } static int rna_Scene_active_keying_set_editable(PointerRNA *ptr) @@ -1675,12 +1677,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) #ifdef WITH_FFMPEG {R_H264, "H264", ICON_FILE_MOVIE, "H.264", ""}, {R_XVID, "XVID", ICON_FILE_MOVIE, "Xvid", ""}, - // XXX broken -#if 0 -#ifdef WITH_OGG {R_THEORA, "THEORA", ICON_FILE_MOVIE, "Ogg Theora", ""}, -#endif -#endif {R_FFMPEG, "FFMPEG", ICON_FILE_MOVIE, "FFMpeg", ""}, #endif {R_FRAMESERVER, "FRAMESERVER", ICON_FILE_SCRIPT, "Frame Server", ""}, @@ -1731,16 +1728,15 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {FFMPEG_DV, "DV", 0, "DV", ""}, {FFMPEG_H264, "H264", 0, "H.264", ""}, {FFMPEG_XVID, "XVID", 0, "Xvid", ""}, - // XXX broken -#if 0 -#ifdef WITH_OGG {FFMPEG_OGG, "OGG", 0, "Ogg", ""}, -#endif -#endif + {FFMPEG_MKV, "MKV", 0, "Matroska", ""}, {FFMPEG_FLV, "FLASH", 0, "Flash", ""}, + {FFMPEG_WAV, "WAV", 0, "Wav", ""}, + {FFMPEG_MP3, "MP3", 0, "Mp3", ""}, {0, NULL, 0, NULL, NULL}}; - + static EnumPropertyItem ffmpeg_codec_items[] = { + {CODEC_ID_NONE, "NONE", 0, "None", ""}, {CODEC_ID_MPEG1VIDEO, "MPEG1", 0, "MPEG-1", ""}, {CODEC_ID_MPEG2VIDEO, "MPEG2", 0, "MPEG-2", ""}, {CODEC_ID_MPEG4, "MPEG4", 0, "MPEG-4(divx)", ""}, @@ -1748,18 +1744,18 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {CODEC_ID_DVVIDEO, "DV", 0, "DV", ""}, {CODEC_ID_H264, "H264", 0, "H.264", ""}, {CODEC_ID_XVID, "XVID", 0, "Xvid", ""}, -#ifdef WITH_OGG {CODEC_ID_THEORA, "THEORA", 0, "Theora", ""}, -#endif {CODEC_ID_FLV1, "FLASH", 0, "Flash Video", ""}, {0, NULL, 0, NULL, NULL}}; - + static EnumPropertyItem ffmpeg_audio_codec_items[] = { + {CODEC_ID_NONE, "NONE", 0, "None", ""}, {CODEC_ID_MP2, "MP2", 0, "MP2", ""}, {CODEC_ID_MP3, "MP3", 0, "MP3", ""}, {CODEC_ID_AC3, "AC3", 0, "AC3", ""}, {CODEC_ID_AAC, "AAC", 0, "AAC", ""}, {CODEC_ID_VORBIS, "VORBIS", 0, "Vorbis", ""}, + {CODEC_ID_FLAC, "FLAC", 0, "FLAC", ""}, {CODEC_ID_PCM_S16LE, "PCM", 0, "PCM", ""}, {0, NULL, 0, NULL, NULL}}; #endif @@ -1992,7 +1988,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); /* FFMPEG Audio*/ - prop= RNA_def_property(srna, "ffmpeg_audio_codec", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "ffcodecdata.audio_codec"); RNA_def_property_enum_items(prop, ffmpeg_audio_codec_items); @@ -2005,11 +2000,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Bitrate", "Audio bitrate(kb/s)"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "ffmpeg_multiplex_audio", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "ffcodecdata.flags", FFMPEG_MULTIPLEX_AUDIO); - RNA_def_property_ui_text(prop, "Multiplex Audio", "Interleave audio with the output video"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "ffmpeg_audio_mixrate", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.audio_mixrate"); RNA_def_property_range(prop, 8000, 192000); @@ -2636,6 +2626,7 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "r.cfra"); RNA_def_property_range(prop, MINAFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Current Frame", ""); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_property_update(prop, NC_SCENE|ND_FRAME, "rna_Scene_frame_update"); prop= RNA_def_property(srna, "start_frame", PROP_INT, PROP_TIME); diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 7ffaa4d478b..00a156cf820 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -93,7 +93,7 @@ static void rna_Sequence_frame_change_update(Scene *scene, Sequence *seq) { Editing *ed= seq_give_editing(scene, FALSE); ListBase *seqbase= seq_seqbase(&ed->seqbase, seq); - calc_sequence_disp(seq); + calc_sequence_disp(scene, seq); if(seq_test_overlap(seqbase, seq)) { shuffle_seq(seqbase, seq, scene); // XXX - BROKEN!, uses context seqbasep @@ -351,14 +351,14 @@ static void rna_Sequence_update(Main *bmain, Scene *scene, PointerRNA *ptr) free_imbuf_seq(scene, &ed->seqbase, FALSE); if(RNA_struct_is_a(ptr->type, &RNA_SoundSequence)) - seq_update_sound(ptr->data); + seq_update_sound(scene, ptr->data); } static void rna_Sequence_mute_update(Main *bmain, Scene *scene, PointerRNA *ptr) { Editing *ed= seq_give_editing(scene, FALSE); - seq_update_muting(ed); + seq_update_muting(scene, ed); rna_Sequence_update(bmain, scene, ptr); } @@ -606,24 +606,28 @@ static void rna_def_sequence(BlenderRNA *brna) prop= RNA_def_property(srna, "length", PROP_INT, PROP_TIME); RNA_def_property_int_sdna(prop, NULL, "len"); RNA_def_property_range(prop, 1, MAXFRAME); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Length", "The length of the contents of this strip before the handles are applied"); RNA_def_property_int_funcs(prop, "rna_Sequence_length_get", "rna_Sequence_length_set",NULL); RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); prop= RNA_def_property(srna, "start_frame", PROP_INT, PROP_TIME); RNA_def_property_int_sdna(prop, NULL, "start"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Start Frame", ""); RNA_def_property_int_funcs(prop, NULL, "rna_Sequence_start_frame_set",NULL); // overlap tests and calc_seq_disp RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); prop= RNA_def_property(srna, "start_frame_final", PROP_INT, PROP_TIME); RNA_def_property_int_sdna(prop, NULL, "startdisp"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Start Frame", "Start frame displayed in the sequence editor after offsets are applied, setting this is equivilent to moving the handle, not the actual start frame."); RNA_def_property_int_funcs(prop, NULL, "rna_Sequence_start_frame_final_set", NULL); // overlap tests and calc_seq_disp RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); prop= RNA_def_property(srna, "end_frame_final", PROP_INT, PROP_TIME); RNA_def_property_int_sdna(prop, NULL, "enddisp"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "End Frame", "End frame displayed in the sequence editor after offsets are applied."); RNA_def_property_int_funcs(prop, NULL, "rna_Sequence_end_frame_final_set", NULL); // overlap tests and calc_seq_disp RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); @@ -949,6 +953,12 @@ static void rna_def_sound(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Sound", "Sound datablock used by this sequence."); RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); + prop= RNA_def_property(srna, "volume", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "volume"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Volume", "Playback volume of the sound"); + RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); + prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "strip->stripdata->name"); RNA_def_property_ui_text(prop, "Filename", ""); @@ -961,14 +971,6 @@ static void rna_def_sound(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); rna_def_input(srna); - - RNA_def_struct_sdna_from(srna, "SoundHandle", "sound_handle"); - - prop= RNA_def_property(srna, "volume", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "volume"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Volume", "Playback volume of the sound"); - RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); } static void rna_def_effect(BlenderRNA *brna) -- cgit v1.2.3