Browse Source

Update dexed to latest upstream code

tags/2018-04-16
falkTX 6 years ago
parent
commit
fb62971d56
45 changed files with 3100 additions and 2132 deletions
  1. +86
    -65
      ports/dexed/source/AlgoDisplay.cpp
  2. +3
    -1
      ports/dexed/source/AlgoDisplay.h
  3. +806
    -974
      ports/dexed/source/BinaryData.cpp
  4. +7
    -4
      ports/dexed/source/BinaryData.h
  5. +78
    -49
      ports/dexed/source/CartManager.cpp
  6. +9
    -7
      ports/dexed/source/CartManager.h
  7. +45
    -18
      ports/dexed/source/DXComponents.cpp
  8. +5
    -4
      ports/dexed/source/DXComponents.h
  9. +6
    -1
      ports/dexed/source/DXLookNFeel.cpp
  10. +6
    -5
      ports/dexed/source/DXLookNFeel.h
  11. +15
    -2
      ports/dexed/source/Dexed.h
  12. +219
    -170
      ports/dexed/source/EngineMkI.cpp
  13. +8
    -9
      ports/dexed/source/EngineMkI.h
  14. +16
    -4
      ports/dexed/source/EngineOpl.cpp
  15. +1
    -1
      ports/dexed/source/EngineOpl.h
  16. +88
    -5
      ports/dexed/source/GlobalEditor.cpp
  17. +6
    -2
      ports/dexed/source/GlobalEditor.h
  18. +2
    -2
      ports/dexed/source/JucePluginCharacteristics.h
  19. +36
    -7
      ports/dexed/source/OperatorEditor.cpp
  20. +7
    -8
      ports/dexed/source/OperatorEditor.h
  21. +364
    -7
      ports/dexed/source/ParamDialog.cpp
  22. +21
    -3
      ports/dexed/source/ParamDialog.h
  23. +130
    -138
      ports/dexed/source/PluginData.cpp
  24. +220
    -40
      ports/dexed/source/PluginData.h
  25. +34
    -73
      ports/dexed/source/PluginEditor.cpp
  26. +2
    -6
      ports/dexed/source/PluginEditor.h
  27. +16
    -0
      ports/dexed/source/PluginFx.cpp
  28. +4
    -0
      ports/dexed/source/PluginFx.h
  29. +199
    -47
      ports/dexed/source/PluginParam.cpp
  30. +1
    -0
      ports/dexed/source/PluginParam.h
  31. +127
    -65
      ports/dexed/source/PluginProcessor.cpp
  32. +11
    -7
      ports/dexed/source/PluginProcessor.h
  33. +26
    -19
      ports/dexed/source/ProgramListBox.cpp
  34. +11
    -9
      ports/dexed/source/ProgramListBox.h
  35. +0
    -3
      ports/dexed/source/SysexComm.cpp
  36. +94
    -11
      ports/dexed/source/msfa/controllers.h
  37. +192
    -172
      ports/dexed/source/msfa/dx7note.cc
  38. +41
    -40
      ports/dexed/source/msfa/dx7note.h
  39. +79
    -69
      ports/dexed/source/msfa/env.cc
  40. +3
    -1
      ports/dexed/source/msfa/env.h
  41. +3
    -4
      ports/dexed/source/msfa/fm_core.cc
  42. +10
    -11
      ports/dexed/source/msfa/fm_core.h
  43. +61
    -61
      ports/dexed/source/msfa/lfo.cc
  44. +1
    -1
      ports/dexed/source/msfa/lfo.h
  45. +1
    -7
      ports/dexed/source/msfa/synth.h

+ 86
- 65
ports/dexed/source/AlgoDisplay.cpp View File

@@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2014 Pascal Gauthier.
* Copyright (c) 2014, 2017 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
@@ -27,82 +27,103 @@ AlgoDisplay::AlgoDisplay() {
algo = &tmpAlgo;
}
inline void displayOp(Graphics &g, char id, int x, int y, char link, char fb) {
void AlgoDisplay::displayOp(Graphics &g, char id, int x, int y, char link, char fb) {
const int LINE_SZ = 3;
String t(id);
bool opOn = opStatus[6-id] == '1';
x *= 25;
x += 3;
y *= 21;
y += 5;
g.setColour(Colours::white);
if ( opOn )
g.setColour(Colours::white);
else
g.setColour(DXLookNFeel::roundBackground);
g.drawText(t, x, y, 16, 12, Justification::centred, true);
g.setColour(DXLookNFeel::fillColour);
if ( opOn )
g.setColour(DXLookNFeel::fillColour);
else
g.setColour(DXLookNFeel::roundBackground);
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 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;
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+20, y-4, LINE_SZ);
g.drawLine(x+19, y-4, x+19, y+15, LINE_SZ);
g.drawLine(x+18, y+15, x+19, y+15, 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;
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);
@@ -249,7 +270,7 @@ void AlgoDisplay::paint(Graphics &g) {
displayOp(g, 1, 3, 3, 0, 0);
break;
case 18:
displayOp(g, 6, 3, 2, 0, 1);
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);
@@ -260,20 +281,20 @@ void AlgoDisplay::paint(Graphics &g) {
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, 0, 1);
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, 0, 0);
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, 0, 1);
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, 0, 1);
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);
@@ -281,7 +302,7 @@ void AlgoDisplay::paint(Graphics &g) {
displayOp(g, 1, 1, 3, 1, 0);
break;
case 22: // CC
displayOp(g, 6, 3, 2, 0, 1);
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);
@@ -289,7 +310,7 @@ void AlgoDisplay::paint(Graphics &g) {
displayOp(g, 1, 1, 3, 1, 0);
break;
case 23: // CC
displayOp(g, 6, 3, 2, 0, 1);
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);
@@ -297,7 +318,7 @@ void AlgoDisplay::paint(Graphics &g) {
displayOp(g, 1, 0, 3, 1, 0);
break;
case 24: // CC
displayOp(g, 6, 3, 2, 0, 1);
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);
@@ -350,7 +371,7 @@ void AlgoDisplay::paint(Graphics &g) {
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);
displayOp(g, 1, 0, 3, 1, 0);
break;
case 31:
displayOp(g, 6, 5, 3, 2, 1);


+ 3
- 1
ports/dexed/source/AlgoDisplay.h View File

