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