First try for Teensy-3.5 with audio shield

pull/4/head
Holger Wirtz 6 years ago
parent ca3a5af54e
commit 13b46f987d
  1. 24
      EngineMkI.cpp
  2. 14
      EngineOpl.cpp
  3. 56
      MicroDexed.ino
  4. 52
      dexed.cpp
  5. 4
      dexed.h
  6. 2
      fm_core.h
  7. 32
      fm_op_kernel.cpp
  8. 2
      lfo.cpp
  9. 2
      pitchenv.cpp
  10. 2
      synth.h

@ -44,9 +44,9 @@
double round(double n) { double round(double n) {
return n < 0.0 ? ceil(n - 0.5) : floor(n + 0.5); return n < 0.0 ? ceil(n - 0.5) : floor(n + 0.5);
} }
__declspec(align(16)) const int zeros[N] = {0}; __declspec(align(16)) const int zeros[_N_] = {0};
#else #else
const int32_t __attribute__ ((aligned(16))) zeros[N] = {0}; const int32_t __attribute__ ((aligned(16))) zeros[_N_] = {0};
#endif #endif
static const uint16_t NEGATIVE_BIT = 0x8000; static const uint16_t NEGATIVE_BIT = 0x8000;
@ -147,12 +147,12 @@ inline int32_t mkiSin(int32_t phase, uint16_t env) {
void EngineMkI::compute(int32_t *output, const int32_t *input, void EngineMkI::compute(int32_t *output, const int32_t *input,
int32_t phase0, int32_t freq, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, bool add) { int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
const int32_t *adder = add ? output : zeros; const int32_t *adder = add ? output : zeros;
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
int32_t y = mkiSin((phase+input[i]), gain); int32_t y = mkiSin((phase+input[i]), gain);
output[i] = y + adder[i]; output[i] = y + adder[i];
@ -163,12 +163,12 @@ void EngineMkI::compute(int32_t *output, const int32_t *input,
void EngineMkI::compute_pure(int32_t *output, int32_t phase0, int32_t freq, void EngineMkI::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, bool add) { int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
const int32_t *adder = add ? output : zeros; const int32_t *adder = add ? output : zeros;
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
int32_t y = mkiSin(phase , gain); int32_t y = mkiSin(phase , gain);
output[i] = y + adder[i]; output[i] = y + adder[i];
@ -179,14 +179,14 @@ void EngineMkI::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
void EngineMkI::compute_fb(int32_t *output, int32_t phase0, int32_t freq, void EngineMkI::compute_fb(int32_t *output, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, int32_t gain1, int32_t gain2,
int32_t *fb_buf, int fb_shift, bool add) { int32_t *fb_buf, int fb_shift, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
const int32_t *adder = add ? output : zeros; const int32_t *adder = add ? output : zeros;
int32_t y0 = fb_buf[0]; int32_t y0 = fb_buf[0];
int32_t y = fb_buf[1]; int32_t y = fb_buf[1];
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
int32_t scaled_fb = (y0 + y) >> (fb_shift + 1); int32_t scaled_fb = (y0 + y) >> (fb_shift + 1);
y0 = y; y0 = y;
@ -215,10 +215,10 @@ void EngineMkI::compute_fb2(int32_t *output, FmOpParams *parms, int32_t gain01,
gain[0] = gain01; gain[0] = gain01;
gain[1] = parms[1].gain_out == 0 ? (ENV_MAX-1) : parms[1].gain_out; gain[1] = parms[1].gain_out == 0 ? (ENV_MAX-1) : parms[1].gain_out;
dgain[0] = (gain02 - gain01 + (N >> 1)) >> LG_N; dgain[0] = (gain02 - gain01 + (_N_ >> 1)) >> LG_N;
dgain[1] = (parms[1].gain_out - (parms[1].gain_out == 0 ? (ENV_MAX-1) : parms[1].gain_out)); dgain[1] = (parms[1].gain_out - (parms[1].gain_out == 0 ? (ENV_MAX-1) : parms[1].gain_out));
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
int32_t scaled_fb = (y0 + y) >> (fb_shift + 1); int32_t scaled_fb = (y0 + y) >> (fb_shift + 1);
// op 0 // op 0
@ -257,12 +257,12 @@ void EngineMkI::compute_fb3(int32_t *output, FmOpParams *parms, int32_t gain01,
gain[1] = parms[1].gain_out == 0 ? (ENV_MAX-1) : parms[1].gain_out; gain[1] = parms[1].gain_out == 0 ? (ENV_MAX-1) : parms[1].gain_out;
gain[2] = parms[2].gain_out == 0 ? (ENV_MAX-1) : parms[2].gain_out; gain[2] = parms[2].gain_out == 0 ? (ENV_MAX-1) : parms[2].gain_out;
dgain[0] = (gain02 - gain01 + (N >> 1)) >> LG_N; dgain[0] = (gain02 - gain01 + (_N_ >> 1)) >> LG_N;
dgain[1] = (parms[1].gain_out - (parms[1].gain_out == 0 ? (ENV_MAX-1) : parms[1].gain_out)); dgain[1] = (parms[1].gain_out - (parms[1].gain_out == 0 ? (ENV_MAX-1) : parms[1].gain_out));
dgain[2] = (parms[2].gain_out - (parms[2].gain_out == 0 ? (ENV_MAX-1) : parms[2].gain_out)); dgain[2] = (parms[2].gain_out - (parms[2].gain_out == 0 ? (ENV_MAX-1) : parms[2].gain_out));
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
int32_t scaled_fb = (y0 + y) >> (fb_shift + 1); int32_t scaled_fb = (y0 + y) >> (fb_shift + 1);
// op 0 // op 0

@ -28,7 +28,7 @@
#ifdef _WIN32 #ifdef _WIN32
__declspec(align(16)) const int zeros[N] = {0}; __declspec(align(16)) const int zeros[N] = {0};
#else #else
const int32_t __attribute__ ((aligned(16))) zeros[N] = {0}; const int32_t __attribute__ ((aligned(16))) zeros[_N_] = {0};
#endif #endif
uint16_t SignBit = 0x8000; uint16_t SignBit = 0x8000;
@ -117,12 +117,12 @@ inline int16_t oplSin( uint16_t phase, uint16_t env ) {
} }
void EngineOpl::compute(int32_t *output, const int32_t *input, int32_t phase0, int32_t freq, int32_t gain1, int32_t gain2, bool add) { void EngineOpl::compute(int32_t *output, const int32_t *input, int32_t phase0, int32_t freq, int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
const int32_t *adder = add ? output : zeros; const int32_t *adder = add ? output : zeros;
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
int32_t y = oplSin((phase+input[i]) >> 14, gain); int32_t y = oplSin((phase+input[i]) >> 14, gain);
output[i] = (y << 14) + adder[i]; output[i] = (y << 14) + adder[i];
@ -131,12 +131,12 @@ void EngineOpl::compute(int32_t *output, const int32_t *input, int32_t phase0, i
} }
void EngineOpl::compute_pure(int32_t *output, int32_t phase0, int32_t freq, int32_t gain1, int32_t gain2, bool add) { void EngineOpl::compute_pure(int32_t *output, int32_t phase0, int32_t freq, int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
const int32_t *adder = add ? output : zeros; const int32_t *adder = add ? output : zeros;
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
int32_t y = oplSin(phase >> 14, gain); int32_t y = oplSin(phase >> 14, gain);
output[i] = (y << 14) + adder[i]; output[i] = (y << 14) + adder[i];
@ -147,14 +147,14 @@ void EngineOpl::compute_pure(int32_t *output, int32_t phase0, int32_t freq, int3
void EngineOpl::compute_fb(int32_t *output, int32_t phase0, int32_t freq, void EngineOpl::compute_fb(int32_t *output, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, int32_t gain1, int32_t gain2,
int32_t *fb_buf, int fb_shift, bool add) { int32_t *fb_buf, int fb_shift, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
const int32_t *adder = add ? output : zeros; const int32_t *adder = add ? output : zeros;
int32_t y0 = fb_buf[0]; int32_t y0 = fb_buf[0];
int32_t y = fb_buf[1]; int32_t y = fb_buf[1];
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
int32_t scaled_fb = (y0 + y) >> (fb_shift + 1); int32_t scaled_fb = (y0 + y) >> (fb_shift + 1);
y0 = y; y0 = y;

@ -4,17 +4,71 @@
#include "dexed.h" #include "dexed.h"
#define RATE 128 #define RATE 128
#define TEENSY 1
Dexed* dexed=new Dexed(RATE); #ifdef TEENSY
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioPlayQueue queue1; //xy=811,259
AudioOutputI2S i2s1; //xy=1185,252
AudioConnection patchCord2(queue1, 0, i2s1, 0);
AudioConnection patchCord3(queue1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=830,376
// GUItool: end automatically generated code
#endif
MIDI_CREATE_DEFAULT_INSTANCE();
Dexed* dexed = new Dexed(RATE);
void setup() void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Serial.println(F("MicroDexed")); Serial.println(F("MicroDexed"));
MIDI.begin(MIDI_CHANNEL_OMNI);
#ifdef TEENSY
// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(8);
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
// Initialize processor and memory measurements
//AudioProcessorUsageMaxReset();
//AudioMemoryUsageMaxReset();
#endif
} }
void loop() void loop()
{ {
int16_t* audio_buffer; // pointer for 128 * int16_t
#ifdef TEENSY
audio_buffer = queue1.getBuffer();
#endif
//memset(buf, 0, 128);
// process midi->audio
while(MIDI.read())
{
dexed->ProcessMidiMessage((byte)MIDI.getType(),(byte)MIDI.getData1(),(byte)MIDI.getData2());
}
dexed->GetSamples(audio_buffer);
#ifdef TEENSY
// play the current buffer
queue1.playBuffer();
#endif
} }

@ -114,7 +114,7 @@ void Dexed::activate(void)
void Dexed::deactivate(void) void Dexed::deactivate(void)
{ {
; ; // Nothing to do - please reboot ;-)
} }
/* /*
@ -337,8 +337,7 @@ void Dexed::set_params(void)
} }
*/ */
// override the run() method /*void Dexed::run (uint8_t* midi_data)
void Dexed::run (uint8_t* midi_data)
{ {
static int16_t buffer; static int16_t buffer;
@ -348,11 +347,11 @@ void Dexed::run (uint8_t* midi_data)
GetSamples(&buffer); GetSamples(&buffer);
//fx.process(&buffer,_rate); //fx.process(&buffer,_rate);
} }*/
void Dexed::GetSamples(int16_t* buffer) void Dexed::GetSamples(int16_t* buffer)
{ {
uint32_t i; uint32_t i=0;
if(refreshVoice) { if(refreshVoice) {
for(i=0;i < max_notes;i++) { for(i=0;i < max_notes;i++) {
@ -364,11 +363,11 @@ void Dexed::GetSamples(int16_t* buffer)
} }
// remaining buffer is still to be processed // remaining buffer is still to be processed
for (; i < _rate; i += N) { for (; i < _rate; i += _N_) {
AlignedBuf<int32_t, N> audiobuf; AlignedBuf<int32_t, _N_> audiobuf;
float sumbuf[N]; float sumbuf[_N_];
for (uint32_t j = 0; j < N; ++j) { for (uint32_t j = 0; j < _N_; ++j) {
audiobuf.get()[j] = 0; audiobuf.get()[j] = 0;
sumbuf[j] = 0.0; sumbuf[j] = 0.0;
} }
@ -379,7 +378,7 @@ void Dexed::GetSamples(int16_t* buffer)
for (uint8_t note = 0; note < max_notes; ++note) { for (uint8_t note = 0; note < max_notes; ++note) {
if (voices[note].live) { if (voices[note].live) {
voices[note].dx7_note->compute(audiobuf.get(), lfovalue, lfodelay, &controllers); voices[note].dx7_note->compute(audiobuf.get(), lfovalue, lfodelay, &controllers);
for (uint32_t j=0; j < N; ++j) { for (uint32_t j=0; j < _N_; ++j) {
int32_t val = audiobuf.get()[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; int32_t clip_val = val < -(1 << 24) ? 0x8000 : val >= (1 << 24) ? 0x7fff : val >> 9;
@ -392,7 +391,7 @@ void Dexed::GetSamples(int16_t* buffer)
} }
} }
for (uint32_t j = 0; j < N; ++j) for (uint32_t j = 0; j < _N_; ++j)
buffer[i + j] = sumbuf[j]; buffer[i + j] = sumbuf[j];
} }
@ -434,43 +433,39 @@ void Dexed::GetSamples(int16_t* buffer)
} }
} }
bool Dexed::ProcessMidiMessage(uint8_t *buf) { bool Dexed::ProcessMidiMessage(uint8_t cmd,uint8_t data1,uint8_t data2)
uint8_t cmd = buf[0]; {
switch(cmd & 0xf0) { switch(cmd & 0xf0) {
case 0x80 : case 0x80 :
// TRACE("MIDI keyup event: %d",buf[1]); // TRACE("MIDI keyup event: %d",buf[1]);
keyup(buf[1]); keyup(data1);
return(false); return(false);
break; break;
case 0x90 : case 0x90 :
// TRACE("MIDI keydown event: %d %d",buf[1],buf[2]); // TRACE("MIDI keydown event: %d %d",buf[1],buf[2]);
keydown(buf[1], buf[2]); keydown(data1, data2);
return(false); return(false);
break; break;
case 0xb0 : { case 0xb0 : {
uint8_t ctrl = buf[1]; switch(data1) {
uint8_t value = buf[2];
switch(ctrl) {
case 1: case 1:
// TRACE("MIDI modwheel event: %d %d",ctrl,value); // TRACE("MIDI modwheel event: %d %d",ctrl,value);
controllers.modwheel_cc = value; controllers.modwheel_cc = data2;
controllers.refresh(); controllers.refresh();
break; break;
case 2: case 2:
// TRACE("MIDI breath event: %d %d",ctrl,value); // TRACE("MIDI breath event: %d %d",ctrl,value);
controllers.breath_cc = value; controllers.breath_cc = data2;
controllers.refresh(); controllers.refresh();
break; break;
case 4: case 4:
// TRACE("MIDI footsw event: %d %d",ctrl,value); // TRACE("MIDI footsw event: %d %d",ctrl,value);
controllers.foot_cc = value; controllers.foot_cc = data2;
controllers.refresh(); controllers.refresh();
break; break;
case 64: case 64:
// TRACE("MIDI sustain event: %d %d",ctrl,value); // TRACE("MIDI sustain event: %d %d",ctrl,value);
sustain = value > 63; sustain = data2 > 63;
if (!sustain) { if (!sustain) {
for (uint8_t note = 0; note < max_notes; note++) { for (uint8_t note = 0; note < max_notes; note++) {
if (voices[note].sustained && !voices[note].keydown) { if (voices[note].sustained && !voices[note].keydown) {
@ -495,23 +490,20 @@ bool Dexed::ProcessMidiMessage(uint8_t *buf) {
} }
// case 0xc0 : // case 0xc0 :
// setCurrentProgram(buf[1]); // setCurrentProgram(data1);
// break; // break;
// channel aftertouch // channel aftertouch
case 0xd0 : case 0xd0 :
// TRACE("MIDI aftertouch 0xd0 event: %d %d",buf[1]); controllers.aftertouch_cc = data1;
controllers.aftertouch_cc = buf[1];
controllers.refresh(); controllers.refresh();
break; break;
// pitchbend // pitchbend
case 0xe0 : case 0xe0 :
// TRACE("MIDI pitchbend 0xe0 event: %d %d",buf[1],buf[2]); controllers.values_[kControllerPitch] = data1 | (data2 << 7);
controllers.values_[kControllerPitch] = buf[1] | (buf[2] << 7);
break; break;
default: default:
// TRACE("MIDI event unknown: cmd=%d, val1=%d, val2=%d",buf[0],buf[1],buf[2]);
break; break;
} }

@ -83,12 +83,12 @@ class Dexed
void setMonoMode(bool mode); void setMonoMode(bool mode);
void set_params(void); void set_params(void);
void GetSamples(int16_t* buffer); void GetSamples(int16_t* buffer);
bool ProcessMidiMessage(uint8_t cmd,uint8_t data1,uint8_t data2);
Controllers controllers; Controllers controllers;
VoiceStatus voiceStatus; VoiceStatus voiceStatus;
protected: protected:
bool ProcessMidiMessage(uint8_t* buf);
//void onParam(uint8_t param_num,float param_val); //void onParam(uint8_t param_num,float param_val);
void keyup(uint8_t pitch); void keyup(uint8_t pitch);
void keydown(uint8_t pitch, uint8_t velo); void keydown(uint8_t pitch, uint8_t velo);
@ -110,7 +110,7 @@ class Dexed
EngineOpl* engineOpl; EngineOpl* engineOpl;
float* outbuf_; float* outbuf_;
uint32_t bufsize_; uint32_t bufsize_;
float extra_buf_[N]; float extra_buf_[_N_];
uint32_t extra_buf_size_; uint32_t extra_buf_size_;
private: private:

@ -51,7 +51,7 @@ public:
uint8_t get_carrier_operators(uint8_t algorithm); uint8_t get_carrier_operators(uint8_t algorithm);
virtual void render(int32_t *output, FmOpParams *params, int algorithm, int32_t *fb_buf, int32_t feedback_gain); virtual void render(int32_t *output, FmOpParams *params, int algorithm, int32_t *fb_buf, int32_t feedback_gain);
protected: protected:
AlignedBuf<int32_t, N>buf_[2]; AlignedBuf<int32_t, _N_>buf_[2];
const static FmAlgorithm algorithms[32]; const static FmAlgorithm algorithms[32];
}; };

@ -47,7 +47,7 @@ static bool hasNeon() {
void FmOpKernel::compute(int32_t *output, const int32_t *input, void FmOpKernel::compute(int32_t *output, const int32_t *input,
int32_t phase0, int32_t freq, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, bool add) { int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
if (hasNeon()) { if (hasNeon()) {
@ -57,7 +57,7 @@ void FmOpKernel::compute(int32_t *output, const int32_t *input,
#endif #endif
} else { } else {
if (add) { if (add) {
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
int32_t y = Sin::lookup(phase + input[i]); int32_t y = Sin::lookup(phase + input[i]);
int32_t y1 = ((int64_t)y * (int64_t)gain) >> 24; int32_t y1 = ((int64_t)y * (int64_t)gain) >> 24;
@ -65,7 +65,7 @@ void FmOpKernel::compute(int32_t *output, const int32_t *input,
phase += freq; phase += freq;
} }
} else { } else {
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
int32_t y = Sin::lookup(phase + input[i]); int32_t y = Sin::lookup(phase + input[i]);
int32_t y1 = ((int64_t)y * (int64_t)gain) >> 24; int32_t y1 = ((int64_t)y * (int64_t)gain) >> 24;
@ -78,17 +78,17 @@ void FmOpKernel::compute(int32_t *output, const int32_t *input,
void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq, void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, bool add) { int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
if (hasNeon()) { if (hasNeon()) {
#ifdef HAVE_NEON #ifdef HAVE_NEON
neon_fm_kernel(zeros, add ? output : zeros, output, N, neon_fm_kernel(zeros, add ? output : zeros, output, _N_,
phase0, freq, gain, dgain); phase0, freq, gain, dgain);
#endif #endif
} else { } else {
if (add) { if (add) {
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
int32_t y = Sin::lookup(phase); int32_t y = Sin::lookup(phase);
int32_t y1 = ((int64_t)y * (int64_t)gain) >> 24; int32_t y1 = ((int64_t)y * (int64_t)gain) >> 24;
@ -96,7 +96,7 @@ void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
phase += freq; phase += freq;
} }
} else { } else {
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
int32_t y = Sin::lookup(phase); int32_t y = Sin::lookup(phase);
int32_t y1 = ((int64_t)y * (int64_t)gain) >> 24; int32_t y1 = ((int64_t)y * (int64_t)gain) >> 24;
@ -113,13 +113,13 @@ void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
void FmOpKernel::compute_fb(int32_t *output, int32_t phase0, int32_t freq, void FmOpKernel::compute_fb(int32_t *output, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, int32_t gain1, int32_t gain2,
int32_t *fb_buf, int fb_shift, bool add) { int32_t *fb_buf, int fb_shift, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
int32_t y0 = fb_buf[0]; int32_t y0 = fb_buf[0];
int32_t y = fb_buf[1]; int32_t y = fb_buf[1];
if (add) { if (add) {
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
int32_t scaled_fb = (y0 + y) >> (fb_shift + 1); int32_t scaled_fb = (y0 + y) >> (fb_shift + 1);
y0 = y; y0 = y;
@ -129,7 +129,7 @@ void FmOpKernel::compute_fb(int32_t *output, int32_t phase0, int32_t freq,
phase += freq; phase += freq;
} }
} else { } else {
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
int32_t scaled_fb = (y0 + y) >> (fb_shift + 1); int32_t scaled_fb = (y0 + y) >> (fb_shift + 1);
y0 = y; y0 = y;
@ -154,7 +154,7 @@ void FmOpKernel::compute_fb(int32_t *output, int32_t phase0, int32_t freq,
// high accuracy: 5.0 mean, 49 worst case // high accuracy: 5.0 mean, 49 worst case
void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq, void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, bool add) { int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
#ifdef HIGH_ACCURACY #ifdef HIGH_ACCURACY
@ -188,7 +188,7 @@ void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
// freq < 0.25: 17.9 mean, 78 worst // freq < 0.25: 17.9 mean, 78 worst
void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq, void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, bool add) { int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
#ifdef HIGH_ACCURACY #ifdef HIGH_ACCURACY
@ -202,7 +202,7 @@ void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
v = ((int64_t)v * gain) >> 24; v = ((int64_t)v * gain) >> 24;
int32_t a = Sin::compute(freq >> 1) << 1; int32_t a = Sin::compute(freq >> 1) << 1;
#endif #endif
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
output[i] = u; output[i] = u;
v -= ((int64_t)a * (int64_t)u) >> 24; v -= ((int64_t)a * (int64_t)u) >> 24;
u += ((int64_t)a * (int64_t)v) >> 24; u += ((int64_t)a * (int64_t)v) >> 24;
@ -216,7 +216,7 @@ void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
// with high accuracy: mean 4.2, worst 292 (near freq = 0.5) // with high accuracy: mean 4.2, worst 292 (near freq = 0.5)
void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq, void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, bool add) { int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
#ifdef DOUBLE_ACCURACY #ifdef DOUBLE_ACCURACY
@ -242,7 +242,7 @@ void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
#endif #endif
if (aa < 0) aa = (1 << 31) - 1; if (aa < 0) aa = (1 << 31) - 1;
for (int i = 0; i < N; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
output[i] = ((int64_t)u * (int64_t)gain) >> 30; output[i] = ((int64_t)u * (int64_t)gain) >> 30;
v -= ((int64_t)aa * (int64_t)u) >> 29; v -= ((int64_t)aa * (int64_t)u) >> 29;
@ -256,7 +256,7 @@ void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
// high accuracy 2.9 mean, 143 worst // high accuracy 2.9 mean, 143 worst
void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq, void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, bool add) { int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (N >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0; int32_t phase = phase0;
#ifdef HIGH_ACCURACY #ifdef HIGH_ACCURACY

@ -25,7 +25,7 @@ uint32_t Lfo::unit_;
void Lfo::init(double sample_rate) { void Lfo::init(double sample_rate) {
// constant is 1 << 32 / 15.5s / 11 // constant is 1 << 32 / 15.5s / 11
Lfo::unit_ = (int32_t)(N * 25190424 / sample_rate + 0.5); Lfo::unit_ = (int32_t)(_N_ * 25190424 / sample_rate + 0.5);
} }
void Lfo::reset(const uint8_t params[6]) { void Lfo::reset(const uint8_t params[6]) {

@ -20,7 +20,7 @@
int PitchEnv::unit_; int PitchEnv::unit_;
void PitchEnv::init(double sample_rate) { void PitchEnv::init(double sample_rate) {
unit_ = N * (1 << 24) / (21.3 * sample_rate) + 0.5; unit_ = _N_ * (1 << 24) / (21.3 * sample_rate) + 0.5;
} }
const uint8_t pitchenv_rate[] = { const uint8_t pitchenv_rate[] = {

@ -27,7 +27,7 @@ typedef __int16 SInt16;
#endif #endif
#define LG_N 6 #define LG_N 6
#define N (1 << LG_N) #define _N_ (1 << LG_N)
#if defined(__APPLE__) #if defined(__APPLE__)
#include <libkern/OSAtomic.h> #include <libkern/OSAtomic.h>

Loading…
Cancel
Save