Program Listing for File directspeaker_conversion.hpp
↰ Return to documentation for file (include/eat/process/directspeaker_conversion.hpp)
//
// Created by Richard Bailey on 05/08/2022.
//
#pragma once
#include <adm/elements_fwd.hpp>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>
#include "eat/process/adm_bw64.hpp"
namespace eat::process {
struct CartesianPosition {
float x;
float y;
float z;
};
namespace detail {
struct SpeakerData {
std::string audioChannelFormatName;
std::string speakerLabel;
CartesianPosition pos;
};
const SpeakerData Left{"RoomCentricLeft", "RC_L", {-1.0, 1.0, 0.0}};
const SpeakerData Right{"RoomCentricRight", "RC_R", {1.0, 1.0, 0.0}};
const SpeakerData Center{"RoomCentricCenter", "RC_C", {0.0, 1.0, 0.0}};
const SpeakerData LFE{"RoomCentricLFE", "RC_LFE", {-1.0, 1.0, -1.0}};
const SpeakerData LeftSurround{"RoomCentricLeftSurround", "RC_Ls", {-1.0, -0.363970, 0.0}};
const SpeakerData RightSurround{"RoomCentricRightSurround", "RC_Rs", {1.0, -0.363970, 0.0}};
const SpeakerData LeftSideSurround{"RoomCentricLeftSideSurround", "RC_Lss", {-1.0, 0.0, 0.0}};
const SpeakerData RightSideSurround{"RoomCentricRightSideSurround", "RC_Rss", {1.0, 0.0, 0.0}};
const SpeakerData LeftRearSurround{"RoomCentricLeftRearSurround", "RC_Lrs", {-1.0, -1.0, 0.0}};
const SpeakerData RightRearSurround{"RoomCentricRightRearSurround", "RC_Rrs", {1.0, -1.0, 0.0}};
const SpeakerData LeftTopSurround{"RoomCentricLeftTopSurround", "RC_Lts", {-1.0, 0.0, 1.0}};
const SpeakerData RightTopSurround{"RoomCentricRightTopSurround", "RC_Rts", {1.0, 0.0, 1.0}};
/* TODO: add all packs */
/* TODO: deal with zeroing non existing buffers */
const std::map<std::string, std::vector<SpeakerData>> common_pack_to_atmos_speaker_map{
/* 2.0 */
{"AP_00010002", {Left, Right}},
/* 3.0 */
{"AP_0001000a", {Left, Right, Center}},
/* 5.0 */
{"AP_0001000c", {Left, Right, Center, LeftSurround, RightSurround}},
/* 5.1 */
{"AP_00010003", {Left, Right, Center, LFE, LeftSurround, RightSurround}},
/* 7.1back */
{"AP_0001000f",
{Left, Right, Center, LFE, LeftSideSurround, RightSideSurround, LeftRearSurround, RightRearSurround}},
/* 7.1.2*/
{"AP_00010016",
{Left, Right, Center, LFE, LeftSideSurround, RightSideSurround, LeftRearSurround, RightRearSurround,
LeftTopSurround, RightTopSurround}},
};
struct DSChannel {
std::string audioChannelFormatName;
std::shared_ptr<adm::AudioChannelFormat> channel;
std::shared_ptr<adm::AudioTrackFormat> track;
std::shared_ptr<adm::AudioStreamFormat> stream;
};
using PackConversionLookup = std::map<std::string, std::vector<SpeakerData>>;
struct ConvertibleLayout {
std::vector<std::shared_ptr<adm::AudioTrackUid>> uids;
std::vector<SpeakerData> target_layout;
};
using TargetLayoutMap = std::unordered_map<std::shared_ptr<adm::AudioPackFormat>, ConvertibleLayout>;
struct MappedPack {
std::shared_ptr<adm::AudioPackFormat> target;
std::vector<DSChannel> elements;
};
using MappedPacks = std::unordered_map<std::shared_ptr<adm::AudioPackFormat>, MappedPack>;
using MappedUids = std::unordered_map<std::shared_ptr<adm::AudioTrackUid>, std::shared_ptr<adm::AudioTrackUid>>;
/*
* For each AudioPackFormat in the input document that
* a) is referenced by an AudioTrackUID in the document
* b) has a pack ID that is a key in the provided layoutMap
* Return a mapping from that pack format to a target speaker layout
*/
TargetLayoutMap find_target_layouts(adm::Document &document, PackConversionLookup const &layoutMap);
/*
* Returns a set of all speakers used in the mapped target layouts
*/
std::vector<SpeakerData> mapped_speaker_set(TargetLayoutMap const &layouts);
/*
* For each speaker provided, create an AudioChannelFormat, AudioTrackFormat, and AudioStreamFormat that reference each
* other.
*/
std::vector<DSChannel> convert_speakers(std::vector<SpeakerData> const &speakerData);
/*
* For each target layout, return a mapping from the original AudioPackFormat, to a target AudioPackFormat and vector of
* objects that represent speakers in that layout (AudioChannelFormat, AudioTrackFormat, AudioStreamFormat)
*/
MappedPacks create_converted_packs(TargetLayoutMap const &layoutMap, std::vector<DSChannel> const &convertedChannels);
/*
* For every uid in the document, if it references a mapped pack, create a replacement that references the target pack.
* Return a mapping from the mapped document uids to the replacement uids
*/
MappedUids create_converted_uids(adm::Document &document, MappedPacks const &packs);
/*
* For every AudioObject that references a mapped AudioTrackUid, change the reference to point to the replacement uid
* Remove all mapped uids, add all replacement uids to the document
* (This also adds their referenced AudioTrackFormat, AudioPackFormat, AudioStreamFormat elements)
* For mapped AudioTrackUids, replace their IDs in the channel map with their replacements.
*/
void replace_layouts(adm::Document &doc, channel_map_t &channel_map, MappedUids const &uids);
/*
* For every pack format reference in every AudioObject, if the referred pack has been converted, replace the reference
* with one to the new pack.
*/
void replace_object_pack_references(adm::Document &doc, MappedPacks const &packMap);
} // namespace detail
} // namespace eat::process