/
StringControl.cpp
118 lines (102 loc) · 2.98 KB
/
StringControl.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "StringControl.h"
#include "SpectralGen.h"
#include "SpectralHarp.h"
#include "Params.h"
const float kPadding = 16;
StringControl::StringControl(const SpectralGen& rSpectrum, IPlugBase *pPlug, IRECT pR, int handleRadius)
: IControl(pPlug, pR)
, spectrum(rSpectrum)
, mHandleRadius(handleRadius)
, mMouseX(-1)
, mMouseY(-1)
, stringAnimation(0)
{
}
bool StringControl::Draw(IGraphics* pGraphics)
{
//const int numBands = (Settings::BandLast - Settings::BandFirst) * Settings::BandDensity;
const float numBands = (float)mPlug->GetParam(kBandDensity)->Int();
const float bandFirst = (float)mPlug->GetParam(kBandFirst)->Int();
const float bandLast = (float)mPlug->GetParam(kBandLast)->Int();
SpectralHarp* harp = static_cast<SpectralHarp*>(mPlug);
if ( numBands > 0 && harp != nullptr)
{
for (int b = 0; b <= numBands; ++b)
{
const float freq = harp->FrequencyOfString(b);
const float x = Map((float)b, 0, numBands, mRECT.L + kPadding, mRECT.R - kPadding);
const float p = spectrum.getBandPhase(freq) + stringAnimation;
const float m = spectrum.getBandMagnitude(freq);
const int g = (int)(255.f * Map(m, 0, kSpectralAmpMax, 0.4f, 1.f));
const IColor color(255, g, g, g);
const float w = Map(m, 0, kSpectralAmpMax, 0, 6);
const float segments = 32;
const float segLength = mRECT.H() / segments;
float py0 = 0;
float px0 = x + w*sinf(p);
for (int i = 1; i < segments+1; ++i)
{
const float py1 = i*segLength;
const float s1 = py1 / mRECT.H() * (float)M_PI * 8 + p;
const float px1 = x + w*sinf(s1);
pGraphics->DrawLine(&color, px0, py0, px1, py1);
px0 = px1;
py0 = py1;
}
}
}
const float dt = 1.0f / 60.f;
stringAnimation += dt * TWO_PI * 2;
if (stringAnimation > TWO_PI)
{
stringAnimation -= TWO_PI;
}
if (mMouseX != -1 || mMouseY != -1)
{
SnapToMouse(mMouseX, mMouseY);
}
SetDirty(false);
Redraw();
return true;
}
void StringControl::OnMouseDown(int x, int y, IMouseMod* pMod)
{
if ( pMod->R )
{
SpectralHarp* harp = dynamic_cast<SpectralHarp*>(mPlug);
if (harp != nullptr)
{
harp->BeginMIDILearn(kPluckX, kPluckY, x, y);
}
}
else if ( pMod->L )
{
mMouseX = x;
mMouseY = y;
SnapToMouse(x, y);
}
}
void StringControl::OnMouseUp(int x, int y, IMouseMod* pMod)
{
mMouseX = -1;
mMouseY = -1;
}
void StringControl::OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod)
{
if (pMod->L)
{
mMouseX = x;
mMouseY = y;
SnapToMouse(x, y);
}
}
void StringControl::SnapToMouse(int x, int y)
{
const float pluckX = BOUNDED(Map((float)x, mRECT.L + kPadding, mRECT.R - kPadding, 0, 1), 0, 1);
const float pluckY = BOUNDED(Map((float)y, mRECT.T, mRECT.B, 1, 0), 0, 1);
SpectralHarp* harp = static_cast<SpectralHarp*>(mPlug);
if (harp != nullptr)
{
harp->Pluck(pluckX, pluckY);
}
}