diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index 45faebc7e97..afa1568d6dc 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -516,21 +516,40 @@ AUD_Device* AUD_openReadDevice(AUD_Specs specs) } } -int AUD_playDevice(AUD_Device* device, AUD_Sound* sound) +AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound) { assert(device); assert(sound); try { - return device->play(sound) != NULL; + return device->play(sound); } catch(AUD_Exception) { - return false; + return NULL; } } +int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle, + float volume) +{ + if(handle) + { + assert(device); + AUD_SourceCaps caps; + caps.handle = handle; + caps.value = volume; + + try + { + return device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps); + } + catch(AUD_Exception) {} + } + return false; +} + int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length) { assert(device); diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h index 6ec5ec87ad5..b02b465bff2 100644 --- a/intern/audaspace/intern/AUD_C-API.h +++ b/intern/audaspace/intern/AUD_C-API.h @@ -303,9 +303,20 @@ extern AUD_Device* AUD_openReadDevice(AUD_Specs specs); * Plays back a sound file through a read device. * \param device The read device. * \param sound The handle of the sound file. - * \return Whether the sound could be played back. + * \return A handle to the played back sound. */ -extern int AUD_playDevice(AUD_Device* device, AUD_Sound* sound); +extern AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound); + +/** + * Sets the volume of a played back sound of a read device. + * \param device The read device. + * \param handle The handle to the sound. + * \param volume The new volume, must be between 0.0 and 1.0. + * \return Whether the action succeeded. + */ +extern int AUD_setDeviceSoundVolume(AUD_Device* device, + AUD_Handle* handle, + float volume); /** * Reads the next samples into the supplied buffer. diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h index e9f6eb21e36..cbce4663d6f 100644 --- a/source/blender/blenkernel/BKE_sound.h +++ b/source/blender/blenkernel/BKE_sound.h @@ -71,7 +71,7 @@ void sound_update_playing(struct bContext *C); void sound_scrub(struct bContext *C); #ifdef AUD_CAPI -AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end); +AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end, float volume); #endif void sound_stop_all(struct bContext *C); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 6f9ed3e0978..a9d7caaf5e0 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -419,7 +419,7 @@ Scene *add_scene(char *name) pset->brush[PE_BRUSH_CUT].strength= 100; sce->jumpframe = 10; - sce->r.audio.mixrate = 44100; + sce->r.ffcodecdata.audio_mixrate = 44100; strcpy(sce->r.backbuf, "//backbuf"); strcpy(sce->r.pic, U.renderdir); diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 2d5d8dad7a8..fdf6283925e 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -421,7 +421,7 @@ void sound_scrub(struct bContext *C) int cfra = CFRA; float fps = FPS; - if(scene->r.audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer) + if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer) { AUD_lock(); @@ -443,13 +443,14 @@ void sound_scrub(struct bContext *C) } } -AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end) +AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end, float volume) { AUD_Device* mixdown = AUD_openReadDevice(specs); SoundHandle *handle; float fps = FPS; AUD_Sound *limiter, *delayer; int frameskip, s, e; + AUD_Handle* h; end++; @@ -470,7 +471,8 @@ AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int e limiter = AUD_limitSound(handle->source->handle, frameskip / fps, e / fps); delayer = AUD_delaySound(limiter, s / fps); - AUD_playDevice(mixdown, delayer); + h = AUD_playDevice(mixdown, delayer); + AUD_setDeviceSoundVolume(mixdown, h, volume); AUD_unload(delayer); AUD_unload(limiter); diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index a90924055b3..1953058fddf 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -559,7 +559,7 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex c->codec_id = codec_id; c->codec_type = CODEC_TYPE_AUDIO; - c->sample_rate = rd->audio.mixrate; + c->sample_rate = rd->ffcodecdata.audio_mixrate; c->bit_rate = ffmpeg_audio_bitrate*1000; c->channels = 2; codec = avcodec_find_encoder(c->codec_id); @@ -734,7 +734,7 @@ static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty) if (ffmpeg_type == FFMPEG_DV) { fmt->audio_codec = CODEC_ID_PCM_S16LE; - if (ffmpeg_multiplex_audio && rd->audio.mixrate != 48000) { + if (ffmpeg_multiplex_audio && rd->ffcodecdata.audio_mixrate != 48000) { G.afbreek = 1; //XXX error("FFMPEG only supports 48khz / stereo " // "audio for DV!"); @@ -831,7 +831,6 @@ static void makeffmpegstring(RenderData* rd, char* string) { } } - void start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty) { ffmpeg_autosplit_count = 0; @@ -844,8 +843,8 @@ void start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty) 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); + specs.rate = rd->ffcodecdata.audio_mixrate; + audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->efra, rd->ffcodecdata.audio_volume); } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c5dcf1ce520..2d612cffc7d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9354,7 +9354,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* toolsettings */ for(scene= main->scene.first; scene; scene= scene->id.next) - scene->r.audio = scene->audio; + { + scene->r.ffcodecdata.audio_mixrate = scene->audio.mixrate; + scene->r.ffcodecdata.audio_volume = scene->audio.main; + } /* shader, composit and texture node trees have id.name empty, put something in * to have them show in RNA viewer and accessible otherwise. diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index a055041d8ae..ef28ff6dbd1 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2206,7 +2206,7 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event) /* sync, don't sync, or follow scene setting */ if(sad->flag & ANIMPLAY_FLAG_SYNC) sync= 1; else if(sad->flag & ANIMPLAY_FLAG_NO_SYNC) sync= 0; - else sync= (scene->r.audio.flag & AUDIO_SYNC); + else sync= (scene->audio.flag & AUDIO_SYNC); if(sync) { /* skip frames */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 73afc3d1a53..b41cd79b6d4 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -93,6 +93,8 @@ typedef struct FFMpegCodecData { int audio_codec; int video_bitrate; int audio_bitrate; + int audio_mixrate; + int audio_volume; int gop_size; int flags; @@ -106,8 +108,8 @@ typedef struct FFMpegCodecData { typedef struct AudioData { - int mixrate; - float main; /* Main mix in dB */ + int mixrate; // 2.5: now in FFMpegCodecData: audio_mixrate + float main; // 2.5: now in FFMpegCodecData: audio_volume short flag; short pad[3]; } AudioData; @@ -170,7 +172,6 @@ typedef struct RenderData { struct AviCodecData *avicodecdata; struct QuicktimeCodecData *qtcodecdata; struct FFMpegCodecData ffcodecdata; - struct AudioData audio; /* new in 2.5 */ int cfra, sfra, efra; /* frames as in 'images' */ int psfra, pefra; /* start+end frames of preview range */ @@ -697,7 +698,7 @@ typedef struct Scene { /* migrate or replace? depends on some internal things... */ /* no, is on the right place (ton) */ struct RenderData r; - struct AudioData audio; /* DEPRECATED 2.5 */ + struct AudioData audio; ListBase markers; ListBase transform_spaces; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 08efa13d8f4..d6991a3a624 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1512,6 +1512,19 @@ static void rna_def_scene_render_data(BlenderRNA *brna) 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); + RNA_def_property_ui_text(prop, "Sample", "Audio samplerate(samples/s)"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "ffmpeg_audio_volume", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "ffcodecdata.audio_volume"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Volume", "Audio volume"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + #endif prop= RNA_def_property(srna, "fps", PROP_INT, PROP_NONE); @@ -1583,11 +1596,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Fields Still", "Disable the time difference between fields."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "sync_audio", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_SYNC); - RNA_def_property_ui_text(prop, "Sync Audio", "Play back and sync with audio from Sequence Editor"); - RNA_def_property_update(prop, NC_SCENE, NULL); - prop= RNA_def_property(srna, "render_shadows", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_SHADOW); RNA_def_property_ui_text(prop, "Render Shadows", "Calculate shadows while rendering."); @@ -2063,6 +2071,22 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_struct_type(prop, "TimelineMarker"); RNA_def_property_ui_text(prop, "Timeline Markers", "Markers used in all timelines for the current scene."); + /* Audio Settings */ + prop= RNA_def_property(srna, "mute_audio", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_MUTE); + RNA_def_property_ui_text(prop, "Mute Audio", "Play back of audio from Sequence Editor will be muted."); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "sync_audio", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_SYNC); + RNA_def_property_ui_text(prop, "Sync Audio", "Play back and sync with audio from Sequence Editor."); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "scrub_audio", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_SCRUB); + RNA_def_property_ui_text(prop, "Scrub Audio", "Play audio from Sequence Editor while scrubbing."); + RNA_def_property_update(prop, NC_SCENE, NULL); + /* Game Settings */ prop= RNA_def_property(srna, "game_data", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL);