Implement ADSREditor

This commit is contained in:
Jack Andersen 2018-08-03 16:07:34 -10:00
parent 721dd361fa
commit 57cbbf24b1
6 changed files with 1327 additions and 22 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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;
}; };

View File

@ -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,

View File

@ -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

View File

@ -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>

View File

@ -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)