commit 544f663b311d1451acaf72849a48235386a1518d
parent 02ab7d99f28fe3931a34a916bb66e29b9956edd5
Author: 790 <790@users.noreply.github.com>
Date: Sun, 16 Jan 2022 22:18:06 +0000
add scale. fix crashes. better reverb/delay controls
Diffstat:
11 files changed, 129 insertions(+), 65 deletions(-)
diff --git a/source/jucePlugin/CMakeLists.txt b/source/jucePlugin/CMakeLists.txt
@@ -70,6 +70,8 @@ juce_add_binary_data(jucePlugin_BinaryData
"assets/panels/bg_fx_1018x620.png"
"assets/panels/bg_lfo_1018x620.png"
"assets/panels/bg_osc_1018x620.png"
+ "assets/panels/bg_fxreverb_481x234.png"
+ "assets/panels/bg_fxdelay_481x234.png"
"assets/buttons/GLOBAL_btn_arp_settings_141x26.png"
"assets/buttons/GLOBAL_btn_effects_141x26.png"
"assets/buttons/GLOBAL_btn_lfo_matrix_141x26.png"
diff --git a/source/jucePlugin/PluginEditor.cpp b/source/jucePlugin/PluginEditor.cpp
@@ -15,7 +15,7 @@ AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudi
const auto config = processorRef.getController().getConfig();
auto scale = config->getIntValue("scale", 100);
m_virusEditor->setTopLeftPosition(0, 0);
- m_scale.setBounds(8,8,64,24);
+ m_scale.setBounds(0,0,52,24);
m_scale.addItem("50%", 50);
m_scale.addItem("75%", 75);
m_scale.addItem("100%", 100);
diff --git a/source/jucePlugin/VirusController.cpp b/source/jucePlugin/VirusController.cpp
@@ -348,8 +348,12 @@ namespace Virus
const auto ch = patch.progNumber == 0x40 ? 0 : patch.progNumber;
for (auto i = 0; i < kDataSizeInBytes; i++)
{
- if (auto *p = findSynthParam(ch, i > bankSize ? 0x71 : 0x70, i % bankSize))
- p->setValueFromSynth(patch.data[i], true);
+ if (auto *p = findSynthParam(ch, i > bankSize ? 0x71 : 0x70, i % bankSize)) {
+ if((p->getDescription().classFlags & Parameter::MULTI_OR_SINGLE) && isMultiMode())
+ continue;
+ else
+ p->setValueFromSynth(patch.data[i], true);
+ }
}
if (onProgramChange) {
onProgramChange();
@@ -391,9 +395,9 @@ namespace Virus
if (auto* p = findSynthParam(pt, virusLib::PAGE_B, virusLib::CLOCK_TEMPO)) {
p->setValueFromSynth(patch.data[virusLib::MD_CLOCK_TEMPO], true);
}
- if (auto* p = findSynthParam(pt, virusLib::PAGE_A, virusLib::EFFECT_SEND)) {
+/* if (auto* p = findSynthParam(pt, virusLib::PAGE_A, virusLib::EFFECT_SEND)) {
p->setValueFromSynth(patch.data[virusLib::MD_PART_EFFECT_SEND], true);
- }
+ }*/
m_currentBank[pt] = (virusLib::BankNumber)(patch.data[virusLib::MD_PART_BANK_NUMBER + pt]+1);
m_currentProgram[pt] = patch.data[virusLib::MD_PART_PROGRAM_NUMBER + pt];
}
@@ -1566,7 +1570,7 @@ namespace Virus
{Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 108, "Chorus Delay", {0,127}, {},{}, true, false, false},
{Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 109, "Chorus Feedback", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true},
{Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 110, "Chorus Lfo Shape", {0,67}, numToLfoShape, {}, true, true, false},
- {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 112, "Delay/Reverb Mode", {0,26}, numToDelayReverbMode, {}, true, true, false},
+ {Parameter::Page::A, Parameter::Class::SOUNDBANK_A|Parameter::Class::MULTI_OR_SINGLE, 112, "Delay/Reverb Mode", {0,26}, numToDelayReverbMode, {}, true, true, false},
{Parameter::Page::A, Parameter::Class::SOUNDBANK_A|Parameter::Class::MULTI_OR_SINGLE, 113, "Effect Send", {0,127}, {},{}, true, false, false},
{Parameter::Page::A, Parameter::Class::SOUNDBANK_A|Parameter::Class::MULTI_OR_SINGLE|Parameter::Class::NON_PART_SENSITIVE, 114, "Delay Time", {0,127}, {},{}, true, false, false},
{Parameter::Page::A, Parameter::Class::SOUNDBANK_A|Parameter::Class::MULTI_OR_SINGLE|Parameter::Class::NON_PART_SENSITIVE, 115, "Delay Feedback", {0,127}, {},{}, true, false, false},
@@ -1669,7 +1673,7 @@ namespace Virus
{Parameter::Page::B, Parameter::Class::SOUNDBANK_B|Parameter::Class::VIRUS_C, 101, "Distortion Intensity", {0,127}, {},{}, true, false, false},
{Parameter::Page::B, Parameter::Class::SOUNDBANK_B|Parameter::Class::VIRUS_C, 103, "Assign 4 Source", {0,27}, numToModMatrixSource,{}, true, true, false},
{Parameter::Page::B, Parameter::Class::SOUNDBANK_B|Parameter::Class::VIRUS_C, 104, "Assign 4 Destination", {0,122}, numToModMatrixDest, {}, true, true, false},
- {Parameter::Page::B, Parameter::Class::SOUNDBANK_B|Parameter::Class::VIRUS_C, 105, "Assign 4 Amount", {0,127}, {},{}, true, false, false},
+ {Parameter::Page::B, Parameter::Class::SOUNDBANK_B|Parameter::Class::VIRUS_C, 105, "Assign 4 Amount", {0,127}, {},{}, true, false, false, true},
{Parameter::Page::B, Parameter::Class::SOUNDBANK_B|Parameter::Class::VIRUS_C, 106, "Assign 5 Source", {0,27}, numToModMatrixSource, {}, true, true, false},
{Parameter::Page::B, Parameter::Class::SOUNDBANK_B|Parameter::Class::VIRUS_C, 107, "Assign 5 Destination", {0,122}, numToModMatrixDest, {}, true, true, false},
{Parameter::Page::B, Parameter::Class::SOUNDBANK_B|Parameter::Class::VIRUS_C, 108, "Assign 5 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true},
diff --git a/source/jucePlugin/VirusParameterBinding.cpp b/source/jucePlugin/VirusParameterBinding.cpp
@@ -2,6 +2,7 @@
#include "VirusParameter.h"
#include "PluginProcessor.h"
class Parameter;
+
VirusParameterBinding::~VirusParameterBinding()
{
clearBindings();
diff --git a/source/jucePlugin/assets/panels/bg_fxdelay_481x234.png b/source/jucePlugin/assets/panels/bg_fxdelay_481x234.png
Binary files differ.
diff --git a/source/jucePlugin/assets/panels/bg_fxreverb_481x234.png b/source/jucePlugin/assets/panels/bg_fxreverb_481x234.png
Binary files differ.
diff --git a/source/jucePlugin/ui/VirusEditor.cpp b/source/jucePlugin/ui/VirusEditor.cpp
@@ -38,7 +38,7 @@ VirusEditor::VirusEditor(VirusParameterBinding &_parameterBinding, AudioPluginAu
addAndMakeVisible (m_mainButtons);
m_arpEditor = std::make_unique<ArpEditor>(_parameterBinding);
- m_fxEditor = std::make_unique<FxEditor>(_parameterBinding);
+ m_fxEditor = std::make_unique<FxEditor>(_parameterBinding, m_controller);
m_lfoEditor = std::make_unique<LfoEditor>(_parameterBinding);
m_oscEditor = std::make_unique<OscEditor>(_parameterBinding);
m_patchBrowser = std::make_unique<PatchBrowser>(_parameterBinding, m_controller);
@@ -387,7 +387,7 @@ void VirusEditor::recreateControls()
m_lfoEditor = std::make_unique<LfoEditor>(m_parameterBinding);
addChildComponent(m_lfoEditor.get());
- m_fxEditor = std::make_unique<FxEditor>(m_parameterBinding);
+ m_fxEditor = std::make_unique<FxEditor>(m_parameterBinding, m_controller);
addChildComponent(m_fxEditor.get());
m_arpEditor = std::make_unique<ArpEditor>(m_parameterBinding);
diff --git a/source/jucePlugin/ui/Virus_FxEditor.cpp b/source/jucePlugin/ui/Virus_FxEditor.cpp
@@ -6,12 +6,13 @@ using namespace juce;
constexpr auto comboBoxWidth = 84;
-FxEditor::FxEditor(VirusParameterBinding &_parameterBinding) :
+FxEditor::FxEditor(VirusParameterBinding &_parameterBinding, Virus::Controller& _controller) :
m_dist(_parameterBinding), m_analogBoost(_parameterBinding), m_phaser(_parameterBinding),
m_chorus(_parameterBinding), m_eq(_parameterBinding), m_envFollow(_parameterBinding), m_punch(_parameterBinding),
- m_delayReverb(_parameterBinding), m_vocoder(_parameterBinding)
+ m_vocoder(_parameterBinding), m_fxMode("FX Mode"), m_parameterBinding(_parameterBinding)
{
setupBackground(*this, m_background, BinaryData::bg_fx_1018x620_png, BinaryData::bg_fx_1018x620_pngSize);
+ setupRotary(*this, m_fxSend);
setBounds(m_background->getDrawableBounds().toNearestIntEdges());
m_dist.setBounds(23, 28, 273, 116);
@@ -28,12 +29,60 @@ FxEditor::FxEditor(VirusParameterBinding &_parameterBinding) :
addAndMakeVisible(m_envFollow);
m_punch.setBounds(m_envFollow.getRight() + 2, m_envFollow.getY(), 174, 103);
addAndMakeVisible(m_punch);
- m_delayReverb.setBounds(m_phaser.getRight() + 2, m_dist.getY(), 481, m_phaser.getHeight() * 2);
- addAndMakeVisible(m_delayReverb);
- m_vocoder.setBounds(m_delayReverb.getBounds().withY(m_delayReverb.getBottom() + 2).withHeight(304));
+
+ m_delay = std::make_unique<Delay>(_parameterBinding);
+ m_reverb = std::make_unique<Reverb>(_parameterBinding);
+ m_delay->setBounds(m_phaser.getRight() + 2, m_dist.getY(), 481, m_phaser.getHeight() * 2);
+ m_reverb->setBounds(m_phaser.getRight() + 2, m_dist.getY(), 481, m_phaser.getHeight() * 2);
+
+ addChildComponent(m_delay.get());
+ m_delay->setVisible(true);
+
+ addChildComponent(m_reverb.get());
+
+ m_vocoder.setBounds(m_delay->getBounds().withY(m_delay->getBottom() + 2).withHeight(304));
addAndMakeVisible(m_vocoder);
-}
+ m_fxMode.setBounds(m_reverb->getX()+18, m_reverb->getY()+42, comboBoxWidth, comboBoxHeight);
+ addAndMakeVisible(m_fxMode);
+ m_fxMode.setAlwaysOnTop(true);
+ //m_fxSend.getProperties().set(Virus::LookAndFeel::KnobStyleProp, Virus::LookAndFeel::KnobStyle::GENERIC_RED);
+ m_fxSend.setBounds(m_reverb->getX()+376, m_phaser.getY() - 2, knobSize, knobSize);
+ addAndMakeVisible(m_fxSend);
+ m_fxSend.setAlwaysOnTop(true);
+ _parameterBinding.bind(m_fxSend, Virus::Param_EffectSend);
+ _parameterBinding.bind(m_fxMode, Virus::Param_DelayReverbMode, 0);
+ auto p = _controller.getParameter(Virus::Param_DelayReverbMode, 0);
+ if (p) {
+ const auto val = (int)p->getValueObject().getValueSource().getValue();
+ if (val > 1 && val < 5) {
+ m_fxMode.setSelectedId(val + 1, juce::dontSendNotification);
+ const bool isReverb = (val > 1 && val < 5);
+ m_reverb->setVisible(isReverb);
+ m_delay->setVisible(!isReverb);
+ }
+ p->onValueChanged = nullptr;
+ p->onValueChanged = [this, p]() {
+ rebind();
+ const auto value = (int)p->getValueObject().getValueSource().getValue();
+ m_fxMode.setSelectedId(value + 1, juce::dontSendNotification);
+ const bool isReverb = (value > 1 && value < 5);
+ m_reverb->setVisible(isReverb);
+ m_delay->setVisible(!isReverb);
+
+ };
+ }
+}
+void FxEditor::rebind() {
+ removeChildComponent(m_delay.get());
+ m_delay = std::make_unique<FxEditor::Delay>(m_parameterBinding);
+ addChildComponent(m_delay.get());
+ removeChildComponent(m_reverb.get());
+ m_reverb = std::make_unique<FxEditor::Reverb>(m_parameterBinding);
+ addChildComponent(m_reverb.get());
+ m_delay->setBounds(m_phaser.getRight() + 2, m_dist.getY(), 481, m_phaser.getHeight() * 2);
+ m_reverb->setBounds(m_phaser.getRight() + 2, m_dist.getY(), 481, m_phaser.getHeight() * 2);
+}
FxEditor::Distortion::Distortion(VirusParameterBinding &_parameterBinding)
{
setupRotary(*this, m_intensity);
@@ -149,8 +198,9 @@ FxEditor::Punch::Punch(VirusParameterBinding &_parameterBinding)
_parameterBinding.bind(m_amount, Virus::Param_PunchIntensity);
}
-FxEditor::DelayAndReverb::DelayAndReverb(VirusParameterBinding &_parameterBinding) : m_sync(_parameterBinding)
+FxEditor::Delay::Delay(VirusParameterBinding &_parameterBinding)
{
+ setupBackground(*this, m_background, BinaryData::bg_fxdelay_481x234_png, BinaryData::bg_fxdelay_481x234_pngSize);
constexpr auto y = 18;
for (auto *s : {&m_time, &m_rate, &m_depth, &m_color, &m_feedback})
setupRotary(*this, *s);
@@ -160,44 +210,42 @@ FxEditor::DelayAndReverb::DelayAndReverb(VirusParameterBinding &_parameterBindin
m_color.setBounds(m_depth.getRight() - 3, y, knobSize, knobSize);
m_feedback.setBounds(m_color.getRight() - 3, y, knobSize, knobSize);
- addAndMakeVisible(m_fxMode);
- m_fxMode.setBounds(18, 42, comboBoxWidth, comboBoxHeight);
- m_sync.setBounds(0, 116 + 2, 481, 116);
- addAndMakeVisible(m_sync);
+ addAndMakeVisible(m_clock);
+ m_clock.setBounds(18, 116+2+22, comboBoxWidth, comboBoxHeight);
+ addAndMakeVisible(m_lfoShape);
+ m_lfoShape.setBounds(m_clock.getBounds().getRight() + 26, 116+2+22, comboBoxWidth, comboBoxHeight);
+
+ _parameterBinding.bind(m_clock, Virus::Param_DelayClock, 0);
+ _parameterBinding.bind(m_lfoShape, Virus::Param_DelayLfoShape, 0);
_parameterBinding.bind(m_time, Virus::Param_DelayTime, 0);
_parameterBinding.bind(m_rate, Virus::Param_DelayRateReverbDecayTime, 0);
_parameterBinding.bind(m_depth, Virus::Param_DelayDepthReverbRoomSize, 0);
_parameterBinding.bind(m_color, Virus::Param_DelayColor, 0);
_parameterBinding.bind(m_feedback, Virus::Param_DelayFeedback, 0);
- _parameterBinding.bind(m_fxMode, Virus::Param_DelayReverbMode, 0);
}
-FxEditor::DelayAndReverb::Sync::Sync(VirusParameterBinding &_parameterBinding)
+FxEditor::Reverb::Reverb(VirusParameterBinding &_parameterBinding)
{
- setupRotary(*this, m_mix);
- setupRotary(*this, m_damping);
- m_mix.getProperties().set(Virus::LookAndFeel::KnobStyleProp, Virus::LookAndFeel::KnobStyle::GENERIC_RED);
- m_mix.setBounds(376, -2, knobSize, knobSize);
-
- addAndMakeVisible(m_clock);
- m_clock.setBounds(18, 22, comboBoxWidth, comboBoxHeight);
- addAndMakeVisible(m_lfoShape);
- m_lfoShape.setBounds(m_clock.getBounds().getRight() + 26, 22, comboBoxWidth, comboBoxHeight);
-
+ setupBackground(*this, m_background, BinaryData::bg_fxreverb_481x234_png, BinaryData::bg_fxreverb_481x234_pngSize);
+ constexpr auto y = 18;
+ for (auto *s : {&m_time, &m_rate, &m_damping, &m_color, &m_feedback})
+ setupRotary(*this, *s);
+ m_time.setBounds(118, 18, knobSize, knobSize);
+ m_rate.setBounds(m_time.getRight() - 8, y, knobSize, knobSize);
+ m_damping.setBounds(m_rate.getRight() - 8, y, knobSize, knobSize);
+ m_color.setBounds(m_damping.getRight() - 3, y, knobSize, knobSize);
+ m_feedback.setBounds(m_color.getRight() - 3, y, knobSize, knobSize);
+ m_reverbMode.setBounds(18, 116+2+22, comboBoxWidth, comboBoxHeight);
addAndMakeVisible(m_reverbMode);
- m_reverbMode.setBounds(m_lfoShape.getBounds().getRight() + 26, 22, comboBoxWidth, comboBoxHeight);
-
- m_damping.getProperties().set(Virus::LookAndFeel::KnobStyleProp, Virus::LookAndFeel::KnobStyle::GENERIC_RED);
- m_damping.setBounds(m_reverbMode.getBounds().getRight() + 2, -2, knobSize, knobSize);
- addAndMakeVisible(m_damping);
- _parameterBinding.bind(m_mix, Virus::Param_EffectSend);
- _parameterBinding.bind(m_clock, Virus::Param_DelayClock, 0);
- _parameterBinding.bind(m_lfoShape, Virus::Param_DelayLfoShape, 0);
- _parameterBinding.bind(m_damping, Virus::Param_DelayLfoShape, 0);
_parameterBinding.bind(m_reverbMode, Virus::Param_DelayDepthReverbRoomSize, 0);
+ _parameterBinding.bind(m_time, Virus::Param_DelayTime, 0);
+ _parameterBinding.bind(m_rate, Virus::Param_DelayRateReverbDecayTime, 0);
+ _parameterBinding.bind(m_damping, Virus::Param_DelayLfoShape, 0);
+ _parameterBinding.bind(m_color, Virus::Param_DelayColor, 0);
+ _parameterBinding.bind(m_feedback, Virus::Param_DelayFeedback, 0);
}
FxEditor::Vocoder::Vocoder(VirusParameterBinding &_parameterBinding) :
diff --git a/source/jucePlugin/ui/Virus_FxEditor.h b/source/jucePlugin/ui/Virus_FxEditor.h
@@ -2,14 +2,14 @@
#include "../PluginProcessor.h"
#include "Virus_Buttons.h"
-
+#include "../VirusController.h"
class VirusParameterBinding;
class FxEditor : public juce::Component
{
public:
- FxEditor(VirusParameterBinding& _parameterBinding);
-
+ FxEditor(VirusParameterBinding& _parameterBinding, Virus::Controller& _controller);
+ void rebind();
private:
struct Distortion : juce::Component
{
@@ -75,26 +75,29 @@ private:
juce::Slider m_amount;
} m_punch;
- struct DelayAndReverb : juce::Component
+ struct Delay : juce::Component
{
- DelayAndReverb(VirusParameterBinding &_parameterBinding);
+ Delay(VirusParameterBinding &_parameterBinding);
+ std::unique_ptr<juce::Drawable> m_background;
juce::Slider m_time;
juce::Slider m_rate;
juce::Slider m_depth;
juce::Slider m_color;
juce::Slider m_feedback;
- juce::ComboBox m_fxMode;
-
- struct Sync : juce::Component
- {
- Sync(VirusParameterBinding &_parameterBinding);
- juce::Slider m_mix;
- juce::ComboBox m_clock, m_lfoShape;
- juce::ComboBox m_reverbMode;
- juce::Slider m_damping;
- } m_sync;
- } m_delayReverb;
+ juce::ComboBox m_clock, m_lfoShape;
+ };
+ struct Reverb : juce::Component
+ {
+ Reverb(VirusParameterBinding &_parameterBinding);
+ std::unique_ptr<juce::Drawable> m_background;
+ juce::Slider m_time;
+ juce::Slider m_rate;
+ juce::Slider m_damping;
+ juce::Slider m_color;
+ juce::Slider m_feedback;
+ juce::ComboBox m_reverbMode;
+ };
struct Vocoder : juce::Component
{
Vocoder(VirusParameterBinding &_parameterBinding);
@@ -123,6 +126,10 @@ private:
juce::ComboBox m_modInput;
} m_modulator;
} m_vocoder;
-
+ juce::ComboBox m_fxMode;
+ juce::Slider m_fxSend;
+ std::unique_ptr<Delay> m_delay;
+ std::unique_ptr<Reverb> m_reverb;
+ VirusParameterBinding &m_parameterBinding;
std::unique_ptr<juce::Drawable> m_background;
};
diff --git a/source/jucePlugin/ui/Virus_Parts.cpp b/source/jucePlugin/ui/Virus_Parts.cpp
@@ -107,7 +107,7 @@ Parts::Parts(VirusParameterBinding & _parameterBinding, Virus::Controller& _cont
addAndMakeVisible(m_btMultiMode);
//addAndMakeVisible(m_btMultiSingleMode);
m_btSingleMode.setTopLeftPosition(102, 756);
- m_btSingleMode.setSize(70, 30);
+ m_btSingleMode.setSize(103, 30);
m_btSingleMode.setColour(TextButton::ColourIds::textColourOnId, juce::Colours::white);
m_btSingleMode.setColour(TextButton::ColourIds::textColourOffId, juce::Colours::grey);
@@ -119,8 +119,8 @@ Parts::Parts(VirusParameterBinding & _parameterBinding, Virus::Controller& _cont
m_btMultiSingleMode.onClick = [this]() { setPlayMode(virusLib::PlayMode::PlayModeMultiSingle); };
m_btMultiMode.onClick = [this]() { setPlayMode(virusLib::PlayMode::PlayModeMulti); };
- m_btMultiSingleMode.setBounds(m_btSingleMode.getBounds().translated(m_btSingleMode.getWidth()+4, 0));
- m_btMultiMode.setBounds(m_btMultiSingleMode.getBounds().translated(m_btMultiSingleMode.getWidth()+4, 0));
+ //m_btMultiSingleMode.setBounds(m_btSingleMode.getBounds().translated(m_btSingleMode.getWidth()+4, 0));
+ m_btMultiMode.setBounds(m_btSingleMode.getBounds().translated(m_btSingleMode.getWidth()+4, 0));
}
Parts::~Parts() {
}
@@ -172,5 +172,8 @@ void Parts::changePart(uint8_t _part)
void Parts::setPlayMode(uint8_t _mode) {
m_controller.getParameter(Virus::Param_PlayMode)->setValue(_mode);
+ if (_mode == virusLib::PlayModeSingle && m_controller.getCurrentPart() != 0) {
+ changePart(0);
+ }
getParentComponent()->postCommandMessage(VirusEditor::Commands::Rebind);
-}
-\ No newline at end of file
+}
diff --git a/source/virusLib/microcontroller.cpp b/source/virusLib/microcontroller.cpp
@@ -904,10 +904,10 @@ void Microcontroller::applyToSingleEditBuffer(TPreset& _single, const Page _page
void Microcontroller::applyToMultiEditBuffer(const uint8_t _part, const uint8_t _param, const uint8_t _value)
{
// remap page C parameters into the multi edit buffer
- if (_part == PAGE_C && _param >= PART_MIDI_CHANNEL && _param <= PART_OUTPUT_SELECT) {
+ if (_param >= PART_MIDI_CHANNEL && _param <= PART_OUTPUT_SELECT) {
m_multiEditBuffer[MD_PART_MIDI_CHANNEL + ((_param-PART_MIDI_CHANNEL)*16) + _part] = _value;
}
- else if (_part == PAGE_B && _param == CLOCK_TEMPO) {
+ else if (_param == CLOCK_TEMPO) {
m_multiEditBuffer[MD_CLOCK_TEMPO] = _value;
}
}