@@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2014 Pascal Gauthier.
* Copyright (c) 2014-2017 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
@@ -24,7 +24,9 @@
#include "JuceHeader.h"
class AlgoDisplay : public Component {
void displayOp(Graphics &g, char id, int x, int y, char link, char fb);
public:
const char *opStatus;
AlgoDisplay();
char *algo;
void paint(Graphics &g);


+ 806
- 974
ports/dexed/source/BinaryData.cpp
File diff suppressed because it is too large
View File


+ 7
- 4
ports/dexed/source/BinaryData.h View File

@@ -9,6 +9,9 @@
namespace BinaryData
{
extern const char* Switch_32x32_png;
const int Switch_32x32_pngSize = 841;
extern const char* Switch_48x26_png;
const int Switch_48x26_pngSize = 2261;
@@ -43,19 +46,19 @@ namespace BinaryData
const int builtin_pgm_zipSize = 88890;
extern const char* about_png;
const int about_pngSize = 23143;
const int about_pngSize = 24863;
extern const char* GlobalEditor_864x144_png;
const int GlobalEditor_864x144_pngSize = 27571;
const int GlobalEditor_864x144_pngSize = 17334;
extern const char* OperatorEditor_287x218_png;
const int OperatorEditor_287x218_pngSize = 15614;
const int OperatorEditor_287x218_pngSize = 10927;
// Points to the start of a list of resource names.
extern const char* namedResourceList[];
// Number of elements in the namedResourceList array.
const int namedResourceListSize = 14;
const int namedResourceListSize = 15;
// If you provide the name of one of the binary resource variables above, this function will
// return the corresponding data and its size (or a null pointer if the name isn't found).


+ 78
- 49
ports/dexed/source/CartManager.cpp View File

@@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2015 Pascal Gauthier.
* Copyright (c) 2015-2017 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
@@ -31,15 +31,48 @@ class SyxFileFilter : public FileFilter {
public:
SyxFileFilter() : FileFilter(".syx") {}
bool isFileSuitable(const File &file) const {
return file.getFileExtension().toLowerCase() == ".syx" && file.getSize() == 4104;
return file.getFileExtension().toLowerCase() == ".syx" && file.getSize() >= 4096;
}
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);
}
}
refresh();
}
};
CartManager::CartManager(DexedAudioProcessorEditor *editor) : Component("CartManager") {
mainWindow = editor;
cartDir = DexedAudioProcessor::dexedCartDir;
@@ -57,8 +90,10 @@ CartManager::CartManager(DexedAudioProcessorEditor *editor) : Component("CartMan
timeSliceThread->startThread();
cartBrowserList = new DirectoryContentsList(syxFileFilter, *timeSliceThread);
cartBrowserList->setDirectory(cartDir, true, true);
cartBrowser = new FileTreeComponent(*cartBrowserList);
cartBrowser = new FileTreeDrop(*cartBrowserList);
cartBrowser->addKeyListener(this);
addAndMakeVisible(cartBrowser);
cartBrowser->setBounds(23, 18, 590, 384);
cartBrowser->setDragAndDropDescription("Sysex Browser");
cartBrowser->addListener(this);
@@ -82,7 +117,7 @@ CartManager::CartManager(DexedAudioProcessorEditor *editor) : Component("CartMan
*
* 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);
@@ -90,7 +125,6 @@ CartManager::CartManager(DexedAudioProcessorEditor *editor) : Component("CartMan
addAndMakeVisible(getDXCartButton = new TextButton("GET DX7 CART"));
getDXCartButton->setBounds(755, 545, 100, 30);
getDXCartButton->addListener(this);
*/
}
@@ -115,10 +149,8 @@ void CartManager::programSelected(ProgramListBox *source, int pos) {
mainWindow->processor->setCurrentProgram(pos);
mainWindow->processor->updateHostDisplay();
} else {
if ( source->getCurrentCart() == nullptr )
return;
char unpackPgm[161];
unpackProgramFromSysex(unpackPgm, source->getCurrentCart(), pos);
uint8_t unpackPgm[161];
source->getCurrentCart().unpackProgram(unpackPgm, pos);
activeCart->setSelected(-1);
browserCart->setSelected(pos);
repaint();
@@ -177,11 +209,11 @@ void CartManager::fileDoubleClicked(const File& file) {
if ( file.isDirectory() )
return;
mainWindow->loadCart(file);
activeCart->setCartridge(mainWindow->processor->sysex);
activeCart->setCartridge(mainWindow->processor->currentCart);
}
void CartManager::fileClicked(const File& file, const MouseEvent& e) {
if ( e.mods.isRightButtonDown() ) {
if ( e.mods.isRightButtonDown() || e.mods.isAnyModifierKeyDown() ) {
PopupMenu menu;
menu.addItem(1000, "Open location");
@@ -215,7 +247,7 @@ void CartManager::setActiveProgram(int idx, String activeName) {
}
void CartManager::resetActiveSysex() {
activeCart->setCartridge(mainWindow->processor->sysex);
activeCart->setCartridge(mainWindow->processor->currentCart);
}
void CartManager::selectionChanged() {
@@ -227,21 +259,14 @@ void CartManager::selectionChanged() {
if ( file.isDirectory() )
return;
String f = file.getFullPathName();
uint8_t syx_data[4104];
ifstream fp_in(f.toRawUTF8(), ios::binary);
if (fp_in.fail()) {
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Error", "Unable to open: " + f);
Cartridge browserSysex;
int rc = browserSysex.load(file);
if ( rc < 0 ) {
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Error", "Unable to open file");
return;
}
fp_in.read((char *)syx_data, 4104);
fp_in.close();
char browserSysex[4104];
memcpy(browserSysex, syx_data+6, 4096);
int checksum = sysexChecksum(((char *) &browserSysex), 4096);
if ( checksum != syx_data[4102] ) {
if ( rc != 0 ) {
browserCart->readOnly = true;
} else {
browserCart->readOnly = false;
@@ -260,19 +285,19 @@ void CartManager::programRightClicked(ProgramListBox *source, int pos) {
switch(menu.show()) {
case 1000:
char unpackPgm[161];
uint8_t unpackPgm[161];
if ( source == activeCart ) {
unpackProgramFromSysex(unpackPgm, mainWindow->processor->sysex, pos);
mainWindow->processor->currentCart.unpackProgram(unpackPgm, pos);
} else {
char *sysex = source->getCurrentCart();
if ( sysex == nullptr )
return;
unpackProgramFromSysex(unpackPgm, sysex, pos);
source->getCurrentCart().unpackProgram(unpackPgm, pos);
}
if ( mainWindow->processor->sysexComm.isOutputActive() )
mainWindow->processor->sysexComm.send(MidiMessage(unpackPgm, 161));
if ( mainWindow->processor->sysexComm.isOutputActive() ) {
uint8_t msg[163];
exportSysexPgm(msg, unpackPgm);
mainWindow->processor->sysexComm.send(MidiMessage(msg, 163));
}
break;
case 1010:
@@ -284,7 +309,7 @@ void CartManager::programRightClicked(ProgramListBox *source, int pos) {
void CartManager::programDragged(ProgramListBox *destListBox, int dest, char *packedPgm) {
if ( destListBox == activeCart ) {
char *sysex = mainWindow->processor->sysex;
char *sysex = mainWindow->processor->currentCart.getRawVoice();
memcpy(sysex+(dest*128), packedPgm, 128);
mainWindow->updateUI();
} else {
@@ -295,22 +320,14 @@ void CartManager::programDragged(ProgramListBox *destListBox, int dest, char *pa
if ( file.isDirectory() )
return;
if ( file.getSize() > 5000 )
return;
MemoryBlock block;
file.loadFileAsData(block);
if ( block.getSize() < 4104 )
if ( file.getSize() != 4104 && file.getSize() != 4096 )
return;
char *sysex = ((char *) block.getData()) + 6;
memcpy(sysex+(dest*128), packedPgm, 128);
char exported[4104];
exportSysexCart(exported, sysex, 0);
file.replaceWithData(exported, 4104);
browserCart->setCartridge(sysex);
Cartridge cart;
cart.load(file);
memcpy(cart.getRawVoice()+(dest*128), packedPgm, 128);
cart.saveVoice(file);
browserCart->setCartridge(cart);
}
}
@@ -318,6 +335,18 @@ 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"


+ 9
- 7
ports/dexed/source/CartManager.h View File

@@ -24,9 +24,10 @@
#include "JuceHeader.h"
#include "PluginData.h"
#include "ProgramListBox.h"
#include "PluginData.h"
class CartManager : public Component, public ButtonListener, public DragAndDropContainer, public FileBrowserListener
, public ProgramListBoxListener {
, public ProgramListBoxListener, public KeyListener {
ScopedPointer<TextButton> newButton;
ScopedPointer<TextButton> loadButton;
ScopedPointer<TextButton> saveButton;
@@ -53,13 +54,13 @@ class CartManager : public Component, public ButtonListener, public DragAndDrop
public:
CartManager(DexedAudioProcessorEditor *editor);
virtual ~CartManager();
void paint(Graphics& g);
void buttonClicked (Button* buttonThatWasClicked);
void paint(Graphics& g) override;
void buttonClicked (Button* buttonThatWasClicked) override;
void selectionChanged();
void fileClicked (const File& file, const MouseEvent& e);
void fileDoubleClicked (const File& file);
void browserRootChanged (const File& newRoot);
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();
@@ -67,6 +68,7 @@ public:
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();
};


+ 45
- 18
ports/dexed/source/DXComponents.cpp View File

@@ -1,4 +1,4 @@
/**
/**
*
* Copyright (c) 2014 Pascal Gauthier.
*
@@ -157,13 +157,13 @@ static double getDuration(int p_rate, int p_level_l, int p_level_r) {
}
EnvDisplay::EnvDisplay() {
pvalues = (char *) &TMP_LEVEL_PTR;
pvalues = (uint8_t *) &TMP_LEVEL_PTR;
}
void EnvDisplay::paint(Graphics &g) {
int h = getHeight();
char *rates = pvalues;
char *levels = pvalues + 4;
uint8_t *rates = pvalues;
uint8_t *levels = pvalues + 4;
double d[4];
double keyoff = 0.0;
@@ -250,15 +250,15 @@ void EnvDisplay::paint(Graphics &g) {
}
PitchEnvDisplay::PitchEnvDisplay() {
pvalues = (char *) &TMP_LEVEL_PTR;
pvalues = (uint8_t *) &TMP_LEVEL_PTR;
vPos = 0;
}
void PitchEnvDisplay::paint(Graphics &g) {
g.setColour(Colours::white);
char *levels = pvalues + 4;
char *rates = pvalues;
uint8_t *levels = pvalues + 4;
uint8_t *rates = pvalues;
float dist[4];
float total = 0;
@@ -363,25 +363,22 @@ ComboBoxImage::ComboBoxImage() {
itemPos[0] = -1;
}
static void comboBoxPopupMenuFinishedCallback (int result, ComboBoxImage* combo)
{
if (combo != nullptr)
{
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));
.withItemThatMustBeVisible(getSelectedId())
.withMinimumWidth(getWidth())
.withMaximumNumColumns(1)
.withStandardItemHeight(itemHeight),
ModalCallbackFunction::forComponent(comboBoxPopupMenuFinishedCallback, this));
}
void ComboBoxImage::setImage(Image image) {
@@ -411,5 +408,35 @@ void ComboBoxImage::setImage(Image image, int pos[]) {
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);
}

+ 5
- 4
ports/dexed/source/DXComponents.h View File

@@ -22,11 +22,12 @@
#define DXCOMPONENTS_H_INCLUDED
#include "JuceHeader.h"
#include <stdint.h>
class EnvDisplay : public Component {
public:
EnvDisplay();
char *pvalues;
uint8_t *pvalues;
char vPos;
void paint(Graphics &g);
};
@@ -35,7 +36,7 @@ class PitchEnvDisplay : public Component {
char rvalues[8];
public:
PitchEnvDisplay();
char *pvalues;
uint8_t *pvalues;
char vPos;
void paint(Graphics &g);
};
@@ -58,12 +59,11 @@ class ComboBoxImage : public ComboBox {
Image items;
int itemHeight;
PopupMenu popup;
int itemPos[4];
public:
ComboBoxImage();
virtual void paint(Graphics &g);
virtual void paint(Graphics &g) override;
virtual void showPopup() override;
void setImage(Image image);
void setImage(Image image, int pos[]);
@@ -71,6 +71,7 @@ public:
class ProgramSelector : public ComboBox {
public:
void mouseDown(const MouseEvent &event) override;
virtual void paint(Graphics &g) override;
};


+ 6
- 1
ports/dexed/source/DXLookNFeel.cpp View File

@@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2013-2014 Pascal Gauthier.
* 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
@@ -64,6 +64,7 @@ DXLookNFeel::DXLookNFeel() {
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);;
@@ -119,6 +120,10 @@ DXLookNFeel::DXLookNFeel() {
imageSwitch = findImage(path);
continue;
}
if ( name == "Switch_32x64.png" ) {
imageSwitchOperator = findImage(path);
continue;
}
if ( name == "ButtonUnlabeled_50x30.png" ) {
imageButton = findImage(path);
continue;


+ 6
- 5
ports/dexed/source/DXLookNFeel.h View File

@@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2013-2014 Pascal Gauthier.
* 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
@@ -35,11 +35,12 @@ public:
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 );
virtual void drawToggleButton(Graphics& g, ToggleButton& button, bool isMouseOverButton, bool isButtonDown);
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;
@@ -49,8 +50,8 @@ public:
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 &);
virtual void positionComboBoxText (ComboBox& box, Label& label);
virtual Typeface::Ptr getTypefaceForFont(const Font &) override;
virtual void positionComboBoxText (ComboBox& box, Label& label) override;
static DXLookNFeel *getLookAndFeel();
static Colour fillColour;


+ 15
- 2
ports/dexed/source/Dexed.h View File

@@ -21,7 +21,20 @@
#ifndef DEXED_H_INCLUDED
#define DEXED_H_INCLUDED
#define DEXED_VERSION "0.9.0"
#define TRACE(fmt, ...)
void dexed_trace(const char *source, const char *fmt, ...);
#define DEXED_ID "0.9.4"
#ifdef DEBUG
#define DEXED_VERSION DEXED_ID " DEBUG"
#ifdef _MSC_VER
#define TRACE(fmt, ...) dexed_trace(__FUNCTION__,fmt,##__VA_ARGS__)
#else
#define TRACE(fmt, ...) dexed_trace(__PRETTY_FUNCTION__,fmt,##__VA_ARGS__)
#endif
#else
#define DEXED_VERSION DEXED_ID
#define TRACE(fmt, ...)
#endif
#endif // DEXED_H_INCLUDED

+ 219
- 170
ports/dexed/source/EngineMkI.cpp View File

@@ -1,155 +1,211 @@
/*
* Copyright 2014 Pascal Gauthier.
* Copyright 2012 Google Inc.
* Copyright (C) 2015-2017 Pascal Gauthier.
*
* 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
* 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.
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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
*
* The code is based on ppplay https://github.com/stohrendorf/ppplay and opl3
* math documentation :
* https://github.com/gtaylormb/opl3_fpga/blob/master/docs/opl3math/opl3math.pdf
*
* 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 "EngineMkI.h"
#include <math.h>
#define _USE_MATH_DEFINES
#include <cmath>
#include <cstdlib>
#include "msfa/sin.h"
#include "msfa/exp2.h"
const FmAlgorithm EngineMkI::algo2[32] = {
{ { 0xc1, 0x11, 0x11, 0x14, 0x01, 0x14 } }, // 1
{ { 0x01, 0x11, 0x11, 0x14, 0xc1, 0x14 } }, // 2
{ { 0xc1, 0x11, 0x14, 0x01, 0x11, 0x14 } }, // 3
{ { 0xc4, 0x00, 0x00, 0x01, 0x11, 0x14 } }, // 4 ** EXCEPTION VIA CODE
{ { 0xc1, 0x14, 0x01, 0x14, 0x01, 0x14 } }, // 5
{ { 0xc4, 0x00, 0x01, 0x14, 0x01, 0x14 } }, // 6 ** EXCEPTION VIA CODE
{ { 0xc1, 0x11, 0x05, 0x14, 0x01, 0x14 } }, // 7
{ { 0x01, 0x11, 0xc5, 0x14, 0x01, 0x14 } }, // 8
{ { 0x01, 0x11, 0x05, 0x14, 0xc1, 0x14 } }, // 9
{ { 0x01, 0x05, 0x14, 0xc1, 0x11, 0x14 } }, // 10
{ { 0xc1, 0x05, 0x14, 0x01, 0x11, 0x14 } }, // 11
{ { 0x01, 0x05, 0x05, 0x14, 0xc1, 0x14 } }, // 12
{ { 0xc1, 0x05, 0x05, 0x14, 0x01, 0x14 } }, // 13
{ { 0xc1, 0x05, 0x11, 0x14, 0x01, 0x14 } }, // 14
{ { 0x01, 0x05, 0x11, 0x14, 0xc1, 0x14 } }, // 15
{ { 0xc1, 0x11, 0x02, 0x25, 0x05, 0x14 } }, // 16
{ { 0x01, 0x11, 0x02, 0x25, 0xc5, 0x14 } }, // 17
{ { 0x01, 0x11, 0x11, 0xc5, 0x05, 0x14 } }, // 18
{ { 0xc1, 0x14, 0x14, 0x01, 0x11, 0x14 } }, // 19
{ { 0x01, 0x05, 0x14, 0xc1, 0x14, 0x14 } }, // 20
{ { 0x01, 0x14, 0x14, 0xc1, 0x14, 0x14 } }, // 21
{ { 0xc1, 0x14, 0x14, 0x14, 0x01, 0x14 } }, // 22
{ { 0xc1, 0x14, 0x14, 0x01, 0x14, 0x04 } }, // 23
{ { 0xc1, 0x14, 0x14, 0x14, 0x04, 0x04 } }, // 24
{ { 0xc1, 0x14, 0x14, 0x04, 0x04, 0x04 } }, // 25
{ { 0xc1, 0x05, 0x14, 0x01, 0x14, 0x04 } }, // 26
{ { 0x01, 0x05, 0x14, 0xc1, 0x14, 0x04 } }, // 27
{ { 0x04, 0xc1, 0x11, 0x14, 0x01, 0x14 } }, // 28
{ { 0xc1, 0x14, 0x01, 0x14, 0x04, 0x04 } }, // 29
{ { 0x04, 0xc1, 0x11, 0x14, 0x04, 0x04 } }, // 30
{ { 0xc1, 0x14, 0x04, 0x04, 0x04, 0x04 } }, // 31
{ { 0xc4, 0x04, 0x04, 0x04, 0x04, 0x04 } }, // 32
};
#ifdef DEBUG
#include "time.h"
//#define MKIDEBUG
#endif
#ifdef _WIN32
#if _MSC_VER < 1800
double log2(double n) {
return log(n) / log(2.0);
}
double round(double n) {
return n < 0.0 ? ceil(n - 0.5) : floor(n + 0.5);
}
#endif
__declspec(align(16)) const int zeros[N] = {0};
#else
const int32_t __attribute__ ((aligned(16))) zeros[N] = {0};
#endif
static const uint16_t NEGATIVE_BIT = 0x8000;
static const uint16_t ENV_BITDEPTH = 14;
static const uint16_t SINLOG_BITDEPTH = 10;
static const uint16_t SINLOG_TABLESIZE = 1<<SINLOG_BITDEPTH;
static uint16_t sinLogTable[SINLOG_TABLESIZE];
static const uint16_t SINEXP_BITDEPTH = 10;
static const uint16_t SINEXP_TABLESIZE = 1<<SINEXP_BITDEPTH;
static uint16_t sinExpTable[SINEXP_TABLESIZE];
const uint16_t ENV_MAX = 1<<ENV_BITDEPTH;
static inline uint16_t sinLog(uint16_t phi) {
const uint16_t SINLOG_TABLEFILTER = SINLOG_TABLESIZE-1;
const uint16_t index = (phi & SINLOG_TABLEFILTER);
switch( ( phi & (SINLOG_TABLESIZE * 3) ) ) {
case 0:
return sinLogTable[index];
case SINLOG_TABLESIZE:
return sinLogTable[index ^ SINLOG_TABLEFILTER];
case SINLOG_TABLESIZE * 2 :
return sinLogTable[index] | NEGATIVE_BIT;
default:
return sinLogTable[index ^ SINLOG_TABLEFILTER] | NEGATIVE_BIT;
}
}
EngineMkI::EngineMkI() {
float bitReso = SINLOG_TABLESIZE;
for(int i=0;i<SINLOG_TABLESIZE;i++) {
float x1 = sin(((0.5+i)/bitReso) * M_PI/2.0);
sinLogTable[i] = round(-1024 * log2(x1));
}
bitReso = SINEXP_TABLESIZE;
for(int i=0;i<SINEXP_TABLESIZE;i++) {
float x1 = (pow(2, float(i)/bitReso)-1) * 4096;
sinExpTable[i] = round(x1);
}
#ifdef MKIDEBUG
char buffer[4096];
int pos = 0;
TRACE("****************************************");
for(int i=0;i<SINLOG_TABLESIZE;i++) {
pos += sprintf(buffer+pos, "%d ", sinLogTable[i]);
if ( pos > 90 ) {
TRACE("SINLOGTABLE: %s" ,buffer);
buffer[0] = 0;
pos = 0;
}
}
TRACE("SINLOGTABLE: %s", buffer);
buffer[0] = 0;
pos = 0;
TRACE("----------------------------------------");
for(int i=0;i<SINEXP_TABLESIZE;i++) {
pos += sprintf(buffer+pos, "%d ", sinExpTable[i]);
if ( pos > 90 ) {
TRACE("SINEXTTABLE: %s" ,buffer);
buffer[0] = 0;
pos = 0;
}
}
TRACE("SINEXTTABLE: %s", buffer);
TRACE("****************************************");
#endif
}
inline int32_t mkiSin(int32_t phase, uint16_t env) {
uint16_t expVal = sinLog(phase >> (22 - SINLOG_BITDEPTH)) + (env);
//int16_t expValShow = expVal;
const bool isSigned = expVal & NEGATIVE_BIT;
expVal &= ~NEGATIVE_BIT;
const uint16_t SINEXP_FILTER = 0x3FF;
uint16_t result = 4096 + sinExpTable[( expVal & SINEXP_FILTER ) ^ SINEXP_FILTER];
//uint16_t resultB4 = result;
result >>= ( expVal >> 10 ); // exp
#ifdef MKIDEBUG
if ( ( time(NULL) % 5 ) == 0 ) {
if ( expValShow < 0 ) {
expValShow = (expValShow + 0x7FFF) * -1;
}
//TRACE(",%d,%d,%d,%d,%d,%d", phase >> (22 - SINLOG_BITDEPTH), env, expValShow, ( expVal & SINEXP_FILTER ) ^ SINEXP_FILTER, resultB4, result);
}
#endif
if( isSigned )
return (-result - 1) << 13;
else
return result << 13;
}
void EngineMkI::compute(int32_t *output, const int32_t *input,
int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, bool add, const Controllers *controllers) {
int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N;
int32_t gain = gain1;
int32_t phase = phase0;
if (add) {
for (int i = 0; i < N; i++) {
gain += dgain;
int32_t y = Sin::lookup(phase + input[i]);
y &= controllers->sinBitFilter;
int32_t y1 = ((int64_t)y * (int64_t)gain) >> 24;
output[i] += y1;
phase += freq;
}
} else {
for (int i = 0; i < N; i++) {
gain += dgain;
int32_t y = Sin::lookup(phase + input[i]);
y &= controllers->sinBitFilter;
int32_t y1 = ((int64_t)y * (int64_t)gain) >> 24;
output[i] = y1;
phase += freq;
}
const int32_t *adder = add ? output : zeros;
for (int i = 0; i < N; i++) {
gain += dgain;
int32_t y = mkiSin((phase+input[i]), gain);
output[i] = y + adder[i];
phase += freq;
}
}
void EngineMkI::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, bool add, const Controllers *controllers) {
int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N;
int32_t gain = gain1;
int32_t phase = phase0;
if (add) {
for (int i = 0; i < N; i++) {
gain += dgain;
int32_t y = Sin::lookup(phase);
y &= controllers->sinBitFilter;
int32_t y1 = ((int64_t)y * (int64_t)gain) >> 24;
output[i] += y1;
phase += freq;
}
} else {
for (int i = 0; i < N; i++) {
gain += dgain;
int32_t y = Sin::lookup(phase);
y &= controllers->sinBitFilter;
int32_t y1 = ((int64_t)y * (int64_t)gain) >> 24;
output[i] = y1;
phase += freq;
}
const int32_t *adder = add ? output : zeros;
for (int i = 0; i < N; i++) {
gain += dgain;
int32_t y = mkiSin(phase , gain);
output[i] = y + adder[i];
phase += freq;
}
}
void EngineMkI::compute_fb(int32_t *output, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2,
int32_t *fb_buf, int fb_shift, bool add, const Controllers *controllers) {
int32_t *fb_buf, int fb_shift, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N;
int32_t gain = gain1;
int32_t phase = phase0;
const int32_t *adder = add ? output : zeros;
int32_t y0 = fb_buf[0];
int32_t y = fb_buf[1];
if (add) {
for (int i = 0; i < N; i++) {
gain += dgain;
int32_t scaled_fb = (y0 + y) >> (fb_shift + 1);
y0 = y;
y = Sin::lookup(phase + scaled_fb);
y &= controllers->sinBitFilter;
y = ((int64_t)y * (int64_t)gain) >> 24;
output[i] += y;
phase += freq;
}
} else {
for (int i = 0; i < N; i++) {
gain += dgain;
int32_t scaled_fb = (y0 + y) >> (fb_shift + 1);
y0 = y;
y = Sin::lookup(phase + scaled_fb);
y &= controllers->sinBitFilter;
y = ((int64_t)y * (int64_t)gain) >> 24;
output[i] = y;
phase += freq;
}
for (int i = 0; i < N; i++) {
gain += dgain;
int32_t scaled_fb = (y0 + y) >> (fb_shift + 1);
y0 = y;
y = mkiSin((phase+scaled_fb), gain);
output[i] = y + adder[i];
phase += freq;
}
fb_buf[0] = y0;
fb_buf[1] = y;
}
// exclusively used for ALGO 6 with feedback
void EngineMkI::compute_fb2(int32_t *output, FmOpParams *parms, int32_t gain01, int32_t gain02, int32_t *fb_buf, int fb_shift, const Controllers *cont) {
void EngineMkI::compute_fb2(int32_t *output, FmOpParams *parms, int32_t gain01, int32_t gain02, int32_t *fb_buf, int fb_shift) {
int32_t dgain[2];
int32_t gain[2];
int32_t phase[2];
@@ -158,39 +214,37 @@ void EngineMkI::compute_fb2(int32_t *output, FmOpParams *parms, int32_t gain01,
phase[0] = parms[0].phase;
phase[1] = parms[1].phase;
parms[1].gain_out = (ENV_MAX-(parms[1].level_in >> (28-ENV_BITDEPTH)));
gain[0] = gain01;
gain[1] = parms[1].gain_out;
gain[1] = parms[1].gain_out == 0 ? (ENV_MAX-1) : parms[1].gain_out;
dgain[0] = (gain02 - gain01 + (N >> 1)) >> LG_N;
dgain[1] = (parms[1].gain_out - (parms[1].gain_out == 0 ? (ENV_MAX-1) : parms[1].gain_out));
parms[1].gain_out = Exp2::lookup(parms[1].level_in - (14 * (1 << 24)));
dgain[1] = (parms[1].gain_out - gain[1] + (N >> 1)) >> LG_N;
for (int i = 0; i < N; i++) {
int32_t scaled_fb = (y0 + y) >> (fb_shift + 1);
// op 0
gain[0] += dgain[0];
int32_t scaled_fb = (y0 + y) >> (fb_shift + 2); // tsk tsk tsk: this needs some tuning
y0 = y;
y = Sin::lookup(phase[0] + scaled_fb);
y &= cont->sinBitFilter;
y = ((int64_t)y * (int64_t)gain[0]) >> 24;
y = mkiSin(phase[0]+scaled_fb, gain[0]);
phase[0] += parms[0].freq;
// op 1
gain[1] += dgain[1];
y = Sin::lookup(phase[1] + y);
y &= cont->sinBitFilter;
y = ((int64_t)y * (int64_t)gain[1]) >> 24;
output[i] = y;
y = mkiSin(phase[1]+y, gain[1]);
phase[1] += parms[1].freq;
output[i] = y;
}
fb_buf[0] = y0;
fb_buf[1] = y;
}
// exclusively used for ALGO 4 with feedback
void EngineMkI::compute_fb3(int32_t *output, FmOpParams *parms, int32_t gain01, int32_t gain02, int32_t *fb_buf, int fb_shift, const Controllers *cont) {
void EngineMkI::compute_fb3(int32_t *output, FmOpParams *parms, int32_t gain01, int32_t gain02, int32_t *fb_buf, int fb_shift) {
int32_t dgain[3];
int32_t gain[3];
int32_t phase[3];
@@ -200,53 +254,55 @@ void EngineMkI::compute_fb3(int32_t *output, FmOpParams *parms, int32_t gain01,
phase[0] = parms[0].phase;
phase[1] = parms[1].phase;
phase[2] = parms[2].phase;
gain[0] = gain01;
gain[1] = parms[1].gain_out;
gain[2] = parms[2].gain_out;
parms[1].gain_out = (ENV_MAX-(parms[1].level_in >> (28-ENV_BITDEPTH)));
parms[2].gain_out = (ENV_MAX-(parms[2].level_in >> (28-ENV_BITDEPTH)));
gain[0] = gain01;
gain[1] = parms[1].gain_out == 0 ? (ENV_MAX-1) : parms[1].gain_out;
gain[2] = parms[2].gain_out == 0 ? (ENV_MAX-1) : parms[2].gain_out;
dgain[0] = (gain02 - gain01 + (N >> 1)) >> LG_N;
dgain[1] = (parms[1].gain_out - (parms[1].gain_out == 0 ? (ENV_MAX-1) : parms[1].gain_out));
dgain[2] = (parms[2].gain_out - (parms[2].gain_out == 0 ? (ENV_MAX-1) : parms[2].gain_out));
parms[1].gain_out = Exp2::lookup(parms[1].level_in - (14 * (1 << 24)));
dgain[1] = (parms[1].gain_out - gain[1] + (N >> 1)) >> LG_N;
parms[2].gain_out = Exp2::lookup(parms[2].level_in - (14 * (1 << 24)));
dgain[2] = (parms[1].gain_out - gain[2] + (N >> 1)) >> LG_N;
for (int i = 0; i < N; i++) {
int32_t scaled_fb = (y0 + y) >> (fb_shift + 1);
// op 0
gain[0] += dgain[0];
int32_t scaled_fb = (y0 + y) >> (fb_shift + 6); // tsk tsk tsk: this needs some tuning
y0 = y;
y = Sin::lookup(phase[0] + scaled_fb);
y &= cont->sinBitFilter;
y = ((int64_t)y * (int64_t)gain[0]) >> 24;
y = mkiSin(phase[0]+scaled_fb, gain[0]);
phase[0] += parms[0].freq;
// op 1
gain[1] += dgain[1];
y = Sin::lookup(phase[1] + y);
y &= cont->sinBitFilter;
y = ((int64_t)y * (int64_t)gain[1]) >> 24;
y = mkiSin(phase[1]+y, gain[1]);
phase[1] += parms[1].freq;
// op 2
gain[2] += dgain[2];
y = Sin::lookup(phase[2] + y);
y &= cont->sinBitFilter;
y = ((int64_t)y * (int64_t)gain[2]) >> 24;
y = mkiSin(phase[2]+y, gain[2]);
phase[2] += parms[2].freq;
output[i] = y;
phase[2] += parms[2].freq;
}
fb_buf[0] = y0;
fb_buf[1] = y;
}
void EngineMkI::render(int32_t *output, FmOpParams *params, int algorithm,
int32_t *fb_buf, int feedback_shift, const Controllers *controllers) {
const int kLevelThresh = 1120;
const FmAlgorithm alg = algo2[algorithm];
void EngineMkI::render(int32_t *output, FmOpParams *params, int algorithm, int32_t *fb_buf, int feedback_shift) {
const int kLevelThresh = ENV_MAX-100;
FmAlgorithm alg = algorithms[algorithm];
bool has_contents[3] = { true, false, false };
bool fb_on = feedback_shift < 16;
switch(algorithm) {
case 3 : case 5 :
if ( fb_on )
alg.ops[0] = 0xc4;
}
for (int op = 0; op < 6; op++) {
int flags = alg.ops[op];
@@ -255,11 +311,11 @@ void EngineMkI::render(int32_t *output, FmOpParams *params, int algorithm,
int inbus = (flags >> 4) & 3;
int outbus = flags & 3;
int32_t *outptr = (outbus == 0) ? output : buf_[outbus - 1].get();
int32_t gain1 = param.gain_out;
int32_t gain2 = Exp2::lookup(param.level_in - (14 * (1 << 24)));
int32_t gain1 = param.gain_out == 0 ? (ENV_MAX-1) : param.gain_out;
int32_t gain2 = ENV_MAX-(param.level_in >> (28-ENV_BITDEPTH));
param.gain_out = gain2;
if (gain1 >= kLevelThresh || gain2 >= kLevelThresh) {
if (gain1 <= kLevelThresh || gain2 <= kLevelThresh) {
if (!has_contents[outbus]) {
add = false;
@@ -267,41 +323,34 @@ void EngineMkI::render(int32_t *output, FmOpParams *params, int algorithm,
if (inbus == 0 || !has_contents[inbus]) {
// PG: this is my 'dirty' implementation of FB for 2 and 3 operators...
// still needs some tuning...
if ((flags & 0xc0) == 0xc0 && feedback_shift < 16) {
if ((flags & 0xc0) == 0xc0 && fb_on) {
switch ( algorithm ) {
// two operator feedback, process exception for ALGO 6
case 5 :
compute_fb2(outptr, params, gain1, gain2, fb_buf, feedback_shift, controllers);
params[1].phase += params[1].freq << LG_N; // yuk, hack, we already processed op-5
op++; // ignore next operator;
break;
// three operator feedback, process exception for ALGO 4
case 3 :
compute_fb3(outptr, params, gain1, gain2, fb_buf, feedback_shift, controllers);
compute_fb3(outptr, params, gain1, gain2, fb_buf, min((feedback_shift+2), 16));
params[1].phase += params[1].freq << LG_N; // hack, we already processed op-5 - op-4
params[2].phase += params[2].freq << LG_N; // yuk yuk
op += 2; // ignore the 2 other operators
break;
// two operator feedback, process exception for ALGO 6
case 5 :
compute_fb2(outptr, params, gain1, gain2, fb_buf, min((feedback_shift+2), 16));
params[1].phase += params[1].freq << LG_N; // yuk, hack, we already processed op-5
op++; // ignore next operator;
break;
default:
// one operator feedback, normal proces
//cout << "\t" << op << " fb " << inbus << outbus << add << endl;
compute_fb(outptr, param.phase, param.freq,gain1, gain2, fb_buf, feedback_shift, add, controllers);
compute_fb(outptr, param.phase, param.freq, gain1, gain2, fb_buf, feedback_shift, add);
break;
}
} else {
// cout << op << " pure " << inbus << outbus << add << endl;
compute_pure(outptr, param.phase, param.freq, gain1, gain2, add, controllers);
compute_pure(outptr, param.phase, param.freq, gain1, gain2, add);
}
} else {
// cout << op << " normal " << inbus << outbus << " " << param.freq << add << endl;
compute(outptr, buf_[inbus - 1].get(),
param.phase, param.freq, gain1, gain2, add, controllers);
compute(outptr, buf_[inbus - 1].get(), param.phase, param.freq, gain1, gain2, add);
}
has_contents[outbus] = true;
} else if (!add) {
has_contents[outbus] = false;
}


+ 8
- 9
ports/dexed/source/EngineMkI.h View File

@@ -26,24 +26,23 @@
class EngineMkI : public FmCore {
//refacter this when it is working
const static FmAlgorithm algo2[32];
public:
virtual void render(int32_t *output, FmOpParams *params, int algorithm,
int32_t *fb_buf, int feedback_shift, const Controllers *controllers);
EngineMkI();
void render(int32_t *output, FmOpParams *params, int algorithm, int32_t *fb_buf, int feedback_shift) override;
void compute(int32_t *output, const int32_t *input, int32_t phase0, int32_t freq, int32_t gain1, int32_t gain2,
bool add, const Controllers *controllers);
bool add);
void compute_pure(int32_t *output, int32_t phase0, int32_t freq, int32_t gain1, int32_t gain2,
bool add, const Controllers *controllers);
bool add);
void compute_fb(int32_t *output, int32_t phase0, int32_t freq, int32_t gain1, int32_t gain2,
int32_t *fb_buf, int fb_gain, bool add, const Controllers *controllers);
int32_t *fb_buf, int fb_gain, bool add);
void compute_fb2(int32_t *output, FmOpParams *params, int32_t gain01, int32_t gain02, int32_t *fb_buf, int fb_shift, const Controllers *controllers);
void compute_fb2(int32_t *output, FmOpParams *params, int32_t gain01, int32_t gain02, int32_t *fb_buf, int fb_shift);
void compute_fb3(int32_t *output, FmOpParams *params, int32_t gain01, int32_t gain02, int32_t *fb_buf, int fb_shift, const Controllers *controllers);
void compute_fb3(int32_t *output, FmOpParams *params, int32_t gain01, int32_t gain02, int32_t *fb_buf, int fb_shift);
};


+ 16
- 4
ports/dexed/source/EngineOpl.cpp View File

@@ -26,7 +26,7 @@
#include "EngineOpl.h"
#ifdef _WIN32
__declspec(align(16)) int zeros[N] = {0};
__declspec(align(16)) const int zeros[N] = {0};
#else
const int32_t __attribute__ ((aligned(16))) zeros[N] = {0};
#endif
@@ -71,7 +71,7 @@ uint16_t sinExpTable[256] = {
937, 942, 948, 953, 959, 964, 969, 975, 980, 986, 991, 996, 1002, 1007, 1013, 1018
};
inline uint16_t sinLog( uint16_t phi ) {
inline uint16_t sinLog(uint16_t phi) {
const uint8_t index = (phi & 0xff);
switch( ( phi & 0x0300 ) ) {
@@ -169,7 +169,7 @@ void EngineOpl::compute_fb(int32_t *output, int32_t phase0, int32_t freq,
void EngineOpl::render(int32_t *output, FmOpParams *params, int algorithm,
int32_t *fb_buf, int feedback_shift, const Controllers *controllers) {
int32_t *fb_buf, int feedback_shift) {
const int kLevelThresh = 507; // really ????
const FmAlgorithm alg = algorithms[algorithm];
bool has_contents[3] = { true, false, false };
@@ -211,4 +211,16 @@ void EngineOpl::render(int32_t *output, FmOpParams *params, int algorithm,
}
param.phase += param.freq << LG_N;
}
}
}

+ 1
- 1
ports/dexed/source/EngineOpl.h View File

@@ -31,7 +31,7 @@
class EngineOpl : public FmCore {
public:
virtual void render(int32_t *output, FmOpParams *params, int algorithm,
int32_t *fb_buf, int feedback_shift, const Controllers *controllers);
int32_t *fb_buf, int feedback_shift) override;
void compute(int32_t *output, const int32_t *input, int32_t phase0, int32_t freq, int32_t gain1, int32_t gain2, bool add);
void compute_pure(int32_t *output, int32_t phase0, int32_t freq, int32_t gain1, int32_t gain2, bool add);
void compute_fb(int32_t *output, int32_t phase0, int32_t freq,


+ 88
- 5
ports/dexed/source/GlobalEditor.cpp View File

@@ -7,12 +7,12 @@
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Created with Introjucer version: 3.1.0
Created with Introjucer version: 3.2.0
------------------------------------------------------------------------------
The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-13 by Raw Material Software Ltd.
Copyright (c) 2015 - ROLI Ltd.
==============================================================================
*/
@@ -59,11 +59,39 @@ public:
}
}
};
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);
@@ -224,6 +252,20 @@ GlobalEditor::GlobalEditor ()
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]
@@ -284,6 +326,8 @@ GlobalEditor::~GlobalEditor()
monoMode = nullptr;
lfoType = nullptr;
programSelector = nullptr;
aboutButton = nullptr;
tune = nullptr;
//[Destructor]. You can add your own custom destruction code here..
@@ -306,6 +350,9 @@ void GlobalEditor::paint (Graphics& g)
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);
@@ -338,6 +385,8 @@ void GlobalEditor::resized()
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]
}
@@ -450,6 +499,11 @@ void GlobalEditor::sliderValueChanged (Slider* sliderThatWasMoved)
//[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]
@@ -503,6 +557,13 @@ void GlobalEditor::buttonClicked (Button* buttonThatWasClicked)
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]
@@ -536,14 +597,17 @@ void GlobalEditor::bind(DexedAudioProcessorEditor *edit) {
processor->fxCutoff->bind(cutoff);
processor->fxReso->bind(reso);
processor->output->bind(output);
algoDisplay->algo = &(processor->data[134]);
processor->tune->bind(tune);
algoDisplay->algo = (char *) &(processor->data[134]);
pitchEnvDisplay->pvalues = &(processor->data[126]);
algoDisplay->opStatus = processor->controllers.opSwitch;
editor = edit;
midiMonitor = new MidiMonitor(&(processor->sysexComm));
addAndMakeVisible(midiMonitor);
midiMonitor->setBounds(155, 21, 80, 45);
//addAndMakeVisible(midiMonitor);
//midiMonitor->setBounds(155, 21, 80, 45);
repaint();
}
@@ -574,6 +638,15 @@ void GlobalEditor::updateVu(float f) {
void GlobalEditor::setMonoState(bool state) {
monoMode->setToggleState(state ? Button::buttonDown : Button::buttonNormal, dontSendNotification);
}
void GlobalEditor::mouseDown(const MouseEvent &e) {
if ( e.mods.isRightButtonDown() || e.mods.isAnyModifierKeyDown() ) {
PopupMenu popup;
popup.addItem(1, "Send current program to DX7");
if ( popup.show() == 1 )
processor->sendCurrentSysexProgram();
}
}
//[/MiscUserCode]
@@ -705,6 +778,16 @@ BEGIN_JUCER_METADATA
<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


+ 6
- 2
ports/dexed/source/GlobalEditor.h View File

@@ -7,12 +7,12 @@
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Created with Introjucer version: 3.1.0
Created with Introjucer version: 3.2.0
------------------------------------------------------------------------------
The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-13 by Raw Material Software Ltd.
Copyright (c) 2015 - ROLI Ltd.
==============================================================================
*/
@@ -61,6 +61,8 @@ public:
void setMonoState(bool state);
ProgramSelector *programs;
ScopedPointer<Component> midiMonitor;
void mouseDown(const MouseEvent& e) override;
//[/UserMethods]
void paint (Graphics& g);
@@ -112,6 +114,8 @@ private:
ScopedPointer<ToggleButton> monoMode;
ScopedPointer<ComboBoxImage> lfoType;
ScopedPointer<ProgramSelector> programSelector;
ScopedPointer<ImageButton> aboutButton;
ScopedPointer<Slider> tune;
//==============================================================================


+ 2
- 2
ports/dexed/source/JucePluginCharacteristics.h View File

@@ -33,10 +33,10 @@
#define JucePlugin_ManufacturerEmail ""
#endif
#ifndef JucePlugin_ManufacturerCode
#define JucePlugin_ManufacturerCode 'DGSB'
#define JucePlugin_ManufacturerCode 0x44475342 // 'DGSB'
#endif
#ifndef JucePlugin_PluginCode
#define JucePlugin_PluginCode 'Dexd'
#define JucePlugin_PluginCode 0x44657864 // 'Dexd'
#endif
#ifndef JucePlugin_MaxNumInputChannels
#define JucePlugin_MaxNumInputChannels 0


+ 36
- 7
ports/dexed/source/OperatorEditor.cpp View File

@@ -7,12 +7,12 @@
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Created with Introjucer version: 3.1.0
Created with Introjucer version: 3.2.0
------------------------------------------------------------------------------
The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-13 by Raw Material Software Ltd.
Copyright (c) 2015 - ROLI Ltd.
==============================================================================
*/
@@ -25,13 +25,30 @@
//[MiscUserDefs] You can add your own user definitions and misc code here...
#ifndef M_LN10
#define M_LN10 2.30258509299404568402
#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);
@@ -173,6 +190,7 @@ OperatorEditor::OperatorEditor ()
//[UserPreSize]
addAndMakeVisible(opSwitch = new OperatorSwitch());
//[/UserPreSize]
setSize (287, 218);
@@ -233,6 +251,7 @@ OperatorEditor::~OperatorEditor()
//[Destructor]. You can add your own custom destruction code here..
opSwitch = nullptr;
//[/Destructor]
}
@@ -244,9 +263,14 @@ void OperatorEditor::paint (Graphics& g)
//[/UserPrePaint]
//[UserPaint] Add your own custom painting code here..
g.setColour (Colours::white);
if ( opSwitch->getToggleState() )
g.setColour(Colours::white);
else
g.setColour(DXLookNFeel::roundBackground);
g.setFont(Font (30.00f, Font::plain));
g.drawText(opNum, 242, 8, 30, 30, Justification::centred, true);
g.drawText(opNum, 250, 14, 30, 30, Justification::centred, true);
bool state = opMode->getToggleState();
@@ -259,6 +283,9 @@ void OperatorEditor::paint (Graphics& g)
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);
@@ -284,6 +311,7 @@ void OperatorEditor::resized()
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]
}
@@ -439,6 +467,7 @@ void OperatorEditor::bind(DexedAudioProcessor *parent, int op) {
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]);
@@ -486,7 +515,7 @@ void OperatorEditor::updateEnvPos(char pos) {
}
void OperatorEditor::mouseDown(const MouseEvent &event) {
if ( event.mods.isRightButtonDown() ) {
if ( event.mods.isRightButtonDown() || event.mods.isAnyModifierKeyDown()) {
PopupMenu popup;
popup.addItem(1, "Copy Operator Values");
@@ -507,7 +536,7 @@ void OperatorEditor::mouseDown(const MouseEvent &event) {
case 3:
processor->pasteOpFromClipboard(internalOp);
break;
case 4:
processor->sendCurrentSysexProgram();
break;


+ 7
- 8
ports/dexed/source/OperatorEditor.h View File

@@ -7,12 +7,12 @@
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Created with Introjucer version: 3.1.0
Created with Introjucer version: 3.2.0
------------------------------------------------------------------------------
The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-13 by Raw Material Software Ltd.
Copyright (c) 2015 - ROLI Ltd.
==============================================================================
*/
@@ -56,10 +56,10 @@ public:
void mouseDown(const MouseEvent& e) override;
//[/UserMethods]
void paint (Graphics& g);
void resized();
void sliderValueChanged (Slider* sliderThatWasMoved);
void buttonClicked (Button* buttonThatWasClicked);
void paint (Graphics& g) override;
void resized() override;
void sliderValueChanged (Slider* sliderThatWasMoved) override;
void buttonClicked (Button* buttonThatWasClicked) override;
@@ -68,10 +68,9 @@ private:
String opNum;
int internalOp;
Image light;
DexedAudioProcessor *processor;
Image background;
ScopedPointer<ToggleButton> opSwitch;
//[/UserVariables]
//==============================================================================


+ 364
- 7
ports/dexed/source/ParamDialog.cpp View File

@@ -7,12 +7,12 @@
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Created with Introjucer version: 3.1.0
Created with Introjucer version: 3.2.0
------------------------------------------------------------------------------
The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-13 by Raw Material Software Ltd.
Copyright (c) 2015 - ROLI Ltd.
==============================================================================
*/
@@ -30,6 +30,9 @@
//==============================================================================
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);
@@ -67,7 +70,7 @@ ParamDialog::ParamDialog ()
engineReso->setJustificationType (Justification::centredLeft);
engineReso->setTextWhenNothingSelected (String::empty);
engineReso->setTextWhenNoChoicesAvailable (TRANS("(no choices)"));
engineReso->addItem (TRANS("Modern (Direct)"), 1);
engineReso->addItem (TRANS("Modern (24-bit)"), 1);
engineReso->addItem (TRANS("Mark I"), 2);
engineReso->addItem (TRANS("OPL Series"), 3);
engineReso->addListener (this);
@@ -75,11 +78,83 @@ ParamDialog::ParamDialog ()
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);