Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ if(MOD_SOX)
endif()

if(MOD_SPATIALAUDIO)
pkg_check_modules(spatialaudio REQUIRED IMPORTED_TARGET spatialaudio)
pkg_check_modules(spatialaudio REQUIRED IMPORTED_TARGET spatialaudio>=0.4.0)
list(APPEND MLT_SUPPORTED_COMPONENTS spatialaudio)
endif()

Expand Down
44 changes: 24 additions & 20 deletions src/modules/spatialaudio/filter_ambisonic-decoder.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* filter_ambisonic-decoder.cpp -- decode ambisonic audio to speaker channels
* Copyright (C) 2024 Meltytech, LLC
* Copyright (C) 2024-2026 Meltytech, LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Expand All @@ -20,6 +20,8 @@
#include <framework/mlt.h>
#include <spatialaudio/Ambisonics.h>

using namespace spaudio;

static const auto MAX_CHANNELS = 6;
static const auto AMBISONICS_BLOCK_SIZE = 1024;
static const auto AMBISONICS_ORDER = 1;
Expand All @@ -34,11 +36,11 @@ class SpatialAudio
{
private:
mlt_filter m_filter;
CAmbisonicBinauralizer binauralizer;
AmbisonicBinauralizer binauralizer;
unsigned tailLength;
CAmbisonicDecoder decoder;
CAmbisonicProcessor processor;
CAmbisonicZoomer zoomer;
AmbisonicDecoder decoder;
AmbisonicProcessor processor;
AmbisonicZoomer zoomer;
float *speakers[MAX_CHANNELS];

public:
Expand Down Expand Up @@ -72,17 +74,13 @@ class SpatialAudio
{
bool error = false;
bool binaural = channels >= 2 && mlt_properties_get_int(properties(), "binaural");
int sampleRate = mlt_properties_get_int(MLT_FRAME_PROPERTIES(frame), "audio_frequency");

// 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);
error = !binauralizer.Configure(AMBISONICS_ORDER, true, sampleRate, samples, tailLength);
if (!error) {
binauralizer.Reset();
} else {
Expand All @@ -96,10 +94,12 @@ class SpatialAudio
error = !decoder.Configure(AMBISONICS_ORDER,
true,
AMBISONICS_BLOCK_SIZE,
channels == 6 ? kAmblib_51
: channels == 2 ? kAmblib_Stereo
: channels == 4 ? kAmblib_Quad
: kAmblib_CustomSpeakerSetUp,
sampleRate,
channels == 6 ? Amblib_SpeakerSetUps::kAmblib_51
: channels == 2 ? Amblib_SpeakerSetUps::kAmblib_Stereo
: channels == 4
? Amblib_SpeakerSetUps::kAmblib_Quad
: Amblib_SpeakerSetUps::kAmblib_CustomSpeakerSetUp,
channels);
if (!error) {
mlt_log_verbose(MLT_FILTER_SERVICE(filter()),
Expand All @@ -108,7 +108,10 @@ class SpatialAudio
if (!error) {
mlt_log_verbose(MLT_FILTER_SERVICE(filter()),
"configuring spatial audio zoomer\n");
error = !zoomer.Configure(AMBISONICS_ORDER, true, AMBISONICS_BLOCK_SIZE, 0);
error = !zoomer.Configure(AMBISONICS_ORDER,
true,
AMBISONICS_BLOCK_SIZE,
sampleRate);
if (error) {
mlt_log_error(MLT_FILTER_SERVICE(filter()),
"failed to configure spatial audio zoomer\n");
Expand All @@ -125,17 +128,18 @@ class SpatialAudio

// Processing
if (!error) {
CBFormat bformat;
BFormat bformat;
bformat.Configure(AMBISONICS_ORDER, true, samples);
for (unsigned i = 0; i < AMBISONICS_1_CHANNELS; ++i)
bformat.InsertStream(&buffer[samples * i], i, 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.SetOrientation(
Orientation(-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));
Expand Down
21 changes: 12 additions & 9 deletions src/modules/spatialaudio/filter_ambisonic-encoder.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* filter_ambisonic-encoder.cpp -- position mono and stero sound in ambisonic space
* Copyright (C) 2024 Meltytech, LLC
* Copyright (C) 2024-2026 Meltytech, LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Expand All @@ -20,6 +20,8 @@
#include <framework/mlt.h>
#include <spatialaudio/Ambisonics.h>

using namespace spaudio;

// static const auto MAX_CHANNELS = 6;
static const auto AMBISONICS_ORDER = 1;
static const auto AMBISONICS_1_CHANNELS = 4;
Expand All @@ -33,7 +35,7 @@ class SpatialAudioEncoder
{
private:
mlt_filter m_filter;
CAmbisonicEncoder encoder;
AmbisonicEncoder encoder;

public:
SpatialAudioEncoder()
Expand Down Expand Up @@ -69,7 +71,8 @@ class SpatialAudioEncoder
// First time setup
if (!encoder.GetOrder()) {
mlt_log_verbose(MLT_FILTER_SERVICE(filter()), "configuring spatial audio encoder\n");
error = !encoder.Configure(AMBISONICS_ORDER, true, 0);
int sampleRate = mlt_properties_get_int(MLT_FRAME_PROPERTIES(frame), "audio_frequency");
error = !encoder.Configure(AMBISONICS_ORDER, true, sampleRate, 0.f);
if (error) {
mlt_log_error(MLT_FILTER_SERVICE(filter()),
"failed to configure spatial audio encoder\n");
Expand All @@ -78,16 +81,16 @@ class SpatialAudioEncoder

// Processing
if (!error) {
CBFormat bformat;
PolarPoint polar;
BFormat bformat;
PolarPosition<float> polar;
mlt_position position = mlt_filter_get_position(filter(), frame);
mlt_position length = mlt_filter_get_length2(filter(), frame);

bformat.Configure(AMBISONICS_ORDER, true, samples);
polar.fAzimuth = -DegreesToRadians(getDouble("azimuth", position, length));
polar.fElevation = DegreesToRadians(getDouble("elevation", position, length));
polar.fDistance = getDouble("distance", position, length);
encoder.SetPosition(polar, 1.f);
polar.azimuth = -DegreesToRadians(getDouble("azimuth", position, length));
polar.elevation = DegreesToRadians(getDouble("elevation", position, length));
polar.distance = getDouble("distance", position, length);
encoder.SetPosition(polar);
encoder.Refresh();
encoder.Process(buffer, samples, &bformat);
for (int i = 0; i < AMBISONICS_1_CHANNELS; ++i)
Expand Down
Loading