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