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