Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix monitoring for objects sharing input audio #258

Merged
merged 7 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ struct GainHolder {
struct ItemRouting {
int inputStartingChannel;
int inputChannelCount;
std::vector<std::vector<float>> direct_;
std::vector<std::vector<float>> diffuse_;
firthm01 marked this conversation as resolved.
Show resolved Hide resolved
};

class SceneGainsCalculator {
Expand All @@ -32,13 +34,12 @@ class SceneGainsCalculator {
Eigen::MatrixXf diffuseGains();

private:
void resize(ear::Layout &ouputLayout, std::size_t inputChannelCount);
int totalOutputChannels;
int totalInputChannels;

void removeItem(const communication::ConnectionId &itemId);
void addOrUpdateItem(const proto::MonitoringItemMetadata &item);

std::vector<std::vector<float>> direct_;
std::vector<std::vector<float>> diffuse_;

ear::GainCalculatorObjects objectCalculator_;
ear::GainCalculatorDirectSpeakers directSpeakersCalculator_;
ear::GainCalculatorHOA hoaCalculator_;
Expand Down
1 change: 0 additions & 1 deletion ear-production-suite-plugins/lib/include/scene_store.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ class SceneStore : public MetadataListener {
void addGroup(proto::ProgrammeElement const& element);
void addToggle(proto::ProgrammeElement const& element);
void sendUpdate();
void flagOverlaps();
};
}

Expand Down
119 changes: 54 additions & 65 deletions ear-production-suite-plugins/lib/src/scene_gains_calculator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,24 @@

namespace {

Eigen::MatrixXf toEigenMat(std::vector<std::vector<float>>& vec) {
auto outputCount = vec.size();
auto inputCount = static_cast<int>(vec[0].size());
Eigen::MatrixXf mat(inputCount, outputCount);
for (std::size_t i = 0; i < outputCount; i++) {
mat.col(static_cast<int>(i)) =
Eigen::VectorXf::Map(vec[i].data(), inputCount);
void addToEigenMat(Eigen::MatrixXf& mat,
std::vector<std::vector<float>> const& gainsTable,
int inputStartingChannelOffset) {
for (int inputChannelCounter = 0; inputChannelCounter < gainsTable.size(); ++inputChannelCounter) {
int inputChannel = inputStartingChannelOffset + inputChannelCounter;
if (inputChannel < mat.cols()) {
mat.col(inputChannel) += Eigen::VectorXf::Map(gainsTable[inputChannelCounter].data(),
gainsTable[inputChannelCounter].size());
}
}
}

void resize2dVector(std::vector<std::vector<float>>& vec, int inputs,
int outputs, float fill = 0.f) {
vec.resize(inputs);
for (auto& subVec : vec) {
subVec.resize(outputs, fill);
}
return mat;
}

}
Expand All @@ -29,8 +38,9 @@ SceneGainsCalculator::SceneGainsCalculator(ear::Layout outputLayout,
int inputChannelCount)
: objectCalculator_{outputLayout},
directSpeakersCalculator_{outputLayout},
hoaCalculator_{outputLayout} {
resize(outputLayout, static_cast<std::size_t>(inputChannelCount));
hoaCalculator_{outputLayout},
totalOutputChannels{static_cast<int>(outputLayout.channels().size())},
totalInputChannels{inputChannelCount} {
commonDefinitionHelper_.getElementRelationships();
}

Expand All @@ -45,15 +55,15 @@ bool SceneGainsCalculator::update(proto::SceneStore store) {
for(auto const&[key, val] : routingCache_) {
cachedIdsChecklist.push_back(key);
}
/// Check-off found items, and also zero original gains for changed items and delete from routing cache to be re-evaluated
/// Check-off found items, and also delete changed items from routing cache to be re-evaluated
for(const auto& item : store.monitoring_items()) {
auto itemId = communication::ConnectionId{ item.connection_id() };
cachedIdsChecklist.erase(std::remove(cachedIdsChecklist.begin(), cachedIdsChecklist.end(), itemId), cachedIdsChecklist.end());
if(item.changed()) {
removeItem(itemId);
}
}
/// Zero original gains for removed items and delete from routing cache (i.e, those that weren't checked-off and therefore remain in cachedIdsChecklist)
/// Delete removed items from routing cache (i.e, those that weren't checked-off and therefore remain in cachedIdsChecklist)
for(const auto& itemId : cachedIdsChecklist) {
removeItem(itemId);
}
Expand All @@ -74,37 +84,32 @@ bool SceneGainsCalculator::update(proto::SceneStore store) {
}

Eigen::MatrixXf SceneGainsCalculator::directGains() {
return toEigenMat(direct_);
Eigen::MatrixXf mat = Eigen::MatrixXf::Zero(totalOutputChannels, totalInputChannels);
for (auto const& [itemId, routing] : routingCache_) {
if (routing.inputStartingChannel >= 0 &&
(routing.inputStartingChannel + routing.inputChannelCount) <
totalInputChannels) {
addToEigenMat(mat, routing.direct_, routing.inputStartingChannel);
}
}
return mat;
}

Eigen::MatrixXf SceneGainsCalculator::diffuseGains() {
return toEigenMat(diffuse_);
}

void SceneGainsCalculator::resize(ear::Layout& outputLayout,
std::size_t inputChannelCount) {
direct_.resize(inputChannelCount);
diffuse_.resize(inputChannelCount);
auto outputChannelCount = outputLayout.channels().size();
for (auto& gainVec : direct_) {
gainVec.resize(outputChannelCount, 0.0f);
}
for (auto& gainVec : diffuse_) {
gainVec.resize(outputChannelCount, 0.0f);
Eigen::MatrixXf mat = Eigen::MatrixXf::Zero(totalOutputChannels, totalInputChannels);
for (auto const& [itemId, routing] : routingCache_) {
if (routing.inputStartingChannel >= 0 &&
(routing.inputStartingChannel + routing.inputChannelCount) <
totalInputChannels) {
addToEigenMat(mat, routing.diffuse_, routing.inputStartingChannel);
}
}
return mat;
}

void SceneGainsCalculator::removeItem(const communication::ConnectionId &itemId)
{
auto itemRouting = getValuePointerFromMap(routingCache_, itemId);
if(itemRouting) {
if(itemRouting->inputStartingChannel >= 0) {
int channelLim = std::min((int)direct_.size(), itemRouting->inputStartingChannel + itemRouting->inputChannelCount);
for(int ch = itemRouting->inputStartingChannel; ch < channelLim; ch++) {
std::fill(direct_[ch].begin(), direct_[ch].end(), 0.0f);
std::fill(diffuse_[ch].begin(), diffuse_[ch].end(), 0.0f);
}
}
if (mapHasKey(routingCache_, itemId)) {
routingCache_.erase(itemId);
}
}
Expand All @@ -117,28 +122,24 @@ void SceneGainsCalculator::addOrUpdateItem(const proto::MonitoringItemMetadata &
auto earMetadata = EpsToEarMetadataConverter::convert(item.ds_metadata());
routing->inputStartingChannel = item.routing();
routing->inputChannelCount = earMetadata.size();
auto finalChannel = routing->inputStartingChannel + routing->inputChannelCount - 1;

if(routing->inputStartingChannel >= 0 && finalChannel < direct_.size()) {
for(int i = 0; i < routing->inputChannelCount; i++) {
auto inputChannel = routing->inputStartingChannel + i;
if(inputChannel >= 0 && inputChannel < direct_.size()) {
directSpeakersCalculator_.calculate(earMetadata.at(i),
direct_[inputChannel]);
}
}
resize2dVector(routing->direct_, routing->inputChannelCount, totalOutputChannels);
resize2dVector(routing->diffuse_, routing->inputChannelCount, totalOutputChannels);
for (int inputChannelCounter = 0; inputChannelCounter < routing->inputChannelCount; inputChannelCounter++) {
directSpeakersCalculator_.calculate(
earMetadata.at(inputChannelCounter),
routing->direct_[inputChannelCounter]);
}
}

if(item.has_obj_metadata()) {
auto earMetadata = EpsToEarMetadataConverter::convert(item.obj_metadata());
routing->inputStartingChannel = item.routing();
routing->inputChannelCount = 1;

if(routing->inputStartingChannel >= 0 && routing->inputStartingChannel < direct_.size()) {
objectCalculator_.calculate(earMetadata, direct_[routing->inputStartingChannel],
diffuse_[routing->inputStartingChannel]);
}
resize2dVector(routing->direct_, routing->inputChannelCount, totalOutputChannels);
resize2dVector(routing->diffuse_, routing->inputChannelCount, totalOutputChannels);
objectCalculator_.calculate(earMetadata,
routing->direct_[0],
routing->diffuse_[0]);
}

if(item.has_hoa_metadata()) {
Expand All @@ -149,21 +150,9 @@ void SceneGainsCalculator::addOrUpdateItem(const proto::MonitoringItemMetadata &
}
routing->inputStartingChannel = item.routing();
routing->inputChannelCount = earMetadata.degrees.size();
auto finalChannel = routing->inputStartingChannel + routing->inputChannelCount - 1;

if(routing->inputStartingChannel >= 0 && finalChannel < direct_.size()) {
std::vector<std::vector<float>> hoaGains(
routing->inputChannelCount,
std::vector<float>(direct_[0].size(), 0));
hoaCalculator_.calculate(earMetadata, hoaGains);

for(int i = 0; i < routing->inputChannelCount; i++) {
auto inputChannel = routing->inputStartingChannel + i;
if(inputChannel >= 0 && inputChannel < direct_.size()) {
direct_[inputChannel] = hoaGains[i];
}
}
}
resize2dVector(routing->direct_, routing->inputChannelCount, totalOutputChannels);
resize2dVector(routing->diffuse_, routing->inputChannelCount, totalOutputChannels);
hoaCalculator_.calculate(earMetadata, routing->direct_);
}

if(item.has_bin_metadata()) {
Expand Down
16 changes: 0 additions & 16 deletions ear-production-suite-plugins/lib/src/scene_store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ void SceneStore::dataReset(const ear::plugin::proto::ProgrammeStore &programmes,
}
}
}

flagOverlaps();
}

void ear::plugin::SceneStore::programmeSelected(const ear::plugin::ProgrammeObjects &objects) {
Expand All @@ -46,7 +44,6 @@ void ear::plugin::SceneStore::programmeSelected(const ear::plugin::ProgrammeObje
for(auto const& object : objects) {
addMonitoringItem(object.inputMetadata);
}
flagOverlaps();
}

void ear::plugin::SceneStore::itemsAddedToProgramme(ear::plugin::ProgrammeStatus status,
Expand All @@ -55,7 +52,6 @@ void ear::plugin::SceneStore::itemsAddedToProgramme(ear::plugin::ProgrammeStatus
for (auto const &object: objects) {
addMonitoringItem(object.inputMetadata);
}
flagOverlaps();
}
}

Expand All @@ -78,7 +74,6 @@ void ear::plugin::SceneStore::itemRemovedFromProgramme(ear::plugin::ProgrammeSta
item != monitoringItems->end()) {
monitoringItems->erase(item);
itemsChangedSinceLastSend.insert(id);
flagOverlaps();
}
}
}
Expand All @@ -89,9 +84,6 @@ bool SceneStore::updateMonitoringItem(proto::InputItemMetadata const& inputItem)
item != monitoringItems->end()) {
auto routingChanged = item->routing() != inputItem.routing();
setMonitoringItemFrom(*item, inputItem);
if(routingChanged) {
flagOverlaps();
}
return true;
} else {
return false;
Expand All @@ -103,7 +95,6 @@ void ear::plugin::SceneStore::programmeItemUpdated(ear::plugin::ProgrammeStatus
if(status.isSelected) {
if(!updateMonitoringItem(object.inputMetadata)) {
addMonitoringItem(object.inputMetadata);
flagOverlaps();
}
}
}
Expand Down Expand Up @@ -247,10 +238,3 @@ void SceneStore::exporting(bool isExporting) {
}
}

void SceneStore::flagOverlaps() {
// Keep it simple - for any routing/monitoring mix changes
// Set changed on all items
for(auto& item : store_.all_available_items()) {
itemsChangedSinceLastSend.insert(item.connection_id());
}
}
Loading