11namespace tracktion {
inline namespace engine
15MIDITrackerModifier::MIDITrackerModifier (Edit& e,
const juce::ValueTree& v)
18 auto um = &edit.getUndoManager();
20 nodeState = state.getOrCreateChildWithName (IDs::NODES, um);
22 type.referTo (state, IDs::wave, um, pitch);
23 mode.referTo (state, IDs::mode, um, absolute);
24 relativeRoot.referTo (state, IDs::root, um, 60);
25 relativeSpread.referTo (state, IDs::spread, um, 12);
31 auto* p =
new DiscreteLabelledParameter (paramID, name, *
this, valueRange, labels.size(), labels);
32 addAutomatableParameter (p);
33 p->attachToCurrentValue (val);
42 valueRange.setSkewForCentre (centreVal);
43 auto* p =
new SuffixedParameter (paramID, name, *
this, valueRange, suffix);
44 addAutomatableParameter (p);
45 p->attachToCurrentValue (val);
50 typeParam = addDiscreteParam (
"type",
TRANS(
"MIDI Type"), { 0.0f, (
float) getTypeNames().size() - 1 }, type, getTypeNames());
51 modeParam = addDiscreteParam (
"mode",
TRANS(
"Mode"), { 0.0f, (
float) getModeNames().size() - 1 }, mode, getModeNames());
52 relativeRootParam = addParam (
"relativeRoot",
TRANS(
"Root"), { 1.0f, 127.0f, 1.0f }, 63.5f, relativeRoot, {});
53 relativeSpreadParam = addParam (
"relativeSpread",
TRANS(
"Spread"), { 1.0f, 64.0f, 1.0f }, 32.0f, relativeSpread, {});
57 changedTimer.setCallback ([
this]
59 changedTimer.stopTimer();
63 state.addListener (
this);
66MIDITrackerModifier::~MIDITrackerModifier()
68 state.removeListener (
this);
69 notifyListenersOfDeletion();
71 for (
auto p : getAutomatableParameters())
72 p->detachFromCurrentValue();
74 deleteAutomatableParameters();
77void MIDITrackerModifier::initialise()
79 restoreChangedParametersFromState();
83float MIDITrackerModifier::getCurrentValue()
88int MIDITrackerModifier::getCurrentMIDIValue() const noexcept
100 return {
TRANS(
"MIDI input") };
105 setEditTime (pc.
editTime.getStart());
116 midiTrackerModifierID (mtm.itemID)
120bool MIDITrackerModifier::Assignment::isForModifierSource (
const ModifierSource& source)
const
123 return mod->itemID == midiTrackerModifierID;
128MIDITrackerModifier::Ptr MIDITrackerModifier::Assignment::getMIDITrackerModifier()
const
130 if (
auto mod = findModifierTypeForID<MIDITrackerModifier> (edit, midiTrackerModifierID))
150void MIDITrackerModifier::refreshCurrentValue()
156 updateValueFromMap (midiVal);
163void MIDITrackerModifier::updateMapFromTree()
166 TRACKTION_ASSERT_MESSAGE_THREAD
170 for (
int i = 0; i < 5; ++i)
177 v.setProperty (IDs::midi,
juce::jmap (i, 0, 4, 0, 127),
nullptr);
178 v.setProperty (IDs::value,
juce::jmap ((
float) i, 0.0f, 4.0f, -1.0f, 1.0f),
nullptr);
179 nodeState.
addChild (v, -1,
nullptr);
190 refreshCurrentValue();
193void MIDITrackerModifier::updateValueFromMap (
int midiVal)
196 auto linearInterpolate = [] (
float x1,
float y1,
float x2,
float y2,
float x)
198 return (y1 * (x2 - x) + y2 * (x - x1)) / (x2 - x1);
201 if (getTypedParamValue<Mode> (*modeParam) == relative)
203 const float root = relativeRootParam->getCurrentValue();
204 const float spread = relativeSpreadParam->getCurrentValue();
207 auto val = linearInterpolate (root, 0.0f, root + spread, 1.0f, (
float) midiVal);
220 auto lastNode = map.node[4];
222 for (
int i = 4; --i >= 0;)
224 const auto node = map.node[i];
227 if (nodeMidiVal <= midiVal)
231 auto val = linearInterpolate ((
float) nodeMidiVal,
std::get<float> (node),
250 if (getTypedParamValue<Type> (*typeParam) == pitch)
251 updateValueFromMap (m.getNoteNumber());
253 updateValueFromMap (m.getVelocity());
256void MIDITrackerModifier::valueTreeChanged()
271 else if (i == IDs::root || i == IDs::spread)
273 refreshCurrentValue();
276 else if (v.hasType (IDs::NODE))
278 if (i == IDs::midi || i == IDs::value)
282 ValueTreeAllEventListener::valueTreePropertyChanged (v, i);
bool isValid() const noexcept
void startTimerHz(int timerFrequencyHz) noexcept
bool isTimerRunning() const noexcept
ValueTree getChild(int index) const
void addChild(const ValueTree &child, int index, UndoManager *undoManager)
bool isLoading() const
Returns true if the Edit's not yet fully loaded.
int getCurrentMIDIValue() const noexcept
Returns the MIDI value, either a pitch or velocity.
#define TRANS(stringLiteral)
#define NEEDS_TRANS(stringLiteral)
constexpr Type jmap(Type value0To1, Type targetRangeMin, Type targetRangeMax)
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
Connects a modifier source to an AutomatableParameter.
juce::ValueTree state
Modifier internal state.
The context passed to plugin render methods to provide it with buffers to fill.
MidiMessageArray * bufferForMidiMessages
A buffer of MIDI events to process.
TimeRange editTime
The edit time range this context represents.