Final AMD implementation

pull/1/head
asb2m10 10 years ago
parent c228e50f10
commit 9f8c11346e
  1. BIN
      Builds/MacOSX/Dexed.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatad/UserInterfaceState.xcuserstate
  2. 7
      README.md
  3. 4
      Source/Dexed.h
  4. 11
      Source/PluginFx.h
  5. 9
      Source/PluginParam.cpp
  6. 21
      Source/msfa/dx7note.cc
  7. 4
      Source/msfa/env.cc
  8. 2
      Source/msfa/env.h
  9. 35
      Source/msfa/fm_core.cc
  10. 14
      Source/msfa/fm_op_kernel.cc
  11. 2
      Source/msfa/pitchenv.cc

@ -30,18 +30,15 @@ new version here but you see it in the change log, it's because this version is
(current sprint). Only officials (tested) builds are listed here.
* Version 0.6.1 [vst win32/x64](http://le-son666.com/software/dexed/dexed-0.6.1-win.zip) - [vst os x](http://le-son666.com/software/dexed/dexed-0.6.1-osx.vst.zip)
* Version 0.6.0 [vst win32/x64](http://le-son666.com/software/dexed/dexed-0.6.0-win.zip) - [vst os x](http://le-son666.com/software/dexed/dexed-0.6.0-osx.vst.zip)
* Version 0.5.1 [vst win32](http://le-son666.com/software/dexed/dexed-0.5.1-win32.zip) - [vst win64](http://le-son666.com/software/dexed/dexed-0.5.1-win64.zip) - [vst os x](http://le-son666.com/software/dexed/dexed-0.5.1-osx.vst.zip)
* Version 0.5.0 [vst win32](http://le-son666.com/software/dexed/dexed-0.5.0a-win32.zip) - [vst win64](http://le-son666.com/software/dexed/dexed-0.5.0a-win64.zip) - [vst os x](http://le-son666.com/software/dexed/dexed-0.5.0-osx.vst.zip)
Changelog
---------
#### Version 0.7.0 (current sprint)
* Preliminary Algo 4 & 6 feedback support
* DX Engine 'Dirty DX' emulation
* DX Engine LFO amplitude - still buggy
* DX Engine LFO amplitude
* Fixed stucked notes when programs where changed
* Fixed engine envelop wrong timing if it was not 44100Khz - still buggy
* Fixed engine envelop wrong timing if it was not 44100Khz
#### Version 0.6.1
* Mouse over + LFO type fix + pitch eg values

@ -24,14 +24,14 @@
void dexed_trace(const char *source, const char *fmt, ...);
#ifdef DEBUG
#define DEXED_VERSION "0.7.0 BETA DEBUG"
#define DEXED_VERSION "0.7.0a1 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 "0.7.0 BETA"
#define DEXED_VERSION "0.7.0a1"
#define TRACE(fmt, ...)
#endif

@ -21,6 +21,15 @@
#ifndef PLUGINFX_H_INCLUDED
#define PLUGINFX_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
class ModuleFx {
public:
virtual ~ModuleFx() {};
virtual void init(int sampleRate) = 0;
virtual void process(float *work, int sz) = 0;
};
class PluginFx {
float s1,s2,s3,s4;
float sampleRate;
@ -55,6 +64,8 @@ class PluginFx {
public:
ScopedPointer<ModuleFx> obxdFilter;
// this is set directly by the ui / parameter
float uiCutoff;
float uiReso;

@ -141,15 +141,6 @@ float CtrlDX::getValueHost() {
void CtrlDX::setValueHost(float f) {
setValue((f * steps));
/*
DexedAudioProcessorEditor *editor = (DexedAudioProcessorEditor *) parent->getActiveEditor();
if ( editor == NULL ) {
return;
}
String msg;
msg << label << " = " << getValueDisplay();
editor->global.setParamMessage(msg);*/
}
void CtrlDX::setValue(int v) {

@ -19,6 +19,7 @@
using namespace std;
#endif
#include <math.h>
#include <stdlib.h>
#include "synth.h"
#include "freqlut.h"
#include "exp2.h"
@ -126,8 +127,10 @@ static const uint8_t pitchmodsenstab[] = {
0, 10, 20, 33, 55, 92, 153, 255
};
static const uint8_t ampmodsenstab[] = {
0, 66, 109, 255
// 0, 66, 109, 255
static const uint32_t ampmodsenstab[] = {
0, 4342338, 7171437, 16777216
};
void Dx7Note::init(const char patch[156], int midinote, int velocity) {
@ -190,7 +193,7 @@ void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay,
// TODO(PG) : make this integer friendly
uint32_t pwmd = (ctrls->values_[kControllerModWheel] * 0.7874) * (1 << 24);
int32_t senslfo = pitchmodsens_ * (lfo_val - (1 << 23));
uint32_t amd = ampmoddepth_ * lfo_delay; // Q32 :D
uint32_t amd = ((int64_t)ampmoddepth_ * (int64_t)lfo_delay) >> 8; // Q24 :D
pitchmod += (((int64_t)pwmd) * (int64_t)senslfo) >> 39;
pitchmod += (((int64_t)pmd) * (int64_t)senslfo) >> 39;
@ -216,12 +219,13 @@ void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay,
params_[op].freq = Freqlut::lookup(basepitch_[op] + pitchmod);
int32_t level = env_[op].getsample();
if ( ampmodsens_[op] != 0 ) {
uint32_t sensamp = ampmodsens_[op] * (lfo_val - (1 << 23));
uint32_t amd_level = (((int64_t)amd) * (int64_t)sensamp) >> 40;
level -= amd_level;
}
int32_t gain = Exp2::lookup(level - (14 * (1 << 24)));
if ( ampmodsens_[op] != 0 ) {
uint32_t sensamp = ((int64_t)ampmodsens_[op]) * ((int64_t)gain) >> 24;
sensamp = ((int64_t)sensamp) * ((int64_t)lfo_val) >> 24;
uint32_t amd_level = (((int64_t)amd) * (int64_t)sensamp) >> 24;
gain -= amd_level;
}
params_[op].gain[1] = gain;
}
core_.compute(buf, params_, algorithm_, fb_buf_, fb_shift_, ctrls);
@ -249,6 +253,7 @@ void Dx7Note::update(const char patch[156], int midinote) {
fb_shift_ = feedback != 0 ? 8 - feedback : 16;
pitchmoddepth_ = (patch[139] * 165) >> 6;
pitchmodsens_ = pitchmodsenstab[patch[143] & 7];
ampmoddepth_ = (patch[140] * 165) >> 6;
}
void Dx7Note::peekVoiceStatus(VoiceStatus &status) {

@ -19,7 +19,7 @@
#include "synth.h"
#include "env.h"
using namespace std;
//using namespace std;
uint32_t Env::sr_multiplier = (1<<24);
@ -40,7 +40,7 @@ void Env::init(const int r[4], const int l[4], int32_t ol, int rate_scaling) {
}
int32_t Env::getsample() {
if (ix_ < 3 || (ix_ < 4) && !down_) {
if (ix_ < 3 || ((ix_ < 4) && !down_)) {
if (rising_) {
const int jumptarget = 1716;
if (level_ < (jumptarget << 16)) {

@ -47,7 +47,7 @@ class Env {
static void init_sr(double sample_rate);
private:
// This code is normalized to 44100, need to put a multiplier
// PG: This code is normalized to 44100, need to put a multiplier
// if we are not using 44100.
static uint32_t sr_multiplier;

@ -48,9 +48,9 @@ const FmAlgorithm algorithms[32] = {
{ { 0xc1, 0x11, 0x11, 0x14, 0x01, 0x14 } }, // 1
{ { 0x01, 0x11, 0x11, 0x14, 0xc1, 0x14 } }, // 2
{ { 0xc1, 0x11, 0x14, 0x01, 0x11, 0x14 } }, // 3
{ { 0xe1, 0x11, 0x94, 0x01, 0x11, 0x14 } }, // 4
{ { 0xc1, 0x11, 0x94, 0x01, 0x11, 0x14 } }, // 4 ** EXCEPTION VIA CODE
{ { 0xc1, 0x14, 0x01, 0x14, 0x01, 0x14 } }, // 5
{ { 0xd1, 0x94, 0x01, 0x14, 0x01, 0x14 } }, // 6
{ { 0xc1, 0x94, 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
@ -130,28 +130,33 @@ void FmCore::compute(int32_t *output, FmOpParams *params, int algorithm,
// PG: this is my 'dirty' implementation of FB for 2 and 3 operators...
// still needs some tuning...
if ((flags & 0xc0) == 0xc0 && feedback_shift < 16) {
switch ( (flags >> 6) - 0xc ) {
// one operator feedback, normal process
case 0 :
//cout << "\t" << op << " fb " << inbus << outbus << add << endl;
FmOpKernel::compute_fb(outptr, param.phase, param.freq,
gain1, gain2,
fb_buf, feedback_shift, add, controllers);
break;
switch ( algorithm ) {
// two operator feedback, process exception for ALGO 6
case 1 :
case 5 :
FmOpKernel::compute_fb2(outptr, params, fb_buf, feedback_shift, controllers);
params[1].phase += params[1].freq << LG_N; // yuk, hack, we already processed op-5
param.phase += param.freq << LG_N;
params[1].phase += param.freq + 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 2 :
case 3 :
FmOpKernel::compute_fb3(outptr, params, fb_buf, feedback_shift, controllers);
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
param.phase += param.freq << LG_N;
params[1].phase += param.freq + params[1].freq << LG_N; // hack, we already processed op-5 - op-4
params[2].phase += param.freq + params[1].freq + params[2].freq << LG_N; // yuk yuk
op += 2; // ignore the 2 other operators
break;
default:
// one operator feedback, normal proces
//cout << "\t" << op << " fb " << inbus << outbus << add << endl;
FmOpKernel::compute_fb(outptr, param.phase, param.freq,
gain1, gain2,
fb_buf, feedback_shift, add, controllers);
param.phase += param.freq << LG_N;
break;
}
has_contents[outbus] = true;
continue;
} else {
// cout << op << " pure " << inbus << outbus << add << endl;
FmOpKernel::compute_pure(outptr, param.phase, param.freq,

@ -23,17 +23,9 @@
#endif
#include "synth.h"
#include "sin.h"
#include "fm_op_kernel.h"
uint32_t restdither() {
return rand() & 0x3FFF;
return 0;
}
#ifdef HAVE_NEONx
static bool hasNeon() {
return true;
@ -52,8 +44,6 @@ static bool hasNeon() {
}
#endif
//#define BIT8 0xFFFFFF00
void FmOpKernel::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) {
@ -172,7 +162,7 @@ void FmOpKernel::compute_fb2(int32_t *output, FmOpParams *parms, int32_t *fb_buf
phase[1] = parms[1].phase;
dgain[0] = (parms[0].gain[1] - parms[0].gain[0] + (N >> 1)) >> LG_N;
dgain[1] = (parms[1].gain[1] - parms[1].gain[1] + (N >> 1)) >> LG_N;
dgain[1] = (parms[1].gain[1] - parms[1].gain[0] + (N >> 1)) >> LG_N;
gain[0] = parms[0].gain[0];
gain[1] = parms[1].gain[1];
@ -188,7 +178,7 @@ void FmOpKernel::compute_fb2(int32_t *output, FmOpParams *parms, int32_t *fb_buf
// op 1
gain[1] += dgain[1];
//scaled_fb = (y0 + y) >> (fb_shift + 1);
scaled_fb = (y0 + y) >> (fb_shift + 1);
y0 = y;
y = Sin::lookup(phase[1] + scaled_fb + y);
y = ((int64_t)y * (int64_t)gain) >> 24;

@ -53,7 +53,7 @@ void PitchEnv::set(const int r[4], const int l[4]) {
}
int32_t PitchEnv::getsample() {
if (ix_ < 3 || (ix_ < 4) && !down_) {
if (ix_ < 3 || ((ix_ < 4) && !down_)) {
if (rising_) {
level_ += inc_;
if (level_ >= targetlevel_) {

Loading…
Cancel
Save