Skip to content

Commit

Permalink
Update ui
Browse files Browse the repository at this point in the history
  • Loading branch information
jurihock committed Dec 22, 2023
1 parent 8dfa5b4 commit fe7babf
Show file tree
Hide file tree
Showing 10 changed files with 306 additions and 125 deletions.
4 changes: 2 additions & 2 deletions lib/JIVE.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
CPMAddPackage(
NAME JIVE
VERSION 1.0.0
GIT_TAG 2cadd3a84fe7f502376d18b20087c3d96bbbf0cb
GITHUB_REPOSITORY jurihock/JIVE
GIT_TAG b65bd837e09a14a7e869d12886a69611a9850e2e
GITHUB_REPOSITORY ImJimmi/JIVE
DOWNLOAD_ONLY YES)

if(JIVE_ADDED)
Expand Down
6 changes: 3 additions & 3 deletions src/StftPitchShiftPlugin/Core/InstantCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ class InstantCore : public Core

struct { std::vector<double> input, output; } buffer;

template<typename X, typename Y>
static Y transform(const X x) { return static_cast<Y>(x); }

void process(const std::span<const float> input, const std::span<float> output,
std::function<void(std::span<double> x, std::span<double> y)> callback);

template<typename X, typename Y>
static Y transform(const X x) { return static_cast<Y>(x); }

};
169 changes: 154 additions & 15 deletions src/StftPitchShiftPlugin/Editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,173 @@

#include <StftPitchShiftPlugin/Logger.h>

Editor::Editor(juce::AudioProcessor& process) :
Editor::Editor(juce::AudioProcessor& process, std::shared_ptr<Parameters> params) :
juce::AudioProcessorEditor(process),
process(process)
parameters(params)
{
jive::Interpreter interpreter;

view = interpreter.interpret(juce::ValueTree
juce::String xml(
R"(
<Component {flex-col} width="500" height="500" padding="10">
<Component {flex-row} {fill}>
<Component {flex-col} {fill}>
<Label id="quefrency-name" {label-name}/>
<Knob id="quefrency-slider" {flex-fill} {fill}/>
<Label id="quefrency-value" {label-value}/>
</Component>
<Component {flex-col} {fill}>
<Label id="timbre-name" {label-name}/>
<Knob id="timbre-slider" {flex-fill} {fill}/>
<Label id="timbre-value" {label-value}/>
</Component>
</Component>
<Component {flex-row} {fill}>
<Component {flex-col} {fill}>
<Label id="pitch1-name" {label-name}/>
<Knob id="pitch1-slider" {flex-fill} {fill}/>
<Label id="pitch1-value" {label-value}/>
</Component>
<Component {flex-col} {fill}>
<Label id="pitch2-name" {label-name}/>
<Knob id="pitch2-slider" {flex-fill} {fill}/>
<Label id="pitch2-value" {label-value}/>
</Component>
<Component {flex-col} {fill}>
<Label id="pitch3-name" {label-name}/>
<Knob id="pitch3-slider" {flex-fill} {fill}/>
<Label id="pitch3-value" {label-value}/>
</Component>
</Component>
<Component {flex-row} {fill}>
<Component {flex-col} {fill}>
<Label id="pitch4-name" {label-name}/>
<Knob id="pitch4-slider" {flex-fill} {fill}/>
<Label id="pitch4-value" {label-value}/>
</Component>
<Component {flex-col} {fill}>
<Label id="pitch5-name" {label-name}/>
<Knob id="pitch5-slider" {flex-fill} {fill}/>
<Label id="pitch5-value" {label-value}/>
</Component>
<Component {flex-col} {fill}>
<Label id="stages-name" {label-name}/>
<Knob id="stages-slider" {flex-fill} {fill}/>
<Label id="stages-value" {label-value}/>
</Component>
</Component>
</Component>
)");

xml = xml.replace("{label-name}", R"(min-height="40")");
xml = xml.replace("{label-value}", R"(min-height="20" opacity="0.5")");
xml = xml.replace("{fill}", R"(width="100%" height="100%")");
xml = xml.replace("{flex-fill}", R"(flex-grow="1")");
xml = xml.replace("{flex-row}", R"(display="flex" flex-direction="row")");
xml = xml.replace("{flex-col}", R"(display="flex" flex-direction="column")");

auto* root = (view = interpreter.interpret(xml))->getComponent().get();

auto attach_slider = [&](const std::string& id)
{
"Button",
auto* parameter = parameters->get(id);

auto* slider = find<juce::Slider>(root, id + "-slider");
auto* name = find<juce::Label>(root, id + "-name");
auto* value = find<juce::Label>(root, id + "-value");

auto unit = parameter->getLabel().isEmpty() ? juce::String("") :
juce::String::formatted(" %s", parameter->getLabel().getCharPointer());

auto notify = juce::NotificationType::dontSendNotification;

attachments.slider.push_back(std::make_shared<juce::SliderParameterAttachment>(*parameter, *slider));

name->setJustificationType(juce::Justification::centred);
value->setJustificationType(juce::Justification::centred);

name->setText(parameter->getName(42), notify);
value->setText(parameter->getText(parameter->getValue(), 42) + unit, notify);

parameters->on(id, [parameter, value, unit, notify]()
{
value->setText(parameter->getText(parameter->getValue(), 42) + unit, notify);
});

// FIXME: how to change font size via style in XML string?
{
{ "width", 200 },
{ "height", 100 },
auto font = name->getFont();
font.setHeight(font.getHeight() * 1.1);
name->setFont(font);
}
});
};

