From 64f1f29a5081f9a8369b3022f406b2de20eee99d Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Fri, 10 Jan 2025 12:26:24 +0100 Subject: [PATCH] Audio: add AAC and Opus to Render Audio operator There's a "Render -> Render Audio" operator that pretty much calls into Audaspace functionality directly. This PR adds two new options in there, that boThere's a "Render -> Render Audio" operator that pretty much calls into Audaspace functionality directly. This PR adds two new options in there, that both feel like an oversight: - There's an option for AAC container, when someone wants to render into .aac file. Previously you could render AAC audio, but only in MKV (Matroska) container. This is a user request #131980. - When using MKV (Matroska) or Ogg container, it did not list Opus as an audio codec that can be used. This felt like an oversight; both the rest of Blender and Audaspace can handle that, jus the option was not spelled out in the RNA enums. Pull Request: https://projects.blender.org/blender/blender/pulls/132877th feel like an oversight: - There's an option for AAC container, when someone wants to render into `.aac` file. Previously you _could_ render AAC audio, but only in MKV (Matroska) container. This is a user request #131980. - When using MKV (Matroska) or Ogg container, it did not list Opus as an audio codec that can be used. This felt like an oversight; both the rest of Blender and Audaspace can handle that, jus the option was not spelled out in the RNA enums. Note however that without fix in #132872 the Matroska container continues to be useless in that it produces wrong result. Upstream Audaspace PR for the 2nd point: https://github.com/neXyon/audaspace/pull/47 (was just merged!) Pull Request: https://projects.blender.org/blender/blender/pulls/132877 --- extern/audaspace/bindings/C/AUD_Sound.cpp | 5 +++++ extern/audaspace/bindings/C/AUD_Types.h | 3 ++- extern/audaspace/bindings/python/PyAPI.cpp | 1 + extern/audaspace/bindings/python/PySound.cpp | 5 +++++ extern/audaspace/include/file/IWriter.h | 3 ++- extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp | 2 +- source/blender/editors/sound/sound_ops.cc | 8 ++++++++ 7 files changed, 24 insertions(+), 3 deletions(-) diff --git a/extern/audaspace/bindings/C/AUD_Sound.cpp b/extern/audaspace/bindings/C/AUD_Sound.cpp index 06ed6de6693..8398f9c5a6f 100644 --- a/extern/audaspace/bindings/C/AUD_Sound.cpp +++ b/extern/audaspace/bindings/C/AUD_Sound.cpp @@ -208,6 +208,8 @@ AUD_API const char* AUD_Sound_write(AUD_Sound* sound, const char* filename, AUD_ container = AUD_CONTAINER_OGG; else if(extension == ".wav") container = AUD_CONTAINER_WAV; + else if(extension == ".aac") + container = AUD_CONTAINER_AAC; else return invalid_container_error; } @@ -237,6 +239,9 @@ AUD_API const char* AUD_Sound_write(AUD_Sound* sound, const char* filename, AUD_ case AUD_CONTAINER_WAV: codec = AUD_CODEC_PCM; break; + case AUD_CONTAINER_AAC: + codec = AUD_CODEC_AAC; + break; default: return "Unknown container, cannot select default codec."; } diff --git a/extern/audaspace/bindings/C/AUD_Types.h b/extern/audaspace/bindings/C/AUD_Types.h index f0f4e66851c..2a6e5d516eb 100644 --- a/extern/audaspace/bindings/C/AUD_Types.h +++ b/extern/audaspace/bindings/C/AUD_Types.h @@ -73,7 +73,8 @@ typedef enum AUD_CONTAINER_MP2, AUD_CONTAINER_MP3, AUD_CONTAINER_OGG, - AUD_CONTAINER_WAV + AUD_CONTAINER_WAV, + AUD_CONTAINER_AAC, } AUD_Container; /// Audio codecs for writers. diff --git a/extern/audaspace/bindings/python/PyAPI.cpp b/extern/audaspace/bindings/python/PyAPI.cpp index cceadbc0992..16c7b662563 100644 --- a/extern/audaspace/bindings/python/PyAPI.cpp +++ b/extern/audaspace/bindings/python/PyAPI.cpp @@ -167,6 +167,7 @@ PyInit_aud() PY_MODULE_ADD_CONSTANT(module, CONTAINER_MP3); PY_MODULE_ADD_CONSTANT(module, CONTAINER_OGG); PY_MODULE_ADD_CONSTANT(module, CONTAINER_WAV); + PY_MODULE_ADD_CONSTANT(module, CONTAINER_AAC); // distance model constants PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_EXPONENT); PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_EXPONENT_CLAMPED); diff --git a/extern/audaspace/bindings/python/PySound.cpp b/extern/audaspace/bindings/python/PySound.cpp index d99038e0caa..4a598ea8bc5 100644 --- a/extern/audaspace/bindings/python/PySound.cpp +++ b/extern/audaspace/bindings/python/PySound.cpp @@ -233,6 +233,8 @@ Sound_write(Sound* self, PyObject* args, PyObject* kwds) container = CONTAINER_OGG; else if(extension == ".wav") container = CONTAINER_WAV; + else if(extension == ".aac") + container = CONTAINER_AAC; else { PyErr_SetString(AUDError, invalid_container_error); @@ -265,6 +267,9 @@ Sound_write(Sound* self, PyObject* args, PyObject* kwds) case CONTAINER_WAV: codec = CODEC_PCM; break; + case CONTAINER_AAC: + codec = CODEC_AAC; + break; default: PyErr_SetString(AUDError, "Unknown container, cannot select default codec."); return nullptr; diff --git a/extern/audaspace/include/file/IWriter.h b/extern/audaspace/include/file/IWriter.h index 96decdda391..01d6ed926fb 100644 --- a/extern/audaspace/include/file/IWriter.h +++ b/extern/audaspace/include/file/IWriter.h @@ -36,7 +36,8 @@ enum Container CONTAINER_MP2, CONTAINER_MP3, CONTAINER_OGG, - CONTAINER_WAV + CONTAINER_WAV, + CONTAINER_AAC }; /// Audio codecs for writers. diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp index 1a6a8f1688c..10a80bc6f9b 100644 --- a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp +++ b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp @@ -179,7 +179,7 @@ FFMPEGWriter::FFMPEGWriter(const std::string &filename, DeviceSpecs specs, Conta m_input_samples(0), m_deinterleave(false) { - static const char* formats[] = { nullptr, "ac3", "flac", "matroska", "mp2", "mp3", "ogg", "wav" }; + static const char* formats[] = { nullptr, "ac3", "flac", "matroska", "mp2", "mp3", "ogg", "wav", "adts" }; if(avformat_alloc_output_context2(&m_formatCtx, nullptr, formats[format], filename.c_str()) < 0) AUD_THROW(FileException, "File couldn't be written, format couldn't be found with ffmpeg."); diff --git a/source/blender/editors/sound/sound_ops.cc b/source/blender/editors/sound/sound_ops.cc index 56a5d043ef2..6b46c4ca942 100644 --- a/source/blender/editors/sound/sound_ops.cc +++ b/source/blender/editors/sound/sound_ops.cc @@ -411,6 +411,7 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op) #ifdef WITH_AUDASPACE static const EnumPropertyItem container_items[] = { # ifdef WITH_FFMPEG + {AUD_CONTAINER_AAC, "AAC", 0, "AAC", "Advanced Audio Coding"}, {AUD_CONTAINER_AC3, "AC3", 0, "AC3", "Dolby Digital ATRAC 3"}, # endif {AUD_CONTAINER_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"}, @@ -540,12 +541,14 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op) {AUD_CODEC_MP2, "MP2", 0, "MP2", "MPEG-1 Audio Layer II"}, {AUD_CODEC_MP3, "MP3", 0, "MP3", "MPEG-2 Audio Layer III"}, {AUD_CODEC_PCM, "PCM", 0, "PCM", "Pulse Code Modulation (RAW)"}, + {AUD_CODEC_OPUS, "OPUS", 0, "Opus", "Opus Interactive Audio Codec"}, {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"}, {0, nullptr, 0, nullptr, nullptr}, }; static const EnumPropertyItem ogg_codec_items[] = { {AUD_CODEC_FLAC, "FLAC", 0, "FLAC", "Free Lossless Audio Codec"}, + {AUD_CODEC_OPUS, "OPUS", 0, "Opus", "Opus Interactive Audio Codec"}, {AUD_CODEC_VORBIS, "VORBIS", 0, "Vorbis", "Xiph.Org Vorbis Codec"}, {0, nullptr, 0, nullptr, nullptr}, }; @@ -571,6 +574,11 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op) RNA_def_property_flag(prop_format, PROP_HIDDEN); switch (container) { + case AUD_CONTAINER_AAC: + RNA_def_property_enum_items(prop_codec, all_codec_items); + RNA_enum_set(op->ptr, "codec", AUD_CODEC_AAC); + RNA_enum_set(op->ptr, "format", AUD_FORMAT_FLOAT32); + break; case AUD_CONTAINER_AC3: RNA_def_property_enum_items(prop_codec, all_codec_items); RNA_enum_set(op->ptr, "codec", AUD_CODEC_AC3);