FIRST WORKING VERSION!
pull/4/head
Holger Wirtz 7 years ago
parent 4660200948
commit fd755727b5
  1. 23
      MicroDexed.ino
  2. 7
      dexed.cpp
  3. 3
      dexed.h
  4. 67
      dx7note.cpp
  5. 1
      synth.h

@ -4,6 +4,7 @@
#include "dexed.h"
#define RATE 128
#define SAMPLERATE 44100
#define TEENSY 1
#define TEST_MIDI 1
#define TEST_NOTE1 59
@ -18,11 +19,13 @@
// GUItool: begin automatically generated code
AudioPlayQueue queue1; //xy=266,484
AudioEffectReverb reverb1; //xy=486,545
//AudioEffectReverb reverb1; //xy=486,545
AudioOutputI2S i2s1; //xy=739,486
AudioConnection patchCord1(queue1, reverb1);
AudioConnection patchCord2(reverb1, 0, i2s1, 0);
AudioConnection patchCord3(reverb1, 0, i2s1, 1);
//AudioConnection patchCord1(queue1, reverb1);
//AudioConnection patchCord2(reverb1, 0, i2s1, 0);
//AudioConnection patchCord3(reverb1, 0, i2s1, 1);
AudioConnection patchCord2(queue1, 0, i2s1, 0);
AudioConnection patchCord3(queue1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=384,610
// GUItool: end automatically generated code
@ -40,7 +43,7 @@ AudioControlSGTL5000 sgtl5000_1; //xy=384,610
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
Dexed* dexed = new Dexed(RATE);
Dexed* dexed = new Dexed(SAMPLERATE);
void setup()
{
@ -57,7 +60,7 @@ void setup()
AudioMemory(16);
sgtl5000_1.enable();
sgtl5000_1.volume(0.6);
sgtl5000_1.volume(0.3);
// Initialize processor and memory measurements
//AudioProcessorUsageMaxReset();
@ -82,7 +85,7 @@ void setup()
dexed->ProcessMidiMessage(0x90, TEST_NOTE2, 60);
#endif
reverb1.reverbTime(5.0);
//reverb1.reverbTime(5.0);
Serial.println("Go");
}
@ -110,16 +113,14 @@ void loop()
// process midi->audio
if (MIDI.read())
{
Serial.print("Type: ");
/* Serial.print("Type: ");
Serial.print(MIDI.getType(), DEC);
Serial.print(" Data1: ");
Serial.print(MIDI.getData1(), DEC);
Serial.print(" Data2: ");
Serial.println(MIDI.getData2(), DEC);
Serial.println(MIDI.getData2(), DEC); */
dexed->ProcessMidiMessage(MIDI.getType(), MIDI.getData1(), MIDI.getData2());
}
else
dexed->GetSamples(RATE, audio_buffer);
/* uint8_t i = 0;

@ -31,7 +31,7 @@
#include <unistd.h>
#include <limits.h>
Dexed::Dexed(uint8_t rate)
Dexed::Dexed(int rate)
{
uint8_t i;
@ -177,12 +177,11 @@ void Dexed::GetSamples(uint16_t n_samples, int16_t* buffer)
voices[note].dx7_note->compute(audiobuf.get(), lfovalue, lfodelay, &controllers);
for (uint8_t j = 0; j < _N_; ++j) {
int32_t val = audiobuf.get()[j];
//val = val >> 4;
val = val >> 4;
int32_t clip_val = val < -(1 << 24) ? 0x8000 : val >= (1 << 24) ? 0x7fff : val >> 9;
/* float f = static_cast<float>(clip_val >> 1) / static_cast<float>(0x8000);
float f = static_cast<float>(clip_val >> 1) / static_cast<float>(0x8000);
if (f > 1) f = 1;
if (f < -1) f = -1;
sumbuf[j] += f;*/
sumbuf[j] += clip_val;
audiobuf.get()[j] = 0;
}

