Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
429904fe4d | ||
|
0f3794d410 | ||
|
c7fad0ee06 | ||
|
0805abdf8e | ||
|
1303d77f5b | ||
|
60a0a3da58 | ||
|
986be58599 | ||
|
cf72be9e1c | ||
|
d4a5299b2b | ||
|
b75ead6fdc | ||
|
352f93a06e | ||
|
73a50a5ab2 | ||
|
16fef1a8b5 | ||
|
77acf5e800 | ||
|
3e16f5314f | ||
|
72fa8a2aab | ||
|
36aa2de0db | ||
|
8ac07f03ae | ||
|
31c8b46cf4 | ||
|
3636ae356a | ||
|
cdca13f412 |
@ -10,6 +10,7 @@
|
|||||||
NAME = chassis
|
NAME = chassis
|
||||||
|
|
||||||
FILES_DSP = \
|
FILES_DSP = \
|
||||||
|
ic1.cpp \
|
||||||
parameters.cpp \
|
parameters.cpp \
|
||||||
voicecpu.cpp \
|
voicecpu.cpp \
|
||||||
chassis.cpp \
|
chassis.cpp \
|
||||||
|
2685
plugin/assigner.off
Normal file
2685
plugin/assigner.off
Normal file
File diff suppressed because it is too large
Load Diff
69
plugin/calls.txt
Normal file
69
plugin/calls.txt
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
10 CALF $0D45 // look up digit value
|
||||||
|
1 CALF $085C // send "Zero DAC" to module board
|
||||||
|
1 CALF $087E // save edited value and send to sysex and module
|
||||||
|
1 CALF $08E9 // send sysex header if manual pressed
|
||||||
|
1 CALF $0955 // send pitchbend to midi
|
||||||
|
1 CALF $097E // send modwheel to midi
|
||||||
|
1 CALF $0996 // to do with voice functions
|
||||||
|
1 CALF $0A18 // to do with voice functions
|
||||||
|
1 CALF $0A76 // to do with voice functions
|
||||||
|
1 CALF $0A88 // voice functions
|
||||||
|
1 CALF $0AAF // voice functions
|
||||||
|
1 CALF $0AF8 // voice functions
|
||||||
|
1 CALF $0B30 // voice functions
|
||||||
|
1 CALF $0BA9 // Sustain on/off
|
||||||
|
1 CALF $0BCC // range switch values
|
||||||
|
1 CALF $0BDA // osc switch values
|
||||||
|
1 CALF $0BEB // both range and osc values
|
||||||
|
1 CALF $0C0C // switches2 values
|
||||||
|
1 CALF $0C54 // switches values
|
||||||
|
1 CALF $0F27 // maybe tape?
|
||||||
|
2 CALF $0800 // display
|
||||||
|
2 CALF $0813 // set flags and store midi channel
|
||||||
|
2 CALF $0871 // read ADCs
|
||||||
|
2 CALF $08C3 // unknown1
|
||||||
|
2 CALF $0936 // calculate patch number for MIDI
|
||||||
|
2 CALF $0947 // send to module board
|
||||||
|
2 CALF $09C2 // send note on message to MIDI
|
||||||
|
2 CALF $09DC // add midi channel and send
|
||||||
|
2 CALF $09E6_setRunningStatus
|
||||||
|
2 CALF $0A0D // to do with note on flags
|
||||||
|
2 CALF $0B55 // unison note on to module board
|
||||||
|
2 CALF $0C47 // manual mode middle bars
|
||||||
|
2 CALF $0CA7 // calculate address for patch data
|
||||||
|
2 CALF $0CF1 // transmit 8 bytes to module board
|
||||||
|
2 CALF $0D06 // something to do with patches
|
||||||
|
2 CALF $0D25 // encode switches byte into upper bits
|
||||||
|
2 CALF $0EB4 // unknown2
|
||||||
|
2 CALF $0EC3 // unknown2
|
||||||
|
2 CALF $0EE7 // unknown3
|
||||||
|
2 CALF $0EFB // memory protect switch
|
||||||
|
2 CALF $0F64 // unknown4
|
||||||
|
3 CALF $0837 // send B, A to module board
|
||||||
|
3 CALF $0843_sendOmniOffPoly
|
||||||
|
3 CALF $08D6 // send single value sysex
|
||||||
|
3 CALF $0915_sendSysexHeader
|
||||||
|
3 CALF $0B9E // clear note on bits at FF30
|
||||||
|
3 CALF $0D33 // save digit pattern
|
||||||
|
3 CALF $0D3C // restore digit pattern
|
||||||
|
3 CALF $0ED5 // unknown5
|
||||||
|
4 CALF $0828 // centre bend to module board
|
||||||
|
4 CALF $08f0_sendSysexPatch
|
||||||
|
4 CALF $0929 // send program change over MIDI
|
||||||
|
4 CALF $0B81 // voice allocation
|
||||||
|
4 CALF $0B9A // clear MIDI on bits
|
||||||
|
4 CALF $0BF9 // send switches 1 to module board
|
||||||
|
4 CALF $0C29 // send switches 2 to module board
|
||||||
|
4 CALF $0C9D // shift bits in A and count
|
||||||
|
4 CALF $0F01 // detect two keys pressed together, maybe poly1+2
|
||||||
|
4 CALF $0F18 // unknown6, probably tape
|
||||||
|
5 CALF $09D5 // omni off running status
|
||||||
|
5 CALF $0C3C // something to do with testing switches
|
||||||
|
5 CALF $0F38 // unknown7 very likely tape
|
||||||
|
6 CALF $0B70_stopAllNotes
|
||||||
|
6 CALF $0C93 // decimal points off?
|
||||||
|
6 CALF $0CD0 // patch change
|
||||||
|
6 CALF $0F07 // possibly to do with tape
|
||||||
|
7 CALF $0D5B // decimal points on?
|
||||||
|
7 CALF $0EF0 // something to do with LEDs, possibly to do with tape?
|
||||||
|
85 CALF $09E8_sendToTx
|
@ -18,8 +18,11 @@
|
|||||||
|
|
||||||
#include "chassis.hpp"
|
#include "chassis.hpp"
|
||||||
|
|
||||||
|
#include "ic1.hpp"
|
||||||
#include "patches.hpp"
|
#include "patches.hpp"
|
||||||
|
|
||||||
|
Assigner ic1;
|
||||||
|
|
||||||
START_NAMESPACE_DISTRHO
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
Chassis::Chassis() : Plugin(parameterCount, 128, 0), sampleRate(getSampleRate()) { // one parameter, no programs, no states
|
Chassis::Chassis() : Plugin(parameterCount, 128, 0), sampleRate(getSampleRate()) { // one parameter, no programs, no states
|
||||||
@ -52,6 +55,16 @@ void Chassis::activate() {
|
|||||||
for (uint8_t i = 0; i < 104; i++) {
|
for (uint8_t i = 0; i < 104; i++) {
|
||||||
s.pitchCV[i] = (440.0f * powf(2, (i - 49) / 12.0f)) / sampleRate;
|
s.pitchCV[i] = (440.0f * powf(2, (i - 49) / 12.0f)) / sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resetvoices
|
||||||
|
for (uint8_t i=0; i<8; i++) {
|
||||||
|
s.noteTbl[i] = 0x80;
|
||||||
|
s.voiceTbl[i] = i;
|
||||||
|
s.voice[i].phase = (0.7*((rand()%65536)/65536.0f));//(60*s.voice[i].omega*i);
|
||||||
|
printf("%f %d\n", s.voice[i].phase, i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chassis::deactivate() {
|
void Chassis::deactivate() {
|
||||||
@ -60,33 +73,33 @@ void Chassis::deactivate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Chassis::noteOn(uint8_t note) {
|
void Chassis::noteOn(uint8_t note) {
|
||||||
uint32_t i;
|
|
||||||
|
// needed for LFO for now
|
||||||
s.keyon = true;
|
s.keyon = true;
|
||||||
for (i = 0; i < NUM_VOICES; i++) {
|
|
||||||
vPtr++;
|
// Unison Voice On
|
||||||
if (vPtr == NUM_VOICES) vPtr = 0;
|
for (uint8_t i=0; i<8; i++ ) {
|
||||||
if (s.voice[vPtr].isFree()) {
|
//s.noteTbl[i] = note;
|
||||||
// if it's an existing note don't reset
|
s.voice[i].on(note, false);
|
||||||
s.voice[vPtr].on(note, s.voice[i].note != note);
|
s.voice[i].voicenum=i;
|
||||||
break;
|
// printf("%f %i\n", s.voice[i].phase, i);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == NUM_VOICES) { // didn't find a free voice
|
//s.voice[vPtr].on(note, true);
|
||||||
vPtr++;
|
|
||||||
if (vPtr == NUM_VOICES) vPtr = 0;
|
|
||||||
s.voice[vPtr].on(note, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chassis::noteOff(uint8_t note) {
|
void Chassis::noteOff(uint8_t note) {
|
||||||
s.keyon = false;
|
|
||||||
for (uint32_t i = 0; i < NUM_VOICES; i++) {
|
// Unison Voice On
|
||||||
if (s.voice[i].note == note && !s.voice[i].isFree()) {
|
for (uint8_t i=0; i<8; i++ ) {
|
||||||
s.voice[i].off();
|
//s.noteTbl[i] = note;
|
||||||
break;
|
s.voice[i].off();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// s.voice[i].off();
|
||||||
|
s.keyon=false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chassis::doMidi(const MidiEvent *ev, uint32_t count, uint32_t timeLimit) {
|
void Chassis::doMidi(const MidiEvent *ev, uint32_t count, uint32_t timeLimit) {
|
||||||
@ -104,6 +117,8 @@ void Chassis::doMidi(const MidiEvent *ev, uint32_t count, uint32_t timeLimit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastEvent = i;
|
lastEvent = i;
|
||||||
|
|
||||||
|
//ic1.voiceOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chassis::run(const float **, float **outputs, uint32_t frames, const MidiEvent *midiEvents, uint32_t midiEventCount) {
|
void Chassis::run(const float **, float **outputs, uint32_t frames, const MidiEvent *midiEvents, uint32_t midiEventCount) {
|
||||||
@ -159,6 +174,26 @@ void Chassis::run(const float **, float **outputs, uint32_t frames, const MidiEv
|
|||||||
s.blockLeft -= sizeThisTime;
|
s.blockLeft -= sizeThisTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// highpass filter
|
||||||
|
|
||||||
|
float tmp = s.hptmp;
|
||||||
|
float smp, flt = 0;
|
||||||
|
float cut_tbl[4] = {0.91245, 0.97097, 1, 0.99088};
|
||||||
|
float cut = cut_tbl[(s.patchRam.switch2 & 0x18) >> 3];
|
||||||
|
float gain_tbl[4] = {-1, -1, 0, 4};
|
||||||
|
float gain = gain_tbl[(s.patchRam.switch2 & 0x18) >> 3];
|
||||||
|
|
||||||
|
// printf("hp= %02x\n", (s.patchRam.switch2 & 0x18)>>3);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < frames; i++) {
|
||||||
|
smp = outputs[0][i];
|
||||||
|
|
||||||
|
flt = ((tmp - smp) * cut) + smp;
|
||||||
|
tmp = flt;
|
||||||
|
outputs[0][i] = ((flt * gain) + smp);
|
||||||
|
}
|
||||||
|
s.hptmp = flt;
|
||||||
|
|
||||||
// copy left to right
|
// copy left to right
|
||||||
memmove(outputs[1], outputs[0], sizeof(float) * frames);
|
memmove(outputs[1], outputs[0], sizeof(float) * frames);
|
||||||
// outputs[1][1]=1;
|
// outputs[1][1]=1;
|
||||||
|
@ -61,7 +61,13 @@ class Chassis : public Plugin {
|
|||||||
paramSustain,
|
paramSustain,
|
||||||
paramRelease,
|
paramRelease,
|
||||||
|
|
||||||
|
paramChorusMode,
|
||||||
|
|
||||||
|
paramPolyMode,
|
||||||
|
paramUnisonDetune,
|
||||||
|
|
||||||
paramModWheel,
|
paramModWheel,
|
||||||
|
|
||||||
|
|
||||||
parameterCount
|
parameterCount
|
||||||
};
|
};
|
||||||
|
2543
plugin/ic1.cpp
Normal file
2543
plugin/ic1.cpp
Normal file
File diff suppressed because it is too large
Load Diff
48
plugin/ic1.hpp
Normal file
48
plugin/ic1.hpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
Chassis polysynth framework
|
||||||
|
|
||||||
|
Copyright 2024 Gordon JC Pearce <gordonjcp@gjcp.net>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||||
|
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class Assigner {
|
||||||
|
public:
|
||||||
|
void noteOn(uint8_t c);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 256 bytes of RAM from $ff00 to $ffff
|
||||||
|
uint8_t ram[256];
|
||||||
|
|
||||||
|
// bitmask data is at $0008 and $0010
|
||||||
|
// eight padding bytes at the start
|
||||||
|
uint8_t bitMask[24] = {
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
|
||||||
|
0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
|
||||||
|
|
||||||
|
uint16_t a = 0, b = 0, c = 0, eal = 0, eah = 0;
|
||||||
|
uint32_t bc, de, hl, ea = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
23:31 < Alipha> gordonjcp: struct reg16 { uint16_t value; uint8_t hi() const { return value >> 8; } uint8_t lo() const { return value;
|
||||||
|
} };
|
||||||
|
23:31 < gordonjcp> Alipha
|
||||||
|
*/
|
||||||
|
|
||||||
|
};
|
||||||
|
|
1751
plugin/ic29.cpp
Normal file
1751
plugin/ic29.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2781
plugin/module.cpp
Normal file
2781
plugin/module.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -149,7 +149,7 @@ void Chassis::initParameter(uint32_t index, Parameter& parameter) {
|
|||||||
parameter.name = "HPF";
|
parameter.name = "HPF";
|
||||||
parameter.symbol = "ch_hpf";
|
parameter.symbol = "ch_hpf";
|
||||||
parameter.ranges.min = 0.0f;
|
parameter.ranges.min = 0.0f;
|
||||||
parameter.ranges.max = 3.0f;
|
parameter.ranges.max = 3.9f;
|
||||||
parameter.ranges.def = 0.0f;
|
parameter.ranges.def = 0.0f;
|
||||||
parameter.midiCC = 20;
|
parameter.midiCC = 20;
|
||||||
break;
|
break;
|
||||||
@ -290,6 +290,50 @@ void Chassis::initParameter(uint32_t index, Parameter& parameter) {
|
|||||||
parameter.midiCC = 26;
|
parameter.midiCC = 26;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case paramChorusMode:
|
||||||
|
parameter.hints = kParameterIsAutomatable | kParameterIsInteger;
|
||||||
|
parameter.name = "Chorus";
|
||||||
|
parameter.symbol = "ch_chorusmode";
|
||||||
|
parameter.ranges.min = 0.0f;
|
||||||
|
parameter.ranges.max = 2.0f;
|
||||||
|
parameter.ranges.def = 1.0f;
|
||||||
|
parameter.midiCC = 93;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
case paramPolyMode:
|
||||||
|
parameter.hints = kParameterIsAutomatable | kParameterIsInteger;
|
||||||
|
parameter.name = "Poly";
|
||||||
|
parameter.symbol = "ch_poly";
|
||||||
|
parameter.ranges.min = 0.0f;
|
||||||
|
parameter.ranges.max = 2.0f;
|
||||||
|
parameter.ranges.def = 0.0f;
|
||||||
|
parameter.midiCC = 86;
|
||||||
|
parameter.enumValues.count = 3;
|
||||||
|
parameter.enumValues.restrictedMode = true;
|
||||||
|
{
|
||||||
|
ParameterEnumerationValue* const enumValues = new ParameterEnumerationValue[3];
|
||||||
|
enumValues[0].value = 0.0f;
|
||||||
|
enumValues[0].label = "16'";
|
||||||
|
enumValues[1].value = 1.0f;
|
||||||
|
enumValues[1].label = "8'";
|
||||||
|
enumValues[2].value = 2.0f;
|
||||||
|
enumValues[2].label = "4'";
|
||||||
|
parameter.enumValues.values = enumValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
case paramUnisonDetune:
|
||||||
|
parameter.hints = kParameterIsAutomatable;
|
||||||
|
parameter.name = "Detune";
|
||||||
|
parameter.symbol = "ch_detune";
|
||||||
|
parameter.ranges.min = 0.0f;
|
||||||
|
parameter.ranges.max = 1.0f;
|
||||||
|
parameter.ranges.def = 0.2f;
|
||||||
|
parameter.midiCC=84;
|
||||||
|
break;
|
||||||
|
|
||||||
case paramModWheel:
|
case paramModWheel:
|
||||||
parameter.hints = kParameterIsAutomatable | kParameterIsHidden;
|
parameter.hints = kParameterIsAutomatable | kParameterIsHidden;
|
||||||
parameter.name = "Mod wheel";
|
parameter.name = "Mod wheel";
|
||||||
@ -297,7 +341,7 @@ void Chassis::initParameter(uint32_t index, Parameter& parameter) {
|
|||||||
parameter.ranges.min = 0.0f;
|
parameter.ranges.min = 0.0f;
|
||||||
parameter.ranges.max = 127.0f;
|
parameter.ranges.max = 127.0f;
|
||||||
parameter.ranges.def = 0.0f;
|
parameter.ranges.def = 0.0f;
|
||||||
parameter.midiCC = 1;
|
//parameter.midiCC = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// chorus, porta, bend range, key mode still to do
|
// chorus, porta, bend range, key mode still to do
|
||||||
@ -397,14 +441,22 @@ void Chassis::setParameterValue(uint32_t index, float value) {
|
|||||||
|
|
||||||
case paramHPF: // bits 3-4 of switch 2
|
case paramHPF: // bits 3-4 of switch 2
|
||||||
// doesn't look great in Carla because of odd behaviour with small integer knobs
|
// doesn't look great in Carla because of odd behaviour with small integer knobs
|
||||||
|
printf("setPV %d %f\n", index, value);
|
||||||
if (value > 3) value = 3;
|
if (value > 3) value = 3;
|
||||||
s.patchRam.switch2 &= 0xf3;
|
s.patchRam.switch2 &= 0xe7;
|
||||||
s.patchRam.switch2 |= (int)value << 3;
|
s.patchRam.switch2 |= (3 - (int)value) << 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case paramModWheel:
|
case paramModWheel:
|
||||||
s.ff64 = (int)value << 1;
|
s.ff64 = (int)value << 1;
|
||||||
break;
|
break;
|
||||||
|
//case paramPolyMode:
|
||||||
|
// s.polymode = (int)value;
|
||||||
|
// break;
|
||||||
|
|
||||||
|
case paramUnisonDetune:
|
||||||
|
s.unisonDetune = value;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,7 +504,7 @@ float Chassis::getParameterValue(uint32_t index) const {
|
|||||||
return s.patchRam.noise;
|
return s.patchRam.noise;
|
||||||
break;
|
break;
|
||||||
case paramHPF:
|
case paramHPF:
|
||||||
return (s.patchRam.switch2 & 0x18) >> 3;
|
return 3 - ((s.patchRam.switch2 & 0x18) >> 3);
|
||||||
break;
|
break;
|
||||||
case paramVCFFreq:
|
case paramVCFFreq:
|
||||||
return s.patchRam.vcfFreq;
|
return s.patchRam.vcfFreq;
|
||||||
@ -491,6 +543,10 @@ float Chassis::getParameterValue(uint32_t index) const {
|
|||||||
|
|
||||||
case paramVCALevel:
|
case paramVCALevel:
|
||||||
return s.patchRam.vca;
|
return s.patchRam.vca;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case paramUnisonDetune:
|
||||||
|
return s.unisonDetune;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -42,17 +42,21 @@ void Voice::run(Synth &s, float *buffer, uint32_t samples) {
|
|||||||
float fb, res = s.patchRam.vcfReso / 28.0f; // guess
|
float fb, res = s.patchRam.vcfReso / 28.0f; // guess
|
||||||
|
|
||||||
float cut = 248.0f * (powf(2, (vcfenv - 0x1880) / 1143.0f));
|
float cut = 248.0f * (powf(2, (vcfenv - 0x1880) / 1143.0f));
|
||||||
|
cut *= (1-detune[voicenum]);
|
||||||
// now radians
|
// now radians
|
||||||
cut = 0.25 * 6.2832 * cut / 48000.0f;
|
cut = 0.25 * 6.2832 * cut / 48000.0f;
|
||||||
|
|
||||||
// now correct
|
// now correct
|
||||||
cut = cut / (1 + cut);
|
cut = cut / (1 + cut);
|
||||||
|
|
||||||
float sqr = (s.patchRam.switch1 & 0x08) ? 0.63 : 0; //? 0.175 : 0;
|
float sqr = (s.patchRam.switch1 & 0x08) ? 0.65 : 0;
|
||||||
float saw = (s.patchRam.switch1 & 0x10) ? 0.8 : 0; //? 0.220 : 0;
|
float saw = (s.patchRam.switch1 & 0x10) ? 0.83 : 0;
|
||||||
float sub = (s.patchRam.sub / 127.0f); // * 0.275;
|
float sub = (s.patchRam.sub / 127.0f);
|
||||||
|
float noise = (s.patchRam.noise / 127.0f) * 0.8;
|
||||||
|
|
||||||
float gain = 0.5 * powf(2, (s.patchRam.vca / 64.0f) - 1);
|
|
||||||
|
float gain = 0.5*powf(2, (4*s.patchRam.vca / 127.0f) - 1.0f);
|
||||||
|
//printf("%f %f\n",s.patchRam.vca / 127.0f, gain);
|
||||||
|
|
||||||
float vcaEnv = (s.patchRam.switch2 & 0x04) ? (float)ff11 : (env / 16384.0f);
|
float vcaEnv = (s.patchRam.switch2 & 0x04) ? (float)ff11 : (env / 16384.0f);
|
||||||
|
|
||||||
@ -98,6 +102,11 @@ void Voice::run(Synth &s, float *buffer, uint32_t samples) {
|
|||||||
|
|
||||||
// out = (2 * y) - 1;
|
// out = (2 * y) - 1;
|
||||||
out = y;
|
out = y;
|
||||||
|
|
||||||
|
lcg = (lcg*519)+3;
|
||||||
|
|
||||||
|
out += noise * ((lcg / 2147483647.0f)-1);
|
||||||
|
|
||||||
// widthDelay = pw;
|
// widthDelay = pw;
|
||||||
|
|
||||||
out *= 0.707;
|
out *= 0.707;
|
||||||
@ -118,7 +127,8 @@ void Voice::run(Synth &s, float *buffer, uint32_t samples) {
|
|||||||
vr58c106 += ((vcaEnv - vr58c106) * 0.005);
|
vr58c106 += ((vcaEnv - vr58c106) * 0.005);
|
||||||
lastpw = pw;
|
lastpw = pw;
|
||||||
|
|
||||||
out = b4 * (0.25);
|
// gain for fully resonant needs to be 128mV output
|
||||||
|
out = b4 * (0.1625);
|
||||||
|
|
||||||
buffer[i] += (gain * out * vr58c106);
|
buffer[i] += (gain * out * vr58c106);
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@ class Synth;
|
|||||||
class Voice {
|
class Voice {
|
||||||
public:
|
public:
|
||||||
uint8_t note = 60; // per-voice note, set to middle C at 02b1h
|
uint8_t note = 60; // per-voice note, set to middle C at 02b1h
|
||||||
|
float detune[8] = {-0.13, -0.09, -0.05, -0.025, 0.018, 0.06, 0.11, 0.16};
|
||||||
|
uint8_t voicenum;
|
||||||
|
|
||||||
void on(uint32_t key, bool reset);
|
void on(uint32_t key, bool reset);
|
||||||
void off();
|
void off();
|
||||||
@ -40,6 +42,8 @@ class Voice {
|
|||||||
|
|
||||||
float omega;
|
float omega;
|
||||||
uint16_t vcfenv;
|
uint16_t vcfenv;
|
||||||
|
float phase = 0, subosc = 1;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum { ATTACK,
|
enum { ATTACK,
|
||||||
@ -61,10 +65,10 @@ class Voice {
|
|||||||
|
|
||||||
uint16_t env;
|
uint16_t env;
|
||||||
|
|
||||||
float phase = 0, subosc = 1;
|
|
||||||
// float env, target;
|
// float env, target;
|
||||||
float delay;
|
float delay;
|
||||||
uint8_t pulseStage = 0;
|
uint8_t pulseStage = 0;
|
||||||
|
uint32_t lcg;
|
||||||
|
|
||||||
float lastpw = 0;
|
float lastpw = 0;
|
||||||
float vr58c106 = 0;
|
float vr58c106 = 0;
|
||||||
@ -79,6 +83,12 @@ class Synth {
|
|||||||
uint32_t blockLeft;
|
uint32_t blockLeft;
|
||||||
uint32_t framesLeft = 0;
|
uint32_t framesLeft = 0;
|
||||||
|
|
||||||
|
uint8_t polymode;
|
||||||
|
uint8_t noteTbl[8];
|
||||||
|
uint8_t voiceTbl[8];
|
||||||
|
|
||||||
|
float unisonDetune;
|
||||||
|
|
||||||
bool keyon;
|
bool keyon;
|
||||||
uint8_t ff63 = 0;
|
uint8_t ff63 = 0;
|
||||||
|
|
||||||
@ -133,6 +143,7 @@ class Synth {
|
|||||||
} patchRam;
|
} patchRam;
|
||||||
|
|
||||||
float pitchCV[104];
|
float pitchCV[104];
|
||||||
|
float hptmp;
|
||||||
|
|
||||||
void runLFO();
|
void runLFO();
|
||||||
void lfoDelay();
|
void lfoDelay();
|
||||||
|
@ -296,6 +296,10 @@ h0407:
|
|||||||
h0432:
|
h0432:
|
||||||
// printf("setting omega for note %d \n", a);
|
// printf("setting omega for note %d \n", a);
|
||||||
omega = ((s.pitchCV[a + 1] - s.pitchCV[a]) * (s.ff6e / 256.0)) + s.pitchCV[a];
|
omega = ((s.pitchCV[a + 1] - s.pitchCV[a]) * (s.ff6e / 256.0)) + s.pitchCV[a];
|
||||||
|
|
||||||
|
omega *= 1 + (s.unisonDetune*0.25*detune[voicenum]);
|
||||||
|
//printf("%f %f %d\n", s.unisonDetune, omega, voicenum);
|
||||||
|
//phase = (2.4*omega*voicenum);
|
||||||
// 0432 onwards calculates the address for the CV
|
// 0432 onwards calculates the address for the CV
|
||||||
// table at E60 and stacks it
|
// table at E60 and stacks it
|
||||||
// 043a onwards fetches the value from the divider
|
// 043a onwards fetches the value from the divider
|
||||||
|
Loading…
Reference in New Issue
Block a user