You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
dexed/Source/DXComponents.cpp

298 lines
9.2 KiB

/**
*
* Copyright (c) 2014 Pascal Gauthier.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*/
#include "DXComponents.h"
#include "PluginProcessor.h"
#include "msfa/pitchenv.h"
/**
* Algorithm arrangements, based on the DX1 display.
*/
static const char algoArr[][13] = {
// 1 2 3 4 5 6 7 8 9 A B C D
{ 0, 0, 1, 3, 0, 0, 0, 2, 4, 0, 0, 5, -6 }, // 1
{ 0, 0, 1, 3, 0, 0, 0, -2, 4, 0, 0, 5, 6 }, // 2
{ 0, 0, 1, 4, 0, 0, 0, 2, 5, 0, 3, -6, 0 }, // 3
{ 0, 0, 1, -4, 0, 0, 0, 2, -5, 0, 3, -6, 0 }, // 4
{ 0, 1, 3, 5, 0, 0, 2, 4, -6, 0, 0, 0, 0 }, // 5
{ 0, 1, 3, -5, 0, 0, 2, 4, -6, 0, 0, 0, 0 }, // 6
{ 0, 1, 3, 0, 0, 0, 2, 4, 5, 0, 0, -6, 0 }, // 7
{ 0, 1, 3, 0, 0, 0, 2, -4, 5, 0, 0, 6, 0 }, // 8
{ 0, 1, 3, 0, 0, 0, -2, 4, 5, 0, 0, 6, 0 }, // 9
{ 0, 0, 4, 1, 0, 0, 5, 6, 2, 0, 0, -3, 0 }, // 10
{ 0, 0, 4, 1, 0, 0, 5, -6, 2, 0, 0, 3, 0 }, // 11
{ 0, 0, 3, 0, 1, 0, 4, 5, 6, -2, 0, 0, 0 }, // 12
{ 0, 0, 3, 0, 1, 0, 4, 5, -6, 2, 0, 0, 0 }, // 13
// 1 2 3 4 5 6 7 8 9 A B C D
{ 0, 0, 1, 3, 0, 0, 0, 2, 4, 0, 5, -6, 0 }, // 14
{ 0, 0, 1, 3, 0, 0, 0, -2, 4, 0, 5, 6, 0 }, // 15
{ 0, 0, 1, 0, 0, 0, 2, 3, 5, 0, 4, -6, 0 }, // 16
{ 0, 0, 1, 0, 0, 0, -2, 3, 5, 0, 4, 6, 0 }, // 17
{ 0, 0, 1, 0, 0, 0, 2, -3, 4, 0, 0, 5, 6 }, // 18
{ 0, 0, 1, 4, 5, 0, 0, 2, -6, 0, 3, 0, 0 }, // 19
{ 0, 1, 2, 0, 4, 0, -3, 0, 5, 6, 0, 0, 0 }, // 20
{ 0, 1, 2, 4, 5, 0, -3, 0, 6, 0, 0, 0, 0 }, // 21
{ 0, 1, 3, 4, 5, 0, 2, 0, -6, 0, 0, 0, 0 }, // 22
{ 0, 1, 2, 4, 5, 0, 0, 3, -6, 0, 0, 0, 0 }, // 23
{ 1, 2, 3, 4, 5, 0, 0, 0, -6, 0, 0, 0, 0 }, // 24
{ 1, 2, 3, 4, 5, 0, 0, 0, -6, 0, 0, 0, 0 }, // 25
{ 0, 1, 2, 0, 4, 0, 0, 3, 5, -6, 0, 0, 0 }, // 26
// 1 2 3 4 5 6 7 8 9 A B C D
{ 0, 1, 2, 0, 4, 0, 0, -3, 5, 6, 0, 0, 0 }, // 27
{ 0, 1, 3, 6, 0, 0, 2, 4, 0, 0, -5, 0, 0 }, // 28
{ 0, 1, 2, 3, 5, 0, 0, 0, 4, -6, 0, 0, 0 }, // 29
{ 0, 1, 2, 3, 6, 0, 0, 0, 4, 0, 0, -5, 0 }, // 30
{ 1, 2, 3, 4, 5, 0, 0, 0, 0, -6, 0, 0, 0 }, // 31
{ 1, 2, 3, 4, 5, -6, 0, 0, 0, 0, 0, 0, 0 } // 32
};
static char TMP_LEVEL_PTR[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
AlgoDisplay::AlgoDisplay() {
static char tmpAlgo = 0;
algo = &tmpAlgo;
}
void AlgoDisplay::paint(Graphics &g) {
int alg;
if ( *algo <= 31 ) {
alg = *algo;
} else {
alg = 31;
}
const char *arr = algoArr[alg];
g.setColour (Colours::black.withAlpha(0.1f));
g.fillRoundedRectangle (0.0f, 0.0f, (float) getWidth(), (float) getHeight(), 1.0f);
for(int i=0;i<13;i++) {
int target = arr[i];
if ( target == 0 )
continue;
if ( i < 6 ) {
drawOp(g, i, 3, target);
continue;
}
if ( i < 10 ){
drawOp(g, (i-6)+1, 2, target);
continue;
}
if ( i < 12 ) {
drawOp(g, (i-10)+2, 1, target);
continue;
}
// last one
drawOp(g, (i-12)+3, 0, target);
}
String algoTxt;
algoTxt << (alg+1);
g.drawText(algoTxt, 5, 1, 21, 14, Justification::left, true);
}
void AlgoDisplay::drawOp(Graphics &g, int x, int y, int num) {
String txt;
txt << abs(num);
int offx = 24;
int offy = 17;
g.setColour(Colour(0xFF0FC00F));
g.fillRect(x*offx+4, y*offy+3, offx-2, offy-1);
g.setColour(Colour(0xFFFFFFFF));
g.drawText(txt, x*offx+3, y*offy+2, offx+2, offy+2, Justification::centred, true);
if ( num < 0 ) {
g.setColour(Colour(0xFFFFFFFF));
int x1 = (x*offx) + 24;
g.drawLine(x1+1, y*offy+3, x1+1, y*offy+offy+2, 3);
}
}
EnvDisplay::EnvDisplay() {
pvalues = (char *) &TMP_LEVEL_PTR;
}
void EnvDisplay::paint(Graphics &g) {
g.setColour(Colours::black.withAlpha(0.5f));
g.fillRoundedRectangle (0.0f, 0.0f, (float) getWidth(), (float) getHeight(), 1.0f);
char *levels = pvalues + 4;
char *rates = pvalues;
float dist[4];
float total = 0;
int old = levels[3];
for(int i=0;i<4;i++) {
int nw = levels[i];
dist[i] = ((float)abs(nw - old)) / rates[i] == 0 ? 1 : rates[i];
total += dist[i];
old = nw;
}
if ( total < 1 ) {
dist[0] = dist[1] = dist[2] = dist[3] = 1;
total = 4;
}
// TODO : this is WIP
float ratio = 96 / total;
int oldx = 0;
int oldy = 32 - ((float)levels[3] / 3.125);
Path p;
p.startNewSubPath(0, 32);
g.setColour(Colours::white);
int i;
for(i=0;i<4;i++) {
int newx = dist[i] * ratio + oldx;
int newy = 32 - ((float)levels[i] / 3.125);
p.lineTo(newx, newy);
if ( vPos == i ) {
g.fillEllipse(oldx-2, oldy-2, 4, 4);
}
oldx = newx;
oldy = newy;
}
p.lineTo(96,32);
p.lineTo(0, 32);
if ( vPos == i ) {
g.fillEllipse(oldx-2, oldy-2, 4, 4);
}
g.setColour(Colour(0xFF0FC00F).withAlpha(0.3f));
g.fillPath(p);
g.setColour(Colour(0xFFFFFFFF));
String len;
len << ((int) total);
g.drawText(len, 5, 1, 72, 14, Justification::left, true);
}
PitchEnvDisplay::PitchEnvDisplay() {
pvalues = (char *) &TMP_LEVEL_PTR;
vPos = 0;
}
void PitchEnvDisplay::paint(Graphics &g) {
g.setColour(Colours::black.withAlpha(0.1f));
g.fillRoundedRectangle (0.0f, 0.0f, (float) getWidth(), (float) getHeight(), 1.0f);
g.setColour(Colours::white);
char *levels = pvalues + 4;
char *rates = pvalues;
float dist[4];
float total = 0;
int old = pitchenv_tab[levels[3]] + 128;
// find the scale
for(int i=0;i<4;i++) {
int nw = pitchenv_tab[levels[i]] + 128;
dist[i] = ((float)abs(nw - old)) / pitchenv_rate[rates[i]];
total += dist[i];
old = nw;
}
if ( total < 0.00001 ) {
dist[0] = dist[1] = dist[2] = dist[3] = 1;
total = 4;
}
// TODO : this is WIP
float ratio = 96 / total;
int oldx = 0;
int oldy = 25 - (pitchenv_tab[levels[3]] + 128) / 10;
int i;
for(i=0;i<4;i++) {
int newx = dist[i] * ratio + oldx;
int newy = 25 - (pitchenv_tab[levels[i]] + 128) / 10;
g.drawLine(oldx, oldy, newx, newy, 2);
if ( vPos == i ) {
g.fillEllipse(oldx-2, oldy-2, 4, 4);
}
oldx = newx;
oldy = newy;
}
if ( vPos == i ) {
g.fillEllipse(oldx-2, oldy-2, 4, 4);
}
}
void VuMeter::paint(Graphics &g) {
// taken from the drawLevelMeter ;
float width = getWidth();
float height = getHeight();
g.setColour (Colours::black);
g.fillRoundedRectangle (0.0f, 0.0f, (float) width, (float) height, 0);
/*g.setColour (Colours::black.withAlpha (0.2f));
g.drawRoundedRectangle (1.0f, 1.0f, width - 2.0f, height - 2.0f, 3.0f, 1.0f);*/
const int totalBlocks = 16;
const int numBlocks = roundToInt (totalBlocks * v);
const float h = (height - 6.0f) / (float) totalBlocks;
for (int i = 0; i < totalBlocks; ++i) {
g.setColour (Colours::red);
if (i >= numBlocks)
g.setColour (Colours::red.withAlpha (0.2f));
else
g.setColour (Colours::red);
//g.fillRoundedRectangle (3.0f + i * w + w * 0.1f, 3.0f, w * 0.8f, height - 6.0f, w * 0.4f);
g.fillRoundedRectangle (3.0f, (height-3.0f) - (3.0f + i * h + h * 0.1f) , width - 6.0f, h * 0.8f, 0);
}
}
void LcdDisplay::paint(Graphics &g) {
g.setColour(Colours::black.withAlpha(0.4f));
g.fillRoundedRectangle (0.0f, 0.0f, (float) getWidth(), (float) getHeight(), 1.0f);
g.setColour (Colours::white);
g.setFont (Font (Font::getDefaultMonospacedFontName(), 15.00f, Font::plain));
g.drawText (systemMsg,
4, 4, 300, 8,
Justification::centredLeft, true);
g.drawText (paramMsg,
4, 20, 300, 8,
Justification::centredLeft, true);
}