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
This commit is contained in:
Aras Pranckevicius
2025-01-10 12:26:24 +01:00
committed by Aras Pranckevicius
parent 6a865a2265
commit 64f1f29a50
7 changed files with 24 additions and 3 deletions

View File

@@ -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.";
}

View File

@@ -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.

View File

@@ -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);

View File

@@ -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;

View File

@@ -36,7 +36,8 @@ enum Container
CONTAINER_MP2,
CONTAINER_MP3,
CONTAINER_OGG,
CONTAINER_WAV
CONTAINER_WAV,
CONTAINER_AAC
};
/// Audio codecs for writers.

View File

@@ -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.");

View File

@@ -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);