Blender  V3.3
sound_ops.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2007 Blender Foundation. All rights reserved. */
3 
8 #include <stddef.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include "MEM_guardedalloc.h"
14 
15 #include "BLI_blenlib.h"
16 #include "BLI_utildefines.h"
17 
18 #include "DNA_scene_types.h"
19 #include "DNA_sequence_types.h"
20 #include "DNA_sound_types.h"
21 #include "DNA_space_types.h"
22 #include "DNA_userdef_types.h"
23 
24 #include "BKE_context.h"
25 #include "BKE_fcurve.h"
26 #include "BKE_global.h"
27 #include "BKE_lib_id.h"
28 #include "BKE_main.h"
29 #include "BKE_packedFile.h"
30 #include "BKE_report.h"
31 #include "BKE_scene.h"
32 #include "BKE_sound.h"
33 
34 #include "RNA_access.h"
35 #include "RNA_define.h"
36 #include "RNA_enum_types.h"
37 #include "RNA_prototypes.h"
38 
39 #include "SEQ_iterator.h"
40 #include "SEQ_utils.h"
41 
42 #include "UI_interface.h"
43 
44 #include "WM_api.h"
45 #include "WM_types.h"
46 
47 #ifdef WITH_AUDASPACE
48 # include <AUD_Special.h>
49 #endif
50 
51 #include "DEG_depsgraph_query.h"
52 
53 #include "ED_sound.h"
54 #include "ED_util.h"
55 
56 /******************** open sound operator ********************/
57 
59 {
60  MEM_freeN(op->customdata);
61  op->customdata = NULL;
62 }
63 
65 {
66  PropertyPointerRNA *pprop;
67 
68  op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
70 }
71 
72 #ifdef WITH_AUDASPACE
73 static int sound_open_exec(bContext *C, wmOperator *op)
74 {
75  char path[FILE_MAX];
76  bSound *sound;
77  PropertyPointerRNA *pprop;
78  PointerRNA idptr;
79  Main *bmain = CTX_data_main(C);
80 
81  RNA_string_get(op->ptr, "filepath", path);
82  sound = BKE_sound_new_file(bmain, path);
83 
84  if (!op->customdata) {
85  sound_open_init(C, op);
86  }
87 
88  if (RNA_boolean_get(op->ptr, "mono")) {
89  sound->flags |= SOUND_FLAGS_MONO;
90  }
91 
92  if (RNA_boolean_get(op->ptr, "cache")) {
93  sound->flags |= SOUND_FLAGS_CACHING;
94  }
95 
96  /* hook into UI */
97  pprop = op->customdata;
98 
99  if (pprop->prop) {
100  /* when creating new ID blocks, use is already 1, but RNA
101  * pointer use also increases user, so this compensates it */
102  id_us_min(&sound->id);
103 
104  RNA_id_pointer_create(&sound->id, &idptr);
105  RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr, NULL);
106  RNA_property_update(C, &pprop->ptr, pprop->prop);
107  }
108 
110 
111  MEM_freeN(op->customdata);
112  return OPERATOR_FINISHED;
113 }
114 
115 #else /* WITH_AUDASPACE */
116 
118 {
119  BKE_report(op->reports, RPT_ERROR, "Compiled without sound support");
120 
121  return OPERATOR_CANCELLED;
122 }
123 
124 #endif
125 
126 static int sound_open_invoke(bContext *C, wmOperator *op, const wmEvent *event)
127 {
128  if (RNA_struct_property_is_set(op->ptr, "filepath")) {
129  return sound_open_exec(C, op);
130  }
131 
132  sound_open_init(C, op);
133 
134  return WM_operator_filesel(C, op, event);
135 }
136 
138 {
139  /* identifiers */
140  ot->name = "Open Sound";
141  ot->description = "Load a sound file";
142  ot->idname = "SOUND_OT_open";
143 
144  /* api callbacks */
148 
149  /* flags */
151 
152  /* properties */
155  FILE_SPECIAL,
160  RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
161  RNA_def_boolean(ot->srna, "mono", false, "Mono", "Merge all the sound's channels into one");
162 }
163 
165 {
166  /* identifiers */
167  ot->name = "Open Sound Mono";
168  ot->description = "Load a sound file as mono";
169  ot->idname = "SOUND_OT_open_mono";
170 
171  /* api callbacks */
175 
176  /* flags */
178 
179  /* properties */
182  FILE_SPECIAL,
187  RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
188  RNA_def_boolean(ot->srna, "mono", true, "Mono", "Mixdown the sound to mono");
189 }
190 
191 /* ******************************************************* */
192 
194 
196 {
197  struct FCurve *fcu;
198  Scene *scene = (Scene *)user_data;
199  bool driven;
200 
201  fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, &driven);
202  if (fcu || driven) {
204  }
205  else {
207  }
208 
209  fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pitch", 0, &driven);
210  if (fcu || driven) {
212  }
213  else {
215  }
216 
217  fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pan", 0, &driven);
218  if (fcu || driven) {
220  }
221  else {
222  seq->flag &= ~SEQ_AUDIO_PAN_ANIMATED;
223  }
224 
225  if (seq->type == SEQ_TYPE_SCENE) {
226  /* TODO(sergey): For now we do manual recursion into the scene strips,
227  * but perhaps it should be covered by recursive_apply?
228  */
230  }
231 
232  return true;
233 }
234 
236 {
237  struct FCurve *fcu;
238  bool driven;
239 
240  if (scene->id.tag & LIB_TAG_DOIT) {
241  return;
242  }
243  scene->id.tag |= LIB_TAG_DOIT;
244 
245  if (scene->ed != NULL) {
247  }
248 
249  fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven);
250  if (fcu || driven) {
252  }
253  else {
255  }
256 }
257 
259 {
261 
265  return OPERATOR_FINISHED;
266 }
267 
269 {
270  /*
271  * This operator is needed to set a correct state of the sound animation
272  * System. Unfortunately there's no really correct place to call the exec
273  * function, that's why I made it an operator that's only visible in the
274  * search menu. Apart from that the bake animation operator calls it too.
275  */
276 
277  /* identifiers */
278  ot->name = "Update Animation";
279  ot->description = "Update animation flags";
280  ot->idname = "SOUND_OT_update_animation_flags";
281 
282  /* api callbacks */
284 
285  /* flags */
287 }
288 
289 /* ******************************************************* */
290 
292 {
294  /* NOTE: We will be forcefully evaluating dependency graph at every frame, so no need to ensure
295  * current scene state is evaluated as it will be lost anyway. */
297  int oldfra = scene->r.cfra;
298  int cfra;
299 
301 
302  for (cfra = (scene->r.sfra > 0) ? (scene->r.sfra - 1) : 0; cfra <= scene->r.efra + 1; cfra++) {
303  scene->r.cfra = cfra;
305  }
306 
307  scene->r.cfra = oldfra;
309 
310  return OPERATOR_FINISHED;
311 }
312 
314 {
315  /* identifiers */
316  ot->name = "Update Animation Cache";
317  ot->description = "Update the audio animation cache";
318  ot->idname = "SOUND_OT_bake_animation";
319 
320  /* api callbacks */
322 
323  /* flags */
325 }
326 
327 /******************** mixdown operator ********************/
328 
330 {
331 #ifdef WITH_AUDASPACE
332  char path[FILE_MAX];
333  char filename[FILE_MAX];
335  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
336  Main *bmain = CTX_data_main(C);
337  int split;
338 
339  int bitrate, accuracy;
340  AUD_DeviceSpecs specs;
341  AUD_Container container;
342  AUD_Codec codec;
343  int result;
344  char error_message[1024] = {'\0'};
345 
347 
348  RNA_string_get(op->ptr, "filepath", path);
349  bitrate = RNA_int_get(op->ptr, "bitrate") * 1000;
350  accuracy = RNA_int_get(op->ptr, "accuracy");
351  specs.format = RNA_enum_get(op->ptr, "format");
352  container = RNA_enum_get(op->ptr, "container");
353  codec = RNA_enum_get(op->ptr, "codec");
354  split = RNA_boolean_get(op->ptr, "split_channels");
355  specs.channels = scene_eval->r.ffcodecdata.audio_channels;
356  specs.rate = scene_eval->r.ffcodecdata.audio_mixrate;
357 
358  BLI_strncpy(filename, path, sizeof(filename));
359  BLI_path_abs(filename, BKE_main_blendfile_path(bmain));
360 
361  const double fps = (((double)scene_eval->r.frs_sec) / (double)scene_eval->r.frs_sec_base);
362  const int start_frame = scene_eval->r.sfra;
363  const int end_frame = scene_eval->r.efra;
364 
365  if (split) {
366  result = AUD_mixdown_per_channel(scene_eval->sound_scene,
367  start_frame * specs.rate / fps,
368  (end_frame - start_frame + 1) * specs.rate / fps,
369  accuracy,
370  filename,
371  specs,
372  container,
373  codec,
374  bitrate,
375  NULL,
376  NULL,
377  error_message,
378  sizeof(error_message));
379  }
380  else {
381  result = AUD_mixdown(scene_eval->sound_scene,
382  start_frame * specs.rate / fps,
383  (end_frame - start_frame + 1) * specs.rate / fps,
384  accuracy,
385  filename,
386  specs,
387  container,
388  codec,
389  bitrate,
390  NULL,
391  NULL,
392  error_message,
393  sizeof(error_message));
394  }
395 
396  BKE_sound_reset_scene_specs(scene_eval);
397 
398  if (!result) {
399  BKE_report(op->reports, RPT_ERROR, error_message);
400  return OPERATOR_CANCELLED;
401  }
402 #else /* WITH_AUDASPACE */
403  (void)C;
404  (void)op;
405 #endif /* WITH_AUDASPACE */
406  return OPERATOR_FINISHED;
407 }
408 
409 #ifdef WITH_AUDASPACE
410 static const EnumPropertyItem container_items[] = {
411 # ifdef WITH_FFMPEG
412  {AUD_CONTAINER_AC3, "AC3", 0, "ac3", "Dolby Digital ATRAC 3"},
413 # endif
414  {AUD_CONTAINER_FLAC, "FLAC", 0, "flac", "Free Lossless Audio Codec"},
415 # ifdef WITH_FFMPEG
416  {AUD_CONTAINER_MATROSKA, "MATROSKA", 0, "mkv", "Matroska"},
417  {AUD_CONTAINER_MP2, "MP2", 0, "mp2", "MPEG-1 Audio Layer II"},
418  {AUD_CONTAINER_MP3, "MP3", 0, "mp3", "MPEG-2 Audio Layer III"},
419 # endif
420  {AUD_CONTAINER_OGG, "OGG", 0, "ogg", "Xiph.Org Ogg Container"},
421  {AUD_CONTAINER_WAV, "WAV", 0, "wav", "Waveform Audio File Format"},
422  {0, NULL, 0, NULL, NULL},
423 };
424 
425 static const char *snd_ext_sound[] = {
426  ".ac3",
427  ".flac",
428  ".mkv",
429  ".mp2",
430  ".mp3",
431  ".ogg",
432  ".wav",
433  NULL,
434 };
435 
436 static bool sound_mixdown_check(bContext *UNUSED(C), wmOperator *op)
437 {
438  AUD_Container container = RNA_enum_get(op->ptr, "container");
439 
440  const char *extension = NULL;
441 
442  const EnumPropertyItem *item = container_items;
443  while (item->identifier != NULL) {
444  if (item->value == container) {
445  const char **ext = snd_ext_sound;
446  while (*ext != NULL) {
447  if (STREQ(*ext + 1, item->name)) {
448  extension = *ext;
449  break;
450  }
451 
452  ext++;
453  }
454  }
455  item++;
456  }
457 
458  if (extension) {
459  PropertyRNA *prop;
460  char filepath[FILE_MAX];
461 
462  int check;
463 
464  prop = RNA_struct_find_property(op->ptr, "filepath");
465  RNA_property_string_get(op->ptr, prop, filepath);
466 
467  if (BLI_path_extension_check_array(filepath, snd_ext_sound)) {
468  check = BLI_path_extension_replace(filepath, FILE_MAX, extension);
469  }
470  else {
471  check = BLI_path_extension_ensure(filepath, FILE_MAX, extension);
472  }
473 
474  if (!check) {
475  return check;
476  }
477 
478  RNA_property_string_set(op->ptr, prop, filepath);
479  return true;
480  }
481 
482  return false;
483 }
484 
485 #endif /* WITH_AUDASPACE */
486 
487 static int sound_mixdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
488 {
489  if (RNA_struct_property_is_set(op->ptr, "filepath")) {
490  return sound_mixdown_exec(C, op);
491  }
492 
493  return WM_operator_filesel(C, op, event);
494 }
495 
496 #ifdef WITH_AUDASPACE
497 
498 static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr),
499  PropertyRNA *prop,
500  void *UNUSED(user_data))
501 {
502  const char *prop_id = RNA_property_identifier(prop);
503  return !(STR_ELEM(prop_id, "filepath", "directory", "filename"));
504 }
505 
506 static void sound_mixdown_draw(bContext *C, wmOperator *op)
507 {
508  static const EnumPropertyItem pcm_format_items[] = {
509  {AUD_FORMAT_U8, "U8", 0, "U8", "8-bit unsigned"},
510  {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"},
511 # ifdef WITH_SNDFILE
512  {AUD_FORMAT_S24, "S24", 0, "S24", "24-bit signed"},
513 # endif
514  {AUD_FORMAT_S32, "S32", 0, "S32", "32-bit signed"},
515  {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32-bit floating-point"},
516  {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64-bit floating-point"},
517  {0, NULL, 0, NULL, NULL},
518  };
519 
520  static const EnumPropertyItem mp3_format_items[] = {
521  {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"},
522  {AUD_FORMAT_S32, "S32", 0, "S32", "32-bit signed"},
523  {0, NULL, 0, NULL, NULL},
524  };
525 
526 # ifdef WITH_SNDFILE
527  static const EnumPropertyItem flac_format_items[] = {
528  {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"},
529  {AUD_FORMAT_S24, "S24", 0, "S24", "24-bit signed"},
530  {0, NULL, 0, NULL, NULL},
531  };
532 # endif
533 
534  static const EnumPropertyItem all_codec_items[] = {
535  {AUD_CODEC_AAC, "AAC", 0, "AAC", "Advanced Audio Coding"},
536  {AUD_CODEC_AC3, "AC3", 0, "AC3", "Dolby Digital ATRAC 3"},
537  {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
538  {AUD_CODEC_MP2, "MP2", 0, "MP2", "MPEG-1 Audio Layer II"},
539  {AUD_CODEC_MP3, "MP3", 0, "MP3", "MPEG-2 Audio Layer III"},
540  {AUD_CODEC_PCM, "PCM", 0, "PCM", "Pulse Code Modulation (RAW)"},
541  {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
542  {0, NULL, 0, NULL, NULL},
543  };
544 
545  static const EnumPropertyItem ogg_codec_items[] = {
546  {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
547  {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
548  {0, NULL, 0, NULL, NULL},
549  };
550 
551  uiLayout *layout = op->layout;
553  PointerRNA ptr;
554  PropertyRNA *prop_format;
555  PropertyRNA *prop_codec;
556  PropertyRNA *prop_bitrate;
557 
558  uiLayoutSetPropSep(layout, true);
559  uiLayoutSetPropDecorate(layout, false);
560 
561  AUD_Container container = RNA_enum_get(op->ptr, "container");
562  AUD_Codec codec = RNA_enum_get(op->ptr, "codec");
563 
564  prop_format = RNA_struct_find_property(op->ptr, "format");
565  prop_codec = RNA_struct_find_property(op->ptr, "codec");
566  prop_bitrate = RNA_struct_find_property(op->ptr, "bitrate");
567 
569  RNA_def_property_flag(prop_codec, PROP_HIDDEN);
570  RNA_def_property_flag(prop_format, PROP_HIDDEN);
571 
572  switch (container) {
573  case AUD_CONTAINER_AC3:
574  RNA_def_property_enum_items(prop_codec, all_codec_items);
575  RNA_enum_set(op->ptr, "codec", AUD_CODEC_AC3);
576  RNA_enum_set(op->ptr, "format", AUD_FORMAT_FLOAT32);
577  break;
578  case AUD_CONTAINER_FLAC:
579  RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
580  RNA_def_property_enum_items(prop_codec, all_codec_items);
581  RNA_enum_set(op->ptr, "codec", AUD_CODEC_FLAC);
582 # ifdef WITH_SNDFILE
584  RNA_def_property_enum_items(prop_format, flac_format_items);
585 # else
586  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
587 # endif
588  break;
589  case AUD_CONTAINER_MATROSKA:
591  RNA_def_property_enum_items(prop_codec, all_codec_items);
592 
593  switch (codec) {
594  case AUD_CODEC_AAC:
595  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
596  break;
597  case AUD_CODEC_AC3:
598  RNA_enum_set(op->ptr, "format", AUD_FORMAT_FLOAT32);
599  break;
600  case AUD_CODEC_FLAC:
601  RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
602  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
603  break;
604  case AUD_CODEC_MP2:
605  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
606  break;
607  case AUD_CODEC_MP3:
608  RNA_def_property_enum_items(prop_format, mp3_format_items);
610  break;
611  case AUD_CODEC_PCM:
612  RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
613  RNA_def_property_enum_items(prop_format, pcm_format_items);
615  break;
616  case AUD_CODEC_VORBIS:
617  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
618  break;
619  default:
620  break;
621  }
622 
623  break;
624  case AUD_CONTAINER_MP2:
625  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
626  RNA_enum_set(op->ptr, "codec", AUD_CODEC_MP2);
627  RNA_def_property_enum_items(prop_codec, all_codec_items);
628  break;
629  case AUD_CONTAINER_MP3:
631  RNA_def_property_enum_items(prop_format, mp3_format_items);
632  RNA_def_property_enum_items(prop_codec, all_codec_items);
633  RNA_enum_set(op->ptr, "codec", AUD_CODEC_MP3);
634  break;
635  case AUD_CONTAINER_OGG:
637  RNA_def_property_enum_items(prop_codec, ogg_codec_items);
638  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
639  break;
640  case AUD_CONTAINER_WAV:
641  RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
643  RNA_def_property_enum_items(prop_format, pcm_format_items);
644  RNA_def_property_enum_items(prop_codec, all_codec_items);
645  RNA_enum_set(op->ptr, "codec", AUD_CODEC_PCM);
646  break;
647  default:
648  break;
649  }
650 
651  RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
652 
653  /* main draw call */
655  layout, &ptr, sound_mixdown_draw_check_prop, NULL, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
656 }
657 #endif /* WITH_AUDASPACE */
658 
660 {
661 #ifdef WITH_AUDASPACE
662  static const EnumPropertyItem format_items[] = {
663  {AUD_FORMAT_U8, "U8", 0, "U8", "8-bit unsigned"},
664  {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"},
665  {AUD_FORMAT_S24, "S24", 0, "S24", "24-bit signed"},
666  {AUD_FORMAT_S32, "S32", 0, "S32", "32-bit signed"},
667  {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32-bit floating-point"},
668  {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64-bit floating-point"},
669  {0, NULL, 0, NULL, NULL},
670  };
671 
672  static const EnumPropertyItem codec_items[] = {
673 # ifdef WITH_FFMPEG
674  {AUD_CODEC_AAC, "AAC", 0, "AAC", "Advanced Audio Coding"},
675  {AUD_CODEC_AC3, "AC3", 0, "AC3", "Dolby Digital ATRAC 3"},
676 # endif
677  {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
678 # ifdef WITH_FFMPEG
679  {AUD_CODEC_MP2, "MP2", 0, "MP2", "MPEG-1 Audio Layer II"},
680  {AUD_CODEC_MP3, "MP3", 0, "MP3", "MPEG-2 Audio Layer III"},
681 # endif
682  {AUD_CODEC_PCM, "PCM", 0, "PCM", "Pulse Code Modulation (RAW)"},
683  {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
684  {0, NULL, 0, NULL, NULL},
685  };
686 
687 #endif /* WITH_AUDASPACE */
688 
689  /* identifiers */
690  ot->name = "Mixdown";
691  ot->description = "Mix the scene's audio to a sound file";
692  ot->idname = "SOUND_OT_mixdown";
693 
694  /* api callbacks */
697 
698 #ifdef WITH_AUDASPACE
699  ot->check = sound_mixdown_check;
700  ot->ui = sound_mixdown_draw;
701 #endif
702  /* flags */
704 
705  /* properties */
708  FILE_SPECIAL,
709  FILE_SAVE,
713 #ifdef WITH_AUDASPACE
714  RNA_def_int(
715  ot->srna,
716  "accuracy",
717  1024,
718  1,
719  16777216,
720  "Accuracy",
721  "Sample accuracy, important for animation data (the lower the value, the more accurate)",
722  1,
723  16777216);
724  RNA_def_enum(
725  ot->srna, "container", container_items, AUD_CONTAINER_FLAC, "Container", "File format");
726  RNA_def_enum(ot->srna, "codec", codec_items, AUD_CODEC_FLAC, "Codec", "Audio Codec");
727  RNA_def_enum(ot->srna, "format", format_items, AUD_FORMAT_S16, "Format", "Sample format");
728  RNA_def_int(ot->srna, "bitrate", 192, 32, 512, "Bitrate", "Bitrate in kbit/s", 32, 512);
730  "split_channels",
731  0,
732  "Split channels",
733  "Each channel will be rendered into a mono file");
734 #endif /* WITH_AUDASPACE */
735 }
736 
737 /* ******************************************************* */
738 
739 static bool sound_poll(bContext *C)
740 {
741  Editing *ed = CTX_data_scene(C)->ed;
742 
743  if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM) {
744  return false;
745  }
746 
747  return true;
748 }
749 /********************* pack operator *********************/
750 
752 {
753  Main *bmain = CTX_data_main(C);
754  Editing *ed = CTX_data_scene(C)->ed;
755  bSound *sound;
756 
757  if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM) {
758  return OPERATOR_CANCELLED;
759  }
760 
761  sound = ed->act_seq->sound;
762 
763  if (!sound || sound->packedfile) {
764  return OPERATOR_CANCELLED;
765  }
766 
768  op->reports, sound->filepath, ID_BLEND_PATH(bmain, &sound->id));
769 
770  DEG_id_tag_update_ex(bmain, &sound->id, ID_RECALC_AUDIO);
771 
772  return OPERATOR_FINISHED;
773 }
774 
776 {
777  /* identifiers */
778  ot->name = "Pack Sound";
779  ot->description = "Pack the sound into the current blend file";
780  ot->idname = "SOUND_OT_pack";
781 
782  /* api callbacks */
784  ot->poll = sound_poll;
785 
786  /* flags */
788 }
789 
790 /********************* unpack operator *********************/
791 
793 {
794  Main *bmain = CTX_data_main(C);
795  int method = RNA_enum_get(op->ptr, "method");
796  bSound *sound = NULL;
797 
798  /* find the supplied image by name */
799  if (RNA_struct_property_is_set(op->ptr, "id")) {
800  char sndname[MAX_ID_NAME - 2];
801  RNA_string_get(op->ptr, "id", sndname);
802  sound = BLI_findstring(&bmain->sounds, sndname, offsetof(ID, name) + 2);
803  }
804 
805  if (!sound || !sound->packedfile) {
806  return OPERATOR_CANCELLED;
807  }
808 
809  if (G.fileflags & G_FILE_AUTOPACK) {
810  BKE_report(op->reports,
811  RPT_WARNING,
812  "AutoPack is enabled, so image will be packed again on file save");
813  }
814 
815  BKE_packedfile_unpack_sound(bmain, op->reports, sound, method);
816 
817  return OPERATOR_FINISHED;
818 }
819 
820 static int sound_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
821 {
822  Editing *ed = CTX_data_scene(C)->ed;
823  bSound *sound;
824 
825  if (RNA_struct_property_is_set(op->ptr, "id")) {
826  return sound_unpack_exec(C, op);
827  }
828 
829  if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM) {
830  return OPERATOR_CANCELLED;
831  }
832 
833  sound = ed->act_seq->sound;
834 
835  if (!sound || !sound->packedfile) {
836  return OPERATOR_CANCELLED;
837  }
838 
839  if (G.fileflags & G_FILE_AUTOPACK) {
840  BKE_report(op->reports,
841  RPT_WARNING,
842  "AutoPack is enabled, so image will be packed again on file save");
843  }
844 
845  unpack_menu(
846  C, "SOUND_OT_unpack", sound->id.name + 2, sound->filepath, "sounds", sound->packedfile);
847 
848  return OPERATOR_FINISHED;
849 }
850 
852 {
853  /* identifiers */
854  ot->name = "Unpack Sound";
855  ot->description = "Unpack the sound to the samples filename";
856  ot->idname = "SOUND_OT_unpack";
857 
858  /* api callbacks */
861  ot->poll = sound_poll;
862 
863  /* flags */
865 
866  /* properties */
867  RNA_def_enum(
868  ot->srna, "method", rna_enum_unpack_method_items, PF_USE_LOCAL, "Method", "How to unpack");
869  /* XXX: weak!, will fail with library, name collisions */
871  ot->srna, "id", NULL, MAX_ID_NAME - 2, "Sound Name", "Sound data-block name to unpack");
872 }
873 
874 /* ******************************************************* */
875 
877 {
885 }
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1528
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1505
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
struct FCurve * id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, const char *prop_name, int index, bool *r_driven)
Definition: fcurve.c:201
@ G_FILE_AUTOPACK
Definition: BKE_global.h:209
void BKE_main_id_tag_idcode(struct Main *mainvar, short type, int tag, bool value)
Definition: lib_id.c:920
void id_us_min(struct ID *id)
Definition: lib_id.c:313
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
struct PackedFile * BKE_packedfile_new(struct ReportList *reports, const char *filepath, const char *basepath)
Definition: packedFile.c:177
int BKE_packedfile_unpack_sound(struct Main *bmain, struct ReportList *reports, struct bSound *sound, enum ePF_FileStatus how)
Definition: packedFile.c:594
@ PF_USE_LOCAL
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
void BKE_scene_graph_update_for_newframe(struct Depsgraph *depsgraph)
Definition: scene.cc:2728
struct bSound * BKE_sound_new_file(struct Main *main, const char *filepath)
void BKE_sound_reset_scene_specs(struct Scene *scene)
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
bool BLI_path_extension_check_array(const char *str, const char **ext_array) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:1326
#define FILE_MAX
bool BLI_path_extension_ensure(char *path, size_t maxlen, const char *ext) ATTR_NONNULL()
Definition: path_util.c:1420
bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext) ATTR_NONNULL()
Definition: path_util.c:1393
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:897
#define STR_ELEM(...)
Definition: BLI_string.h:539
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
#define UNUSED(x)
#define STREQ(a, b)
typedef double(DMatrix)[4][4]
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_id_tag_update_ex(struct Main *bmain, struct ID *id, int flag)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ ID_RECALC_AUDIO
Definition: DNA_ID.h:848
@ ID_RECALC_SEQUENCER_STRIPS
Definition: DNA_ID.h:838
#define MAX_ID_NAME
Definition: DNA_ID.h:337
#define ID_BLEND_PATH(_bmain, _id)
Definition: DNA_ID.h:559
@ LIB_TAG_DOIT
Definition: DNA_ID.h:707
@ ID_SCE
Definition: DNA_ID_enums.h:45
#define AUDIO_VOLUME_ANIMATED
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_SCENE
@ SEQ_AUDIO_PITCH_ANIMATED
@ SEQ_AUDIO_VOLUME_ANIMATED
@ SEQ_AUDIO_PAN_ANIMATED
@ SOUND_FLAGS_MONO
@ SOUND_FLAGS_CACHING
@ FILE_SORT_DEFAULT
@ FILE_SPECIAL
@ FILE_TYPE_MOVIE
@ FILE_TYPE_SOUND
@ FILE_TYPE_FOLDER
@ FILE_DEFAULTDISPLAY
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
void unpack_menu(struct bContext *C, const char *opname, const char *id_name, const char *abs_name, const char *folder, struct PackedFile *pf)
Definition: ed_util.c:357
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
Read Guarded memory(de)allocation.
@ PROP_HIDDEN
Definition: RNA_types.h:216
#define C
Definition: RandGen.cpp:25
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
@ UI_BUT_LABEL_ALIGN_NONE
void UI_context_active_but_prop_get_templateID(struct bContext *C, struct PointerRNA *r_ptr, struct PropertyRNA **r_prop)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, bool(*check_prop)(struct PointerRNA *ptr, struct PropertyRNA *prop, void *user_data), void *user_data, struct PropertyRNA *prop_activate_init, eButLabelAlign label_align, bool compact)
@ WM_FILESEL_RELPATH
Definition: WM_api.h:752
@ WM_FILESEL_SHOW_PROPS
Definition: WM_api.h:758
@ WM_FILESEL_FILEPATH
Definition: WM_api.h:755
@ FILE_OPENFILE
Definition: WM_api.h:764
@ FILE_SAVE
Definition: WM_api.h:765
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
Scene scene
const Depsgraph * depsgraph
void * user_data
SyclQueue void void size_t num_bytes void
void SEQ_for_each_callback(ListBase *seqbase, SeqForEachFunc callback, void *user_data)
Definition: iterator.c:76
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define G(x, y, z)
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
Definition: abc_util.cc:92
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1000
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value, ReportList *reports)
Definition: rna_access.c:3532
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2138
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:5116
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4910
void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
Definition: rna_access.c:3149
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:5301
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:5015
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
Definition: rna_access.c:3239
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
Definition: rna_define.c:1872
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1495
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3687
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1490
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3597
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3783
const EnumPropertyItem rna_enum_unpack_method_items[]
static void SOUND_OT_pack(wmOperatorType *ot)
Definition: sound_ops.c:775
static int sound_open_exec(bContext *UNUSED(C), wmOperator *op)
Definition: sound_ops.c:117
static void SOUND_OT_open(wmOperatorType *ot)
Definition: sound_ops.c:137
static void SOUND_OT_open_mono(wmOperatorType *ot)
Definition: sound_ops.c:164
static bool sound_update_animation_flags_fn(Sequence *seq, void *user_data)
Definition: sound_ops.c:195
static int sound_pack_exec(bContext *C, wmOperator *op)
Definition: sound_ops.c:751
static int sound_open_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: sound_ops.c:126
static bool sound_poll(bContext *C)
Definition: sound_ops.c:739
static void SOUND_OT_update_animation_flags(wmOperatorType *ot)
Definition: sound_ops.c:268
static void sound_open_cancel(bContext *UNUSED(C), wmOperator *op)
Definition: sound_ops.c:58
static int sound_mixdown_exec(bContext *C, wmOperator *op)
Definition: sound_ops.c:329
void ED_operatortypes_sound(void)
Definition: sound_ops.c:876
static void SOUND_OT_bake_animation(wmOperatorType *ot)
Definition: sound_ops.c:313
static void sound_update_animation_flags(Scene *scene)
Definition: sound_ops.c:235
static void SOUND_OT_mixdown(wmOperatorType *ot)
Definition: sound_ops.c:659
static void SOUND_OT_unpack(wmOperatorType *ot)
Definition: sound_ops.c:851
static int sound_update_animation_flags_exec(bContext *C, wmOperator *UNUSED(op))
Definition: sound_ops.c:258
static int sound_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: sound_ops.c:820
static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op))
Definition: sound_ops.c:291
static int sound_unpack_exec(bContext *C, wmOperator *op)
Definition: sound_ops.c:792
static void sound_open_init(bContext *C, wmOperator *op)
Definition: sound_ops.c:64
static int sound_mixdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: sound_ops.c:487
ListBase seqbase
Sequence * act_seq
const char * identifier
Definition: RNA_types.h:461
const char * name
Definition: RNA_types.h:465
Definition: DNA_ID.h:368
int tag
Definition: DNA_ID.h:387
char name[66]
Definition: DNA_ID.h:378
Definition: BKE_main.h:121
ListBase sounds
Definition: BKE_main.h:188
struct PropertyRNA * prop
Definition: RNA_types.h:43
PointerRNA ptr
Definition: RNA_types.h:42
float frs_sec_base
struct FFMpegCodecData ffcodecdata
void * sound_scene
struct Editing * ed
struct RenderData r
struct AudioData audio
struct Scene * scene
struct bSound * sound
struct PackedFile * packedfile
char filepath[1024]
short flags
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:927
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
void(* ui)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:954
bool(* check)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:911
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
struct ReportList * reports
IDProperty * properties
struct uiLayout * layout
struct wmOperatorType * type
struct PointerRNA * ptr
PointerRNA * ptr
Definition: wm_files.c:3480
wmOperatorType * ot
Definition: wm_files.c:3479
void WM_operator_properties_filesel(wmOperatorType *ot, const int filter, const short type, const eFileSel_Action action, const eFileSel_Flag flag, const short display, const short sort)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
int WM_operator_filesel(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))