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