kopia lustrzana https://github.com/jameshball/osci-render
Add functional sliders for bit crush and bulge
rodzic
0ed2a10ac4
commit
3056ae3997
|
@ -23,22 +23,19 @@ EffectsComponent::EffectsComponent(OscirenderAudioProcessor& p) : audioProcessor
|
|||
auto effect = effects[i];
|
||||
effect->setValue(0.5);
|
||||
audioProcessor.enableEffect(effect);
|
||||
itemData.data.push_back(effect);
|
||||
}
|
||||
|
||||
itemData.data.push_back(juce::String("Item 1"));
|
||||
itemData.data.push_back(juce::String("Item 2"));
|
||||
itemData.data.push_back(juce::String("Item 3"));
|
||||
|
||||
addBtn.setButtonText("Add Item...");
|
||||
/*addBtn.setButtonText("Add Item...");
|
||||
addBtn.onClick = [this]()
|
||||
{
|
||||
itemData.data.push_back(juce::String("Item " + juce::String(1 + itemData.getNumItems())));
|
||||
listBox.updateContent();
|
||||
};
|
||||
addAndMakeVisible(addBtn);
|
||||
addAndMakeVisible(addBtn);*/
|
||||
|
||||
listBox.setModel(&listBoxModel);
|
||||
listBox.setRowHeight(40);
|
||||
listBox.setRowHeight(30);
|
||||
addAndMakeVisible(listBox);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,20 @@ BitCrushEffect::BitCrushEffect() {}
|
|||
|
||||
BitCrushEffect::~BitCrushEffect() {}
|
||||
|
||||
// algorithm from https://www.kvraudio.com/forum/viewtopic.php?t=163880
|
||||
Vector2 BitCrushEffect::apply(int index, Vector2 input) {
|
||||
double crush = 3.0 * (1.0 - value);
|
||||
return Vector2(bitCrush(input.x, crush), bitCrush(input.y, crush));
|
||||
// change rage of value from 0-1 to 0.0-0.78
|
||||
double rangedValue = value * 0.78;
|
||||
double powValue = pow(2.0f, 1.0 - rangedValue) - 1.0;
|
||||
double crush = powValue * 12;
|
||||
double x = powf(2.0f, crush);
|
||||
double quant = 0.5 * x;
|
||||
double dequant = 1.0f / quant;
|
||||
return Vector2(dequant * (int)(input.x * quant), dequant * (int)(input.y * quant));
|
||||
}
|
||||
|
||||
double BitCrushEffect::getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
void BitCrushEffect::setValue(double value) {
|
||||
|
@ -25,9 +36,10 @@ void BitCrushEffect::setPrecedence(int precedence) {
|
|||
this->precedence = precedence;
|
||||
}
|
||||
|
||||
double BitCrushEffect::bitCrush(double value, double places) {
|
||||
long factor = (long) pow(10, places);
|
||||
value = value * factor;
|
||||
long tmp = round(value);
|
||||
return (double) tmp / factor;
|
||||
juce::String BitCrushEffect::getName() {
|
||||
return juce::String("Bit Crush");
|
||||
}
|
||||
|
||||
juce::String BitCrushEffect::getId() {
|
||||
return juce::String("bitCrush");
|
||||
}
|
||||
|
|
|
@ -8,15 +8,16 @@ public:
|
|||
~BitCrushEffect();
|
||||
|
||||
Vector2 apply(int index, Vector2 input) override;
|
||||
double getValue() override;
|
||||
void setValue(double value) override;
|
||||
void setFrequency(double frequency) override;
|
||||
int getPrecedence() override;
|
||||
void setPrecedence(int precedence) override;
|
||||
juce::String getName() override;
|
||||
juce::String getId() override;
|
||||
private:
|
||||
|
||||
double value = 0.0;
|
||||
double frequency = 1.0;
|
||||
int precedence = -1;
|
||||
|
||||
double bitCrush(double value, double places);
|
||||
};
|
|
@ -14,6 +14,10 @@ Vector2 BulgeEffect::apply(int index, Vector2 input) {
|
|||
return Vector2(rn * cos(theta), rn * sin(theta));
|
||||
}
|
||||
|
||||
double BulgeEffect::getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
void BulgeEffect::setValue(double value) {
|
||||
this->value = value;
|
||||
}
|
||||
|
@ -29,3 +33,11 @@ int BulgeEffect::getPrecedence() {
|
|||
void BulgeEffect::setPrecedence(int precedence) {
|
||||
this->precedence = precedence;
|
||||
}
|
||||
|
||||
juce::String BulgeEffect::getName() {
|
||||
return juce::String("Bulge");
|
||||
}
|
||||
|
||||
juce::String BulgeEffect::getId() {
|
||||
return juce::String("bulge");
|
||||
}
|
||||
|
|
|
@ -7,13 +7,14 @@ public:
|
|||
BulgeEffect();
|
||||
~BulgeEffect();
|
||||
|
||||
|
||||
|
||||
Vector2 apply(int index, Vector2 input) override;
|
||||
double getValue() override;
|
||||
void setValue(double value) override;
|
||||
void setFrequency(double frequency) override;
|
||||
int getPrecedence() override;
|
||||
void setPrecedence(int precedence) override;
|
||||
juce::String getName() override;
|
||||
juce::String getId() override;
|
||||
|
||||
private:
|
||||
double value = 0.0;
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
#pragma once
|
||||
#include "../shape/Vector2.h"
|
||||
#include <JuceHeader.h>
|
||||
|
||||
class Effect {
|
||||
public:
|
||||
Effect();
|
||||
|
||||
virtual Vector2 apply(int index, Vector2 input) = 0;
|
||||
virtual double getValue() = 0;
|
||||
virtual void setValue(double value) = 0;
|
||||
virtual void setFrequency(double frequency) = 0;
|
||||
virtual int getPrecedence() = 0;
|
||||
virtual void setPrecedence(int precedence) = 0;
|
||||
virtual juce::String getName() = 0;
|
||||
virtual juce::String getId() = 0;
|
||||
};
|
|
@ -1,45 +1,35 @@
|
|||
#include "MyListComponent.h"
|
||||
|
||||
MyListComponent::MyListComponent(DraggableListBox& lb, MyListBoxItemData& data, int rn)
|
||||
: DraggableListBoxItem(lb, data, rn)
|
||||
{
|
||||
actionBtn.setButtonText("Action");
|
||||
actionBtn.onClick = [this]()
|
||||
{
|
||||
((MyListBoxItemData&)modelData).doItemAction(rowNum);
|
||||
};
|
||||
addAndMakeVisible(actionBtn);
|
||||
MyListComponent::MyListComponent(DraggableListBox& lb, MyListBoxItemData& data, int rn) : DraggableListBoxItem(lb, data, rn) {
|
||||
addAndMakeVisible(slider);
|
||||
addAndMakeVisible(label);
|
||||
|
||||
deleteBtn.setButtonText("Delete");
|
||||
deleteBtn.onClick = [this]()
|
||||
{
|
||||
modelData.deleteItem(rowNum);
|
||||
listBox.updateContent();
|
||||
};
|
||||
addAndMakeVisible(deleteBtn);
|
||||
label.setText(data.getText(rn), juce::dontSendNotification);
|
||||
label.attachToComponent(&slider, true);
|
||||
|
||||
slider.setSliderStyle(juce::Slider::LinearHorizontal);
|
||||
slider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 90, slider.getTextBoxHeight());
|
||||
slider.setRange(0.0, 1.0, 0.01);
|
||||
slider.setValue(data.getValue(rn), juce::dontSendNotification);
|
||||
slider.onValueChange = [this] {
|
||||
((MyListBoxItemData&)modelData).setValue(rowNum, slider.getValue());
|
||||
};
|
||||
}
|
||||
|
||||
MyListComponent::~MyListComponent()
|
||||
{
|
||||
|
||||
}
|
||||
MyListComponent::~MyListComponent() {}
|
||||
|
||||
void MyListComponent::paint (juce::Graphics& g)
|
||||
{
|
||||
void MyListComponent::paint (juce::Graphics& g) {
|
||||
modelData.paintContents(rowNum, g, dataArea);
|
||||
DraggableListBoxItem::paint(g);
|
||||
}
|
||||
|
||||
void MyListComponent::resized()
|
||||
{
|
||||
dataArea = getLocalBounds();
|
||||
actionBtn.setBounds(dataArea.removeFromLeft(70).withSizeKeepingCentre(56, 24));
|
||||
deleteBtn.setBounds(dataArea.removeFromRight(70).withSizeKeepingCentre(56, 24));
|
||||
void MyListComponent::resized() {
|
||||
auto sliderLeft = 100;
|
||||
slider.setBounds(sliderLeft, 0, getWidth() - 110, getHeight());
|
||||
}
|
||||
|
||||
|
||||
juce::Component* MyListBoxModel::refreshComponentForRow(int rowNumber, bool isRowSelected, juce::Component *existingComponentToUpdate)
|
||||
{
|
||||
juce::Component* MyListBoxModel::refreshComponentForRow(int rowNumber, bool isRowSelected, juce::Component *existingComponentToUpdate) {
|
||||
std::unique_ptr<MyListComponent> item(dynamic_cast<MyListComponent*>(existingComponentToUpdate));
|
||||
if (juce::isPositiveAndBelow(rowNumber, modelData.getNumItems()))
|
||||
{
|
||||
|
|
|
@ -1,39 +1,33 @@
|
|||
#pragma once
|
||||
#include "DraggableListBox.h"
|
||||
#include <JuceHeader.h>
|
||||
#include "../audio/Effect.h"
|
||||
|
||||
// Application-specific data container
|
||||
struct MyListBoxItemData : public DraggableListBoxItemData
|
||||
{
|
||||
std::vector<juce::String> data;
|
||||
std::vector<std::shared_ptr<Effect>> data;
|
||||
|
||||
int getNumItems() override
|
||||
{
|
||||
int getNumItems() override {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
void deleteItem(int indexOfItemToDelete) override
|
||||
{
|
||||
void deleteItem(int indexOfItemToDelete) override {
|
||||
data.erase(data.begin() + indexOfItemToDelete);
|
||||
}
|
||||
|
||||
void addItemAtEnd() override
|
||||
{
|
||||
data.push_back(juce::String("Yahoo"));
|
||||
void addItemAtEnd() override {
|
||||
// data.push_back(juce::String("Yahoo"));
|
||||
}
|
||||
|
||||
void paintContents(int rowNum, juce::Graphics& g, juce::Rectangle<int> bounds) override
|
||||
{
|
||||
void paintContents(int rowNum, juce::Graphics& g, juce::Rectangle<int> bounds) override {
|
||||
g.fillAll(juce::Colours::lightgrey);
|
||||
g.setColour(juce::Colours::black);
|
||||
g.drawRect(bounds);
|
||||
if (rowNum < data.size()) {
|
||||
g.drawText(data[rowNum], bounds, juce::Justification::centred);
|
||||
}
|
||||
}
|
||||
|
||||
void moveBefore(int indexOfItemToMove, int indexOfItemToPlaceBefore) override {
|
||||
juce::String temp = data[indexOfItemToMove];
|
||||
auto temp = data[indexOfItemToMove];
|
||||
|
||||
if (indexOfItemToMove < indexOfItemToPlaceBefore) {
|
||||
move(data, indexOfItemToMove, indexOfItemToPlaceBefore - 1);
|
||||
|
@ -43,7 +37,7 @@ struct MyListBoxItemData : public DraggableListBoxItemData
|
|||
}
|
||||
|
||||
void moveAfter(int indexOfItemToMove, int indexOfItemToPlaceAfter) override {
|
||||
juce::String temp = data[indexOfItemToMove];
|
||||
auto temp = data[indexOfItemToMove];
|
||||
|
||||
if (indexOfItemToMove <= indexOfItemToPlaceAfter) {
|
||||
move(data, indexOfItemToMove, indexOfItemToPlaceAfter);
|
||||
|
@ -52,20 +46,25 @@ struct MyListBoxItemData : public DraggableListBoxItemData
|
|||
}
|
||||
}
|
||||
|
||||
template <typename t> void move(std::vector<t>& v, size_t oldIndex, size_t newIndex)
|
||||
{
|
||||
template <typename t> void move(std::vector<t>& v, size_t oldIndex, size_t newIndex) {
|
||||
if (oldIndex > newIndex) {
|
||||
std::rotate(v.rend() - oldIndex - 1, v.rend() - oldIndex, v.rend() - newIndex);
|
||||
} else {
|
||||
std::rotate(v.begin() + oldIndex, v.begin() + oldIndex + 1, v.begin() + newIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// This is an example of an operation on a single list item.
|
||||
void doItemAction(int itemIndex)
|
||||
{
|
||||
DBG(data[itemIndex]);
|
||||
|
||||
void setValue(int itemIndex, double value) {
|
||||
data[itemIndex]->setValue(value);
|
||||
}
|
||||
|
||||
juce::String getText(int itemIndex) {
|
||||
return data[itemIndex]->getName();
|
||||
}
|
||||
|
||||
double getValue(int itemIndex) {
|
||||
return data[itemIndex]->getValue();
|
||||
}
|
||||
};
|
||||
|
||||
// Custom list-item Component (which includes item-delete button)
|
||||
|
@ -80,7 +79,10 @@ public:
|
|||
|
||||
protected:
|
||||
juce::Rectangle<int> dataArea;
|
||||
juce::TextButton actionBtn, deleteBtn;
|
||||
|
||||
juce::Slider slider;
|
||||
juce::Label label;
|
||||
juce::String id;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MyListComponent)
|
||||
|
|
Ładowanie…
Reference in New Issue