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