Added main volume control.

Added 1 ms offset to attack an release, to avoid clipping with 0 value. It seems that it's already implemented in the Audio Library, so it needs mors investigation.
Added filter mode function, to switch for band pass to a band stop filter with knob mid-course.
Modified readme to specify libraries used.
pull/1/head
Pierre-Loup Martin 4 years ago
parent 851cd7f6e7
commit 3a22ae1ac9
  1. 15
      README.MD
  2. 4
      minimoog_mega_1/defs.h
  3. 6
      minimoog_mega_2/defs.h
  4. 11
      minimoog_mega_2/minimoog_mega_2.ino
  5. 87
      minimoog_teensy/audio_setup.h
  6. 4
      minimoog_teensy/defs.h
  7. 24
      minimoog_teensy/function settings.txt
  8. 155
      minimoog_teensy/minimoog_teensy.ino

@ -28,6 +28,14 @@ The main and lateral control panels, control panel bottom and rear enclosure are
There was no sketch made for the walnut enclosure, but I should have done some : it's quite thin (around 7cm tall), and it gave me headaches to integrate some components in it. There is plenty of room, but I had to change things several time to accomodate the keyboard height, the front panel with sontrols and the rear panel with plugs...
#### Dependencies
Apart from Teensy audio, this program uses a few libraries.
[Arduino Midi library by FortySevenEffects](https://github.com/FortySevenEffects/arduino_midi_library), for internal communication between the boards. It's the one implemented by Teensy for usb MIDI, very complete.
[PushButton](https://github.com/troisiemetype/PushButton) is used to debounce all switches, and detect changes.
[expFilter](https://github.com/troisiemetype/expfilter) is used to smooth ADC readings. It gives a result close to a running average, but without the need of big tables to store results.
## Function implemented
As said above, the goal is to have something looking as close as possible to the original Minimoog.
@ -51,7 +59,7 @@ Maybe external input will be implemented once, but I wanted this feedback.
the mixer is copy-paste on the original minimoog : a potentiometer for each of the five channels, and a switch for rapid on / off.
### Filter
The filter is (I believe) close from the minimoog one. Cutoff frequency and emphasis (resonance) are available. Their is an associated envelope generator that modulates the cutoff frequency. Their is also an addition compared to the minimoog : there is a knob to slide continuously from low pass to band pass, to high pass filter.
The filter is (I believe) close from the minimoog one. Cutoff frequency and emphasis (resonance) are available. Their is an associated envelope generator that modulates the cutoff frequency. Their is also an addition compared to the minimoog : there is a knob to slide continuously from low pass to band pass, to high pass filter. It can also slide continuously from low pass to high pass, thus resulting in a band stop filter at mid-course. (see _functions_ above)
### Envelope generator
There are two envelope generators : one for the filter, the other for the global sound shape. On the original minimoog, decay can be used (_via_ a switch) to add release to notes. On this one a knob is there for, so this is a classic ADSR envelope.
@ -95,5 +103,10 @@ The detune table stores a fix detune coefficient for each of all 128 MIDI notes.
Output resolution can be changed. The default is 16 bits, but any bitsize between 4 and 16 can be choose.
The bitcrushing is applied at the end of the audio stream, just before the i2s / USB output.
#### Filter mode
The filter band knob slide continuously from low pass to high pass. It can be choosen wether :
* it slides from low pass to band pass for the lower half (high pass cut), and from band pass to high pass in the upper half (low pass cut), or
* it slides continuously from low pass to high pass, thus resulting in a band stop filter when knob is centered. (well, kind of : having a true band stop filter would mean to mix two different filters with frequency offsets. Here they overlap.)
#### MIDI channel setting
The MIDI channel the synth listens and emit on when connected _via_ USB can be changed. Any channel from 1 to 16.

@ -160,7 +160,7 @@
// #define CC_FOOT_CTRL CC4
#define CC_PORTAMENTO_TIME CC5
// #define CC_DATA_ENTRY_MSB CC6
// #define CC_CHANNEL_VOL CC7
#define CC_CHANNEL_VOL CC7
// #define CC_BALANCE CC8
#define CC_OSC_TUNE CC9
// #define CC_PAN CC10
@ -192,7 +192,7 @@
// #define CC_FOOT_CTRL_LSB CC36
#define CC_PORTAMENTO_TIME_LSB CC37
// #define CC_DATA_ENTRY_MSB_LSB CC38
// #define CC_CHANNEL_VOL_LSB CC39
#define CC_CHANNEL_VOL_LSB CC39
// #define CC_BALANCE_LSB CC40
#define CC_OSC_TUNE_LSB CC41
// #define CC_PAN_LSB CC42

@ -160,7 +160,7 @@
// #define CC_FOOT_CTRL CC4
#define CC_PORTAMENTO_TIME CC5
// #define CC_DATA_ENTRY_MSB CC6
// #define CC_CHANNEL_VOL CC7
#define CC_CHANNEL_VOL CC7
// #define CC_BALANCE CC8
#define CC_OSC_TUNE CC9
// #define CC_PAN CC10
@ -192,7 +192,7 @@
// #define CC_FOOT_CTRL_LSB CC36
#define CC_PORTAMENTO_TIME_LSB CC37
// #define CC_DATA_ENTRY_MSB_LSB CC38
// #define CC_CHANNEL_VOL_LSB CC39
#define CC_CHANNEL_VOL_LSB CC39
// #define CC_BALANCE_LSB CC40
#define CC_OSC_TUNE_LSB CC41
// #define CC_PAN_LSB CC42
@ -281,5 +281,3 @@
// #define CC_OMNI_MODE_ON CC125
// #define CC_MONO_MODE_ON CC126
// #define CC_POLY_MODE_ON CC127

@ -49,6 +49,8 @@
* decay pot A12 CC 28
* sustain pot A13 CC 29
* release pot A14 CC 30
* Mixer
* master volume pot A15 CC 07
* Communication
* TX1 to teensy 18
* RX1 from teensy 19
@ -63,8 +65,8 @@
// Constants
const uint8_t NUM_SWITCHES = 3;
const uint8_t NUM_POTS = 15;
const uint8_t POT_FILTER_COEF = 15;
const uint8_t NUM_POTS = 16;
const uint8_t POT_FILTER_COEF = 20;
// Note : pins are defined via tables, to improve code efficiency.
// Digital pin definition
@ -93,7 +95,7 @@ const uint8_t APIN_SUSTAIN = A13;
const uint8_t APIN_RELEASE = A14;
*/
const uint8_t APIN[NUM_POTS] = {A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14};
const uint8_t APIN[NUM_POTS] = {A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15};
// Variables
uint16_t potState[NUM_POTS];
@ -214,6 +216,9 @@ void updateControls(){
case 14:
controlChange = CC_EG_RELEASE;
break;
case 15:
controlChange = CC_CHANNEL_VOL;
break;
default:
continue;

@ -5,45 +5,47 @@
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioSynthWaveformDc dcFilterEnvelope; //xy=169,540
AudioSynthWaveformDc dcOscTune; //xy=228,149
AudioSynthWaveformDc dcKeyTrack; //xy=231,113
AudioSynthWaveformDc dcPitchBend; //xy=234,184
AudioSynthWaveformDc dcFilter; //xy=336,595
AudioSynthNoisePink pinkNoise; //xy=358,320
AudioSynthWaveformDc dcLfoFreq; //xy=360,369
AudioSynthNoiseWhite whiteNoise; //xy=361,284
AudioEffectEnvelope filterEnvelope; //xy=367,540
AudioSynthWaveformDc dcFilterKeyTrack; //xy=369,629
AudioAmplifier ampPitchBend; //xy=407,184
AudioMixer4 noiseMixer; //xy=544,317
AudioSynthWaveformModulated lfoWaveform; //xy=549,369
AudioAmplifier ampOsc3Mod; //xy=549,437
AudioAmplifier ampModEg; //xy=559,475
AudioMixer4 mainTuneMixer; //xy=631,133
AudioMixer4 modMix2; //xy=755,470
AudioMixer4 modMix1; //xy=756,399
AudioSynthWaveformDc dcOsc3; //xy=758,193
AudioMixer4 osc3ControlMixer; //xy=933,199
AudioMixer4 modMixer; //xy=945,448
AudioSynthWaveformDc dcOsc2Tune; //xy=1105,155
AudioSynthWaveformDc dcOsc3Tune; //xy=1106,221
AudioAmplifier ampModWheel; //xy=1159,448
AudioMixer4 osc3TuneMixer; //xy=1289,217
AudioMixer4 osc2TuneMixer; //xy=1290,153
AudioSynthWaveformDc dcPulse; //xy=1306,65
AudioSynthWaveformModulated osc1Waveform; //xy=1523,114
AudioSynthWaveformModulated osc2Waveform; //xy=1524,151
AudioSynthWaveformModulated osc3Waveform; //xy=1524,188
AudioMixer4 oscMixer; //xy=1710,157
AudioMixer4 globalMixer; //xy=1919,204
AudioAmplifier ampPreFilter; //xy=2083,203
AudioMixer4 filterMixer; //xy=2101,446
AudioFilterStateVariable vcf; //xy=2270,440
AudioMixer4 bandMixer; //xy=2441,435
AudioEffectEnvelope mainEnvelope; //xy=2620,436
AudioEffectBitcrusher bitCrushOutput; //xy=2856,433
AudioOutputI2S i2s; //xy=3046,435
AudioSynthWaveformDc dcFilterEnvelope; //xy=101.75,518
AudioSynthWaveformDc dcOscTune; //xy=160.75,127
AudioSynthWaveformDc dcKeyTrack; //xy=163.75,91
AudioSynthWaveformDc dcPitchBend; //xy=166.75,162
AudioSynthWaveformDc dcFilter; //xy=268.75,573
AudioSynthNoisePink pinkNoise; //xy=290.75,298
AudioSynthWaveformDc dcLfoFreq; //xy=292.75,347
AudioSynthNoiseWhite whiteNoise; //xy=293.75,262
AudioEffectEnvelope filterEnvelope; //xy=299.75,518
AudioSynthWaveformDc dcFilterKeyTrack; //xy=301.75,607
AudioAmplifier ampPitchBend; //xy=339.75,162
AudioMixer4 noiseMixer; //xy=476.75,295
AudioSynthWaveformModulated lfoWaveform; //xy=481.75,347
AudioAmplifier ampOsc3Mod; //xy=481.75,415
AudioAmplifier ampModEg; //xy=491.75,453
AudioMixer4 mainTuneMixer; //xy=563.75,111
AudioMixer4 modMix2; //xy=687.75,448
AudioMixer4 modMix1; //xy=688.75,377
AudioSynthWaveformDc dcOsc3; //xy=690.75,171
AudioMixer4 osc3ControlMixer; //xy=865.75,177
AudioMixer4 modMixer; //xy=877.75,426
AudioSynthWaveformDc dcOsc2Tune; //xy=1037.75,133
AudioSynthWaveformDc dcOsc3Tune; //xy=1038.75,199
AudioAmplifier ampModWheel; //xy=1091.75,426
AudioMixer4 osc3TuneMixer; //xy=1221.75,195
AudioMixer4 osc2TuneMixer; //xy=1222.75,131
AudioSynthWaveformDc dcPulse; //xy=1238.75,43
AudioSynthWaveformModulated osc1Waveform; //xy=1455.75,92
AudioSynthWaveformModulated osc2Waveform; //xy=1456.75,129
AudioSynthWaveformModulated osc3Waveform; //xy=1456.75,166
AudioMixer4 oscMixer; //xy=1642.75,135
AudioMixer4 globalMixer; //xy=1851.75,182
AudioAmplifier ampPreFilter; //xy=2015.75,181
AudioMixer4 filterMixer; //xy=2033.75,424
AudioFilterStateVariable vcf; //xy=2202.75,418
AudioMixer4 bandMixer; //xy=2373.75,413
AudioEffectEnvelope mainEnvelope; //xy=2552.75,414
AudioEffectBitcrusher bitCrushOutput; //xy=2788.75,411
AudioAmplifier masterVolume; //xy=2981.75,410.75
AudioOutputI2S i2s; //xy=3150.75,391
//AudioOutputUSB usbOut; //xy=3153.75,429.75
AudioConnection patchCord1(dcFilterEnvelope, filterEnvelope);
AudioConnection patchCord2(dcOscTune, 0, mainTuneMixer, 1);
AudioConnection patchCord3(dcKeyTrack, 0, mainTuneMixer, 0);
@ -92,6 +94,9 @@ AudioConnection patchCord45(vcf, 2, bandMixer, 2);
AudioConnection patchCord46(bandMixer, mainEnvelope);
AudioConnection patchCord47(mainEnvelope, bitCrushOutput);
AudioConnection patchCord48(mainEnvelope, 0, globalMixer, 1);
AudioConnection patchCord49(bitCrushOutput, 0, i2s, 0);
AudioConnection patchCord50(bitCrushOutput, 0, i2s, 1);
AudioConnection patchCord49(bitCrushOutput, masterVolume);
AudioConnection patchCord50(masterVolume, 0, i2s, 0);
AudioConnection patchCord51(masterVolume, 0, i2s, 1);
//AudioConnection patchCord52(masterVolume, 0, usbOut, 0);
//AudioConnection patchCord53(masterVolume, 0, usbOut, 1);
// GUItool: end automatically generated code

@ -160,7 +160,7 @@
// #define CC_FOOT_CTRL CC4
#define CC_PORTAMENTO_TIME CC5
// #define CC_DATA_ENTRY_MSB CC6
// #define CC_CHANNEL_VOL CC7
#define CC_CHANNEL_VOL CC7
// #define CC_BALANCE CC8
#define CC_OSC_TUNE CC9
// #define CC_PAN CC10
@ -192,7 +192,7 @@
// #define CC_FOOT_CTRL_LSB CC36
#define CC_PORTAMENTO_TIME_LSB CC37
// #define CC_DATA_ENTRY_MSB_LSB CC38
// #define CC_CHANNEL_VOL_LSB CC39
#define CC_CHANNEL_VOL_LSB CC39
// #define CC_BALANCE_LSB CC40
#define CC_OSC_TUNE_LSB CC41
// #define CC_PAN_LSB CC42

@ -1,24 +1,38 @@
Keyboard mode
first
last
lower
upper
note : in any case, when there are several notes pressed, releasing one will trigger another, according to priority mode.
first The first key pressed has priority. It must be released for another to trigger note
last Last key pressed triggers new note.
lower The lower key on the keyboard has priority
upper The upper key has priority
Bitcrush
bit crusher : reduce resolution of the samples before output
4 - 16
Midi in channel
the channel the synth reacts to when connected to USB MIDI
1 - 16
Midi out channel
the channel the synths sends on
1 - 16
Retrigger
when a key is pressed and there was already one (or several), retrigger the envelope or no
0 / 1
Detune
Add a small amount of detune to each note, to simulate a resistor ladder vintage keyboard
off
soft
medium
hard
reset
reset
filter mode
The filter band can be changed steplessly from low pass to high pass.
This gives the choice of how it behave at mid course
Band pass The lower half of the control mixes low pass with band pass. High pass cut.
The upper half mixes band pass with high pass. Low pass cut.
Band stop The low and high pass are mixed continuously, band pass cut, resulting in a band stop
on middle position.

@ -66,6 +66,7 @@ const uint8_t NUM_KEYS = 30;
const uint8_t MAX_OCTAVE = 10;
const uint8_t FILTER_MAX_OCTAVE = 5;
const float NOTE_MIDI_0 = 8.1757989156434;
const float NOTE_RATIO = 1.0594630943593;
@ -85,12 +86,13 @@ const int16_t PITCH_BEND_MIN = -168;
const int16_t PITCH_BEND_MAX = 134;
const int16_t PITCH_BEND_NEUTRAL = PITCH_BEND_MIN + (PITCH_BEND_MAX - PITCH_BEND_MIN) / 2;
const int16_t PITCH_BEND_COURSE = PITCH_BEND_MAX - PITCH_BEND_MIN;
/*
// Moved to Mega 1
const uint16_t MOD_WHEEL_MIN = 360;
const uint16_t MOD_WHEEL_MAX = 666;
const uint16_t MOD_WHEEL_NEUTRAL = MOD_WHEEL_MIN + (MOD_WHEEL_MAX - MOD_WHEEL_MIN) / 2;
const uint16_t MOD_WHEEL_COURSE = MOD_WHEEL_MAX - MOD_WHEEL_MIN;
*/
const uint8_t MEGA1_RST = 2;
const uint8_t MEGA2_RST = 18;
@ -100,6 +102,7 @@ const uint16_t EE_MIDI_IN_CH_ADD = 2;
const uint16_t EE_MIDI_OUT_CH_ADD = 3;
const uint16_t EE_TRIGGER_ADD = 4;
const uint16_t EE_DETUNE_ADD = 5;
const uint16_t EE_FILTER_MODE = 6;
const uint16_t EE_DETUNE_TABLE_ADD = 20;
// variables
@ -125,6 +128,8 @@ bool decay = 0;
float filterDecay = 0;
float egDecay = 0;
int16_t filterBandValue = 0;
// Waveforms
uint8_t waveforms[6] = {WAVEFORM_SINE, WAVEFORM_TRIANGLE, WAVEFORM_SAWTOOTH,
WAVEFORM_SAWTOOTH_REVERSE, WAVEFORM_SQUARE, WAVEFORM_PULSE};
@ -147,6 +152,7 @@ enum function_t{
FUNCTION_RETRIGGER,
FUNCTION_DETUNE,
FUNCTION_BITCRUSH,
FUNCTION_FILTER_MODE,
FUNCTION_MIDI_IN_CHANNEL,
FUNCTION_MIDI_OUT_CHANNEL,
};
@ -173,6 +179,13 @@ enum detune_t{
detune_t detune = DETUNE_OFF;
float detuneCoeff[4] = {0, 0.1, 0.3, 0.5};
enum filterMode_t{
FILTER_BAND_PASS = 0,
FILTER_BAND_STOP,
};
filterMode_t filterMode = FILTER_BAND_PASS;
uint8_t bitCrushLevel = 16;
struct midiSettings : public midi::DefaultSettings{
@ -181,7 +194,7 @@ struct midiSettings : public midi::DefaultSettings{
};
// USB midi for sending and receiving to other device or computer.
// MIDI_CREATE_DEFAULT_INSTANCE();
MIDI_CREATE_DEFAULT_INSTANCE();
// The ones we use on synth for internal communication between Mega and Teensy
MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial1, midi1, midiSettings);
MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial4, midi2, midiSettings);
@ -219,6 +232,7 @@ void setup() {
EEPROM.get(EE_MIDI_OUT_CH_ADD, midiOutChannel);
EEPROM.get(EE_TRIGGER_ADD, noteRetrigger);
EEPROM.get(EE_DETUNE_ADD, detune);
EEPROM.get(EE_FILTER_MODE, filterMode);
uint16_t address = EE_DETUNE_TABLE_ADD;
for(uint16_t i = 0; i < 128; ++i){
@ -226,11 +240,10 @@ void setup() {
address += 4;
}
// TODO : check how to receive and transmit on different channels.
// MIDI.begin(midiInChannel);
// MIDI.turnThruOff();
// MIDI.setHandleNoteOn(handleNoteOn);
// MIDI.setHandleNoteOff(handleNoteOff);
// MIDI.setHandlePitchBend(handlePitchBend);
usbMIDI.setHandleNoteOn(handleNoteOn);
usbMIDI.setHandleNoteOff(handleNoteOff);
// usbMIDI.setHandlePitchBend(handlePitchBend);
usbMIDI.begin();
AudioMemory(200);
@ -255,6 +268,7 @@ void setup() {
ampPreFilter.gain(1.0);
ampModEg.gain(0.1);
ampOsc3Mod.gain(1);
masterVolume.gain(1.0);
osc1Waveform.frequencyModulation(MAX_OCTAVE);
osc2Waveform.frequencyModulation(MAX_OCTAVE);
@ -337,7 +351,7 @@ void setup() {
delay(1000);
digitalWrite(13, 0);
delay(100);
delay(200);
// Blink. For debug. And letting a bit more time to Mega 1 to start.
for(uint8_t i = 0; i < 5; ++i){
@ -356,17 +370,17 @@ void setup() {
void loop() {
midi1.read();
midi2.read();
usbMIDI.read(midiInChannel);
}
void noteOn(uint8_t note, uint8_t velocity, bool trigger = 1){
// MIDI.sendNoteOn(note, velocity, 1);
/*
Serial.print("playing :");
Serial.println(note);
*/
nowPlaying = note;
float fineTune = detuneTable[note] * detuneCoeff[detune];
float duration = (float)glideEn * (float)glide * 3.75;
float duration = 1.0 + (float)glideEn * (float)glide * 3.75;
float level = ((float)note + 12 * transpose) * HALFTONE_TO_DC;
level += fineTune;
float filterLevel = (((float)note - FILTER_BASE_NOTE) + (12 * transpose)) * FILTER_HALFTONE_TO_DC;
@ -383,8 +397,6 @@ void noteOn(uint8_t note, uint8_t velocity, bool trigger = 1){
}
void noteOff(){
// MIDI.sendNoteOff(nowPlaying, 0, 1);
AudioNoInterrupts();
filterEnvelope.noteOff();
mainEnvelope.noteOff();
@ -474,6 +486,7 @@ void handleInternalNoteOn(uint8_t channel, uint8_t note, uint8_t velocity){
handleKeyboardFunction(note, 1);
return;
}
usbMIDI.sendNoteOn(note + MIDI_OFFSET + 12 * transpose, velocity, midiOutChannel);
handleNoteOn(channel, note + MIDI_OFFSET, velocity);
}
@ -554,6 +567,7 @@ void handleInternalNoteOff(uint8_t channel, uint8_t note, uint8_t velocity){
// handleKeyboardFunction(note, 0);
return;
}
usbMIDI.sendNoteOff(note + MIDI_OFFSET + 12 * transpose, 0, midiOutChannel);
handleNoteOff(channel, note + MIDI_OFFSET, velocity);
}
@ -636,7 +650,7 @@ void handleNoteOff(uint8_t channel, uint8_t note, uint8_t velocity){
void handlePitchBend(uint8_t channel, int16_t bend){
// dcPitchBend.amplitude(((float)bend - PITCH_BEND_NEUTRAL) / PITCH_BEND_COURSE); // Pitch bend goes from -168 to 134.
dcPitchBend.amplitude(((float)bend) / 8190);
// dcPitchBend.amplitude(((float)bend) / 8190);
// neutral at -11 from up, -24 from down. :/
// MIDI.sendPitchBend(bend - PITCH_BEND_NEUTRAL, 0);
/*
@ -691,6 +705,9 @@ void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){
case CC_PORTAMENTO_TIME:
// CC_5
break;
case CC_CHANNEL_VOL:
// CC_7
break;
case CC_OSC_TUNE:
// CC_9
break;
@ -773,6 +790,10 @@ void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){
// CC_37
glide = longValue;
break;
case CC_CHANNEL_VOL_LSB:
// CC_39
masterVolume.gain((float)longValue / RESO);
break;
case CC_OSC_TUNE_LSB:
// CC_41
dcOscTune.amplitude(HALFTONE_TO_DC * 2 * ((float)longValue - HALF_RESO) / RESO);
@ -807,15 +828,22 @@ void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){
break;
case CC_FILTER_BAND_LSB:
// CC_51
filterBandValue = longValue;
AudioNoInterrupts();
if(longValue < HALF_RESO){
bandMixer.gain(0, ((float)HALF_RESO - (float)longValue) / HALF_RESO);
bandMixer.gain(1, (float)longValue / HALF_RESO);
bandMixer.gain(2, 0.0);
} else {
bandMixer.gain(0, 0.0);
bandMixer.gain(1, ((float)RESO - (float)longValue) / HALF_RESO);
bandMixer.gain(2, ((float)longValue - HALF_RESO) / HALF_RESO);
if(filterMode == FILTER_BAND_PASS){
if(longValue < HALF_RESO){
bandMixer.gain(0, ((float)HALF_RESO - (float)longValue) / HALF_RESO);
bandMixer.gain(1, (float)longValue / HALF_RESO);
bandMixer.gain(2, 0.0);
} else {
bandMixer.gain(0, 0.0);
bandMixer.gain(1, ((float)RESO - (float)longValue) / HALF_RESO);
bandMixer.gain(2, ((float)longValue - HALF_RESO) / HALF_RESO);
}
} else if(filterMode == FILTER_BAND_STOP){
bandMixer.gain(0, (float)(RESO - longValue) / RESO);
bandMixer.gain(1, 0.0);
bandMixer.gain(2, (float)longValue / RESO);
}
AudioInterrupts();
break;
@ -833,7 +861,7 @@ void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){
break;
case CC_FILTER_ATTACK_LSB:
// CC_55
filterEnvelope.attack((float)longValue * 5.0);
filterEnvelope.attack(1 + (float)longValue * 5.0);
break;
case CC_FILTER_DECAY_LSB:
// CC_56
@ -845,11 +873,11 @@ void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){
break;
case CC_FILTER_RELEASE_LSB:
// CC_58
filterEnvelope.release((float)longValue * 5.0);
filterEnvelope.release(1 + (float)longValue * 5.0);
break;
case CC_EG_ATTACK_LSB:
// CC_59
mainEnvelope.attack((float)longValue * 5.0);
mainEnvelope.attack(1 + (float)longValue * 5.0);
break;
case CC_EG_DECAY_LSB:
// CC_60
@ -861,7 +889,7 @@ void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){
break;
case CC_EG_RELEASE_LSB:
// CC_62
mainEnvelope.release((float)longValue * 5.0);
mainEnvelope.release(1 + (float)longValue * 5.0);
break;
case CC_LFO_RATE_LSB:
// CC_63
@ -1047,15 +1075,15 @@ void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){
}
}
void handleKeyboardFunction(uint8_t note, bool active){
void handleKeyboardFunction(uint8_t key, bool active){
//
/*
Serial.print("key pressed : ");
Serial.println(note);
Serial.println(key);
*/
// Change function
switch(note){
switch(key){
case 0:
// lower DO
currentFunction = FUNCTION_KEYBOARD_MODE;
@ -1078,61 +1106,84 @@ void handleKeyboardFunction(uint8_t note, bool active){
break;
case 7:
// lower SOL
currentFunction = FUNCTION_MIDI_IN_CHANNEL;
// Serial.println("midi in channel");
currentFunction = FUNCTION_FILTER_MODE;
break;
case 9:
// lower LA
currentFunction = FUNCTION_MIDI_OUT_CHANNEL;
// Serial.println("midi out channel");
currentFunction = FUNCTION_MIDI_IN_CHANNEL;
// Serial.println("midi in channel");
break;
case 11:
// lower Si
// lower SI
currentFunction = FUNCTION_MIDI_OUT_CHANNEL;
// Serial.println("midi out channel");
break;
default:
if(note < 12) return;
note -= 12;
if(key < 12) return;
key -= 12;
break;
}
switch(currentFunction){
case FUNCTION_KEYBOARD_MODE:
if(note > KEY_UPPER) return;
keyMode = (keyMode_t)note;
if(key > KEY_UPPER) return;
keyMode = (keyMode_t)key;
EEPROM.put(EE_KEYBOARD_MODE_ADD, keyMode);
break;
case FUNCTION_RETRIGGER:
if(note > 1) return;
noteRetrigger = note;
if(key > 1) return;
noteRetrigger = key;
EEPROM.put(EE_TRIGGER_ADD, noteRetrigger);
break;
case FUNCTION_DETUNE:
if(note > DETUNE_RESET) return;
if(note == DETUNE_RESET){
if(key > DETUNE_RESET) return;
if(key == DETUNE_RESET){
// run a new detuning table
resetDetuneTable();
} else {
detune = (detune_t)note;
detune = (detune_t)key;
EEPROM.put(EE_DETUNE_ADD, detune);
}
break;
case FUNCTION_BITCRUSH:
if(note > 12) return;
note += 4;
bitCrushOutput.bits(note);
EEPROM.put(EE_BITCRUSH_ADD, note);
break;
if(key > 12) return;
key += 4;
bitCrushOutput.bits(key);
EEPROM.put(EE_BITCRUSH_ADD, key);
break;
case FUNCTION_FILTER_MODE:
if(key > 1) return;
filterMode = (filterMode_t)key;
EEPROM.put(EE_FILTER_MODE, filterMode);
AudioNoInterrupts();
if(filterMode == FILTER_BAND_PASS){
if(filterBandValue < HALF_RESO){
bandMixer.gain(0, ((float)HALF_RESO - (float)filterBandValue) / HALF_RESO);
bandMixer.gain(1, (float)filterBandValue / HALF_RESO);
bandMixer.gain(2, 0.0);
} else {
bandMixer.gain(0, 0.0);
bandMixer.gain(1, ((float)RESO - (float)filterBandValue) / HALF_RESO);
bandMixer.gain(2, ((float)filterBandValue - HALF_RESO) / HALF_RESO);
}
} else if(filterMode == FILTER_BAND_STOP){
bandMixer.gain(0, (float)(RESO - filterBandValue) / RESO);
bandMixer.gain(1, 0.0);
bandMixer.gain(2, (float)filterBandValue / RESO);
}
AudioInterrupts();
break;
case FUNCTION_MIDI_IN_CHANNEL:
// change (usb) midi in channel
if(note > 16)return;
midiInChannel = note;
if(key > 16)return;
midiInChannel = key + 1;
//MIDI.begin(midiInChannel);
EEPROM.put(EE_MIDI_IN_CH_ADD, midiInChannel);
break;
case FUNCTION_MIDI_OUT_CHANNEL:
// change (usb) midi out channel
if(note > 16)return;
midiOutChannel = note;
if(key > 16)return;
midiOutChannel = key + 1;
//MIDI.begin(midiInChannel);
EEPROM.put(EE_MIDI_OUT_CH_ADD, midiOutChannel);
break;

Loading…
Cancel
Save