Blender V2.61 - r43446

sound_ops.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version. 
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2007 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * 
00022  * Contributor(s): Blender Foundation
00023  *
00024  * ***** END GPL LICENSE BLOCK *****
00025  */
00026 
00032 #include <string.h>
00033 #include <stdlib.h>
00034 #include <stdio.h>
00035 #include <stddef.h>
00036 
00037 #include "MEM_guardedalloc.h"
00038 
00039 #include "BLI_blenlib.h"
00040 #include "BLI_utildefines.h"
00041 
00042 #include "DNA_anim_types.h"
00043 #include "DNA_packedFile_types.h"
00044 #include "DNA_scene_types.h"
00045 #include "DNA_space_types.h"
00046 #include "DNA_sequence_types.h"
00047 #include "DNA_sound_types.h"
00048 #include "DNA_userdef_types.h"
00049 
00050 #include "BKE_context.h"
00051 #include "BKE_fcurve.h"
00052 #include "BKE_global.h"
00053 #include "BKE_main.h"
00054 #include "BKE_report.h"
00055 #include "BKE_packedFile.h"
00056 #include "BKE_scene.h"
00057 #include "BKE_sound.h"
00058 #include "BKE_sequencer.h"
00059 
00060 #include "RNA_access.h"
00061 #include "RNA_define.h"
00062 #include "RNA_enum_types.h"
00063 
00064 #include "UI_interface.h"
00065 
00066 #include "WM_api.h"
00067 #include "WM_types.h"
00068 
00069 #ifdef WITH_AUDASPACE
00070 #  include "AUD_C-API.h"
00071 #endif
00072 
00073 #include "ED_sound.h"
00074 #include "ED_util.h"
00075 
00076 #include "sound_intern.h"
00077 
00078 /******************** open sound operator ********************/
00079 
00080 static int sound_open_cancel(bContext *UNUSED(C), wmOperator *op)
00081 {
00082     MEM_freeN(op->customdata);
00083     op->customdata= NULL;
00084     return OPERATOR_CANCELLED;
00085 }
00086 
00087 static void sound_open_init(bContext *C, wmOperator *op)
00088 {
00089     PropertyPointerRNA *pprop;
00090 
00091     op->customdata= pprop= MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
00092     uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
00093 }
00094 
00095 #ifdef WITH_AUDASPACE
00096 static int sound_open_exec(bContext *C, wmOperator *op)
00097 {
00098     char path[FILE_MAX];
00099     bSound *sound;
00100     PropertyPointerRNA *pprop;
00101     PointerRNA idptr;
00102     AUD_SoundInfo info;
00103     Main *bmain = CTX_data_main(C);
00104 
00105     RNA_string_get(op->ptr, "filepath", path);
00106     sound = sound_new_file(bmain, path);
00107 
00108     if(!op->customdata)
00109         sound_open_init(C, op);
00110 
00111     if (sound==NULL || sound->playback_handle == NULL) {
00112         if(op->customdata) MEM_freeN(op->customdata);
00113         BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
00114         return OPERATOR_CANCELLED;
00115     }
00116 
00117     info = AUD_getInfo(sound->playback_handle);
00118 
00119     if (info.specs.channels == AUD_CHANNELS_INVALID) {
00120         sound_delete(bmain, sound);
00121         if(op->customdata) MEM_freeN(op->customdata);
00122         BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
00123         return OPERATOR_CANCELLED;
00124     }
00125 
00126     if(RNA_boolean_get(op->ptr, "mono")) {
00127         sound->flags |= SOUND_FLAGS_MONO;
00128         sound_load(bmain, sound);
00129     }
00130 
00131     if (RNA_boolean_get(op->ptr, "cache")) {
00132         sound_cache(sound);
00133     }
00134 
00135     /* hook into UI */
00136     pprop= op->customdata;
00137 
00138     if(pprop->prop) {
00139         /* when creating new ID blocks, use is already 1, but RNA
00140          * pointer se also increases user, so this compensates it */
00141         sound->id.us--;
00142 
00143         RNA_id_pointer_create(&sound->id, &idptr);
00144         RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
00145         RNA_property_update(C, &pprop->ptr, pprop->prop);
00146     }
00147 
00148     if(op->customdata) MEM_freeN(op->customdata);
00149     return OPERATOR_FINISHED;
00150 }
00151 
00152 #else //WITH_AUDASPACE
00153 
00154 static int sound_open_exec(bContext *UNUSED(C), wmOperator *op)
00155 {
00156     BKE_report(op->reports, RPT_ERROR, "Compiled without sound support");
00157 
00158     return OPERATOR_CANCELLED;
00159 }
00160 
00161 #endif
00162 
00163 static int sound_open_invoke(bContext *C, wmOperator *op, wmEvent *event)
00164 {
00165     if(RNA_struct_property_is_set(op->ptr, "filepath"))
00166         return sound_open_exec(C, op);
00167 
00168     sound_open_init(C, op);
00169 
00170     return WM_operator_filesel(C, op, event);
00171 }
00172 
00173 static void SOUND_OT_open(wmOperatorType *ot)
00174 {
00175     /* identifiers */
00176     ot->name= "Open Sound";
00177     ot->description= "Load a sound file";
00178     ot->idname= "SOUND_OT_open";
00179 
00180     /* api callbacks */
00181     ot->exec= sound_open_exec;
00182     ot->invoke= sound_open_invoke;
00183     ot->cancel= sound_open_cancel;
00184 
00185     /* flags */
00186     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00187 
00188     /* properties */
00189     WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH);
00190     RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory");
00191     RNA_def_boolean(ot->srna, "mono", FALSE, "Mono", "Mixdown the sound to mono");
00192 }
00193 
00194 static void SOUND_OT_open_mono(wmOperatorType *ot)
00195 {
00196     /* identifiers */
00197     ot->name= "Open Sound Mono";
00198     ot->description= "Load a sound file as mono";
00199     ot->idname= "SOUND_OT_open_mono";
00200 
00201     /* api callbacks */
00202     ot->exec= sound_open_exec;
00203     ot->invoke= sound_open_invoke;
00204     ot->cancel= sound_open_cancel;
00205 
00206     /* flags */
00207     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00208 
00209     /* properties */
00210     WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH);
00211     RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory");
00212     RNA_def_boolean(ot->srna, "mono", TRUE, "Mono", "Mixdown the sound to mono");
00213 }
00214 
00215 /* ******************************************************* */
00216 
00217 static int sound_update_animation_flags_exec(bContext *C, wmOperator *UNUSED(op))
00218 {
00219     Sequence* seq;
00220     Scene* scene = CTX_data_scene(C);
00221     struct FCurve* fcu;
00222     char driven;
00223 
00224     SEQ_BEGIN(scene->ed, seq) {
00225         fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, &driven);
00226         if(fcu || driven)
00227             seq->flag |= SEQ_AUDIO_VOLUME_ANIMATED;
00228         else
00229             seq->flag &= ~SEQ_AUDIO_VOLUME_ANIMATED;
00230 
00231         fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pitch", 0, &driven);
00232         if(fcu || driven)
00233             seq->flag |= SEQ_AUDIO_PITCH_ANIMATED;
00234         else
00235             seq->flag &= ~SEQ_AUDIO_PITCH_ANIMATED;
00236 
00237         fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pan", 0, &driven);
00238         if(fcu || driven)
00239             seq->flag |= SEQ_AUDIO_PAN_ANIMATED;
00240         else
00241             seq->flag &= ~SEQ_AUDIO_PAN_ANIMATED;
00242     }
00243     SEQ_END
00244 
00245     fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven);
00246     if(fcu || driven)
00247         scene->audio.flag |= AUDIO_VOLUME_ANIMATED;
00248     else
00249         scene->audio.flag &= ~AUDIO_VOLUME_ANIMATED;
00250 
00251     return OPERATOR_FINISHED;
00252 }
00253 
00254 static void SOUND_OT_update_animation_flags(wmOperatorType *ot)
00255 {
00256     /*
00257       This operator is needed to set a correct state of the sound animation
00258       System. Unfortunately there's no really correct place to call the exec
00259       function, that's why I made it an operator that's only visible in the
00260       search menu. Apart from that the bake animation operator calls it too.
00261     */
00262 
00263     /* identifiers */
00264     ot->name= "Update animation";
00265     ot->description= "Update animation flags";
00266     ot->idname= "SOUND_OT_update_animation_flags";
00267 
00268     /* api callbacks */
00269     ot->exec= sound_update_animation_flags_exec;
00270 
00271     /* flags */
00272     ot->flag= OPTYPE_REGISTER;
00273 }
00274 
00275 /* ******************************************************* */
00276 
00277 static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op))
00278 {
00279     Main* bmain = CTX_data_main(C);
00280     Scene* scene = CTX_data_scene(C);
00281     int oldfra = scene->r.cfra;
00282     int cfra;
00283 
00284     sound_update_animation_flags_exec(C, NULL);
00285 
00286     for(cfra = scene->r.sfra > 0 ? scene->r.sfra - 1 : 0; cfra <= scene->r.efra + 1; cfra++)
00287     {
00288         scene->r.cfra = cfra;
00289         scene_update_for_newframe(bmain, scene, scene->lay);
00290     }
00291 
00292     scene->r.cfra = oldfra;
00293     scene_update_for_newframe(bmain, scene, scene->lay);
00294 
00295     return OPERATOR_FINISHED;
00296 }
00297 
00298 static void SOUND_OT_bake_animation(wmOperatorType *ot)
00299 {
00300     /* identifiers */
00301     ot->name= "Update animation cache";
00302     ot->description= "Updates the audio animation cache so that it's up to date";
00303     ot->idname= "SOUND_OT_bake_animation";
00304 
00305     /* api callbacks */
00306     ot->exec= sound_bake_animation_exec;
00307 
00308     /* flags */
00309     ot->flag= OPTYPE_REGISTER;
00310 }
00311 
00312 
00313 /******************** mixdown operator ********************/
00314 
00315 static int sound_mixdown_exec(bContext *C, wmOperator *op)
00316 {
00317 #ifdef WITH_AUDASPACE
00318     char path[FILE_MAX];
00319     char filename[FILE_MAX];
00320     Scene *scene;
00321     Main *bmain;
00322 
00323     int bitrate, accuracy;
00324     AUD_DeviceSpecs specs;
00325     AUD_Container container;
00326     AUD_Codec codec;
00327     const char* result;
00328 
00329     sound_bake_animation_exec(C, op);
00330 
00331     RNA_string_get(op->ptr, "filepath", path);
00332     bitrate = RNA_int_get(op->ptr, "bitrate") * 1000;
00333     accuracy = RNA_int_get(op->ptr, "accuracy");
00334     specs.format = RNA_enum_get(op->ptr, "format");
00335     container = RNA_enum_get(op->ptr, "container");
00336     codec = RNA_enum_get(op->ptr, "codec");
00337     scene = CTX_data_scene(C);
00338     bmain = CTX_data_main(C);
00339     specs.channels = scene->r.ffcodecdata.audio_channels;
00340     specs.rate = scene->r.ffcodecdata.audio_mixrate;
00341 
00342     BLI_strncpy(filename, path, sizeof(filename));
00343     BLI_path_abs(filename, bmain->name);
00344 
00345     result = AUD_mixdown(scene->sound_scene, SFRA * specs.rate / FPS, (EFRA - SFRA) * specs.rate / FPS,
00346                          accuracy, filename, specs, container, codec, bitrate);
00347 
00348     if(result)
00349     {
00350         BKE_report(op->reports, RPT_ERROR, result);
00351         return OPERATOR_CANCELLED;
00352     }
00353 #else // WITH_AUDASPACE
00354     (void)C;
00355     (void)op;
00356 #endif // WITH_AUDASPACE
00357     return OPERATOR_FINISHED;
00358 }
00359 
00360 static int sound_mixdown_invoke(bContext *C, wmOperator *op, wmEvent *event)
00361 {
00362     if(RNA_struct_property_is_set(op->ptr, "filepath"))
00363         return sound_mixdown_exec(C, op);
00364 
00365     return WM_operator_filesel(C, op, event);
00366 }
00367 
00368 #ifdef WITH_AUDASPACE
00369 
00370 static int sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
00371 {
00372     const char *prop_id= RNA_property_identifier(prop);
00373     return !(   strcmp(prop_id, "filepath") == 0 ||
00374                 strcmp(prop_id, "directory") == 0 ||
00375                 strcmp(prop_id, "filename") == 0
00376     );
00377 }
00378 
00379 static void sound_mixdown_draw(bContext *C, wmOperator *op)
00380 {
00381     static EnumPropertyItem pcm_format_items[] = {
00382         {AUD_FORMAT_U8, "U8", 0, "U8", "8 bit unsigned"},
00383         {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
00384 #ifdef WITH_SNDFILE
00385         {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"},
00386 #endif
00387         {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"},
00388         {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"},
00389         {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64 bit floating point"},
00390         {0, NULL, 0, NULL, NULL}};
00391 
00392     static EnumPropertyItem mp3_format_items[] = {
00393         {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
00394         {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"},
00395         {0, NULL, 0, NULL, NULL}};
00396 
00397     static EnumPropertyItem ac3_format_items[] = {
00398         {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
00399         {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"},
00400         {0, NULL, 0, NULL, NULL}};
00401 
00402 #ifdef WITH_SNDFILE
00403     static EnumPropertyItem flac_format_items[] = {
00404         {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
00405         {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"},
00406         {0, NULL, 0, NULL, NULL}};
00407 #endif
00408 
00409     static EnumPropertyItem all_codec_items[] = {
00410         {AUD_CODEC_AAC, "AAC", 0, "AAC", "Advanced Audio Coding"},
00411         {AUD_CODEC_AC3, "AC3", 0, "AC3", "Dolby Digital ATRAC 3"},
00412         {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
00413         {AUD_CODEC_MP2, "MP2", 0, "MP2", "MPEG-1 Audio Layer II"},
00414         {AUD_CODEC_MP3, "MP3", 0, "MP3", "MPEG-2 Audio Layer III"},
00415         {AUD_CODEC_PCM, "PCM", 0, "PCM", "Pulse Code Modulation (RAW)"},
00416         {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
00417         {0, NULL, 0, NULL, NULL}};
00418 
00419     static EnumPropertyItem ogg_codec_items[] = {
00420         {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
00421         {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
00422         {0, NULL, 0, NULL, NULL}};
00423 
00424     uiLayout *layout = op->layout;
00425     wmWindowManager *wm= CTX_wm_manager(C);
00426     PointerRNA ptr;
00427     PropertyRNA *prop_format;
00428     PropertyRNA *prop_codec;
00429     PropertyRNA *prop_bitrate;
00430 
00431     AUD_Container container = RNA_enum_get(op->ptr, "container");
00432     AUD_Codec codec = RNA_enum_get(op->ptr, "codec");
00433 
00434     prop_format = RNA_struct_find_property(op->ptr, "format");
00435     prop_codec = RNA_struct_find_property(op->ptr, "codec");
00436     prop_bitrate = RNA_struct_find_property(op->ptr, "bitrate");
00437 
00438     RNA_def_property_clear_flag(prop_bitrate, PROP_HIDDEN);
00439     RNA_def_property_flag(prop_codec, PROP_HIDDEN);
00440     RNA_def_property_flag(prop_format, PROP_HIDDEN);
00441 
00442     switch(container)
00443     {
00444     case AUD_CONTAINER_AC3:
00445         RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
00446         RNA_def_property_enum_items(prop_format, ac3_format_items);
00447         RNA_def_property_enum_items(prop_codec, all_codec_items);
00448         RNA_enum_set(op->ptr, "codec", AUD_CODEC_AC3);
00449         break;
00450     case AUD_CONTAINER_FLAC:
00451         RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
00452         RNA_def_property_enum_items(prop_codec, all_codec_items);
00453         RNA_enum_set(op->ptr, "codec", AUD_CODEC_FLAC);
00454 #ifdef WITH_SNDFILE
00455         RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
00456         RNA_def_property_enum_items(prop_format, flac_format_items);
00457 #else
00458         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
00459 #endif
00460         break;
00461     case AUD_CONTAINER_MATROSKA:
00462         RNA_def_property_clear_flag(prop_codec, PROP_HIDDEN);
00463         RNA_def_property_enum_items(prop_codec, all_codec_items);
00464 
00465         switch(codec)
00466         {
00467         case AUD_CODEC_AAC:
00468             RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
00469             break;
00470         case AUD_CODEC_AC3:
00471             RNA_def_property_enum_items(prop_format, ac3_format_items);
00472             RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
00473             break;
00474         case AUD_CODEC_FLAC:
00475             RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
00476             RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
00477             break;
00478         case AUD_CODEC_MP2:
00479             RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
00480             break;
00481         case AUD_CODEC_MP3:
00482             RNA_def_property_enum_items(prop_format, mp3_format_items);
00483             RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
00484             break;
00485         case AUD_CODEC_PCM:
00486             RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
00487             RNA_def_property_enum_items(prop_format, pcm_format_items);
00488             RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
00489             break;
00490         case AUD_CODEC_VORBIS:
00491             RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
00492             break;
00493         default:
00494             break;
00495         }
00496 
00497         break;
00498     case AUD_CONTAINER_MP2:
00499         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
00500         RNA_enum_set(op->ptr, "codec", AUD_CODEC_MP2);
00501         RNA_def_property_enum_items(prop_codec, all_codec_items);
00502         break;
00503     case AUD_CONTAINER_MP3:
00504         RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
00505         RNA_def_property_enum_items(prop_format, mp3_format_items);
00506         RNA_def_property_enum_items(prop_codec, all_codec_items);
00507         RNA_enum_set(op->ptr, "codec", AUD_CODEC_MP3);
00508         break;
00509     case AUD_CONTAINER_OGG:
00510         RNA_def_property_clear_flag(prop_codec, PROP_HIDDEN);
00511         RNA_def_property_enum_items(prop_codec, ogg_codec_items);
00512         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
00513         break;
00514     case AUD_CONTAINER_WAV:
00515         RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
00516         RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
00517         RNA_def_property_enum_items(prop_format, pcm_format_items);
00518         RNA_def_property_enum_items(prop_codec, all_codec_items);
00519         RNA_enum_set(op->ptr, "codec", AUD_CODEC_PCM);
00520         break;
00521     default:
00522         break;
00523     }
00524 
00525     RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
00526 
00527     /* main draw call */
00528     uiDefAutoButsRNA(layout, &ptr, sound_mixdown_draw_check_prop, '\0');
00529 }
00530 #endif // WITH_AUDASPACE
00531 
00532 static void SOUND_OT_mixdown(wmOperatorType *ot)
00533 {
00534 #ifdef WITH_AUDASPACE
00535     static EnumPropertyItem format_items[] = {
00536         {AUD_FORMAT_U8, "U8", 0, "U8", "8 bit unsigned"},
00537         {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
00538         {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"},
00539         {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"},
00540         {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"},
00541         {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64 bit floating point"},
00542         {0, NULL, 0, NULL, NULL}};
00543 
00544     static EnumPropertyItem container_items[] = {
00545 #ifdef WITH_FFMPEG
00546         {AUD_CONTAINER_AC3, "AC3", 0, "ac3", "Dolby Digital ATRAC 3"},
00547 #endif
00548         {AUD_CONTAINER_FLAC, "FLAC", 0, "flac", "Free Lossless Audio Codec"},
00549 #ifdef WITH_FFMPEG
00550         {AUD_CONTAINER_MATROSKA, "MATROSKA", 0, "mkv", "Matroska"},
00551         {AUD_CONTAINER_MP2, "MP2", 0, "mp2", "MPEG-1 Audio Layer II"},
00552         {AUD_CONTAINER_MP3, "MP3", 0, "mp3", "MPEG-2 Audio Layer III"},
00553 #endif
00554         {AUD_CONTAINER_OGG, "OGG", 0, "ogg", "Xiph.Org Ogg Container"},
00555         {AUD_CONTAINER_WAV, "WAV", 0, "wav", "Waveform Audio File Format"},
00556         {0, NULL, 0, NULL, NULL}};
00557 
00558     static EnumPropertyItem codec_items[] = {
00559 #ifdef WITH_FFMPEG
00560         {AUD_CODEC_AAC, "AAC", 0, "AAC", "Advanced Audio Coding"},
00561         {AUD_CODEC_AC3, "AC3", 0, "AC3", "Dolby Digital ATRAC 3"},
00562 #endif
00563         {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
00564 #ifdef WITH_FFMPEG
00565         {AUD_CODEC_MP2, "MP2", 0, "MP2", "MPEG-1 Audio Layer II"},
00566         {AUD_CODEC_MP3, "MP3", 0, "MP3", "MPEG-2 Audio Layer III"},
00567 #endif
00568         {AUD_CODEC_PCM, "PCM", 0, "PCM", "Pulse Code Modulation (RAW)"},
00569         {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
00570         {0, NULL, 0, NULL, NULL}};
00571 
00572 #endif // WITH_AUDASPACE
00573 
00574     /* identifiers */
00575     ot->name= "Mixdown";
00576     ot->description= "Mixes the scene's audio to a sound file";
00577     ot->idname= "SOUND_OT_mixdown";
00578 
00579     /* api callbacks */
00580     ot->exec= sound_mixdown_exec;
00581     ot->invoke= sound_mixdown_invoke;
00582 
00583 #ifdef WITH_AUDASPACE
00584     ot->ui= sound_mixdown_draw;
00585 #endif
00586     /* flags */
00587     ot->flag= OPTYPE_REGISTER;
00588 
00589     /* properties */
00590     WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH);
00591 #ifdef WITH_AUDASPACE
00592     RNA_def_int(ot->srna, "accuracy", 1024, 1, 16777216, "Accuracy", "Sample accuracy, important for animation data (the lower the value, the more accurate)", 1, 16777216);
00593     RNA_def_enum(ot->srna, "container", container_items, AUD_CONTAINER_FLAC, "Container", "File format");
00594     RNA_def_enum(ot->srna, "codec", codec_items, AUD_CODEC_FLAC, "Codec", "Audio Codec");
00595     RNA_def_enum(ot->srna, "format", format_items, AUD_FORMAT_S16, "Format", "Sample format");
00596     RNA_def_int(ot->srna, "bitrate", 192, 32, 512, "Bitrate", "Bitrate in kbit/s", 32, 512);
00597 #endif // WITH_AUDASPACE
00598 }
00599 
00600 /* ******************************************************* */
00601 
00602 static int sound_poll(bContext *C)
00603 {
00604     Editing* ed = CTX_data_scene(C)->ed;
00605 
00606     if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND)
00607         return 0;
00608 
00609     return 1;
00610 }
00611 /********************* pack operator *********************/
00612 
00613 static int sound_pack_exec(bContext *C, wmOperator *op)
00614 {
00615     Main *bmain= CTX_data_main(C);
00616     Editing* ed = CTX_data_scene(C)->ed;
00617     bSound* sound;
00618 
00619     if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND)
00620         return OPERATOR_CANCELLED;
00621 
00622     sound = ed->act_seq->sound;
00623 
00624     if(!sound || sound->packedfile)
00625         return OPERATOR_CANCELLED;
00626 
00627     sound->packedfile= newPackedFile(op->reports, sound->name, ID_BLEND_PATH(bmain, &sound->id));
00628     sound_load(CTX_data_main(C), sound);
00629 
00630     return OPERATOR_FINISHED;
00631 }
00632 
00633 static void SOUND_OT_pack(wmOperatorType *ot)
00634 {
00635     /* identifiers */
00636     ot->name= "Pack Sound";
00637     ot->description= "Pack the sound into the current blend file";
00638     ot->idname= "SOUND_OT_pack";
00639 
00640     /* api callbacks */
00641     ot->exec= sound_pack_exec;
00642     ot->poll= sound_poll;
00643 
00644     /* flags */
00645     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00646 }
00647 
00648 /********************* unpack operator *********************/
00649 
00650 static int sound_unpack_exec(bContext *C, wmOperator *op)
00651 {
00652     int method= RNA_enum_get(op->ptr, "method");
00653     bSound* sound= NULL;
00654 
00655     /* find the suppplied image by name */
00656     if (RNA_struct_property_is_set(op->ptr, "id")) {
00657         char sndname[MAX_ID_NAME-2];
00658         RNA_string_get(op->ptr, "id", sndname);
00659         sound = BLI_findstring(&CTX_data_main(C)->sound, sndname, offsetof(ID, name) + 2);
00660     }
00661 
00662     if(!sound || !sound->packedfile)
00663         return OPERATOR_CANCELLED;
00664 
00665     if(G.fileflags & G_AUTOPACK)
00666         BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save");
00667 
00668     unpackSound(CTX_data_main(C), op->reports, sound, method);
00669 
00670     return OPERATOR_FINISHED;
00671 }
00672 
00673 static int sound_unpack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00674 {
00675     Editing* ed = CTX_data_scene(C)->ed;
00676     bSound* sound;
00677 
00678     if(RNA_struct_property_is_set(op->ptr, "id"))
00679         return sound_unpack_exec(C, op);
00680 
00681     if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND)
00682         return OPERATOR_CANCELLED;
00683 
00684     sound = ed->act_seq->sound;
00685 
00686     if(!sound || !sound->packedfile)
00687         return OPERATOR_CANCELLED;
00688 
00689     if(G.fileflags & G_AUTOPACK)
00690         BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save");
00691 
00692     unpack_menu(C, "SOUND_OT_unpack", sound->id.name+2, sound->name, "sounds", sound->packedfile);
00693 
00694     return OPERATOR_FINISHED;
00695 }
00696 
00697 static void SOUND_OT_unpack(wmOperatorType *ot)
00698 {
00699     /* identifiers */
00700     ot->name= "Unpack Sound";
00701     ot->description= "Unpack the sound to the samples filename";
00702     ot->idname= "SOUND_OT_unpack";
00703 
00704     /* api callbacks */
00705     ot->exec= sound_unpack_exec;
00706     ot->invoke= sound_unpack_invoke;
00707     ot->poll= sound_poll;
00708 
00709     /* flags */
00710     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00711 
00712     /* properties */
00713     RNA_def_enum(ot->srna, "method", unpack_method_items, PF_USE_LOCAL, "Method", "How to unpack");
00714     RNA_def_string(ot->srna, "id", "", MAX_ID_NAME-2, "Sound Name", "Sound datablock name to unpack"); /* XXX, weark!, will fail with library, name collisions */
00715 }
00716 
00717 /* ******************************************************* */
00718 
00719 void ED_operatortypes_sound(void)
00720 {
00721     WM_operatortype_append(SOUND_OT_open);
00722     WM_operatortype_append(SOUND_OT_open_mono);
00723     WM_operatortype_append(SOUND_OT_mixdown);
00724     WM_operatortype_append(SOUND_OT_pack);
00725     WM_operatortype_append(SOUND_OT_unpack);
00726     WM_operatortype_append(SOUND_OT_update_animation_flags);
00727     WM_operatortype_append(SOUND_OT_bake_animation);
00728 }