Skip to content
Open
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
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,9 @@
[submodule "3rdparty/xtl"]
path = 3rdparty/xtl
url = https://github.com/xtensor-stack/xtl
[submodule "3rdparty/libadm"]
path = 3rdparty/libadm
url = https://github.com/ebu/libadm
[submodule "3rdparty/libbw64"]
path = 3rdparty/libbw64
url = https://github.com/ebu/libbw64
1 change: 1 addition & 0 deletions 3rdparty/3rdparty.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function(restore_var VAR)
endif()
endfunction()

include(3rdparty/bw64.cmake)
include(3rdparty/dspfilters.cmake)
include(3rdparty/eigen.cmake)
include(3rdparty/gamma.cmake)
Expand Down
14 changes: 14 additions & 0 deletions src/plugins/score-plugin-media/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ set(HDRS ${HDRS}
"${CMAKE_CURRENT_SOURCE_DIR}/Media/Sound/SoundComponent.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Media/Sound/SoundLibraryHandler.hpp"

"${CMAKE_CURRENT_SOURCE_DIR}/Media/Sound/BW64/AdmData.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Media/Sound/BW64/Bw64AdmReader.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Media/Sound/BW64/Bw64Drop.hpp"

"${CMAKE_CURRENT_SOURCE_DIR}/Media/Effect/Settings/Model.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Media/Effect/Settings/Presenter.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Media/Effect/Settings/View.hpp"
Expand Down Expand Up @@ -98,6 +102,9 @@ set(SRCS
"${CMAKE_CURRENT_SOURCE_DIR}/Media/Sound/Drop/SoundDrop.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Media/Sound/SoundComponent.cpp"

"${CMAKE_CURRENT_SOURCE_DIR}/Media/Sound/BW64/Bw64AdmReader.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Media/Sound/BW64/Bw64Drop.cpp"

"${CMAKE_CURRENT_SOURCE_DIR}/Media/Effect/Settings/Model.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Media/Effect/Settings/Presenter.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Media/Effect/Settings/View.cpp"
Expand Down Expand Up @@ -151,8 +158,15 @@ score_generate_command_list_file(${PROJECT_NAME} "${HDRS}")
target_link_libraries(${PROJECT_NAME} PUBLIC
${QT_PREFIX}::Core ${QT_PREFIX}::Widgets
score_lib_base score_plugin_engine score_plugin_library score_plugin_audio score_plugin_dataflow
score_plugin_automation score_plugin_curve
)

# BW64/ADM support for object-based audio
if(TARGET bw64 AND TARGET adm)
target_link_libraries(${PROJECT_NAME} PUBLIC bw64 adm)
target_compile_definitions(${PROJECT_NAME} PUBLIC SCORE_HAS_BW64_ADM)
endif()

### FFMPEG ###
if(EMSCRIPTEN)
target_include_directories(${PROJECT_NAME} PUBLIC ${OSSIA_SDK}/ffmpeg/include)
Expand Down
74 changes: 74 additions & 0 deletions src/plugins/score-plugin-media/Media/Sound/BW64/AdmData.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#pragma once
#include <Process/TimeValue.hpp>

#include <QString>

#include <vector>

namespace Media::BW64
{

struct AdmAutomationPoint
{
double time; // normalized 0-1
double value;
};

struct AdmAutomation
{
enum Parameter
{
X,
Y,
Z,
Gain,
Width,
Height,
Depth,
Diffuse
};

Parameter param{X};
QString name;
double minValue{-1.0};
double maxValue{1.0};
std::vector<AdmAutomationPoint> points;
};

struct AdmAudioObject
{
QString name;
int audioChannelIndex{0}; // Channel index in the WAV file (0-based)
std::vector<AdmAutomation> automations;
};

struct Bw64AdmData
{
QString filePath;
TimeVal duration;
int sampleRate{48000};
int totalChannels{0};
std::vector<AdmAudioObject> objects;

bool isValid() const noexcept { return !objects.empty() && duration > TimeVal::zero(); }
};

// Convert ADM spherical coordinates (azimuth, elevation, distance) to cartesian (x, y, z)
// ADM convention:
// azimuth: 0° = front, +90° = left, -90° = right (degrees)
// elevation: 0° = horizon, +90° = above, -90° = below (degrees)
// distance: 0 to 1 (normalized)
inline void
sphericalToCartesian(double azimuth, double elevation, double distance, double& x, double& y, double& z)
{
constexpr double deg_to_rad = 3.14159265358979323846 / 180.0;
const double az_rad = azimuth * deg_to_rad;
const double el_rad = elevation * deg_to_rad;

// ADM/ossia convention: +Y is front, +X is left, +Z is up
x = std::sin(az_rad) * std::cos(el_rad) * distance;
y = std::cos(az_rad) * std::cos(el_rad) * distance;
z = std::sin(el_rad) * distance;
}

}
Loading
Loading