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
|
||||
|
||||
#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
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class ADSRView;
|
||||
friend class ADSRControls;
|
||||
ADSRView* m_adsrView;
|
||||
ADSRControls* m_controls;
|
||||
public:
|
||||
explicit ADSREditor(QWidget* parent = Q_NULLPTR);
|
||||
bool loadData(ProjectModel::ADSRNode* node);
|
||||
void unloadData();
|
||||
ProjectModel::INode* currentNode() const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,16 @@ protected:
|
|||
{
|
||||
SMChangeVal,
|
||||
SampLoop,
|
||||
SampPitch
|
||||
SampPitch,
|
||||
ADSRAttack,
|
||||
ADSRDecay,
|
||||
ADSRSustain,
|
||||
ADSRAttackAndDecay,
|
||||
ADSRDecayAndSustain,
|
||||
ADSRRelease,
|
||||
ADSRDLS,
|
||||
ADSRVelToAttack,
|
||||
ADSRKeyToDecay
|
||||
};
|
||||
public:
|
||||
EditorUndoCommand(amuse::ObjToken<ProjectModel::INode> node,
|
||||
|
|
|
@ -72,9 +72,14 @@ class SampleControls : public QFrame
|
|||
bool m_enableUpdate = true;
|
||||
bool m_enableFileWrite = true;
|
||||
public:
|
||||
SampleControls(QWidget* parent = Q_NULLPTR);
|
||||
explicit SampleControls(QWidget* parent = Q_NULLPTR);
|
||||
void doFileWrite();
|
||||
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:
|
||||
void zoomSliderChanged(int val);
|
||||
void loopStateChanged(int state);
|
||||
|
@ -84,13 +89,6 @@ public slots:
|
|||
void makeWAVVersion();
|
||||
void makeCompressedVersion();
|
||||
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
|
||||
|
|
|
@ -1,6 +1,101 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<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>
|
||||
<name>Core::Internal</name>
|
||||
<message>
|
||||
|
|
|
@ -1169,6 +1169,14 @@ static inline double TimeCentsToSeconds(int32_t tc)
|
|||
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 */
|
||||
struct ITable : LittleDNAV
|
||||
{
|
||||
|
@ -1188,15 +1196,19 @@ struct ADSR : ITable
|
|||
{
|
||||
AT_DECL_DNA_YAML
|
||||
AT_DECL_DNAV
|
||||
Value<atUint16> attack;
|
||||
Value<atUint16> decay;
|
||||
Value<atUint16> sustain; /* 0x1000 == 100% */
|
||||
Value<atUint16> release; /* milliseconds */
|
||||
Value<atUint16> attack = 0;
|
||||
Value<atUint16> decay = 0x8000;
|
||||
Value<atUint16> sustain = 0; /* 0x1000 == 100% */
|
||||
Value<atUint16> release = 0; /* milliseconds */
|
||||
|
||||
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); }
|
||||
void setDecay(double v) { decay = v == 0.0 ? 0x8000 : v * 1000.0; }
|
||||
double getSustain() const { return sustain / double(0x1000); }
|
||||
void setSustain(double v) { sustain = v * double(0x1000); }
|
||||
double getRelease() const { return release / 1000.0; }
|
||||
void setRelease(double v) { release = v * 1000.0; }
|
||||
|
||||
Type Isa() const { return ITable::Type::ADSR; }
|
||||
};
|
||||
|
@ -1206,23 +1218,61 @@ struct ADSRDLS : ITable
|
|||
{
|
||||
AT_DECL_DNA_YAML
|
||||
AT_DECL_DNAV
|
||||
Value<atUint32> attack; /* 16.16 Time-cents */
|
||||
Value<atUint32> decay; /* 16.16 Time-cents */
|
||||
Value<atUint16> sustain; /* 0x1000 == 100% */
|
||||
Value<atUint16> release; /* milliseconds */
|
||||
Value<atUint32> velToAttack; /* 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> attack = 0x80000000; /* 16.16 Time-cents */
|
||||
Value<atUint32> decay = 0x80000000; /* 16.16 Time-cents */
|
||||
Value<atUint16> sustain = 0; /* 0x1000 == 100% */
|
||||
Value<atUint16> release = 0; /* milliseconds */
|
||||
Value<atUint32> velToAttack = 0x80000000; /* 16.16, 1000.0 == 100%; attack = <attack> + (vel/128) * <velToAttack> */
|
||||
Value<atUint32> keyToDecay = 0x80000000; /* 16.16, 1000.0 == 100%; decay = <decay> + (note/128) * <keyToDecay> */
|
||||
|
||||
double getAttack() const { return TimeCentsToSeconds(attack); }
|
||||
void setAttack(double v) { attack = SecondsToTimeCents(v); }
|
||||
double getDecay() const { return TimeCentsToSeconds(decay); }
|
||||
void setDecay(double v) { decay = SecondsToTimeCents(v); }
|
||||
double getSustain() const { return sustain / double(0x1000); }
|
||||
void setSustain(double v) { sustain = v * double(0x1000); }
|
||||
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
|
||||
{
|
||||
if (velToAttack == 0x80000000)
|
||||
return getAttack();
|
||||
return getAttack() + vel * (velToAttack / 65536.0 / 1000.0) / 128.0;
|
||||
}
|
||||
|
||||
double getKeyToDecay(int8_t note) const
|
||||
{
|
||||
if (keyToDecay == 0x80000000)
|
||||
|
|
Loading…
Reference in New Issue