Fixes and additions for portamento.

Added modulator input for mono2stereo.
Changed memory usage for AUDIO_MEM.
pull/32/head
Holger Wirtz 5 years ago
parent 86e1aa57e0
commit 89c13cfef3
  1. 11
      config.h
  2. 5
      dexed.cpp
  3. 1
      dexed.h
  4. 29
      dx7note.cpp
  5. 4
      dx7note.h
  6. 36
      effect_mono2stereo.cpp
  7. 7
      effect_mono2stereo.h

@ -91,17 +91,17 @@
//************************************************************************************************* //*************************************************************************************************
#ifndef TEENSY_AUDIO_BOARD #ifndef TEENSY_AUDIO_BOARD
#if AUDIO_BLOCK_SAMPLES == 64 #if AUDIO_BLOCK_SAMPLES == 64
#define AUDIO_MEM 450 #define AUDIO_MEM 256
#else #else
#define AUDIO_MEM 225 #define AUDIO_MEM 128
#endif #endif
#define REDUCE_LOUDNESS 1 #define REDUCE_LOUDNESS 1
#else // IF TEENSY_AUDIO_BOARD #else // IF TEENSY_AUDIO_BOARD
#define SGTL5000_LINEOUT_LEVEL 29 #define SGTL5000_LINEOUT_LEVEL 29
#if AUDIO_BLOCK_SAMPLES == 64 #if AUDIO_BLOCK_SAMPLES == 64
#define AUDIO_MEM 900 #define AUDIO_MEM 512
#else #else
#define AUDIO_MEM 450 #define AUDIO_MEM 256
#endif #endif
#define DELAY_MAX_TIME 600 #define DELAY_MAX_TIME 600
#define REDUCE_LOUDNESS 1 #define REDUCE_LOUDNESS 1
@ -475,9 +475,12 @@ typedef struct {
dexed_t dexed[NUM_DEXED]; dexed_t dexed[NUM_DEXED];
} config_t; } config_t;
#if !defined(_MAPFLOAT)
#define _MAPFLOAT
inline float mapfloat(float val, float in_min, float in_max, float out_min, float out_max) inline float mapfloat(float val, float in_min, float in_max, float out_min, float out_max)
{ {
return (val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; return (val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
} }
#endif
#endif // CONFIG_H_INCLUDED #endif // CONFIG_H_INCLUDED

@ -119,7 +119,7 @@ void Dexed::getSamples(uint16_t n_samples, int16_t* buffer)
for (i = 0; i < max_notes; i++) for (i = 0; i < max_notes; i++)
{ {
if ( voices[i].live ) if ( voices[i].live )
voices[i].dx7_note->update(data, voices[i].midi_note, voices[i].velocity); voices[i].dx7_note->update(data, voices[i].midi_note, voices[i].velocity, voices[i].porta);
} }
lfo.reset(data + 137); lfo.reset(data + 137);
@ -212,7 +212,8 @@ void Dexed::keydown(int16_t pitch, uint8_t velo) {
voices[note].velocity = velo; voices[note].velocity = velo;
voices[note].sustained = sustain; voices[note].sustained = sustain;
voices[note].keydown = true; voices[note].keydown = true;
voices[note].dx7_note->init(data, pitch, velo, previousKeyDown, porta); int srcnote = (previousKeyDown >= 0) ? previousKeyDown : pitch;
voices[note].dx7_note->init(data, pitch, velo, srcnote, porta);
if ( data[136] ) if ( data[136] )
voices[note].dx7_note->oscSync(); voices[note].dx7_note->oscSync();
break; break;

@ -48,6 +48,7 @@ extern float vol_left;
struct ProcessorVoice { struct ProcessorVoice {
int16_t midi_note; int16_t midi_note;
uint8_t velocity; uint8_t velocity;
int16_t porta;
bool keydown; bool keydown;
bool sustained; bool sustained;
bool live; bool live;

@ -23,6 +23,7 @@
#include "exp2.h" #include "exp2.h"
#include "controllers.h" #include "controllers.h"
#include "dx7note.h" #include "dx7note.h"
#include "dexed.h"
const int FEEDBACK_BITDEPTH = 8; const int FEEDBACK_BITDEPTH = 8;
@ -33,6 +34,13 @@ int32_t midinote_to_logfreq(int midinote) {
return base + step * midinote; return base + step * midinote;
} }
int32_t logfreq_round2semi(int freq) {
const int base = 50857777; // (1 << 24) * (log(440) / log(2) - 69/12)
const int step = (1 << 24) / 12;
const int rem = (freq - base) % step;
return freq - rem;
}
const int32_t coarsemul[] = { const int32_t coarsemul[] = {
-16777216, 0, 16777216, 26591258, 33554432, 38955489, 43368474, 47099600, -16777216, 0, 16777216, 26591258, 33554432, 38955489, 43368474, 47099600,
50331648, 53182516, 55732705, 58039632, 60145690, 62083076, 63876816, 50331648, 53182516, 55732705, 58039632, 60145690, 62083076, 63876816,
@ -176,6 +184,7 @@ void Dx7Note::init(const uint8_t patch[173], int midinote, int velocity, int src
int32_t freq = osc_freq(midinote, mode, coarse, fine, detune); int32_t freq = osc_freq(midinote, mode, coarse, fine, detune);
opMode[op] = mode; opMode[op] = mode;
basepitch_[op] = freq; basepitch_[op] = freq;
porta_curpitch_[op] = freq;
ampmodsens_[op] = ampmodsenstab[patch[off + 14] & 3]; ampmodsens_[op] = ampmodsenstab[patch[off + 14] & 3];
if (porta >= 0) if (porta >= 0)
@ -193,6 +202,7 @@ void Dx7Note::init(const uint8_t patch[173], int midinote, int velocity, int src
pitchmodsens_ = pitchmodsenstab[patch[143] & 7]; pitchmodsens_ = pitchmodsenstab[patch[143] & 7];
ampmoddepth_ = (patch[140] * 165) >> 6; ampmoddepth_ = (patch[140] * 165) >> 6;
porta_rateindex_ = (porta < 128) ? porta : 127; porta_rateindex_ = (porta < 128) ? porta : 127;
porta_gliss_ = patch[68];
} }
void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay, const Controllers *ctrls) { void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay, const Controllers *ctrls) {
@ -246,8 +256,11 @@ void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay, const Co
if ( opMode[op] ) if ( opMode[op] )
params_[op].freq = Freqlut::lookup(basepitch + pitch_base); params_[op].freq = Freqlut::lookup(basepitch + pitch_base);
else { else {
if ( porta_rateindex_ >= 0 ) if ( porta_rateindex_ >= 0 ) {
basepitch = porta_curpitch_[op]; basepitch = porta_curpitch_[op];
if ( porta_gliss_ )
basepitch = logfreq_round2semi(basepitch);
}
params_[op].freq = Freqlut::lookup(basepitch + pitch_mod); params_[op].freq = Freqlut::lookup(basepitch + pitch_mod);
} }
@ -293,7 +306,7 @@ void Dx7Note::keyup() {
pitchenv_.keydown(false); pitchenv_.keydown(false);
} }
void Dx7Note::update(const uint8_t patch[156], int midinote, int velocity) { void Dx7Note::update(const uint8_t patch[156], int midinote, int velocity, int porta) {
int rates[4]; int rates[4];
int levels[4]; int levels[4];
for (int op = 0; op < 6; op++) { for (int op = 0; op < 6; op++) {
@ -302,7 +315,9 @@ void Dx7Note::update(const uint8_t patch[156], int midinote, int velocity) {
int coarse = patch[off + 18]; int coarse = patch[off + 18];
int fine = patch[off + 19]; int fine = patch[off + 19];
int detune = patch[off + 20]; int detune = patch[off + 20];
basepitch_[op] = osc_freq(midinote, mode, coarse, fine, detune); int32_t freq = osc_freq(midinote, mode, coarse, fine, detune);
basepitch_[op] = freq;
porta_curpitch_[op] = freq;
ampmodsens_[op] = ampmodsenstab[patch[off + 14] & 3]; ampmodsens_[op] = ampmodsenstab[patch[off + 14] & 3];
opMode[op] = mode; opMode[op] = mode;
@ -328,6 +343,8 @@ void Dx7Note::update(const uint8_t patch[156], int midinote, int velocity) {
pitchmoddepth_ = (patch[139] * 165) >> 6; pitchmoddepth_ = (patch[139] * 165) >> 6;
pitchmodsens_ = pitchmodsenstab[patch[143] & 7]; pitchmodsens_ = pitchmodsenstab[patch[143] & 7];
ampmoddepth_ = (patch[140] * 165) >> 6; ampmoddepth_ = (patch[140] * 165) >> 6;
porta_rateindex_ = (porta < 128) ? porta : 127;
porta_gliss_ = patch[68];
} }
void Dx7Note::peekVoiceStatus(VoiceStatus &status) { void Dx7Note::peekVoiceStatus(VoiceStatus &status) {
@ -356,6 +373,12 @@ void Dx7Note::transferSignal(Dx7Note &src) {
} }
} }
void Dx7Note::transferPortamento(Dx7Note &src) {
for (int i = 0; i < 6; i++) {
porta_curpitch_[i] = src.porta_curpitch_[i];
}
}
void Dx7Note::oscSync() { void Dx7Note::oscSync() {
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
params_[i].gain_out = 0; params_[i].gain_out = 0;

@ -53,10 +53,11 @@ class Dx7Note {
// keyup, that won't work. // keyup, that won't work.
// PG:add the update // PG:add the update
void update(const uint8_t patch[156], int midinote, int velocity); void update(const uint8_t patch[156], int midinote, int velocity, int porta);
void peekVoiceStatus(VoiceStatus &status); void peekVoiceStatus(VoiceStatus &status);
void transferState(Dx7Note& src); void transferState(Dx7Note& src);
void transferSignal(Dx7Note &src); void transferSignal(Dx7Note &src);
void transferPortamento(Dx7Note &src);
void oscSync(); void oscSync();
private: private:
@ -75,6 +76,7 @@ class Dx7Note {
int pitchmodsens_; int pitchmodsens_;
int porta_rateindex_; int porta_rateindex_;
int porta_gliss_;
int32_t porta_curpitch_[6]; int32_t porta_curpitch_[6];
}; };

@ -22,47 +22,59 @@
#include <Arduino.h> #include <Arduino.h>
#include <Audio.h> #include <Audio.h>
#include "mono2stereo.h" #include "effect_mono2stereo.h"
/*************************************************************************/ /*************************************************************************/
// A u d i o E f f e c t M o n o 2 S t e r e o // A u d i o E f f e c t M o n o 2 S t e r e o
// Written by Holger Wirtz // Written by Holger Wirtz
// 20191122 - inital version // 20191122 - initial version
void Mono2Stereo::pan(float pan) #if !defined(_MAPFLOAT)
#define _MAPFLOAT
inline float mapfloat(float val, float in_min, float in_max, float out_min, float out_max)
{ {
constrain(pan, 0.0, 1.0); return (val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
_pan = pan;
} }
#endif
void Mono2Stereo::update(void) void Mono2Stereo::update(void)
{ {
audio_block_t *in; audio_block_t *in;
audio_block_t *mod;
audio_block_t *out[2]; audio_block_t *out[2];
in = receiveReadOnly(0); in = receiveReadOnly(0);
mod = receiveReadOnly(1);
out[0] = allocate(); out[0] = allocate();
out[1] = allocate(); out[1] = allocate();
if (in && out[0] && out[1]) if (in && mod && out[0] && out[1])
{ {
int16_t *ip = in->data; int16_t *ip = in->data;
int16_t *modp = mod->data;
int16_t *op[2] = { out[0]->data, out[1]->data }; int16_t *op[2] = { out[0]->data, out[1]->data };
float f_l = _pseudo_log * sinf(_pan * PI / 2); // _Pan [L0.0 ... M0.5 ... 1.0R]
float f_r = _pseudo_log * cosf(_pan * PI / 2);
for (uint16_t i = 0; i < AUDIO_BLOCK_SAMPLES; i++) for (uint16_t i = 0; i < AUDIO_BLOCK_SAMPLES; i++)
{ {
*op[0] = int16_t(f_l * (*ip)); mapfloat(*modp, -1.0, 1.0, 0.0, 1.0);
*op[1] = int16_t(f_r * (*ip++)); float f_l = _pseudo_log * sinf(*modp * PI / 2); // _Pan [L0.0 ... M0.5 ... 1.0R]
op[0]++; float f_r = _pseudo_log * cosf(*modp * PI / 2);
op[1]++; *op[0]++ = int16_t(f_l * (*ip));
*op[1]++ = int16_t(f_r * (*ip++));
//op[0]++;
//op[1]++;
mod++;
} }
if (in) if (in)
{ {
release(in); release(in);
} }
if (mod)
{
release(mod);
}
for (uint8_t i = 0; i < 2; i++) for (uint8_t i = 0; i < 2; i++)
{ {
if (out[i]) if (out[i])

@ -20,8 +20,8 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
#ifndef mono2stereo_h_ #ifndef effect_mono2stereo_h_
#define mono2stereo_h_ #define effect_mono2stereo_h_
#include "Arduino.h" #include "Arduino.h"
#include "AudioStream.h" #include "AudioStream.h"
@ -35,13 +35,12 @@ class Mono2Stereo : public AudioStream
{ {
public: public:
Mono2Stereo(void): Mono2Stereo(void):
AudioStream(1, inputQueueArray) AudioStream(2, inputQueueArray)
{ {
_pan = 0.5; _pan = 0.5;
} }
virtual void update(void); virtual void update(void);
virtual void pan(float pan);
private: private:
audio_block_t *inputQueueArray[4]; audio_block_t *inputQueueArray[4];
Loading…
Cancel
Save