Merge branch 'blender2.7'
[blender.git] / source / blender / editors / sound / sound_ops.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2007 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file \ingroup edsnd
21  */
22
23
24 #include <string.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <stddef.h>
28
29 #include "MEM_guardedalloc.h"
30
31 #include "BLI_blenlib.h"
32 #include "BLI_utildefines.h"
33
34 #include "DNA_packedFile_types.h"
35 #include "DNA_scene_types.h"
36 #include "DNA_space_types.h"
37 #include "DNA_sequence_types.h"
38 #include "DNA_sound_types.h"
39 #include "DNA_userdef_types.h"
40
41 #include "BKE_context.h"
42 #include "BKE_fcurve.h"
43 #include "BKE_global.h"
44 #include "BKE_library.h"
45 #include "BKE_main.h"
46 #include "BKE_packedFile.h"
47 #include "BKE_report.h"
48 #include "BKE_scene.h"
49 #include "BKE_sequencer.h"
50 #include "BKE_sound.h"
51
52 #include "RNA_access.h"
53 #include "RNA_define.h"
54 #include "RNA_enum_types.h"
55
56 #include "UI_interface.h"
57
58 #include "WM_api.h"
59 #include "WM_types.h"
60
61 #ifdef WITH_AUDASPACE
62 #  include <AUD_Special.h>
63 #endif
64
65 #include "ED_sound.h"
66 #include "ED_util.h"
67
68
69 /******************** open sound operator ********************/
70
71 static void sound_open_cancel(bContext *UNUSED(C), wmOperator *op)
72 {
73         MEM_freeN(op->customdata);
74         op->customdata = NULL;
75 }
76
77 static void sound_open_init(bContext *C, wmOperator *op)
78 {
79         PropertyPointerRNA *pprop;
80
81         op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
82         UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop);
83 }
84
85 #ifdef WITH_AUDASPACE
86 static int sound_open_exec(bContext *C, wmOperator *op)
87 {
88         char path[FILE_MAX];
89         bSound *sound;
90         PropertyPointerRNA *pprop;
91         PointerRNA idptr;
92         AUD_SoundInfo info;
93         Main *bmain = CTX_data_main(C);
94
95         RNA_string_get(op->ptr, "filepath", path);
96         sound = BKE_sound_new_file(bmain, path);
97
98         if (!op->customdata)
99                 sound_open_init(C, op);
100
101         if (sound->playback_handle == NULL) {
102                 if (op->customdata) MEM_freeN(op->customdata);
103                 BKE_id_free(bmain, sound);
104                 BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
105                 return OPERATOR_CANCELLED;
106         }
107
108         info = AUD_getInfo(sound->playback_handle);
109
110         if (info.specs.channels == AUD_CHANNELS_INVALID) {
111                 BKE_id_free(bmain, sound);
112                 if (op->customdata) MEM_freeN(op->customdata);
113                 BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
114                 return OPERATOR_CANCELLED;
115         }
116
117         if (RNA_boolean_get(op->ptr, "mono")) {
118                 sound->flags |= SOUND_FLAGS_MONO;
119                 BKE_sound_load(bmain, sound);
120         }
121
122         if (RNA_boolean_get(op->ptr, "cache")) {
123                 BKE_sound_cache(sound);
124         }
125
126         /* hook into UI */
127         pprop = op->customdata;
128
129         if (pprop->prop) {
130                 /* when creating new ID blocks, use is already 1, but RNA
131                  * pointer use also increases user, so this compensates it */
132                 id_us_min(&sound->id);
133
134                 RNA_id_pointer_create(&sound->id, &idptr);
135                 RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
136                 RNA_property_update(C, &pprop->ptr, pprop->prop);
137         }
138
139         MEM_freeN(op->customdata);
140         return OPERATOR_FINISHED;
141 }
142
143 #else //WITH_AUDASPACE
144
145 static int sound_open_exec(bContext *UNUSED(C), wmOperator *op)
146 {
147         BKE_report(op->reports, RPT_ERROR, "Compiled without sound support");
148
149         return OPERATOR_CANCELLED;
150 }
151
152 #endif
153
154 static int sound_open_invoke(bContext *C, wmOperator *op, const wmEvent *event)
155 {
156         if (RNA_struct_property_is_set(op->ptr, "filepath"))
157                 return sound_open_exec(C, op);
158
159         sound_open_init(C, op);
160
161         return WM_operator_filesel(C, op, event);
162 }
163
164 static void SOUND_OT_open(wmOperatorType *ot)
165 {
166         /* identifiers */
167         ot->name = "Open Sound";
168         ot->description = "Load a sound file";
169         ot->idname = "SOUND_OT_open";
170
171         /* api callbacks */
172         ot->exec = sound_open_exec;
173         ot->invoke = sound_open_invoke;
174         ot->cancel = sound_open_cancel;
175
176         /* flags */
177         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
178
179         /* properties */
180         WM_operator_properties_filesel(
181                 ot, FILE_TYPE_FOLDER | FILE_TYPE_SOUND | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
182                 WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
183         RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
184         RNA_def_boolean(ot->srna, "mono", false, "Mono", "Merge all the sound's channels into one");
185 }
186
187 static void SOUND_OT_open_mono(wmOperatorType *ot)
188 {
189         /* identifiers */
190         ot->name = "Open Sound Mono";
191         ot->description = "Load a sound file as mono";
192         ot->idname = "SOUND_OT_open_mono";
193
194         /* api callbacks */
195         ot->exec = sound_open_exec;
196         ot->invoke = sound_open_invoke;
197         ot->cancel = sound_open_cancel;
198
199         /* flags */
200         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
201
202         /* properties */
203         WM_operator_properties_filesel(
204                 ot, FILE_TYPE_FOLDER | FILE_TYPE_SOUND | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
205                 WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
206         RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
207         RNA_def_boolean(ot->srna, "mono", true, "Mono", "Mixdown the sound to mono");
208 }
209
210 /* ******************************************************* */
211
212 static void sound_update_animation_flags(Scene *scene);
213
214 static int sound_update_animation_flags_cb(Sequence *seq, void *user_data)
215 {
216         struct FCurve *fcu;
217         Scene *scene = (Scene *)user_data;
218         bool driven;
219
220         fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, &driven);
221         if (fcu || driven)
222                 seq->flag |= SEQ_AUDIO_VOLUME_ANIMATED;
223         else
224                 seq->flag &= ~SEQ_AUDIO_VOLUME_ANIMATED;
225
226         fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pitch", 0, &driven);
227         if (fcu || driven)
228                 seq->flag |= SEQ_AUDIO_PITCH_ANIMATED;
229         else
230                 seq->flag &= ~SEQ_AUDIO_PITCH_ANIMATED;
231
232         fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pan", 0, &driven);
233         if (fcu || driven)
234                 seq->flag |= SEQ_AUDIO_PAN_ANIMATED;
235         else
236                 seq->flag &= ~SEQ_AUDIO_PAN_ANIMATED;
237
238         if (seq->type == SEQ_TYPE_SCENE) {
239                 /* TODO(sergey): For now we do manual recursion into the scene strips,
240                  * but perhaps it should be covered by recursive_apply?
241                  */
242                 sound_update_animation_flags(seq->scene);
243         }
244
245         return 0;
246 }
247
248 static void sound_update_animation_flags(Scene *scene)
249 {
250         struct FCurve *fcu;
251         bool driven;
252         Sequence *seq;
253
254         if (scene->id.tag & LIB_TAG_DOIT) {
255                 return;
256         }
257         scene->id.tag |= LIB_TAG_DOIT;
258
259         SEQ_BEGIN(scene->ed, seq)
260         {
261                 BKE_sequencer_recursive_apply(seq, sound_update_animation_flags_cb, scene);
262         } SEQ_END;
263
264         fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven);
265         if (fcu || driven)
266                 scene->audio.flag |= AUDIO_VOLUME_ANIMATED;
267         else
268                 scene->audio.flag &= ~AUDIO_VOLUME_ANIMATED;
269 }
270
271 static int sound_update_animation_flags_exec(bContext *C, wmOperator *UNUSED(op))
272 {
273         BKE_main_id_tag_idcode(CTX_data_main(C), ID_SCE, LIB_TAG_DOIT, false);
274         sound_update_animation_flags(CTX_data_scene(C));
275         return OPERATOR_FINISHED;
276 }
277
278 static void SOUND_OT_update_animation_flags(wmOperatorType *ot)
279 {
280         /*
281          * This operator is needed to set a correct state of the sound animation
282          * System. Unfortunately there's no really correct place to call the exec
283          * function, that's why I made it an operator that's only visible in the
284          * search menu. Apart from that the bake animation operator calls it too.
285          */
286
287         /* identifiers */
288         ot->name = "Update Animation";
289         ot->description = "Update animation flags";
290         ot->idname = "SOUND_OT_update_animation_flags";
291
292         /* api callbacks */
293         ot->exec = sound_update_animation_flags_exec;
294
295         /* flags */
296         ot->flag = OPTYPE_REGISTER;
297 }
298
299 /* ******************************************************* */
300
301 static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op))
302 {
303         Main *bmain = CTX_data_main(C);
304         Scene *scene = CTX_data_scene(C);
305         struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
306         int oldfra = scene->r.cfra;
307         int cfra;
308
309         sound_update_animation_flags_exec(C, NULL);
310
311         for (cfra = (scene->r.sfra > 0) ? (scene->r.sfra - 1) : 0; cfra <= scene->r.efra + 1; cfra++) {
312                 scene->r.cfra = cfra;
313                 BKE_scene_graph_update_for_newframe(depsgraph, bmain);
314         }
315
316         scene->r.cfra = oldfra;
317         BKE_scene_graph_update_for_newframe(depsgraph, bmain);
318
319         return OPERATOR_FINISHED;
320 }
321
322 static void SOUND_OT_bake_animation(wmOperatorType *ot)
323 {
324         /* identifiers */
325         ot->name = "Update Animation Cache";
326         ot->description = "Update the audio animation cache";
327         ot->idname = "SOUND_OT_bake_animation";
328
329         /* api callbacks */
330         ot->exec = sound_bake_animation_exec;
331
332         /* flags */
333         ot->flag = OPTYPE_REGISTER;
334 }
335
336
337 /******************** mixdown operator ********************/
338
339 static int sound_mixdown_exec(bContext *C, wmOperator *op)
340 {
341 #ifdef WITH_AUDASPACE
342         char path[FILE_MAX];
343         char filename[FILE_MAX];
344         Scene *scene;
345         Main *bmain;
346         int split;
347
348         int bitrate, accuracy;
349         AUD_DeviceSpecs specs;
350         AUD_Container container;
351         AUD_Codec codec;
352         const char *result;
353
354         sound_bake_animation_exec(C, op);
355
356         RNA_string_get(op->ptr, "filepath", path);
357         bitrate = RNA_int_get(op->ptr, "bitrate") * 1000;
358         accuracy = RNA_int_get(op->ptr, "accuracy");
359         specs.format = RNA_enum_get(op->ptr, "format");
360         container = RNA_enum_get(op->ptr, "container");
361         codec = RNA_enum_get(op->ptr, "codec");
362         split = RNA_boolean_get(op->ptr, "split_channels");
363         scene = CTX_data_scene(C);
364         bmain = CTX_data_main(C);
365         specs.channels = scene->r.ffcodecdata.audio_channels;
366         specs.rate = scene->r.ffcodecdata.audio_mixrate;
367
368         BLI_strncpy(filename, path, sizeof(filename));
369         BLI_path_abs(filename, BKE_main_blendfile_path(bmain));
370
371         if (split)
372                 result = AUD_mixdown_per_channel(scene->sound_scene, SFRA * specs.rate / FPS, (EFRA - SFRA + 1) * specs.rate / FPS,
373                                                  accuracy, filename, specs, container, codec, bitrate);
374         else
375                 result = AUD_mixdown(scene->sound_scene, SFRA * specs.rate / FPS, (EFRA - SFRA + 1) * specs.rate / FPS,
376                                      accuracy, filename, specs, container, codec, bitrate);
377
378         BKE_sound_reset_scene_specs(scene);
379
380         if (result) {
381                 BKE_report(op->reports, RPT_ERROR, result);
382                 return OPERATOR_CANCELLED;
383         }
384 #else // WITH_AUDASPACE
385         (void)C;
386         (void)op;
387 #endif // WITH_AUDASPACE
388         return OPERATOR_FINISHED;
389 }
390
391 #ifdef WITH_AUDASPACE
392 static const EnumPropertyItem container_items[] = {
393 #ifdef WITH_FFMPEG
394         {AUD_CONTAINER_AC3, "AC3", 0, "ac3", "Dolby Digital ATRAC 3"},
395 #endif
396         {AUD_CONTAINER_FLAC, "FLAC", 0, "flac", "Free Lossless Audio Codec"},
397 #ifdef WITH_FFMPEG
398         {AUD_CONTAINER_MATROSKA, "MATROSKA", 0, "mkv", "Matroska"},
399         {AUD_CONTAINER_MP2, "MP2", 0, "mp2", "MPEG-1 Audio Layer II"},
400         {AUD_CONTAINER_MP3, "MP3", 0, "mp3", "MPEG-2 Audio Layer III"},
401 #endif
402         {AUD_CONTAINER_OGG, "OGG", 0, "ogg", "Xiph.Org Ogg Container"},
403         {AUD_CONTAINER_WAV, "WAV", 0, "wav", "Waveform Audio File Format"},
404         {0, NULL, 0, NULL, NULL},
405 };
406
407 static const char *snd_ext_sound[] = {
408         ".ac3",
409         ".flac",
410         ".mkv",
411         ".mp2",
412         ".mp3",
413         ".ogg",
414         ".wav",
415         NULL,
416 };
417
418 static bool sound_mixdown_check(bContext *UNUSED(C), wmOperator *op)
419 {
420         AUD_Container container = RNA_enum_get(op->ptr, "container");
421
422         const char *extension = NULL;
423
424         const EnumPropertyItem *item = container_items;
425         while (item->identifier != NULL) {
426                 if (item->value == container) {
427                         const char **ext = snd_ext_sound;
428                         while (*ext != NULL) {
429                                 if (STREQ(*ext + 1, item->name)) {
430                                         extension = *ext;
431                                         break;
432                                 }
433
434                                 ext++;
435                         }
436                 }
437                 item++;
438         }
439
440         if (extension) {
441                 PropertyRNA *prop;
442                 char filepath[FILE_MAX];
443
444                 int check;
445
446                 prop = RNA_struct_find_property(op->ptr, "filepath");
447                 RNA_property_string_get(op->ptr, prop, filepath);
448
449                 if (BLI_path_extension_check_array(filepath, snd_ext_sound))
450                         check = BLI_path_extension_replace(filepath, FILE_MAX, extension);
451                 else
452                         check = BLI_path_extension_ensure(filepath, FILE_MAX, extension);
453
454                 if (!check)
455                         return check;
456
457                 RNA_property_string_set(op->ptr, prop, filepath);
458                 return true;
459         }
460
461         return false;
462 }
463
464 #endif // WITH_AUDASPACE
465
466 static int sound_mixdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
467 {
468         if (RNA_struct_property_is_set(op->ptr, "filepath"))
469                 return sound_mixdown_exec(C, op);
470
471         return WM_operator_filesel(C, op, event);
472 }
473
474 #ifdef WITH_AUDASPACE
475
476 static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
477 {
478         const char *prop_id = RNA_property_identifier(prop);
479         return !(STREQ(prop_id, "filepath") ||
480                  STREQ(prop_id, "directory") ||
481                  STREQ(prop_id, "filename"));
482 }
483
484 static void sound_mixdown_draw(bContext *C, wmOperator *op)
485 {
486         static const EnumPropertyItem pcm_format_items[] = {
487                 {AUD_FORMAT_U8, "U8", 0, "U8", "8 bit unsigned"},
488                 {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
489 #ifdef WITH_SNDFILE
490                 {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"},
491 #endif
492                 {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"},
493                 {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"},
494                 {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64 bit floating point"},
495                 {0, NULL, 0, NULL, NULL},
496         };
497
498         static const EnumPropertyItem mp3_format_items[] = {
499                 {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
500                 {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"},
501                 {0, NULL, 0, NULL, NULL},
502         };
503
504 #ifdef WITH_SNDFILE
505         static const EnumPropertyItem flac_format_items[] = {
506                 {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
507                 {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"},
508                 {0, NULL, 0, NULL, NULL},
509         };
510 #endif
511
512         static const EnumPropertyItem all_codec_items[] = {
513                 {AUD_CODEC_AAC, "AAC", 0, "AAC", "Advanced Audio Coding"},
514                 {AUD_CODEC_AC3, "AC3", 0, "AC3", "Dolby Digital ATRAC 3"},
515                 {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
516                 {AUD_CODEC_MP2, "MP2", 0, "MP2", "MPEG-1 Audio Layer II"},
517                 {AUD_CODEC_MP3, "MP3", 0, "MP3", "MPEG-2 Audio Layer III"},
518                 {AUD_CODEC_PCM, "PCM", 0, "PCM", "Pulse Code Modulation (RAW)"},
519                 {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
520                 {0, NULL, 0, NULL, NULL},
521         };
522
523         static const EnumPropertyItem ogg_codec_items[] = {
524                 {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
525                 {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
526                 {0, NULL, 0, NULL, NULL},
527         };
528
529         uiLayout *layout = op->layout;
530         wmWindowManager *wm = CTX_wm_manager(C);
531         PointerRNA ptr;
532         PropertyRNA *prop_format;
533         PropertyRNA *prop_codec;
534         PropertyRNA *prop_bitrate;
535
536         AUD_Container container = RNA_enum_get(op->ptr, "container");
537         AUD_Codec codec = RNA_enum_get(op->ptr, "codec");
538
539         prop_format = RNA_struct_find_property(op->ptr, "format");
540         prop_codec = RNA_struct_find_property(op->ptr, "codec");
541         prop_bitrate = RNA_struct_find_property(op->ptr, "bitrate");
542
543         RNA_def_property_clear_flag(prop_bitrate, PROP_HIDDEN);
544         RNA_def_property_flag(prop_codec, PROP_HIDDEN);
545         RNA_def_property_flag(prop_format, PROP_HIDDEN);
546
547         switch (container) {
548                 case AUD_CONTAINER_AC3:
549                         RNA_def_property_enum_items(prop_codec, all_codec_items);
550                         RNA_enum_set(op->ptr, "codec", AUD_CODEC_AC3);
551                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_FLOAT32);
552                         break;
553                 case AUD_CONTAINER_FLAC:
554                         RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
555                         RNA_def_property_enum_items(prop_codec, all_codec_items);
556                         RNA_enum_set(op->ptr, "codec", AUD_CODEC_FLAC);
557 #ifdef WITH_SNDFILE
558                         RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
559                         RNA_def_property_enum_items(prop_format, flac_format_items);
560 #else
561                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
562 #endif
563                         break;
564                 case AUD_CONTAINER_MATROSKA:
565                         RNA_def_property_clear_flag(prop_codec, PROP_HIDDEN);
566                         RNA_def_property_enum_items(prop_codec, all_codec_items);
567
568                         switch (codec) {
569                                 case AUD_CODEC_AAC:
570                                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
571                                         break;
572                                 case AUD_CODEC_AC3:
573                                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_FLOAT32);
574                                         break;
575                                 case AUD_CODEC_FLAC:
576                                         RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
577                                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
578                                         break;
579                                 case AUD_CODEC_MP2:
580                                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
581                                         break;
582                                 case AUD_CODEC_MP3:
583                                         RNA_def_property_enum_items(prop_format, mp3_format_items);
584                                         RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
585                                         break;
586                                 case AUD_CODEC_PCM:
587                                         RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
588                                         RNA_def_property_enum_items(prop_format, pcm_format_items);
589                                         RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
590                                         break;
591                                 case AUD_CODEC_VORBIS:
592                                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
593                                         break;
594                                 default:
595                                         break;
596                         }
597
598                         break;
599                 case AUD_CONTAINER_MP2:
600                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
601                         RNA_enum_set(op->ptr, "codec", AUD_CODEC_MP2);
602                         RNA_def_property_enum_items(prop_codec, all_codec_items);
603                         break;
604                 case AUD_CONTAINER_MP3:
605                         RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
606                         RNA_def_property_enum_items(prop_format, mp3_format_items);
607                         RNA_def_property_enum_items(prop_codec, all_codec_items);
608                         RNA_enum_set(op->ptr, "codec", AUD_CODEC_MP3);
609                         break;
610                 case AUD_CONTAINER_OGG:
611                         RNA_def_property_clear_flag(prop_codec, PROP_HIDDEN);
612                         RNA_def_property_enum_items(prop_codec, ogg_codec_items);
613                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
614                         break;
615                 case AUD_CONTAINER_WAV:
616                         RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
617                         RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
618                         RNA_def_property_enum_items(prop_format, pcm_format_items);
619                         RNA_def_property_enum_items(prop_codec, all_codec_items);
620                         RNA_enum_set(op->ptr, "codec", AUD_CODEC_PCM);
621                         break;
622                 default:
623                         break;
624         }
625
626         RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
627
628         /* main draw call */
629         uiDefAutoButsRNA(layout, &ptr, sound_mixdown_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
630 }
631 #endif // WITH_AUDASPACE
632
633 static void SOUND_OT_mixdown(wmOperatorType *ot)
634 {
635 #ifdef WITH_AUDASPACE
636         static const EnumPropertyItem format_items[] = {
637                 {AUD_FORMAT_U8, "U8", 0, "U8", "8 bit unsigned"},
638                 {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
639                 {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"},
640                 {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"},
641                 {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"},
642                 {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64 bit floating point"},
643                 {0, NULL, 0, NULL, NULL},
644         };
645
646         static const EnumPropertyItem codec_items[] = {
647 #ifdef WITH_FFMPEG
648                 {AUD_CODEC_AAC, "AAC", 0, "AAC", "Advanced Audio Coding"},
649                 {AUD_CODEC_AC3, "AC3", 0, "AC3", "Dolby Digital ATRAC 3"},
650 #endif
651                 {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
652 #ifdef WITH_FFMPEG
653                 {AUD_CODEC_MP2, "MP2", 0, "MP2", "MPEG-1 Audio Layer II"},
654                 {AUD_CODEC_MP3, "MP3", 0, "MP3", "MPEG-2 Audio Layer III"},
655 #endif
656                 {AUD_CODEC_PCM, "PCM", 0, "PCM", "Pulse Code Modulation (RAW)"},
657                 {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
658                 {0, NULL, 0, NULL, NULL},
659         };
660
661 #endif // WITH_AUDASPACE
662
663         /* identifiers */
664         ot->name = "Mixdown";
665         ot->description = "Mix the scene's audio to a sound file";
666         ot->idname = "SOUND_OT_mixdown";
667
668         /* api callbacks */
669         ot->exec = sound_mixdown_exec;
670         ot->invoke = sound_mixdown_invoke;
671
672 #ifdef WITH_AUDASPACE
673         ot->check = sound_mixdown_check;
674         ot->ui = sound_mixdown_draw;
675 #endif
676         /* flags */
677         ot->flag = OPTYPE_REGISTER;
678
679         /* properties */
680         WM_operator_properties_filesel(
681                 ot, FILE_TYPE_FOLDER | FILE_TYPE_SOUND, FILE_SPECIAL, FILE_SAVE,
682                 WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
683 #ifdef WITH_AUDASPACE
684         RNA_def_int(ot->srna, "accuracy", 1024, 1, 16777216, "Accuracy",
685                     "Sample accuracy, important for animation data (the lower the value, the more accurate)",
686                     1, 16777216);
687         RNA_def_enum(ot->srna, "container", container_items, AUD_CONTAINER_FLAC, "Container", "File format");
688         RNA_def_enum(ot->srna, "codec", codec_items, AUD_CODEC_FLAC, "Codec", "Audio Codec");
689         RNA_def_enum(ot->srna, "format", format_items, AUD_FORMAT_S16, "Format", "Sample format");
690         RNA_def_int(ot->srna, "bitrate", 192, 32, 512, "Bitrate", "Bitrate in kbit/s", 32, 512);
691         RNA_def_boolean(ot->srna, "split_channels", 0, "Split channels", "Each channel will be rendered into a mono file");
692 #endif // WITH_AUDASPACE
693 }
694
695 /* ******************************************************* */
696
697 static bool sound_poll(bContext *C)
698 {
699         Editing *ed = CTX_data_scene(C)->ed;
700
701         if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM)
702                 return 0;
703
704         return 1;
705 }
706 /********************* pack operator *********************/
707
708 static int sound_pack_exec(bContext *C, wmOperator *op)
709 {
710         Main *bmain = CTX_data_main(C);
711         Editing *ed = CTX_data_scene(C)->ed;
712         bSound *sound;
713
714         if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM)
715                 return OPERATOR_CANCELLED;
716
717         sound = ed->act_seq->sound;
718
719         if (!sound || sound->packedfile)
720                 return OPERATOR_CANCELLED;
721
722         sound->packedfile = newPackedFile(op->reports, sound->name, ID_BLEND_PATH(bmain, &sound->id));
723         BKE_sound_load(bmain, sound);
724
725         return OPERATOR_FINISHED;
726 }
727
728 static void SOUND_OT_pack(wmOperatorType *ot)
729 {
730         /* identifiers */
731         ot->name = "Pack Sound";
732         ot->description = "Pack the sound into the current blend file";
733         ot->idname = "SOUND_OT_pack";
734
735         /* api callbacks */
736         ot->exec = sound_pack_exec;
737         ot->poll = sound_poll;
738
739         /* flags */
740         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
741 }
742
743 /********************* unpack operator *********************/
744
745 static int sound_unpack_exec(bContext *C, wmOperator *op)
746 {
747         Main *bmain = CTX_data_main(C);
748         int method = RNA_enum_get(op->ptr, "method");
749         bSound *sound = NULL;
750
751         /* find the suppplied image by name */
752         if (RNA_struct_property_is_set(op->ptr, "id")) {
753                 char sndname[MAX_ID_NAME - 2];
754                 RNA_string_get(op->ptr, "id", sndname);
755                 sound = BLI_findstring(&bmain->sound, sndname, offsetof(ID, name) + 2);
756         }
757
758         if (!sound || !sound->packedfile)
759                 return OPERATOR_CANCELLED;
760
761         if (G.fileflags & G_FILE_AUTOPACK)
762                 BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save");
763
764         unpackSound(bmain, op->reports, sound, method);
765
766         return OPERATOR_FINISHED;
767 }
768
769 static int sound_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
770 {
771         Editing *ed = CTX_data_scene(C)->ed;
772         bSound *sound;
773
774         if (RNA_struct_property_is_set(op->ptr, "id"))
775                 return sound_unpack_exec(C, op);
776
777         if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM)
778                 return OPERATOR_CANCELLED;
779
780         sound = ed->act_seq->sound;
781
782         if (!sound || !sound->packedfile)
783                 return OPERATOR_CANCELLED;
784
785         if (G.fileflags & G_FILE_AUTOPACK)
786                 BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save");
787
788         unpack_menu(C, "SOUND_OT_unpack", sound->id.name + 2, sound->name, "sounds", sound->packedfile);
789
790         return OPERATOR_FINISHED;
791 }
792
793 static void SOUND_OT_unpack(wmOperatorType *ot)
794 {
795         /* identifiers */
796         ot->name = "Unpack Sound";
797         ot->description = "Unpack the sound to the samples filename";
798         ot->idname = "SOUND_OT_unpack";
799
800         /* api callbacks */
801         ot->exec = sound_unpack_exec;
802         ot->invoke = sound_unpack_invoke;
803         ot->poll = sound_poll;
804
805         /* flags */
806         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
807
808         /* properties */
809         RNA_def_enum(ot->srna, "method", rna_enum_unpack_method_items, PF_USE_LOCAL, "Method", "How to unpack");
810         /* XXX, weark!, will fail with library, name collisions */
811         RNA_def_string(ot->srna, "id", NULL, MAX_ID_NAME - 2, "Sound Name", "Sound data-block name to unpack");
812 }
813
814 /* ******************************************************* */
815
816 void ED_operatortypes_sound(void)
817 {
818         WM_operatortype_append(SOUND_OT_open);
819         WM_operatortype_append(SOUND_OT_open_mono);
820         WM_operatortype_append(SOUND_OT_mixdown);
821         WM_operatortype_append(SOUND_OT_pack);
822         WM_operatortype_append(SOUND_OT_unpack);
823         WM_operatortype_append(SOUND_OT_update_animation_flags);
824         WM_operatortype_append(SOUND_OT_bake_animation);
825 }