mirror of https://github.com/AxioDL/amuse.git
Implement ADSREditor
This commit is contained in:
parent
721dd361fa
commit
57cbbf24b1
File diff suppressed because it is too large
Load Diff
|
@ -2,13 +2,80 @@
|
||||||
#define AMUSE_ADSR_EDITOR_HPP
|
#define AMUSE_ADSR_EDITOR_HPP
|
||||||
|
|
||||||
#include "EditorWidget.hpp"
|
#include "EditorWidget.hpp"
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QStaticText>
|
||||||
|
|
||||||
|
class ADSREditor;
|
||||||
|
|
||||||
|
class ADSRView : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
friend class ADSRControls;
|
||||||
|
amuse::ObjToken<ProjectModel::ADSRNode> m_node;
|
||||||
|
QFont m_gridFont;
|
||||||
|
QStaticText m_percentTexts[11];
|
||||||
|
std::vector<QStaticText> m_timeTexts;
|
||||||
|
int m_dragPoint = -1;
|
||||||
|
ADSREditor* getEditor() const;
|
||||||
|
public:
|
||||||
|
explicit ADSRView(QWidget* parent = Q_NULLPTR);
|
||||||
|
void loadData(ProjectModel::ADSRNode* node);
|
||||||
|
void unloadData();
|
||||||
|
ProjectModel::INode* currentNode() const;
|
||||||
|
|
||||||
|
void paintEvent(QPaintEvent* ev);
|
||||||
|
void mousePressEvent(QMouseEvent* ev);
|
||||||
|
void mouseReleaseEvent(QMouseEvent* ev);
|
||||||
|
void mouseMoveEvent(QMouseEvent* ev);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ADSRControls : public QFrame
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
friend class ADSRView;
|
||||||
|
QDoubleSpinBox* m_attack;
|
||||||
|
QDoubleSpinBox* m_decay;
|
||||||
|
QDoubleSpinBox* m_sustain;
|
||||||
|
QDoubleSpinBox* m_release;
|
||||||
|
QCheckBox* m_dls;
|
||||||
|
QLabel* m_velToAttackLab;
|
||||||
|
QDoubleSpinBox* m_velToAttack;
|
||||||
|
QLabel* m_keyToDecayLab;
|
||||||
|
QDoubleSpinBox* m_keyToDecay;
|
||||||
|
bool m_enableUpdate = true;
|
||||||
|
ADSREditor* getEditor() const;
|
||||||
|
void setAttackAndDecay(double attack, double decay);
|
||||||
|
void setDecayAndSustain(double decay, double sustain);
|
||||||
|
public:
|
||||||
|
explicit ADSRControls(QWidget* parent = Q_NULLPTR);
|
||||||
|
void loadData();
|
||||||
|
void unloadData();
|
||||||
|
public slots:
|
||||||
|
void attackChanged(double val);
|
||||||
|
void decayChanged(double val);
|
||||||
|
void sustainChanged(double val);
|
||||||
|
void releaseChanged(double val);
|
||||||
|
void dlsStateChanged(int state);
|
||||||
|
void velToAttackChanged(double val);
|
||||||
|
void keyToDecayChanged(double val);
|
||||||
|
};
|
||||||
|
|
||||||
class ADSREditor : public EditorWidget
|
class ADSREditor : public EditorWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
friend class ADSRView;
|
||||||
|
friend class ADSRControls;
|
||||||
|
ADSRView* m_adsrView;
|
||||||
|
ADSRControls* m_controls;
|
||||||
public:
|
public:
|
||||||
explicit ADSREditor(QWidget* parent = Q_NULLPTR);
|
explicit ADSREditor(QWidget* parent = Q_NULLPTR);
|
||||||
bool loadData(ProjectModel::ADSRNode* node);
|
bool loadData(ProjectModel::ADSRNode* node);
|
||||||
|
void unloadData();
|
||||||
|
ProjectModel::INode* currentNode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,16 @@ protected:
|
||||||
{
|
{
|
||||||
SMChangeVal,
|
SMChangeVal,
|
||||||
SampLoop,
|
SampLoop,
|
||||||
SampPitch
|
SampPitch,
|
||||||
|
ADSRAttack,
|
||||||
|
ADSRDecay,
|
||||||
|
ADSRSustain,
|
||||||
|
ADSRAttackAndDecay,
|
||||||
|
ADSRDecayAndSustain,
|
||||||
|
ADSRRelease,
|
||||||
|
ADSRDLS,
|
||||||
|
ADSRVelToAttack,
|
||||||
|
ADSRKeyToDecay
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
EditorUndoCommand(amuse::ObjToken<ProjectModel::INode> node,
|
EditorUndoCommand(amuse::ObjToken<ProjectModel::INode> node,
|
||||||
|
|
|
@ -72,9 +72,14 @@ class SampleControls : public QFrame
|
||||||
bool m_enableUpdate = true;
|
bool m_enableUpdate = true;
|
||||||
bool m_enableFileWrite = true;
|
bool m_enableFileWrite = true;
|
||||||
public:
|
public:
|
||||||
SampleControls(QWidget* parent = Q_NULLPTR);
|
explicit SampleControls(QWidget* parent = Q_NULLPTR);
|
||||||
void doFileWrite();
|
void doFileWrite();
|
||||||
void setFileWrite(bool w);
|
void setFileWrite(bool w);
|
||||||
|
void updateFileState();
|
||||||
|
void setLoopStartSample(int sample) { m_loopStart->setValue(sample); }
|
||||||
|
void setLoopEndSample(int sample) { m_loopEnd->setValue(sample); }
|
||||||
|
void loadData(bool reset);
|
||||||
|
void unloadData();
|
||||||
public slots:
|
public slots:
|
||||||
void zoomSliderChanged(int val);
|
void zoomSliderChanged(int val);
|
||||||
void loopStateChanged(int state);
|
void loopStateChanged(int state);
|
||||||
|
@ -84,13 +89,6 @@ public slots:
|
||||||
void makeWAVVersion();
|
void makeWAVVersion();
|
||||||
void makeCompressedVersion();
|
void makeCompressedVersion();
|
||||||
void showInBrowser();
|
void showInBrowser();
|
||||||
void updateFileState();
|
|
||||||
|
|
||||||
void setLoopStartSample(int sample) { m_loopStart->setValue(sample); }
|
|
||||||
void setLoopEndSample(int sample) { m_loopEnd->setValue(sample); }
|
|
||||||
|
|
||||||
void loadData(bool reset);
|
|
||||||
void unloadData();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SampleEditor : public EditorWidget
|
class SampleEditor : public EditorWidget
|
||||||
|
|
|
@ -1,6 +1,101 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE TS>
|
<!DOCTYPE TS>
|
||||||
<TS version="2.1" language="de_DE">
|
<TS version="2.1" language="de_DE">
|
||||||
|
<context>
|
||||||
|
<name>ADSRControls</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../ADSREditor.cpp" line="+332"/>
|
||||||
|
<source>Change Attack</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+64"/>
|
||||||
|
<source>Change Decay</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+64"/>
|
||||||
|
<source>Change Sustain</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+65"/>
|
||||||
|
<source>Change Attack/Decay</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+74"/>
|
||||||
|
<source>Change Decay/Sustain</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+73"/>
|
||||||
|
<source>Change Release</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+90"/>
|
||||||
|
<source>Change DLS</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+87"/>
|
||||||
|
<source>Change Vel To Attack</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+53"/>
|
||||||
|
<source>Change Key To Decay</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+64"/>
|
||||||
|
<source>Attack</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+8"/>
|
||||||
|
<location line="+14"/>
|
||||||
|
<location line="+23"/>
|
||||||
|
<source> sec</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="-31"/>
|
||||||
|
<source>Decay</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+13"/>
|
||||||
|
<source>Sustain</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+5"/>
|
||||||
|
<source> %</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+5"/>
|
||||||
|
<source>Release</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+13"/>
|
||||||
|
<source>DLS</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+10"/>
|
||||||
|
<source>Vel To Attack</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location line="+11"/>
|
||||||
|
<source>Key To Decay</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>Core::Internal</name>
|
<name>Core::Internal</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -1169,6 +1169,14 @@ static inline double TimeCentsToSeconds(int32_t tc)
|
||||||
return std::exp2(tc / (1200.0 * 65536.0));
|
return std::exp2(tc / (1200.0 * 65536.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Converts seconds representation to time-cents */
|
||||||
|
static inline int32_t SecondsToTimeCents(double sec)
|
||||||
|
{
|
||||||
|
if (sec == 0.0)
|
||||||
|
return 0x80000000;
|
||||||
|
return int32_t(std::log2(sec) * (1200.0 * 65536.0));
|
||||||
|
}
|
||||||
|
|
||||||
/** Polymorphic interface for representing table data */
|
/** Polymorphic interface for representing table data */
|
||||||
struct ITable : LittleDNAV
|
struct ITable : LittleDNAV
|
||||||
{
|
{
|
||||||
|
@ -1188,15 +1196,19 @@ struct ADSR : ITable
|
||||||
{
|
{
|
||||||
AT_DECL_DNA_YAML
|
AT_DECL_DNA_YAML
|
||||||
AT_DECL_DNAV
|
AT_DECL_DNAV
|
||||||
Value<atUint16> attack;
|
Value<atUint16> attack = 0;
|
||||||
Value<atUint16> decay;
|
Value<atUint16> decay = 0x8000;
|
||||||
Value<atUint16> sustain; /* 0x1000 == 100% */
|
Value<atUint16> sustain = 0; /* 0x1000 == 100% */
|
||||||
Value<atUint16> release; /* milliseconds */
|
Value<atUint16> release = 0; /* milliseconds */
|
||||||
|
|
||||||
double getAttack() const { return attack / 1000.0; }
|
double getAttack() const { return attack / 1000.0; }
|
||||||
|
void setAttack(double v) { attack = v * 1000.0; }
|
||||||
double getDecay() const { return (decay == 0x8000) ? 0.0 : (decay / 1000.0); }
|
double getDecay() const { return (decay == 0x8000) ? 0.0 : (decay / 1000.0); }
|
||||||
|
void setDecay(double v) { decay = v == 0.0 ? 0x8000 : v * 1000.0; }
|
||||||
double getSustain() const { return sustain / double(0x1000); }
|
double getSustain() const { return sustain / double(0x1000); }
|
||||||
|
void setSustain(double v) { sustain = v * double(0x1000); }
|
||||||
double getRelease() const { return release / 1000.0; }
|
double getRelease() const { return release / 1000.0; }
|
||||||
|
void setRelease(double v) { release = v * 1000.0; }
|
||||||
|
|
||||||
Type Isa() const { return ITable::Type::ADSR; }
|
Type Isa() const { return ITable::Type::ADSR; }
|
||||||
};
|
};
|
||||||
|
@ -1206,23 +1218,61 @@ struct ADSRDLS : ITable
|
||||||
{
|
{
|
||||||
AT_DECL_DNA_YAML
|
AT_DECL_DNA_YAML
|
||||||
AT_DECL_DNAV
|
AT_DECL_DNAV
|
||||||
Value<atUint32> attack; /* 16.16 Time-cents */
|
Value<atUint32> attack = 0x80000000; /* 16.16 Time-cents */
|
||||||
Value<atUint32> decay; /* 16.16 Time-cents */
|
Value<atUint32> decay = 0x80000000; /* 16.16 Time-cents */
|
||||||
Value<atUint16> sustain; /* 0x1000 == 100% */
|
Value<atUint16> sustain = 0; /* 0x1000 == 100% */
|
||||||
Value<atUint16> release; /* milliseconds */
|
Value<atUint16> release = 0; /* milliseconds */
|
||||||
Value<atUint32> velToAttack; /* 16.16, 1000.0 == 100%; attack = <attack> + (vel/128) * <velToAttack> */
|
Value<atUint32> velToAttack = 0x80000000; /* 16.16, 1000.0 == 100%; attack = <attack> + (vel/128) * <velToAttack> */
|
||||||
Value<atUint32> keyToDecay; /* 16.16, 1000.0 == 100%; decay = <decay> + (note/128) * <keyToDecay> */
|
Value<atUint32> keyToDecay = 0x80000000; /* 16.16, 1000.0 == 100%; decay = <decay> + (note/128) * <keyToDecay> */
|
||||||
|
|
||||||
double getAttack() const { return TimeCentsToSeconds(attack); }
|
double getAttack() const { return TimeCentsToSeconds(attack); }
|
||||||
|
void setAttack(double v) { attack = SecondsToTimeCents(v); }
|
||||||
double getDecay() const { return TimeCentsToSeconds(decay); }
|
double getDecay() const { return TimeCentsToSeconds(decay); }
|
||||||
|
void setDecay(double v) { decay = SecondsToTimeCents(v); }
|
||||||
double getSustain() const { return sustain / double(0x1000); }
|
double getSustain() const { return sustain / double(0x1000); }
|
||||||
|
void setSustain(double v) { sustain = v * double(0x1000); }
|
||||||
double getRelease() const { return release / 1000.0; }
|
double getRelease() const { return release / 1000.0; }
|
||||||
|
void setRelease(double v) { release = v * 1000.0; }
|
||||||
|
|
||||||
|
double _getVelToAttack() const
|
||||||
|
{
|
||||||
|
if (velToAttack == 0x80000000)
|
||||||
|
return 0.0;
|
||||||
|
else
|
||||||
|
return velToAttack / 65536.0 / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setVelToAttack(double v)
|
||||||
|
{
|
||||||
|
if (v == 0.0)
|
||||||
|
velToAttack = 0x80000000;
|
||||||
|
else
|
||||||
|
velToAttack = atUint32(v * 1000.0 * 65536.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double _getKeyToDecay() const
|
||||||
|
{
|
||||||
|
if (keyToDecay == 0x80000000)
|
||||||
|
return 0.0;
|
||||||
|
else
|
||||||
|
return keyToDecay / 65536.0 / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setKeyToDecay(double v)
|
||||||
|
{
|
||||||
|
if (v == 0.0)
|
||||||
|
keyToDecay = 0x80000000;
|
||||||
|
else
|
||||||
|
keyToDecay = atUint32(v * 1000.0 * 65536.0);
|
||||||
|
}
|
||||||
|
|
||||||
double getVelToAttack(int8_t vel) const
|
double getVelToAttack(int8_t vel) const
|
||||||
{
|
{
|
||||||
if (velToAttack == 0x80000000)
|
if (velToAttack == 0x80000000)
|
||||||
return getAttack();
|
return getAttack();
|
||||||
return getAttack() + vel * (velToAttack / 65536.0 / 1000.0) / 128.0;
|
return getAttack() + vel * (velToAttack / 65536.0 / 1000.0) / 128.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double getKeyToDecay(int8_t note) const
|
double getKeyToDecay(int8_t note) const
|
||||||
{
|
{
|
||||||
if (keyToDecay == 0x80000000)
|
if (keyToDecay == 0x80000000)
|
||||||
|
|
Loading…
Reference in New Issue