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

128 channel support with user feedback #254

Merged
merged 34 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
40283ca
Initial changes for 128 channels
firthm01 Apr 3, 2023
5df3fdd
Remove unused 64-channel limited funcs
firthm01 Apr 6, 2023
8d34671
Update test for channel out-of-bounds
firthm01 Apr 6, 2023
bc48869
rn global_config.h daw_channel_count.h
firthm01 Oct 4, 2023
a11a9b5
Funcs to get DAW channel count
firthm01 Oct 4, 2023
9cfcce3
Full bus routing uses api.GetDawChannelCount()
firthm01 Oct 4, 2023
aa10ba2
EAR UniqueValueAssigner should only use currently available channels
firthm01 Oct 5, 2023
546daa4
EarComboBoxEntry::setSelectable and make visible changes
firthm01 Oct 6, 2023
bd62ad9
getEntryById to retrieve EarComboBoxEntry object
firthm01 Oct 6, 2023
0e38b33
getPopup method so parent classes can access entries
firthm01 Oct 6, 2023
3fd8fb6
Impl DAW channel count UI changes in Obj plugin
firthm01 Oct 6, 2023
cee7e33
add*Entry methods return the constructed entry
firthm01 Oct 6, 2023
b43d110
Impl DAW channel count UI changes in HOA plugin
firthm01 Oct 6, 2023
f15d61d
Impl DAW channel count UI changes in DS plugin
firthm01 Oct 6, 2023
2768bc0
Error message for missing AXML/CHNA chunk
firthm01 Oct 10, 2023
4f2dd24
Routing info tooltip on REAPER <v7 (Obj plugin)
firthm01 Oct 11, 2023
d031971
Routing info tooltip on REAPER <v7 (HOA plugin)
firthm01 Oct 11, 2023
4099b4e
Routing info tooltip on REAPER <v7 (DS plugin)
firthm01 Oct 11, 2023
935f83c
Recentre the DS meters
firthm01 Oct 12, 2023
ed555b8
Import classes support receiving warning messages
firthm01 Oct 11, 2023
1623858
Import dialog only closes automatically if no warnings occurred
firthm01 Oct 11, 2023
6fd222d
Handle ImportStatus::COMPLETE state only once
firthm01 Oct 11, 2023
8060c7d
PluginSuites can pass back error messages
firthm01 Oct 12, 2023
8fd1516
Show warnings to user
firthm01 Oct 12, 2023
c3d70d0
Might as well implement warnings about unsupported PFs
firthm01 Oct 12, 2023
b2ec02f
Fix missing include
firthm01 Oct 17, 2023
86e2890
Show ear-plugin-base headers in IDE
firthm01 Nov 2, 2023
2d08f3b
Move common vst-reaper integration code into separate header
firthm01 Nov 2, 2023
c0bd7fc
Move registerPluginLoad code to reaper_integration
firthm01 Nov 2, 2023
f8df265
Move requestInputInstanceId code to reaper_integration
firthm01 Nov 2, 2023
9076ff2
Make MAX_DAW_CHANNELS a constexpr
firthm01 Nov 2, 2023
731d434
Use static_cast over c-sytle
firthm01 Nov 2, 2023
0948108
Common setup code for Routing Info Icon
firthm01 Nov 2, 2023
a7d37bc
Common positioning code for Routing Info Icon
firthm01 Nov 2, 2023
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
7 changes: 5 additions & 2 deletions ear-production-suite-plugins/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set(EAR_PROTO_INPUT

protobuf_generate_cpp(EAR_PROTO_SRC EAR_PROTO_HDR ${EAR_PROTO_INPUT})

add_library(ear-plugin-base STATIC
set(EAR_BASE_SOURCES
src/communication/commands.cpp
src/communication/metadata_sender.cpp
src/communication/direct_speakers_metadata_sender.cpp
Expand Down Expand Up @@ -56,7 +56,7 @@ add_library(ear-plugin-base STATIC
${EAR_PROTO_SRC} src/restored_pending_store.cpp
)

set(EAR_BASE_HEADERS
set(EAR_BASE_HEADERS
include/binaural_monitoring_audio_processor.hpp
include/binaural_monitoring_backend.hpp
include/communication/commands.hpp
Expand Down Expand Up @@ -131,10 +131,13 @@ set(EAR_BASE_HEADERS
include/scene_store.hpp
include/communication/metadata_thread.hpp
include/auto_mode_controller.hpp
include/reaper_integration.hpp
include/reaper_vst3_interfaces.h
${EPS_SHARED_DIR}/helper/container_helpers.hpp
${EPS_SHARED_DIR}/speaker_setups.hpp
)

add_library(ear-plugin-base STATIC ${EAR_BASE_HEADERS} ${EAR_BASE_SOURCES})
set_source_files_properties(${EAR_PROTO_INPUT} PROPERTIES HEADER_ONLY TRUE)
source_group("Header Files" FILES ${EAR_BASE_HEADERS})
target_sources(ear-plugin-base PRIVATE ${EAR_PROTO_INPUT} ${EAR_BASE_HEADERS})
Expand Down
44 changes: 44 additions & 0 deletions ear-production-suite-plugins/lib/include/reaper_integration.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#pragma once

#include <functional>
#include <string>

#include "reaper_vst3_interfaces.h"
#include <daw_channel_count.h>

inline int DetermineChannelCount(IReaperHostApplication* reaperHostPtr) {
if (!reaperHostPtr) {
return MAX_DAW_CHANNELS;
}
auto getAppVersionPtr = reaperHostPtr->getReaperApi("GetAppVersion");
if (!getAppVersionPtr) {
return MAX_DAW_CHANNELS;
}
return GetReaperChannelCount(getAppVersionPtr);
}

// When a plugin is initialised, it should register itself with the extension using this function
// A callback function should be provided as an argument,
// which the extension will use to return XML data to set the plugin state
inline bool registerPluginLoadWithExtension(
IReaperHostApplication* reaperHostPtr,
std::function<void(std::string const& xmlStateData)> callback) {
if (!reaperHostPtr) return false;
void registerPluginLoadSig(std::function<void(std::string const&)>);
auto registerPluginLoadPtr = reaperHostPtr->getReaperApi("registerPluginLoad");
if (!registerPluginLoadPtr) return false;
auto registerPluginLoad = reinterpret_cast<decltype(&registerPluginLoadSig)>(registerPluginLoadPtr);
registerPluginLoad(callback);
return true;
}

// Queries the extension to get a unique ID for a plugin instance
inline uint32_t requestInstanceIdFromExtension(
IReaperHostApplication* reaperHostPtr) {
if(!reaperHostPtr) return 0;
uint32_t requestInputInstanceIdSig();
auto requestInputInstanceIdPtr = reaperHostPtr->getReaperApi("requestInputInstanceId");
if (!requestInputInstanceIdPtr) return 0;
auto requestInputInstanceId = reinterpret_cast<decltype(&requestInputInstanceIdSig)>(requestInputInstanceIdPtr);
return requestInputInstanceId();
}
2 changes: 1 addition & 1 deletion ear-production-suite-plugins/lib/src/store_metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ void Metadata::setElementOrder(const ProgrammeInternalId &progId, const std::vec
}

// This is horribly inefficient algorithm wise (O(n^2)?).
// OTOH, order.size() is always <= 64 so a linear vector search probably still wins over a map. (it may fit in cache.)
// OTOH, order.size() is probably <= 128 (unless asset reuse and huge project) so a linear vector search probably still wins over a map. (it may fit in cache.)
// If this ends up profiling slow, try changing it.
// This should only be called rarely (on a routing change in auto mode or an element move in the GUI),
// so it's not on a hot path.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "variable_block_adapter.hpp"
#include <version/eps_version.h>
#include <helper/resource_paths_juce-file.hpp>
#include <daw_channel_count.h>

#define DEFAULT_OSC_PORT 8000

Expand Down Expand Up @@ -108,8 +109,8 @@ EarBinauralMonitoringAudioProcessor::EarBinauralMonitoringAudioProcessor()
bypass_->setValueNotifyingHost(bypass_->get());
};

backend_ =
std::make_unique<ear::plugin::BinauralMonitoringBackend>(nullptr, 64);
backend_ = std::make_unique<ear::plugin::BinauralMonitoringBackend>(
nullptr, MAX_DAW_CHANNELS);
connector_ =
std::make_unique<ui::BinauralMonitoringJuceFrontendConnector>(this);
connector_->setListenerOrientationInstance(backend_->listenerOrientation);
Expand Down Expand Up @@ -158,7 +159,7 @@ EarBinauralMonitoringAudioProcessor::EarBinauralMonitoringAudioProcessor()

std::lock_guard<std::mutex> lock(processorMutex_);
processor_ = std::make_unique<ear::plugin::BinauralMonitoringAudioProcessor>(
64, 64, 64, 48000, 512,
MAX_DAW_CHANNELS, MAX_DAW_CHANNELS, MAX_DAW_CHANNELS, 48000, 512,
bearDataFilePath); // Used to verify if BEAR can be initialised - can't
// get SR and block size in ctor. Made assumption -
// prepareToPlay will be called with correct values
Expand Down Expand Up @@ -218,7 +219,7 @@ void EarBinauralMonitoringAudioProcessor::timerCallback() {
juce::AudioProcessor::BusesProperties
EarBinauralMonitoringAudioProcessor::_getBusProperties() {
auto ret = BusesProperties().withInput(
"Input", AudioChannelSet::discreteChannels(64), true);
"Input", AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS), true);
ret = ret.withOutput("Left Ear", AudioChannelSet::mono(), true);
ret = ret.withOutput("Right Ear", AudioChannelSet::mono(), true);
ret = ret.withOutput("(Unused)", AudioChannelSet::discreteChannels(62), true);
Expand Down Expand Up @@ -307,7 +308,9 @@ void EarBinauralMonitoringAudioProcessor::prepareToPlay(double sampleRate,
if (!processor_ || !processor_->configMatches(sampleRate, samplesPerBlock)) {
processor_ =
std::make_unique<ear::plugin::BinauralMonitoringAudioProcessor>(
64, 64, 64, sampleRate, samplesPerBlock, bearDataFilePath);
MAX_DAW_CHANNELS, MAX_DAW_CHANNELS, MAX_DAW_CHANNELS,
sampleRate, samplesPerBlock,
bearDataFilePath);
}
}

Expand All @@ -323,7 +326,8 @@ bool EarBinauralMonitoringAudioProcessor::isBusesLayoutSupported(

if(layouts.inputBuses.size() != 1)
return false;
if(layouts.inputBuses[0] != AudioChannelSet::discreteChannels(64))
if (layouts.inputBuses[0] !=
AudioChannelSet::discreteChannels(MAX_DAW_CHANNELS))
return false;

if(layouts.outputBuses.size() != 3)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ set(HEADERS_DIRECT_SPEAKERS_INPUT
${EPS_SHARED_DIR}/components/onboarding.hpp
${EPS_SHARED_DIR}/components/onboarding_slide.hpp
${EPS_SHARED_DIR}/components/overlay.hpp
${EPS_SHARED_DIR}/components/routing_info_icon.hpp
${EPS_SHARED_DIR}/components/segment_progress_bar.hpp
${EPS_SHARED_DIR}/components/speaker_layer.hpp
${EPS_SHARED_DIR}/components/version_label.hpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ class ChannelMeterLayout : public Component {
if(speakerLevels_.size() > 18) meterRows = 4;

auto metersBoxHeight = area.getHeight() / meterRows;
// 6 meters require 337 px - centre them with left padding
int leftPad = (area.getWidth() - 337) / 2;
if (leftPad > 0) area.removeFromLeft(leftPad);

auto metersBoxArea = area.removeFromTop(metersBoxHeight);
channelMeterBox1to6_->setBounds(metersBoxArea.reduced(0, 5));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "JuceHeader.h"

#include "components/look_and_feel/tooltips.hpp"
#include "components/ear_combo_box.hpp"
#include "components/onboarding.hpp"
#include "components/overlay.hpp"
Expand Down Expand Up @@ -42,6 +43,10 @@ class DirectSpeakersComponent : public Component,
propertiesFileLock(
std::make_unique<InterProcessLock>("EPS_preferences")),
propertiesFile(getPropertiesFile(propertiesFileLock.get())) {

tooltipWindow.setLookAndFeel(&tooltipLookAndFeel);
tooltipWindow.setOpaque(false);

header->setText(" Direct Speakers");

onBoardingButton->setButtonText("?");
Expand All @@ -68,6 +73,7 @@ class DirectSpeakersComponent : public Component,
addChildComponent(onBoardingOverlay.get());

//addAndMakeVisible(metadataValueBox.get());
mainValueBox->showRoutingTooltip(p->getNumDawChannels() < 128);
addAndMakeVisible(mainValueBox.get());
addAndMakeVisible(channelMetersBox.get());

Expand Down Expand Up @@ -110,8 +116,10 @@ class DirectSpeakersComponent : public Component,
headingArea.removeFromRight(39).removeFromBottom(39));
header->setBounds(headingArea);

auto leftColumn = area.withTrimmedRight(area.getWidth() / 2);
auto rightColumn = area.withTrimmedLeft(area.getWidth() / 2);
auto leftColumnWidth = area.getWidth() / 2;
if (leftColumnWidth < 385) leftColumnWidth = 385;
auto leftColumn = area.removeFromLeft(leftColumnWidth);
auto rightColumn = area;

// left column
mainValueBox->setBounds(leftColumn.removeFromTop(223).reduced(5, 5));
Expand Down Expand Up @@ -161,6 +169,10 @@ class DirectSpeakersComponent : public Component,

private:
DirectSpeakersAudioProcessor* p_;

TooltipWindow tooltipWindow{this};
TooltipLookAndFeel tooltipLookAndFeel;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DirectSpeakersComponent)
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "detail/weak_ptr_helpers.hpp"

#include "speaker_setups.hpp"
#include <daw_channel_count.h>

namespace {
String routingLayoutDescriptionAt(int position, int layoutSizeFixed) {
Expand Down Expand Up @@ -186,8 +187,9 @@ void DirectSpeakersJuceFrontendConnector::setSpeakerSetup(
speakerSetupByIndex(cachedSpeakerSetupIndex_).speakers.size();
routingComboBoxLocked->clearEntries();
auto layoutSizeFixed = layoutSize != 0 ? layoutSize - 1 : layoutSize;
for (int i = 1; i + layoutSizeFixed <= 64; ++i) {
routingComboBoxLocked->addTextEntry(routingLayoutDescriptionAt(i, layoutSizeFixed));
for (int i = 1; i + layoutSizeFixed <= MAX_DAW_CHANNELS; ++i) {
auto entry = routingComboBoxLocked->addTextEntry(routingLayoutDescriptionAt(i, layoutSizeFixed), i);
entry->setSelectable(i + layoutSizeFixed <= p_->getNumDawChannels());
}
routingComboBoxLocked->selectEntry(cachedRouting_, sendNotification);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
#include "components/non_automatable_parameter.hpp"
#include "direct_speakers_plugin_editor.hpp"
#include "direct_speakers_frontend_connector.hpp"

void registerPluginLoadSig(std::function<void(std::string const&)>);
uint32_t requestInputInstanceIdSig();
#include "reaper_integration.hpp"

using namespace ear::plugin;

Expand All @@ -24,7 +22,7 @@ DirectSpeakersAudioProcessor::DirectSpeakersAudioProcessor()
addParameter(routing_ =
new ui::NonAutomatedParameter<AudioParameterInt>(
"routing", "Routing",
-1, 63, -1));
-1, MAX_DAW_CHANNELS-1, -1));
firthm01 marked this conversation as resolved.
Show resolved Hide resolved
addParameter(packFormatIdValue_ =
new ui::NonAutomatedParameter<AudioParameterInt>(
"packFormatIdValue", "PackFormat ID Value",
Expand Down Expand Up @@ -197,20 +195,15 @@ void DirectSpeakersAudioProcessor::setIHostApplication(Steinberg::FUnknown * unk
VST3ClientExtensions::setIHostApplication(unknown);
if(reaperHost) {

auto requestInputInstanceIdPtr = reaperHost->getReaperApi("requestInputInstanceId");
if(requestInputInstanceIdPtr) {
auto requestInputInstanceId = reinterpret_cast<decltype(&requestInputInstanceIdSig)>(requestInputInstanceIdPtr);
uint32_t inputInstanceId = requestInputInstanceId();
inputInstanceId_->internalSetIntAndNotifyHost(inputInstanceId);
}
inputInstanceId_->internalSetIntAndNotifyHost(
requestInstanceIdFromExtension(reaperHost));

auto registerPluginLoadPtr = reaperHost->getReaperApi("registerPluginLoad");
if(registerPluginLoadPtr) {
auto registerPluginLoad = reinterpret_cast<decltype(&registerPluginLoadSig)>(registerPluginLoadPtr);
registerPluginLoad([this](std::string const& xmlState) {
this->extensionSetState(xmlState);
});
}
registerPluginLoadWithExtension(reaperHost,
[this](std::string const& xmlState) {
this->extensionSetState(xmlState);
});

numDawChannels_ = DetermineChannelCount(reaperHost);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "components/level_meter_calculator.hpp"
#include "reaper_vst3_interfaces.h"
#include "components/read_only_audio_parameter_int.hpp"
#include <daw_channel_count.h>

#include <memory>

Expand Down Expand Up @@ -72,6 +73,8 @@ class DirectSpeakersAudioProcessor : public AudioProcessor, public VST3ClientExt
void setIHostApplication(Steinberg::FUnknown *unknown) override;
void extensionSetState(std::string const& xmlState);

int getNumDawChannels() { return numDawChannels_; }

private:
IReaperHostApplication* reaperHost{ nullptr };
ear::plugin::communication::ConnectionId connectionId_;
Expand All @@ -87,6 +90,7 @@ class DirectSpeakersAudioProcessor : public AudioProcessor, public VST3ClientExt
std::unique_ptr<ear::plugin::DirectSpeakersBackend> backend_;

int samplerate_;
int numDawChannels_{MAX_DAW_CHANNELS};
std::shared_ptr<ear::plugin::LevelMeterCalculator> levelMeter_;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DirectSpeakersAudioProcessor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "components/ear_combo_box.hpp"
#include "components/ear_name_text_editor.hpp"
#include "components/routing_info_icon.hpp"
#include "components/look_and_feel/colours.hpp"
#include "components/look_and_feel/fonts.hpp"

Expand All @@ -20,6 +21,7 @@ class ValueBoxMain : public Component {
speakerSetupLabel_(std::make_unique<Label>()),
speakerSetupsComboBox_(std::make_shared<EarComboBox>()),
routingLabel_(std::make_unique<Label>()),
routingInfoIcon_(createRoutingInfoIcon()),
routingComboBox_(std::make_shared<EarComboBox>()) {
name_->setLabelText("Object Name");
name_->setText("Object_1");
Expand All @@ -38,6 +40,8 @@ class ValueBoxMain : public Component {
routingLabel_->setJustificationType(Justification::right);
addAndMakeVisible(routingLabel_.get());

addChildComponent(routingInfoIcon_.get());

routingComboBox_->setDefaultText("Select Scene channel range");
addAndMakeVisible(routingComboBox_.get());

Expand Down Expand Up @@ -92,13 +96,21 @@ class ValueBoxMain : public Component {

auto routingArea = area.removeFromTop(rowHeight_);
auto routingLabelArea = routingArea.withWidth(labelWidth_);
routingLabel_->setBounds(routingLabelArea);
if (routingInfoIcon_->isVisible()) {
placeRoutingInfoIconRight(routingArea, routingInfoIcon_.get());
routingArea.removeFromRight(marginSmall_);
}
auto routingComboBoxArea =
routingArea.withTrimmedLeft(labelWidth_ + marginBig_)
.reduced(0, marginSmall_);
routingLabel_->setBounds(routingLabelArea);
routingComboBox_->setBounds(routingComboBoxArea);
}

void showRoutingTooltip(bool visible) {
routingInfoIcon_->setVisible(visible);
}

std::shared_ptr<EarNameTextEditor> getNameTextEditor() { return name_; }
std::shared_ptr<ToggleButton> getUseTrackNameCheckbox() { return useTrackNameCheckbox_; }
std::shared_ptr<EarComboBox> getRoutingComboBox() { return routingComboBox_; }
Expand All @@ -119,6 +131,7 @@ class ValueBoxMain : public Component {
std::shared_ptr<EarComboBox> speakerSetupsComboBox_;
std::unique_ptr<Label> routingLabel_;
std::shared_ptr<EarComboBox> routingComboBox_;
std::shared_ptr<ImageComponent> routingInfoIcon_;
std::shared_ptr<ToggleButton> useTrackNameCheckbox_;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ValueBoxMain)
Expand Down
1 change: 1 addition & 0 deletions ear-production-suite-plugins/plugins/hoa/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ set(HEADERS_HOA_INPUT
${EPS_SHARED_DIR}/components/level_meter_calculator.hpp
${EPS_SHARED_DIR}/components/non_automatable_parameter.hpp
${EPS_SHARED_DIR}/components/onboarding.hpp
${EPS_SHARED_DIR}/components/routing_info_icon.hpp
${EPS_SHARED_DIR}/components/version_label.hpp

${EPS_SHARED_DIR}/components/look_and_feel/colours.hpp
Expand Down
Loading
Loading