mirror of https://github.com/dcoredump/dexed.git
parent
3dd5e5a224
commit
3d5ec67038
@ -1,379 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2014, 2015 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 3 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 "AlgoDisplay.h" |
||||
#include "DXLookNFeel.h" |
||||
#include "Dexed.h" |
||||
|
||||
AlgoDisplay::AlgoDisplay() { |
||||
static char tmpAlgo = 0; |
||||
algo = &tmpAlgo; |
||||
} |
||||
|
||||
inline void displayOp(Graphics &g, char id, int x, int y, char link, char fb) { |
||||
const int LINE_SZ = 3; |
||||
String t(id); |
||||
|
||||
x *= 25; |
||||
x += 3; |
||||
y *= 21; |
||||
y += 5; |
||||
|
||||
g.setColour(Colours::white); |
||||
g.drawText(t, x, y, 16, 12, Justification::centred, true); |
||||
|
||||
g.setColour(DXLookNFeel::fillColour); |
||||
switch(link) { |
||||
case 0 : // LINE DOWN
|
||||
g.drawLine(x+8, y+12, x+8, y+21, LINE_SZ); |
||||
break; |
||||
case 1: // ARROW TO RIGHT
|
||||
g.drawLine(x+8, y+12, x+8, y+18, LINE_SZ); |
||||
g.drawLine(x+7, y+18, x+34, y+18, LINE_SZ); |
||||
break; |
||||
case 2: // ARROW TO RIGHT JOIN
|
||||
g.drawLine(x+8, y+12, x+8, y+19, LINE_SZ); |
||||
break; |
||||
case 3: // ARROW TO RIGHT AND DOWN
|
||||
g.drawLine(x+8, y+12, x+8, y+21, LINE_SZ); |
||||
g.drawLine(x+7, y+18, x+34, y+18, LINE_SZ); |
||||
g.drawLine(x+34, y+17, x+34, y+21, LINE_SZ); |
||||
break; |
||||
case 4: // ARROW TO RIGHT+LEFT AND DOWN
|
||||
g.drawLine(x+8, y+12, x+8, y+21, LINE_SZ); |
||||
g.drawLine(x+7, y+18, x+34, y+18, LINE_SZ); |
||||
g.drawLine(x+34, y+17, x+34, y+21, LINE_SZ); |
||||
g.drawLine(x-17, y+18, x+8, y+18, LINE_SZ); |
||||
g.drawLine(x-17, y+17, x-17, y+21, LINE_SZ); |
||||
break; |
||||
case 6: |
||||
g.drawLine(x+8, y+12, x+8, y+18, LINE_SZ); |
||||
g.drawLine(x+7, y+18, x+58, y+18, LINE_SZ); |
||||
break; |
||||
case 7: // ARROW TO LEFT
|
||||
g.drawLine(x+8, y+12, x+8, y+19, LINE_SZ); |
||||
g.drawLine(x-17, y+18, x+9, y+18, LINE_SZ); |
||||
break; |
||||
} |
||||
|
||||
switch(fb) { |
||||
case 0: |
||||
break; |
||||
case 1: |
||||
g.drawLine(x+7, y, x+8, y-5, LINE_SZ); |
||||
g.drawLine(x+8, y-4, x+21, y-4, LINE_SZ); |
||||
g.drawLine(x+20, y-4, x+20, y+15, LINE_SZ); |
||||
g.drawLine(x+19, y+15, x+20, y+16, LINE_SZ); |
||||
g.drawLine(x+8, y+15, x+20, y+15, LINE_SZ); |
||||
break; |
||||
case 2: // ALGO 4
|
||||
g.drawLine(x+7, y, x+8, y-5, LINE_SZ); |
||||
g.drawLine(x+8, y-4, x+20, y-4, LINE_SZ); |
||||
g.drawLine(x+19, y-4, x+19, y+59, LINE_SZ); |
||||
g.drawLine(x+8, y+58, x+19, y+58, LINE_SZ); |
||||
break; |
||||
case 3: // ALGO 6
|
||||
g.drawLine(x+7, y, x+8, y-5, LINE_SZ); |
||||
g.drawLine(x+8, y-4, x+20, y-4, LINE_SZ); |
||||
g.drawLine(x+19, y-4, x+19, y+37, LINE_SZ); |
||||
g.drawLine(x+8, y+36, x+19, y+36, LINE_SZ); |
||||
break; |
||||
case 4: |
||||
g.drawLine(x+7, y, x+8, y-5, LINE_SZ); |
||||
g.drawLine(x+8, y-4, x-4, y-4, LINE_SZ); |
||||
g.drawLine(x-3, y-4, x-3, y+15, LINE_SZ); |
||||
g.drawLine(x-3, y+15, x+8, y+15, LINE_SZ); |
||||
g.drawLine(x+8, y+15, x+8, y+12, LINE_SZ); |
||||
break; |
||||
} |
||||
|
||||
} |
||||
|
||||
void AlgoDisplay::paint(Graphics &g) { |
||||
|
||||
g.setColour(DXLookNFeel::fillColour); |
||||
g.fillRect(1, 3, 20, 15); |
||||
String n = String(*algo +1); |
||||
|
||||
g.setColour(Colours::white); |
||||
g.drawText(n, 1, 3, 20, 15, Justification::centred, true); |
||||
|
||||
switch(*algo) { |
||||
case 0: |
||||
displayOp(g, 6, 3, 0, 0, 1); |
||||
displayOp(g, 5, 3, 1, 0, 0); |
||||
displayOp(g, 4, 3, 2, 0, 0); |
||||
displayOp(g, 3, 3, 3, 2, 0); |
||||
displayOp(g, 2, 2, 2, 0, 0); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 1: |
||||
displayOp(g, 6, 3, 0, 0, 0); |
||||
displayOp(g, 5, 3, 1, 0, 0); |
||||
displayOp(g, 4, 3, 2, 0, 0); |
||||
displayOp(g, 3, 3, 3, 2, 0); |
||||
displayOp(g, 2, 2, 2, 0, 1); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 2: |
||||
displayOp(g, 6, 3, 1, 0, 1); |
||||
displayOp(g, 5, 3, 2, 0, 0); |
||||
displayOp(g, 4, 3, 3, 2, 0); |
||||
displayOp(g, 3, 2, 1, 0, 0); |
||||
displayOp(g, 2, 2, 2, 0, 0); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 3: //
|
||||
displayOp(g, 6, 3, 1, 0, 2); |
||||
displayOp(g, 5, 3, 2, 0, 0); |
||||
displayOp(g, 4, 3, 3, 2, 0); |
||||
displayOp(g, 3, 2, 1, 0, 0); |
||||
displayOp(g, 2, 2, 2, 0, 0); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 4: |
||||
displayOp(g, 6, 4, 2, 0, 1); |
||||
displayOp(g, 5, 4, 3, 2, 0); |
||||
displayOp(g, 4, 3, 2, 0, 0); |
||||
displayOp(g, 3, 3, 3, 1, 0); |
||||
displayOp(g, 2, 2, 2, 0, 0); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 5: //
|
||||
displayOp(g, 6, 4, 2, 0, 3); |
||||
displayOp(g, 5, 4, 3, 2, 0); |
||||
displayOp(g, 4, 3, 2, 0, 0); |
||||
displayOp(g, 3, 3, 3, 1, 0); |
||||
displayOp(g, 2, 2, 2, 0, 0); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 6: |
||||
displayOp(g, 6, 4, 1, 0, 1); |
||||
displayOp(g, 5, 4, 2, 7, 0); |
||||
displayOp(g, 4, 3, 2, 0, 0); |
||||
displayOp(g, 3, 3, 3, 2, 0); |
||||
displayOp(g, 2, 2, 2, 0, 0); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 7: |
||||
displayOp(g, 6, 4, 1, 0, 0); |
||||
displayOp(g, 5, 4, 2, 7, 0); |
||||
displayOp(g, 4, 3, 2, 0, 4); |
||||
displayOp(g, 3, 3, 3, 2, 0); |
||||
displayOp(g, 2, 2, 2, 0, 0); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 8: |
||||
displayOp(g, 6, 4, 1, 0, 0); |
||||
displayOp(g, 5, 4, 2, 7, 0); |
||||
displayOp(g, 4, 3, 2, 0, 0); |
||||
displayOp(g, 3, 3, 3, 2, 0); |
||||
displayOp(g, 2, 2, 2, 0, 1); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 9: |
||||
displayOp(g, 6, 2, 2, 0, 0); |
||||
displayOp(g, 5, 1, 2, 1, 0); |
||||
displayOp(g, 4, 2, 3, 1, 0); |
||||
displayOp(g, 3, 3, 1, 0, 1); |
||||
displayOp(g, 2, 3, 2, 0, 0); |
||||
displayOp(g, 1, 3, 3, 2, 0); |
||||
break; |
||||
case 10: |
||||
displayOp(g, 6, 2, 2, 0, 1); |
||||
displayOp(g, 5, 1, 2, 1, 0); |
||||
displayOp(g, 4, 2, 3, 1, 0); |
||||
displayOp(g, 3, 3, 1, 0, 0); |
||||
displayOp(g, 2, 3, 2, 0, 0); |
||||
displayOp(g, 1, 3, 3, 2, 0); |
||||
break; |
||||
case 11: |
||||
displayOp(g, 6, 3, 2, 7, 0); |
||||
displayOp(g, 5, 2, 2, 0, 0); |
||||
displayOp(g, 4, 1, 2, 1, 0); |
||||
displayOp(g, 3, 2, 3, 6, 0); |
||||
displayOp(g, 2, 4, 2, 0, 1); |
||||
displayOp(g, 1, 4, 3, 2, 0); |
||||
break; |
||||
case 12: |
||||
displayOp(g, 6, 3, 2, 7, 1); |
||||
displayOp(g, 5, 2, 2, 0, 0); |
||||
displayOp(g, 4, 1, 2, 1, 0); |
||||
displayOp(g, 3, 2, 3, 6, 0); |
||||
displayOp(g, 2, 4, 2, 0, 0); |
||||
displayOp(g, 1, 4, 3, 2, 0); |
||||
break; |
||||
case 13: |
||||
displayOp(g, 6, 3, 1, 0, 1); |
||||
displayOp(g, 5, 2, 1, 1, 0); |
||||
displayOp(g, 4, 3, 2, 0, 0); |
||||
displayOp(g, 3, 3, 3, 2, 0); |
||||
displayOp(g, 2, 2, 2, 0, 0); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 14: |
||||
displayOp(g, 6, 3, 1, 0, 0); |
||||
displayOp(g, 5, 2, 1, 1, 0); |
||||
displayOp(g, 4, 3, 2, 0, 0); |
||||
displayOp(g, 3, 3, 3, 2, 0); |
||||
displayOp(g, 2, 2, 2, 0, 4); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 15: |
||||
displayOp(g, 6, 4, 1, 0, 1); |
||||
displayOp(g, 5, 4, 2, 7, 0); |
||||
displayOp(g, 4, 3, 1, 0, 0); |
||||
displayOp(g, 3, 3, 2, 0, 0); |
||||
displayOp(g, 2, 2, 2, 1, 0); |
||||
displayOp(g, 1, 3, 3, 0, 0); |
||||
break; |
||||
case 16: |
||||
displayOp(g, 6, 4, 1, 0, 0); |
||||
displayOp(g, 5, 4, 2, 7, 0); |
||||
displayOp(g, 4, 3, 1, 0, 0); |
||||
displayOp(g, 3, 3, 2, 0, 0); |
||||
displayOp(g, 2, 2, 2, 1, 4); |
||||
displayOp(g, 1, 3, 3, 0, 0); |
||||
break; |
||||
case 17: |
||||
displayOp(g, 6, 4, 0, 0, 0); |
||||
displayOp(g, 5, 4, 1, 0, 0); |
||||
displayOp(g, 4, 4, 2, 7, 0); |
||||
displayOp(g, 3, 3, 2, 0, 4); |
||||
displayOp(g, 2, 2, 2, 1, 0); |
||||
displayOp(g, 1, 3, 3, 0, 0); |
||||
break; |
||||
case 18: |
||||
displayOp(g, 6, 3, 2, 3, 1); |
||||
displayOp(g, 5, 4, 3, 2, 0); |
||||
displayOp(g, 4, 3, 3, 1, 0); |
||||
displayOp(g, 3, 2, 1, 0, 0); |
||||
displayOp(g, 2, 2, 2, 0, 0); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 19: |
||||
displayOp(g, 6, 4, 2, 0, 0); |
||||
displayOp(g, 5, 3, 2, 1, 0); |
||||
displayOp(g, 4, 4, 3, 2, 0); |
||||
displayOp(g, 3, 1, 2, 3, 1); |
||||
displayOp(g, 2, 2, 3, 6, 0); |
||||
displayOp(g, 1, 1, 3, 1, 0); |
||||
break; |
||||
case 20: |
||||
displayOp(g, 6, 3, 2, 3, 0); |
||||
displayOp(g, 5, 4, 3, 2, 0); |
||||
displayOp(g, 4, 3, 3, 1, 0); |
||||
displayOp(g, 3, 1, 2, 3, 1); |
||||
displayOp(g, 2, 2, 3, 1, 0); |
||||
displayOp(g, 1, 1, 3, 1, 0); |
||||
break; |
||||
case 21: |
||||
displayOp(g, 6, 3, 2, 4, 1); |
||||
displayOp(g, 5, 4, 3, 2, 0); |
||||
displayOp(g, 4, 3, 3, 1, 0); |
||||
displayOp(g, 3, 2, 3, 1, 0); |
||||
displayOp(g, 2, 1, 2, 0, 0); |
||||
displayOp(g, 1, 1, 3, 1, 0); |
||||
break; |
||||
case 22: // CC
|
||||
displayOp(g, 6, 3, 2, 3, 1); |
||||
displayOp(g, 5, 4, 3, 2, 0); |
||||
displayOp(g, 4, 3, 3, 1, 0); |
||||
displayOp(g, 3, 2, 2, 0, 0); |
||||
displayOp(g, 2, 2, 3, 1, 0); |
||||
displayOp(g, 1, 1, 3, 1, 0); |
||||
break; |
||||
case 23: // CC
|
||||
displayOp(g, 6, 3, 2, 4, 1); |
||||
displayOp(g, 5, 4, 3, 2, 0); |
||||
displayOp(g, 4, 3, 3, 1, 0); |
||||
displayOp(g, 3, 2, 3, 1, 0); |
||||
displayOp(g, 2, 1, 3, 1, 0); |
||||
displayOp(g, 1, 0, 3, 1, 0); |
||||
break; |
||||
case 24: // CC
|
||||
displayOp(g, 6, 3, 2, 3, 1); |
||||
displayOp(g, 5, 4, 3, 2, 0); |
||||
displayOp(g, 4, 3, 3, 1, 0); |
||||
displayOp(g, 3, 2, 3, 1, 0); |
||||
displayOp(g, 2, 1, 3, 1, 0); |
||||
displayOp(g, 1, 0, 3, 1, 0); |
||||
break; |
||||
case 25: |
||||
displayOp(g, 6, 4, 2, 0, 1); |
||||
displayOp(g, 5, 3, 2, 1, 0); |
||||
displayOp(g, 4, 4, 3, 2, 0); |
||||
displayOp(g, 3, 2, 2, 0, 0); |
||||
displayOp(g, 2, 2, 3, 6, 0); |
||||
displayOp(g, 1, 1, 3, 1, 0); |
||||
break; |
||||
case 26: |
||||
displayOp(g, 6, 4, 2, 0, 0); |
||||
displayOp(g, 5, 3, 2, 1, 0); |
||||
displayOp(g, 4, 4, 3, 2, 0); |
||||
displayOp(g, 3, 2, 2, 0, 1); |
||||
displayOp(g, 2, 2, 3, 6, 0); |
||||
displayOp(g, 1, 1, 3, 1, 0); |
||||
break; |
||||
case 27: |
||||
displayOp(g, 6, 4, 3, 2, 0); |
||||
displayOp(g, 5, 3, 1, 0, 1); |
||||
displayOp(g, 4, 3, 2, 0, 0); |
||||
displayOp(g, 3, 3, 3, 1, 0); |
||||
displayOp(g, 2, 2, 2, 0, 0); |
||||
displayOp(g, 1, 2, 3, 1, 0); |
||||
break; |
||||
case 28: |
||||
displayOp(g, 6, 4, 2, 0, 1); |
||||
displayOp(g, 5, 4, 3, 2, 0); |
||||
displayOp(g, 4, 3, 2, 0, 0); |
||||
displayOp(g, 3, 3, 3, 1, 0); |
||||
displayOp(g, 2, 2, 3, 1, 0); |
||||
displayOp(g, 1, 1, 3, 1, 0); |
||||
break; |
||||
case 29: |
||||
displayOp(g, 6, 4, 3, 2, 0); |
||||
displayOp(g, 5, 3, 1, 0, 1); |
||||
displayOp(g, 4, 3, 2, 0, 0); |
||||
displayOp(g, 3, 3, 3, 1, 0); |
||||
displayOp(g, 2, 2, 3, 1, 0); |
||||
displayOp(g, 1, 1, 3, 1, 0); |
||||
break; |
||||
case 30: |
||||
displayOp(g, 6, 4, 2, 0, 1); |
||||
displayOp(g, 5, 4, 3, 2, 0); |
||||
displayOp(g, 4, 3, 3, 1, 0); |
||||
displayOp(g, 3, 2, 3, 1, 0); |
||||
displayOp(g, 2, 1, 3, 1, 0); |
||||
displayOp(g, 1, 0, 3, 1, 0);
|
||||
break; |
||||
case 31: |
||||
displayOp(g, 6, 5, 3, 2, 1); |
||||
displayOp(g, 5, 4, 3, 1, 0); |
||||
displayOp(g, 4, 3, 3, 1, 0); |
||||
displayOp(g, 3, 2, 3, 1, 0); |
||||
displayOp(g, 2, 1, 3, 1, 0); |
||||
displayOp(g, 1, 0, 3, 1, 0);
|
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
} |
||||
|
@ -1,33 +0,0 @@ |
||||
/**
|
||||
* |
||||
* 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 3 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 |
||||
* |
||||
*/ |
||||
|
||||
#ifndef ALGODISPLAY_H_INCLUDED |
||||
#define ALGODISPLAY_H_INCLUDED |
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h" |
||||
|
||||
class AlgoDisplay : public Component { |
||||
public: |
||||
AlgoDisplay(); |
||||
char *algo; |
||||
void paint(Graphics &g); |
||||
}; |
||||
|
||||
#endif // ALGODISPLAY_H_INCLUDED
|
@ -1,359 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2015 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 3 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 "PluginProcessor.h" |
||||
#include "PluginEditor.h" |
||||
#include "CartManager.h" |
||||
#include "DXLookNFeel.h" |
||||
#include "PluginData.h" |
||||
|
||||
#include <fstream> |
||||
using namespace ::std; |
||||
|
||||
class SyxFileFilter : public FileFilter { |
||||
public: |
||||
SyxFileFilter() : FileFilter(".syx") {} |
||||
bool isFileSuitable(const File &file) const { |
||||
return file.getFileExtension().toLowerCase() == ".syx" && file.getSize() >= 4104; |
||||
} |
||||
bool isDirectorySuitable(const File &file) const { |
||||
return true; |
||||
}; |
||||
}; |
||||
|
||||
class FileTreeDrop : public FileTreeComponent { |
||||
public : |
||||
FileTreeDrop(DirectoryContentsList &listToShow) : FileTreeComponent(listToShow) {} |
||||
|
||||
bool isInterestedInFileDrag (const StringArray &files) override { |
||||
bool found = false; |
||||
|
||||
for(int i=0; i<files.size(); i++) { |
||||
String filename = files[i].toLowerCase(); |
||||
found |= filename.endsWith(".syx"); |
||||
} |
||||
return found; |
||||
} |
||||
|
||||
void filesDropped(const StringArray &files, int x, int y) override { |
||||
File targetDir = getSelectedFile(); |
||||
|
||||
if ( ! targetDir.exists() ) |
||||
targetDir = DexedAudioProcessor::dexedCartDir; |
||||
|
||||
if ( ! targetDir.isDirectory() ) |
||||
targetDir = targetDir.getParentDirectory(); |
||||
|
||||
for(int i=0; i<files.size(); i++) { |
||||
if ( files[i].toLowerCase().endsWith(".syx") ) { |
||||
File src(files[i]); |
||||
File target = targetDir.getChildFile(src.getFileName()); |
||||
src.copyFileTo(target); |
||||
} |
||||
} |
||||
fileList.refresh(); |
||||
} |
||||
}; |
||||
|
||||
CartManager::CartManager(DexedAudioProcessorEditor *editor) : Component("CartManager") { |
||||
mainWindow = editor; |
||||
cartDir = DexedAudioProcessor::dexedCartDir;
|
||||
|
||||
addAndMakeVisible(activeCart = new ProgramListBox("activepgm", 8)); |
||||
activeCart->setBounds(28, 441, 800, 96); |
||||
activeCart->addListener(this); |
||||
|
||||
addAndMakeVisible(browserCart = new ProgramListBox("browserpgm", 2)); |
||||
browserCart->setBounds(635, 18, 200, 384); |
||||
browserCart->addListener(this); |
||||
|
||||
// -------------------------
|
||||
syxFileFilter = new SyxFileFilter(); |
||||
timeSliceThread = new TimeSliceThread("Cartridge Directory Scanner"); |
||||
timeSliceThread->startThread(); |
||||
cartBrowserList = new DirectoryContentsList(syxFileFilter, *timeSliceThread); |
||||
cartBrowserList->setDirectory(cartDir, true, true); |
||||
cartBrowser = new FileTreeDrop(*cartBrowserList); |
||||
cartBrowser->addKeyListener(this); |
||||
addAndMakeVisible(cartBrowser); |
||||
|
||||
cartBrowser->setBounds(23, 18, 590, 384); |
||||
cartBrowser->setDragAndDropDescription("Sysex Browser"); |
||||
cartBrowser->addListener(this); |
||||
|
||||
addAndMakeVisible(closeButton = new TextButton("CLOSE")); |
||||
closeButton->setBounds(4, 545, 50, 30); |
||||
closeButton->addListener(this); |
||||
|
||||
addAndMakeVisible(loadButton = new TextButton("LOAD")); |
||||
loadButton->setBounds(52, 545, 50, 30); |
||||
loadButton->addListener(this); |
||||
|
||||
addAndMakeVisible(saveButton = new TextButton("SAVE")); |
||||
saveButton->setBounds(100, 545, 50, 30); |
||||
saveButton->addListener(this); |
||||
|
||||
addAndMakeVisible(fileMgrButton = new TextButton("SHOW DIR")); |
||||
fileMgrButton->setBounds(148, 545, 70, 30); |
||||
fileMgrButton->addListener(this); |
||||
/*
|
||||
* |
||||
* I've removed this since it only works on the DX7 II. TBC. |
||||
* |
||||
|
||||
addAndMakeVisible(getDXPgmButton = new TextButton("GET DX7 PGM")); |
||||
getDXPgmButton->setBounds(656, 545, 100, 30); |
||||
getDXPgmButton->addListener(this); |
||||
|
||||
addAndMakeVisible(getDXCartButton = new TextButton("GET DX7 CART")); |
||||
getDXCartButton->setBounds(755, 545, 100, 30); |
||||
getDXCartButton->addListener(this); |
||||
*/ |
||||
} |
||||
|
||||
CartManager::~CartManager() { |
||||
timeSliceThread->stopThread(500); |
||||
delete cartBrowser; |
||||
delete cartBrowserList; |
||||
delete timeSliceThread; |
||||
} |
||||
|
||||
void CartManager::paint(Graphics &g) { |
||||
g.fillAll(DXLookNFeel::lightBackground); |
||||
g.setColour(DXLookNFeel::roundBackground); |
||||
g.fillRoundedRectangle(8, 418, 843, 126, 15); |
||||
g.setColour(Colours::whitesmoke); |
||||
g.drawText("currently loaded cartridge", 38, 410, 150, 40, Justification::left); |
||||
} |
||||
|
||||
void CartManager::programSelected(ProgramListBox *source, int pos) { |
||||
if ( source == activeCart ) { |
||||
browserCart->setSelected(-1); |
||||
mainWindow->processor->setCurrentProgram(pos); |
||||
mainWindow->processor->updateHostDisplay(); |
||||
} else { |
||||
uint8_t unpackPgm[161]; |
||||
source->getCurrentCart().unpackProgram(unpackPgm, pos); |
||||
activeCart->setSelected(-1); |
||||
browserCart->setSelected(pos); |
||||
repaint(); |
||||
mainWindow->processor->updateProgramFromSysex((uint8_t *) unpackPgm); |
||||
mainWindow->processor->updateHostDisplay(); |
||||
} |
||||
} |
||||
|
||||
void CartManager::buttonClicked(juce::Button *buttonThatWasClicked) { |
||||
if ( buttonThatWasClicked == closeButton ) { |
||||
mainWindow->startTimer(100); |
||||
setVisible(false); |
||||
return; |
||||
} |
||||
|
||||
if ( buttonThatWasClicked == loadButton ) { |
||||
FileChooser fc ("Import original DX sysex...", File::nonexistent, "*.syx;*.SYX;*.*", 1); |
||||
|
||||
if ( fc.browseForFileToOpen()) |
||||
mainWindow->loadCart(fc.getResult()); |
||||
return; |
||||
} |
||||
|
||||
if ( buttonThatWasClicked == saveButton ) { |
||||
mainWindow->saveCart(); |
||||
} |
||||
|
||||
if ( buttonThatWasClicked == fileMgrButton ) { |
||||
cartDir.revealToUser(); |
||||
return; |
||||
} |
||||
|
||||
// THIS IS NOT USED
|
||||
if ( buttonThatWasClicked == getDXPgmButton ) { |
||||
if ( mainWindow->processor->sysexComm.isInputActive() && mainWindow->processor->sysexComm.isOutputActive() ) { |
||||
unsigned char msg[] = { 0xF0, 0x43, 0x20, 0x09, 0xF7 }; |
||||
mainWindow->processor->sysexComm.send(MidiMessage(msg, 5)); |
||||
} else { |
||||
showSysexConfigMsg(); |
||||
} |
||||
return; |
||||
} |
||||
|
||||
if ( buttonThatWasClicked == getDXCartButton ) { |
||||
if ( mainWindow->processor->sysexComm.isInputActive() && mainWindow->processor->sysexComm.isOutputActive() ) { |
||||
unsigned char msg[] = { 0xF0, 0x43, 0x20, 0x00, 0xF7 }; |
||||
mainWindow->processor->sysexComm.send(MidiMessage(msg, 5)); |
||||
} else { |
||||
showSysexConfigMsg(); |
||||
} |
||||
return; |
||||
} |
||||
} |
||||
|
||||
void CartManager::fileDoubleClicked(const File& file) { |
||||
if ( file.isDirectory() ) |
||||
return; |
||||
mainWindow->loadCart(file); |
||||
activeCart->setCartridge(mainWindow->processor->currentCart); |
||||
} |
||||
|
||||
void CartManager::fileClicked(const File& file, const MouseEvent& e) { |
||||
if ( e.mods.isRightButtonDown() ) { |
||||
PopupMenu menu; |
||||
|
||||
menu.addItem(1000, "Open location"); |
||||
if ( ! file.isDirectory() ) { |
||||
menu.addItem(1010, "Send sysex cartridge to DX7"); |
||||
} |
||||
menu.addSeparator(); |
||||
menu.addItem(1020, "Refresh"); |
||||
|
||||
switch(menu.show()) { |
||||
case 1000: |
||||
file.revealToUser(); |
||||
break; |
||||
case 1010 : |
||||
mainWindow->processor->sendSysexCartridge(file); |
||||
break; |
||||
case 1020: |
||||
cartBrowserList->refresh(); |
||||
break; |
||||
} |
||||
return; |
||||
} |
||||
} |
||||
|
||||
void CartManager::setActiveProgram(int idx, String activeName) { |
||||
if ( activeCart->programNames[idx] == activeName ) { |
||||
activeCart->setSelected(idx); |
||||
browserCart->setSelected(-1); |
||||
} |
||||
activeCart->repaint(); |
||||
} |
||||
|
||||
void CartManager::resetActiveSysex() { |
||||
activeCart->setCartridge(mainWindow->processor->currentCart); |
||||
} |
||||
|
||||
void CartManager::selectionChanged() { |
||||
File file = cartBrowser->getSelectedFile(); |
||||
|
||||
if ( ! file.exists() ) |
||||
return; |
||||
|
||||
if ( file.isDirectory() ) |
||||
return; |
||||
|
||||
Cartridge browserSysex; |
||||
int rc = browserSysex.load(file); |
||||
if ( rc < 0 ) { |
||||
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Error", "Unable to open file"); |
||||
return; |
||||
} |
||||
|
||||
if ( rc != 0 ) { |
||||
browserCart->readOnly = true; |
||||
} else { |
||||
browserCart->readOnly = false; |
||||
} |
||||
browserCart->setSelected(-1); |
||||
browserCart->setCartridge(browserSysex); |
||||
} |
||||
|
||||
void CartManager::programRightClicked(ProgramListBox *source, int pos) { |
||||
PopupMenu menu; |
||||
|
||||
menu.addItem(1000, "Send program '" + source->programNames[pos] + "' to DX7"); |
||||
|
||||
if ( source == activeCart ) |
||||
menu.addItem(1010, "Send current sysex cartridge to DX7"); |
||||
|
||||
switch(menu.show()) { |
||||
case 1000: |
||||
uint8_t unpackPgm[161]; |
||||
|
||||
if ( source == activeCart ) { |
||||
mainWindow->processor->currentCart.unpackProgram(unpackPgm, pos); |
||||
} else { |
||||
source->getCurrentCart().unpackProgram(unpackPgm, pos); |
||||
} |
||||
|
||||
if ( mainWindow->processor->sysexComm.isOutputActive() ) { |
||||
uint8_t msg[163]; |
||||
exportSysexPgm(msg, unpackPgm); |
||||
mainWindow->processor->sysexComm.send(MidiMessage(msg, 163)); |
||||
} |
||||
break; |
||||
|
||||
case 1010: |
||||
mainWindow->processor->sendCurrentSysexCartridge(); |
||||
break; |
||||
} |
||||
|
||||
} |
||||
|
||||
void CartManager::programDragged(ProgramListBox *destListBox, int dest, char *packedPgm) { |
||||
if ( destListBox == activeCart ) { |
||||
char *sysex = mainWindow->processor->currentCart.getRawVoice(); |
||||
memcpy(sysex+(dest*128), packedPgm, 128); |
||||
mainWindow->updateUI(); |
||||
} else { |
||||
File file = cartBrowser->getSelectedFile(); |
||||
|
||||
if ( ! file.exists() ) |
||||
return; |
||||
|
||||
if ( file.isDirectory() ) |
||||
return; |
||||
if ( file.getSize() != 4104 ) |
||||
return; |
||||
|
||||
Cartridge cart; |
||||
cart.load(file); |
||||
memcpy(cart.getRawVoice()+(dest*128), packedPgm, 128); |
||||
cart.saveVoice(file); |
||||
browserCart->setCartridge(cart); |
||||
} |
||||
} |
||||
|
||||
void CartManager::initialFocus() { |
||||
cartBrowser->grabKeyboardFocus(); |
||||
} |
||||
|
||||
bool CartManager::keyPressed(const KeyPress& key, Component* originatingComponent) { |
||||
if ( key.getKeyCode() == 13 ) { |
||||
File file = cartBrowser->getSelectedFile(); |
||||
if ( file.isDirectory() ) |
||||
return true; |
||||
mainWindow->loadCart(file); |
||||
activeCart->setCartridge(mainWindow->processor->currentCart); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
void CartManager::showSysexConfigMsg() { |
||||
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Warning", "The DX7 midi interface is not configured correctly.\n\n" |
||||
"These buttons are used to 'ask' the DX7 to send the current program/cartridge.\n\n"
|
||||
"In order to use this correctly, you need to connect your midi in and midi out of your DX7 to a midi interface and configure this midi interface with the [PARM] dialog. THIS ONLY WORKS ON A DX7-II"); |
||||
} |
||||
|
||||
// unused stuff from FileBrowserListener
|
||||
void CartManager::browserRootChanged (const File& newRoot) {} |
||||
|
||||
|
@ -1,77 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2015 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 3 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 |
||||
* |
||||
*/ |
||||
|
||||
#ifndef CARTMANAGER_H_INCLUDED |
||||
#define CARTMANAGER_H_INCLUDED |
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h" |
||||
#include "PluginData.h" |
||||
#include "ProgramListBox.h" |
||||
#include "PluginData.h" |
||||
|
||||
class CartManager : public Component, public ButtonListener, public DragAndDropContainer, public FileBrowserListener |
||||
, public ProgramListBoxListener, public KeyListener { |
||||
ScopedPointer<TextButton> newButton; |
||||
ScopedPointer<TextButton> loadButton; |
||||
ScopedPointer<TextButton> saveButton; |
||||
ScopedPointer<TextButton> closeButton; |
||||
ScopedPointer<TextButton> fileMgrButton; |
||||
ScopedPointer<TextButton> getDXPgmButton; |
||||
ScopedPointer<TextButton> getDXCartButton; |
||||
|
||||
ScopedPointer<ProgramListBox> activeCart; |
||||
ScopedPointer<ProgramListBox> browserCart; |
||||
|
||||
ScopedPointer<FileFilter> syxFileFilter; |
||||
|
||||
FileTreeComponent *cartBrowser; |
||||
TimeSliceThread *timeSliceThread; |
||||
DirectoryContentsList *cartBrowserList; |
||||
|
||||
File cartDir; |
||||
|
||||
DexedAudioProcessorEditor *mainWindow; |
||||
|
||||
void showSysexConfigMsg(); |
||||
|
||||
public: |
||||
CartManager(DexedAudioProcessorEditor *editor); |
||||
virtual ~CartManager(); |
||||
void paint(Graphics& g) override; |
||||
void buttonClicked (Button* buttonThatWasClicked) override; |
||||
|
||||
void selectionChanged() override; |
||||
void fileClicked (const File& file, const MouseEvent& e) override; |
||||
void fileDoubleClicked (const File& file) override; |
||||
void browserRootChanged (const File& newRoot) override; |
||||
|
||||
void setActiveProgram(int idx, String activeName); |
||||
void resetActiveSysex(); |
||||
|
||||
virtual void programSelected(ProgramListBox *source, int pos) override; |
||||
virtual void programRightClicked(ProgramListBox *source, int pos) override; |
||||
virtual void programDragged(ProgramListBox *destListBox, int dest, char *packedPgm) override; |
||||
virtual bool keyPressed(const KeyPress& key, Component* originatingComponent) override; |
||||
|
||||
void initialFocus(); |
||||
}; |
||||
|
||||
|
||||
#endif // CARTMANAGER_H_INCLUDED
|
@ -1,442 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2014 Pascal Gauthier. |
||||
* |
||||
* DX7 Envelope Tables from legasynth-0.4.1 / DX7 Patch Editor |
||||
* Copyright (C) 2002 Juan Linietsky <coding@reduz.com.ar> |
||||
* Copyright (C) 2006 Mark-André Hopf <mhopf@mark13.org> |
||||
* |
||||
* 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 3 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 "Dexed.h" |
||||
#include "DXComponents.h" |
||||
#include "DXLookNFeel.h" |
||||
#include "PluginProcessor.h" |
||||
#include "msfa/pitchenv.h" |
||||
|
||||
static char TMP_LEVEL_PTR[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
||||
|
||||
static float EG_rate_rise_duration[128] = { |
||||
38.00000 ,34.96000 ,31.92000 ,28.88000 ,25.84000 , |
||||
22.80000 ,20.64000 ,18.48000 ,16.32000 ,14.16000 , |
||||
12.00000 ,11.10000 ,10.20000 ,9.30000 ,8.40000 , |
||||
7.50000 ,6.96000 ,6.42000 ,5.88000 ,5.34000 , |
||||
4.80000 ,4.38000 ,3.96000 ,3.54000 ,3.12000 , |
||||
2.70000 ,2.52000 ,2.34000 ,2.16000 ,1.98000 , |
||||
1.80000 ,1.70000 ,1.60000 ,1.50000 ,1.40000 , |
||||
1.30000 ,1.22962 ,1.15925 ,1.08887 ,1.01850 , |
||||
0.94813 ,0.87775 ,0.80737 ,0.73700 ,0.69633 , |
||||
0.65567 ,0.61500 ,0.57833 ,0.54167 ,0.50500 , |
||||
0.47300 ,0.44100 ,0.40900 ,0.37967 ,0.35033 , |
||||
0.32100 ,0.28083 ,0.24067 ,0.20050 ,0.16033 , |
||||
0.12017 ,0.08000 ,0.07583 ,0.07167 ,0.06750 , |
||||
0.06333 ,0.05917 ,0.05500 ,0.04350 ,0.03200 , |
||||
0.02933 ,0.02667 ,0.02400 ,0.02200 ,0.02000 , |
||||
0.01800 ,0.01667 ,0.01533 ,0.01400 ,0.01300 , |
||||
0.01200 ,0.01100 ,0.01000 ,0.00900 ,0.00800 , |
||||
0.00800 ,0.00800 ,0.00800 ,0.00767 ,0.00733 , |
||||
0.00700 ,0.00633 ,0.00567 ,0.00500 ,0.00433 , |
||||
0.00367 ,0.00300 ,0.00300 ,0.00300 ,0.00300 , |
||||
0.00300 ,0.00300 ,0.00300 ,0.00300 ,0.00300 , |
||||
0.00300 ,0.00300 ,0.00300 ,0.00300 ,0.00300 , |
||||
0.00300 ,0.00300 ,0.00300 ,0.00300 ,0.00300 , |
||||
0.00300 ,0.00300 ,0.00300 ,0.00300 ,0.00300 , |
||||
0.00300 ,0.00300 ,0.00300 ,0.00300 ,0.00300 , |
||||
0.00300 ,0.00300 ,0.00300 |
||||
}; |
||||
|
||||
static float EG_rate_decay_duration[128] = { |
||||
318.00000 ,283.75000 ,249.50000 ,215.25000 ,181.00000 , |
||||
167.80000 ,154.60001 ,141.39999 ,128.20000 ,115.00000 , |
||||
104.60000 ,94.20000 ,83.80000 ,73.40000 ,63.00000 , |
||||
58.34000 ,53.68000 ,49.02000 ,44.36000 ,39.70000 , |
||||
35.76000 ,31.82000 ,27.88000 ,23.94000 ,20.00000 , |
||||
18.24000 ,16.48000 ,14.72000 ,12.96000 ,11.20000 , |
||||
10.36000 ,9.52000 ,8.68000 ,7.84000 ,7.00000 , |
||||
6.83250 ,6.66500 ,6.49750 ,6.33000 ,6.16250 , |
||||
5.99500 ,5.82750 ,5.66000 ,5.10000 ,4.54000 , |
||||
3.98000 ,3.64833 ,3.31667 ,2.98500 ,2.65333 , |
||||
2.32167 ,1.99000 ,1.77333 ,1.55667 ,1.34000 , |
||||
1.22333 ,1.10667 ,0.99000 ,0.89667 ,0.80333 , |
||||
0.71000 ,0.65000 ,0.59000 ,0.53000 ,0.47000 , |
||||
0.41000 ,0.32333 ,0.23667 ,0.15000 ,0.12700 , |
||||
0.10400 ,0.08100 ,0.07667 ,0.07233 ,0.06800 , |
||||
0.06100 ,0.05400 ,0.04700 ,0.04367 ,0.04033 , |
||||
0.03700 ,0.03300 ,0.02900 ,0.02500 ,0.02333 , |
||||
0.02167 ,0.02000 ,0.01767 ,0.01533 ,0.01300 , |
||||
0.01133 ,0.00967 ,0.00800 ,0.00800 ,0.00800 , |
||||
0.00800 ,0.00800 ,0.00800 ,0.00800 ,0.00800 , |
||||
0.00800 ,0.00800 ,0.00800 ,0.00800 ,0.00800 , |
||||
0.00800 ,0.00800 ,0.00800 ,0.00800 ,0.00800 , |
||||
0.00800 ,0.00800 ,0.00800 ,0.00800 ,0.00800 , |
||||
0.00800 ,0.00800 ,0.00800 ,0.00800 ,0.00800 , |
||||
0.00800 ,0.00800 ,0.00800 ,0.00800 ,0.00800 , |
||||
0.00800 ,0.00800 ,0.00800 |
||||
}; |
||||
|
||||
static float EG_rate_decay_percent[128] = { |
||||
0.00001 ,0.00001 ,0.00001 ,0.00001 ,0.00001 , |
||||
0.00001 ,0.00001 ,0.00001 ,0.00001 ,0.00001 , |
||||
0.00001 ,0.00001 ,0.00001 ,0.00001 ,0.00001 , |
||||
0.00001 ,0.00001 ,0.00001 ,0.00001 ,0.00001 , |
||||
0.00001 ,0.00001 ,0.00001 ,0.00001 ,0.00001 , |
||||
0.00001 ,0.00001 ,0.00001 ,0.00001 ,0.00001 , |
||||
0.00001 ,0.00001 ,0.00501 ,0.01001 ,0.01500 , |
||||
0.02000 ,0.02800 ,0.03600 ,0.04400 ,0.05200 , |
||||
0.06000 ,0.06800 ,0.07600 ,0.08400 ,0.09200 , |
||||
0.10000 ,0.10800 ,0.11600 ,0.12400 ,0.13200 , |
||||
0.14000 ,0.15000 ,0.16000 ,0.17000 ,0.18000 , |
||||
0.19000 ,0.20000 ,0.21000 ,0.22000 ,0.23000 , |
||||
0.24000 ,0.25100 ,0.26200 ,0.27300 ,0.28400 , |
||||
0.29500 ,0.30600 ,0.31700 ,0.32800 ,0.33900 , |
||||
0.35000 ,0.36500 ,0.38000 ,0.39500 ,0.41000 , |
||||
0.42500 ,0.44000 ,0.45500 ,0.47000 ,0.48500 , |
||||
0.50000 ,0.52000 ,0.54000 ,0.56000 ,0.58000 , |
||||
0.60000 ,0.62000 ,0.64000 ,0.66000 ,0.68000 , |
||||
0.70000 ,0.73200 ,0.76400 ,0.79600 ,0.82800 , |
||||
0.86000 ,0.89500 ,0.93000 ,0.96500 ,1.00000 , |
||||
1.00000 ,1.00000 ,1.00000 ,1.00000 ,1.00000 , |
||||
1.00000 ,1.00000 ,1.00000 ,1.00000 ,1.00000 , |
||||
1.00000 ,1.00000 ,1.00000 ,1.00000 ,1.00000 , |
||||
1.00000 ,1.00000 ,1.00000 ,1.00000 ,1.00000 , |
||||
1.00000 ,1.00000 ,1.00000 ,1.00000 ,1.00000 , |
||||
1.00000 ,1.00000 ,1.00000 |
||||
|
||||
}; |
||||
|
||||
static float EG_rate_rise_percent[128] = { |
||||
0.00001 ,0.00001 ,0.00001 ,0.00001 ,0.00001 , |
||||
0.00001 ,0.00001 ,0.00001 ,0.00001 ,0.00001 , |
||||
0.00001 ,0.00001 ,0.00001 ,0.00001 ,0.00001 , |
||||
0.00001 ,0.00001 ,0.00001 ,0.00001 ,0.00001 , |
||||
0.00001 ,0.00001 ,0.00001 ,0.00001 ,0.00001 , |
||||
0.00001 ,0.00001 ,0.00001 ,0.00001 ,0.00001 , |
||||
0.00001 ,0.00001 ,0.00501 ,0.01001 ,0.01500 , |
||||
0.02000 ,0.02800 ,0.03600 ,0.04400 ,0.05200 , |
||||
0.06000 ,0.06800 ,0.07600 ,0.08400 ,0.09200 , |
||||
0.10000 ,0.10800 ,0.11600 ,0.12400 ,0.13200 , |
||||
0.14000 ,0.15000 ,0.16000 ,0.17000 ,0.18000 , |
||||
0.19000 ,0.20000 ,0.21000 ,0.22000 ,0.23000 , |
||||
0.24000 ,0.25100 ,0.26200 ,0.27300 ,0.28400 , |
||||
0.29500 ,0.30600 ,0.31700 ,0.32800 ,0.33900 , |
||||
0.35000 ,0.36500 ,0.38000 ,0.39500 ,0.41000 , |
||||
0.42500 ,0.44000 ,0.45500 ,0.47000 ,0.48500 , |
||||
0.50000 ,0.52000 ,0.54000 ,0.56000 ,0.58000 , |
||||
0.60000 ,0.62000 ,0.64000 ,0.66000 ,0.68000 , |
||||
0.70000 ,0.73200 ,0.76400 ,0.79600 ,0.82800 , |
||||
0.86000 ,0.89500 ,0.93000 ,0.96500 ,1.00000 , |
||||
1.00000 ,1.00000 ,1.00000 ,1.00000 ,1.00000 , |
||||
1.00000 ,1.00000 ,1.00000 ,1.00000 ,1.00000 , |
||||
1.00000 ,1.00000 ,1.00000 ,1.00000 ,1.00000 , |
||||
1.00000 ,1.00000 ,1.00000 ,1.00000 ,1.00000 , |
||||
1.00000 ,1.00000 ,1.00000 ,1.00000 ,1.00000 , |
||||
1.00000 ,1.00000 ,1.00000 |
||||
}; |
||||
|
||||
static double getDuration(int p_rate, int p_level_l, int p_level_r) { |
||||
float *duration_table=(p_level_r>p_level_l) ? EG_rate_rise_duration : EG_rate_decay_duration; |
||||
double duration=duration_table[p_rate]; |
||||
|
||||
float* percent_table =(p_level_r>p_level_l) ? EG_rate_rise_percent : EG_rate_decay_percent; |
||||
duration *= fabs(percent_table[p_level_r]-percent_table[p_level_l]); |
||||
return duration; |
||||
} |
||||
|
||||
EnvDisplay::EnvDisplay() { |
||||
pvalues = (uint8_t *) &TMP_LEVEL_PTR; |
||||
} |
||||
|
||||
void EnvDisplay::paint(Graphics &g) { |
||||
int h = getHeight(); |
||||
uint8_t *rates = pvalues; |
||||
uint8_t *levels = pvalues + 4; |
||||
|
||||
double d[4]; |
||||
double keyoff = 0.0; |
||||
double release = 0.0; |
||||
d[0] = getDuration(rates[0], levels[3], levels[0]); |
||||
d[1] = getDuration(rates[1], levels[0], levels[1]); |
||||
d[2] = getDuration(rates[2], levels[1], levels[2]); |
||||
|
||||
double ko = 0.0; |
||||
for(int j=0; j<3; ++j) |
||||
ko += d[j]; |
||||
if (ko>keyoff) |
||||
keyoff=ko; |
||||
|
||||
d[3] = getDuration(rates[3], levels[2], levels[3]); |
||||
if ( d[3]>release ) { |
||||
release = d[3]; |
||||
} |
||||
keyoff += 10.0; |
||||
double w = getWidth() / (keyoff + release); |
||||
|
||||
g.setColour(Colour(0xF0000000)); |
||||
g.fillRoundedRectangle (keyoff*w, 0.0f, (float) getWidth(), (float) getHeight(), 1.0f); |
||||
g.setColour(Colours::white); |
||||
|
||||
int x, y; |
||||
|
||||
Path p; |
||||
p.startNewSubPath(0, 32); |
||||
|
||||
// 0
|
||||
x = 0; |
||||
y = h - h / 99.0 * levels[3]; |
||||
p.lineTo(x, y); |
||||
if ( vPos == 0 || vPos == 1 ) { |
||||
g.fillEllipse(x-2, y-2, 4, 4); |
||||
} |
||||
|
||||
// 1
|
||||
x = d[0]*w; |
||||
y = h - h / 99.0 * levels[0]; |
||||
p.lineTo( x, y ); |
||||
if ( vPos == 1 || vPos == 2 ) { |
||||
g.fillEllipse(x-2, y-2, 4, 4); |
||||
} |
||||
|
||||
// 2
|
||||
x = (d[0]+d[1])*w; |
||||
y = h - h / 99.0 * levels[1]; |
||||
p.lineTo( x, y ); |
||||
if ( vPos == 2 || vPos == 3 ) { |
||||
g.fillEllipse(x-2, y-2, 4, 4); |
||||
} |
||||
|
||||
// 3
|
||||
x = (d[0]+d[1]+d[2])*w; |
||||
y = h - h / 99.0 * levels[2]; |
||||
p.lineTo( x, y ); |
||||
if ( vPos == 3 || vPos == 4) { |
||||
g.fillEllipse(x-2, y-2, 4, 4); |
||||
} |
||||
|
||||
// 4
|
||||
x = keyoff*w; |
||||
y = h - h / 99.0 * levels[2]; |
||||
p.lineTo( x, y ); |
||||
if ( vPos == 4 ) { |
||||
g.fillEllipse(x-2, y-2, 4, 4); |
||||
} |
||||
|
||||
// 5
|
||||
p.lineTo( (d[0]+d[1]+d[2]+keyoff+d[3])*w, h - h / 99.0 * levels[3] ); |
||||
|
||||
p.lineTo(96,32); |
||||
p.lineTo(0, 32); |
||||
|
||||
g.setColour(DXLookNFeel::fillColour); |
||||
g.fillPath(p); |
||||
|
||||
g.setColour(Colour(0xFFFFFFFF)); |
||||
String len; |
||||
len << ((int) vPos); |
||||
g.drawText(len, 5, 1, 72, 14, Justification::left, true); |
||||
} |
||||
|
||||
PitchEnvDisplay::PitchEnvDisplay() { |
||||
pvalues = (uint8_t *) &TMP_LEVEL_PTR; |
||||
vPos = 0; |
||||
} |
||||
|
||||
void PitchEnvDisplay::paint(Graphics &g) { |
||||
g.setColour(Colours::white); |
||||
|
||||
uint8_t *levels = pvalues + 4; |
||||
uint8_t *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; |
||||
} |
||||
|
||||
float ratio = 96 / total; |
||||
|
||||
Path p; |
||||
p.startNewSubPath(0, 32); |
||||
|
||||
int x = 0; |
||||
int y = 25 - (pitchenv_tab[levels[3]] + 128) / 10; |
||||
p.lineTo(0,y); |
||||
|
||||
int dx = x; |
||||
int dy = y; |
||||
|
||||
int i; |
||||
for(i=0;i<4;i++) { |
||||
if ( vPos == i ) { |
||||
dx = x; |
||||
dy = y; |
||||
} |
||||
|
||||
x = dist[i] * ratio + x; |
||||
y = 25 - (pitchenv_tab[levels[i]] + 128) / 10; |
||||
p.lineTo(x, y); |
||||
} |
||||
|
||||
if ( vPos == i ) { |
||||
dx = x; |
||||
dy = y; |
||||
} |
||||
|
||||
p.lineTo(96,32); |
||||
p.lineTo(0, 32); |
||||
g.setColour(DXLookNFeel::fillColour); |
||||
g.fillPath(p); |
||||
|
||||
g.setColour(Colours::white); |
||||
g.fillEllipse(dx-2, dy-2, 4, 4); |
||||
} |
||||
|
||||
void VuMeter::paint(Graphics &g) { |
||||
Image myStrip = ImageCache::getFromMemory(BinaryData::Meter_140x8_png, BinaryData::Meter_140x8_pngSize); |
||||
|
||||
g.drawImage(myStrip, 0, 0, 140, 8, 0, 0, 140, 8); |
||||
|
||||
if ( v <= 0 ) |
||||
return; |
||||
|
||||
const int totalBlocks = 46; |
||||
int numBlocks = roundToInt(totalBlocks * v); |
||||
|
||||
if ( numBlocks > 46 ) |
||||
numBlocks = totalBlocks; |
||||
int brkpoint = numBlocks * 3 + 2; |
||||
|
||||
g.drawImage(myStrip, 0, 0, brkpoint, 8, 0, 8, brkpoint, 8); |
||||
} |
||||
|
||||
LcdDisplay::LcdDisplay() { |
||||
paramMsg = "DEXED " DEXED_VERSION; |
||||
} |
||||
|
||||
void LcdDisplay::setSystemMsg(String msg) { |
||||
paramMsg = msg; |
||||
} |
||||
|
||||
void LcdDisplay::paint(Graphics &g) { |
||||
g.setColour (Colours::white);
|
||||
g.drawText (paramMsg, |
||||
0, 0, 140, 14, |
||||
Justification::centred, true); |
||||
} |
||||
|
||||
void ComboBoxImage::paint(Graphics &g) { |
||||
int idx = getSelectedItemIndex(); |
||||
if ( itemPos[0] != -1 ) { |
||||
if ( idx < 4 ) |
||||
idx = itemPos[idx]; |
||||
} |
||||
|
||||
g.drawImage(items, 0, 0, items.getWidth(), itemHeight, 0, idx * itemHeight, items.getWidth(), itemHeight); |
||||
} |
||||
|
||||
ComboBoxImage::ComboBoxImage() { |
||||
itemPos[0] = -1; |
||||
} |
||||
|
||||
static void comboBoxPopupMenuFinishedCallback (int result, ComboBoxImage* combo) { |
||||
if (combo != nullptr) { |
||||
combo->hidePopup(); |
||||
|
||||
if (result != 0) |
||||
combo->setSelectedId (result); |
||||
} |
||||
} |
||||
|
||||
void ComboBoxImage::showPopup() { |
||||
popup.showMenuAsync (PopupMenu::Options().withTargetComponent (this) |
||||
.withItemThatMustBeVisible(getSelectedId()) |
||||
.withMinimumWidth(getWidth()) |
||||
.withMaximumNumColumns(1) |
||||
.withStandardItemHeight(itemHeight), |
||||
ModalCallbackFunction::forComponent(comboBoxPopupMenuFinishedCallback, this)); |
||||
} |
||||
|
||||
void ComboBoxImage::setImage(Image image) { |
||||
items = image; |
||||
|
||||
int numItems = getNumItems(); |
||||
itemHeight = image.getHeight() / numItems; |
||||
|
||||
for(int i=0;i<numItems;i++) { |
||||
Image tmp = image.getClippedImage(Rectangle<int>(0,itemHeight*i, image.getWidth(), itemHeight)); |
||||
popup.addItem(i+1, getItemText(i), true, false, tmp); |
||||
} |
||||
} |
||||
|
||||
void ComboBoxImage::setImage(Image image, int pos[]) { |
||||
items = image; |
||||
|
||||
int numItems = getNumItems(); |
||||
itemHeight = 26; |
||||
|
||||
for(int i=0;i<numItems;i++) { |
||||
Image tmp = image.getClippedImage(Rectangle<int>(0,itemHeight*pos[i], image.getWidth(), itemHeight)); |
||||
popup.addItem(i+1, getItemText(i), true, false, tmp); |
||||
} |
||||
|
||||
for(int i=0;i<4;i++) |
||||
itemPos[i] = pos[i]; |
||||
} |
||||
|
||||
void ProgramSelector::mouseDown(const MouseEvent &event) { |
||||
if ( event.x < getWidth() - 8) { |
||||
ComboBox::mouseDown(event); |
||||
return; |
||||
} |
||||
|
||||
int cur = getSelectedItemIndex(); |
||||
if ( event.y < getHeight() / 2 ) { |
||||
if ( cur == 0 ) |
||||
cur = 31; |
||||
else |
||||
cur--; |
||||
} else { |
||||
if ( cur == 31 ) |
||||
cur = 0; |
||||
else |
||||
cur++; |
||||
} |
||||
setSelectedItemIndex(cur); |
||||
} |
||||
|
||||
void ProgramSelector::paint(Graphics &g) { |
||||
int x = getWidth(); |
||||
int y = getHeight(); |
||||
|
||||
Path path; |
||||
path.addTriangle(x-8, y/2-1, x-4, 2, x, y/2-1); |
||||
path.addTriangle(x-8, y/2+1, x-4, y-2, x, y/2+1); |
||||
|
||||
g.setColour(Colours::white); |
||||
g.fillPath(path); |
||||
} |
@ -1,78 +0,0 @@ |
||||
/**
|
||||
* |
||||
* 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 3 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 |
||||
* |
||||
*/ |
||||
|
||||
#ifndef DXCOMPONENTS_H_INCLUDED |
||||
#define DXCOMPONENTS_H_INCLUDED |
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h" |
||||
#include <stdint.h> |
||||
|
||||
class EnvDisplay : public Component { |
||||
public: |
||||
EnvDisplay(); |
||||
uint8_t *pvalues; |
||||
char vPos;
|
||||
void paint(Graphics &g); |
||||
}; |
||||
|
||||
class PitchEnvDisplay : public Component { |
||||
char rvalues[8]; |
||||
public: |
||||
PitchEnvDisplay(); |
||||
uint8_t *pvalues; |
||||
char vPos; |
||||
void paint(Graphics &g); |
||||
}; |
||||
|
||||
class VuMeter: public Component { |
||||
void paint(Graphics &g); |
||||
public :
|
||||
float v; |
||||
}; |
||||
|
||||
class LcdDisplay : public Component { |
||||
public: |
||||
LcdDisplay(); |
||||
void setSystemMsg(String msg); |
||||
String paramMsg; |
||||
void paint(Graphics &g);
|
||||
}; |
||||
|
||||
class ComboBoxImage : public ComboBox { |
||||
Image items; |
||||
int itemHeight; |
||||
PopupMenu popup; |
||||
int itemPos[4]; |
||||
public: |
||||
ComboBoxImage(); |
||||
|
||||
virtual void paint(Graphics &g) override; |
||||
virtual void showPopup() override; |
||||
void setImage(Image image); |
||||
void setImage(Image image, int pos[]); |
||||
}; |
||||
|
||||
class ProgramSelector : public ComboBox { |
||||
public: |
||||
void mouseDown(const MouseEvent &event) override;
|
||||
virtual void paint(Graphics &g) override; |
||||
}; |
||||
|
||||
#endif // DXCOMPONENTS_H_INCLUDED
|
@ -1,255 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2013-2016 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 3 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 "DXLookNFeel.h" |
||||
#include "DXComponents.h" |
||||
#include "Dexed.h" |
||||
#include "PluginProcessor.h" |
||||
|
||||
#define REG_COLOUR(id, value) setColour(id, value); colourMap.set(#id, id) |
||||
|
||||
Image findImage(String path) { |
||||
Image img; |
||||
if ( path.length() <= 3 )
|
||||
return img; |
||||
File imgFile(path); |
||||
img = ImageCache::getFromFile(imgFile); |
||||
return img; |
||||
} |
||||
|
||||
DXLookNFeel::DXLookNFeel() { |
||||
Colour ctrlBackground; |
||||
|
||||
DexedAudioProcessor::dexedAppDir.setAsCurrentWorkingDirectory(); |
||||
ctrlBackground = Colour(20,18,18); |
||||
|
||||
REG_COLOUR(TextButton::buttonColourId,Colour(0xFF0FC00F)); |
||||
REG_COLOUR(TextButton::textColourOnId, Colours::white); |
||||
REG_COLOUR(TextButton::textColourOffId, Colours::white); |
||||
REG_COLOUR(Slider::rotarySliderOutlineColourId,Colour(0xFF0FC00F)); |
||||
REG_COLOUR(Slider::rotarySliderFillColourId,Colour(0xFFFFFFFF)); |
||||
REG_COLOUR(AlertWindow::backgroundColourId,lightBackground); |
||||
REG_COLOUR(AlertWindow::textColourId, Colours::white); |
||||
REG_COLOUR(TextEditor::backgroundColourId,ctrlBackground); |
||||
REG_COLOUR(TextEditor::textColourId, Colours::white); |
||||
REG_COLOUR(TextEditor::highlightColourId, fillColour); |
||||
REG_COLOUR(TextEditor::outlineColourId, Colours::transparentBlack); |
||||
REG_COLOUR(ComboBox::backgroundColourId, ctrlBackground); |
||||
REG_COLOUR(ComboBox::textColourId, Colours::white); |
||||
REG_COLOUR(ComboBox::buttonColourId, Colours::white); |
||||
REG_COLOUR(PopupMenu::backgroundColourId, background); |
||||
REG_COLOUR(PopupMenu::textColourId, Colours::white); |
||||
REG_COLOUR(PopupMenu::highlightedTextColourId, Colours::white); |
||||
REG_COLOUR(PopupMenu::highlightedBackgroundColourId, fillColour); |
||||
REG_COLOUR(TreeView::backgroundColourId, background); |
||||
REG_COLOUR(DirectoryContentsDisplayComponent::highlightColourId, fillColour); |
||||
REG_COLOUR(DirectoryContentsDisplayComponent::textColourId, Colours::white); |
||||
|
||||
imageKnob = ImageCache::getFromMemory(BinaryData::Knob_34x34_png, BinaryData::Knob_34x34_pngSize); |
||||
imageSwitch = ImageCache::getFromMemory(BinaryData::Switch_48x26_png, BinaryData::Switch_48x26_pngSize); |
||||
imageSwitchOperator = ImageCache::getFromMemory(BinaryData::Switch_32x32_png, BinaryData::Switch_32x32_pngSize); |
||||
imageButton = ImageCache::getFromMemory(BinaryData::ButtonUnlabeled_50x30_png, BinaryData::ButtonUnlabeled_50x30_pngSize); |
||||
imageSlider = ImageCache::getFromMemory(BinaryData::Slider_26x26_png, BinaryData::Slider_26x26_pngSize); |
||||
imageScaling = ImageCache::getFromMemory(BinaryData::Scaling_36_26_png, BinaryData::Scaling_36_26_pngSize);; |
||||
imageLight = ImageCache::getFromMemory(BinaryData::Light_14x14_png, BinaryData::Light_14x14_pngSize); |
||||
imageLFO = ImageCache::getFromMemory(BinaryData::LFO_36_26_png, BinaryData::LFO_36_26_pngSize); |
||||
imageOperator = ImageCache::getFromMemory(BinaryData::OperatorEditor_287x218_png, BinaryData::OperatorEditor_287x218_pngSize); |
||||
imageGlobal = ImageCache::getFromMemory (BinaryData::GlobalEditor_864x144_png, BinaryData::GlobalEditor_864x144_pngSize); |
||||
|
||||
defaultFont = Typeface::createSystemTypefaceFor(BinaryData::NotoSansRegular_ttf, BinaryData::NotoSansRegular_ttfSize); |
||||
defaultFontBold = Typeface::createSystemTypefaceFor(BinaryData::NotoSansBold_ttf, BinaryData::NotoSansBold_ttfSize); |
||||
|
||||
File dexedTheme = DexedAudioProcessor::dexedAppDir.getChildFile("DexedTheme.xml"); |
||||
|
||||
if ( ! dexedTheme.existsAsFile() ) |
||||
return; |
||||
|
||||
XmlElement *root = XmlDocument::parse(dexedTheme); |
||||
if ( root == NULL ) |
||||
return; |
||||
|
||||
forEachXmlChildElementWithTagName(*root, colour, "colour") { |
||||
String name = colour->getStringAttribute("id", ""); |
||||
if ( name == "" ) |
||||
continue; |
||||
String value = colour->getStringAttribute("value", ""); |
||||
if ( value == "" ) |
||||
continue; |
||||
if ( value.length() < 8 )
|
||||
continue; |
||||
int conv = strtol(value.toRawUTF8(), NULL, 16); |
||||
if ( colourMap.contains(name) ) { |
||||
setColour(colourMap[name], Colour(conv)); |
||||
} else { |
||||
if ( name == "Dexed::backgroundId" ) { |
||||
background = Colour(conv); |
||||
continue; |
||||
} |
||||
if ( name == "Dexed::fillColourId" ) { |
||||
fillColour = Colour(conv); |
||||
continue; |
||||
} |
||||
} |
||||
} |
||||
|
||||
forEachXmlChildElementWithTagName(*root, image, "image") { |
||||
String name = image->getStringAttribute("id", ""); |
||||
String path = image->getStringAttribute("path", ""); |
||||
if ( name == "Knob_34x34.png" ) { |
||||
imageKnob = findImage(path); |
||||
continue; |
||||
} |
||||
if ( name == "Switch_48x26.png" ) { |
||||
imageSwitch = findImage(path); |
||||
continue; |
||||
} |
||||
if ( name == "Switch_32x64.png" ) { |
||||
imageSwitchOperator = findImage(path); |
||||
continue; |
||||
} |
||||
if ( name == "ButtonUnlabeled_50x30.png" ) { |
||||
imageButton = findImage(path); |
||||
continue; |
||||
} |
||||
if ( name == "Slider_26x26.png" ) { |
||||
imageSlider = findImage(path); |
||||
continue; |
||||
} |
||||
if ( name == "Scaling_36_26.png" ) { |
||||
imageScaling = findImage(path); |
||||
continue; |
||||
} |
||||
if ( name == "Light_14x14.png" ) { |
||||
imageLight = findImage(path); |
||||
continue; |
||||
} |
||||
if ( name == "LFO_36_26.png" ) { |
||||
imageLFO = findImage(path); |
||||
continue; |
||||
} |
||||
if ( name == "OperatorEditor_287x218.png" ) { |
||||
imageOperator = findImage(path); |
||||
continue; |
||||
} |
||||
if ( name == "GlobalEditor_864x144.png" ) { |
||||
imageGlobal = findImage(path); |
||||
continue; |
||||
} |
||||
} |
||||
|
||||
delete root; |
||||
} |
||||
|
||||
Typeface::Ptr DXLookNFeel::getTypefaceForFont(const Font &) { |
||||
return defaultFont; |
||||
} |
||||
|
||||
void DXLookNFeel::drawRotarySlider( Graphics &g, int x, int y, int width, int height, float sliderPosProportional, |
||||
float rotaryStartAngle, float rotaryEndAngle, Slider &slider ) { |
||||
if ( imageKnob.isNull() ) { |
||||
LookAndFeel_V3::drawRotarySlider(g, x, y, width, height, sliderPosProportional, rotaryStartAngle, rotaryEndAngle, slider); |
||||
return; |
||||
} |
||||
|
||||
const double fractRotation = (slider.getValue() - slider.getMinimum()) / (slider.getMaximum() - slider.getMinimum()); //value between 0 and 1 for current amount of rotation
|
||||
const int nFrames = imageKnob.getHeight()/imageKnob.getWidth(); // number of frames for vertical film strip
|
||||
const int frameIdx = (int)ceil(fractRotation * ((double)nFrames-1.0) ); // current index from 0 --> nFrames-1
|
||||
|
||||
const float radius = jmin (width / 2.0f, height / 2.0f) ; |
||||
const float centreX = x + width * 0.5f; |
||||
const float centreY = y + height * 0.5f; |
||||
const float rx = centreX - radius - 1.0f; |
||||
const float ry = centreY - radius - 1.0f; |
||||
|
||||
g.drawImage(imageKnob, (int)rx, (int)ry, 2*(int)radius, 2*(int)radius, 0, frameIdx*imageKnob.getWidth(), imageKnob.getWidth(), imageKnob.getWidth()); |
||||
}; |
||||
|
||||
void DXLookNFeel::drawToggleButton(Graphics& g, ToggleButton& button, bool isMouseOverButton, bool isButtonDown) { |
||||
if ( imageSwitch.isNull() ) { |
||||
LookAndFeel_V3::drawToggleButton(g, button, isMouseOverButton, isButtonDown); |
||||
return; |
||||
} |
||||
|
||||
g.drawImage(imageSwitch, 0, 0, 48, 26, 0, button.getToggleState() ? 0 : 26, 48, 26); |
||||
} |
||||
|
||||
void DXLookNFeel::drawButtonBackground(Graphics &g, Button &button, const Colour& backgroundColour, bool isMouseOverButton, bool isButtonDown) { |
||||
if ( imageButton.isNull() ) { |
||||
LookAndFeel_V3::drawButtonBackground(g, button, backgroundColour, isMouseOverButton, isButtonDown); |
||||
return; |
||||
} |
||||
|
||||
int w = button.getWidth(); |
||||
|
||||
// dx, dy, dw, dl, sx, sy, sw, sl
|
||||
g.drawImage(imageButton, 0, 0, 3, 30, 0, isButtonDown ? 30 : 0, 3, 30); |
||||
g.drawImage(imageButton, 3, 0, w-6, 30, 3, isButtonDown ? 30 : 0, 44, 30); |
||||
g.drawImage(imageButton, w-3, 0, 3, 30, 47, isButtonDown ? 30 : 0, 47, 30); |
||||
} |
||||
|
||||
void DXLookNFeel::drawLinearSliderBackground (Graphics&, int x, int y, int width, int height, |
||||
float sliderPos, float minSliderPos, float maxSliderPos, |
||||
const Slider::SliderStyle st, Slider& s) { |
||||
// NOP
|
||||
} |
||||
|
||||
void DXLookNFeel::drawLinearSliderThumb (Graphics& g, int x, int y, int width, int height, |
||||
float sliderPos, float minSliderPos, float maxSliderPos, |
||||
const Slider::SliderStyle st, Slider& s) { |
||||
if ( imageSlider.isNull() ) { |
||||
LookAndFeel_V3::drawLinearSliderThumb(g, x, y, width, height, sliderPos, minSliderPos, maxSliderPos, st, s); |
||||
return; |
||||
} |
||||
|
||||
int p = sliderPos - minSliderPos; |
||||
p -= 6; |
||||
g.drawImage(imageSlider, p, 0, 26, 26, 0, 0, 26, 26); |
||||
} |
||||
|
||||
Font DXLookNFeel::getTextButtonFont(TextButton& button, int buttonHeight) { |
||||
return Font(defaultFontBold); |
||||
} |
||||
|
||||
void DXLookNFeel::positionComboBoxText(ComboBox& box, Label& label) { |
||||
ComboBox *src = &box; |
||||
|
||||
// I'm not proud of this one, but really... it must be another way to do this....
|
||||
ComboBoxImage* img = dynamic_cast<ComboBoxImage*>(src); |
||||
if( img != 0 ) { |
||||
return; |
||||
} |
||||
|
||||
LookAndFeel_V3::positionComboBoxText(box, label); |
||||
} |
||||
|
||||
CriticalSection DXLookNFeel::lock; |
||||
DXLookNFeel * DXLookNFeel::ins = NULL; |
||||
Colour DXLookNFeel::fillColour = Colour(77,159,151); |
||||
Colour DXLookNFeel::lightBackground = Colour(78,72,63); |
||||
Colour DXLookNFeel::background = Colour(60,50,47); |
||||
Colour DXLookNFeel::roundBackground = Colour(58,52,48); |
||||
|
||||
DXLookNFeel *DXLookNFeel::getLookAndFeel() { |
||||
const ScopedLock locker(lock); |
||||
if ( ins != NULL ) |
||||
return ins; |
||||
ins = new DXLookNFeel(); |
||||
return ins; |
||||
} |
@ -1,63 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2013-2016 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 3 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 |
||||
* |
||||
*/ |
||||
|
||||
#ifndef DXLOOKNFEEL_H_INCLUDED |
||||
#define DXLOOKNFEEL_H_INCLUDED |
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h" |
||||
|
||||
class DXLookNFeel : public LookAndFeel_V3 { |
||||
static CriticalSection lock; |
||||
static DXLookNFeel *ins; |
||||
DXLookNFeel(); |
||||
|
||||
HashMap<String, int> colourMap; |
||||
|
||||
public: |
||||
Typeface::Ptr defaultFont; |
||||
Typeface::Ptr defaultFontBold; |
||||
|
||||
Image imageKnob, imageSwitch, imageButton, imageSlider, imageScaling, imageLight, imageLFO; |
||||
Image imageSwitchOperator; |
||||
Image imageOperator, imageGlobal; |
||||
|
||||
/* overriden methods */ |
||||
virtual void drawRotarySlider(Graphics &g, int x, int y, int width, int height, float sliderPosProportional, float rotaryStartAngle, float rotaryEndAngle, Slider &slider ) override; |
||||
virtual void drawToggleButton(Graphics& g, ToggleButton& button, bool isMouseOverButton, bool isButtonDown) override; |
||||
virtual void drawLinearSliderBackground (Graphics&, int x, int y, int width, int height, |
||||
float sliderPos, float minSliderPos, float maxSliderPos, |
||||
const Slider::SliderStyle, Slider&) override; |
||||
virtual void drawLinearSliderThumb (Graphics&, int x, int y, int width, int height, |
||||
float sliderPos, float minSliderPos, float maxSliderPos, |
||||
const Slider::SliderStyle, Slider&) override; |
||||
virtual void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour, |
||||
bool isMouseOverButton, bool isButtonDown) override; |
||||
virtual Font getTextButtonFont(TextButton&, int buttonHeight) override; |
||||
virtual Typeface::Ptr getTypefaceForFont(const Font &) override; |
||||
virtual void positionComboBoxText (ComboBox& box, Label& label) override; |
||||
|
||||
static DXLookNFeel *getLookAndFeel(); |
||||
static Colour fillColour; |
||||
static Colour lightBackground; |
||||
static Colour background; |
||||
static Colour roundBackground; |
||||
}; |
||||
|
||||
#endif // DXLOOKNFEEL_H_INCLUDED
|
@ -1,788 +0,0 @@ |
||||
/*
|
||||
============================================================================== |
||||
|
||||
This is an automatically generated GUI class created by the Introjucer! |
||||
|
||||
Be careful when adding custom code to these files, as only the code within |
||||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded |
||||
and re-saved. |
||||
|
||||
Created with Introjucer version: 3.2.0 |
||||
|
||||
------------------------------------------------------------------------------ |
||||
|
||||
The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions" |
||||
Copyright (c) 2015 - ROLI Ltd. |
||||
|
||||
============================================================================== |
||||
*/ |
||||
|
||||
//[Headers] You can add your own extra header files here...
|
||||
#include "PluginEditor.h" |
||||
#include "DXLookNFeel.h" |
||||
//[/Headers]
|
||||
|
||||
#include "GlobalEditor.h" |
||||
|
||||
|
||||
//[MiscUserDefs] You can add your own user definitions and misc code here...
|
||||
|
||||
/**
|
||||
* Ugly but usefull midi monitor to know if you are really sending/receiving something from the DX7 |
||||
* If the midi is not configured this component wont show up |
||||
*/ |
||||
class MidiMonitor : public Component { |
||||
SysexComm *midi; |
||||
Image light; |
||||
|
||||
public: |
||||
MidiMonitor(SysexComm *sysexComm) { |
||||
midi = sysexComm; |
||||
light = DXLookNFeel::getLookAndFeel()->imageLight; |
||||
} |
||||
|
||||
void paint(Graphics &g) { |
||||
if ( ! (midi->isInputActive() || midi->isOutputActive() ) ) |
||||
return; |
||||
g.setColour(Colours::white); |
||||
|
||||
if ( midi->isInputActive() ) { |
||||
g.drawSingleLineText("DX7 IN", 17,14); |
||||
g.drawImage(light, 0, 3, 14, 14, 0, midi->inActivity ? 14 : 0, 14, 14); |
||||
midi->inActivity = false; |
||||
} |
||||
|
||||
if ( midi->isOutputActive() ) { |
||||
g.drawSingleLineText("DX7 OUT", 17, 28); |
||||
g.drawImage(light, 0, 17, 14, 14, 0, midi->outActivity ? 14 : 0, 14, 14); |
||||
midi->outActivity = false; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
class AboutBox : public DialogWindow { |
||||
public: |
||||
Image about_png; |
||||
|
||||
AboutBox(Component *parent) : DialogWindow("About", Colour(0xFF000000), true) { |
||||
setUsingNativeTitleBar(false); |
||||
setAlwaysOnTop(true); |
||||
about_png = ImageCache::getFromMemory(BinaryData::about_png, BinaryData::about_pngSize); |
||||
setSize(about_png.getWidth(), about_png.getHeight()); |
||||
centreAroundComponent (parent, getWidth(), getHeight()); |
||||
} |
||||
|
||||
void closeButtonPressed() { |
||||
setVisible (false); |
||||
} |
||||
|
||||
void paint(Graphics &g) { |
||||
g.drawImage (about_png, 0, 0, about_png.getWidth(), about_png.getHeight(), |
||||
0, 0, about_png.getWidth(), about_png.getHeight()); |
||||
g.setColour(Colour(0xFF000000)); |
||||
String ver("Version " DEXED_VERSION " ; build date " __DATE__ ); |
||||
g.drawSingleLineText(ver, 18, 130); |
||||
} |
||||
}; |
||||
//[/MiscUserDefs]
|
||||
|
||||
//==============================================================================
|
||||
GlobalEditor::GlobalEditor () |
||||
{ |
||||
//[Constructor_pre] You can add your own custom stuff here..
|
||||
//[/Constructor_pre]
|
||||
|
||||
addAndMakeVisible (lfoSpeed = new Slider ("lfoSpeed")); |
||||
lfoSpeed->setRange (0, 99, 1); |
||||
lfoSpeed->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
lfoSpeed->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
lfoSpeed->addListener (this); |
||||
|
||||
addAndMakeVisible (lfoAmDepth = new Slider ("lfoAmDepth")); |
||||
lfoAmDepth->setRange (0, 99, 1); |
||||
lfoAmDepth->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
lfoAmDepth->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
lfoAmDepth->addListener (this); |
||||
|
||||
addAndMakeVisible (lfoPitchDepth = new Slider ("lfoPitchDepth")); |
||||
lfoPitchDepth->setRange (0, 99, 1); |
||||
lfoPitchDepth->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
lfoPitchDepth->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
lfoPitchDepth->addListener (this); |
||||
|
||||
addAndMakeVisible (lfoDelay = new Slider ("lfoDelay")); |
||||
lfoDelay->setRange (0, 99, 1); |
||||
lfoDelay->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
lfoDelay->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
lfoDelay->addListener (this); |
||||
|
||||
addAndMakeVisible (cutoff = new Slider ("cutoff")); |
||||
cutoff->setRange (0, 1, 0); |
||||
cutoff->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
cutoff->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); |
||||
cutoff->addListener (this); |
||||
|
||||
addAndMakeVisible (reso = new Slider ("reso")); |
||||
reso->setRange (0, 1, 0); |
||||
reso->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
reso->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); |
||||
reso->addListener (this); |
||||
|
||||
addAndMakeVisible (pitchRate2 = new Slider ("pitchRate2")); |
||||
pitchRate2->setRange (0, 99, 1); |
||||
pitchRate2->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
pitchRate2->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
pitchRate2->addListener (this); |
||||
|
||||
addAndMakeVisible (pitchRate3 = new Slider ("pitchRate3")); |
||||
pitchRate3->setRange (0, 99, 1); |
||||
pitchRate3->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
pitchRate3->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
pitchRate3->addListener (this); |
||||
|
||||
addAndMakeVisible (pitchRate4 = new Slider ("pitchRate4")); |
||||
pitchRate4->setRange (0, 99, 1); |
||||
pitchRate4->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
pitchRate4->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
pitchRate4->addListener (this); |
||||
|
||||
addAndMakeVisible (pitchRate1 = new Slider ("pitchRate1")); |
||||
pitchRate1->setRange (0, 99, 1); |
||||
pitchRate1->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
pitchRate1->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
pitchRate1->addListener (this); |
||||
|
||||
addAndMakeVisible (pitchLevel2 = new Slider ("pitchLevel2")); |
||||
pitchLevel2->setRange (0, 99, 1); |
||||
pitchLevel2->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
pitchLevel2->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
pitchLevel2->addListener (this); |
||||
|
||||
addAndMakeVisible (pitchLevel3 = new Slider ("pitchLevel3")); |
||||
pitchLevel3->setRange (0, 99, 1); |
||||
pitchLevel3->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
pitchLevel3->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
pitchLevel3->addListener (this); |
||||
|
||||
addAndMakeVisible (pitchLevel4 = new Slider ("pitchLevel4")); |
||||
pitchLevel4->setRange (0, 99, 1); |
||||
pitchLevel4->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
pitchLevel4->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
pitchLevel4->addListener (this); |
||||
|
||||
addAndMakeVisible (pitchLevel1 = new Slider ("pitchLevel1")); |
||||
pitchLevel1->setRange (0, 99, 1); |
||||
pitchLevel1->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
pitchLevel1->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
pitchLevel1->addListener (this); |
||||
|
||||
addAndMakeVisible (transpose = new Slider ("transpose")); |
||||
transpose->setRange (0, 48, 1); |
||||
transpose->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
transpose->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); |
||||
transpose->addListener (this); |
||||
|
||||
addAndMakeVisible (oscSync = new ToggleButton ("oscSync")); |
||||
oscSync->setButtonText (String::empty); |
||||
oscSync->addListener (this); |
||||
|
||||
addAndMakeVisible (pitchModSens = new Slider ("pitchModSens")); |
||||
pitchModSens->setRange (0, 7, 1); |
||||
pitchModSens->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
pitchModSens->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
pitchModSens->addListener (this); |
||||
|
||||
addAndMakeVisible (lfoSync = new ToggleButton ("lfoSync")); |
||||
lfoSync->setButtonText (String::empty); |
||||
lfoSync->addListener (this); |
||||
|
||||
addAndMakeVisible (pitchEnvDisplay = new PitchEnvDisplay()); |
||||
pitchEnvDisplay->setName ("pitchEnvDisplay"); |
||||
|
||||
addAndMakeVisible (algoDisplay = new AlgoDisplay()); |
||||
algoDisplay->setName ("algoDisplay"); |
||||
|
||||
addAndMakeVisible (feedback = new Slider ("feedback")); |
||||
feedback->setRange (0, 7, 1); |
||||
feedback->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
feedback->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
feedback->addListener (this); |
||||
|
||||
addAndMakeVisible (algo = new Slider ("algo")); |
||||
algo->setRange (1, 32, 1); |
||||
algo->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
algo->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); |
||||
algo->addListener (this); |
||||
|
||||
addAndMakeVisible (lcdDisplay = new LcdDisplay()); |
||||
lcdDisplay->setName ("lcdDisplay"); |
||||
|
||||
addAndMakeVisible (output = new Slider ("output")); |
||||
output->setRange (0, 1, 0); |
||||
output->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
output->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); |
||||
output->addListener (this); |
||||
|
||||
addAndMakeVisible (vuOutput = new VuMeter()); |
||||
vuOutput->setName ("vuOutput"); |
||||
|
||||
addAndMakeVisible (initButton = new TextButton ("initButton")); |
||||
initButton->setButtonText (TRANS("INIT")); |
||||
initButton->addListener (this); |
||||
|
||||
addAndMakeVisible (parmButton = new TextButton ("parmButton")); |
||||
parmButton->setButtonText (TRANS("PARM")); |
||||
parmButton->addListener (this); |
||||
|
||||
addAndMakeVisible (cartButton = new TextButton ("cartButton")); |
||||
cartButton->setButtonText (TRANS("CART")); |
||||
cartButton->addListener (this); |
||||
|
||||
addAndMakeVisible (storeButton = new TextButton ("storeButton")); |
||||
storeButton->setButtonText (TRANS("STORE")); |
||||
storeButton->addListener (this); |
||||
|
||||
addAndMakeVisible (monoMode = new ToggleButton ("monoMode")); |
||||
monoMode->setButtonText (String::empty); |
||||
monoMode->addListener (this); |
||||
|
||||
addAndMakeVisible (lfoType = new ComboBoxImage()); |
||||
lfoType->setName ("lfoType"); |
||||
|
||||
addAndMakeVisible (programSelector = new ProgramSelector()); |
||||
programSelector->setName ("programSelector"); |
||||
|
||||
addAndMakeVisible (aboutButton = new ImageButton ("aboutButton")); |
||||
aboutButton->setButtonText (String::empty); |
||||
aboutButton->addListener (this); |
||||
|
||||
aboutButton->setImages (false, true, false, |
||||
Image(), 1.000f, Colour (0x00000000), |
||||
Image(), 1.000f, Colour (0x00000000), |
||||
Image(), 1.000f, Colour (0x00000000)); |
||||
addAndMakeVisible (tune = new Slider ("tune")); |
||||
tune->setRange (0, 1, 0); |
||||
tune->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
tune->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); |
||||
tune->addListener (this); |
||||
|
||||
|
||||
//[UserPreSize]
|
||||
//[/UserPreSize]
|
||||
|
||||
setSize (864, 144); |
||||
|
||||
|
||||
//[Constructor] You can add your own custom stuff here..
|
||||
lfoType->addItem("TRIANGLE", 1); |
||||
lfoType->addItem("SAW DOWN", 2); |
||||
lfoType->addItem("SAW UP", 3); |
||||
lfoType->addItem("SQUARE", 4); |
||||
lfoType->addItem("SINE", 5); |
||||
lfoType->addItem("S&HOLD", 6); |
||||
lfoType->setImage(DXLookNFeel::getLookAndFeel()->imageLFO); |
||||
|
||||
programs = programSelector; |
||||
|
||||
background = DXLookNFeel::getLookAndFeel()->imageGlobal; |
||||
imageLight = DXLookNFeel::getLookAndFeel()->imageLight; |
||||
//[/Constructor]
|
||||
} |
||||
|
||||
GlobalEditor::~GlobalEditor() |
||||
{ |
||||
//[Destructor_pre]. You can add your own custom destruction code here..
|
||||
//[/Destructor_pre]
|
||||
|
||||
lfoSpeed = nullptr; |
||||
lfoAmDepth = nullptr; |
||||
lfoPitchDepth = nullptr; |
||||
lfoDelay = nullptr; |
||||
cutoff = nullptr; |
||||
reso = nullptr; |
||||
pitchRate2 = nullptr; |
||||
pitchRate3 = nullptr; |
||||
pitchRate4 = nullptr; |
||||
pitchRate1 = nullptr; |
||||
pitchLevel2 = nullptr; |
||||
pitchLevel3 = nullptr; |
||||
pitchLevel4 = nullptr; |
||||
pitchLevel1 = nullptr; |
||||
transpose = nullptr; |
||||
oscSync = nullptr; |
||||
pitchModSens = nullptr; |
||||
lfoSync = nullptr; |
||||
pitchEnvDisplay = nullptr; |
||||
algoDisplay = nullptr; |
||||
feedback = nullptr; |
||||
algo = nullptr; |
||||
lcdDisplay = nullptr; |
||||
output = nullptr; |
||||
vuOutput = nullptr; |
||||
initButton = nullptr; |
||||
parmButton = nullptr; |
||||
cartButton = nullptr; |
||||
storeButton = nullptr; |
||||
monoMode = nullptr; |
||||
lfoType = nullptr; |
||||
programSelector = nullptr; |
||||
aboutButton = nullptr; |
||||
tune = nullptr; |
||||
|
||||
|
||||
//[Destructor]. You can add your own custom destruction code here..
|
||||
//[/Destructor]
|
||||
} |
||||
|
||||
//==============================================================================
|
||||
void GlobalEditor::paint (Graphics& g) |
||||
{ |
||||
//[UserPrePaint] Add your own custom painting code here..
|
||||
g.drawImage(background, 0, 0, 864, 144, 0, 0, 864, 144); |
||||
//[/UserPrePaint]
|
||||
|
||||
//[UserPaint] Add your own custom painting code here..
|
||||
g.drawImage(imageLight, 300, 70, 14, 14, 0, monoMode->getToggleState() ? 14 : 0, 14, 14); |
||||
g.drawImage(imageLight, 619, 102, 14, 14, 0, lfoSync->getToggleState() ? 14 : 0, 14, 14); |
||||
g.drawImage(imageLight, 705, 102, 14, 14, 0, oscSync->getToggleState() ? 14 : 0, 14, 14); |
||||
//[/UserPaint]
|
||||
} |
||||
|
||||
void GlobalEditor::resized() |
||||
{ |
||||
//[UserPreResize] Add your own custom resize code here..
|
||||
//[/UserPreResize]
|
||||
|
||||
lfoSpeed->setBounds (564, 50, 34, 34); |
||||
lfoAmDepth->setBounds (686, 50, 34, 34); |
||||
lfoPitchDepth->setBounds (646, 50, 34, 34); |
||||
lfoDelay->setBounds (603, 50, 34, 34); |
||||
cutoff->setBounds (234, 9, 34, 34); |
||||
reso->setBounds (278, 9, 34, 34); |
||||
pitchRate2->setBounds (767, 96, 34, 34); |
||||
pitchRate3->setBounds (795, 96, 35, 34); |
||||
pitchRate4->setBounds (823, 96, 34, 34); |
||||
pitchRate1->setBounds (739, 96, 34, 34); |
||||
pitchLevel2->setBounds (767, 57, 34, 34); |
||||
pitchLevel3->setBounds (795, 56, 34, 34); |
||||
pitchLevel4->setBounds (823, 56, 34, 34); |
||||
pitchLevel1->setBounds (739, 57, 34, 34); |
||||
transpose->setBounds (202, 60, 34, 34); |
||||
oscSync->setBounds (650, 96, 48, 26); |
||||
pitchModSens->setBounds (666, 5, 34, 34); |
||||
lfoSync->setBounds (565, 96, 48, 26); |
||||
pitchEnvDisplay->setBounds (751, 10, 93, 30); |
||||
algoDisplay->setBounds (335, 30, 152, 91); |
||||
feedback->setBounds (501, 81, 34, 34); |
||||
algo->setBounds (501, 22, 34, 34); |
||||
lcdDisplay->setBounds (6, 87, 140, 13); |
||||
output->setBounds (157, 60, 34, 34); |
||||
vuOutput->setBounds (6, 103, 140, 8); |
||||
initButton->setBounds (100, 111, 50, 30); |
||||
parmButton->setBounds (52, 111, 50, 30); |
||||
cartButton->setBounds (3, 111, 50, 30); |
||||
storeButton->setBounds (270, 109, 50, 30); |
||||
monoMode->setBounds (249, 65, 48, 26); |
||||
lfoType->setBounds (583, 8, 36, 26); |
||||
programSelector->setBounds (153, 115, 112, 18); |
||||
aboutButton->setBounds (8, 11, 135, 46); |
||||
tune->setBounds (190, 9, 34, 34); |
||||
//[UserResized] Add your own custom resize handling here..
|
||||
//[/UserResized]
|
||||
} |
||||
|
||||
void GlobalEditor::sliderValueChanged (Slider* sliderThatWasMoved) |
||||
{ |
||||
//[UsersliderValueChanged_Pre]
|
||||
//[/UsersliderValueChanged_Pre]
|
||||
|
||||
if (sliderThatWasMoved == lfoSpeed) |
||||
{ |
||||
//[UserSliderCode_lfoSpeed] -- add your slider handling code here..
|
||||
//[/UserSliderCode_lfoSpeed]
|
||||
} |
||||
else if (sliderThatWasMoved == lfoAmDepth) |
||||
{ |
||||
//[UserSliderCode_lfoAmDepth] -- add your slider handling code here..
|
||||
//[/UserSliderCode_lfoAmDepth]
|
||||
} |
||||
else if (sliderThatWasMoved == lfoPitchDepth) |
||||
{ |
||||
//[UserSliderCode_lfoPitchDepth] -- add your slider handling code here..
|
||||
//[/UserSliderCode_lfoPitchDepth]
|
||||
} |
||||
else if (sliderThatWasMoved == lfoDelay) |
||||
{ |
||||
//[UserSliderCode_lfoDelay] -- add your slider handling code here..
|
||||
//[/UserSliderCode_lfoDelay]
|
||||
} |
||||
else if (sliderThatWasMoved == cutoff) |
||||
{ |
||||
//[UserSliderCode_cutoff] -- add your slider handling code here..
|
||||
//[/UserSliderCode_cutoff]
|
||||
} |
||||
else if (sliderThatWasMoved == reso) |
||||
{ |
||||
//[UserSliderCode_reso] -- add your slider handling code here..
|
||||
//[/UserSliderCode_reso]
|
||||
} |
||||
else if (sliderThatWasMoved == pitchRate2) |
||||
{ |
||||
//[UserSliderCode_pitchRate2] -- add your slider handling code here..
|
||||
pitchEnvDisplay->repaint(); |
||||
//[/UserSliderCode_pitchRate2]
|
||||
} |
||||
else if (sliderThatWasMoved == pitchRate3) |
||||
{ |
||||
//[UserSliderCode_pitchRate3] -- add your slider handling code here..
|
||||
pitchEnvDisplay->repaint(); |
||||
//[/UserSliderCode_pitchRate3]
|
||||
} |
||||
else if (sliderThatWasMoved == pitchRate4) |
||||
{ |
||||
//[UserSliderCode_pitchRate4] -- add your slider handling code here..
|
||||
pitchEnvDisplay->repaint(); |
||||
//[/UserSliderCode_pitchRate4]
|
||||
} |
||||
else if (sliderThatWasMoved == pitchRate1) |
||||
{ |
||||
//[UserSliderCode_pitchRate1] -- add your slider handling code here..
|
||||
pitchEnvDisplay->repaint(); |
||||
//[/UserSliderCode_pitchRate1]
|
||||
} |
||||
else if (sliderThatWasMoved == pitchLevel2) |
||||
{ |
||||
//[UserSliderCode_pitchLevel2] -- add your slider handling code here..
|
||||
pitchEnvDisplay->repaint(); |
||||
//[/UserSliderCode_pitchLevel2]
|
||||
} |
||||
else if (sliderThatWasMoved == pitchLevel3) |
||||
{ |
||||
//[UserSliderCode_pitchLevel3] -- add your slider handling code here..
|
||||
pitchEnvDisplay->repaint(); |
||||
//[/UserSliderCode_pitchLevel3]
|
||||
} |
||||
else if (sliderThatWasMoved == pitchLevel4) |
||||
{ |
||||
//[UserSliderCode_pitchLevel4] -- add your slider handling code here..
|
||||
pitchEnvDisplay->repaint(); |
||||
//[/UserSliderCode_pitchLevel4]
|
||||
} |
||||
else if (sliderThatWasMoved == pitchLevel1) |
||||
{ |
||||
//[UserSliderCode_pitchLevel1] -- add your slider handling code here..
|
||||
pitchEnvDisplay->repaint(); |
||||
//[/UserSliderCode_pitchLevel1]
|
||||
} |
||||
else if (sliderThatWasMoved == transpose) |
||||
{ |
||||
//[UserSliderCode_transpose] -- add your slider handling code here..
|
||||
//[/UserSliderCode_transpose]
|
||||
} |
||||
else if (sliderThatWasMoved == pitchModSens) |
||||
{ |
||||
//[UserSliderCode_pitchModSens] -- add your slider handling code here..
|
||||
//[/UserSliderCode_pitchModSens]
|
||||
} |
||||
else if (sliderThatWasMoved == feedback) |
||||
{ |
||||
//[UserSliderCode_feedback] -- add your slider handling code here..
|
||||
//[/UserSliderCode_feedback]
|
||||
} |
||||
else if (sliderThatWasMoved == algo) |
||||
{ |
||||
//[UserSliderCode_algo] -- add your slider handling code here..
|
||||
//[/UserSliderCode_algo]
|
||||
} |
||||
else if (sliderThatWasMoved == output) |
||||
{ |
||||
//[UserSliderCode_output] -- add your slider handling code here..
|
||||
//[/UserSliderCode_output]
|
||||
} |
||||
else if (sliderThatWasMoved == tune) |
||||
{ |
||||
//[UserSliderCode_tune] -- add your slider handling code here..
|
||||
//[/UserSliderCode_tune]
|
||||
} |
||||
|
||||
//[UsersliderValueChanged_Post]
|
||||
//[/UsersliderValueChanged_Post]
|
||||
} |
||||
|
||||
void GlobalEditor::buttonClicked (Button* buttonThatWasClicked) |
||||
{ |
||||
//[UserbuttonClicked_Pre]
|
||||
//[/UserbuttonClicked_Pre]
|
||||
|
||||
if (buttonThatWasClicked == oscSync) |
||||
{ |
||||
//[UserButtonCode_oscSync] -- add your button handler code here..
|
||||
repaint(); |
||||
//[/UserButtonCode_oscSync]
|
||||
} |
||||
else if (buttonThatWasClicked == lfoSync) |
||||
{ |
||||
//[UserButtonCode_lfoSync] -- add your button handler code here..
|
||||
repaint(); |
||||
//[/UserButtonCode_lfoSync]
|
||||
} |
||||
else if (buttonThatWasClicked == initButton) |
||||
{ |
||||
//[UserButtonCode_initButton] -- add your button handler code here..
|
||||
editor->initProgram(); |
||||
//[/UserButtonCode_initButton]
|
||||
} |
||||
else if (buttonThatWasClicked == parmButton) |
||||
{ |
||||
//[UserButtonCode_parmButton] -- add your button handler code here..
|
||||
editor->parmShow(); |
||||
//[/UserButtonCode_parmButton]
|
||||
} |
||||
else if (buttonThatWasClicked == cartButton) |
||||
{ |
||||
//[UserButtonCode_cartButton] -- add your button handler code here..
|
||||
editor->cartShow(); |
||||
//[/UserButtonCode_cartButton]
|
||||
} |
||||
else if (buttonThatWasClicked == storeButton) |
||||
{ |
||||
//[UserButtonCode_storeButton] -- add your button handler code here..
|
||||
editor->storeProgram(); |
||||
//[/UserButtonCode_storeButton]
|
||||
} |
||||
else if (buttonThatWasClicked == monoMode) |
||||
{ |
||||
//[UserButtonCode_monoMode] -- add your button handler code here..
|
||||
editor->processor->setMonoMode(monoMode->getToggleState()); |
||||
repaint(); |
||||
//[/UserButtonCode_monoMode]
|
||||
} |
||||
else if (buttonThatWasClicked == aboutButton) |
||||
{ |
||||
//[UserButtonCode_aboutButton] -- add your button handler code here..
|
||||
AboutBox about(this->getParentComponent()); |
||||
about.runModalLoop(); |
||||
//[/UserButtonCode_aboutButton]
|
||||
} |
||||
|
||||
//[UserbuttonClicked_Post]
|
||||
//[/UserbuttonClicked_Post]
|
||||
} |
||||
|
||||
|
||||
|
||||
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
|
||||
|
||||
void GlobalEditor::bind(DexedAudioProcessorEditor *edit) { |
||||
processor = edit->processor; |
||||
processor->algo->bind(algo); |
||||
processor->lfoRate->bind(lfoSpeed); |
||||
processor->lfoDelay->bind(lfoDelay); |
||||
processor->lfoWaveform->bind(lfoType); |
||||
processor->lfoAmpDepth->bind(lfoAmDepth); |
||||
processor->lfoPitchDepth->bind(lfoPitchDepth); |
||||
processor->lfoSync->bind(lfoSync); |
||||
processor->oscSync->bind(oscSync); |
||||
processor->transpose->bind(transpose); |
||||
processor->feedback->bind(feedback); |
||||
processor->pitchModSens->bind(pitchModSens); |
||||
processor->pitchEgLevel[0]->bind(pitchLevel1); |
||||
processor->pitchEgLevel[1]->bind(pitchLevel2); |
||||
processor->pitchEgLevel[2]->bind(pitchLevel3); |
||||
processor->pitchEgLevel[3]->bind(pitchLevel4); |
||||
processor->pitchEgRate[0]->bind(pitchRate1); |
||||
processor->pitchEgRate[1]->bind(pitchRate2); |
||||
processor->pitchEgRate[2]->bind(pitchRate3); |
||||
processor->pitchEgRate[3]->bind(pitchRate4); |
||||
processor->fxCutoff->bind(cutoff); |
||||
processor->fxReso->bind(reso); |
||||
processor->output->bind(output); |
||||
processor->tune->bind(tune); |
||||
algoDisplay->algo = (char *) &(processor->data[134]); |
||||
pitchEnvDisplay->pvalues = &(processor->data[126]); |
||||
|
||||
editor = edit; |
||||
|
||||
midiMonitor = new MidiMonitor(&(processor->sysexComm)); |
||||
//addAndMakeVisible(midiMonitor);
|
||||
//midiMonitor->setBounds(155, 21, 80, 45);
|
||||
|
||||
repaint(); |
||||
} |
||||
|
||||
void GlobalEditor::setSystemMessage(String msg) { |
||||
lcdDisplay->setSystemMsg(msg); |
||||
} |
||||
|
||||
void GlobalEditor::setParamMessage(String msg) { |
||||
lcdDisplay->paramMsg = msg; |
||||
} |
||||
|
||||
void GlobalEditor::updateDisplay() { |
||||
repaint(); |
||||
} |
||||
|
||||
void GlobalEditor::updatePitchPos(int pos) { |
||||
pitchEnvDisplay->vPos = pos; |
||||
pitchEnvDisplay->repaint(); |
||||
} |
||||
|
||||
void GlobalEditor::updateVu(float f) { |
||||
vuOutput->v = f; |
||||
vuOutput->repaint(); |
||||
midiMonitor->repaint(); |
||||
} |
||||
|
||||
void GlobalEditor::setMonoState(bool state) { |
||||
monoMode->setToggleState(state ? Button::buttonDown : Button::buttonNormal, dontSendNotification); |
||||
} |
||||
//[/MiscUserCode]
|
||||
|
||||
|
||||
//==============================================================================
|
||||
#if 0 |
||||
/* -- Introjucer information section --
|
||||
|
||||
This is where the Introjucer stores the metadata that describe this GUI layout, so |
||||
make changes in here at your peril! |
||||
|
||||
BEGIN_JUCER_METADATA |
||||
|
||||
<JUCER_COMPONENT documentType="Component" className="GlobalEditor" componentName="" |
||||
parentClasses="public Component" constructorParams="" variableInitialisers="" |
||||
snapPixels="8" snapActive="0" snapShown="1" overlayOpacity="0.330" |
||||
fixedSize="1" initialWidth="864" initialHeight="144"> |
||||
<BACKGROUND backgroundColour="ffffff"/> |
||||
<SLIDER name="lfoSpeed" id="b10eaf327ab3bff5" memberName="lfoSpeed" virtualName="" |
||||
explicitFocusOrder="0" pos="564 50 34 34" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="lfoAmDepth" id="3e95a6206fa4a891" memberName="lfoAmDepth" |
||||
virtualName="" explicitFocusOrder="0" pos="686 50 34 34" min="0" |
||||
max="99" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="lfoPitchDepth" id="6ead769ca786c813" memberName="lfoPitchDepth" |
||||
virtualName="" explicitFocusOrder="0" pos="646 50 34 34" min="0" |
||||
max="99" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="lfoDelay" id="1fce68dc81619ef5" memberName="lfoDelay" virtualName="" |
||||
explicitFocusOrder="0" pos="603 50 34 34" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="cutoff" id="40531f16bb0bd225" memberName="cutoff" virtualName="" |
||||
explicitFocusOrder="0" pos="234 9 34 34" min="0" max="1" int="0" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="0" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="reso" id="c8c13464e81a8d83" memberName="reso" virtualName="" |
||||
explicitFocusOrder="0" pos="278 9 34 34" min="0" max="1" int="0" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="0" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="pitchRate2" id="73f386b3c91d3de4" memberName="pitchRate2" |
||||
virtualName="" explicitFocusOrder="0" pos="767 96 34 34" min="0" |
||||
max="99" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="pitchRate3" id="187c25b24413fccf" memberName="pitchRate3" |
||||
virtualName="" explicitFocusOrder="0" pos="795 96 35 34" min="0" |
||||
max="99" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="pitchRate4" id="1aeb2a8fbbcbeaab" memberName="pitchRate4" |
||||
virtualName="" explicitFocusOrder="0" pos="823 96 34 34" min="0" |
||||
max="99" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="pitchRate1" id="419d613b3fb9604e" memberName="pitchRate1" |
||||
virtualName="" explicitFocusOrder="0" pos="739 96 34 34" min="0" |
||||
max="99" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="pitchLevel2" id="3a355ad2221887d9" memberName="pitchLevel2" |
||||
virtualName="" explicitFocusOrder="0" pos="767 57 34 34" min="0" |
||||
max="99" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="pitchLevel3" id="5c5d782e8a7f3ad7" memberName="pitchLevel3" |
||||
virtualName="" explicitFocusOrder="0" pos="795 56 34 34" min="0" |
||||
max="99" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="pitchLevel4" id="eb900b141fbad8ff" memberName="pitchLevel4" |
||||
virtualName="" explicitFocusOrder="0" pos="823 56 34 34" min="0" |
||||
max="99" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="pitchLevel1" id="344cbe26ec9fa128" memberName="pitchLevel1" |
||||
virtualName="" explicitFocusOrder="0" pos="739 57 34 34" min="0" |
||||
max="99" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="transpose" id="7d1266b1c1534947" memberName="transpose" |
||||
virtualName="" explicitFocusOrder="0" pos="202 60 34 34" min="0" |
||||
max="48" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="0" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<TOGGLEBUTTON name="oscSync" id="8f3fe641537cd00" memberName="oscSync" virtualName="" |
||||
explicitFocusOrder="0" pos="650 96 48 26" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<SLIDER name="pitchModSens" id="904f73df85a9f886" memberName="pitchModSens" |
||||
virtualName="" explicitFocusOrder="0" pos="666 5 34 34" min="0" |
||||
max="7" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<TOGGLEBUTTON name="lfoSync" id="ff92bb0a5a4f7187" memberName="lfoSync" virtualName="" |
||||
explicitFocusOrder="0" pos="565 96 48 26" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<GENERICCOMPONENT name="pitchEnvDisplay" id="9ddaae8ef924a038" memberName="pitchEnvDisplay" |
||||
virtualName="" explicitFocusOrder="0" pos="751 10 93 30" class="PitchEnvDisplay" |
||||
params=""/> |
||||
<GENERICCOMPONENT name="algoDisplay" id="b26fb9e3b5f0bc37" memberName="algoDisplay" |
||||
virtualName="" explicitFocusOrder="0" pos="335 30 152 91" class="AlgoDisplay" |
||||
params=""/> |
||||
<SLIDER name="feedback" id="4fac1940c29ab8c" memberName="feedback" virtualName="" |
||||
explicitFocusOrder="0" pos="501 81 34 34" min="0" max="7" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="algo" id="8a226ddf9bbff752" memberName="algo" virtualName="" |
||||
explicitFocusOrder="0" pos="501 22 34 34" min="1" max="32" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="0" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<GENERICCOMPONENT name="lcdDisplay" id="30c7bb8f114cbbe3" memberName="lcdDisplay" |
||||
virtualName="" explicitFocusOrder="0" pos="6 87 140 13" class="LcdDisplay" |
||||
params=""/> |
||||
<SLIDER name="output" id="7697fdd54fd1593e" memberName="output" virtualName="" |
||||
explicitFocusOrder="0" pos="157 60 34 34" min="0" max="1" int="0" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="0" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<GENERICCOMPONENT name="vuOutput" id="dac75af912267f51" memberName="vuOutput" virtualName="" |
||||
explicitFocusOrder="0" pos="6 103 140 8" class="VuMeter" params=""/> |
||||
<TEXTBUTTON name="initButton" id="92b278163c42e21d" memberName="initButton" |
||||
virtualName="" explicitFocusOrder="0" pos="100 111 50 30" buttonText="INIT" |
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/> |
||||
<TEXTBUTTON name="parmButton" id="d5cd6260b34be817" memberName="parmButton" |
||||
virtualName="" explicitFocusOrder="0" pos="52 111 50 30" buttonText="PARM" |
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/> |
||||
<TEXTBUTTON name="cartButton" id="465a101c3a0e744" memberName="cartButton" |
||||
virtualName="" explicitFocusOrder="0" pos="3 111 50 30" buttonText="CART" |
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/> |
||||
<TEXTBUTTON name="storeButton" id="a94bec26832eb58b" memberName="storeButton" |
||||
virtualName="" explicitFocusOrder="0" pos="270 109 50 30" buttonText="STORE" |
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/> |
||||
<TOGGLEBUTTON name="monoMode" id="e683d8cbe286367b" memberName="monoMode" virtualName="" |
||||
explicitFocusOrder="0" pos="249 65 48 26" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<GENERICCOMPONENT name="lfoType" id="62f61dda9f76c8f" memberName="lfoType" virtualName="" |
||||
explicitFocusOrder="0" pos="583 8 36 26" class="ComboBoxImage" |
||||
params=""/> |
||||
<GENERICCOMPONENT name="programSelector" id="990bbcccae72dbe6" memberName="programSelector" |
||||
virtualName="" explicitFocusOrder="0" pos="153 115 112 18" class="ProgramSelector" |
||||
params=""/> |
||||
<IMAGEBUTTON name="aboutButton" id="d195a60b29440aa1" memberName="aboutButton" |
||||
virtualName="" explicitFocusOrder="0" pos="8 11 135 46" buttonText="" |
||||
connectedEdges="0" needsCallback="1" radioGroupId="0" keepProportions="0" |
||||
resourceNormal="" opacityNormal="1" colourNormal="0" resourceOver="" |
||||
opacityOver="1" colourOver="0" resourceDown="" opacityDown="1" |
||||
colourDown="0"/> |
||||
<SLIDER name="tune" id="d22c34aa3363a28a" memberName="tune" virtualName="" |
||||
explicitFocusOrder="0" pos="190 9 34 34" min="0" max="1" int="0" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="0" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
</JUCER_COMPONENT> |
||||
|
||||
END_JUCER_METADATA |
||||
*/ |
||||
#endif |
||||
|
||||
|
||||
//[EndFile] You can add extra defines here...
|
||||
//[/EndFile]
|
@ -1,126 +0,0 @@ |
||||
/*
|
||||
============================================================================== |
||||
|
||||
This is an automatically generated GUI class created by the Introjucer! |
||||
|
||||
Be careful when adding custom code to these files, as only the code within |
||||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded |
||||
and re-saved. |
||||
|
||||
Created with Introjucer version: 3.2.0 |
||||
|
||||
------------------------------------------------------------------------------ |
||||
|
||||
The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions" |
||||
Copyright (c) 2015 - ROLI Ltd. |
||||
|
||||
============================================================================== |
||||
*/ |
||||
|
||||
#ifndef __JUCE_HEADER_10638A2B49B704D0__ |
||||
#define __JUCE_HEADER_10638A2B49B704D0__ |
||||
|
||||
//[Headers] -- You can add your own extra header files here --
|
||||
#include "JuceHeader.h" |
||||
#include "PluginProcessor.h" |
||||
#include "DXComponents.h" |
||||
#include "AlgoDisplay.h" |
||||
|
||||
class DexedAudioProcessorEditor; |
||||
//[/Headers]
|
||||
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
//[Comments]
|
||||
An auto-generated component, created by the Introjucer. |
||||
|
||||
Describe your class and how it works here! |
||||
//[/Comments]
|
||||
*/ |
||||
class GlobalEditor : public Component, |
||||
public SliderListener, |
||||
public ButtonListener |
||||
{ |
||||
public: |
||||
//==============================================================================
|
||||
GlobalEditor (); |
||||
~GlobalEditor(); |
||||
|
||||
//==============================================================================
|
||||
//[UserMethods] -- You can add your own custom methods in this section.
|
||||
void bind(DexedAudioProcessorEditor *processor); |
||||
void setSystemMessage(String msg); |
||||
void setParamMessage(String msg); |
||||
void updatePitchPos(int pos); |
||||
void updateVu(float v); |
||||
void updateDisplay(); |
||||
void repaintMsg(); |
||||
|
||||
void setMonoState(bool state); |
||||
ProgramSelector *programs; |
||||
ScopedPointer<Component> midiMonitor; |
||||
//[/UserMethods]
|
||||
|
||||
void paint (Graphics& g); |
||||
void resized(); |
||||
void sliderValueChanged (Slider* sliderThatWasMoved); |
||||
void buttonClicked (Button* buttonThatWasClicked); |
||||
|
||||
|
||||
|
||||
private: |
||||
//[UserVariables] -- You can add your own custom variables in this section.
|
||||
DexedAudioProcessorEditor *editor; |
||||
DexedAudioProcessor *processor; |
||||
|
||||
Image background; |
||||
Image imageLight; |
||||
//[/UserVariables]
|
||||
|
||||
//==============================================================================
|
||||
ScopedPointer<Slider> lfoSpeed; |
||||
ScopedPointer<Slider> lfoAmDepth; |
||||
ScopedPointer<Slider> lfoPitchDepth; |
||||
ScopedPointer<Slider> lfoDelay; |
||||
ScopedPointer<Slider> cutoff; |
||||
ScopedPointer<Slider> reso; |
||||
ScopedPointer<Slider> pitchRate2; |
||||
ScopedPointer<Slider> pitchRate3; |
||||
ScopedPointer<Slider> pitchRate4; |
||||
ScopedPointer<Slider> pitchRate1; |
||||
ScopedPointer<Slider> pitchLevel2; |
||||
ScopedPointer<Slider> pitchLevel3; |
||||
ScopedPointer<Slider> pitchLevel4; |
||||
ScopedPointer<Slider> pitchLevel1; |
||||
ScopedPointer<Slider> transpose; |
||||
ScopedPointer<ToggleButton> oscSync; |
||||
ScopedPointer<Slider> pitchModSens; |
||||
ScopedPointer<ToggleButton> lfoSync; |
||||
ScopedPointer<PitchEnvDisplay> pitchEnvDisplay; |
||||
ScopedPointer<AlgoDisplay> algoDisplay; |
||||
ScopedPointer<Slider> feedback; |
||||
ScopedPointer<Slider> algo; |
||||
ScopedPointer<LcdDisplay> lcdDisplay; |
||||
ScopedPointer<Slider> output; |
||||
ScopedPointer<VuMeter> vuOutput; |
||||
ScopedPointer<TextButton> initButton; |
||||
ScopedPointer<TextButton> parmButton; |
||||
ScopedPointer<TextButton> cartButton; |
||||
ScopedPointer<TextButton> storeButton; |
||||
ScopedPointer<ToggleButton> monoMode; |
||||
ScopedPointer<ComboBoxImage> lfoType; |
||||
ScopedPointer<ProgramSelector> programSelector; |
||||
ScopedPointer<ImageButton> aboutButton; |
||||
ScopedPointer<Slider> tune; |
||||
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GlobalEditor) |
||||
}; |
||||
|
||||
//[EndFile] You can add extra defines here...
|
||||
//[/EndFile]
|
||||
|
||||
#endif // __JUCE_HEADER_10638A2B49B704D0__
|
@ -1,660 +0,0 @@ |
||||
/*
|
||||
============================================================================== |
||||
|
||||
This is an automatically generated GUI class created by the Introjucer! |
||||
|
||||
Be careful when adding custom code to these files, as only the code within |
||||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded |
||||
and re-saved. |
||||
|
||||
Created with Introjucer version: 3.2.0 |
||||
|
||||
------------------------------------------------------------------------------ |
||||
|
||||
The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions" |
||||
Copyright (c) 2015 - ROLI Ltd. |
||||
|
||||
============================================================================== |
||||
*/ |
||||
|
||||
//[Headers] You can add your own extra header files here...
|
||||
//[/Headers]
|
||||
|
||||
#include "OperatorEditor.h" |
||||
|
||||
|
||||
//[MiscUserDefs] You can add your own user definitions and misc code here...
|
||||
#ifndef M_LN10 |
||||
#define M_LN10 2.30258509299404568402 |
||||
#endif |
||||
|
||||
class OperatorSwitch : public ToggleButton { |
||||
Image image; |
||||
public : |
||||
OperatorSwitch() : ToggleButton("opSwitch") { |
||||
image = DXLookNFeel::getLookAndFeel()->imageSwitchOperator; |
||||
setSize(32, 32); |
||||
} |
||||
|
||||
void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) { |
||||
g.drawImage(image, 0, 0, 32, 32, 0, getToggleState() ? 0 : 32, 32, 32); |
||||
} |
||||
}; |
||||
|
||||
//[/MiscUserDefs]
|
||||
|
||||
//==============================================================================
|
||||
OperatorEditor::OperatorEditor () |
||||
{ |
||||
//[Constructor_pre] You can add your own custom stuff here..
|
||||
//[/Constructor_pre]
|
||||
|
||||
addAndMakeVisible (s_egl1 = new Slider ("egl1")); |
||||
s_egl1->setRange (0, 99, 1); |
||||
s_egl1->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
s_egl1->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
s_egl1->addListener (this); |
||||
|
||||
addAndMakeVisible (s_egl2 = new Slider ("egl2")); |
||||
s_egl2->setRange (0, 99, 1); |
||||
s_egl2->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
s_egl2->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
s_egl2->addListener (this); |
||||
|
||||
addAndMakeVisible (s_egl3 = new Slider ("egl3")); |
||||
s_egl3->setRange (0, 99, 1); |
||||
s_egl3->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
s_egl3->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
s_egl3->addListener (this); |
||||
|
||||
addAndMakeVisible (s_egl4 = new Slider ("egl4")); |
||||
s_egl4->setRange (0, 99, 1); |
||||
s_egl4->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
s_egl4->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
s_egl4->addListener (this); |
||||
|
||||
addAndMakeVisible (s_egv1 = new Slider ("egr1")); |
||||
s_egv1->setRange (0, 99, 1); |
||||
s_egv1->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
s_egv1->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
s_egv1->addListener (this); |
||||
|
||||
addAndMakeVisible (s_egv2 = new Slider ("egr3")); |
||||
s_egv2->setRange (0, 99, 1); |
||||
s_egv2->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
s_egv2->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
s_egv2->addListener (this); |
||||
|
||||
addAndMakeVisible (s_egv3 = new Slider ("egr3")); |
||||
s_egv3->setRange (0, 99, 1); |
||||
s_egv3->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
s_egv3->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
s_egv3->addListener (this); |
||||
|
||||
addAndMakeVisible (s_egv4 = new Slider ("egr4")); |
||||
s_egv4->setRange (0, 99, 1); |
||||
s_egv4->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
s_egv4->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
s_egv4->addListener (this); |
||||
|
||||
addAndMakeVisible (opLevel = new Slider ("opLevel")); |
||||
opLevel->setRange (0, 99, 1); |
||||
opLevel->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
opLevel->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
opLevel->addListener (this); |
||||
|
||||
addAndMakeVisible (opFine = new Slider ("opFine")); |
||||
opFine->setRange (0, 99, 1); |
||||
opFine->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
opFine->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
opFine->addListener (this); |
||||
|
||||
addAndMakeVisible (opCoarse = new Slider ("opCoarse")); |
||||
opCoarse->setRange (0, 31, 1); |
||||
opCoarse->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
opCoarse->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
opCoarse->addListener (this); |
||||
|
||||
addAndMakeVisible (khzDisplay = new Label ("khz", |
||||
TRANS("1,000 kHz"))); |
||||
khzDisplay->setFont (Font (12.60f, Font::plain)); |
||||
khzDisplay->setJustificationType (Justification::centred); |
||||
khzDisplay->setEditable (false, false, false); |
||||
khzDisplay->setColour (Label::backgroundColourId, Colour (0x6a000000)); |
||||
khzDisplay->setColour (Label::textColourId, Colours::white); |
||||
khzDisplay->setColour (Label::outlineColourId, Colour (0x00000000)); |
||||
khzDisplay->setColour (TextEditor::textColourId, Colours::black); |
||||
khzDisplay->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); |
||||
|
||||
addAndMakeVisible (detune = new Slider ("detune")); |
||||
detune->setRange (-7, 7, 1); |
||||
detune->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
detune->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); |
||||
detune->addListener (this); |
||||
|
||||
addAndMakeVisible (envDisplay = new EnvDisplay()); |
||||
envDisplay->setName ("envDisplay"); |
||||
|
||||
addAndMakeVisible (sclLeftLevel = new Slider ("sclLeftLevel")); |
||||
sclLeftLevel->setTooltip (TRANS("Keyboard Scale Level Left Depth ")); |
||||
sclLeftLevel->setRange (0, 99, 1); |
||||
sclLeftLevel->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
sclLeftLevel->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
sclLeftLevel->addListener (this); |
||||
|
||||
addAndMakeVisible (sclRightLevel = new Slider ("sclRightLevel")); |
||||
sclRightLevel->setTooltip (TRANS("Keyboard Scale Level Right Depth ")); |
||||
sclRightLevel->setRange (0, 99, 1); |
||||
sclRightLevel->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
sclRightLevel->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
sclRightLevel->addListener (this); |
||||
|
||||
addAndMakeVisible (sclLvlBrkPt = new Slider ("sclLvlBrkPt")); |
||||
sclLvlBrkPt->setTooltip (TRANS("Scale Level Breakpoint")); |
||||
sclLvlBrkPt->setRange (0, 99, 1); |
||||
sclLvlBrkPt->setSliderStyle (Slider::LinearHorizontal); |
||||
sclLvlBrkPt->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
sclLvlBrkPt->addListener (this); |
||||
|
||||
addAndMakeVisible (sclRateScaling = new Slider ("sclRateScaling")); |
||||
sclRateScaling->setTooltip (TRANS("Keyboard Rate Scaling")); |
||||
sclRateScaling->setRange (0, 7, 1); |
||||
sclRateScaling->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
sclRateScaling->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
sclRateScaling->addListener (this); |
||||
|
||||
addAndMakeVisible (keyVelSens = new Slider ("keyVelSens")); |
||||
keyVelSens->setRange (0, 7, 1); |
||||
keyVelSens->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
keyVelSens->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
keyVelSens->addListener (this); |
||||
|
||||
addAndMakeVisible (ampModSens = new Slider ("ampModSens")); |
||||
ampModSens->setRange (0, 3, 1); |
||||
ampModSens->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
ampModSens->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); |
||||
ampModSens->addListener (this); |
||||
|
||||
addAndMakeVisible (vu = new VuMeter()); |
||||
vu->setName ("vu"); |
||||
|
||||
addAndMakeVisible (opMode = new ToggleButton ("opMode")); |
||||
opMode->setButtonText (String::empty); |
||||
opMode->addListener (this); |
||||
|
||||
addAndMakeVisible (kbdLeftCurve = new ComboBoxImage()); |
||||
kbdLeftCurve->setName ("kbdLeftCurve"); |
||||
|
||||
addAndMakeVisible (kbdRightCurve = new ComboBoxImage()); |
||||
kbdRightCurve->setName ("kbdRightCurve"); |
||||
|
||||
|
||||
//[UserPreSize]
|
||||
addAndMakeVisible(opSwitch = new OperatorSwitch()); |
||||
//[/UserPreSize]
|
||||
|
||||
setSize (287, 218); |
||||
|
||||
|
||||
//[Constructor] You can add your own custom stuff here..
|
||||
light = DXLookNFeel::getLookAndFeel()->imageLight; |
||||
Image tmp = DXLookNFeel::getLookAndFeel()->imageScaling; |
||||
|
||||
kbdLeftCurve->addItem("-LN", 1); |
||||
kbdLeftCurve->addItem("-EX", 2); |
||||
kbdLeftCurve->addItem("+EX", 3); |
||||
kbdLeftCurve->addItem("+LN", 4); |
||||
int posLeft[] = {0,5,4,3}; |
||||
kbdLeftCurve->setImage(tmp, posLeft); |
||||
|
||||
kbdRightCurve->addItem("-LN", 1); |
||||
kbdRightCurve->addItem("-EX", 2); |
||||
kbdRightCurve->addItem("+EX", 3); |
||||
kbdRightCurve->addItem("+LN", 4); |
||||
int posRight[] = {3,2,1,0}; |
||||
kbdRightCurve->setImage(tmp, posRight); |
||||
|
||||
background = DXLookNFeel::getLookAndFeel()->imageOperator; |
||||
|
||||
//[/Constructor]
|
||||
} |
||||
|
||||
OperatorEditor::~OperatorEditor() |
||||
{ |
||||
//[Destructor_pre]. You can add your own custom destruction code here..
|
||||
//[/Destructor_pre]
|
||||
|
||||
s_egl1 = nullptr; |
||||
s_egl2 = nullptr; |
||||
s_egl3 = nullptr; |
||||
s_egl4 = nullptr; |
||||
s_egv1 = nullptr; |
||||
s_egv2 = nullptr; |
||||
s_egv3 = nullptr; |
||||
s_egv4 = nullptr; |
||||
opLevel = nullptr; |
||||
opFine = nullptr; |
||||
opCoarse = nullptr; |
||||
khzDisplay = nullptr; |
||||
detune = nullptr; |
||||
envDisplay = nullptr; |
||||
sclLeftLevel = nullptr; |
||||
sclRightLevel = nullptr; |
||||
sclLvlBrkPt = nullptr; |
||||
sclRateScaling = nullptr; |
||||
keyVelSens = nullptr; |
||||
ampModSens = nullptr; |
||||
vu = nullptr; |
||||
opMode = nullptr; |
||||
kbdLeftCurve = nullptr; |
||||
kbdRightCurve = nullptr; |
||||
|
||||
|
||||
//[Destructor]. You can add your own custom destruction code here..
|
||||
opSwitch = nullptr; |
||||
//[/Destructor]
|
||||
} |
||||
|
||||
//==============================================================================
|
||||
void OperatorEditor::paint (Graphics& g) |
||||
{ |
||||
//[UserPrePaint] Add your own custom painting code here..
|
||||
g.drawImage(background, 0, 0, 287, 218, 0, 0, 287, 218); |
||||
//[/UserPrePaint]
|
||||
|
||||
//[UserPaint] Add your own custom painting code here..
|
||||
g.setColour (Colours::white); |
||||
g.setFont(Font (30.00f, Font::plain)); |
||||
g.drawText(opNum, 250, 14, 30, 30, Justification::centred, true); |
||||
|
||||
bool state = opMode->getToggleState(); |
||||
|
||||
// 129 x 24
|
||||
g.drawImage(light, 127, 24, 14, 14, 0, state ? 0 : 14, 14, 14); |
||||
// 199 x 24
|
||||
g.drawImage(light, 198, 24, 14, 14, 0, !state ? 0 : 14, 14, 14); |
||||
//[/UserPaint]
|
||||
} |
||||
|
||||
void OperatorEditor::resized() |
||||
{ |
||||
//[UserPreResize] Add your own custom resize code here..
|
||||
//[/UserPreResize]
|
||||
|
||||
s_egl1->setBounds (5, 128, 34, 34); |
||||
s_egl2->setBounds (33, 129, 34, 34); |
||||
s_egl3->setBounds (61, 128, 34, 34); |
||||
s_egl4->setBounds (89, 128, 34, 34); |
||||
s_egv1->setBounds (5, 169, 34, 34); |
||||
s_egv2->setBounds (33, 169, 34, 34); |
||||
s_egv3->setBounds (61, 169, 34, 34); |
||||
s_egv4->setBounds (89, 169, 34, 34); |
||||
opLevel->setBounds (245, 76, 34, 34); |
||||
opFine->setBounds (78, 24, 34, 34); |
||||
opCoarse->setBounds (43, 24, 34, 34); |
||||
khzDisplay->setBounds (15, 10, 95, 10); |
||||
detune->setBounds (6, 24, 34, 34); |
||||
envDisplay->setBounds (16, 83, 94, 30); |
||||
sclLeftLevel->setBounds (131, 115, 34, 34); |
||||
sclRightLevel->setBounds (241, 115, 34, 34); |
||||
sclLvlBrkPt->setBounds (178, 130, 54, 24); |
||||
sclRateScaling->setBounds (186, 179, 34, 34); |
||||
keyVelSens->setBounds (204, 76, 34, 34); |
||||
ampModSens->setBounds (140, 76, 34, 34); |
||||
vu->setBounds (132, 52, 140, 8); |
||||
opMode->setBounds (146, 19, 48, 26); |
||||
kbdLeftCurve->setBounds (128, 170, 36, 26); |
||||
kbdRightCurve->setBounds (240, 170, 36, 26); |
||||
//[UserResized] Add your own custom resize handling here..
|
||||
opSwitch->setBounds(226, 13, 64, 32); |
||||
//[/UserResized]
|
||||
} |
||||
|
||||
void OperatorEditor::sliderValueChanged (Slider* sliderThatWasMoved) |
||||
{ |
||||
//[UsersliderValueChanged_Pre]
|
||||
//[/UsersliderValueChanged_Pre]
|
||||
|
||||
if (sliderThatWasMoved == s_egl1) |
||||
{ |
||||
//[UserSliderCode_s_egl1] -- add your slider handling code here..
|
||||
envDisplay->repaint(); |
||||
//[/UserSliderCode_s_egl1]
|
||||
} |
||||
else if (sliderThatWasMoved == s_egl2) |
||||
{ |
||||
//[UserSliderCode_s_egl2] -- add your slider handling code here..
|
||||
envDisplay->repaint(); |
||||
//[/UserSliderCode_s_egl2]
|
||||
} |
||||
else if (sliderThatWasMoved == s_egl3) |
||||
{ |
||||
//[UserSliderCode_s_egl3] -- add your slider handling code here..
|
||||
envDisplay->repaint(); |
||||
//[/UserSliderCode_s_egl3]
|
||||
} |
||||
else if (sliderThatWasMoved == s_egl4) |
||||
{ |
||||
//[UserSliderCode_s_egl4] -- add your slider handling code here..
|
||||
envDisplay->repaint(); |
||||
//[/UserSliderCode_s_egl4]
|
||||
} |
||||
else if (sliderThatWasMoved == s_egv1) |
||||
{ |
||||
//[UserSliderCode_s_egv1] -- add your slider handling code here..
|
||||
envDisplay->repaint(); |
||||
//[/UserSliderCode_s_egv1]
|
||||
} |
||||
else if (sliderThatWasMoved == s_egv2) |
||||
{ |
||||
//[UserSliderCode_s_egv2] -- add your slider handling code here..
|
||||
envDisplay->repaint(); |
||||
//[/UserSliderCode_s_egv2]
|
||||
} |
||||
else if (sliderThatWasMoved == s_egv3) |
||||
{ |
||||
//[UserSliderCode_s_egv3] -- add your slider handling code here..
|
||||
envDisplay->repaint(); |
||||
//[/UserSliderCode_s_egv3]
|
||||
} |
||||
else if (sliderThatWasMoved == s_egv4) |
||||
{ |
||||
//[UserSliderCode_s_egv4] -- add your slider handling code here..
|
||||
envDisplay->repaint(); |
||||
//[/UserSliderCode_s_egv4]
|
||||
} |
||||
else if (sliderThatWasMoved == opLevel) |
||||
{ |
||||
//[UserSliderCode_opLevel] -- add your slider handling code here..
|
||||
//[/UserSliderCode_opLevel]
|
||||
} |
||||
else if (sliderThatWasMoved == opFine) |
||||
{ |
||||
//[UserSliderCode_opFine] -- add your slider handling code here..
|
||||
updateDisplay(); |
||||
//[/UserSliderCode_opFine]
|
||||
} |
||||
else if (sliderThatWasMoved == opCoarse) |
||||
{ |
||||
//[UserSliderCode_opCoarse] -- add your slider handling code here..
|
||||
updateDisplay(); |
||||
//[/UserSliderCode_opCoarse]
|
||||
} |
||||
else if (sliderThatWasMoved == detune) |
||||
{ |
||||
//[UserSliderCode_detune] -- add your slider handling code here..
|
||||
updateDisplay(); |
||||
//[/UserSliderCode_detune]
|
||||
} |
||||
else if (sliderThatWasMoved == sclLeftLevel) |
||||
{ |
||||
//[UserSliderCode_sclLeftLevel] -- add your slider handling code here..
|
||||
//[/UserSliderCode_sclLeftLevel]
|
||||
} |
||||
else if (sliderThatWasMoved == sclRightLevel) |
||||
{ |
||||
//[UserSliderCode_sclRightLevel] -- add your slider handling code here..
|
||||
//[/UserSliderCode_sclRightLevel]
|
||||
} |
||||
else if (sliderThatWasMoved == sclLvlBrkPt) |
||||
{ |
||||
//[UserSliderCode_sclLvlBrkPt] -- add your slider handling code here..
|
||||
//[/UserSliderCode_sclLvlBrkPt]
|
||||
} |
||||
else if (sliderThatWasMoved == sclRateScaling) |
||||
{ |
||||
//[UserSliderCode_sclRateScaling] -- add your slider handling code here..
|
||||
//[/UserSliderCode_sclRateScaling]
|
||||
} |
||||
else if (sliderThatWasMoved == keyVelSens) |
||||
{ |
||||
//[UserSliderCode_keyVelSens] -- add your slider handling code here..
|
||||
//[/UserSliderCode_keyVelSens]
|
||||
} |
||||
else if (sliderThatWasMoved == ampModSens) |
||||
{ |
||||
//[UserSliderCode_ampModSens] -- add your slider handling code here..
|
||||
//[/UserSliderCode_ampModSens]
|
||||
} |
||||
|
||||
//[UsersliderValueChanged_Post]
|
||||
//[/UsersliderValueChanged_Post]
|
||||
} |
||||
|
||||
void OperatorEditor::buttonClicked (Button* buttonThatWasClicked) |
||||
{ |
||||
//[UserbuttonClicked_Pre]
|
||||
//[/UserbuttonClicked_Pre]
|
||||
|
||||
if (buttonThatWasClicked == opMode) |
||||
{ |
||||
//[UserButtonCode_opMode] -- add your button handler code here..
|
||||
repaint(); |
||||
//[/UserButtonCode_opMode]
|
||||
} |
||||
|
||||
//[UserbuttonClicked_Post]
|
||||
//[/UserbuttonClicked_Post]
|
||||
} |
||||
|
||||
|
||||
|
||||
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
|
||||
void OperatorEditor::bind(DexedAudioProcessor *parent, int op) { |
||||
parent->opCtrl[op].egLevel[0]->bind(s_egl1); |
||||
parent->opCtrl[op].egLevel[1]->bind(s_egl2); |
||||
parent->opCtrl[op].egLevel[2]->bind(s_egl3); |
||||
parent->opCtrl[op].egLevel[3]->bind(s_egl4); |
||||
parent->opCtrl[op].egRate[0]->bind(s_egv1); |
||||
parent->opCtrl[op].egRate[1]->bind(s_egv2); |
||||
parent->opCtrl[op].egRate[2]->bind(s_egv3); |
||||
parent->opCtrl[op].egRate[3]->bind(s_egv4); |
||||
parent->opCtrl[op].level->bind(opLevel); |
||||
parent->opCtrl[op].opMode->bind(opMode); |
||||
parent->opCtrl[op].fine->bind(opFine); |
||||
parent->opCtrl[op].coarse->bind(opCoarse); |
||||
parent->opCtrl[op].detune->bind(detune); |
||||
parent->opCtrl[op].sclBrkPt->bind(sclLvlBrkPt); |
||||
parent->opCtrl[op].sclLeftCurve->bind(kbdLeftCurve); |
||||
parent->opCtrl[op].sclRightCurve->bind(kbdRightCurve); |
||||
parent->opCtrl[op].sclLeftDepth->bind(sclLeftLevel); |
||||
parent->opCtrl[op].sclRightDepth->bind(sclRightLevel); |
||||
parent->opCtrl[op].sclRate->bind(sclRateScaling); |
||||
parent->opCtrl[op].ampModSens->bind(ampModSens); |
||||
parent->opCtrl[op].velModSens->bind(keyVelSens); |
||||
parent->opCtrl[op].opSwitch->bind(opSwitch); |
||||
|
||||
int offset = parent->opCtrl[op].egRate[0]->getOffset(); |
||||
envDisplay->pvalues = &(parent->data[offset]); |
||||
processor = parent; |
||||
|
||||
opNum << op + 1; |
||||
internalOp = 5-op; |
||||
} |
||||
|
||||
void OperatorEditor::updateGain(float v) { |
||||
vu->v = v; |
||||
vu->repaint(); |
||||
} |
||||
|
||||
void OperatorEditor::updateDisplay() { |
||||
float freq = opCoarse->getValue(); |
||||
float fine = opFine->getValue(); |
||||
String txtFreq; |
||||
|
||||
if (opMode->getToggleState() == 0) { |
||||
if ( freq == 0 ) |
||||
freq = 0.5; |
||||
txtFreq << "f = " << (freq + (freq * (fine/100))); |
||||
} else { |
||||
freq = pow(10,((int)freq)&3); |
||||
freq = freq * exp(M_LN10*(fine/100)); |
||||
txtFreq << freq << " Hz"; |
||||
} |
||||
|
||||
int det = detune->getValue(); |
||||
if ( det != 0 ) { |
||||
if ( det > 0 ) |
||||
txtFreq << " +" << det; |
||||
else |
||||
txtFreq << " " << det; |
||||
} |
||||
khzDisplay->setText(txtFreq, dontSendNotification); |
||||
repaint(); |
||||
} |
||||
|
||||
|
||||
void OperatorEditor::updateEnvPos(char pos) { |
||||
envDisplay->vPos = pos; |
||||
envDisplay->repaint(); |
||||
} |
||||
|
||||
void OperatorEditor::mouseDown(const MouseEvent &event) { |
||||
if ( event.mods.isRightButtonDown() ) { |
||||
PopupMenu popup; |
||||
|
||||
popup.addItem(1, "Copy Operator Values"); |
||||
popup.addItem(2, "Paste Envelope Values", processor->hasClipboardContent()); |
||||
popup.addItem(3, "Paste Operator Values", processor->hasClipboardContent()); |
||||
popup.addSeparator(); |
||||
popup.addItem(4, "Send current program to DX7"); |
||||
|
||||
switch(popup.show()) { |
||||
case 1: |
||||
processor->copyToClipboard(internalOp); |
||||
break; |
||||
|
||||
case 2: |
||||
processor->pasteEnvFromClipboard(internalOp); |
||||
break; |
||||
|
||||
case 3: |
||||
processor->pasteOpFromClipboard(internalOp); |
||||
break; |
||||
|
||||
case 4: |
||||
processor->sendCurrentSysexProgram(); |
||||
break; |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
//[/MiscUserCode]
|
||||
|
||||
|
||||
//==============================================================================
|
||||
#if 0 |
||||
/* -- Introjucer information section --
|
||||
|
||||
This is where the Introjucer stores the metadata that describe this GUI layout, so |
||||
make changes in here at your peril! |
||||
|
||||
BEGIN_JUCER_METADATA |
||||
|
||||
<JUCER_COMPONENT documentType="Component" className="OperatorEditor" componentName="" |
||||
parentClasses="public Component" constructorParams="" variableInitialisers="" |
||||
snapPixels="2" snapActive="0" snapShown="1" overlayOpacity="0.330" |
||||
fixedSize="1" initialWidth="287" initialHeight="218"> |
||||
<BACKGROUND backgroundColour="ffffff"/> |
||||
<SLIDER name="egl1" id="dc070cc41347df47" memberName="s_egl1" virtualName="" |
||||
explicitFocusOrder="0" pos="5 128 34 34" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="egl2" id="66f5195e9c374029" memberName="s_egl2" virtualName="" |
||||
explicitFocusOrder="0" pos="33 129 34 34" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="egl3" id="9d57bd53203dcdb4" memberName="s_egl3" virtualName="" |
||||
explicitFocusOrder="0" pos="61 128 34 34" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="egl4" id="4f7c3ece3ea2cf9c" memberName="s_egl4" virtualName="" |
||||
explicitFocusOrder="0" pos="89 128 34 34" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="egr1" id="2ca8137d80da46fb" memberName="s_egv1" virtualName="" |
||||
explicitFocusOrder="0" pos="5 169 34 34" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="egr3" id="4ad6d0c532d15973" memberName="s_egv2" virtualName="" |
||||
explicitFocusOrder="0" pos="33 169 34 34" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="egr3" id="8a2027f9ede16b4f" memberName="s_egv3" virtualName="" |
||||
explicitFocusOrder="0" pos="61 169 34 34" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="egr4" id="8c04f1c943d837e8" memberName="s_egv4" virtualName="" |
||||
explicitFocusOrder="0" pos="89 169 34 34" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="opLevel" id="f8521c8214fb8993" memberName="opLevel" virtualName="" |
||||
explicitFocusOrder="0" pos="245 76 34 34" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="opFine" id="e445aa61bd6cddcb" memberName="opFine" virtualName="" |
||||
explicitFocusOrder="0" pos="78 24 34 34" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="opCoarse" id="4eec63d30d7488d2" memberName="opCoarse" virtualName="" |
||||
explicitFocusOrder="0" pos="43 24 34 34" min="0" max="31" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<LABEL name="khz" id="eb961eed8902a6fc" memberName="khzDisplay" virtualName="" |
||||
explicitFocusOrder="0" pos="15 10 95 10" bkgCol="6a000000" textCol="ffffffff" |
||||
outlineCol="0" edTextCol="ff000000" edBkgCol="0" labelText="1,000 kHz" |
||||
editableSingleClick="0" editableDoubleClick="0" focusDiscardsChanges="0" |
||||
fontname="Default font" fontsize="12.599999999999999645" bold="0" |
||||
italic="0" justification="36"/> |
||||
<SLIDER name="detune" id="f093ec8defca2fc2" memberName="detune" virtualName="" |
||||
explicitFocusOrder="0" pos="6 24 34 34" min="-7" max="7" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="0" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<GENERICCOMPONENT name="envDisplay" id="b18856de924c6340" memberName="envDisplay" |
||||
virtualName="" explicitFocusOrder="0" pos="16 83 94 30" class="EnvDisplay" |
||||
params=""/> |
||||
<SLIDER name="sclLeftLevel" id="bd6f338ae68e454f" memberName="sclLeftLevel" |
||||
virtualName="" explicitFocusOrder="0" pos="131 115 34 34" tooltip="Keyboard Scale Level Left Depth " |
||||
min="0" max="99" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="sclRightLevel" id="b9e23ed5187fc7e5" memberName="sclRightLevel" |
||||
virtualName="" explicitFocusOrder="0" pos="241 115 34 34" tooltip="Keyboard Scale Level Right Depth " |
||||
min="0" max="99" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="sclLvlBrkPt" id="c563ac3116923bbc" memberName="sclLvlBrkPt" |
||||
virtualName="" explicitFocusOrder="0" pos="178 130 54 24" tooltip="Scale Level Breakpoint" |
||||
min="0" max="99" int="1" style="LinearHorizontal" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="sclRateScaling" id="f0d17c8e09aa4c49" memberName="sclRateScaling" |
||||
virtualName="" explicitFocusOrder="0" pos="186 179 34 34" tooltip="Keyboard Rate Scaling" |
||||
min="0" max="7" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="keyVelSens" id="21795d045d07602b" memberName="keyVelSens" |
||||
virtualName="" explicitFocusOrder="0" pos="204 76 34 34" min="0" |
||||
max="7" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="ampModSens" id="634ceaa7b0f81a6c" memberName="ampModSens" |
||||
virtualName="" explicitFocusOrder="0" pos="140 76 34 34" min="0" |
||||
max="3" int="1" style="RotaryVerticalDrag" textBoxPos="NoTextBox" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<GENERICCOMPONENT name="vu" id="6f952594ea99dc1e" memberName="vu" virtualName="" |
||||
explicitFocusOrder="0" pos="132 52 140 8" class="VuMeter" params=""/> |
||||
<TOGGLEBUTTON name="opMode" id="15db8e5c9dd13966" memberName="opMode" virtualName="" |
||||
explicitFocusOrder="0" pos="146 19 48 26" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<GENERICCOMPONENT name="kbdLeftCurve" id="ee4e60dfcd6cb790" memberName="kbdLeftCurve" |
||||
virtualName="" explicitFocusOrder="0" pos="128 170 36 26" class="ComboBoxImage" |
||||
params=""/> |
||||
<GENERICCOMPONENT name="kbdRightCurve" id="f5ca44d67593488a" memberName="kbdRightCurve" |
||||
virtualName="" explicitFocusOrder="0" pos="240 170 36 26" class="ComboBoxImage" |
||||
params=""/> |
||||
</JUCER_COMPONENT> |
||||
|
||||
END_JUCER_METADATA |
||||
*/ |
||||
#endif |
||||
|
||||
|
||||
//[EndFile] You can add extra defines here...
|
||||
//[/EndFile]
|
@ -1,110 +0,0 @@ |
||||
/*
|
||||
============================================================================== |
||||
|
||||
This is an automatically generated GUI class created by the Introjucer! |
||||
|
||||
Be careful when adding custom code to these files, as only the code within |
||||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded |
||||
and re-saved. |
||||
|
||||
Created with Introjucer version: 3.2.0 |
||||
|
||||
------------------------------------------------------------------------------ |
||||
|
||||
The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions" |
||||
Copyright (c) 2015 - ROLI Ltd. |
||||
|
||||
============================================================================== |
||||
*/ |
||||
|
||||
#ifndef __JUCE_HEADER_F21C2CC3FAD5D98E__ |
||||
#define __JUCE_HEADER_F21C2CC3FAD5D98E__ |
||||
|
||||
//[Headers] -- You can add your own extra header files here --
|
||||
#include "JuceHeader.h" |
||||
#include "PluginProcessor.h" |
||||
#include "DXComponents.h" |
||||
#include "DXLookNFeel.h" |
||||
//[/Headers]
|
||||
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
//[Comments]
|
||||
An auto-generated component, created by the Introjucer. |
||||
|
||||
Describe your class and how it works here! |
||||
//[/Comments]
|
||||
*/ |
||||
class OperatorEditor : public Component, |
||||
public SliderListener, |
||||
public ButtonListener |
||||
{ |
||||
public: |
||||
//==============================================================================
|
||||
OperatorEditor (); |
||||
~OperatorEditor(); |
||||
|
||||
//==============================================================================
|
||||
//[UserMethods] -- You can add your own custom methods in this section.
|
||||
|
||||
void bind(DexedAudioProcessor *processor, int num); |
||||
void updateGain(float v); |
||||
void updateDisplay(); |
||||
void updateEnvPos(char pos); |
||||
void mouseDown(const MouseEvent& e) override; |
||||
//[/UserMethods]
|
||||
|
||||
void paint (Graphics& g) override; |
||||
void resized() override; |
||||
void sliderValueChanged (Slider* sliderThatWasMoved) override; |
||||
void buttonClicked (Button* buttonThatWasClicked) override; |
||||
|
||||
|
||||
|
||||
private: |
||||
//[UserVariables] -- You can add your own custom variables in this section.
|
||||
String opNum; |
||||
int internalOp; |
||||
Image light; |
||||
DexedAudioProcessor *processor; |
||||
Image background; |
||||
ScopedPointer<ToggleButton> opSwitch; |
||||
//[/UserVariables]
|
||||
|
||||
//==============================================================================
|
||||
ScopedPointer<Slider> s_egl1; |
||||
ScopedPointer<Slider> s_egl2; |
||||
ScopedPointer<Slider> s_egl3; |
||||
ScopedPointer<Slider> s_egl4; |
||||
ScopedPointer<Slider> s_egv1; |
||||
ScopedPointer<Slider> s_egv2; |
||||
ScopedPointer<Slider> s_egv3; |
||||
ScopedPointer<Slider> s_egv4; |
||||
ScopedPointer<Slider> opLevel; |
||||
ScopedPointer<Slider> opFine; |
||||
ScopedPointer<Slider> opCoarse; |
||||
ScopedPointer<Label> khzDisplay; |
||||
ScopedPointer<Slider> detune; |
||||
ScopedPointer<EnvDisplay> envDisplay; |
||||
ScopedPointer<Slider> sclLeftLevel; |
||||
ScopedPointer<Slider> sclRightLevel; |
||||
ScopedPointer<Slider> sclLvlBrkPt; |
||||
ScopedPointer<Slider> sclRateScaling; |
||||
ScopedPointer<Slider> keyVelSens; |
||||
ScopedPointer<Slider> ampModSens; |
||||
ScopedPointer<VuMeter> vu; |
||||
ScopedPointer<ToggleButton> opMode; |
||||
ScopedPointer<ComboBoxImage> kbdLeftCurve; |
||||
ScopedPointer<ComboBoxImage> kbdRightCurve; |
||||
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OperatorEditor) |
||||
}; |
||||
|
||||
//[EndFile] You can add extra defines here...
|
||||
//[/EndFile]
|
||||
|
||||
#endif // __JUCE_HEADER_F21C2CC3FAD5D98E__
|
@ -1,703 +0,0 @@ |
||||
/*
|
||||
============================================================================== |
||||
|
||||
This is an automatically generated GUI class created by the Introjucer! |
||||
|
||||
Be careful when adding custom code to these files, as only the code within |
||||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded |
||||
and re-saved. |
||||
|
||||
Created with Introjucer version: 3.2.0 |
||||
|
||||
------------------------------------------------------------------------------ |
||||
|
||||
The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions" |
||||
Copyright (c) 2015 - ROLI Ltd. |
||||
|
||||
============================================================================== |
||||
*/ |
||||
|
||||
//[Headers] You can add your own extra header files here...
|
||||
#include "Dexed.h" |
||||
//[/Headers]
|
||||
|
||||
#include "ParamDialog.h" |
||||
|
||||
|
||||
//[MiscUserDefs] You can add your own user definitions and misc code here...
|
||||
//[/MiscUserDefs]
|
||||
|
||||
//==============================================================================
|
||||
ParamDialog::ParamDialog () |
||||
{ |
||||
//[Constructor_pre] You can add your own custom stuff here..
|
||||
//[/Constructor_pre]
|
||||
|
||||
addAndMakeVisible (pitchRange = new Slider ("pitchRange")); |
||||
pitchRange->setRange (0, 12, 1); |
||||
pitchRange->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
pitchRange->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20); |
||||
pitchRange->addListener (this); |
||||
|
||||
addAndMakeVisible (pitchStep = new Slider ("pitchStep")); |
||||
pitchStep->setRange (0, 12, 1); |
||||
pitchStep->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
pitchStep->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20); |
||||
pitchStep->addListener (this); |
||||
|
||||
addAndMakeVisible (sysexIn = new ComboBox ("sysexIn")); |
||||
sysexIn->setEditableText (false); |
||||
sysexIn->setJustificationType (Justification::centredLeft); |
||||
sysexIn->setTextWhenNothingSelected (String::empty); |
||||
sysexIn->setTextWhenNoChoicesAvailable (TRANS("(no choices)")); |
||||
sysexIn->addListener (this); |
||||
|
||||
addAndMakeVisible (sysexOut = new ComboBox ("sysexOut")); |
||||
sysexOut->setEditableText (false); |
||||
sysexOut->setJustificationType (Justification::centredLeft); |
||||
sysexOut->setTextWhenNothingSelected (String::empty); |
||||
sysexOut->setTextWhenNoChoicesAvailable (TRANS("(no choices)")); |
||||
sysexOut->addListener (this); |
||||
|
||||
addAndMakeVisible (sysexChl = new Slider ("sysexChl")); |
||||
sysexChl->setRange (1, 16, 1); |
||||
sysexChl->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
sysexChl->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20); |
||||
sysexChl->addListener (this); |
||||
|
||||
addAndMakeVisible (engineReso = new ComboBox ("new combo box")); |
||||
engineReso->setEditableText (false); |
||||
engineReso->setJustificationType (Justification::centredLeft); |
||||
engineReso->setTextWhenNothingSelected (String::empty); |
||||
engineReso->setTextWhenNoChoicesAvailable (TRANS("(no choices)")); |
||||
engineReso->addItem (TRANS("Modern (24-bit)"), 1); |
||||
engineReso->addItem (TRANS("Mark I"), 2); |
||||
engineReso->addItem (TRANS("OPL Series"), 3); |
||||
engineReso->addListener (this); |
||||
|
||||
addAndMakeVisible (showKeyboard = new ToggleButton ("showKeyboard")); |
||||
showKeyboard->setButtonText (String::empty); |
||||
|
||||
addAndMakeVisible (whlRange = new Slider ("whlRange")); |
||||
whlRange->setRange (0, 99, 1); |
||||
whlRange->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
whlRange->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20); |
||||
whlRange->addListener (this); |
||||
|
||||
addAndMakeVisible (ftRange = new Slider ("ftRange")); |
||||
ftRange->setRange (0, 99, 1); |
||||
ftRange->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
ftRange->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20); |
||||
ftRange->addListener (this); |
||||
|
||||
addAndMakeVisible (brRange = new Slider ("brRange")); |
||||
brRange->setRange (0, 99, 1); |
||||
brRange->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
brRange->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20); |
||||
brRange->addListener (this); |
||||
|
||||
addAndMakeVisible (atRange = new Slider ("atRange")); |
||||
atRange->setRange (0, 99, 1); |
||||
atRange->setSliderStyle (Slider::RotaryVerticalDrag); |
||||
atRange->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20); |
||||
atRange->addListener (this); |
||||
|
||||
addAndMakeVisible (whlEg = new ToggleButton ("whlEg")); |
||||
whlEg->setButtonText (String::empty); |
||||
whlEg->addListener (this); |
||||
|
||||
addAndMakeVisible (ftEg = new ToggleButton ("ftEg")); |
||||
ftEg->setButtonText (String::empty); |
||||
ftEg->addListener (this); |
||||
|
||||
addAndMakeVisible (brEg = new ToggleButton ("brEg")); |
||||
brEg->setButtonText (String::empty); |
||||
brEg->addListener (this); |
||||
|
||||
addAndMakeVisible (atEg = new ToggleButton ("atEg")); |
||||
atEg->setButtonText (String::empty); |
||||
atEg->addListener (this); |
||||
|
||||
addAndMakeVisible (whlAmp = new ToggleButton ("whlAmp")); |
||||
whlAmp->setButtonText (String::empty); |
||||
whlAmp->addListener (this); |
||||
|
||||
addAndMakeVisible (ftAmp = new ToggleButton ("ftAmp")); |
||||
ftAmp->setButtonText (String::empty); |
||||
ftAmp->addListener (this); |
||||
|
||||
addAndMakeVisible (brAmp = new ToggleButton ("brAmp")); |
||||
brAmp->setButtonText (String::empty); |
||||
brAmp->addListener (this); |
||||
|
||||
addAndMakeVisible (atAmp = new ToggleButton ("atAmp")); |
||||
atAmp->setButtonText (String::empty); |
||||
atAmp->addListener (this); |
||||
|
||||
addAndMakeVisible (whlPitch = new ToggleButton ("whlPitch")); |
||||
whlPitch->setButtonText (String::empty); |
||||
whlPitch->addListener (this); |
||||
|
||||
addAndMakeVisible (ftPitch = new ToggleButton ("ftPitch")); |
||||
ftPitch->setButtonText (String::empty); |
||||
ftPitch->addListener (this); |
||||
|
||||
addAndMakeVisible (brPitch = new ToggleButton ("brPitch")); |
||||
brPitch->setButtonText (String::empty); |
||||
brPitch->addListener (this); |
||||
|
||||
addAndMakeVisible (atPitch = new ToggleButton ("atPitch")); |
||||
atPitch->setButtonText (String::empty); |
||||
atPitch->addListener (this); |
||||
|
||||
|
||||
//[UserPreSize]
|
||||
//[/UserPreSize]
|
||||
|
||||
setSize (710, 350); |
||||
|
||||
|
||||
//[Constructor] You can add your own custom stuff here..
|
||||
pitchRange->setEnabled(pitchStep->getValue() == 0); |
||||
|
||||
StringArray input; |
||||
input.add("None"); |
||||
input.addArray(MidiInput::getDevices()); |
||||
sysexIn->addItemList(input, 2); |
||||
|
||||
StringArray output; |
||||
output.add("None"); |
||||
output.addArray(MidiOutput::getDevices()); |
||||
sysexOut->addItemList(output, 2); |
||||
|
||||
//[/Constructor]
|
||||
} |
||||
|
||||
ParamDialog::~ParamDialog() |
||||
{ |
||||
//[Destructor_pre]. You can add your own custom destruction code here..
|
||||
//[/Destructor_pre]
|
||||
|
||||
pitchRange = nullptr; |
||||
pitchStep = nullptr; |
||||
sysexIn = nullptr; |
||||
sysexOut = nullptr; |
||||
sysexChl = nullptr; |
||||
engineReso = nullptr; |
||||
showKeyboard = nullptr; |
||||
whlRange = nullptr; |
||||
ftRange = nullptr; |
||||
brRange = nullptr; |
||||
atRange = nullptr; |
||||
whlEg = nullptr; |
||||
ftEg = nullptr; |
||||
brEg = nullptr; |
||||
atEg = nullptr; |
||||
whlAmp = nullptr; |
||||
ftAmp = nullptr; |
||||
brAmp = nullptr; |
||||
atAmp = nullptr; |
||||
whlPitch = nullptr; |
||||
ftPitch = nullptr; |
||||
brPitch = nullptr; |
||||
atPitch = nullptr; |
||||
|
||||
|
||||
//[Destructor]. You can add your own custom destruction code here..
|
||||
//[/Destructor]
|
||||
} |
||||
|
||||
//==============================================================================
|
||||
void ParamDialog::paint (Graphics& g) |
||||
{ |
||||
//[UserPrePaint] Add your own custom painting code here..
|
||||
//[/UserPrePaint]
|
||||
|
||||
g.fillAll (Colour (0xff3c322f)); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("Pitch Bend Range"), |
||||
20, 16, 276, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("Pitch Bend Step"), |
||||
20, 56, 276, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("DX7 In"), |
||||
20, 224, 131, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("DX7 Out"), |
||||
20, 264, 131, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("DX7 Channel"), |
||||
20, 304, 245, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("Engine Resolution"), |
||||
20, 156, 276, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::black); |
||||
g.fillRect (22, 138, 306, 1); |
||||
|
||||
g.setColour (Colours::black); |
||||
g.fillRect (22, 195, 306, 1); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("Show Keyboard"), |
||||
20, 96, 276, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::black); |
||||
g.fillRect (352, 11, 1, 325); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("Wheel"), |
||||
368, 16, 276, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("Foot"), |
||||
368, 96, 276, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("Breath"), |
||||
368, 56, 276, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("After Touch"), |
||||
368, 136, 276, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("PITCH"), |
||||
533, 163, 48, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("AMP"), |
||||
589, 163, 48, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
g.setColour (Colours::white); |
||||
g.setFont (Font (15.00f, Font::plain)); |
||||
g.drawText (TRANS("EG BIAS"), |
||||
645, 163, 48, 23, |
||||
Justification::centredLeft, true); |
||||
|
||||
//[UserPaint] Add your own custom painting code here..
|
||||
//[/UserPaint]
|
||||
} |
||||
|
||||
void ParamDialog::resized() |
||||
{ |
||||
//[UserPreResize] Add your own custom resize code here..
|
||||
//[/UserPreResize]
|
||||
|
||||
pitchRange->setBounds (264, 16, 72, 24); |
||||
pitchStep->setBounds (264, 56, 72, 24); |
||||
sysexIn->setBounds (104, 224, 224, 24); |
||||
sysexOut->setBounds (104, 264, 224, 24); |
||||
sysexChl->setBounds (264, 304, 72, 24); |
||||
engineReso->setBounds (160, 156, 168, 24); |
||||
showKeyboard->setBounds (264, 96, 56, 24); |
||||
whlRange->setBounds (448, 16, 72, 24); |
||||
ftRange->setBounds (448, 56, 72, 24); |
||||
brRange->setBounds (448, 96, 72, 24); |
||||
atRange->setBounds (448, 136, 72, 24); |
||||
whlEg->setBounds (640, 16, 56, 24); |
||||
ftEg->setBounds (640, 56, 56, 24); |
||||
brEg->setBounds (640, 96, 56, 24); |
||||
atEg->setBounds (640, 136, 56, 24); |
||||
whlAmp->setBounds (584, 16, 56, 24); |
||||
ftAmp->setBounds (584, 56, 56, 24); |
||||
brAmp->setBounds (584, 96, 56, 24); |
||||
atAmp->setBounds (584, 136, 56, 24); |
||||
whlPitch->setBounds (528, 16, 56, 24); |
||||
ftPitch->setBounds (528, 56, 56, 24); |
||||
brPitch->setBounds (528, 96, 56, 24); |
||||
atPitch->setBounds (528, 136, 56, 24); |
||||
//[UserResized] Add your own custom resize handling here..
|
||||
//[/UserResized]
|
||||
} |
||||
|
||||
void ParamDialog::sliderValueChanged (Slider* sliderThatWasMoved) |
||||
{ |
||||
//[UsersliderValueChanged_Pre]
|
||||
//[/UsersliderValueChanged_Pre]
|
||||
|
||||
if (sliderThatWasMoved == pitchRange) |
||||
{ |
||||
//[UserSliderCode_pitchRange] -- add your slider handling code here..
|
||||
//[/UserSliderCode_pitchRange]
|
||||
} |
||||
else if (sliderThatWasMoved == pitchStep) |
||||
{ |
||||
//[UserSliderCode_pitchStep] -- add your slider handling code here..
|
||||
pitchRange->setEnabled(pitchStep->getValue() == 0); |
||||
//[/UserSliderCode_pitchStep]
|
||||
} |
||||
else if (sliderThatWasMoved == sysexChl) |
||||
{ |
||||
//[UserSliderCode_sysexChl] -- add your slider handling code here..
|
||||
//[/UserSliderCode_sysexChl]
|
||||
} |
||||
else if (sliderThatWasMoved == whlRange) |
||||
{ |
||||
//[UserSliderCode_whlRange] -- add your slider handling code here..
|
||||
//[/UserSliderCode_whlRange]
|
||||
} |
||||
else if (sliderThatWasMoved == ftRange) |
||||
{ |
||||
//[UserSliderCode_ftRange] -- add your slider handling code here..
|
||||
//[/UserSliderCode_ftRange]
|
||||
} |
||||
else if (sliderThatWasMoved == brRange) |
||||
{ |
||||
//[UserSliderCode_brRange] -- add your slider handling code here..
|
||||
//[/UserSliderCode_brRange]
|
||||
} |
||||
else if (sliderThatWasMoved == atRange) |
||||
{ |
||||
//[UserSliderCode_atRange] -- add your slider handling code here..
|
||||
//[/UserSliderCode_atRange]
|
||||
} |
||||
|
||||
//[UsersliderValueChanged_Post]
|
||||
//[/UsersliderValueChanged_Post]
|
||||
} |
||||
|
||||
void ParamDialog::comboBoxChanged (ComboBox* comboBoxThatHasChanged) |
||||
{ |
||||
//[UsercomboBoxChanged_Pre]
|
||||
//[/UsercomboBoxChanged_Pre]
|
||||
|
||||
if (comboBoxThatHasChanged == sysexIn) |
||||
{ |
||||
//[UserComboBoxCode_sysexIn] -- add your combo box handling code here..
|
||||
//[/UserComboBoxCode_sysexIn]
|
||||
} |
||||
else if (comboBoxThatHasChanged == sysexOut) |
||||
{ |
||||
//[UserComboBoxCode_sysexOut] -- add your combo box handling code here..
|
||||
//[/UserComboBoxCode_sysexOut]
|
||||
} |
||||
else if (comboBoxThatHasChanged == engineReso) |
||||
{ |
||||
//[UserComboBoxCode_engineReso] -- add your combo box handling code here..
|
||||
//[/UserComboBoxCode_engineReso]
|
||||
} |
||||
|
||||
//[UsercomboBoxChanged_Post]
|
||||
//[/UsercomboBoxChanged_Post]
|
||||
} |
||||
|
||||
void ParamDialog::buttonClicked (Button* buttonThatWasClicked) |
||||
{ |
||||
//[UserbuttonClicked_Pre]
|
||||
//[/UserbuttonClicked_Pre]
|
||||
|
||||
if (buttonThatWasClicked == whlEg) |
||||
{ |
||||
//[UserButtonCode_whlEg] -- add your button handler code here..
|
||||
//[/UserButtonCode_whlEg]
|
||||
} |
||||
else if (buttonThatWasClicked == ftEg) |
||||
{ |
||||
//[UserButtonCode_ftEg] -- add your button handler code here..
|
||||
//[/UserButtonCode_ftEg]
|
||||
} |
||||
else if (buttonThatWasClicked == brEg) |
||||
{ |
||||
//[UserButtonCode_brEg] -- add your button handler code here..
|
||||
//[/UserButtonCode_brEg]
|
||||
} |
||||
else if (buttonThatWasClicked == atEg) |
||||
{ |
||||
//[UserButtonCode_atEg] -- add your button handler code here..
|
||||
//[/UserButtonCode_atEg]
|
||||
} |
||||
else if (buttonThatWasClicked == whlAmp) |
||||
{ |
||||
//[UserButtonCode_whlAmp] -- add your button handler code here..
|
||||
//[/UserButtonCode_whlAmp]
|
||||
} |
||||
else if (buttonThatWasClicked == ftAmp) |
||||
{ |
||||
//[UserButtonCode_ftAmp] -- add your button handler code here..
|
||||
//[/UserButtonCode_ftAmp]
|
||||
} |
||||
else if (buttonThatWasClicked == brAmp) |
||||
{ |
||||
//[UserButtonCode_brAmp] -- add your button handler code here..
|
||||
//[/UserButtonCode_brAmp]
|
||||
} |
||||
else if (buttonThatWasClicked == atAmp) |
||||
{ |
||||
//[UserButtonCode_atAmp] -- add your button handler code here..
|
||||
//[/UserButtonCode_atAmp]
|
||||
} |
||||
else if (buttonThatWasClicked == whlPitch) |
||||
{ |
||||
//[UserButtonCode_whlPitch] -- add your button handler code here..
|
||||
//[/UserButtonCode_whlPitch]
|
||||
} |
||||
else if (buttonThatWasClicked == ftPitch) |
||||
{ |
||||
//[UserButtonCode_ftPitch] -- add your button handler code here..
|
||||
//[/UserButtonCode_ftPitch]
|
||||
} |
||||
else if (buttonThatWasClicked == brPitch) |
||||
{ |
||||
//[UserButtonCode_brPitch] -- add your button handler code here..
|
||||
//[/UserButtonCode_brPitch]
|
||||
} |
||||
else if (buttonThatWasClicked == atPitch) |
||||
{ |
||||
//[UserButtonCode_atPitch] -- add your button handler code here..
|
||||
//[/UserButtonCode_atPitch]
|
||||
} |
||||
|
||||
//[UserbuttonClicked_Post]
|
||||
//[/UserbuttonClicked_Post]
|
||||
} |
||||
|
||||
|
||||
|
||||
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
|
||||
|
||||
void ParamDialog::setDialogValues(Controllers &c, SysexComm &mgr, int reso, bool showKey) { |
||||
pitchRange->setValue(c.values_[kControllerPitchRange]); |
||||
pitchStep->setValue(c.values_[kControllerPitchStep]); |
||||
sysexChl->setValue(mgr.getChl() + 1); |
||||
|
||||
whlRange->setValue(c.wheel.range); |
||||
whlPitch->setToggleState(c.wheel.pitch, dontSendNotification); |
||||
whlPitch->setToggleState(c.wheel.pitch, dontSendNotification); |
||||
whlAmp->setToggleState(c.wheel.amp, dontSendNotification); |
||||
whlEg->setToggleState(c.wheel.eg, dontSendNotification); |
||||
|
||||
ftRange->setValue(c.foot.range); |
||||
ftPitch->setToggleState(c.foot.pitch, dontSendNotification); |
||||
ftAmp->setToggleState(c.foot.amp, dontSendNotification); |
||||
ftEg->setToggleState(c.foot.eg, dontSendNotification); |
||||
|
||||
brRange->setValue(c.breath.range); |
||||
brPitch->setToggleState(c.breath.pitch, dontSendNotification); |
||||
brAmp->setToggleState(c.breath.amp, dontSendNotification); |
||||
brEg->setToggleState(c.breath.eg, dontSendNotification); |
||||
|
||||
atRange->setValue(c.at.range); |
||||
atPitch->setToggleState(c.at.pitch, dontSendNotification); |
||||
atAmp->setToggleState(c.at.amp, dontSendNotification); |
||||
atEg->setToggleState(c.at.eg, dontSendNotification); |
||||
|
||||
StringArray inputs = MidiInput::getDevices(); |
||||
int idx = inputs.indexOf(mgr.getInput()); |
||||
idx = idx == -1 ? 0 : idx + 1; |
||||
sysexIn->setSelectedItemIndex(idx); |
||||
|
||||
StringArray outputs = MidiOutput::getDevices(); |
||||
idx = outputs.indexOf(mgr.getOutput()); |
||||
idx = idx == -1 ? 0 : idx + 1; |
||||
sysexOut->setSelectedItemIndex(idx); |
||||
|
||||
engineReso->setSelectedItemIndex(reso); |
||||
showKeyboard->setToggleState(showKey, false); |
||||
} |
||||
|
||||
bool ParamDialog::getDialogValues(Controllers &c, SysexComm &mgr, int *reso, bool *showKey) { |
||||
bool ret = true; |
||||
|
||||
c.values_[kControllerPitchRange] = pitchRange->getValue(); |
||||
c.values_[kControllerPitchStep] = pitchStep->getValue(); |
||||
|
||||
c.wheel.range = whlRange->getValue(); |
||||
c.wheel.pitch = whlPitch->getToggleState(); |
||||
c.wheel.amp = whlAmp->getToggleState(); |
||||
c.wheel.eg = whlEg->getToggleState(); |
||||
|
||||
c.foot.range = ftRange->getValue(); |
||||
c.foot.pitch = ftPitch->getToggleState(); |
||||
c.foot.amp = ftAmp->getToggleState(); |
||||
c.foot.eg = ftEg->getToggleState(); |
||||
|
||||
c.breath.range = brRange->getValue(); |
||||
c.breath.pitch = brPitch->getToggleState(); |
||||
c.breath.amp = brAmp->getToggleState(); |
||||
c.breath.eg = brEg->getToggleState(); |
||||
|
||||
c.at.range = atRange->getValue(); |
||||
c.at.pitch = atPitch->getToggleState(); |
||||
c.at.amp = atAmp->getToggleState(); |
||||
c.at.eg = atEg->getToggleState(); |
||||
|
||||
c.refresh(); |
||||
|
||||
ret &= mgr.setInput(sysexIn->getItemText(sysexIn->getSelectedItemIndex())); |
||||
ret &= mgr.setOutput(sysexOut->getItemText(sysexOut->getSelectedItemIndex())); |
||||
mgr.setChl(sysexChl->getValue() - 1); |
||||
|
||||
*reso = engineReso->getSelectedItemIndex(); |
||||
*showKey = showKeyboard->getToggleState(); |
||||
return ret; |
||||
} |
||||
|
||||
//[/MiscUserCode]
|
||||
|
||||
|
||||
//==============================================================================
|
||||
#if 0 |
||||
/* -- Introjucer information section --
|
||||
|
||||
This is where the Introjucer stores the metadata that describe this GUI layout, so |
||||
make changes in here at your peril! |
||||
|
||||
BEGIN_JUCER_METADATA |
||||
|
||||
<JUCER_COMPONENT documentType="Component" className="ParamDialog" componentName="" |
||||
parentClasses="public Component" constructorParams="" variableInitialisers="" |
||||
snapPixels="8" snapActive="1" snapShown="1" overlayOpacity="0.330" |
||||
fixedSize="1" initialWidth="710" initialHeight="350"> |
||||
<BACKGROUND backgroundColour="ff3c322f"> |
||||
<TEXT pos="20 16 276 23" fill="solid: ffffffff" hasStroke="0" text="Pitch Bend Range" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<TEXT pos="20 56 276 23" fill="solid: ffffffff" hasStroke="0" text="Pitch Bend Step" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<TEXT pos="20 224 131 23" fill="solid: ffffffff" hasStroke="0" text="DX7 In" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<TEXT pos="20 264 131 23" fill="solid: ffffffff" hasStroke="0" text="DX7 Out" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<TEXT pos="20 304 245 23" fill="solid: ffffffff" hasStroke="0" text="DX7 Channel" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<TEXT pos="20 156 276 23" fill="solid: ffffffff" hasStroke="0" text="Engine Resolution" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<RECT pos="22 138 306 1" fill="solid: ff000000" hasStroke="0"/> |
||||
<RECT pos="22 195 306 1" fill="solid: ff000000" hasStroke="0"/> |
||||
<TEXT pos="20 96 276 23" fill="solid: ffffffff" hasStroke="0" text="Show Keyboard" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<RECT pos="352 11 1 325" fill="solid: ff000000" hasStroke="0"/> |
||||
<TEXT pos="368 16 276 23" fill="solid: ffffffff" hasStroke="0" text="Wheel" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<TEXT pos="368 96 276 23" fill="solid: ffffffff" hasStroke="0" text="Foot" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<TEXT pos="368 56 276 23" fill="solid: ffffffff" hasStroke="0" text="Breath" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<TEXT pos="368 136 276 23" fill="solid: ffffffff" hasStroke="0" text="After Touch" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<TEXT pos="533 163 48 23" fill="solid: ffffffff" hasStroke="0" text="PITCH" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<TEXT pos="589 163 48 23" fill="solid: ffffffff" hasStroke="0" text="AMP" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
<TEXT pos="645 163 48 23" fill="solid: ffffffff" hasStroke="0" text="EG BIAS" |
||||
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/> |
||||
</BACKGROUND> |
||||
<SLIDER name="pitchRange" id="7409be5a8dfaa91" memberName="pitchRange" |
||||
virtualName="" explicitFocusOrder="0" pos="264 16 72 24" min="0" |
||||
max="12" int="1" style="RotaryVerticalDrag" textBoxPos="TextBoxLeft" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="pitchStep" id="b86af4b792e768ca" memberName="pitchStep" |
||||
virtualName="" explicitFocusOrder="0" pos="264 56 72 24" min="0" |
||||
max="12" int="1" style="RotaryVerticalDrag" textBoxPos="TextBoxLeft" |
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<COMBOBOX name="sysexIn" id="3750642d8b5be11" memberName="sysexIn" virtualName="" |
||||
explicitFocusOrder="0" pos="104 224 224 24" editable="0" layout="33" |
||||
items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/> |
||||
<COMBOBOX name="sysexOut" id="44730115841c2214" memberName="sysexOut" virtualName="" |
||||
explicitFocusOrder="0" pos="104 264 224 24" editable="0" layout="33" |
||||
items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/> |
||||
<SLIDER name="sysexChl" id="7fdc8830f90a7c86" memberName="sysexChl" virtualName="" |
||||
explicitFocusOrder="0" pos="264 304 72 24" min="1" max="16" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="TextBoxLeft" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<COMBOBOX name="new combo box" id="4087ff978c3d9e8d" memberName="engineReso" |
||||
virtualName="" explicitFocusOrder="0" pos="160 156 168 24" editable="0" |
||||
layout="33" items="Modern (24-bit) Mark I OPL Series" |
||||
textWhenNonSelected="" textWhenNoItems="(no choices)"/> |
||||
<TOGGLEBUTTON name="showKeyboard" id="c963d2cb8e49ffd7" memberName="showKeyboard" |
||||
virtualName="" explicitFocusOrder="0" pos="264 96 56 24" buttonText="" |
||||
connectedEdges="0" needsCallback="0" radioGroupId="0" state="0"/> |
||||
<SLIDER name="whlRange" id="3d6522f5f581e580" memberName="whlRange" virtualName="" |
||||
explicitFocusOrder="0" pos="448 16 72 24" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="TextBoxLeft" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="ftRange" id="cf553f74c3fb0d12" memberName="ftRange" virtualName="" |
||||
explicitFocusOrder="0" pos="448 56 72 24" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="TextBoxLeft" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="brRange" id="c4aa6814f75016a7" memberName="brRange" virtualName="" |
||||
explicitFocusOrder="0" pos="448 96 72 24" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="TextBoxLeft" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<SLIDER name="atRange" id="d0aa1ebb24284577" memberName="atRange" virtualName="" |
||||
explicitFocusOrder="0" pos="448 136 72 24" min="0" max="99" int="1" |
||||
style="RotaryVerticalDrag" textBoxPos="TextBoxLeft" textBoxEditable="1" |
||||
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> |
||||
<TOGGLEBUTTON name="whlEg" id="d8242ae592c912a" memberName="whlEg" virtualName="" |
||||
explicitFocusOrder="0" pos="640 16 56 24" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<TOGGLEBUTTON name="ftEg" id="69d816607bd71cb0" memberName="ftEg" virtualName="" |
||||
explicitFocusOrder="0" pos="640 56 56 24" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<TOGGLEBUTTON name="brEg" id="ba89ae54d676983f" memberName="brEg" virtualName="" |
||||
explicitFocusOrder="0" pos="640 96 56 24" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<TOGGLEBUTTON name="atEg" id="371934a58ce5f1bc" memberName="atEg" virtualName="" |
||||
explicitFocusOrder="0" pos="640 136 56 24" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<TOGGLEBUTTON name="whlAmp" id="3d4e46e63c3ddd86" memberName="whlAmp" virtualName="" |
||||
explicitFocusOrder="0" pos="584 16 56 24" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<TOGGLEBUTTON name="ftAmp" id="f631892e209b094a" memberName="ftAmp" virtualName="" |
||||
explicitFocusOrder="0" pos="584 56 56 24" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<TOGGLEBUTTON name="brAmp" id="d0a68d37220638f1" memberName="brAmp" virtualName="" |
||||
explicitFocusOrder="0" pos="584 96 56 24" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<TOGGLEBUTTON name="atAmp" id="4220c7b22e7845ea" memberName="atAmp" virtualName="" |
||||
explicitFocusOrder="0" pos="584 136 56 24" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<TOGGLEBUTTON name="whlPitch" id="b7a626ec1e45af16" memberName="whlPitch" virtualName="" |
||||
explicitFocusOrder="0" pos="528 16 56 24" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<TOGGLEBUTTON name="ftPitch" id="1acedf6f16a5a3" memberName="ftPitch" virtualName="" |
||||
explicitFocusOrder="0" pos="528 56 56 24" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<TOGGLEBUTTON name="brPitch" id="23fa82533e004b96" memberName="brPitch" virtualName="" |
||||
explicitFocusOrder="0" pos="528 96 56 24" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
<TOGGLEBUTTON name="atPitch" id="43805c6a4673e291" memberName="atPitch" virtualName="" |
||||
explicitFocusOrder="0" pos="528 136 56 24" buttonText="" connectedEdges="0" |
||||
needsCallback="1" radioGroupId="0" state="0"/> |
||||
</JUCER_COMPONENT> |
||||
|
||||
END_JUCER_METADATA |
||||
*/ |
||||
#endif |
||||
|
||||
|
||||
//[EndFile] You can add extra defines here...
|
||||
//[/EndFile]
|
@ -1,100 +0,0 @@ |
||||
/*
|
||||
============================================================================== |
||||
|
||||
This is an automatically generated GUI class created by the Introjucer! |
||||
|
||||
Be careful when adding custom code to these files, as only the code within |
||||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded |
||||
and re-saved. |
||||
|
||||
Created with Introjucer version: 3.2.0 |
||||
|
||||
------------------------------------------------------------------------------ |
||||
|
||||
The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions" |
||||
Copyright (c) 2015 - ROLI Ltd. |
||||
|
||||
============================================================================== |
||||
*/ |
||||
|
||||
#ifndef __JUCE_HEADER_D00F97AD887A66__ |
||||
#define __JUCE_HEADER_D00F97AD887A66__ |
||||
|
||||
//[Headers] -- You can add your own extra header files here --
|
||||
#include "JuceHeader.h" |
||||
#include "msfa/controllers.h" |
||||
#include "SysexComm.h" |
||||
//[/Headers]
|
||||
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
//[Comments]
|
||||
An auto-generated component, created by the Introjucer. |
||||
|
||||
Describe your class and how it works here! |
||||
//[/Comments]
|
||||
*/ |
||||
class ParamDialog : public Component, |
||||
public SliderListener, |
||||
public ComboBoxListener, |
||||
public ButtonListener |
||||
{ |
||||
public: |
||||
//==============================================================================
|
||||
ParamDialog (); |
||||
~ParamDialog(); |
||||
|
||||
//==============================================================================
|
||||
//[UserMethods] -- You can add your own custom methods in this section.
|
||||
void setDialogValues(Controllers &c, SysexComm &mgr, int reso, bool showKeyboard); |
||||
bool getDialogValues(Controllers &c, SysexComm &mgr, int *reso, bool *showKeyboard); |
||||
//[/UserMethods]
|
||||
|
||||
void paint (Graphics& g); |
||||
void resized(); |
||||
void sliderValueChanged (Slider* sliderThatWasMoved); |
||||
void comboBoxChanged (ComboBox* comboBoxThatHasChanged); |
||||
void buttonClicked (Button* buttonThatWasClicked); |
||||
|
||||
|
||||
|
||||
private: |
||||
//[UserVariables] -- You can add your own custom variables in this section.
|
||||
//[/UserVariables]
|
||||
|
||||
//==============================================================================
|
||||
ScopedPointer<Slider> pitchRange; |
||||
ScopedPointer<Slider> pitchStep; |
||||
ScopedPointer<ComboBox> sysexIn; |
||||
ScopedPointer<ComboBox> sysexOut; |
||||
ScopedPointer<Slider> sysexChl; |
||||
ScopedPointer<ComboBox> engineReso; |
||||
ScopedPointer<ToggleButton> showKeyboard; |
||||
ScopedPointer<Slider> whlRange; |
||||
ScopedPointer<Slider> ftRange; |
||||
ScopedPointer<Slider> brRange; |
||||
ScopedPointer<Slider> atRange; |
||||
ScopedPointer<ToggleButton> whlEg; |
||||
ScopedPointer<ToggleButton> ftEg; |
||||
ScopedPointer<ToggleButton> brEg; |
||||
ScopedPointer<ToggleButton> atEg; |
||||
ScopedPointer<ToggleButton> whlAmp; |
||||
ScopedPointer<ToggleButton> ftAmp; |
||||
ScopedPointer<ToggleButton> brAmp; |
||||
ScopedPointer<ToggleButton> atAmp; |
||||
ScopedPointer<ToggleButton> whlPitch; |
||||
ScopedPointer<ToggleButton> ftPitch; |
||||
ScopedPointer<ToggleButton> brPitch; |
||||
ScopedPointer<ToggleButton> atPitch; |
||||
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParamDialog) |
||||
}; |
||||
|
||||
//[EndFile] You can add extra defines here...
|
||||
//[/EndFile]
|
||||
|
||||
#endif // __JUCE_HEADER_D00F97AD887A66__
|
@ -1,452 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2014-2016 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 3 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 <time.h> |
||||
|
||||
#include "PluginParam.h" |
||||
#include "PluginProcessor.h" |
||||
#include "PluginData.h" |
||||
#include "Dexed.h" |
||||
|
||||
#include <fstream> |
||||
using namespace ::std; |
||||
|
||||
uint8_t sysexChecksum(const uint8_t *sysex, int size) { |
||||
int sum = 0; |
||||
int i; |
||||
|
||||
for (i = 0; i < size; sum -= sysex[i++]); |
||||
return sum & 0x7F; |
||||
} |
||||
|
||||
void exportSysexPgm(uint8_t *dest, uint8_t *src) { |
||||
uint8_t header[] = { 0xF0, 0x43, 0x00, 0x00, 0x01, 0x1B }; |
||||
|
||||
memcpy(dest, header, 6); |
||||
|
||||
// copy 1 unpacked voices
|
||||
memcpy(dest+6, src, 155); |
||||
|
||||
// put some logic to "mute" an operator if the level is 0
|
||||
|
||||
// make checksum for dump
|
||||
uint8_t footer[] = { sysexChecksum(src, 155), 0xF7 }; |
||||
|
||||
memcpy(dest+161, footer, 2); |
||||
} |
||||
|
||||
/**
|
||||
* Pack a program into a 32 packed sysex |
||||
*/ |
||||
void Cartridge::packProgram(uint8_t *src, int idx, String name, char *opSwitch) { |
||||
uint8_t *bulk = voiceData + 6 + (idx * 128); |
||||
|
||||
for(int op = 0; op < 6; op++) { |
||||
// eg rate and level, brk pt, depth, scaling
|
||||
memcpy(bulk + op * 17, src + op * 21, 11); |
||||
int pp = op*17; |
||||
int up = op*21; |
||||
|
||||
// left curves
|
||||
bulk[pp+11] = (src[up+11]&0x03) | ((src[up+12]&0x03) << 2); |
||||
bulk[pp+12] = (src[up+13]&0x07) | ((src[up+20]&0x0f) << 3); |
||||
// kvs_ams
|
||||
bulk[pp+13] = (src[up+14]&0x03) | ((src[up+15]&0x07) << 2); |
||||
// output lvl
|
||||
if ( opSwitch[op] == '0' ) |
||||
bulk[pp+14] = 0; |
||||
else |
||||
bulk[pp+14] = src[up+16]; |
||||
// fcoarse_mode
|
||||
bulk[pp+15] = (src[up+17]&0x01) | ((src[up+18]&0x1f) << 1); |
||||
// fine freq
|
||||
bulk[pp+16] = src[up+19]; |
||||
} |
||||
memcpy(bulk + 102, src + 126, 9); // pitch env, algo
|
||||
bulk[111] = (src[135]&0x07) | ((src[136]&0x01) << 3); |
||||
memcpy(bulk + 112, src + 137, 4); // lfo
|
||||
bulk[116] = (src[141]&0x01) | (((src[142]&0x07) << 1) | ((src[143]&0x07) << 4)); |
||||
bulk[117] = src[144]; |
||||
|
||||
int eos = 0; |
||||
|
||||
for(int i=0; i < 10; i++) { |
||||
char c = (char) name[i]; |
||||
if ( c == 0 ) |
||||
eos = 1; |
||||
if ( eos ) { |
||||
bulk[118+i] = ' '; |
||||
continue; |
||||
} |
||||
c = c < 32 ? ' ' : c; |
||||
c = c > 127 ? ' ' : c; |
||||
bulk[118+i] = c; |
||||
} |
||||
} |
||||
|
||||
/**
|
||||
* This function normalize data that comes from corrupted sysex. |
||||
* It used to avoid engine crashing upon extrem values |
||||
*/ |
||||
char normparm(char value, char max, int id) { |
||||
if ( value <= max && value >= 0 ) |
||||
return value; |
||||
|
||||
// if this is beyond the max, we expect a 0-255 range, normalize this
|
||||
// to the expected return value; and this value as a random data.
|
||||
|
||||
value = abs(value); |
||||
|
||||
char v = ((float)value)/255 * max; |
||||
|
||||
return v; |
||||
} |
||||
|
||||
void Cartridge::unpackProgram(uint8_t *unpackPgm, int idx) { |
||||
// TODO put this in uint8_t :D
|
||||
char *bulk = (char *)voiceData + 6 + (idx * 128); |
||||
|
||||
for (int op = 0; op < 6; op++) { |
||||
// eg rate and level, brk pt, depth, scaling
|
||||
|
||||
for(int i=0; i<11; i++) { |
||||
unpackPgm[op * 21 + i] = normparm(bulk[op * 17 + i], 99, i); |
||||
} |
||||
|
||||
memcpy(unpackPgm + op * 21, bulk + op * 17, 11); |
||||
char leftrightcurves = bulk[op * 17 + 11]; |
||||
unpackPgm[op * 21 + 11] = leftrightcurves & 3; |
||||
unpackPgm[op * 21 + 12] = (leftrightcurves >> 2) & 3; |
||||
char detune_rs = bulk[op * 17 + 12]; |
||||
unpackPgm[op * 21 + 13] = detune_rs & 7; |
||||
char kvs_ams = bulk[op * 17 + 13]; |
||||
unpackPgm[op * 21 + 14] = kvs_ams & 3; |
||||
unpackPgm[op * 21 + 15] = kvs_ams >> 2; |
||||
unpackPgm[op * 21 + 16] = bulk[op * 17 + 14]; // output level
|
||||
char fcoarse_mode = bulk[op * 17 + 15]; |
||||
unpackPgm[op * 21 + 17] = fcoarse_mode & 1; |
||||
unpackPgm[op * 21 + 18] = fcoarse_mode >> 1; |
||||
unpackPgm[op * 21 + 19] = bulk[op * 17 + 16]; // fine freq
|
||||
unpackPgm[op * 21 + 20] = detune_rs >> 3; |
||||
} |
||||
|
||||
for (int i=0; i<8; i++) { |
||||
unpackPgm[126+i] = normparm(bulk[102+i], 99, 126+i); |
||||
} |
||||
unpackPgm[134] = normparm(bulk[110], 31, 134); |
||||
|
||||
char oks_fb = bulk[111]; |
||||
unpackPgm[135] = oks_fb & 7; |
||||
unpackPgm[136] = oks_fb >> 3; |
||||
memcpy(unpackPgm + 137, bulk + 112, 4); // lfo
|
||||
char lpms_lfw_lks = bulk[116]; |
||||
unpackPgm[141] = lpms_lfw_lks & 1; |
||||
unpackPgm[142] = (lpms_lfw_lks >> 1) & 7; |
||||
unpackPgm[143] = lpms_lfw_lks >> 4; |
||||
memcpy(unpackPgm + 144, bulk + 117, 11); // transpose, name
|
||||
unpackPgm[155] = 1; // operator on/off (DEPRECATED)
|
||||
unpackPgm[156] = 1; |
||||
unpackPgm[157] = 1; |
||||
unpackPgm[158] = 1; |
||||
unpackPgm[159] = 1; |
||||
unpackPgm[160] = 1; |
||||
} |
||||
|
||||
void DexedAudioProcessor::loadCartridge(Cartridge &sysex) { |
||||
currentCart = sysex; |
||||
currentCart.getProgramNames(programNames); |
||||
} |
||||
|
||||
void DexedAudioProcessor::updateProgramFromSysex(const uint8_t *rawdata) { |
||||
memcpy(data, rawdata, 161); |
||||
lfo.reset(data + 137); |
||||
triggerAsyncUpdate(); |
||||
} |
||||
|
||||
void DexedAudioProcessor::setupStartupCart() { |
||||
File startup = dexedCartDir.getChildFile("Dexed_01.syx"); |
||||
|
||||
if ( currentCart.load(startup) != -1 ) |
||||
return; |
||||
|
||||
// The user deleted the file :/, load from the builtin zip file.
|
||||
MemoryInputStream *mis = new MemoryInputStream(BinaryData::builtin_pgm_zip, BinaryData::builtin_pgm_zipSize, false); |
||||
ZipFile *builtin_pgm = new ZipFile(mis, true); |
||||
InputStream *is = builtin_pgm->createStreamForEntry(builtin_pgm->getIndexOfFileName(("Dexed_01.syx"))); |
||||
Cartridge init; |
||||
|
||||
if ( init.load(*is) != -1 ) |
||||
loadCartridge(init); |
||||
|
||||
delete is; |
||||
delete builtin_pgm; |
||||
} |
||||
|
||||
void DexedAudioProcessor::resetToInitVoice() { |
||||
const char init_voice[] = |
||||
{ 99, 99, 99, 99, 99, 99, 99, 00, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, |
||||
99, 99, 99, 99, 99, 99, 99, 00, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, |
||||
99, 99, 99, 99, 99, 99, 99, 00, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, |
||||
99, 99, 99, 99, 99, 99, 99, 00, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, |
||||
99, 99, 99, 99, 99, 99, 99, 00, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, |
||||
99, 99, 99, 99, 99, 99, 99, 00, 39, 0, 0, 0, 0, 0, 0, 0, 99, 0, 1, 0, 7, |
||||
99, 99, 99, 99, 50, 50, 50, 50, 0, 0, 1, 35, 0, 0, 0, 1, 0, 3, 24, |
||||
73, 78, 73, 84, 32, 86, 79, 73, 67, 69 }; |
||||
|
||||
for(int i=0;i<sizeof(init_voice);i++) { |
||||
data[i] = init_voice[i]; |
||||
} |
||||
panic(); |
||||
triggerAsyncUpdate(); |
||||
} |
||||
|
||||
void DexedAudioProcessor::copyToClipboard(int srcOp) { |
||||
memcpy(clipboard, data, 161); |
||||
clipboardContent = srcOp; |
||||
} |
||||
|
||||
void DexedAudioProcessor::pasteOpFromClipboard(int destOp) { |
||||
memcpy(data+(destOp*21), clipboard+(clipboardContent*21), 21); |
||||
triggerAsyncUpdate(); |
||||
} |
||||
|
||||
void DexedAudioProcessor::pasteEnvFromClipboard(int destOp) { |
||||
memcpy(data+(destOp*21), clipboard+(clipboardContent*21), 8); |
||||
triggerAsyncUpdate(); |
||||
} |
||||
|
||||
void DexedAudioProcessor::sendCurrentSysexProgram() { |
||||
uint8_t raw[163]; |
||||
|
||||
exportSysexPgm(raw, data); |
||||
if ( sysexComm.isOutputActive() ) { |
||||
sysexComm.send(MidiMessage(raw, 163)); |
||||
} |
||||
} |
||||
|
||||
void DexedAudioProcessor::sendCurrentSysexCartridge() { |
||||
uint8_t raw[4104]; |
||||
|
||||
currentCart.saveVoice(raw); |
||||
if ( sysexComm.isOutputActive() ) { |
||||
sysexComm.send(MidiMessage(raw, 4104)); |
||||
} |
||||
} |
||||
|
||||
void DexedAudioProcessor::sendSysexCartridge(File cart) { |
||||
if ( ! sysexComm.isOutputActive() ) |
||||
return; |
||||
|
||||
FileInputStream *fis = cart.createInputStream(); |
||||
if ( fis == NULL ) { |
||||
String f = cart.getFullPathName(); |
||||
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, |
||||
"Error", |
||||
"Unable to open: " + f); |
||||
} |
||||
|
||||
uint8 syx_data[65535]; |
||||
int sz = fis->read(syx_data, 65535); |
||||
delete fis; |
||||
|
||||
if (syx_data[0] != 0xF0) { |
||||
String f = cart.getFullPathName(); |
||||
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, |
||||
"Error", |
||||
"File: " + f + " doesn't seems to contain any sysex data"); |
||||
return; |
||||
} |
||||
sysexComm.send(MidiMessage(syx_data, sz)); |
||||
} |
||||
|
||||
|
||||
bool DexedAudioProcessor::hasClipboardContent() { |
||||
return clipboardContent != -1; |
||||
} |
||||
|
||||
//==============================================================================
|
||||
void DexedAudioProcessor::getStateInformation(MemoryBlock& destData) { |
||||
// You should use this method to store your parameters in the memory block.
|
||||
// You could do that either as raw data, or use the XML or ValueTree classes
|
||||
// as intermediaries to make it easy to save and load complex data.
|
||||
|
||||
// used to SAVE plugin state
|
||||
|
||||
XmlElement dexedState("dexedState"); |
||||
XmlElement *dexedBlob = dexedState.createNewChildElement("dexedBlob"); |
||||
|
||||
dexedState.setAttribute("cutoff", fx.uiCutoff); |
||||
dexedState.setAttribute("reso", fx.uiReso); |
||||
dexedState.setAttribute("gain", fx.uiGain); |
||||
dexedState.setAttribute("currentProgram", currentProgram); |
||||
dexedState.setAttribute("monoMode", monoMode); |
||||
dexedState.setAttribute("engineType", (int) engineType); |
||||
dexedState.setAttribute("masterTune", controllers.masterTune); |
||||
dexedState.setAttribute("opSwitch", controllers.opSwitch); |
||||
|
||||
char mod_cfg[15]; |
||||
controllers.wheel.setConfig(mod_cfg); |
||||
dexedState.setAttribute("wheelMod", mod_cfg); |
||||
controllers.foot.setConfig(mod_cfg); |
||||
dexedState.setAttribute("footMod", mod_cfg); |
||||
controllers.breath.setConfig(mod_cfg); |
||||
dexedState.setAttribute("breathMod", mod_cfg); |
||||
controllers.at.setConfig(mod_cfg); |
||||
dexedState.setAttribute("aftertouchMod", mod_cfg); |
||||
|
||||
if ( activeFileCartridge.exists() ) |
||||
dexedState.setAttribute("activeFileCartridge", activeFileCartridge.getFullPathName()); |
||||
|
||||
NamedValueSet blobSet; |
||||
blobSet.set("sysex", var((void *) currentCart.getVoiceSysex(), 4104)); |
||||
blobSet.set("program", var((void *) &data, 161)); |
||||
|
||||
blobSet.copyToXmlAttributes(*dexedBlob); |
||||
copyXmlToBinary(dexedState, destData); |
||||
} |
||||
|
||||
void DexedAudioProcessor::setStateInformation(const void* source, int sizeInBytes) { |
||||
// You should use this method to restore your parameters from this memory block,
|
||||
// whose contents will have been created by the getStateInformation() call.
|
||||
|
||||
// used to LOAD plugin state
|
||||
ScopedPointer<XmlElement> root(getXmlFromBinary(source, sizeInBytes)); |
||||
|
||||
if (root == nullptr) { |
||||
TRACE("unkown state format"); |
||||
return; |
||||
} |
||||
|
||||
fx.uiCutoff = root->getDoubleAttribute("cutoff"); |
||||
fx.uiReso = root->getDoubleAttribute("reso"); |
||||
fx.uiGain = root->getDoubleAttribute("gain"); |
||||
currentProgram = root->getIntAttribute("currentProgram"); |
||||
|
||||
String opSwitchValue = root->getStringAttribute("opSwitch"); |
||||
if ( opSwitchValue.length() != 6 ) { |
||||
strcpy(controllers.opSwitch, "111111"); |
||||
} else { |
||||
strncpy(controllers.opSwitch, opSwitchValue.toRawUTF8(), 6); |
||||
} |
||||
|
||||
controllers.wheel.parseConfig(root->getStringAttribute("wheelMod").toRawUTF8()); |
||||
controllers.foot.parseConfig(root->getStringAttribute("footMod").toRawUTF8()); |
||||
controllers.breath.parseConfig(root->getStringAttribute("breathMod").toRawUTF8()); |
||||
controllers.at.parseConfig(root->getStringAttribute("aftertouchMod").toRawUTF8()); |
||||
|
||||
setEngineType(root->getIntAttribute("engineType", 1)); |
||||
monoMode = root->getIntAttribute("monoMode", 0); |
||||
controllers.masterTune = root->getIntAttribute("masterTune", 0); |
||||
|
||||
File possibleCartridge = File(root->getStringAttribute("activeFileCartridge")); |
||||
if ( possibleCartridge.exists() ) |
||||
activeFileCartridge = possibleCartridge; |
||||
|
||||
XmlElement *dexedBlob = root->getChildByName("dexedBlob"); |
||||
if ( dexedBlob == NULL ) { |
||||
TRACE("dexedBlob element not found"); |
||||
return; |
||||
} |
||||
|
||||
NamedValueSet blobSet; |
||||
blobSet.setFromXmlAttributes(*dexedBlob); |
||||
|
||||
var sysex_blob = blobSet["sysex"]; |
||||
var program = blobSet["program"]; |
||||
|
||||
if ( sysex_blob.isVoid() || program.isVoid() ) { |
||||
TRACE("unkown serialized blob data"); |
||||
return; |
||||
} |
||||
|
||||
Cartridge cart; |
||||
cart.load((uint8 *)sysex_blob.getBinaryData()->getData(), 4104); |
||||
loadCartridge(cart); |
||||
memcpy(data, program.getBinaryData()->getData(), 161); |
||||
|
||||
lastStateSave = (long) time(NULL); |
||||
TRACE("setting VST STATE"); |
||||
updateUI(); |
||||
} |
||||
|
||||
File DexedAudioProcessor::dexedAppDir; |
||||
File DexedAudioProcessor::dexedCartDir; |
||||
|
||||
void DexedAudioProcessor::resolvAppDir() { |
||||
#if JUCE_MAC || JUCE_IOS |
||||
File parent = File::getSpecialLocation(File::currentExecutableFile).getParentDirectory().getParentDirectory().getParentDirectory().getSiblingFile("Dexed"); |
||||
|
||||
if ( parent.isDirectory() ) { |
||||
dexedAppDir = parent; |
||||
} else { |
||||
dexedAppDir = File("~/Library/Application Support/DigitalSuburban/Dexed"); |
||||
} |
||||
#elif JUCE_WINDOWS |
||||
if ( File::getSpecialLocation(File::currentExecutableFile).getSiblingFile("Dexed").isDirectory() ) { |
||||
dexedAppDir = File::getSpecialLocation(File::currentExecutableFile).getSiblingFile("Dexed"); |
||||
} else { |
||||
dexedAppDir = File::getSpecialLocation(File::userApplicationDataDirectory).getChildFile("DigitalSuburban").getChildFile("Dexed"); |
||||
} |
||||
#else |
||||
if ( File::getSpecialLocation(File::currentExecutableFile).getSiblingFile("Dexed").isDirectory() ) { |
||||
dexedAppDir = File::getSpecialLocation(File::currentExecutableFile).getSiblingFile("Dexed"); |
||||
} else { |
||||
char *xdgHome = getenv("XDG_DATA_HOME"); |
||||
if ( xdgHome == nullptr ) { |
||||
dexedAppDir = File("~/.local/share").getChildFile("DigitalSuburban").getChildFile("Dexed"); |
||||
} else { |
||||
dexedAppDir = File(xdgHome).getChildFile("DigitalSuburban").getChildFile("Dexed"); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
if ( ! dexedAppDir.exists() ) { |
||||
dexedAppDir.createDirectory(); |
||||
// ==========================================================================
|
||||
// For older versions, we move the Dexed.xml config file
|
||||
// This code will be removed in 0.9.0
|
||||
File cfgFile = dexedAppDir.getParentDirectory().getChildFile("Dexed.xml"); |
||||
if ( cfgFile.exists() ) |
||||
cfgFile.moveFileTo(dexedAppDir.getChildFile("Dexed.xml")); |
||||
// *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
// ==========================================================================
|
||||
} |
||||
|
||||
dexedCartDir = dexedAppDir.getChildFile("Cartridges"); |
||||
|
||||
if ( ! dexedCartDir.exists() ) { |
||||
// Initial setup, we unzip the built-in cartridges
|
||||
dexedCartDir.createDirectory(); |
||||
File synprezFmDir = dexedCartDir.getChildFile("SynprezFM"); |
||||
synprezFmDir.createDirectory(); |
||||
|
||||
MemoryInputStream *mis = new MemoryInputStream(BinaryData::builtin_pgm_zip, BinaryData::builtin_pgm_zipSize, false); |
||||
ZipFile *builtin_pgm = new ZipFile(mis, true); |
||||
|
||||
for(int i=0;i<builtin_pgm->getNumEntries();i++) { |
||||
if ( builtin_pgm->getEntry(i)->filename == "Dexed_01.syx" ) { |
||||
builtin_pgm->uncompressEntry(i, dexedCartDir); |
||||
} else { |
||||
builtin_pgm->uncompressEntry(i, synprezFmDir); |
||||
} |
||||
} |
||||
delete builtin_pgm; |
||||
} |
||||
} |
@ -1,247 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2014-2016 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 3 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 |
||||
* |
||||
*/ |
||||
|
||||
#ifndef PLUGINDATA_H_INCLUDED |
||||
#define PLUGINDATA_H_INCLUDED |
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h" |
||||
|
||||
#include <stdint.h> |
||||
#include <string.h> |
||||
#include "Dexed.h" |
||||
|
||||
uint8_t sysexChecksum(const uint8_t *sysex, int size); |
||||
void exportSysexPgm(uint8_t *dest, uint8_t *src); |
||||
|
||||
#define SYSEX_HEADER { 0xF0, 0x43, 0x00, 0x09, 0x20, 0x00 } |
||||
#define SYSEX_SIZE 4104 |
||||
|
||||
class Cartridge { |
||||
uint8_t voiceData[SYSEX_SIZE]; |
||||
uint8_t perfData[SYSEX_SIZE]; |
||||
|
||||
void setHeader() { |
||||
uint8 voiceHeader[] = SYSEX_HEADER; |
||||
memcpy(voiceData, voiceHeader, 6); |
||||
voiceData[4102] = sysexChecksum(voiceData+6, 4096); |
||||
voiceData[4103] = 0xF7; |
||||
} |
||||
|
||||
public: |
||||
Cartridge() { } |
||||
|
||||
Cartridge(const Cartridge &cpy) { |
||||
memcpy(voiceData, cpy.voiceData, SYSEX_SIZE); |
||||
memcpy(perfData, cpy.perfData, SYSEX_SIZE); |
||||
} |
||||
|
||||
static String normalizePgmName(const char *sysexName) { |
||||
char buffer[11]; |
||||
|
||||
memcpy(buffer, sysexName, 10); |
||||
|
||||
for (int j = 0; j < 10; j++) { |
||||
char c = (unsigned char) buffer[j]; |
||||
switch (c) { |
||||
case 92: |
||||
c = 'Y'; |
||||
break; /* yen */ |
||||
case 126: |
||||
c = '>'; |
||||
break; /* >> */ |
||||
case 127: |
||||
c = '<'; |
||||
break; /* << */ |
||||
default: |
||||
if (c < 32 || c > 127) |
||||
c = 32; |
||||
break; |
||||
} |
||||
buffer[j] = c; |
||||
} |
||||
buffer[10] = 0; |
||||
|
||||
return String(buffer); |
||||
} |
||||
|
||||
int load(File f) { |
||||
FileInputStream *fis = f.createInputStream(); |
||||
if ( fis == NULL ) |
||||
return -1; |
||||
int rc = load(*fis); |
||||
delete fis; |
||||
return rc; |
||||
} |
||||
|
||||
/**
|
||||
* Loads sysex stream |
||||
* Returns 0 if it was parsed sucessfully |
||||
* Returns -1 if it cannot open the stream |
||||
*/ |
||||
int load(InputStream &fis) { |
||||
uint8 buffer[65535]; |
||||
int sz = fis.read(buffer, 65535); |
||||
if ( sz == 0 ) |
||||
return -1; |
||||
return load(buffer, sz); |
||||
} |
||||
|
||||
/**
|
||||
* Loads sysex buffer |
||||
* Returns 0 if it was parsed sucessfully |
||||
* Returns 1 if sysex checksum didn't match |
||||
* Returns 2 if no sysex data found, probably random data |
||||
*/ |
||||
int load(const uint8_t *stream, int size) { |
||||
const uint8 voiceHeaderBroken[] = { 0xF0, 0x43, 0x00, 0x00, 0x20, 0x00 }; |
||||
// I've added a stupid bug that saved the wrong sysex data for dx7 sysex (0.9.1)
|
||||
// This is there to support this version. One day we will be able to remove this. :(
|
||||
|
||||
uint8 voiceHeader[] = SYSEX_HEADER; |
||||
uint8 tmp[65535]; |
||||
uint8 *pos = tmp; |
||||
int status = 3; |
||||
|
||||
if ( size > 65535 ) |
||||
size = 65535; |
||||
|
||||
memcpy(tmp, stream, size); |
||||
|
||||
while(size >= 4104) { |
||||
// random data
|
||||
if ( pos[0] != 0xF0 ) { |
||||
if ( status != 3 ) |
||||
return status; |
||||
memcpy(voiceData, pos+6, 4096); |
||||
return 2; |
||||
} |
||||
|
||||
pos[3] = 0; |
||||
if ( memcmp(pos, voiceHeader, 6) == 0 || memcmp(pos, voiceHeaderBroken, 6) == 0) { |
||||
memcpy(voiceData, pos, SYSEX_SIZE); |
||||
if ( sysexChecksum(voiceData + 6, 4096) == pos[4102] ) |
||||
status = 0; |
||||
else |
||||
status = 1; |
||||
size -= 4104; |
||||
pos += 4104; |
||||
continue; |
||||
} |
||||
|
||||
// other sysex
|
||||
int i; |
||||
for(i=0;i<size-1;i++) { |
||||
if ( pos[i] == 0xF7 ) |
||||
break; |
||||
} |
||||
size -= i; |
||||
stream += i; |
||||
} |
||||
|
||||
// nothing good has been found, map it then to random data
|
||||
if ( status > 1 ) { |
||||
memcpy(voiceData, pos+6, 4096); |
||||
return 2; |
||||
} |
||||
|
||||
return status; |
||||
} |
||||
|
||||
int saveVoice(File f) { |
||||
setHeader(); |
||||
|
||||
if ( ! f.existsAsFile() ) { |
||||
// file doesn't exists, create it
|
||||
return f.replaceWithData(voiceData, SYSEX_SIZE); |
||||
} |
||||
|
||||
FileInputStream *fis = f.createInputStream(); |
||||
if ( fis == NULL ) |
||||
return -1; |
||||
|
||||
uint8 buffer[65535]; |
||||
int sz = fis->read(buffer, 65535); |
||||
delete fis; |
||||
|
||||
// if the file is smaller than 4104, it probably needs to be overriden.
|
||||
if ( sz <= 4104 ) { |
||||
return f.replaceWithData(voiceData, SYSEX_SIZE); |
||||
} |
||||
|
||||
// To avoid to erase the performance data, we skip the sysex stream until
|
||||
// we see the header 0xF0, 0x43, 0x00, 0x09, 0x20, 0x00
|
||||
|
||||
int pos = 0; |
||||
bool found = 0; |
||||
while(pos < sz) { |
||||
// corrupted sysex, erase everything :
|
||||
if ( buffer[pos] != 0xF0 ) |
||||
return f.replaceWithData(voiceData, SYSEX_SIZE); |
||||
|
||||
uint8_t header[] = SYSEX_HEADER; |
||||
if ( memcmp(buffer+pos, header, 6) ) { |
||||
found = true; |
||||
memcpy(buffer+pos, voiceData, SYSEX_SIZE); |
||||
break; |
||||
} else { |
||||
for(;pos<sz;pos++) { |
||||
if ( buffer[pos] == 0xF7 ) |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if ( ! found ) |
||||
return -1; |
||||
|
||||
return f.replaceWithData(buffer, sz); |
||||
} |
||||
|
||||
void saveVoice(uint8_t *sysex) { |
||||
setHeader(); |
||||
memcpy(sysex, voiceData, SYSEX_SIZE); |
||||
} |
||||
|
||||
char *getRawVoice() { |
||||
return (char *) voiceData + 6; |
||||
} |
||||
|
||||
char *getVoiceSysex() { |
||||
setHeader(); |
||||
return (char *) voiceData; |
||||
} |
||||
|
||||
void getProgramNames(StringArray &dest) { |
||||
dest.clear(); |
||||
for (int i = 0; i < 32; i++) |
||||
dest.add( normalizePgmName(getRawVoice() + ((i * 128) + 118)) ); |
||||
} |
||||
|
||||
Cartridge operator =(const Cartridge other) { |
||||
memcpy(voiceData, other.voiceData, SYSEX_SIZE); |
||||
memcpy(perfData, other.perfData, SYSEX_SIZE); |
||||
return *this; |
||||
} |
||||
|
||||
void unpackProgram(uint8_t *unpackPgm, int idx); |
||||
void packProgram(uint8_t *src, int idx, String name, char *opSwitch); |
||||
}; |
||||
|
||||
#endif // PLUGINDATA_H_INCLUDED
|
@ -1,341 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2013-2015 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 3 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 "PluginProcessor.h" |
||||
#include "PluginEditor.h" |
||||
#include "GlobalEditor.h" |
||||
#include "ParamDialog.h" |
||||
#include "SysexComm.h" |
||||
#include "Dexed.h" |
||||
#include "math.h" |
||||
#include "DXLookNFeel.h" |
||||
#include <fstream> |
||||
|
||||
#include "msfa/fm_op_kernel.h" |
||||
|
||||
//==============================================================================
|
||||
DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* ownerFilter) |
||||
: AudioProcessorEditor (ownerFilter), |
||||
midiKeyboard (ownerFilter->keyboardState, MidiKeyboardComponent::horizontalKeyboard), |
||||
cartManager(this) |
||||
{ |
||||
LookAndFeel::setDefaultLookAndFeel(DXLookNFeel::getLookAndFeel()); |
||||
|
||||
setSize(866, ownerFilter->showKeyboard ? 674 : 581); |
||||
|
||||
processor = ownerFilter; |
||||
|
||||
background = DXLookNFeel::getLookAndFeel()->background; |
||||
|
||||
// OPERATORS
|
||||
addAndMakeVisible(&(operators[0])); |
||||
operators[0].setBounds(2, 1, 287, 218); |
||||
operators[0].bind(processor, 0); |
||||
|
||||
addAndMakeVisible(&(operators[1])); |
||||
operators[1].setBounds(290, 1, 287, 218); |
||||
operators[1].bind(processor, 1); |
||||
|
||||
addAndMakeVisible(&(operators[2])); |
||||
operators[2].setBounds(578, 1, 287, 218); |
||||
operators[2].bind(processor, 2); |
||||
|
||||
addAndMakeVisible(&(operators[3])); |
||||
operators[3].setBounds(2, 219, 287, 218); |
||||
operators[3].bind(processor, 3); |
||||
|
||||
addAndMakeVisible(&(operators[4])); |
||||
operators[4].setBounds(290, 219, 287, 218); |
||||
operators[4].bind(processor, 4); |
||||
|
||||
addAndMakeVisible(&(operators[5])); |
||||
operators[5].setBounds(578, 219, 287, 218); |
||||
operators[5].bind(processor, 5); |
||||
|
||||
// add the midi keyboard component..
|
||||
addAndMakeVisible (&midiKeyboard); |
||||
|
||||
// The DX7 is a badass on the bass, keep it that way
|
||||
midiKeyboard.setLowestVisibleKey(24); |
||||
|
||||
midiKeyboard.setBounds(4, 581, getWidth() - 8, 90); |
||||
|
||||
addAndMakeVisible(&global); |
||||
global.setBounds(2,436,864,144); |
||||
global.bind(this); |
||||
|
||||
global.setMonoState(processor->isMonoMode()); |
||||
|
||||
rebuildProgramCombobox(); |
||||
global.programs->addListener(this); |
||||
|
||||
addChildComponent(&cartManager); |
||||
|
||||
updateUI(); |
||||
startTimer(100); |
||||
} |
||||
|
||||
DexedAudioProcessorEditor::~DexedAudioProcessorEditor() { |
||||
stopTimer(); |
||||
processor->unbindUI(); |
||||
} |
||||
|
||||
//==============================================================================
|
||||
void DexedAudioProcessorEditor::paint (Graphics& g) {
|
||||
g.setColour(background); |
||||
g.fillRoundedRectangle(0.0f, 0.0f, (float) getWidth(), (float) getHeight(), 0); |
||||
} |
||||
|
||||
void DexedAudioProcessorEditor::cartShow() { |
||||
stopTimer();
|
||||
cartManager.resetActiveSysex(); |
||||
cartManager.setBounds(4, 2, 859, 576); |
||||
cartManager.setVisible(true); |
||||
cartManager.initialFocus(); |
||||
} |
||||
|
||||
|
||||
void DexedAudioProcessorEditor::loadCart(File file) { |
||||
Cartridge cart; |
||||
|
||||
int rc = cart.load(file); |
||||
|
||||
if ( rc < 0 ) { |
||||
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, |
||||
"Error", |
||||
"Unable to open: " + file.getFullPathName()); |
||||
return; |
||||
} |
||||
|
||||
if ( rc != 0 ) { |
||||
rc = AlertWindow::showOkCancelBox(AlertWindow::QuestionIcon, "Unable to find DX7 sysex cartridge in file", |
||||
"This sysex file is not for the DX7 or it is corrupted. " |
||||
"Do you still want to load this file as random data ?"); |
||||
if ( rc == 0 ) |
||||
return; |
||||
} |
||||
|
||||
processor->loadCartridge(cart); |
||||
rebuildProgramCombobox(); |
||||
processor->setCurrentProgram(0); |
||||
global.programs->setSelectedId(processor->getCurrentProgram()+1, dontSendNotification); |
||||
processor->updateHostDisplay(); |
||||
|
||||
processor->activeFileCartridge = file; |
||||
} |
||||
|
||||
void DexedAudioProcessorEditor::saveCart() { |
||||
File startFileName = processor->activeFileCartridge.exists() ? processor->activeFileCartridge : processor->dexedCartDir; |
||||
|
||||
FileChooser fc ("Export DX sysex...", processor->dexedCartDir, "*.syx", 1); |
||||
if ( fc.browseForFileToSave(true) ) { |
||||
if ( ! processor->currentCart.saveVoice(fc.getResults().getReference(0)) ) { |
||||
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, |
||||
"Error", |
||||
"Unable to write: " + fc.getResults().getReference(0).getFullPathName()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void DexedAudioProcessorEditor::parmShow() { |
||||
int tp = processor->getEngineType(); |
||||
|
||||
AlertWindow window("","", AlertWindow::NoIcon, this); |
||||
ParamDialog param; |
||||
param.setColour(AlertWindow::backgroundColourId, Colour(0x32FFFFFF)); |
||||
param.setDialogValues(processor->controllers, processor->sysexComm, tp, processor->showKeyboard); |
||||
|
||||
window.addCustomComponent(¶m); |
||||
window.addButton("OK", 0); |
||||
window.addButton("Cancel" ,1); |
||||
if ( window.runModalLoop() != 0 ) |
||||
return; |
||||
|
||||
bool ret = param.getDialogValues(processor->controllers, processor->sysexComm, &tp, &processor->showKeyboard); |
||||
processor->setEngineType(tp); |
||||
processor->savePreference(); |
||||
|
||||
setSize(866, processor->showKeyboard ? 674 : 581); |
||||
midiKeyboard.repaint(); |
||||
|
||||
if ( ret == false ) { |
||||
AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Midi Interface", "Error opening midi ports"); |
||||
} |
||||
} |
||||
|
||||
void DexedAudioProcessorEditor::initProgram() { |
||||
processor->resetToInitVoice(); |
||||
} |
||||
|
||||
void DexedAudioProcessorEditor::comboBoxChanged (ComboBox* comboBoxThatHasChanged) { |
||||
processor->setCurrentProgram(global.programs->getSelectedId()-1); |
||||
processor->updateHostDisplay(); |
||||
} |
||||
|
||||
void DexedAudioProcessorEditor::timerCallback() { |
||||
if ( processor->forceRefreshUI ) { |
||||
processor->forceRefreshUI = false; |
||||
updateUI(); |
||||
} |
||||
|
||||
if ( ! processor->peekVoiceStatus() ) |
||||
return; |
||||
|
||||
for(int i=0;i<6;i++) { |
||||
operators[i].updateGain(sqrt(processor->voiceStatus.amp[5 - i]) / 8196); // TODO: FUGLY !!!! change this sqrt nonsens
|
||||
operators[i].updateEnvPos(processor->voiceStatus.ampStep[5 - i]); |
||||
} |
||||
global.updatePitchPos(processor->voiceStatus.pitchStep); |
||||
global.updateVu(processor->vuSignal); |
||||
}
|
||||
|
||||
void DexedAudioProcessorEditor::updateUI() { |
||||
for(int i=0;i<processor->ctrl.size();i++) { |
||||
processor->ctrl[i]->updateComponent(); |
||||
} |
||||
for(int i=0;i<6;i++) { |
||||
operators[i].updateDisplay(); |
||||
} |
||||
rebuildProgramCombobox(); |
||||
global.updateDisplay(); |
||||
} |
||||
|
||||
void DexedAudioProcessorEditor::rebuildProgramCombobox() { |
||||
global.programs->clear(dontSendNotification); |
||||
|
||||
processor->currentCart.getProgramNames(processor->programNames); |
||||
|
||||
for(int i=0;i<processor->getNumPrograms();i++) { |
||||
String id; |
||||
id << (i+1) << ". " << processor->getProgramName(i); |
||||
global.programs->addItem(id, i+1); |
||||
} |
||||
|
||||
global.programs->setSelectedId(processor->getCurrentProgram()+1, dontSendNotification); |
||||
|
||||
String name = Cartridge::normalizePgmName((const char *) processor->data+145); |
||||
cartManager.setActiveProgram(processor->getCurrentProgram(), name); |
||||
if ( name != processor->getProgramName(processor->getCurrentProgram()) ) |
||||
global.programs->setText("**. " + name, dontSendNotification); |
||||
|
||||
cartManager.resetActiveSysex(); |
||||
} |
||||
|
||||
void DexedAudioProcessorEditor::storeProgram() { |
||||
String currentName = Cartridge::normalizePgmName((const char *) processor->data+145); |
||||
Cartridge destSysex = processor->currentCart; |
||||
File *externalFile = NULL; |
||||
|
||||
bool activeCartridgeFound = processor->activeFileCartridge.exists(); |
||||
|
||||
while (true) { |
||||
String msg; |
||||
|
||||
if ( externalFile == NULL ) { |
||||
if ( activeCartridgeFound ) |
||||
msg = "Store program to current (" + processor->activeFileCartridge.getFileName() + ") / new cartridge"; |
||||
else |
||||
msg = "Store program to current / new cartridge"; |
||||
} else { |
||||
msg = "Store program to " + externalFile->getFileName(); |
||||
} |
||||
|
||||
AlertWindow dialog("Store Program", msg, AlertWindow::NoIcon, this); |
||||
dialog.addTextEditor("Name", currentName, String("Name"), false); |
||||
// TODO: fix the name length to 10
|
||||
|
||||
StringArray programs; |
||||
destSysex.getProgramNames(programs); |
||||
dialog.addComboBox("Dest", programs, "Program Destination"); |
||||
|
||||
|
||||
if ( externalFile == NULL ) { |
||||
StringArray saveAction; |
||||
saveAction.add("Store program to DAW plugin song state"); |
||||
saveAction.add("Store program and create a new copy of the .syx cartridge"); |
||||
if ( activeCartridgeFound ) |
||||
saveAction.add("Store program and overwrite current .syx cartridge"); |
||||
|
||||
dialog.addComboBox("SaveAction", saveAction, "Store Action"); |
||||
} |
||||
|
||||
dialog.addButton("OK", 0, KeyPress(KeyPress::returnKey)); |
||||
dialog.addButton("CANCEL", 1, KeyPress(KeyPress::escapeKey)); |
||||
dialog.addButton("EXTERNAL FILE", 2, KeyPress()); |
||||
int response = dialog.runModalLoop(); |
||||
|
||||
if ( response == 2 ) { |
||||
FileChooser fc("Destination Sysex", processor->dexedCartDir, "*.syx;*.SYX;*.*", 1); |
||||
|
||||
if ( fc.browseForFileToOpen() ) { |
||||
if ( externalFile != NULL )
|
||||
delete externalFile; |
||||
|
||||
externalFile = new File(fc.getResults().getReference(0)); |
||||
if ( destSysex.load(*externalFile) ) |
||||
continue; |
||||
AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Read error", "Unable to read file"); |
||||
} |
||||
} |
||||
|
||||
if ( response == 0 ) { |
||||
TextEditor *name = dialog.getTextEditor("Name"); |
||||
ComboBox *dest = dialog.getComboBoxComponent("Dest"); |
||||
|
||||
int programNum = dest->getSelectedItemIndex(); |
||||
String programName(name->getText()); |
||||
if ( programName.length() > 10 ) { |
||||
int toStrip = programName.length() - 10; |
||||
programName = programName.dropLastCharacters(toStrip); |
||||
} |
||||
|
||||
if ( externalFile == NULL ) { |
||||
processor->currentCart.packProgram((uint8_t *) processor->data, programNum, programName, processor->controllers.opSwitch); |
||||
rebuildProgramCombobox(); |
||||
processor->setCurrentProgram(programNum); |
||||
processor->updateHostDisplay(); |
||||
|
||||
int action = dialog.getComboBoxComponent("SaveAction")->getSelectedItemIndex(); |
||||
if ( action > 0 ) {
|
||||
File destination = processor->activeFileCartridge; |
||||
if ( ! destination.exists() ) { |
||||
FileChooser fc("Destination Sysex", processor->dexedCartDir, "*.syx", 1); |
||||
if ( ! fc.browseForFileToSave(true) ) |
||||
break; |
||||
destination = fc.getResult(); |
||||
} |
||||
|
||||
processor->currentCart.saveVoice(destination); |
||||
processor->activeFileCartridge = destination; |
||||
} |
||||
} else { |
||||
destSysex.packProgram((uint8_t *) processor->data, programNum, programName, processor->controllers.opSwitch); |
||||
if ( ! destSysex.saveVoice(*externalFile)) { |
||||
AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Write error", "Unable to write file"); |
||||
} |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
|
||||
if ( externalFile != NULL ) |
||||
delete externalFile; |
||||
cartManager.resetActiveSysex(); |
||||
} |
@ -1,61 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2013-2016 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 3 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 |
||||
*/ |
||||
|
||||
#ifndef PLUGINEDITOR_H_INCLUDED |
||||
#define PLUGINEDITOR_H_INCLUDED |
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h" |
||||
#include "PluginProcessor.h" |
||||
#include "OperatorEditor.h" |
||||
#include "GlobalEditor.h" |
||||
#include "DXComponents.h" |
||||
#include "DXLookNFeel.h" |
||||
#include "CartManager.h" |
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
*/ |
||||
class DexedAudioProcessorEditor : public AudioProcessorEditor, public ComboBoxListener, public Timer { |
||||
MidiKeyboardComponent midiKeyboard; |
||||
OperatorEditor operators[6]; |
||||
Colour background; |
||||
CartManager cartManager; |
||||
|
||||
public: |
||||
DexedAudioProcessor *processor; |
||||
GlobalEditor global; |
||||
|
||||
DexedAudioProcessorEditor (DexedAudioProcessor* ownerFilter); |
||||
~DexedAudioProcessorEditor(); |
||||
void timerCallback(); |
||||
|
||||
void paint (Graphics& g); |
||||
void comboBoxChanged (ComboBox* comboBoxThatHasChanged); |
||||
void updateUI(); |
||||
void rebuildProgramCombobox(); |
||||
void loadCart(File file); |
||||
void saveCart(); |
||||
void initProgram(); |
||||
void storeProgram(); |
||||
void cartShow(); |
||||
void parmShow(); |
||||
}; |
||||
|
||||
|
||||
#endif // PLUGINEDITOR_H_INCLUDED
|
@ -1,705 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2013-2016 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 3 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 <time.h> |
||||
#include <stdlib.h> |
||||
|
||||
#include "PluginParam.h" |
||||
#include "PluginProcessor.h" |
||||
#include "PluginEditor.h" |
||||
#include "Dexed.h" |
||||
|
||||
// ************************************************************************
|
||||
// Custom displays
|
||||
|
||||
class CtrlDXLabel : public CtrlDX { |
||||
StringArray labels; |
||||
public: |
||||
CtrlDXLabel(String name, int steps, int offset, StringArray &labels) : CtrlDX(name, steps, offset, 0) { |
||||
this->labels = labels; |
||||
}; |
||||
|
||||
String getValueDisplay() { |
||||
return labels[getValue()]; |
||||
} |
||||
}; |
||||
|
||||
class CtrlDXTranspose : public CtrlDX { |
||||
public: |
||||
CtrlDXTranspose(String name, int steps, int offset) : CtrlDX(name, steps, offset, 0) { |
||||
}; |
||||
|
||||
String getValueDisplay() { |
||||
String ret; |
||||
int value = getValue(); |
||||
|
||||
switch(value % 12) { |
||||
case 0: ret << "C"; break; |
||||
case 1: ret << "C#"; break; |
||||
case 2: ret << "D"; break; |
||||
case 3: ret << "D#"; break; |
||||
case 4: ret << "E"; break; |
||||
case 5: ret << "F"; break; |
||||
case 6: ret << "F#"; break; |
||||
case 7: ret << "G"; break; |
||||
case 8: ret << "G#"; break; |
||||
case 9: ret << "A"; break; |
||||
case 10: ret << "A#"; break; |
||||
case 11: ret << "B"; break; |
||||
} |
||||
return ret << (value/12+1); |
||||
} |
||||
}; |
||||
|
||||
class CtrlTune : public Ctrl { |
||||
public: |
||||
DexedAudioProcessor *processor; |
||||
|
||||
CtrlTune(String name, DexedAudioProcessor *owner) : Ctrl(name) { |
||||
processor = owner; |
||||
} |
||||
|
||||
float getValueHost() { |
||||
// meh. good enough for now
|
||||
int32_t tune = processor->controllers.masterTune / (1.0/12); |
||||
tune = (tune >> 11) + 0x2000; |
||||
return (float)tune / 0x4000; |
||||
} |
||||
|
||||
void setValueHost(float v) { |
||||
int32_t tune = (v * 0x4000) - 0x2000; |
||||
processor->controllers.masterTune = ((float) (tune << 11)) * (1.0/12); |
||||
} |
||||
|
||||
String getValueDisplay() { |
||||
String display; |
||||
display << (getValueHost() * 2) -1; |
||||
return display; |
||||
} |
||||
|
||||
void updateComponent() { |
||||
if (slider != NULL) { |
||||
slider->setValue(getValueHost(), dontSendNotification); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
class CtrlOpSwitch : public Ctrl { |
||||
char *value; |
||||
public : |
||||
CtrlOpSwitch(String name, char *switchValue) : Ctrl(name) { |
||||
value = switchValue; |
||||
} |
||||
|
||||
void setValueHost(float f) { |
||||
if ( f == 0 ) |
||||
*value = '0'; |
||||
else |
||||
*value = '1'; |
||||
} |
||||
|
||||
float getValueHost() { |
||||
if ( *value == '0' ) |
||||
return 0; |
||||
else |
||||
return 1; |
||||
} |
||||
|
||||
String getValueDisplay() { |
||||
String ret; |
||||
ret << label << " " << (*value == '0' ? "OFF" : "ON"); |
||||
return ret; |
||||
} |
||||
|
||||
void updateComponent() { |
||||
if (button != NULL) { |
||||
if (*value == '0') { |
||||
button->setToggleState(false, dontSendNotification); |
||||
} else { |
||||
button->setToggleState(true, dontSendNotification); |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
|
||||
// ************************************************************************
|
||||
//
|
||||
Ctrl::Ctrl(String name) { |
||||
label << name; |
||||
slider = NULL; |
||||
button = NULL; |
||||
comboBox = NULL; |
||||
} |
||||
|
||||
void Ctrl::bind(Slider *s) { |
||||
slider = s; |
||||
updateComponent(); |
||||
s->addListener(this); |
||||
s->addMouseListener(this, true); |
||||
} |
||||
|
||||
void Ctrl::bind(Button *b) { |
||||
button = b; |
||||
updateComponent(); |
||||
b->addListener(this); |
||||
b->addMouseListener(this, true); |
||||
} |
||||
|
||||
void Ctrl::bind(ComboBox *c) { |
||||
comboBox = c; |
||||
updateComponent(); |
||||
c->addListener(this); |
||||
c->addMouseListener(this, true); |
||||
} |
||||
|
||||
void Ctrl::unbind() { |
||||
if (slider != NULL) { |
||||
slider->removeListener(this); |
||||
slider->removeMouseListener(this); |
||||
slider = NULL; |
||||
} |
||||
|
||||
if (button != NULL) { |
||||
button->removeListener(this); |
||||
button->removeMouseListener(this); |
||||
button = NULL; |
||||
} |
||||
|
||||
if (comboBox != NULL) { |
||||
comboBox->removeListener(this); |
||||
comboBox->removeMouseListener(this); |
||||
comboBox = NULL; |
||||
} |
||||
} |
||||
|
||||
void Ctrl::publishValue(float value) { |
||||
parent->beginParameterChangeGesture(idx); |
||||
parent->setParameterNotifyingHost(idx, value); |
||||
parent->endParameterChangeGesture(idx); |
||||
} |
||||
|
||||
void Ctrl::sliderValueChanged(Slider* moved) { |
||||
publishValue(moved->getValue()); |
||||
} |
||||
|
||||
void Ctrl::buttonClicked(Button* clicked) { |
||||
publishValue(clicked->getToggleState()); |
||||
} |
||||
|
||||
void Ctrl::comboBoxChanged(ComboBox* combo) { |
||||
publishValue((combo->getSelectedId() - 1) / combo->getNumItems()); |
||||
} |
||||
|
||||
void Ctrl::mouseEnter(const juce::MouseEvent &event) { |
||||
updateDisplayName(); |
||||
} |
||||
|
||||
void Ctrl::updateDisplayName() { |
||||
} |
||||
|
||||
// ************************************************************************
|
||||
// CtrlDX - control DX mapping
|
||||
CtrlFloat::CtrlFloat(String name, float *storageValue) : Ctrl(name) { |
||||
vPointer = storageValue; |
||||
} |
||||
|
||||
float CtrlFloat::getValueHost() { |
||||
return *vPointer; |
||||
} |
||||
|
||||
void CtrlFloat::setValueHost(float v) { |
||||
*vPointer = v; |
||||
} |
||||
|
||||
String CtrlFloat::getValueDisplay() { |
||||
String display; |
||||
display << *vPointer; |
||||
return display; |
||||
} |
||||
|
||||
void CtrlFloat::updateComponent() { |
||||
if (slider != NULL) { |
||||
slider->setValue(*vPointer, dontSendNotification); |
||||
} |
||||
} |
||||
|
||||
// ************************************************************************
|
||||
// CtrlDX - control DX mapping
|
||||
CtrlDX::CtrlDX(String name, int steps, int offset, int displayValue) : Ctrl(name) { |
||||
this->displayValue = displayValue; |
||||
this->steps = steps; |
||||
dxValue = 0; |
||||
dxOffset = offset; |
||||
} |
||||
|
||||
float CtrlDX::getValueHost() { |
||||
return getValue() / (float) steps; |
||||
} |
||||
|
||||
void CtrlDX::setValueHost(float f) { |
||||
setValue(roundToInt(f * steps)); |
||||
} |
||||
|
||||
void CtrlDX::setValue(int v) { |
||||
TRACE("setting value %d %d", dxOffset, v); |
||||
dxValue = v; |
||||
if (dxOffset >= 0) { |
||||
if (parent != NULL) |
||||
parent->setDxValue(dxOffset, dxValue); |
||||
} |
||||
} |
||||
|
||||
int CtrlDX::getValue() { |
||||
if (dxOffset >= 0) |
||||
dxValue = parent->data[dxOffset]; |
||||
return dxValue; |
||||
} |
||||
|
||||
int CtrlDX::getOffset() { |
||||
return dxOffset; |
||||
} |
||||
|
||||
String CtrlDX::getValueDisplay() { |
||||
String ret; |
||||
ret << ( getValue() + displayValue ); |
||||
return ret; |
||||
} |
||||
|
||||
void CtrlDX::updateDisplayName() { |
||||
DexedAudioProcessorEditor *editor = (DexedAudioProcessorEditor *) parent->getActiveEditor(); |
||||
if ( editor == NULL ) { |
||||
return; |
||||
} |
||||
String msg; |
||||
msg << label << " = " << getValueDisplay(); |
||||
editor->global.setParamMessage(msg); |
||||
editor->global.repaint(); |
||||
} |
||||
|
||||
|
||||
void CtrlDX::publishValue(float value) { |
||||
Ctrl::publishValue(value / steps); |
||||
updateDisplayName(); |
||||
} |
||||
|
||||
void CtrlDX::sliderValueChanged(Slider* moved) { |
||||
publishValue(((int) moved->getValue() - displayValue)); |
||||
} |
||||
|
||||
void CtrlDX::comboBoxChanged(ComboBox* combo) { |
||||
publishValue(combo->getSelectedId() - 1); |
||||
} |
||||
|
||||
void CtrlDX::buttonClicked(Button *button) { |
||||
publishValue((int) button->getToggleState()); |
||||
} |
||||
|
||||
void CtrlDX::updateComponent() { |
||||
if (slider != NULL) { |
||||
slider->setValue(getValue() + displayValue, |
||||
dontSendNotification); |
||||
} |
||||
|
||||
if (button != NULL) { |
||||
if (getValue() == 0) { |
||||
button->setToggleState(false, dontSendNotification); |
||||
} else { |
||||
button->setToggleState(true, dontSendNotification); |
||||
} |
||||
} |
||||
|
||||
if (comboBox != NULL) { |
||||
int cvalue = getValue() + 1; |
||||
if (comboBox->getNumItems() <= cvalue) { |
||||
cvalue = comboBox->getNumItems(); |
||||
} |
||||
comboBox->setSelectedId(cvalue, dontSendNotification); |
||||
} |
||||
} |
||||
|
||||
/***************************************************************
|
||||
* |
||||
*/ |
||||
void DexedAudioProcessor::initCtrl() { |
||||
setupStartupCart(); |
||||
currentProgram = 0; |
||||
|
||||
fxCutoff = new CtrlFloat("Cutoff", &fx.uiCutoff); |
||||
ctrl.add(fxCutoff); |
||||
|
||||
fxReso = new CtrlFloat("Resonance", &fx.uiReso); |
||||
ctrl.add(fxReso); |
||||
|
||||
output = new CtrlFloat("Output", &fx.uiGain); |
||||
ctrl.add(output); |
||||
|
||||
tune = new CtrlTune("MASTER TUNE ADJ", this); |
||||
ctrl.add(tune); |
||||
|
||||
algo = new CtrlDX("ALGORITHM", 31, 134, 1); |
||||
ctrl.add(algo); |
||||
|
||||
feedback = new CtrlDX("FEEDBACK", 7, 135); |
||||
ctrl.add(feedback); |
||||
|
||||
oscSync = new CtrlDX("OSC KEY SYNC", 1, 136); |
||||
ctrl.add(oscSync); |
||||
|
||||
lfoRate = new CtrlDX("LFO SPEED", 99, 137); |
||||
ctrl.add(lfoRate); |
||||
|
||||
lfoDelay = new CtrlDX("LFO DELAY", 99, 138); |
||||
ctrl.add(lfoDelay); |
||||
|
||||
lfoPitchDepth = new CtrlDX("LFO PM DEPTH", 99, 139); |
||||
ctrl.add(lfoPitchDepth); |
||||
|
||||
lfoAmpDepth = new CtrlDX("LFO AM DEPTH", 99, 140); |
||||
ctrl.add(lfoAmpDepth); |
||||
|
||||
lfoSync = new CtrlDX("LFO KEY SYNC", 1, 141); |
||||
ctrl.add(lfoSync); |
||||
|
||||
StringArray lbl; |
||||
lbl.add("TRIANGE"); |
||||
lbl.add("SAW DOWN"); |
||||
lbl.add("SAW UP"); |
||||
lbl.add("SQUARE"); |
||||
lbl.add("SINE"); |
||||
lbl.add("S&HOLD"); |
||||
|
||||
lfoWaveform = new CtrlDXLabel("LFO WAVE", 5, 142, lbl); |
||||
ctrl.add(lfoWaveform); |
||||
|
||||
transpose = new CtrlDXTranspose("MIDDLE C", 48, 144); |
||||
ctrl.add(transpose); |
||||
|
||||
pitchModSens = new CtrlDX("P MODE SENS.", 7, 143); |
||||
ctrl.add(pitchModSens); |
||||
|
||||
for (int i=0;i<4;i++) { |
||||
String rate; |
||||
rate << "PITCH EG RATE " << (i+1); |
||||
pitchEgRate[i] = new CtrlDX(rate, 99, 126+i); |
||||
ctrl.add(pitchEgRate[i]); |
||||
} |
||||
|
||||
for (int i=0;i<4;i++) { |
||||
String level; |
||||
level << "PITCH EG LEVEL " << (i+1); |
||||
pitchEgLevel[i] = new CtrlDX(level, 99, 130+i); |
||||
ctrl.add(pitchEgLevel[i]); |
||||
} |
||||
|
||||
StringArray keyScaleLabels; |
||||
keyScaleLabels.add("-LN"); |
||||
keyScaleLabels.add("-EX"); |
||||
keyScaleLabels.add("+EX"); |
||||
keyScaleLabels.add("+LN"); |
||||
|
||||
// fill operator values;
|
||||
for (int i = 0; i < 6; i++) { |
||||
//// In the Sysex, OP6 comes first, then OP5...
|
||||
int opTarget = (5-i) * 21; |
||||
int opVal = i; |
||||
String opName; |
||||
opName << "OP" << (opVal + 1); |
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
String opRate; |
||||
opRate << opName << " EG RATE " << (j + 1); |
||||
opCtrl[opVal].egRate[j] = new CtrlDX(opRate, 99, opTarget + j); |
||||
ctrl.add(opCtrl[opVal].egRate[j]); |
||||
} |
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
String opLevel; |
||||
opLevel << opName << " EG LEVEL " << (j + 1); |
||||
opCtrl[opVal].egLevel[j] = new CtrlDX(opLevel, 99, opTarget + j + 4); |
||||
ctrl.add(opCtrl[opVal].egLevel[j]); |
||||
} |
||||
|
||||
String opVol; |
||||
opVol << opName << " OUTPUT LEVEL"; |
||||
opCtrl[opVal].level = new CtrlDX(opVol, 99, opTarget + 16); |
||||
ctrl.add(opCtrl[opVal].level); |
||||
|
||||
String opMode; |
||||
opMode << opName << " MODE"; |
||||
opCtrl[opVal].opMode = new CtrlDX(opMode, 1, opTarget + 17); |
||||
ctrl.add(opCtrl[opVal].opMode); |
||||
|
||||
String coarse; |
||||
coarse << opName << " F COARSE"; |
||||
opCtrl[opVal].coarse = new CtrlDX(coarse, 31, opTarget + 18); |
||||
ctrl.add(opCtrl[opVal].coarse); |
||||
|
||||
String fine; |
||||
fine << opName << " F FINE"; |
||||
opCtrl[opVal].fine = new CtrlDX(fine, 99, opTarget + 19); |
||||
ctrl.add(opCtrl[opVal].fine); |
||||
|
||||
String detune; |
||||
detune << opName << " OSC DETUNE"; |
||||
opCtrl[opVal].detune = new CtrlDX(detune, 14, opTarget + 20, -7); |
||||
ctrl.add(opCtrl[opVal].detune); |
||||
|
||||
String sclBrkPt; |
||||
sclBrkPt << opName << " BREAK POINT"; |
||||
opCtrl[opVal].sclBrkPt = new CtrlDX(sclBrkPt, 99, opTarget + 8); |
||||
ctrl.add(opCtrl[opVal].sclBrkPt); |
||||
|
||||
String sclLeftDepth; |
||||
sclLeftDepth << opName << " L SCALE DEPTH"; |
||||
opCtrl[opVal].sclLeftDepth = new CtrlDX(sclLeftDepth, 99, opTarget + 9); |
||||
ctrl.add(opCtrl[opVal].sclLeftDepth); |
||||
|
||||
String sclRightDepth; |
||||
sclRightDepth << opName << " R SCALE DEPTH"; |
||||
opCtrl[opVal].sclRightDepth = new CtrlDX(sclRightDepth, 99, opTarget + 10); |
||||
ctrl.add(opCtrl[opVal].sclRightDepth); |
||||
|
||||
String sclLeftCurve; |
||||
sclLeftCurve << opName << " L KEY SCALE"; |
||||
opCtrl[opVal].sclLeftCurve = new CtrlDXLabel(sclLeftCurve, 3, opTarget + 11, keyScaleLabels); |
||||
ctrl.add(opCtrl[opVal].sclLeftCurve); |
||||
|
||||
String sclRightCurve; |
||||
sclRightCurve << opName << " R KEY SCALE"; |
||||
opCtrl[opVal].sclRightCurve = new CtrlDXLabel(sclRightCurve, 3, opTarget + 12, keyScaleLabels); |
||||
ctrl.add(opCtrl[opVal].sclRightCurve); |
||||
|
||||
String sclRate; |
||||
sclRate << opName << " RATE SCALING"; |
||||
opCtrl[opVal].sclRate = new CtrlDX(sclRate, 7, opTarget + 13); |
||||
ctrl.add(opCtrl[opVal].sclRate); |
||||
|
||||
String ampModSens; |
||||
ampModSens << opName << " A MOD SENS."; |
||||
opCtrl[opVal].ampModSens = new CtrlDX(ampModSens, 3, opTarget + 14); |
||||
ctrl.add(opCtrl[opVal].ampModSens); |
||||
|
||||
String velModSens; |
||||
velModSens << opName << " KEY VELOCITY"; |
||||
opCtrl[opVal].velModSens = new CtrlDX(velModSens, 7, opTarget + 15); |
||||
ctrl.add(opCtrl[opVal].velModSens); |
||||
|
||||
String opSwitchLabel; |
||||
opSwitchLabel << opName << " SWITCH"; |
||||
opCtrl[opVal].opSwitch = new CtrlOpSwitch(opSwitchLabel, (char *)&(controllers.opSwitch)+(5-i)); |
||||
ctrl.add(opCtrl[opVal].opSwitch); |
||||
} |
||||
|
||||
for (int i=0; i < ctrl.size(); i++) { |
||||
ctrl[i]->idx = i; |
||||
ctrl[i]->parent = this; |
||||
} |
||||
} |
||||
|
||||
void DexedAudioProcessor::setDxValue(int offset, int v) { |
||||
if (offset < 0) |
||||
return; |
||||
|
||||
if ( data[offset] != v ) { |
||||
TRACE("setting dx %d %d", offset, v); |
||||
data[offset] = v; |
||||
} else { |
||||
TRACE("ignoring dx7 same values %d %d", offset, v); |
||||
return; |
||||
} |
||||
|
||||
refreshVoice = true; |
||||
|
||||
// MIDDLE C (transpose)
|
||||
if (offset == 144) |
||||
panic(); |
||||
|
||||
if (!sendSysexChange) |
||||
return; |
||||
|
||||
uint8 msg[7] = { 0xF0, 0x43, 0x10, offset > 127, 0, (uint8) v, 0xF7 }; |
||||
msg[2] = 0x10 | sysexComm.getChl(); |
||||
msg[4] = offset & 0x7F; |
||||
|
||||
if ( sysexComm.isOutputActive() ) { |
||||
sysexComm.send(MidiMessage(msg,7)); |
||||
} |
||||
} |
||||
|
||||
void DexedAudioProcessor::unbindUI() { |
||||
for (int i = 0; i < ctrl.size(); i++) { |
||||
ctrl[i]->unbind(); |
||||
} |
||||
} |
||||
|
||||
//==============================================================================
|
||||
int DexedAudioProcessor::getNumParameters() { |
||||
return ctrl.size(); |
||||
} |
||||
|
||||
float DexedAudioProcessor::getParameter(int index) { |
||||
return ctrl[index]->getValueHost(); |
||||
} |
||||
|
||||
void DexedAudioProcessor::setParameter(int index, float newValue) { |
||||
ctrl[index]->setValueHost(newValue); |
||||
forceRefreshUI = true; |
||||
} |
||||
|
||||
int DexedAudioProcessor::getNumPrograms() { |
||||
return 32; |
||||
} |
||||
|
||||
int DexedAudioProcessor::getCurrentProgram() { |
||||
return currentProgram; |
||||
} |
||||
|
||||
void DexedAudioProcessor::setCurrentProgram(int index) { |
||||
TRACE("setting program %d state", index); |
||||
|
||||
if ( lastStateSave + 2 > time(NULL) ) { |
||||
TRACE("skipping save, storage recall to close"); |
||||
return; |
||||
} |
||||
|
||||
panic(); |
||||
|
||||
index = index > 31 ? 31 : index; |
||||
currentCart.unpackProgram(data, index); |
||||
strcpy(controllers.opSwitch, "111111"); |
||||
lfo.reset(data + 137); |
||||
currentProgram = index; |
||||
triggerAsyncUpdate(); |
||||
|
||||
// reset parameter display
|
||||
DexedAudioProcessorEditor *editor = (DexedAudioProcessorEditor *) getActiveEditor(); |
||||
if ( editor == NULL ) { |
||||
return; |
||||
} |
||||
editor->global.setParamMessage(""); |
||||
|
||||
panic(); |
||||
} |
||||
|
||||
const String DexedAudioProcessor::getProgramName(int index) { |
||||
if (index >= 32) |
||||
index = 31; |
||||
return programNames[index]; |
||||
} |
||||
|
||||
void DexedAudioProcessor::changeProgramName(int index, const String& newName) { |
||||
} |
||||
|
||||
const String DexedAudioProcessor::getParameterName(int index) { |
||||
return ctrl[index]->label; |
||||
} |
||||
|
||||
const String DexedAudioProcessor::getParameterText(int index) { |
||||
return ctrl[index]->getValueDisplay(); |
||||
} |
||||
|
||||
void DexedAudioProcessor::loadPreference() { |
||||
File propFile = DexedAudioProcessor::dexedAppDir.getChildFile("Dexed.xml"); |
||||
PropertiesFile::Options prefOptions; |
||||
PropertiesFile prop(propFile, prefOptions); |
||||
|
||||
if ( ! prop.isValidFile() ) { |
||||
return; |
||||
} |
||||
|
||||
if ( prop.containsKey( String("normalizeDxVelocity") ) ) { |
||||
normalizeDxVelocity = prop.getIntValue( String("normalizeDxVelocity") ); |
||||
} |
||||
|
||||
if ( prop.containsKey( String("pitchRange") ) ) { |
||||
controllers.values_[kControllerPitchRange] = prop.getIntValue( String("pitchRange") ); |
||||
} |
||||
|
||||
if ( prop.containsKey( String("pitchStep") ) ) { |
||||
controllers.values_[kControllerPitchStep] = prop.getIntValue( String("pitchStep") ); |
||||
} |
||||
|
||||
if ( prop.containsKey( String("sysexIn") ) ) { |
||||
sysexComm.setInput( prop.getValue("sysexIn") ); |
||||
} |
||||
|
||||
if ( prop.containsKey( String("sysexOut") ) ) { |
||||
sysexComm.setOutput( prop.getValue("sysexOut") ); |
||||
} |
||||
|
||||
if ( prop.containsKey( String("sysexChl") ) ) { |
||||
sysexComm.setChl( prop.getIntValue( String("sysexChl") ) ); |
||||
} |
||||
|
||||
if ( prop.containsKey( String("engineType") ) ) { |
||||
setEngineType(prop.getIntValue(String("engineType"))); |
||||
} |
||||
|
||||
if ( prop.containsKey( String("showKeyboard") ) ) { |
||||
showKeyboard = prop.getIntValue( String("showKeyboard") ); |
||||
} |
||||
|
||||
if ( prop.containsKey( String("wheelMod") ) ) { |
||||
controllers.wheel.parseConfig(prop.getValue(String("wheelMod")).toRawUTF8()); |
||||
} |
||||
|
||||
if ( prop.containsKey( String("footMod") ) ) { |
||||
controllers.foot.parseConfig(prop.getValue(String("footMod")).toRawUTF8()); |
||||
} |
||||
|
||||
if ( prop.containsKey( String("breathMod") ) ) { |
||||
controllers.breath.parseConfig(prop.getValue(String("breathMod")).toRawUTF8()); |
||||
} |
||||
|
||||
if ( prop.containsKey( String("aftertouchMod") ) ) { |
||||
controllers.at.parseConfig(prop.getValue(String("aftertouchMod")).toRawUTF8()); |
||||
} |
||||
} |
||||
|
||||
void DexedAudioProcessor::savePreference() { |
||||
File propFile = DexedAudioProcessor::dexedAppDir.getChildFile("Dexed.xml"); |
||||
PropertiesFile::Options prefOptions; |
||||
PropertiesFile prop(propFile, prefOptions); |
||||
|
||||
prop.setValue(String("normalizeDxVelocity"), normalizeDxVelocity); |
||||
prop.setValue(String("pitchRange"), controllers.values_[kControllerPitchRange]); |
||||
prop.setValue(String("pitchStep"), controllers.values_[kControllerPitchStep]); |
||||
|
||||
prop.setValue(String("sysexIn"), sysexComm.getInput()); |
||||
prop.setValue(String("sysexOut"), sysexComm.getOutput()); |
||||
prop.setValue(String("sysexChl"), sysexComm.getChl()); |
||||
|
||||
prop.setValue(String("showKeyboard"), showKeyboard); |
||||
|
||||
char mod_cfg[15]; |
||||
controllers.wheel.setConfig(mod_cfg); |
||||
prop.setValue(String("wheelMod"), mod_cfg); |
||||
controllers.foot.setConfig(mod_cfg); |
||||
prop.setValue(String("footMod"), mod_cfg); |
||||
controllers.breath.setConfig(mod_cfg); |
||||
prop.setValue(String("breathMod"), mod_cfg); |
||||
controllers.at.setConfig(mod_cfg); |
||||
prop.setValue(String("aftertouchMod"), mod_cfg); |
||||
|
||||
prop.setValue(String("engineType"), (int) engineType); |
||||
|
||||
prop.save(); |
||||
} |
||||
|
@ -1,127 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2013 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 3 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 |
||||
* |
||||
*/ |
||||
|
||||
#ifndef PLUGINPARAM_H_INCLUDED |
||||
#define PLUGINPARAM_H_INCLUDED |
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h" |
||||
|
||||
class DexedAudioProcessor; |
||||
|
||||
class Ctrl : public SliderListener, public ButtonListener, public ComboBoxListener, public MouseListener { |
||||
protected: |
||||
/**
|
||||
* Binded components of the UI |
||||
*/ |
||||
Slider *slider; |
||||
Button *button; |
||||
ComboBox *comboBox; |
||||
|
||||
public: |
||||
String label; |
||||
|
||||
Ctrl(String name); |
||||
void bind(Slider *s); |
||||
void bind(Button *b); |
||||
void bind(ComboBox *c); |
||||
void unbind(); |
||||
|
||||
// use this to signal a parameter change to the host
|
||||
void publishValue(float value); |
||||
|
||||
/**
|
||||
* Host value is related 0.0 to 1.0 values |
||||
*/ |
||||
virtual void setValueHost(float f) = 0; |
||||
virtual float getValueHost() = 0; |
||||
virtual String getValueDisplay() = 0; |
||||
virtual void updateComponent() = 0; |
||||
|
||||
void comboBoxChanged (ComboBox* combo); |
||||
void sliderValueChanged (Slider* moved); |
||||
void buttonClicked (Button* buttonThatWasClicked); |
||||
void mouseEnter(const MouseEvent &event); |
||||
virtual void updateDisplayName(); |
||||
|
||||
/**
|
||||
* Index of this parameter |
||||
*/ |
||||
int idx; |
||||
DexedAudioProcessor *parent; |
||||
}; |
||||
|
||||
class CtrlFloat : public Ctrl { |
||||
float *vPointer; |
||||
public: |
||||
|
||||
CtrlFloat(String name, float *storageValue); |
||||
void setValueHost(float f); |
||||
float getValueHost(); |
||||
String getValueDisplay(); |
||||
void updateComponent(); |
||||
}; |
||||
|
||||
// CtrlDX is a controller that is related to DX parameters
|
||||
class CtrlDX : public Ctrl { |
||||
int dxValue; |
||||
int steps; |
||||
int dxOffset; |
||||
int displayValue; |
||||
|
||||
public: |
||||
CtrlDX(String name, int steps, int offset = -1, int displayValue = 0); |
||||
void setValueHost(float f); |
||||
float getValueHost(); |
||||
void publishValue(float value); |
||||
|
||||
void setValue(int value); |
||||
int getValue(); |
||||
int getOffset(); |
||||
String getValueDisplay(); |
||||
|
||||
void sliderValueChanged (Slider* moved); |
||||
void comboBoxChanged (ComboBox* combo); |
||||
void buttonClicked (Button* buttonThatWasClicked); |
||||
void updateComponent(); |
||||
|
||||
void updateDisplayName(); |
||||
}; |
||||
|
||||
|
||||
struct OperatorCtrl { |
||||
ScopedPointer<CtrlDX> egRate[4]; |
||||
ScopedPointer<CtrlDX> egLevel[4]; |
||||
ScopedPointer<CtrlDX> level; |
||||
ScopedPointer<CtrlDX> opMode; |
||||
ScopedPointer<CtrlDX> coarse; |
||||
ScopedPointer<CtrlDX> fine; |
||||
ScopedPointer<CtrlDX> detune; |
||||
ScopedPointer<CtrlDX> sclBrkPt; |
||||
ScopedPointer<CtrlDX> sclLeftDepth; |
||||
ScopedPointer<CtrlDX> sclRightDepth; |
||||
ScopedPointer<CtrlDX> sclLeftCurve; |
||||
ScopedPointer<CtrlDX> sclRightCurve; |
||||
ScopedPointer<CtrlDX> sclRate; |
||||
ScopedPointer<CtrlDX> ampModSens; |
||||
ScopedPointer<CtrlDX> velModSens; |
||||
ScopedPointer<Ctrl> opSwitch; |
||||
}; |
||||
|
||||
#endif // PLUGINPARAM_H_INCLUDED
|
@ -1,616 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2013-2015 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 3 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 "PluginProcessor.h" |
||||
#include "PluginEditor.h" |
||||
|
||||
#include "Dexed.h" |
||||
#include "msfa/synth.h" |
||||
#include "msfa/freqlut.h" |
||||
#include "msfa/sin.h" |
||||
#include "msfa/exp2.h" |
||||
#include "msfa/env.h" |
||||
#include "msfa/pitchenv.h" |
||||
#include "msfa/aligned_buf.h" |
||||
#include "msfa/fm_op_kernel.h" |
||||
|
||||
//==============================================================================
|
||||
DexedAudioProcessor::DexedAudioProcessor() { |
||||
#ifdef DEBUG |
||||
Logger *tmp = Logger::getCurrentLogger(); |
||||
if ( tmp == NULL ) { |
||||
Logger::setCurrentLogger(FileLogger::createDateStampedLogger("Dexed", "DebugSession-", "log", "DexedAudioProcessor Created")); |
||||
} |
||||
TRACE("Hi"); |
||||
#endif |
||||
|
||||
Exp2::init(); |
||||
Tanh::init(); |
||||
Sin::init(); |
||||
|
||||
lastStateSave = 0; |
||||
currentNote = -1; |
||||
engineType = -1; |
||||
|
||||
vuSignal = 0; |
||||
monoMode = 0; |
||||
|
||||
resolvAppDir(); |
||||
|
||||
TRACE("controler %s", controllers.opSwitch); |
||||
|
||||
initCtrl(); |
||||
sendSysexChange = true; |
||||
normalizeDxVelocity = false; |
||||
sysexComm.listener = this; |
||||
showKeyboard = true; |
||||
|
||||
memset(&voiceStatus, 0, sizeof(VoiceStatus)); |
||||
setEngineType(DEXED_ENGINE_MARKI); |
||||
|
||||
controllers.values_[kControllerPitchRange] = 3; |
||||
controllers.values_[kControllerPitchStep] = 0; |
||||
controllers.masterTune = 0; |
||||
|
||||
loadPreference(); |
||||
|
||||
for (int note = 0; note < MAX_ACTIVE_NOTES; ++note) { |
||||
voices[note].dx7_note = NULL; |
||||
} |
||||
setCurrentProgram(0);
|
||||
nextMidi = NULL; |
||||
midiMsg = NULL; |
||||
|
||||
clipboardContent = -1; |
||||
} |
||||
|
||||
DexedAudioProcessor::~DexedAudioProcessor() { |
||||
TRACE("Bye"); |
||||
} |
||||
|
||||
//==============================================================================
|
||||
void DexedAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock) { |
||||
Freqlut::init(sampleRate); |
||||
Lfo::init(sampleRate); |
||||
PitchEnv::init(sampleRate); |
||||
Env::init_sr(sampleRate); |
||||
fx.init(sampleRate); |
||||
|
||||
for (int note = 0; note < MAX_ACTIVE_NOTES; ++note) { |
||||
voices[note].dx7_note = new Dx7Note; |
||||
voices[note].keydown = false; |
||||
voices[note].sustained = false; |
||||
voices[note].live = false; |
||||
} |
||||
|
||||
currentNote = 0; |
||||
controllers.values_[kControllerPitch] = 0x2000; |
||||
controllers.modwheel_cc = 0; |
||||
controllers.foot_cc = 0; |
||||
controllers.breath_cc = 0; |
||||
controllers.aftertouch_cc = 0; |
||||
|
||||
sustain = false; |
||||
extra_buf_size = 0; |
||||
|
||||
keyboardState.reset(); |
||||
|
||||
lfo.reset(data + 137); |
||||
|
||||
nextMidi = new MidiMessage(0xF0); |
||||
midiMsg = new MidiMessage(0xF0); |
||||
} |
||||
|
||||
void DexedAudioProcessor::releaseResources() { |
||||
currentNote = -1; |
||||
|
||||
for (int note = 0; note < MAX_ACTIVE_NOTES; ++note) { |
||||
if ( voices[note].dx7_note != NULL ) { |
||||
delete voices[note].dx7_note; |
||||
voices[note].dx7_note = NULL; |
||||
} |
||||
voices[note].keydown = false; |
||||
voices[note].sustained = false; |
||||
voices[note].live = false; |
||||
} |
||||
|
||||
keyboardState.reset(); |
||||
if ( nextMidi != NULL ) { |
||||
delete nextMidi; |
||||
nextMidi = NULL; |
||||
} |
||||
if ( midiMsg != NULL ) { |
||||
delete midiMsg; |
||||
midiMsg = NULL; |
||||
} |
||||
} |
||||
|
||||
void DexedAudioProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { |
||||
int numSamples = buffer.getNumSamples(); |
||||
int i; |
||||
|
||||
if ( refreshVoice ) { |
||||
for(i=0;i < MAX_ACTIVE_NOTES;i++) { |
||||
if ( voices[i].live ) |
||||
voices[i].dx7_note->update(data, voices[i].midi_note, feedback_bitdepth); |
||||
} |
||||
lfo.reset(data + 137); |
||||
refreshVoice = false; |
||||
} |
||||
|
||||
keyboardState.processNextMidiBuffer(midiMessages, 0, numSamples, true); |
||||
|
||||
MidiBuffer::Iterator it(midiMessages); |
||||
hasMidiMessage = it.getNextEvent(*nextMidi,midiEventPos); |
||||
|
||||
float *channelData = buffer.getWritePointer(0); |
||||
|
||||
// flush first events
|
||||
for (i=0; i < numSamples && i < extra_buf_size; i++) { |
||||
channelData[i] = extra_buf[i]; |
||||
} |
||||
|
||||
// remaining buffer is still to be processed
|
||||
if (extra_buf_size > numSamples) { |
||||
for (int j = 0; j < extra_buf_size - numSamples; j++) { |
||||
extra_buf[j] = extra_buf[j + numSamples]; |
||||
} |
||||
extra_buf_size -= numSamples; |
||||
|
||||
// flush the events, they will be process in the next cycle
|
||||
while(getNextEvent(&it, numSamples)) { |
||||
processMidiMessage(midiMsg); |
||||
} |
||||
} else { |
||||
for (; i < numSamples; i += N) { |
||||
AlignedBuf<int32_t, N> audiobuf; |
||||
float sumbuf[N]; |
||||
|
||||
while(getNextEvent(&it, i)) { |
||||
processMidiMessage(midiMsg); |
||||
} |
||||
|
||||
for (int j = 0; j < N; ++j) { |
||||
audiobuf.get()[j] = 0; |
||||
sumbuf[j] = 0; |
||||
} |
||||
int32_t lfovalue = lfo.getsample(); |
||||
int32_t lfodelay = lfo.getdelay(); |
||||
|
||||
for (int note = 0; note < MAX_ACTIVE_NOTES; ++note) { |
||||
if (voices[note].live) { |
||||
voices[note].dx7_note->compute(audiobuf.get(), lfovalue, lfodelay, &controllers); |
||||
|
||||
for (int j=0; j < N; ++j) { |
||||
int32_t val = audiobuf.get()[j]; |
||||
|
||||
val = val >> 4; |
||||
int clip_val = val < -(1 << 24) ? 0x8000 : val >= (1 << 24) ? 0x7fff : val >> 9; |
||||
float f = ((float) clip_val) / (float) 0x8000; |
||||
if( f > 1 ) f = 1; |
||||
if( f < -1 ) f = -1; |
||||
sumbuf[j] += f; |
||||
audiobuf.get()[j] = 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
int jmax = numSamples - i; |
||||
for (int j = 0; j < N; ++j) { |
||||
if (j < jmax) { |
||||
channelData[i + j] = sumbuf[j]; |
||||
} else { |
||||
extra_buf[j - jmax] = sumbuf[j]; |
||||
} |
||||
} |
||||
} |
||||
extra_buf_size = i - numSamples; |
||||
} |
||||
|
||||
while(getNextEvent(&it, numSamples)) { |
||||
processMidiMessage(midiMsg); |
||||
} |
||||
|
||||
fx.process(channelData, numSamples); |
||||
for(i=0; i<numSamples; i++) { |
||||
float s = std::abs(channelData[i]); |
||||
|
||||
const double decayFactor = 0.99992; |
||||
if (s > vuSignal) |
||||
vuSignal = s; |
||||
else if (vuSignal > 0.001f) |
||||
vuSignal *= decayFactor; |
||||
else |
||||
vuSignal = 0; |
||||
} |
||||
|
||||
// DX7 is a mono synth
|
||||
buffer.copyFrom(1, 0, channelData, numSamples, 1); |
||||
} |
||||
|
||||
|
||||
//==============================================================================
|
||||
// This creates new instances of the plugin..
|
||||
AudioProcessor* JUCE_CALLTYPE createPluginFilter() { |
||||
return new DexedAudioProcessor(); |
||||
} |
||||
|
||||
bool DexedAudioProcessor::getNextEvent(MidiBuffer::Iterator* iter,const int samplePos) { |
||||
if (hasMidiMessage && midiEventPos <= samplePos) { |
||||
*midiMsg = *nextMidi; |
||||
hasMidiMessage = iter->getNextEvent(*nextMidi, midiEventPos); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
void DexedAudioProcessor::processMidiMessage(const MidiMessage *msg) { |
||||
const uint8 *buf = msg->getRawData(); |
||||
uint8_t cmd = buf[0]; |
||||
|
||||
switch(cmd & 0xf0) { |
||||
case 0x80 : |
||||
keyup(buf[1]); |
||||
return; |
||||
|
||||
case 0x90 : |
||||
keydown(buf[1], buf[2]); |
||||
return; |
||||
|
||||
case 0xb0 : { |
||||
int ctrl = buf[1]; |
||||
int value = buf[2]; |
||||
|
||||
switch(ctrl) { |
||||
case 1: |
||||
controllers.modwheel_cc = value; |
||||
controllers.refresh(); |
||||
break; |
||||
case 2: |
||||
controllers.breath_cc = value; |
||||
controllers.refresh(); |
||||
break; |
||||
case 4: |
||||
controllers.foot_cc = value; |
||||
controllers.refresh(); |
||||
break; |
||||
case 64: |
||||
sustain = value > 63; |
||||
if (!sustain) { |
||||
for (int note = 0; note < MAX_ACTIVE_NOTES; note++) { |
||||
if (voices[note].sustained && !voices[note].keydown) { |
||||
voices[note].dx7_note->keyup(); |
||||
voices[note].sustained = false; |
||||
} |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
return; |
||||
|
||||
case 0xc0 : |
||||
setCurrentProgram(buf[1]); |
||||
return; |
||||
|
||||
// aftertouch
|
||||
case 0xd0 : |
||||
controllers.aftertouch_cc = buf[1]; |
||||
controllers.refresh(); |
||||
return; |
||||
|
||||
} |
||||
|
||||
switch (cmd) { |
||||
case 0xe0 : |
||||
controllers.values_[kControllerPitch] = buf[1] | (buf[2] << 7); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
void DexedAudioProcessor::keydown(uint8_t pitch, uint8_t velo) { |
||||
if ( velo == 0 ) { |
||||
keyup(pitch); |
||||
return; |
||||
} |
||||
|
||||
pitch += data[144] - 24; |
||||
|
||||
if ( normalizeDxVelocity ) { |
||||
velo = ((float)velo) * 0.7874015; // 100/127
|
||||
} |
||||
|
||||
int note = currentNote; |
||||
for (int i=0; i<MAX_ACTIVE_NOTES; i++) { |
||||
if (!voices[note].keydown) { |
||||
currentNote = (note + 1) % MAX_ACTIVE_NOTES; |
||||
lfo.keydown(); // TODO: should only do this if # keys down was 0
|
||||
voices[note].midi_note = pitch; |
||||
voices[note].sustained = sustain; |
||||
voices[note].keydown = true; |
||||
voices[note].dx7_note->init(data, pitch, velo, feedback_bitdepth); |
||||
if ( data[136] ) |
||||
voices[note].dx7_note->oscSync(); |
||||
break; |
||||
} |
||||
note = (note + 1) % MAX_ACTIVE_NOTES; |
||||
} |
||||
|
||||
if ( monoMode ) { |
||||
for(int i=0; i<MAX_ACTIVE_NOTES; i++) {
|
||||
if ( voices[i].live ) { |
||||
// all keys are up, only transfert signal
|
||||
if ( ! voices[i].keydown ) { |
||||
voices[i].live = false; |
||||
voices[note].dx7_note->transferSignal(*voices[i].dx7_note); |
||||
break; |
||||
} |
||||
if ( voices[i].midi_note < pitch ) { |
||||
voices[i].live = false; |
||||
voices[note].dx7_note->transferState(*voices[i].dx7_note); |
||||
break; |
||||
} |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
|
||||
voices[note].live = true; |
||||
} |
||||
|
||||
void DexedAudioProcessor::keyup(uint8_t pitch) { |
||||
pitch += data[144] - 24; |
||||
|
||||
int note; |
||||
for (note=0; note<MAX_ACTIVE_NOTES; ++note) { |
||||
if ( voices[note].midi_note == pitch && voices[note].keydown ) { |
||||
voices[note].keydown = false; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
// note not found ?
|
||||
if ( note >= MAX_ACTIVE_NOTES ) { |
||||
TRACE("note-off not found???"); |
||||
return; |
||||
} |
||||
|
||||
if ( monoMode ) { |
||||
int highNote = -1; |
||||
int target = 0; |
||||
for (int i=0; i<MAX_ACTIVE_NOTES;i++) { |
||||
if ( voices[i].keydown && voices[i].midi_note > highNote ) { |
||||
target = i; |
||||
highNote = voices[i].midi_note; |
||||
} |
||||
} |
||||
|
||||
if ( highNote != -1 ) { |
||||
voices[note].live = false; |
||||
voices[target].live = true; |
||||
voices[target].dx7_note->transferState(*voices[note].dx7_note); |
||||
} |
||||
} |
||||
|
||||
if ( sustain ) { |
||||
voices[note].sustained = true; |
||||
} else { |
||||
voices[note].dx7_note->keyup(); |
||||
} |
||||
} |
||||
|
||||
void DexedAudioProcessor::panic() { |
||||
for(int i=0;i<MAX_ACTIVE_NOTES;i++) { |
||||
voices[i].keydown = false; |
||||
voices[i].live = false; |
||||
if ( voices[i].dx7_note != NULL ) { |
||||
voices[i].dx7_note->oscSync(); |
||||
} |
||||
} |
||||
keyboardState.reset(); |
||||
} |
||||
|
||||
void DexedAudioProcessor::handleIncomingMidiMessage(MidiInput* source, const MidiMessage& message) { |
||||
if ( message.isActiveSense() )
|
||||
return; |
||||
|
||||
sysexComm.inActivity = true; |
||||
|
||||
if ( ! message.isSysEx() ) |
||||
return; |
||||
|
||||
//const uint8 *buf = msg->getSysExData();
|
||||
const uint8 *buf = message.getRawData(); |
||||
int sz = message.getRawDataSize(); |
||||
|
||||
if ( sz < 3 ) |
||||
return; |
||||
|
||||
TRACE("SYSEX RECEIVED %d", sz); |
||||
|
||||
// test if it is a Yamaha Sysex
|
||||
if ( buf[1] != 0x43 ) { |
||||
TRACE("not a yamaha sysex %d", buf[0]); |
||||
return; |
||||
} |
||||
|
||||
// single voice dump
|
||||
if ( buf[3] == 0 ) { |
||||
if ( sz < 155 ) { |
||||
TRACE("wrong single voice datasize %d", sz); |
||||
return; |
||||
} |
||||
|
||||
updateProgramFromSysex(buf+6); |
||||
} |
||||
|
||||
// 32 voice dump
|
||||
if ( buf[3] == 9 ) { |
||||
Cartridge received; |
||||
if ( received.load(buf, sz) ) { |
||||
loadCartridge(received); |
||||
setCurrentProgram(0); |
||||
} |
||||
} |
||||
|
||||
updateHostDisplay(); |
||||
forceRefreshUI = true; |
||||
} |
||||
|
||||
int DexedAudioProcessor::getEngineType() { |
||||
return engineType; |
||||
} |
||||
|
||||
void DexedAudioProcessor::setEngineType(int tp) { |
||||
TRACE("settings engine %d", tp); |
||||
|
||||
switch (tp) { |
||||
case DEXED_ENGINE_MARKI: |
||||
controllers.core = &engineMkI; |
||||
feedback_bitdepth = 11; |
||||
break; |
||||
case DEXED_ENGINE_OPL: |
||||
controllers.core = &engineOpl; |
||||
feedback_bitdepth = 11; |
||||
break; |
||||
default: |
||||
controllers.core = &engineMsfa; |
||||
feedback_bitdepth = 8; |
||||
break; |
||||
} |
||||
engineType = tp; |
||||
} |
||||
|
||||
void DexedAudioProcessor::setMonoMode(bool mode) { |
||||
panic(); |
||||
monoMode = mode; |
||||
} |
||||
|
||||
// ====================================================================
|
||||
bool DexedAudioProcessor::peekVoiceStatus() { |
||||
if ( currentNote == -1 ) |
||||
return false; |
||||
|
||||
// we are trying to find the last "keydown" note
|
||||
int note = currentNote; |
||||
for (int i = 0; i < MAX_ACTIVE_NOTES; i++) { |
||||
if (voices[note].keydown) { |
||||
voices[note].dx7_note->peekVoiceStatus(voiceStatus); |
||||
return true; |
||||
} |
||||
if ( --note < 0 ) |
||||
note = MAX_ACTIVE_NOTES-1; |
||||
} |
||||
|
||||
// not found; try a live note
|
||||
note = currentNote; |
||||
for (int i = 0; i < MAX_ACTIVE_NOTES; i++) { |
||||
if (voices[note].live) { |
||||
voices[note].dx7_note->peekVoiceStatus(voiceStatus); |
||||
return true; |
||||
} |
||||
if ( --note < 0 ) |
||||
note = MAX_ACTIVE_NOTES-1; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
const String DexedAudioProcessor::getInputChannelName (int channelIndex) const { |
||||
return String (channelIndex + 1); |
||||
} |
||||
|
||||
const String DexedAudioProcessor::getOutputChannelName (int channelIndex) const { |
||||
return String (channelIndex + 1); |
||||
} |
||||
|
||||
bool DexedAudioProcessor::isInputChannelStereoPair (int index) const { |
||||
return true; |
||||
} |
||||
|
||||
bool DexedAudioProcessor::isOutputChannelStereoPair (int index) const { |
||||
return true; |
||||
} |
||||
|
||||
bool DexedAudioProcessor::acceptsMidi() const { |
||||
#if JucePlugin_WantsMidiInput |
||||
return true; |
||||
#else |
||||
return false; |
||||
#endif |
||||
} |
||||
|
||||
bool DexedAudioProcessor::producesMidi() const { |
||||
#if JucePlugin_ProducesMidiOutput |
||||
return true; |
||||
#else |
||||
return false; |
||||
#endif |
||||
} |
||||
|
||||
bool DexedAudioProcessor::silenceInProducesSilenceOut() const { |
||||
return false; |
||||
} |
||||
|
||||
double DexedAudioProcessor::getTailLengthSeconds() const { |
||||
return 0.0; |
||||
} |
||||
|
||||
const String DexedAudioProcessor::getName() const { |
||||
return JucePlugin_Name; |
||||
} |
||||
|
||||
//==============================================================================
|
||||
bool DexedAudioProcessor::hasEditor() const { |
||||
return true; // (change this to false if you choose to not supply an editor)
|
||||
} |
||||
|
||||
void DexedAudioProcessor::updateUI() { |
||||
// notify host something has changed
|
||||
updateHostDisplay(); |
||||
|
||||
AudioProcessorEditor *editor = getActiveEditor(); |
||||
if ( editor == NULL ) { |
||||
return; |
||||
} |
||||
DexedAudioProcessorEditor *dexedEditor = (DexedAudioProcessorEditor *) editor; |
||||
dexedEditor->updateUI(); |
||||
} |
||||
|
||||
AudioProcessorEditor* DexedAudioProcessor::createEditor() { |
||||
return new DexedAudioProcessorEditor (this); |
||||
} |
||||
|
||||
void DexedAudioProcessor::handleAsyncUpdate() { |
||||
updateUI(); |
||||
} |
||||
|
||||
void dexed_trace(const char *source, const char *fmt, ...) { |
||||
char output[4096]; |
||||
va_list argptr; |
||||
va_start(argptr, fmt); |
||||
vsnprintf(output, 4095, fmt, argptr); |
||||
va_end(argptr); |
||||
|
||||
String dest; |
||||
dest << source << " " << output; |
||||
Logger::writeToLog(dest); |
||||
} |
||||
|
@ -1,235 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2013-2015 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 3 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 |
||||
* |
||||
*/ |
||||
|
||||
#ifndef PLUGINPROCESSOR_H_INCLUDED |
||||
#define PLUGINPROCESSOR_H_INCLUDED |
||||
|
||||
#include "msfa/controllers.h" |
||||
#include "msfa/dx7note.h" |
||||
#include "msfa/lfo.h" |
||||
#include "msfa/synth.h" |
||||
#include "msfa/fm_core.h" |
||||
#include "PluginFx.h" |
||||
//#include "SysexComm.h"
|
||||
#include "EngineMkI.h" |
||||
#include "EngineOpl.h" |
||||
|
||||
struct ProcessorVoice { |
||||
int midi_note; |
||||
bool keydown; |
||||
bool sustained; |
||||
bool live; |
||||
Dx7Note *dx7_note; |
||||
}; |
||||
|
||||
enum DexedEngineResolution { |
||||
DEXED_ENGINE_MODERN, |
||||
DEXED_ENGINE_MARKI, |
||||
DEXED_ENGINE_OPL |
||||
}; |
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
*/ |
||||
class DexedAudioProcessor : public AudioProcessor, public AsyncUpdater, public MidiInputCallback |
||||
{ |
||||
static const int MAX_ACTIVE_NOTES = 16; |
||||
ProcessorVoice voices[MAX_ACTIVE_NOTES]; |
||||
int currentNote; |
||||
|
||||
// The original DX7 had one single LFO. Later units had an LFO per note.
|
||||
Lfo lfo; |
||||
|
||||
bool sustain; |
||||
bool monoMode; |
||||
|
||||
// Extra buffering for when GetSamples wants a buffer not a multiple of N
|
||||
float extra_buf[N]; |
||||
int extra_buf_size; |
||||
|
||||
int currentProgram; |
||||
|
||||
/**
|
||||
* The last time the state was save, to be able to bypass a VST host bug. |
||||
*/ |
||||
long lastStateSave; |
||||
|
||||
/**
|
||||
* Plugin fx (the filter) |
||||
*/ |
||||
PluginFx fx; |
||||
|
||||
/**
|
||||
* This flag is used in the audio thread to know if the voice has changed |
||||
* and needs to be updated. |
||||
*/ |
||||
bool refreshVoice; |
||||
bool normalizeDxVelocity; |
||||
bool sendSysexChange; |
||||
|
||||
void processMidiMessage(const MidiMessage *msg); |
||||
void keydown(uint8_t pitch, uint8_t velo); |
||||
void keyup(uint8_t pitch); |
||||
|
||||
/**
|
||||
* this is called from the Audio thread to tell |
||||
* to update the UI / hostdata
|
||||
*/ |
||||
void handleAsyncUpdate(); |
||||
void initCtrl(); |
||||
|
||||
MidiMessage* nextMidi,*midiMsg; |
||||
bool hasMidiMessage; |
||||
int midiEventPos; |
||||
bool getNextEvent(MidiBuffer::Iterator* iter,const int samplePos); |
||||
|
||||
void handleIncomingMidiMessage(MidiInput* source, const MidiMessage& message); |
||||
uint32_t engineType; |
||||
|
||||
FmCore engineMsfa; |
||||
EngineMkI engineMkI; |
||||
EngineOpl engineOpl; |
||||
|
||||
char clipboard[161]; |
||||
char clipboardContent; |
||||
|
||||
void resolvAppDir(); |
||||
|
||||
int feedback_bitdepth; |
||||
|
||||
public : |
||||
// in MIDI units (0x4000 is neutral)
|
||||
Controllers controllers; |
||||
StringArray programNames; |
||||
Cartridge currentCart; |
||||
uint8_t data[161]; |
||||
|
||||
SysexComm sysexComm; |
||||
VoiceStatus voiceStatus; |
||||
File activeFileCartridge; |
||||
|
||||
bool forceRefreshUI; |
||||
float vuSignal; |
||||
bool showKeyboard; |
||||
int getEngineType(); |
||||
void setEngineType(int rs); |
||||
|
||||
Array<Ctrl*> ctrl; |
||||
|
||||
OperatorCtrl opCtrl[6]; |
||||
ScopedPointer<CtrlDX> pitchEgRate[4]; |
||||
ScopedPointer<CtrlDX> pitchEgLevel[4]; |
||||
ScopedPointer<CtrlDX> pitchModSens; |
||||
ScopedPointer<CtrlDX> algo; |
||||
ScopedPointer<CtrlDX> oscSync; |
||||
ScopedPointer<CtrlDX> feedback; |
||||
ScopedPointer<CtrlDX> lfoRate; |
||||
ScopedPointer<CtrlDX> lfoDelay; |
||||
ScopedPointer<CtrlDX> lfoAmpDepth; |
||||
ScopedPointer<CtrlDX> lfoPitchDepth; |
||||
ScopedPointer<CtrlDX> lfoWaveform; |
||||
ScopedPointer<CtrlDX> lfoSync; |
||||
ScopedPointer<CtrlDX> transpose; |
||||
|
||||
ScopedPointer<CtrlFloat> fxCutoff; |
||||
ScopedPointer<CtrlFloat> fxReso; |
||||
ScopedPointer<CtrlFloat> output; |
||||
ScopedPointer<Ctrl> tune; |
||||
|
||||
void loadCartridge(Cartridge &cart); |
||||
void setDxValue(int offset, int v); |
||||
|
||||
//==============================================================================
|
||||
DexedAudioProcessor(); |
||||
~DexedAudioProcessor(); |
||||
|
||||
//==============================================================================
|
||||
void prepareToPlay (double sampleRate, int samplesPerBlock); |
||||
void releaseResources(); |
||||
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages); |
||||
void panic(); |
||||
bool isMonoMode() { |
||||
return monoMode; |
||||
} |
||||
void setMonoMode(bool mode); |
||||
|
||||
void copyToClipboard(int srcOp); |
||||
void pasteOpFromClipboard(int destOp); |
||||
void pasteEnvFromClipboard(int destOp); |
||||
void sendCurrentSysexProgram(); |
||||
void sendCurrentSysexCartridge(); |
||||
void sendSysexCartridge(File cart); |
||||
bool hasClipboardContent(); |
||||
|
||||
//==============================================================================
|
||||
AudioProcessorEditor* createEditor(); |
||||
bool hasEditor() const; |
||||
void updateUI(); |
||||
bool peekVoiceStatus(); |
||||
void updateProgramFromSysex(const uint8 *rawdata); |
||||
void setupStartupCart(); |
||||
|
||||
//==============================================================================
|
||||
const String getName() const; |
||||
int getNumParameters(); |
||||
float getParameter (int index); |
||||
void setParameter (int index, float newValue); |
||||
const String getParameterName (int index); |
||||
const String getParameterText (int index); |
||||
|
||||
const String getInputChannelName (int channelIndex) const; |
||||
const String getOutputChannelName (int channelIndex) const; |
||||
bool isInputChannelStereoPair (int index) const; |
||||
bool isOutputChannelStereoPair (int index) const; |
||||
|
||||
bool acceptsMidi() const; |
||||
bool producesMidi() const; |
||||
bool silenceInProducesSilenceOut() const; |
||||
double getTailLengthSeconds() const; |
||||
|
||||
//==============================================================================
|
||||
int getNumPrograms(); |
||||
int getCurrentProgram(); |
||||
void setCurrentProgram(int index); |
||||
const String getProgramName (int index); |
||||
void changeProgramName(int index, const String& newName); |
||||
void resetToInitVoice(); |
||||
|
||||
//==============================================================================
|
||||
void getStateInformation (MemoryBlock& destData); |
||||
void setStateInformation (const void* data, int sizeInBytes); |
||||
|
||||
// this is kept up to date with the midi messages that arrive, and the UI component
|
||||
// registers with it so it can represent the incoming messages
|
||||
MidiKeyboardState keyboardState; |
||||
void unbindUI(); |
||||
|
||||
void loadPreference(); |
||||
void savePreference(); |
||||
|
||||
static File dexedAppDir; |
||||
static File dexedCartDir; |
||||
private: |
||||
//==============================================================================
|
||||
DexedAudioProcessor; |
||||
|
||||
}; |
||||
|
||||
#endif // PLUGINPROCESSOR_H_INCLUDED
|
@ -1,203 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2015 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 3 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 "ProgramListBox.h" |
||||
#include "PluginData.h" |
||||
#include "DXLookNFeel.h" |
||||
#include "Dexed.h" |
||||
|
||||
ProgramListBox::ProgramListBox(const String name, int numCols) : Component(name) { |
||||
cols = numCols; |
||||
rows = 32 / numCols; |
||||
selectedPgm = -1; |
||||
hasContent = false; |
||||
dragCandidate = -1; |
||||
pgmCandidate = -1; |
||||
readOnly = false; |
||||
programNames.clear(); |
||||
} |
||||
|
||||
void ProgramListBox::paint(Graphics &g) { |
||||
int pgm = 0; |
||||
|
||||
g.setColour(Colour(20,18,18)); |
||||
g.fillRect(0,0,getWidth(), getHeight()); |
||||
g.setColour(Colour(0,0,0)); |
||||
g.drawLine(0,0,getWidth(), 0, 2); |
||||
g.setColour(Colour(3,3,1)); |
||||
g.drawLine(0,0,0,getHeight(),2); |
||||
g.setColour(Colour(34,32,32)); |
||||
g.drawLine(getWidth(), 3, getWidth(), getHeight(), 2); |
||||
g.setColour(Colour(75,73,73)); |
||||
g.drawLine(0,getHeight(),getWidth(),getHeight(), 2); |
||||
|
||||
const float dashLength[] = { 4, 4 }; |
||||
|
||||
g.setColour(Colour(83,76,69)); |
||||
for(int i=1;i<cols;i++) { |
||||
Line<float> line(cellWidth*i,0,cellWidth*i,getHeight()); |
||||
g.drawDashedLine(line, dashLength, 2); |
||||
} |
||||
for(int i=1;i<rows;i++) { |
||||
Line<float> line(2, cellHeight*i,getWidth(),cellHeight*i); |
||||
g.drawDashedLine(line, dashLength, 2); |
||||
} |
||||
|
||||
for(int i=0;i<cols;i++) { |
||||
for(int j=0;j<rows;j++) { |
||||
if ( selectedPgm == pgm && dragCandidate == -1 ) { |
||||
g.setColour(DXLookNFeel::fillColour); |
||||
g.fillRoundedRectangle(cellWidth*i+2, cellHeight*j + 2, cellWidth - 4, cellHeight - 4, 0); |
||||
} |
||||
|
||||
if ( hasContent == true ) { |
||||
if ( dragCandidate != pgm ) { |
||||
g.setColour(Colours::white); |
||||
g.drawFittedText(programNames[pgm], cellWidth * i , cellHeight * j, cellWidth, cellHeight, Justification::centred, true); |
||||
} else { |
||||
g.setColour(DXLookNFeel::fillColour); |
||||
g.fillRoundedRectangle(cellWidth*i+2, cellHeight*j + 2, cellWidth - 4, cellHeight - 4, 0); |
||||
} |
||||
|
||||
} |
||||
pgm++; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void ProgramListBox::resized() { |
||||
cellWidth = getWidth() / cols; |
||||
cellHeight = getHeight() / rows; |
||||
} |
||||
|
||||
void ProgramListBox::setCartridge(Cartridge &cart) { |
||||
cartContent = cart; |
||||
cartContent.getProgramNames(programNames); |
||||
hasContent = true; |
||||
repaint(); |
||||
} |
||||
|
||||
void ProgramListBox::addListener(ProgramListBoxListener *listener) { |
||||
this->listener = listener; |
||||
} |
||||
|
||||
int ProgramListBox::programPosition(int x, int y) { |
||||
return (y / cellHeight) + ((x / cellWidth) * rows); |
||||
} |
||||
|
||||
void ProgramListBox::mouseDown(const MouseEvent &event) { |
||||
pgmCandidate = -1; |
||||
|
||||
if ( ! hasContent ) |
||||
return; |
||||
|
||||
if ( event.mods.isRightButtonDown() ) { |
||||
int pos = programPosition(event.getMouseDownX(), event.getMouseDownY()); |
||||
if ( listener != nullptr ) |
||||
listener->programRightClicked(this, pos); |
||||
return; |
||||
} |
||||
|
||||
pgmCandidate = programPosition(event.getMouseDownX(), event.getMouseDownY()); |
||||
} |
||||
|
||||
void ProgramListBox::mouseUp(const MouseEvent &event) { |
||||
if ( pgmCandidate == -1 ) |
||||
return; |
||||
|
||||
int pos = programPosition(event.getMouseDownX(), event.getMouseDownY()); |
||||
if ( pgmCandidate == pos) { |
||||
if ( listener != nullptr ) |
||||
listener->programSelected(this, pgmCandidate); |
||||
pgmCandidate = -1; |
||||
} |
||||
} |
||||
|
||||
void ProgramListBox::mouseDrag(const MouseEvent &event) { |
||||
pgmCandidate = -1; |
||||
if ( ! hasContent ) |
||||
return; |
||||
if ( dragCandidate != -1 ) |
||||
return; |
||||
if ( event.getDistanceFromDragStart() < 7 ) |
||||
return; |
||||
|
||||
if (DragAndDropContainer* const dragContainer = DragAndDropContainer::findParentDragContainerFor(this)) { |
||||
Image snapshot (Image::ARGB, cellWidth, cellHeight, true); |
||||
int position = programPosition(event.getMouseDownX(), event.getMouseDownY()); |
||||
Graphics g(snapshot); |
||||
g.setColour(DXLookNFeel::lightBackground); |
||||
g.fillRect(0,0,cellWidth, cellHeight); |
||||
g.setColour(Colours::white); |
||||
g.drawFittedText(programNames[position], 0, 0, cellWidth, cellHeight, Justification::centred, true); |
||||
void *src = cartContent.getRawVoice() + (position*128); |
||||
var description = var(src, 128); |
||||
dragContainer->startDragging(description, this, snapshot, false); |
||||
} |
||||
} |
||||
|
||||
void ProgramListBox::setSelected(int idx) { |
||||
selectedPgm = idx; |
||||
} |
||||
|
||||
Cartridge &ProgramListBox::getCurrentCart() { |
||||
return cartContent; |
||||
} |
||||
|
||||
bool ProgramListBox::isInterestedInDragSource (const SourceDetails& dragSourceDetail) { |
||||
if ( readOnly ) |
||||
return false; |
||||
if ( ! hasContent ) |
||||
return false; |
||||
|
||||
Component *comp = dragSourceDetail.sourceComponent.get(); |
||||
if ( comp == nullptr ) |
||||
return false; |
||||
if ( dynamic_cast<ProgramListBox*>(comp) == nullptr ) |
||||
return false; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void ProgramListBox::itemDropped(const SourceDetails& dragSourceDetails) { |
||||
dragCandidate = programPosition(dragSourceDetails.localPosition.x, dragSourceDetails.localPosition.y); |
||||
|
||||
MemoryBlock* block = dragSourceDetails.description.getBinaryData(); |
||||
if ( listener != nullptr ) |
||||
listener->programDragged(this, dragCandidate, (char *)block->getData()); |
||||
dragCandidate = -1; |
||||
repaint(); |
||||
} |
||||
|
||||
void ProgramListBox::itemDragEnter(const SourceDetails &dragSourceDetails) { |
||||
dragCandidate = programPosition(dragSourceDetails.localPosition.x, dragSourceDetails.localPosition.y); |
||||
repaint(); |
||||
} |
||||
|
||||
void ProgramListBox::itemDragMove(const SourceDetails &dragSourceDetails) { |
||||
dragCandidate = programPosition(dragSourceDetails.localPosition.x, dragSourceDetails.localPosition.y); |
||||
repaint(); |
||||
} |
||||
|
||||
void ProgramListBox::itemDragExit(const SourceDetails &dragSourceDetails) { |
||||
dragCandidate = -1; |
||||
repaint(); |
||||
} |
||||
|
@ -1,74 +0,0 @@ |
||||
/**
|
||||
* |
||||
* Copyright (c) 2015 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 3 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 |
||||
* |
||||
*/ |
||||
|
||||
#ifndef PROGRAMLISTBOX_H_INCLUDED |
||||
#define PROGRAMLISTBOX_H_INCLUDED |
||||
|
||||
#include "JuceHeader.h" |
||||
#include "PluginData.h" |
||||
|
||||
class ProgramListBox; |
||||
class ProgramListBoxListener { |
||||
public: |
||||
virtual ~ProgramListBoxListener() {} |
||||
virtual void programSelected(ProgramListBox *source, int pos) = 0; |
||||
virtual void programRightClicked(ProgramListBox *source, int pos) = 0; |
||||
virtual void programDragged(ProgramListBox *destListBox, int dest, char *packedPgm) = 0; |
||||
}; |
||||
|
||||
class ProgramListBox : public Component, public DragAndDropTarget { |
||||
ProgramListBoxListener *listener; |
||||
bool hasContent; |
||||
bool showPgmNumber; |
||||
int cols, rows; |
||||
int cellWidth, cellHeight; |
||||
int programPosition(int x, int y); |
||||
int selectedPgm; |
||||
|
||||
Cartridge cartContent; |
||||
|
||||
int dragCandidate; |
||||
int pgmCandidate; |
||||
public: |
||||
StringArray programNames;
|
||||
|
||||
bool readOnly; |
||||
|
||||
ProgramListBox(const String name, int numCols); |
||||
void addListener(ProgramListBoxListener *listener); |
||||
void paint(Graphics &g) override; |
||||
void resized() override; |
||||
void mouseDown(const MouseEvent &event) override; |
||||
void mouseDrag(const MouseEvent &event) override; |
||||
void mouseUp(const MouseEvent &event) override; |
||||
void setSelected(int idx); |
||||
|
||||
Cartridge &getCurrentCart(); |
||||
void setCartridge(Cartridge &cart); |
||||
|
||||
bool isInterestedInDragSource(const SourceDetails& dragSourceDetails) override; |
||||
void itemDragEnter(const SourceDetails &dragSourceDetails) override; |
||||
void itemDragMove(const SourceDetails &dragSourceDetails) override; |
||||
void itemDragExit(const SourceDetails &dragSourceDetails) override; |
||||
void itemDropped(const SourceDetails& dragSourceDetails) override; |
||||
}; |
||||
|
||||
|
||||
#endif // PROGRAMLISTBOX_H_INCLUDED
|
@ -1,155 +0,0 @@ |
||||
/**
|
||||
* |
||||
* 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 3 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 "SysexComm.h" |
||||
#include "Dexed.h" |
||||
|
||||
SysexComm::SysexComm() { |
||||
sysexChl = 0; |
||||
listener = NULL; // this will get injected later
|
||||
|
||||
inputName = ""; |
||||
outputName = ""; |
||||
|
||||
input = NULL; |
||||
output = NULL; |
||||
inputOutput = false; |
||||
} |
||||
|
||||
SysexComm::~SysexComm() { |
||||
if ( input != NULL ) { |
||||
input->stop(); |
||||
delete input; |
||||
} |
||||
|
||||
if ( output != NULL ) |
||||
delete output; |
||||
} |
||||
|
||||
String SysexComm::getInput() { |
||||
return inputName; |
||||
} |
||||
|
||||
bool SysexComm::setInput(String target) { |
||||
if ( input != NULL ) { |
||||
input->stop(); |
||||
delete input; |
||||
input = NULL; |
||||
|
||||
} |
||||
inputOutput = false; |
||||
|
||||
if ( listener == NULL ) |
||||
return true; |
||||
|
||||
StringArray devices = MidiInput::getDevices(); |
||||
int idx = devices.indexOf(target); |
||||
|
||||
if ( idx == -1 ) { |
||||
TRACE("device %s not found", target.toRawUTF8()); |
||||
inputName = ""; |
||||
if ( target == "None" || target == "" ) |
||||
return true; |
||||
return false; |
||||
} |
||||
|
||||
input = MidiInput::openDevice(idx, listener); |
||||
if ( input == NULL ) { |
||||
TRACE("unable to open %s", target.toRawUTF8()); |
||||
return false; |
||||
} |
||||
|
||||
inputName = target; |
||||
TRACE("sysex %s opened", target.toRawUTF8()); |
||||
input->start(); |
||||
|
||||
if ( output ) |
||||
inputOutput = true; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
String SysexComm::getOutput() { |
||||
return outputName; |
||||
} |
||||
|
||||
bool SysexComm::setOutput(String target) { |
||||
if ( output != NULL ) { |
||||
delete output; |
||||
output = NULL; |
||||
} |
||||
inputOutput = false; |
||||
|
||||
StringArray devices = MidiOutput::getDevices(); |
||||
int idx = devices.indexOf(target); |
||||
|
||||
if ( idx == -1 ) { |
||||
TRACE("device %s not found", target.toRawUTF8()); |
||||
outputName = ""; |
||||
if ( target == "None" || target == "" ) |
||||
return true; |
||||
return false; |
||||
} |
||||
|
||||
output = MidiOutput::openDevice(idx); |
||||
if ( output == NULL ) { |
||||
TRACE("unable to open %s", target.toRawUTF8()); |
||||
return false; |
||||
} |
||||
|
||||
outputName = target; |
||||
|
||||
if ( input ) |
||||
inputOutput = true; |
||||
|
||||
TRACE("sysex %s opened", target.toRawUTF8()); |
||||
return true; |
||||
} |
||||
|
||||
bool SysexComm::isInputActive() { |
||||
return input != NULL; |
||||
} |
||||
|
||||
bool SysexComm::isOutputActive() { |
||||
return output != NULL; |
||||
} |
||||
|
||||
int SysexComm::getChl() { |
||||
return sysexChl; |
||||
} |
||||
|
||||
void SysexComm::setChl(int chl) { |
||||
sysexChl = chl; |
||||
} |
||||
|
||||
int SysexComm::send(const MidiMessage &message) { |
||||
if ( output == NULL ) |
||||
return 2; |
||||
|
||||
TRACE("send sysex"); |
||||
|
||||
outActivity = true; |
||||
output->sendMessageNow(message); |
||||
return 0; |
||||
} |
||||
|
||||
void SysexComm::playBuffer(MidiBuffer &keyboardEvents, int numSamples ) { |
||||
noteOutput.addEvents(keyboardEvents, 0, numSamples, 0); |
||||
} |
@ -1,60 +0,0 @@ |
||||
/**
|
||||
* |
||||
* 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 3 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 |
||||
* |
||||
*/ |
||||
|
||||
#ifndef SYSEXCOMM_H_INCLUDED |
||||
#define SYSEXCOMM_H_INCLUDED |
||||
|
||||
class SysexComm { |
||||
MidiInput *input; |
||||
MidiOutput *output; |
||||
String inputName; |
||||
String outputName; |
||||
int sysexChl; |
||||
|
||||
bool inputOutput; |
||||
|
||||
MidiBuffer noteOutput; |
||||
public : |
||||
MidiInputCallback *listener; |
||||
bool inActivity; |
||||
bool outActivity; |
||||
|
||||
SysexComm(); |
||||
~SysexComm(); |
||||
|
||||
bool setInput(String name); |
||||
bool setOutput(String name); |
||||
void setChl(int chl); |
||||
|
||||
String getInput(); |
||||
String getOutput(); |
||||
int getChl(); |
||||
|
||||
bool isInputActive(); |
||||
bool isOutputActive(); |
||||
inline bool isInputOutputActive() { |
||||
return inputOutput; |
||||
} |
||||
|
||||
int send(const MidiMessage& message); |
||||
void playBuffer(MidiBuffer &keyboardEvents, int numSamples); |
||||
}; |
||||
|
||||
#endif // SYSEXCOMM_H_INCLUDED
|
@ -1,76 +0,0 @@ |
||||
/*
|
||||
* Copyright 2012 Google Inc. |
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#include <time.h> |
||||
#include <string.h> |
||||
|
||||
#include "synth.h" |
||||
#include "ringbuffer.h" |
||||
|
||||
RingBuffer::RingBuffer() { |
||||
rd_ix_ = 0; |
||||
wr_ix_ = 0; |
||||
} |
||||
|
||||
int RingBuffer::BytesAvailable() { |
||||
return (wr_ix_ - rd_ix_) & (kBufSize - 1); |
||||
} |
||||
|
||||
int RingBuffer::WriteBytesAvailable() { |
||||
return (rd_ix_ - wr_ix_ - 1) & (kBufSize - 1); |
||||
} |
||||
|
||||
int RingBuffer::Read(int size, uint8_t *bytes) { |
||||
int rd_ix = rd_ix_; |
||||
SynthMemoryBarrier(); // read barrier, make sure data is committed before ix
|
||||
int fragment_size = min(size, kBufSize - rd_ix); |
||||
memcpy(bytes, buf_ + rd_ix, fragment_size); |
||||
if (size > fragment_size) { |
||||
memcpy(bytes + fragment_size, buf_, size - fragment_size); |
||||
} |
||||
SynthMemoryBarrier(); // full barrier, make sure read commits before updating
|
||||
rd_ix_ = (rd_ix + size) & (kBufSize - 1); |
||||
return size; |
||||
} |
||||
|
||||
int RingBuffer::Write(const uint8_t *bytes, int size) { |
||||
int remaining = size; |
||||
while (remaining > 0) { |
||||
int rd_ix = rd_ix_; |
||||
int wr_ix = wr_ix_; |
||||
int space_available = (rd_ix - wr_ix - 1) & (kBufSize - 1); |
||||
if (space_available == 0) { |
||||
struct timespec sleepTime; |
||||
sleepTime.tv_sec = 0; |
||||
sleepTime.tv_nsec = 1000000; |
||||
nanosleep(&sleepTime, NULL); |
||||
} else { |
||||
int wr_size = min(remaining, space_available); |
||||
int fragment_size = min(wr_size, kBufSize - wr_ix); |
||||
memcpy(buf_ + wr_ix, bytes, fragment_size); |
||||
if (wr_size > fragment_size) { |
||||
memcpy(buf_, bytes + fragment_size, wr_size - fragment_size); |
||||
} |
||||
SynthMemoryBarrier(); // write barrier, make sure data commits
|
||||
wr_ix_ = (wr_ix + wr_size) & (kBufSize - 1); |
||||
remaining -= wr_size; |
||||
bytes += wr_size; |
||||
} |
||||
} |
||||
// JJK : defined as returning int
|
||||
return 0; |
||||
} |
||||
|
@ -1,44 +0,0 @@ |
||||
/*
|
||||
* Copyright 2012 Google Inc. |
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#ifndef SYNTH_RINGBUFFER_H_ |
||||
#define SYNTH_RINGBUFFER_H_ |
||||
|
||||
class RingBuffer { |
||||
public: |
||||
RingBuffer(); |
||||
|
||||
// Returns number of bytes available for reading.
|
||||
int BytesAvailable(); |
||||
|
||||
// Returns number of bytes that can be written without blocking.
|
||||
int WriteBytesAvailable(); |
||||
|
||||
// Reads bytes. It is the caller's responsibility to make sure that
|
||||
// size <= a previous value of BytesAvailable().
|
||||
int Read(int size, uint8_t *bytes); |
||||
|
||||
// Writes bytes into the buffer. If the buffer is full, the method will
|
||||
// block until space is available.
|
||||
int Write(const uint8_t *bytes, int size); |
||||
private: |
||||
static const int kBufSize = 8192; |
||||
uint8_t buf_[kBufSize]; |
||||
volatile unsigned int rd_ix_; |
||||
volatile unsigned int wr_ix_; |
||||
}; |
||||
|
||||
#endif // SYNTH_RINGBUFFER_H_
|
Loading…
Reference in new issue