addAndMakeVisible(*view->getComponent());
auto update_timbre_slider = [&]()
{
static const std::array<juce::Slider*, 1> timbre_slider =
{
find<juce::Slider>(root, "timbre-slider")
};

auto quefrency = parameters->get<float>("quefrency");

auto* slider = timbre_slider.front();
auto enabled = quefrency > 0;

slider->setEnabled(enabled);
};

auto update_pitch_sliders = [&]()
{
static const std::array<juce::Slider*, 5> pitch_sliders =
{
find<juce::Slider>(root, "pitch1-slider"),
find<juce::Slider>(root, "pitch2-slider"),
find<juce::Slider>(root, "pitch3-slider"),
find<juce::Slider>(root, "pitch4-slider"),
find<juce::Slider>(root, "pitch5-slider")
};

auto stages = parameters->get<int>("stages");

// setSize(
// view->getComponent()->getWidth(),
// view->getComponent()->getHeight());
for (size_t i = 0; i < pitch_sliders.size(); ++i)
{
auto* slider = pitch_sliders.at(i);
auto enabled = i < stages;

slider->setEnabled(enabled);
}
};

attach_slider("quefrency");
attach_slider("timbre");
attach_slider("pitch1");
attach_slider("pitch2");
attach_slider("pitch3");
attach_slider("pitch4");
attach_slider("pitch5");
attach_slider("stages");

const int w = 500;
const int h = 500;
update_timbre_slider();
parameters->on("quefrency", update_timbre_slider);

setSize(w, h);
update_pitch_sliders();
parameters->on("stages", update_pitch_sliders);

addAndMakeVisible(*root);
setSize(root->getWidth(), root->getHeight());
setResizable(true, true);
}

Editor::~Editor()
{
juce::ignoreUnused(process);
}

void Editor::resized()
{
view->getComponent()->setSize(getWidth(), getHeight());
}
41 changes: 37 additions & 4 deletions src/StftPitchShiftPlugin/Editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,53 @@

#include <JuceHeader.h>

#include <StftPitchShiftPlugin/Parameters.h>

class Editor final : public juce::AudioProcessorEditor
{

public:

explicit Editor(juce::AudioProcessor& process);
~Editor() override;
Editor(juce::AudioProcessor& process, std::shared_ptr<Parameters> params);
~Editor();

private:
void resized() override;

juce::AudioProcessor& process;
private:

std::shared_ptr<Parameters> parameters;
std::unique_ptr<jive::GuiItem> view;

struct
{
std::vector<std::shared_ptr<juce::SliderParameterAttachment>> slider;
} attachments;

template<typename T>
static T* find(const juce::Component* root, const juce::String& id)
{
for (juce::Component* child : root->getChildren())
{
if (child->getComponentID() == id)
{
if (T* t = static_cast<T*>(child))
{
return t;
}

throw std::runtime_error(
"Invalid component type!");
}

if (T* t = find<T>(child, id))
{
return t;
}
}

return nullptr;
}

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Editor)

};
Loading

0 comments on commit fe7babf

Please sign in to comment.