Skip to content

Commit

Permalink
add binaural boolean property to ambisonic-decoder
Browse files Browse the repository at this point in the history
  • Loading branch information
ddennedy committed Feb 17, 2024
1 parent 00f42b4 commit 74828c0
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 36 deletions.
103 changes: 67 additions & 36 deletions src/modules/spatialaudio/filter_ambisonic-decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class SpatialAudio
{
private:
mlt_filter m_filter;
CAmbisonicBinauralizer binauralizer;
unsigned tailLength;
CAmbisonicDecoder decoder;
CAmbisonicProcessor processor;
CAmbisonicZoomer zoomer;
Expand All @@ -56,20 +58,38 @@ class SpatialAudio
m_filter->close = nullptr;
m_filter->parent.close = nullptr;
mlt_service_close(MLT_FILTER_SERVICE(m_filter));
m_filter = nullptr;
}

mlt_filter filter() { return m_filter; }
mlt_properties properties() { return MLT_FILTER_PROPERTIES(filter()); }
double getDouble(const char *name, int position, int length)
{
return mlt_properties_anim_get_double(properties(), name, position, length);
}

bool getAudio(mlt_frame frame, float *buffer, int samples, int channels)
{
m_filter = nullptr;
}

mlt_filter filter() { return m_filter; }
mlt_properties properties() { return MLT_FILTER_PROPERTIES(filter()); }
double getDouble(const char *name, int position, int length)
{
return mlt_properties_anim_get_double(properties(), name, position, length);
}

bool getAudio(mlt_frame frame, float *buffer, int samples, int channels)
{
bool error = false;
if (decoder.GetChannelCount() == 0) {
bool binaural = channels == 2 && mlt_properties_get_int(properties(), "binaural");

// First time setup
if (binaural && !binauralizer.GetChannelCount()) {
mlt_log_verbose(MLT_FILTER_SERVICE(filter()),
"configuring spatial audio binauralizer\n");
error = !binauralizer.Configure(AMBISONICS_ORDER,
true,
mlt_properties_get_int(MLT_FRAME_PROPERTIES(frame),
"audio_frequency"),
samples,
tailLength);
if (!error) {
binauralizer.Reset();
} else {
mlt_log_error(MLT_FILTER_SERVICE(filter()),
"failed to configure spatial audio binauralizer\n");
}
} else if (!binaural && !decoder.GetChannelCount()) {
mlt_log_verbose(MLT_FILTER_SERVICE(filter()),
"configuring spatial audio decoder for %d channels\n",
channels);
Expand All @@ -89,48 +109,59 @@ class SpatialAudio
mlt_log_verbose(MLT_FILTER_SERVICE(filter()),
"configuring spatial audio zoomer\n");
error = !zoomer.Configure(AMBISONICS_ORDER, true, AMBISONICS_BLOCK_SIZE, 0);
if (error) {
mlt_log_error(MLT_FILTER_SERVICE(filter()),
"failed to configure spatial audio zoomer\n");
}
} else {
mlt_log_error(MLT_FILTER_SERVICE(filter()),
"failed to configure spatial audio zoomer\n");
"failed to configure spatial audio processor\n");
}
} else {
mlt_log_error(MLT_FILTER_SERVICE(filter()),
"failed to configure spatial audio processor\n");
"failed to configure spatial audio decoder\n");
}
}

// Processing
if (!error) {
CBFormat bformat;
bformat.Configure(1, true, samples);
bformat.Configure(AMBISONICS_ORDER, true, samples);
for (unsigned i = 0; i < AMBISONICS_1_CHANNELS; ++i)
bformat.InsertStream(&buffer[samples * i], i, samples);

mlt_position position = mlt_filter_get_position(filter(), frame);
mlt_position length = mlt_filter_get_length2(filter(), frame);
processor.SetOrientation({-DegreesToRadians(getDouble("yaw", position, length)),
DegreesToRadians(getDouble("pitch", position, length)),
DegreesToRadians(getDouble("roll", position, length))});
processor.Refresh();
processor.Process(&bformat, samples);
zoomer.SetZoom(getDouble("zoom", position, length));
zoomer.Refresh();
zoomer.Process(&bformat, samples);
if (!binaural) {
mlt_position position = mlt_filter_get_position(filter(), frame);
mlt_position length = mlt_filter_get_length2(filter(), frame);
processor.SetOrientation({-DegreesToRadians(getDouble("yaw", position, length)),
DegreesToRadians(getDouble("pitch", position, length)),
DegreesToRadians(getDouble("roll", position, length))});
processor.Refresh();
processor.Process(&bformat, samples);
zoomer.SetZoom(getDouble("zoom", position, length));
zoomer.Refresh();
zoomer.Process(&bformat, samples);
}

if (channels == 6) {
// libspatialaudio has a different channel order for 5.1
speakers[0] = &buffer[samples * 0]; // left
speakers[1] = &buffer[samples * 1]; // right
speakers[2] = &buffer[samples * 4]; // center
speakers[3] = &buffer[samples * 5]; // LFE (subwoofer)
speakers[4] = &buffer[samples * 2]; // left surround
speakers[5] = &buffer[samples * 3]; // right surround
decoder.Process(&bformat, samples, speakers);
} else if (channels == 4 && mlt_properties_get_int(properties(), "ambisonic")) {
for (int i = 0; i < channels; ++i)
bformat.ExtractStream(&buffer[samples * i], i, samples);
} else {
for (int i = 0; i < channels; ++i)
speakers[i] = &buffer[samples * i];
speakers[3] = &buffer[samples * 5]; // LFE (subwoofer)
speakers[4] = &buffer[samples * 2]; // left surround
speakers[5] = &buffer[samples * 3]; // right surround
decoder.Process(&bformat, samples, speakers);
} else if (channels == 4 && mlt_properties_get_int(properties(), "ambisonic")) {
for (int i = 0; i < channels; ++i)
bformat.ExtractStream(&buffer[samples * i], i, samples);
} else {
for (int i = 0; i < channels; ++i)
speakers[i] = &buffer[samples * i];
if (binaural)
binauralizer.Process(&bformat, speakers, samples);
else
decoder.Process(&bformat, samples, speakers);
}
}
return error;
Expand Down
9 changes: 9 additions & 0 deletions src/modules/spatialaudio/filter_ambisonic-decoder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,12 @@ parameters:
type: boolean
default: 0
mutable: yes

- identifier: binaural
title: Binaural Output
description: >
This indicates whether to render as binaural instead of stereo.
This only applies when the channel count is 2.
type: boolean
default: 0
mutable: no

0 comments on commit 74828c0

Please sign in to comment.