@ -55,7 +55,7 @@ enum DexedEngineResolution {
class Dexed
{
public:
Dexed(uint8_t rate);
Dexed(int rate);
~Dexed();
void activate(void);
void deactivate(void);
@ -96,7 +96,6 @@ class Dexed
uint32_t extra_buf_size_;
private:
uint16_t _rate;
uint8_t _k_rate_counter;
uint8_t _param_change_counter;

@ -1,19 +1,19 @@
/*
* Copyright 2016-2017 Pascal Gauthier.
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Copyright 2016-2017 Pascal Gauthier.
Copyright 2012 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <math.h>
#include <stdlib.h>
@ -26,8 +26,8 @@
const int FEEDBACK_BITDEPTH = 8;
int32_t midinote_to_logfreq(int midinote) {
const int base = 50857777; // (1 << 24) * (log(440) / log(2) - 69/12)
const int step = (1 << 24) / 12;
const int32_t base = 50857777; // (1 << 24) * (log(440) / log(2) - 69/12)
const int32_t step = (1 << 24) / 12;
return base + step * midinote;
}
@ -44,9 +44,8 @@ int32_t osc_freq(int midinote, int mode, int coarse, int fine, int detune) {
int32_t logfreq;
if (mode == 0) {
logfreq = midinote_to_logfreq(midinote);
// could use more precision, closer enough for now. those numbers comes from my DX7
double detuneRatio = 0.0209 * exp(-0.396 * (((float)logfreq)/(1<<24))) / 7;
double detuneRatio = 0.0209 * exp(-0.396 * (((float)logfreq) / (1 << 24))) / 7;
logfreq += detuneRatio * logfreq * (detune - 7);
logfreq += coarsemul[coarse & 31];
@ -122,9 +121,9 @@ int ScaleLevel(int midinote, int break_pt, int left_depth, int right_depth,
int left_curve, int right_curve) {
int offset = midinote - break_pt - 17;
if (offset >= 0) {
return ScaleCurve((offset+1) / 3, right_depth, right_curve);
return ScaleCurve((offset + 1) / 3, right_depth, right_curve);
} else {
return ScaleCurve(-(offset-1) / 3, left_depth, left_curve);
return ScaleCurve(-(offset - 1) / 3, left_depth, left_curve);
}
}
@ -138,7 +137,7 @@ static const uint32_t ampmodsenstab[] = {
};
Dx7Note::Dx7Note() {
for(int op=0;op<6;op++) {
for (int op = 0; op < 6; op++) {
params_[op].phase = 0;
params_[op].gain_out = 0;
}
@ -215,20 +214,20 @@ void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay, const Co
pitch_mod += pitch_base;
// ==== AMP MOD ====
lfo_val = (1<<24) - lfo_val;
lfo_val = (1 << 24) - lfo_val;
uint32_t amod_1 = (uint32_t)(((int64_t) ampmoddepth_ * (int64_t) lfo_delay) >> 8); // Q24 :D
amod_1 = (uint32_t)(((int64_t) amod_1 * (int64_t) lfo_val) >> 24);
uint32_t amod_2 = (uint32_t)(((int64_t) ctrls->amp_mod * (int64_t) lfo_val) >> 7); // Q?? :|
uint32_t amd_mod = max(amod_1, amod_2);
// ==== EG AMP MOD ====
uint32_t amod_3 = (ctrls->eg_mod+1) << 17;
amd_mod = max((1<<24) - amod_3, amd_mod);
uint32_t amod_3 = (ctrls->eg_mod + 1) << 17;
amd_mod = max((1 << 24) - amod_3, amd_mod);
// ==== OP RENDER ====
for (int op = 0; op < 6; op++) {
// if ( ctrls->opSwitch[op] == '0' ) {
if (!(ctrls->opSwitch & (1<<op))) {
if (!(ctrls->opSwitch & (1 << op))) {
env_[op].getsample(); // advance the envelop even if it is not playing
params_[op].level_in = 0;
} else {
@ -244,8 +243,8 @@ void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay, const Co
uint32_t sensamp = (uint32_t)(((uint64_t) amd_mod) * ((uint64_t) ampmodsens_[op]) >> 24);
// TODO: mehhh.. this needs some real tuning.
uint32_t pt = exp(((float)sensamp)/262144 * 0.07 + 12.2);
uint32_t ldiff = (uint32_t)(((uint64_t)level) * (((uint64_t)pt<<4)) >> 28);
uint32_t pt = exp(((float)sensamp) / 262144 * 0.07 + 12.2);
uint32_t ldiff = (uint32_t)(((uint64_t)level) * (((uint64_t)pt << 4)) >> 28);
level -= ldiff;
}
params_[op].level_in = level;
@ -299,7 +298,7 @@ void Dx7Note::update(const uint8_t patch[156], int midinote, int velocity) {
}
void Dx7Note::peekVoiceStatus(VoiceStatus &status) {
for(int i=0;i<6;i++) {
for (int i = 0; i < 6; i++) {
status.amp[i] = Exp2::lookup(params_[i].level_in - (14 * (1 << 24)));
env_[i].getPosition(&status.ampStep[i]);
}
@ -307,10 +306,10 @@ void Dx7Note::peekVoiceStatus(VoiceStatus &status) {
}
/**
* Used in monophonic mode to transfert voice state from different notes
*/
Used in monophonic mode to transfert voice state from different notes
*/
void Dx7Note::transferState(Dx7Note &src) {
for (int i=0;i<6;i++) {
for (int i = 0; i < 6; i++) {
env_[i].transfer(src.env_[i]);
params_[i].gain_out = src.params_[i].gain_out;
params_[i].phase = src.params_[i].phase;
@ -318,14 +317,14 @@ void Dx7Note::transferState(Dx7Note &src) {
}
void Dx7Note::transferSignal(Dx7Note &src) {
for (int i=0;i<6;i++) {
for (int i = 0; i < 6; i++) {
params_[i].gain_out = src.params_[i].gain_out;
params_[i].phase = src.params_[i].phase;
}
}
void Dx7Note::oscSync() {
for (int i=0;i<6;i++) {
for (int i = 0; i < 6; i++) {
params_[i].gain_out = 0;
params_[i].phase = 0;
}

@ -18,6 +18,7 @@
#define __SYNTH_H
#include <Arduino.h>
#define SUPER_PRECISE
// This IS not be present on MSVC.
// See http://stackoverflow.com/questions/126279/c99-stdint-h-header-and-ms-visual-studio

Loading…
Cancel
Save