Blender  V2.93
sound_ops.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2007 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <stddef.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include "MEM_guardedalloc.h"
30 
31 #include "BLI_blenlib.h"
32 #include "BLI_utildefines.h"
33 
34 #include "DNA_scene_types.h"
35 #include "DNA_sequence_types.h"
36 #include "DNA_sound_types.h"
37 #include "DNA_space_types.h"
38 #include "DNA_userdef_types.h"
39 
40 #include "BKE_context.h"
41 #include "BKE_fcurve.h"
42 #include "BKE_global.h"
43 #include "BKE_lib_id.h"
44 #include "BKE_main.h"
45 #include "BKE_packedFile.h"
46 #include "BKE_report.h"
47 #include "BKE_scene.h"
48 #include "BKE_sound.h"
49 
50 #include "RNA_access.h"
51 #include "RNA_define.h"
52 #include "RNA_enum_types.h"
53 
54 #include "SEQ_iterator.h"
55 
56 #include "UI_interface.h"
57 
58 #include "WM_api.h"
59 #include "WM_types.h"
60 
61 #ifdef WITH_AUDASPACE
62 # include <AUD_Special.h>
63 #endif
64 
65 #include "DEG_depsgraph_query.h"
66 
67 #include "ED_sound.h"
68 #include "ED_util.h"
69 
70 /******************** open sound operator ********************/
71 
73 {
74  MEM_freeN(op->customdata);
75  op->customdata = NULL;
76 }
77 
79 {
80  PropertyPointerRNA *pprop;
81 
82  op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
84 }
85 
86 #ifdef WITH_AUDASPACE
87 static int sound_open_exec(bContext *C, wmOperator *op)
88 {
89  char path[FILE_MAX];
90  bSound *sound;
91  PropertyPointerRNA *pprop;
92  PointerRNA idptr;
93  Main *bmain = CTX_data_main(C);
94 
95  RNA_string_get(op->ptr, "filepath", path);
96  sound = BKE_sound_new_file(bmain, path);
97 
98  if (!op->customdata) {
99  sound_open_init(C, op);
100  }
101 
102  if (RNA_boolean_get(op->ptr, "mono")) {
103  sound->flags |= SOUND_FLAGS_MONO;
104  }
105 
106  if (RNA_boolean_get(op->ptr, "cache")) {
107  sound->flags |= SOUND_FLAGS_CACHING;
108  }
109 
110  /* hook into UI */
111  pprop = op->customdata;
112 
113  if (pprop->prop) {
114  /* when creating new ID blocks, use is already 1, but RNA
115  * pointer use also increases user, so this compensates it */
116  id_us_min(&sound->id);
117 
118  RNA_id_pointer_create(&sound->id, &idptr);
119  RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr, NULL);
120  RNA_property_update(C, &pprop->ptr, pprop->prop);
121  }
122 
124 
125  MEM_freeN(op->customdata);
126  return OPERATOR_FINISHED;
127 }
128 
129 #else /* WITH_AUDASPACE */
130 
132 {
133  BKE_report(op->reports, RPT_ERROR, "Compiled without sound support");
134 
135  return OPERATOR_CANCELLED;
136 }
137 
138 #endif
139 
140 static int sound_open_invoke(bContext *C, wmOperator *op, const wmEvent *event)
141 {
142  if (RNA_struct_property_is_set(op->ptr, "filepath")) {
143  return sound_open_exec(C, op);
144  }
145 
146  sound_open_init(C, op);
147 
148  return WM_operator_filesel(C, op, event);
149 }
150 
152 {
153  /* identifiers */
154  ot->name = "Open Sound";
155  ot->description = "Load a sound file";
156  ot->idname = "SOUND_OT_open";
157 
158  /* api callbacks */
162 
163  /* flags */
165 
166  /* properties */
169  FILE_SPECIAL,
174  RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
175  RNA_def_boolean(ot->srna, "mono", false, "Mono", "Merge all the sound's channels into one");
176 }
177 
179 {
180  /* identifiers */
181  ot->name = "Open Sound Mono";
182  ot->description = "Load a sound file as mono";
183  ot->idname = "SOUND_OT_open_mono";
184 
185  /* api callbacks */
189 
190  /* flags */
192 
193  /* properties */
196  FILE_SPECIAL,
201  RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
202  RNA_def_boolean(ot->srna, "mono", true, "Mono", "Mixdown the sound to mono");
203 }
204 
205 /* ******************************************************* */
206 
208 
210 {
211  struct FCurve *fcu;
212  Scene *scene = (Scene *)user_data;
213  bool driven;
214 
215  fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, &driven);
216  if (fcu || driven) {
218  }
219  else {
221  }
222 
223  fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pitch", 0, &driven);
224  if (fcu || driven) {
226  }
227  else {
229  }
230 
231  fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pan", 0, &driven);
232  if (fcu || driven) {
234  }
235  else {
236  seq->flag &= ~SEQ_AUDIO_PAN_ANIMATED;
237  }
238 
239  if (seq->type == SEQ_TYPE_SCENE) {
240  /* TODO(sergey): For now we do manual recursion into the scene strips,
241  * but perhaps it should be covered by recursive_apply?
242  */
244  }
245 
246  return 0;
247 }
248 
250 {
251  struct FCurve *fcu;
252  bool driven;
253  Sequence *seq;
254 
255  if (scene->id.tag & LIB_TAG_DOIT) {
256  return;
257  }
258  scene->id.tag |= LIB_TAG_DOIT;
259 
260  SEQ_ALL_BEGIN (scene->ed, seq) {
262  }
263  SEQ_ALL_END;
264 
265  fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven);
266  if (fcu || driven) {
268  }
269  else {
271  }
272 }
273 
275 {
277 
281  return OPERATOR_FINISHED;
282 }
283 
285 {
286  /*
287  * This operator is needed to set a correct state of the sound animation
288  * System. Unfortunately there's no really correct place to call the exec
289  * function, that's why I made it an operator that's only visible in the
290  * search menu. Apart from that the bake animation operator calls it too.
291  */
292 
293  /* identifiers */
294  ot->name = "Update Animation";
295  ot->description = "Update animation flags";
296  ot->idname = "SOUND_OT_update_animation_flags";
297 
298  /* api callbacks */
300 
301  /* flags */
303 }
304 
305 /* ******************************************************* */
306 
308 {
310  /* NOTE: We will be forcefully evaluating dependency graph at every frame, so no need to ensure
311  * current scene state is evaluated as it will be lost anyway. */
313  int oldfra = scene->r.cfra;
314  int cfra;
315 
317 
318  for (cfra = (scene->r.sfra > 0) ? (scene->r.sfra - 1) : 0; cfra <= scene->r.efra + 1; cfra++) {
319  scene->r.cfra = cfra;
321  }
322 
323  scene->r.cfra = oldfra;
325 
326  return OPERATOR_FINISHED;
327 }
328 
330 {
331  /* identifiers */
332  ot->name = "Update Animation Cache";
333  ot->description = "Update the audio animation cache";
334  ot->idname = "SOUND_OT_bake_animation";
335 
336  /* api callbacks */
338 
339  /* flags */
341 }
342 
343 /******************** mixdown operator ********************/
344 
346 {
347 #ifdef WITH_AUDASPACE
348  char path[FILE_MAX];
349  char filename[FILE_MAX];
351  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
352  Main *bmain = CTX_data_main(C);
353  int split;
354 
355  int bitrate, accuracy;
356  AUD_DeviceSpecs specs;
357  AUD_Container container;
358  AUD_Codec codec;
359  const char *result;
360 
362 
363  RNA_string_get(op->ptr, "filepath", path);
364  bitrate = RNA_int_get(op->ptr, "bitrate") * 1000;
365  accuracy = RNA_int_get(op->ptr, "accuracy");
366  specs.format = RNA_enum_get(op->ptr, "format");
367  container = RNA_enum_get(op->ptr, "container");
368  codec = RNA_enum_get(op->ptr, "codec");
369  split = RNA_boolean_get(op->ptr, "split_channels");
370  specs.channels = scene_eval->r.ffcodecdata.audio_channels;
371  specs.rate = scene_eval->r.ffcodecdata.audio_mixrate;
372 
373  BLI_strncpy(filename, path, sizeof(filename));
374  BLI_path_abs(filename, BKE_main_blendfile_path(bmain));
375 
376  const double fps = (((double)scene_eval->r.frs_sec) / (double)scene_eval->r.frs_sec_base);
377  const int start_frame = scene_eval->r.sfra;
378  const int end_frame = scene_eval->r.efra;
379 
380  if (split) {
381  result = AUD_mixdown_per_channel(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  }
393  else {
394  result = AUD_mixdown(scene_eval->sound_scene,
395  start_frame * specs.rate / fps,
396  (end_frame - start_frame + 1) * specs.rate / fps,
397  accuracy,
398  filename,
399  specs,
400  container,
401  codec,
402  bitrate,
403  NULL,
404  NULL);
405  }
406 
407  BKE_sound_reset_scene_specs(scene_eval);
408 
409  if (result) {
411  return OPERATOR_CANCELLED;
412  }
413 #else /* WITH_AUDASPACE */
414  (void)C;
415  (void)op;
416 #endif /* WITH_AUDASPACE */
417  return OPERATOR_FINISHED;
418 }
419 
420 #ifdef WITH_AUDASPACE
421 static const EnumPropertyItem container_items[] = {
422 # ifdef WITH_FFMPEG
423  {AUD_CONTAINER_AC3, "AC3", 0, "ac3", "Dolby Digital ATRAC 3"},
424 # endif
425  {AUD_CONTAINER_FLAC, "FLAC", 0, "flac", "Free Lossless Audio Codec"},
426 # ifdef WITH_FFMPEG
427  {AUD_CONTAINER_MATROSKA, "MATROSKA", 0, "mkv", "Matroska"},
428  {AUD_CONTAINER_MP2, "MP2", 0, "mp2", "MPEG-1 Audio Layer II"},
429  {AUD_CONTAINER_MP3, "MP3", 0, "mp3", "MPEG-2 Audio Layer III"},
430 # endif
431  {AUD_CONTAINER_OGG, "OGG", 0, "ogg", "Xiph.Org Ogg Container"},
432  {AUD_CONTAINER_WAV, "WAV", 0, "wav", "Waveform Audio File Format"},
433  {0, NULL, 0, NULL, NULL},
434 };
435 
436 static const char *snd_ext_sound[] = {
437  ".ac3",
438  ".flac",
439  ".mkv",
440  ".mp2",
441  ".mp3",
442  ".ogg",
443  ".wav",
444  NULL,
445 };
446 
447 static bool sound_mixdown_check(bContext *UNUSED(C), wmOperator *op)
448 {
449  AUD_Container container = RNA_enum_get(op->ptr, "container");
450 
451  const char *extension = NULL;
452 
453  const EnumPropertyItem *item = container_items;
454  while (item->identifier != NULL) {
455  if (item->value == container) {
456  const char **ext = snd_ext_sound;
457  while (*ext != NULL) {
458  if (STREQ(*ext + 1, item->name)) {
459  extension = *ext;
460  break;
461  }
462 
463  ext++;
464  }
465  }
466  item++;
467  }
468 
469  if (extension) {
470  PropertyRNA *prop;
471  char filepath[FILE_MAX];
472 
473  int check;
474 
475  prop = RNA_struct_find_property(op->ptr, "filepath");
476  RNA_property_string_get(op->ptr, prop, filepath);
477 
478  if (BLI_path_extension_check_array(filepath, snd_ext_sound)) {
479  check = BLI_path_extension_replace(filepath, FILE_MAX, extension);
480  }
481  else {
482  check = BLI_path_extension_ensure(filepath, FILE_MAX, extension);
483  }
484 
485  if (!check) {
486  return check;
487  }
488 
489  RNA_property_string_set(op->ptr, prop, filepath);
490  return true;
491  }
492 
493  return false;
494 }
495 
496 #endif /* WITH_AUDASPACE */
497 
498 static int sound_mixdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
499 {
500  if (RNA_struct_property_is_set(op->ptr, "filepath")) {
501  return sound_mixdown_exec(C, op);
502  }
503 
504  return WM_operator_filesel(C, op, event);
505 }
506 
507 #ifdef WITH_AUDASPACE
508 
509 static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr),
510  PropertyRNA *prop,
511  void *UNUSED(user_data))
512 {
513  const char *prop_id = RNA_property_identifier(prop);
514  return !(STR_ELEM(prop_id, "filepath", "directory", "filename"));
515 }
516 
517 static void sound_mixdown_draw(bContext *C, wmOperator *op)
518 {
519  static const EnumPropertyItem pcm_format_items[] = {
520  {AUD_FORMAT_U8, "U8", 0, "U8", "8-bit unsigned"},
521  {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"},
522 # ifdef WITH_SNDFILE
523  {AUD_FORMAT_S24, "S24", 0, "S24", "24-bit signed"},
524 # endif
525  {AUD_FORMAT_S32, "S32", 0, "S32", "32-bit signed"},
526  {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32-bit floating-point"},
527  {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64-bit floating-point"},
528  {0, NULL, 0, NULL, NULL},
529  };
530 
531  static const EnumPropertyItem mp3_format_items[] = {
532  {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"},
533  {AUD_FORMAT_S32, "S32", 0, "S32", "32-bit signed"},
534  {0, NULL, 0, NULL, NULL},
535  };
536 
537 # ifdef WITH_SNDFILE
538  static const EnumPropertyItem flac_format_items[] = {
539  {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"},
540  {AUD_FORMAT_S24, "S24", 0, "S24", "24-bit signed"},
541  {0, NULL, 0, NULL, NULL},
542  };
543 # endif
544 
545  static const EnumPropertyItem all_codec_items[] = {
546  {AUD_CODEC_AAC, "AAC", 0, "AAC", "Advanced Audio Coding"},
547  {AUD_CODEC_AC3, "AC3", 0, "AC3", "Dolby Digital ATRAC 3"},
548  {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
549  {AUD_CODEC_MP2, "MP2", 0, "MP2", "MPEG-1 Audio Layer II"},
550  {AUD_CODEC_MP3, "MP3", 0, "MP3", "MPEG-2 Audio Layer III"},
551  {AUD_CODEC_PCM, "PCM", 0, "PCM", "Pulse Code Modulation (RAW)"},
552  {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
553  {0, NULL, 0, NULL, NULL},
554  };
555 
556  static const EnumPropertyItem ogg_codec_items[] = {
557  {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
558  {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
559  {0, NULL, 0, NULL, NULL},
560  };
561 
562  uiLayout *layout = op->layout;
564  PointerRNA ptr;
565  PropertyRNA *prop_format;
566  PropertyRNA *prop_codec;
567  PropertyRNA *prop_bitrate;
568 
569  uiLayoutSetPropSep(layout, true);
570  uiLayoutSetPropDecorate(layout, false);
571 
572  AUD_Container container = RNA_enum_get(op->ptr, "container");
573  AUD_Codec codec = RNA_enum_get(op->ptr, "codec");
574 
575  prop_format = RNA_struct_find_property(op->ptr, "format");
576  prop_codec = RNA_struct_find_property(op->ptr, "codec");
577  prop_bitrate = RNA_struct_find_property(op->ptr, "bitrate");
578 
580  RNA_def_property_flag(prop_codec, PROP_HIDDEN);
581  RNA_def_property_flag(prop_format, PROP_HIDDEN);
582 
583  switch (container) {
584  case AUD_CONTAINER_AC3:
585  RNA_def_property_enum_items(prop_codec, all_codec_items);
586  RNA_enum_set(op->ptr, "codec", AUD_CODEC_AC3);
587  RNA_enum_set(op->ptr, "format", AUD_FORMAT_FLOAT32);
588  break;
589  case AUD_CONTAINER_FLAC:
590  RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
591  RNA_def_property_enum_items(prop_codec, all_codec_items);
592  RNA_enum_set(op->ptr, "codec", AUD_CODEC_FLAC);
593 # ifdef WITH_SNDFILE
595  RNA_def_property_enum_items(prop_format, flac_format_items);
596 # else
597  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
598 # endif
599  break;
600  case AUD_CONTAINER_MATROSKA:
602  RNA_def_property_enum_items(prop_codec, all_codec_items);
603 
604  switch (codec) {
605  case AUD_CODEC_AAC:
606  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
607  break;
608  case AUD_CODEC_AC3:
609  RNA_enum_set(op->ptr, "format", AUD_FORMAT_FLOAT32);
610  break;
611  case AUD_CODEC_FLAC:
612  RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
613  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
614  break;
615  case AUD_CODEC_MP2:
616  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
617  break;
618  case AUD_CODEC_MP3:
619  RNA_def_property_enum_items(prop_format, mp3_format_items);
621  break;
622  case AUD_CODEC_PCM:
623  RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
624  RNA_def_property_enum_items(prop_format, pcm_format_items);
626  break;
627  case AUD_CODEC_VORBIS:
628  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
629  break;
630  default:
631  break;
632  }
633 
634  break;
635  case AUD_CONTAINER_MP2:
636  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
637  RNA_enum_set(op->ptr, "codec", AUD_CODEC_MP2);
638  RNA_def_property_enum_items(prop_codec, all_codec_items);
639  break;
640  case AUD_CONTAINER_MP3:
642  RNA_def_property_enum_items(prop_format, mp3_format_items);
643  RNA_def_property_enum_items(prop_codec, all_codec_items);
644  RNA_enum_set(op->ptr, "codec", AUD_CODEC_MP3);
645  break;
646  case AUD_CONTAINER_OGG:
648  RNA_def_property_enum_items(prop_codec, ogg_codec_items);
649  RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
650  break;
651  case AUD_CONTAINER_WAV:
652  RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
654  RNA_def_property_enum_items(prop_format, pcm_format_items);
655  RNA_def_property_enum_items(prop_codec, all_codec_items);
656  RNA_enum_set(op->ptr, "codec", AUD_CODEC_PCM);
657  break;
658  default:
659  break;
660  }
661 
662  RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
663 
664  /* main draw call */
666  layout, &ptr, sound_mixdown_draw_check_prop, NULL, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
667 }
668 #endif /* WITH_AUDASPACE */
669 
671 {
672 #ifdef WITH_AUDASPACE
673  static const EnumPropertyItem format_items[] = {
674  {AUD_FORMAT_U8, "U8", 0, "U8", "8-bit unsigned"},
675  {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"},
676  {AUD_FORMAT_S24, "S24", 0, "S24", "24-bit signed"},
677  {AUD_FORMAT_S32, "S32", 0, "S32", "32-bit signed"},
678  {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32-bit floating-point"},
679  {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64-bit floating-point"},
680  {0, NULL, 0, NULL, NULL},
681  };
682 
683  static const EnumPropertyItem codec_items[] = {
684 # ifdef WITH_FFMPEG
685  {AUD_CODEC_AAC, "AAC", 0, "AAC", "Advanced Audio Coding"},
686  {AUD_CODEC_AC3, "AC3", 0, "AC3", "Dolby Digital ATRAC 3"},
687 # endif
688  {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"},
689 # ifdef WITH_FFMPEG
690  {AUD_CODEC_MP2, "MP2", 0, "MP2", "MPEG-1 Audio Layer II"},
691  {AUD_CODEC_MP3, "MP3", 0, "MP3", "MPEG-2 Audio Layer III"},
692 # endif
693  {AUD_CODEC_PCM, "PCM", 0, "PCM", "Pulse Code Modulation (RAW)"},
694  {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"},
695  {0, NULL, 0, NULL, NULL},
696  };
697 
698 #endif /* WITH_AUDASPACE */
699 
700  /* identifiers */
701  ot->name = "Mixdown";
702  ot->description = "Mix the scene's audio to a sound file";
703  ot->idname = "SOUND_OT_mixdown";
704 
705  /* api callbacks */
708 
709 #ifdef WITH_AUDASPACE
710  ot->check = sound_mixdown_check;
711  ot->ui = sound_mixdown_draw;
712 #endif
713  /* flags */
715 
716  /* properties */
719  FILE_SPECIAL,
720  FILE_SAVE,
724 #ifdef WITH_AUDASPACE
725  RNA_def_int(
726  ot->srna,
727  "accuracy",
728  1024,
729  1,
730  16777216,
731  "Accuracy",
732  "Sample accuracy, important for animation data (the lower the value, the more accurate)",
733  1,
734  16777216);
735  RNA_def_enum(
736  ot->srna, "container", container_items, AUD_CONTAINER_FLAC, "Container", "File format");
737  RNA_def_enum(ot->srna, "codec", codec_items, AUD_CODEC_FLAC, "Codec", "Audio Codec");
738  RNA_def_enum(ot->srna, "format", format_items, AUD_FORMAT_S16, "Format", "Sample format");
739  RNA_def_int(ot->srna, "bitrate", 192, 32, 512, "Bitrate", "Bitrate in kbit/s", 32, 512);
741  "split_channels",
742  0,
743  "Split channels",
744  "Each channel will be rendered into a mono file");
745 #endif /* WITH_AUDASPACE */
746 }
747 
748 /* ******************************************************* */
749 
750 static bool sound_poll(bContext *C)
751 {
752  Editing *ed = CTX_data_scene(C)->ed;
753 
754  if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM) {
755  return false;
756  }
757 
758  return true;
759 }
760 /********************* pack operator *********************/
761 
763 {
764  Main *bmain = CTX_data_main(C);
765  Editing *ed = CTX_data_scene(C)->ed;
766  bSound *sound;
767 
768  if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM) {
769  return OPERATOR_CANCELLED;
770  }
771 
772  sound = ed->act_seq->sound;
773 
774  if (!sound || sound->packedfile) {
775  return OPERATOR_CANCELLED;
776  }
777 
779  op->reports, sound->filepath, ID_BLEND_PATH(bmain, &sound->id));
780  BKE_sound_load(bmain, sound);
781 
782  return OPERATOR_FINISHED;
783 }
784 
786 {
787  /* identifiers */
788  ot->name = "Pack Sound";
789  ot->description = "Pack the sound into the current blend file";
790  ot->idname = "SOUND_OT_pack";
791 
792  /* api callbacks */
794  ot->poll = sound_poll;
795 
796  /* flags */
798 }
799 
800 /********************* unpack operator *********************/
801 
803 {
804  Main *bmain = CTX_data_main(C);
805  int method = RNA_enum_get(op->ptr, "method");
806  bSound *sound = NULL;
807 
808  /* find the supplied image by name */
809  if (RNA_struct_property_is_set(op->ptr, "id")) {
810  char sndname[MAX_ID_NAME - 2];
811  RNA_string_get(op->ptr, "id", sndname);
812  sound = BLI_findstring(&bmain->sounds, sndname, offsetof(ID, name) + 2);
813  }
814 
815  if (!sound || !sound->packedfile) {
816  return OPERATOR_CANCELLED;
817  }
818 
819  if (G.fileflags & G_FILE_AUTOPACK) {
820  BKE_report(op->reports,
821  RPT_WARNING,
822  "AutoPack is enabled, so image will be packed again on file save");
823  }
824 
825  BKE_packedfile_unpack_sound(bmain, op->reports, sound, method);
826 
827  return OPERATOR_FINISHED;
828 }
829 
830 static int sound_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
831 {
832  Editing *ed = CTX_data_scene(C)->ed;
833  bSound *sound;
834 
835  if (RNA_struct_property_is_set(op->ptr, "id")) {
836  return sound_unpack_exec(C, op);
837  }
838 
839  if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM) {
840  return OPERATOR_CANCELLED;
841  }
842 
843  sound = ed->act_seq->sound;
844 
845  if (!sound || !sound->packedfile) {
846  return OPERATOR_CANCELLED;
847  }
848 
849  if (G.fileflags & G_FILE_AUTOPACK) {
850  BKE_report(op->reports,
851  RPT_WARNING,
852  "AutoPack is enabled, so image will be packed again on file save");
853  }
854 
855  unpack_menu(
856  C, "SOUND_OT_unpack", sound->id.name + 2, sound->filepath, "sounds", sound->packedfile);
857 
858  return OPERATOR_FINISHED;
859 }
860 
862 {
863  /* identifiers */
864  ot->name = "Unpack Sound";
865  ot->description = "Unpack the sound to the samples filename";
866  ot->idname = "SOUND_OT_unpack";
867 
868  /* api callbacks */
871  ot->poll = sound_poll;
872 
873  /* flags */
875 
876  /* properties */
877  RNA_def_enum(
878  ot->srna, "method", rna_enum_unpack_method_items, PF_USE_LOCAL, "Method", "How to unpack");
879  /* XXX: weak!, will fail with library, name collisions */
881  ot->srna, "id", NULL, MAX_ID_NAME - 2, "Sound Name", "Sound data-block name to unpack");
882 }
883 
884 /* ******************************************************* */
885 
887 {
895 }
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1424
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1401
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
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:221
@ G_FILE_AUTOPACK
Definition: BKE_global.h:166
void id_us_min(struct ID *id)
Definition: lib_id.c:297
void BKE_main_id_tag_idcode(struct Main *mainvar, const short type, const int tag, const bool value)
Definition: lib_id.c:910
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
int BKE_packedfile_unpack_sound(struct Main *bmain, struct ReportList *reports, struct bSound *sound, enum ePF_FileStatus how)
Definition: packedFile.c:605
struct PackedFile * BKE_packedfile_new(struct ReportList *reports, const char *filename, const char *basepath)
Definition: packedFile.c:192
@ PF_USE_LOCAL
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
void BKE_scene_graph_update_for_newframe(struct Depsgraph *depsgraph)
Definition: scene.c:2794
void BKE_sound_load(struct Main *main, struct bSound *sound)
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, const 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:1487
#define FILE_MAX
bool BLI_path_extension_ensure(char *path, size_t maxlen, const char *ext) ATTR_NONNULL()
Definition: path_util.c:1601
bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext) ATTR_NONNULL()
Definition: path_util.c:1571
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:1016
#define STR_ELEM(...)
Definition: BLI_string.h:218
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define UNUSED(x)
#define STREQ(a, b)
typedef double(DMatrix)[4][4]
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
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_SEQUENCER_STRIPS
Definition: DNA_ID.h:658
@ LIB_TAG_DOIT
Definition: DNA_ID.h:554
#define MAX_ID_NAME
Definition: DNA_ID.h:269
#define ID_BLEND_PATH(_bmain, _id)
Definition: DNA_ID.h:419
@ ID_SCE
Definition: DNA_ID_enums.h:57
#define AUDIO_VOLUME_ANIMATED
@ SEQ_AUDIO_PITCH_ANIMATED
@ SEQ_AUDIO_VOLUME_ANIMATED
@ SEQ_AUDIO_PAN_ANIMATED
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_SCENE
@ SOUND_FLAGS_MONO
@ SOUND_FLAGS_CACHING
@ FILE_SORT_DEFAULT
@ FILE_SPECIAL
@ FILE_TYPE_MOVIE
@ FILE_TYPE_SOUND
@ FILE_TYPE_FOLDER
@ FILE_OPENFILE
@ FILE_SAVE
@ 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:329
_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.
StructRNA RNA_Scene
StructRNA RNA_Sequence
@ PROP_HIDDEN
Definition: RNA_types.h:202
#define C
Definition: RandGen.cpp:39
#define SEQ_ALL_END
Definition: SEQ_iterator.h:48
#define SEQ_ALL_BEGIN(ed, _seq)
Definition: SEQ_iterator.h:41
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, const bool compact)
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)
#define WM_FILESEL_SHOW_PROPS
Definition: WM_api.h:540
#define WM_FILESEL_RELPATH
Definition: WM_api.h:533
#define WM_FILESEL_FILEPATH
Definition: WM_api.h:537
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
Scene scene
const Depsgraph * depsgraph
void * user_data
int SEQ_iterator_recursive_apply(Sequence *seq, int(*apply_fn)(Sequence *, void *), void *arg)
Definition: iterator.c:155
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
Definition: abc_util.cc:115
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1145
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value, ReportList *reports)
Definition: rna_access.c:3673
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2317
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:6514
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
Definition: rna_access.c:3310
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:6685
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6413
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
Definition: rna_access.c:3401
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
Definition: rna_define.c:1892
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1517
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:3675
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
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:3585
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:3771
const EnumPropertyItem rna_enum_unpack_method_items[]
static void SOUND_OT_pack(wmOperatorType *ot)
Definition: sound_ops.c:785
static int sound_open_exec(bContext *UNUSED(C), wmOperator *op)
Definition: sound_ops.c:131
static void SOUND_OT_open(wmOperatorType *ot)
Definition: sound_ops.c:151
static void SOUND_OT_open_mono(wmOperatorType *ot)
Definition: sound_ops.c:178
static int sound_pack_exec(bContext *C, wmOperator *op)
Definition: sound_ops.c:762
static int sound_open_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: sound_ops.c:140
static bool sound_poll(bContext *C)
Definition: sound_ops.c:750
static void SOUND_OT_update_animation_flags(wmOperatorType *ot)
Definition: sound_ops.c:284
static void sound_open_cancel(bContext *UNUSED(C), wmOperator *op)
Definition: sound_ops.c:72
static int sound_mixdown_exec(bContext *C, wmOperator *op)
Definition: sound_ops.c:345
void ED_operatortypes_sound(void)
Definition: sound_ops.c:886
static void SOUND_OT_bake_animation(wmOperatorType *ot)
Definition: sound_ops.c:329
static void sound_update_animation_flags(Scene *scene)
Definition: sound_ops.c:249
static void SOUND_OT_mixdown(wmOperatorType *ot)
Definition: sound_ops.c:670
static void SOUND_OT_unpack(wmOperatorType *ot)
Definition: sound_ops.c:861
static int sound_update_animation_flags_exec(bContext *C, wmOperator *UNUSED(op))
Definition: sound_ops.c:274
static int sound_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: sound_ops.c:830
static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op))
Definition: sound_ops.c:307
static int sound_unpack_exec(bContext *C, wmOperator *op)
Definition: sound_ops.c:802
static void sound_open_init(bContext *C, wmOperator *op)
Definition: sound_ops.c:78
static int sound_update_animation_flags_fn(Sequence *seq, void *user_data)
Definition: sound_ops.c:209
static int sound_mixdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: sound_ops.c:498
Sequence * act_seq
const char * identifier
Definition: RNA_types.h:446
const char * name
Definition: RNA_types.h:450
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
char name[66]
Definition: DNA_ID.h:283
Definition: BKE_main.h:116
ListBase sounds
Definition: BKE_main.h:166
struct PropertyRNA * prop
Definition: RNA_types.h:57
PointerRNA ptr
Definition: RNA_types.h:56
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:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
void(* ui)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:787
bool(* check)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:744
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct ReportList * reports
IDProperty * properties
struct uiLayout * layout
struct wmOperatorType * type
struct PointerRNA * ptr
#define G(x, y, z)
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type, short action, short flag, short display, short sort)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
int WM_operator_filesel(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))