svn merge ^/trunk/blender -r46300:46330
[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 int sound_open_cancel(bContext *UNUSED(C), wmOperator *op)
81 {
82         MEM_freeN(op->customdata);
83         op->customdata= NULL;
84         return OPERATOR_CANCELLED;
85 }
86
87 static void sound_open_init(bContext *C, wmOperator *op)
88 {
89         PropertyPointerRNA *pprop;
90
91         op->customdata= pprop= MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
92         uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
93 }
94
95 #ifdef WITH_AUDASPACE
96 static int sound_open_exec(bContext *C, wmOperator *op)
97 {
98         char path[FILE_MAX];
99         bSound *sound;
100         PropertyPointerRNA *pprop;
101         PointerRNA idptr;
102         AUD_SoundInfo info;
103         Main *bmain = CTX_data_main(C);
104
105         RNA_string_get(op->ptr, "filepath", path);
106         sound = sound_new_file(bmain, path);
107
108         if (!op->customdata)
109                 sound_open_init(C, op);
110
111         if (sound==NULL || sound->playback_handle == NULL) {
112                 if (op->customdata) MEM_freeN(op->customdata);
113                 BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
114                 return OPERATOR_CANCELLED;
115         }
116
117         info = AUD_getInfo(sound->playback_handle);
118
119         if (info.specs.channels == AUD_CHANNELS_INVALID) {
120                 sound_delete(bmain, sound);
121                 if (op->customdata) MEM_freeN(op->customdata);
122                 BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
123                 return OPERATOR_CANCELLED;
124         }
125
126         if (RNA_boolean_get(op->ptr, "mono")) {
127                 sound->flags |= SOUND_FLAGS_MONO;
128                 sound_load(bmain, sound);
129         }
130
131         if (RNA_boolean_get(op->ptr, "cache")) {
132                 sound_cache(sound);
133         }
134
135         /* hook into UI */
136         pprop= op->customdata;
137
138         if (pprop->prop) {
139                 /* when creating new ID blocks, use is already 1, but RNA
140                  * pointer se also increases user, so this compensates it */
141                 sound->id.us--;
142
143                 RNA_id_pointer_create(&sound->id, &idptr);
144                 RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
145                 RNA_property_update(C, &pprop->ptr, pprop->prop);
146         }
147
148         if (op->customdata) MEM_freeN(op->customdata);
149         return OPERATOR_FINISHED;
150 }
151
152 #else //WITH_AUDASPACE
153
154 static int sound_open_exec(bContext *UNUSED(C), wmOperator *op)
155 {
156         BKE_report(op->reports, RPT_ERROR, "Compiled without sound support");
157
158         return OPERATOR_CANCELLED;
159 }
160
161 #endif
162
163 static int sound_open_invoke(bContext *C, wmOperator *op, wmEvent *event)
164 {
165         if (RNA_struct_property_is_set(op->ptr, "filepath"))
166                 return sound_open_exec(C, op);
167
168         sound_open_init(C, op);
169
170         return WM_operator_filesel(C, op, event);
171 }
172
173 static void SOUND_OT_open(wmOperatorType *ot)
174 {
175         /* identifiers */
176         ot->name = "Open Sound";
177         ot->description = "Load a sound file";
178         ot->idname = "SOUND_OT_open";
179
180         /* api callbacks */
181         ot->exec = sound_open_exec;
182         ot->invoke = sound_open_invoke;
183         ot->cancel = sound_open_cancel;
184
185         /* flags */
186         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
187
188         /* properties */
189         WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, 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, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
211         RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory");
212         RNA_def_boolean(ot->srna, "mono", TRUE, "Mono", "Mixdown the sound to mono");
213 }
214
215 /* ******************************************************* */
216
217 static int sound_update_animation_flags_exec(bContext *C, wmOperator *UNUSED(op))
218 {
219         Sequence* seq;
220         Scene* scene = CTX_data_scene(C);
221         struct FCurve* fcu;
222         char driven;
223
224         SEQ_BEGIN (scene->ed, seq)
225         {
226                 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, &driven);
227                 if (fcu || driven)
228                         seq->flag |= SEQ_AUDIO_VOLUME_ANIMATED;
229                 else
230                         seq->flag &= ~SEQ_AUDIO_VOLUME_ANIMATED;
231
232                 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pitch", 0, &driven);
233                 if (fcu || driven)
234                         seq->flag |= SEQ_AUDIO_PITCH_ANIMATED;
235                 else
236                         seq->flag &= ~SEQ_AUDIO_PITCH_ANIMATED;
237
238                 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pan", 0, &driven);
239                 if (fcu || driven)
240                         seq->flag |= SEQ_AUDIO_PAN_ANIMATED;
241                 else
242                         seq->flag &= ~SEQ_AUDIO_PAN_ANIMATED;
243         }
244         SEQ_END
245
246         fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven);
247         if (fcu || driven)
248                 scene->audio.flag |= AUDIO_VOLUME_ANIMATED;
249         else
250                 scene->audio.flag &= ~AUDIO_VOLUME_ANIMATED;
251
252         return OPERATOR_FINISHED;
253 }
254
255 static void SOUND_OT_update_animation_flags(wmOperatorType *ot)
256 {
257         /*
258          * This operator is needed to set a correct state of the sound animation
259          * System. Unfortunately there's no really correct place to call the exec
260          * function, that's why I made it an operator that's only visible in the
261          * search menu. Apart from that the bake animation operator calls it too.
262          */
263
264         /* identifiers */
265         ot->name = "Update animation";
266         ot->description = "Update animation flags";
267         ot->idname = "SOUND_OT_update_animation_flags";
268
269         /* api callbacks */
270         ot->exec = sound_update_animation_flags_exec;
271
272         /* flags */
273         ot->flag = OPTYPE_REGISTER;
274 }
275
276 /* ******************************************************* */
277
278 static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op))
279 {
280         Main* bmain = CTX_data_main(C);
281         Scene* scene = CTX_data_scene(C);
282         int oldfra = scene->r.cfra;
283         int cfra;
284
285         sound_update_animation_flags_exec(C, NULL);
286
287         for (cfra = (scene->r.sfra > 0) ? (scene->r.sfra - 1) : 0; cfra <= scene->r.efra + 1; cfra++) {
288                 scene->r.cfra = cfra;
289                 BKE_scene_update_for_newframe(bmain, scene, scene->lay);
290         }
291
292         scene->r.cfra = oldfra;
293         BKE_scene_update_for_newframe(bmain, scene, scene->lay);
294
295         return OPERATOR_FINISHED;
296 }
297
298 static void SOUND_OT_bake_animation(wmOperatorType *ot)
299 {
300         /* identifiers */
301         ot->name = "Update animation cache";
302         ot->description = "Update the audio animation cache";
303         ot->idname = "SOUND_OT_bake_animation";
304
305         /* api callbacks */
306         ot->exec = sound_bake_animation_exec;
307
308         /* flags */
309         ot->flag = OPTYPE_REGISTER;
310 }
311
312
313 /******************** mixdown operator ********************/
314
315 static int sound_mixdown_exec(bContext *C, wmOperator *op)
316 {
317 #ifdef WITH_AUDASPACE
318         char path[FILE_MAX];
319         char filename[FILE_MAX];
320         Scene *scene;
321         Main *bmain;
322         int split;
323
324         int bitrate, accuracy;
325         AUD_DeviceSpecs specs;
326         AUD_Container container;
327         AUD_Codec codec;
328         const char* result;
329
330         sound_bake_animation_exec(C, op);
331
332         RNA_string_get(op->ptr, "filepath", path);
333         bitrate = RNA_int_get(op->ptr, "bitrate") * 1000;
334         accuracy = RNA_int_get(op->ptr, "accuracy");
335         specs.format = RNA_enum_get(op->ptr, "format");
336         container = RNA_enum_get(op->ptr, "container");
337         codec = RNA_enum_get(op->ptr, "codec");
338         split = RNA_boolean_get(op->ptr, "split_channels");
339         scene = CTX_data_scene(C);
340         bmain = CTX_data_main(C);
341         specs.channels = scene->r.ffcodecdata.audio_channels;
342         specs.rate = scene->r.ffcodecdata.audio_mixrate;
343
344         BLI_strncpy(filename, path, sizeof(filename));
345         BLI_path_abs(filename, bmain->name);
346
347         if (split)
348                 result = AUD_mixdown_per_channel(scene->sound_scene, SFRA * specs.rate / FPS, (EFRA - SFRA) * specs.rate / FPS,
349                                                  accuracy, filename, specs, container, codec, bitrate);
350         else
351                 result = AUD_mixdown(scene->sound_scene, SFRA * specs.rate / FPS, (EFRA - SFRA) * specs.rate / FPS,
352                                      accuracy, filename, specs, container, codec, bitrate);
353
354         if (result) {
355                 BKE_report(op->reports, RPT_ERROR, result);
356                 return OPERATOR_CANCELLED;
357         }
358 #else // WITH_AUDASPACE
359         (void)C;
360         (void)op;
361 #endif // WITH_AUDASPACE
362         return OPERATOR_FINISHED;
363 }
364
365 static int sound_mixdown_invoke(bContext *C, wmOperator *op, wmEvent *event)
366 {
367         if (RNA_struct_property_is_set(op->ptr, "filepath"))
368                 return sound_mixdown_exec(C, op);
369
370         return WM_operator_filesel(C, op, event);
371 }
372
373 #ifdef WITH_AUDASPACE
374
375 static int sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
376 {
377         const char *prop_id= RNA_property_identifier(prop);
378         return !(       strcmp(prop_id, "filepath") == 0 ||
379                                 strcmp(prop_id, "directory") == 0 ||
380                                 strcmp(prop_id, "filename") == 0
381         );
382 }
383
384 static void sound_mixdown_draw(bContext *C, wmOperator *op)
385 {
386         static EnumPropertyItem pcm_format_items[] = {
387                 {AUD_FORMAT_U8, "U8", 0, "U8", "8 bit unsigned"},
388                 {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
389 #ifdef WITH_SNDFILE
390                 {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"},
391 #endif
392                 {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"},
393                 {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"},
394                 {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64 bit floating point"},
395                 {0, NULL, 0, NULL, NULL}};
396
397         static EnumPropertyItem mp3_format_items[] = {
398                 {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
399                 {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"},
400                 {0, NULL, 0, NULL, NULL}};
401
402         static EnumPropertyItem ac3_format_items[] = {
403                 {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
404                 {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"},
405                 {0, NULL, 0, NULL, NULL}};
406
407 #ifdef WITH_SNDFILE
408         static EnumPropertyItem flac_format_items[] = {
409                 {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
410                 {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"},
411                 {0, NULL, 0, NULL, NULL}};
412 #endif
413
414         static EnumPropertyItem all_codec_items[] = {
415                 {AUD_CODEC_AAC, "AAC", 0, "AAC", "Advanced Audio Coding"},
416                 {AUD_CODEC_AC3, "AC3", 0, "AC3", "Dolby Digital ATRAC 3"},
417                 {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
418                 {AUD_CODEC_MP2, "MP2", 0, "MP2", "MPEG-1 Audio Layer II"},
419                 {AUD_CODEC_MP3, "MP3", 0, "MP3", "MPEG-2 Audio Layer III"},
420                 {AUD_CODEC_PCM, "PCM", 0, "PCM", "Pulse Code Modulation (RAW)"},
421                 {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
422                 {0, NULL, 0, NULL, NULL}};
423
424         static EnumPropertyItem ogg_codec_items[] = {
425                 {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
426                 {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
427                 {0, NULL, 0, NULL, NULL}};
428
429         uiLayout *layout = op->layout;
430         wmWindowManager *wm= CTX_wm_manager(C);
431         PointerRNA ptr;
432         PropertyRNA *prop_format;
433         PropertyRNA *prop_codec;
434         PropertyRNA *prop_bitrate;
435
436         AUD_Container container = RNA_enum_get(op->ptr, "container");
437         AUD_Codec codec = RNA_enum_get(op->ptr, "codec");
438
439         prop_format = RNA_struct_find_property(op->ptr, "format");
440         prop_codec = RNA_struct_find_property(op->ptr, "codec");
441         prop_bitrate = RNA_struct_find_property(op->ptr, "bitrate");
442
443         RNA_def_property_clear_flag(prop_bitrate, PROP_HIDDEN);
444         RNA_def_property_flag(prop_codec, PROP_HIDDEN);
445         RNA_def_property_flag(prop_format, PROP_HIDDEN);
446
447         switch (container) {
448         case AUD_CONTAINER_AC3:
449                 RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
450                 RNA_def_property_enum_items(prop_format, ac3_format_items);
451                 RNA_def_property_enum_items(prop_codec, all_codec_items);
452                 RNA_enum_set(op->ptr, "codec", AUD_CODEC_AC3);
453                 break;
454         case AUD_CONTAINER_FLAC:
455                 RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
456                 RNA_def_property_enum_items(prop_codec, all_codec_items);
457                 RNA_enum_set(op->ptr, "codec", AUD_CODEC_FLAC);
458 #ifdef WITH_SNDFILE
459                 RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
460                 RNA_def_property_enum_items(prop_format, flac_format_items);
461 #else
462                 RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
463 #endif
464                 break;
465         case AUD_CONTAINER_MATROSKA:
466                 RNA_def_property_clear_flag(prop_codec, PROP_HIDDEN);
467                 RNA_def_property_enum_items(prop_codec, all_codec_items);
468
469                 switch (codec) {
470                 case AUD_CODEC_AAC:
471                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
472                         break;
473                 case AUD_CODEC_AC3:
474                         RNA_def_property_enum_items(prop_format, ac3_format_items);
475                         RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
476                         break;
477                 case AUD_CODEC_FLAC:
478                         RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
479                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
480                         break;
481                 case AUD_CODEC_MP2:
482                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
483                         break;
484                 case AUD_CODEC_MP3:
485                         RNA_def_property_enum_items(prop_format, mp3_format_items);
486                         RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
487                         break;
488                 case AUD_CODEC_PCM:
489                         RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
490                         RNA_def_property_enum_items(prop_format, pcm_format_items);
491                         RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
492                         break;
493                 case AUD_CODEC_VORBIS:
494                         RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
495                         break;
496                 default:
497                         break;
498                 }
499
500                 break;
501         case AUD_CONTAINER_MP2:
502                 RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
503                 RNA_enum_set(op->ptr, "codec", AUD_CODEC_MP2);
504                 RNA_def_property_enum_items(prop_codec, all_codec_items);
505                 break;
506         case AUD_CONTAINER_MP3:
507                 RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
508                 RNA_def_property_enum_items(prop_format, mp3_format_items);
509                 RNA_def_property_enum_items(prop_codec, all_codec_items);
510                 RNA_enum_set(op->ptr, "codec", AUD_CODEC_MP3);
511                 break;
512         case AUD_CONTAINER_OGG:
513                 RNA_def_property_clear_flag(prop_codec, PROP_HIDDEN);
514                 RNA_def_property_enum_items(prop_codec, ogg_codec_items);
515                 RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
516                 break;
517         case AUD_CONTAINER_WAV:
518                 RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
519                 RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
520                 RNA_def_property_enum_items(prop_format, pcm_format_items);
521                 RNA_def_property_enum_items(prop_codec, all_codec_items);
522                 RNA_enum_set(op->ptr, "codec", AUD_CODEC_PCM);
523                 break;
524         default:
525                 break;
526         }
527
528         RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
529
530         /* main draw call */
531         uiDefAutoButsRNA(layout, &ptr, sound_mixdown_draw_check_prop, '\0');
532 }
533 #endif // WITH_AUDASPACE
534
535 static void SOUND_OT_mixdown(wmOperatorType *ot)
536 {
537 #ifdef WITH_AUDASPACE
538         static EnumPropertyItem format_items[] = {
539                 {AUD_FORMAT_U8, "U8", 0, "U8", "8 bit unsigned"},
540                 {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
541                 {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"},
542                 {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"},
543                 {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"},
544                 {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64 bit floating point"},
545                 {0, NULL, 0, NULL, NULL}};
546
547         static EnumPropertyItem container_items[] = {
548 #ifdef WITH_FFMPEG
549                 {AUD_CONTAINER_AC3, "AC3", 0, "ac3", "Dolby Digital ATRAC 3"},
550 #endif
551                 {AUD_CONTAINER_FLAC, "FLAC", 0, "flac", "Free Lossless Audio Codec"},
552 #ifdef WITH_FFMPEG
553                 {AUD_CONTAINER_MATROSKA, "MATROSKA", 0, "mkv", "Matroska"},
554                 {AUD_CONTAINER_MP2, "MP2", 0, "mp2", "MPEG-1 Audio Layer II"},
555                 {AUD_CONTAINER_MP3, "MP3", 0, "mp3", "MPEG-2 Audio Layer III"},
556 #endif
557                 {AUD_CONTAINER_OGG, "OGG", 0, "ogg", "Xiph.Org Ogg Container"},
558                 {AUD_CONTAINER_WAV, "WAV", 0, "wav", "Waveform Audio File Format"},
559                 {0, NULL, 0, NULL, NULL}};
560
561         static EnumPropertyItem codec_items[] = {
562 #ifdef WITH_FFMPEG
563                 {AUD_CODEC_AAC, "AAC", 0, "AAC", "Advanced Audio Coding"},
564                 {AUD_CODEC_AC3, "AC3", 0, "AC3", "Dolby Digital ATRAC 3"},
565 #endif
566                 {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
567 #ifdef WITH_FFMPEG
568                 {AUD_CODEC_MP2, "MP2", 0, "MP2", "MPEG-1 Audio Layer II"},
569                 {AUD_CODEC_MP3, "MP3", 0, "MP3", "MPEG-2 Audio Layer III"},
570 #endif
571                 {AUD_CODEC_PCM, "PCM", 0, "PCM", "Pulse Code Modulation (RAW)"},
572                 {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
573                 {0, NULL, 0, NULL, NULL}};
574
575 #endif // WITH_AUDASPACE
576
577         /* identifiers */
578         ot->name = "Mixdown";
579         ot->description = "Mixes the scene's audio to a sound file";
580         ot->idname = "SOUND_OT_mixdown";
581
582         /* api callbacks */
583         ot->exec = sound_mixdown_exec;
584         ot->invoke = sound_mixdown_invoke;
585
586 #ifdef WITH_AUDASPACE
587         ot->ui = sound_mixdown_draw;
588 #endif
589         /* flags */
590         ot->flag = OPTYPE_REGISTER;
591
592         /* properties */
593         WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
594 #ifdef WITH_AUDASPACE
595         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);
596         RNA_def_enum(ot->srna, "container", container_items, AUD_CONTAINER_FLAC, "Container", "File format");
597         RNA_def_enum(ot->srna, "codec", codec_items, AUD_CODEC_FLAC, "Codec", "Audio Codec");
598         RNA_def_enum(ot->srna, "format", format_items, AUD_FORMAT_S16, "Format", "Sample format");
599         RNA_def_int(ot->srna, "bitrate", 192, 32, 512, "Bitrate", "Bitrate in kbit/s", 32, 512);
600         RNA_def_boolean(ot->srna, "split_channels", 0, "Split channels", "Each channel will be rendered into a mono file");
601 #endif // WITH_AUDASPACE
602 }
603
604 /* ******************************************************* */
605
606 static int sound_poll(bContext *C)
607 {
608         Editing* ed = CTX_data_scene(C)->ed;
609
610         if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND)
611                 return 0;
612
613         return 1;
614 }
615 /********************* pack operator *********************/
616
617 static int sound_pack_exec(bContext *C, wmOperator *op)
618 {
619         Main *bmain= CTX_data_main(C);
620         Editing* ed = CTX_data_scene(C)->ed;
621         bSound* sound;
622
623         if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND)
624                 return OPERATOR_CANCELLED;
625
626         sound = ed->act_seq->sound;
627
628         if (!sound || sound->packedfile)
629                 return OPERATOR_CANCELLED;
630
631         sound->packedfile= newPackedFile(op->reports, sound->name, ID_BLEND_PATH(bmain, &sound->id));
632         sound_load(CTX_data_main(C), sound);
633
634         return OPERATOR_FINISHED;
635 }
636
637 static void SOUND_OT_pack(wmOperatorType *ot)
638 {
639         /* identifiers */
640         ot->name = "Pack Sound";
641         ot->description = "Pack the sound into the current blend file";
642         ot->idname = "SOUND_OT_pack";
643
644         /* api callbacks */
645         ot->exec = sound_pack_exec;
646         ot->poll = sound_poll;
647
648         /* flags */
649         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
650 }
651
652 /********************* unpack operator *********************/
653
654 static int sound_unpack_exec(bContext *C, wmOperator *op)
655 {
656         int method= RNA_enum_get(op->ptr, "method");
657         bSound* sound= NULL;
658
659         /* find the suppplied image by name */
660         if (RNA_struct_property_is_set(op->ptr, "id")) {
661                 char sndname[MAX_ID_NAME-2];
662                 RNA_string_get(op->ptr, "id", sndname);
663                 sound = BLI_findstring(&CTX_data_main(C)->sound, sndname, offsetof(ID, name) + 2);
664         }
665
666         if (!sound || !sound->packedfile)
667                 return OPERATOR_CANCELLED;
668
669         if (G.fileflags & G_AUTOPACK)
670                 BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save");
671
672         unpackSound(CTX_data_main(C), op->reports, sound, method);
673
674         return OPERATOR_FINISHED;
675 }
676
677 static int sound_unpack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
678 {
679         Editing* ed = CTX_data_scene(C)->ed;
680         bSound* sound;
681
682         if (RNA_struct_property_is_set(op->ptr, "id"))
683                 return sound_unpack_exec(C, op);
684
685         if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND)
686                 return OPERATOR_CANCELLED;
687
688         sound = ed->act_seq->sound;
689
690         if (!sound || !sound->packedfile)
691                 return OPERATOR_CANCELLED;
692
693         if (G.fileflags & G_AUTOPACK)
694                 BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save");
695
696         unpack_menu(C, "SOUND_OT_unpack", sound->id.name+2, sound->name, "sounds", sound->packedfile);
697
698         return OPERATOR_FINISHED;
699 }
700
701 static void SOUND_OT_unpack(wmOperatorType *ot)
702 {
703         /* identifiers */
704         ot->name = "Unpack Sound";
705         ot->description = "Unpack the sound to the samples filename";
706         ot->idname = "SOUND_OT_unpack";
707
708         /* api callbacks */
709         ot->exec = sound_unpack_exec;
710         ot->invoke = sound_unpack_invoke;
711         ot->poll = sound_poll;
712
713         /* flags */
714         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
715
716         /* properties */
717         RNA_def_enum(ot->srna, "method", unpack_method_items, PF_USE_LOCAL, "Method", "How to unpack");
718         RNA_def_string(ot->srna, "id", "", MAX_ID_NAME-2, "Sound Name", "Sound datablock name to unpack"); /* XXX, weark!, will fail with library, name collisions */
719 }
720
721 /* ******************************************************* */
722
723 void ED_operatortypes_sound(void)
724 {
725         WM_operatortype_append(SOUND_OT_open);
726         WM_operatortype_append(SOUND_OT_open_mono);
727         WM_operatortype_append(SOUND_OT_mixdown);
728         WM_operatortype_append(SOUND_OT_pack);
729         WM_operatortype_append(SOUND_OT_unpack);
730         WM_operatortype_append(SOUND_OT_update_animation_flags);
731         WM_operatortype_append(SOUND_OT_bake_animation);
732 }