Added a slightly better version of synth_dexed which supports also F32 (if you set

USE_OPEN_AUDIO_LIB).
pull/41/head
Holger Wirtz 3 years ago
parent 4b2fbe09d5
commit a3ac774a23
  1. 4
      MicroDexed.ino
  2. 2
      UI.hpp
  3. 2
      dexed_sd.h
  4. 118
      synth_dexed.cpp
  5. 137
      synth_dexed.h

@ -43,7 +43,7 @@
#include "UI.hpp"
// Audio engines
AudioSourceMicroDexed* MicroDexed[NUM_DEXED];
AudioSynthDexed* MicroDexed[NUM_DEXED];
#if defined(USE_FX)
AudioSynthWaveform* chorus_modulator[NUM_DEXED];
#if MOD_FILTER_OUTPUT != MOD_NO_FILTER_OUTPUT
@ -173,7 +173,7 @@ AudioConnection * dynamicConnections[NUM_DEXED * 4];
#endif
void create_audio_engine_chain(uint8_t instance_id)
{
MicroDexed[instance_id] = new AudioSourceMicroDexed(SAMPLE_RATE);
MicroDexed[instance_id] = new AudioSynthDexed(SAMPLE_RATE);
mono2stereo[instance_id] = new AudioEffectMonoStereo();
#if defined(USE_FX)
chorus_modulator[instance_id] = new AudioSynthWaveform();

@ -70,7 +70,7 @@ extern void change_disp_sd(bool d);
#endif
extern AudioControlSGTL5000 sgtl5000_1;
extern AudioSourceMicroDexed* MicroDexed[NUM_DEXED];
extern AudioSynthDexed* MicroDexed[NUM_DEXED];
#if defined(USE_FX)
extern AudioSynthWaveform* chorus_modulator[NUM_DEXED];
extern AudioEffectModulatedDelay* modchorus[NUM_DEXED];

@ -30,7 +30,7 @@
extern uint8_t sd_card;
extern Dexed* dexed;
extern AudioSourceMicroDexed * MicroDexed[NUM_DEXED];
extern AudioSynthDexed * MicroDexed[NUM_DEXED];
extern void show_patch(uint8_t instance_id);
extern void send_sysex_voice(uint8_t midi_channel, uint8_t* data);

@ -1,4 +1,5 @@
#include "synth_dexed.h"
/**
Copyright (c) 2013-2014 Pascal Gauthier.
@ -388,13 +389,76 @@ void Dexed::getSamples(uint16_t n_samples, int16_t* buffer)
else if (vuSignal > 0.001f)
vuSignal *= decayFactor;
else
vuSignal = 0;
vuSignal = 0.0;
}
//arm_scale_f32(sumbuf, 0.00015, sumbuf, AUDIO_BLOCK_SAMPLES);
arm_float_to_q15(sumbuf, buffer, AUDIO_BLOCK_SAMPLES);
}
void Dexed::getSamples(uint16_t n_samples, float32_t* buffer)
{
uint16_t i, j;
uint8_t note;
float s;
const double decayFactor = 0.99992;
if (refreshVoice)
{
for (i = 0; i < max_notes; i++)
{
if ( voices[i].live )
voices[i].dx7_note->update(data, voices[i].midi_note, voices[i].velocity, voices[i].porta, &controllers);
}
lfo.reset(data + 137);
refreshVoice = false;
}
for (i = 0; i < n_samples; i += _N_)
{
AlignedBuf<int32_t, _N_> audiobuf;
for (uint8_t j = 0; j < _N_; ++j)
{
audiobuf.get()[j] = 0;
buffer[i + j] = 0.0;
}
int32_t lfovalue = lfo.getsample();
int32_t lfodelay = lfo.getdelay();
for (note = 0; note < max_notes; note++)
{
if (voices[note].live)
{
voices[note].dx7_note->compute(audiobuf.get(), lfovalue, lfodelay, &controllers);
for (j = 0; j < _N_; ++j)
{
buffer[i + j] += static_cast<float>(audiobuf.get()[j]) / 32768;
audiobuf.get()[j] = 0;
}
}
}
}
fx.process(buffer, n_samples); // Needed for fx.Gain()!!!
// mild compression
for (i = 0; i < n_samples; i++)
{
s = abs(buffer[i]);
if (s > vuSignal)
vuSignal = s;
else if (vuSignal > 0.001f)
vuSignal *= decayFactor;
else
vuSignal = 0;
}
arm_scale_f32(buffer, 0.00015, buffer, AUDIO_BLOCK_SAMPLES);
}
void Dexed::keydown(int16_t pitch, uint8_t velo) {
if ( velo == 0 ) {
keyup(pitch);
@ -1591,19 +1655,19 @@ void Env::transfer(Env &src) {
inc_ = src.inc_;
}
/*
* Copyright 2013 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 2013 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.
*/
#ifdef _MSC_VER
@ -2323,19 +2387,19 @@ void Porta::init_sr(double sampleRate)
int32_t Porta::rates[128];
/*
* 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 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.
*/
#define R (1 << 29)

@ -1,8 +1,12 @@
#include <Arduino.h>
#include <Audio.h>
#include "config.h"
#if defined(USE_OPEN_AUDIO_LIB)
#include "OpenAudio_ArduinoLibrary.h"
#endif
/*****************************************************
* CODE; orig_code/synth.h
CODE; orig_code/synth.h
*****************************************************/
/*
Copyright 2012 Google Inc.
@ -76,7 +80,7 @@ inline static T max(const T& a, const T& b) {
//=====================================================
/*****************************************************
* CODE; orig_code/aligned_buf.h
CODE; orig_code/aligned_buf.h
*****************************************************/
/*
Copyright 2013 Google Inc.
@ -111,7 +115,7 @@ class AlignedBuf {
//=====================================================
/*****************************************************
* CODE; orig_code/sin.h
CODE; orig_code/sin.h
*****************************************************/
/*
Copyright 2012 Google Inc.
@ -178,7 +182,7 @@ int32_t Sin::lookup(int32_t phase) {
//=====================================================
/*****************************************************
* CODE; orig_code/exp2.h
CODE; orig_code/exp2.h
*****************************************************/
/*
Copyright 2012 Google Inc.
@ -263,16 +267,16 @@ int32_t Tanh::lookup(int32_t x) {
//=====================================================
/*****************************************************
* CODE; orig_code/fast_log.h
CODE; orig_code/fast_log.h
*****************************************************/
/* ----------------------------------------------------------------------
* https://community.arm.com/tools/f/discussions/4292/cmsis-dsp-new-functionality-proposal/22621#22621
* Fast approximation to the log2() function. It uses a two step
* process. First, it decomposes the floating-point number into
* a fractional component F and an exponent E. The fraction component
* is used in a polynomial approximation and then the exponent added
* to the result. A 3rd order polynomial is used and the result
* when computing db20() is accurate to 7.984884e-003 dB.
https://community.arm.com/tools/f/discussions/4292/cmsis-dsp-new-functionality-proposal/22621#22621
Fast approximation to the log2() function. It uses a two step
process. First, it decomposes the floating-point number into
a fractional component F and an exponent E. The fraction component
is used in a polynomial approximation and then the exponent added
to the result. A 3rd order polynomial is used and the result
when computing db20() is accurate to 7.984884e-003 dB.
** ------------------------------------------------------------------- */
static float log2f_approx_coeff[4] = {1.23149591368684f, -4.11852516267426f, 6.02197014179219f, -3.13396450166353f};
@ -318,7 +322,7 @@ inline float dbToUnit(float db) {
//=====================================================
/*****************************************************
* CODE; orig_code/freqlut.h
CODE; orig_code/freqlut.h
*****************************************************/
/*
Copyright 2012 Google Inc.
@ -344,7 +348,7 @@ class Freqlut {
//=====================================================
/*****************************************************
* CODE; orig_code/lfo.h
CODE; orig_code/lfo.h
*****************************************************/
/*
Copyright 2013 Google Inc.
@ -392,7 +396,7 @@ class Lfo {
//=====================================================
/*****************************************************
* CODE; orig_code/env.h
CODE; orig_code/env.h
*****************************************************/
/*
Copyright 2017 Pascal Gauthier.
@ -472,7 +476,7 @@ class Env {
//=====================================================
/*****************************************************
* CODE; orig_code/pitchenv.h
CODE; orig_code/pitchenv.h
*****************************************************/
/*
Copyright 2013 Google Inc.
@ -525,7 +529,7 @@ extern const int8_t pitchenv_tab[];
//=====================================================
/*****************************************************
* CODE; orig_code/controllers.h
CODE; orig_code/controllers.h
*****************************************************/
/*
Copyright 2013 Google Inc.
@ -571,12 +575,12 @@ class FmMod {
void setRange(uint8_t r)
{
range = r < 0 || r > 99 ? 0 : r;
range = r < 0 && r > 99 ? 0 : r;
}
void setTarget(uint8_t assign)
{
assign = assign < 0 || assign > 7 ? 0 : assign;
assign = assign < 0 && assign > 7 ? 0 : assign;
pitch = assign & 1; // PITCH
amp = assign & 2; // AMP
eg = assign & 4; // EG
@ -664,7 +668,7 @@ class Controllers {
//=====================================================
/*****************************************************
* CODE; orig_code/PluginFx.h
CODE; orig_code/PluginFx.h
*****************************************************/
/**
@ -738,7 +742,7 @@ class PluginFx {
//=====================================================
/*****************************************************
* CODE; orig_code/fm_op_kernel.h
CODE; orig_code/fm_op_kernel.h
*****************************************************/
/*
Copyright 2012 Google Inc.
@ -786,7 +790,7 @@ class FmOpKernel {
//=====================================================
/*****************************************************
* CODE; orig_code/fm_core.h
CODE; orig_code/fm_core.h
*****************************************************/
/*
Copyright 2012 Google Inc.
@ -839,7 +843,7 @@ class FmCore {
//=====================================================
/*****************************************************
* CODE; orig_code/dx7note.h
CODE; orig_code/dx7note.h
*****************************************************/
/*
Copyright 2016-2017 Pascal Gauthier.
@ -918,7 +922,7 @@ class Dx7Note {
//=====================================================
/*****************************************************
* CODE; orig_code/dexed.h
CODE; orig_code/dexed.h
*****************************************************/
/*
MicroDexed
@ -1043,7 +1047,7 @@ class Dexed
bool isMonoMode(void);
void setMonoMode(bool mode);
void setRefreshMode(bool mode);
void getSamples(uint16_t n_samples, int16_t* buffer);
//void getSamples(uint16_t n_samples, int16_t* buffer);
void panic(void);
void notesOff(void);
void resetControllers(void);
@ -1102,12 +1106,14 @@ class Dexed
VoiceStatus voiceStatus;
Lfo lfo;
FmCore* engineMsfa;
void getSamples(uint16_t n_samples, float32_t* buffer);
void getSamples(uint16_t n_samples, int16_t* buffer);
};
//=====================================================
/*****************************************************
* CODE; orig_code/porta.h
CODE; orig_code/porta.h
*****************************************************/
/*
Copyright 2019 Jean Pierre Cimalando.
@ -1134,16 +1140,16 @@ struct Porta {
//=====================================================
/*****************************************************
* CODE; orig_code/source_microdexed.h
CODE; orig_code/source_microdexed.h
*****************************************************/
class AudioSourceMicroDexed : public AudioStream, public Dexed {
class AudioSynthDexed : public AudioStream, public Dexed {
public:
const uint16_t audio_block_time_us = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLES);
uint32_t xrun = 0;
uint16_t render_time_max = 0;
AudioSourceMicroDexed(int sample_rate) : AudioStream(0, NULL), Dexed(sample_rate) { };
AudioSynthDexed(int sample_rate) : AudioStream(0, NULL), Dexed(sample_rate) { };
void update(void)
{
@ -1184,64 +1190,113 @@ class AudioSourceMicroDexed : public AudioStream, public Dexed {
volatile bool in_update = false;
};
#if defined(USE_OPEN_AUDIO_LIB)
class AudioSynthDexed_F32 : public AudioStream_F32, public Dexed {
public:
const uint16_t audio_block_time_us = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLES);
uint32_t xrun = 0;
uint16_t render_time_max = 0;
AudioSynthDexed_F32(int sample_rate) : AudioStream_F32(0, NULL), Dexed(sample_rate) { };
void update(void)
{
if (in_update == true)
{
xrun++;
return;
}
else
in_update = true;
elapsedMicros render_time;
audio_block_f32_t *lblock;
lblock = allocate_f32();
if (!lblock)
{
in_update = false;
return;
}
getSamples(AUDIO_BLOCK_SAMPLES, lblock->data);
if (render_time > audio_block_time_us) // everything greater audio_block_time_us (2.9ms for buffer size of 128) is a buffer underrun!
xrun++;
if (render_time > render_time_max)
render_time_max = render_time;
AudioStream_F32::transmit(lblock, 0);
AudioStream_F32::release(lblock);
in_update = false;
};
private:
volatile bool in_update = false;
};
#endif
//=====================================================
/*****************************************************
* CODE; orig_code/PluginFx.cpp
CODE; orig_code/PluginFx.cpp
*****************************************************/
//=====================================================
/*****************************************************
* CODE; orig_code/dexed.cpp
CODE; orig_code/dexed.cpp
*****************************************************/
//=====================================================
/*****************************************************
* CODE; orig_code/dx7note.cpp
CODE; orig_code/dx7note.cpp
*****************************************************/
//=====================================================
/*****************************************************
* CODE; orig_code/env.cpp
CODE; orig_code/env.cpp
*****************************************************/
//=====================================================
/*****************************************************
* CODE; orig_code/exp2.cpp
CODE; orig_code/exp2.cpp
*****************************************************/
//=====================================================
/*****************************************************
* CODE; orig_code/fm_core.cpp
CODE; orig_code/fm_core.cpp
*****************************************************/
//=====================================================
/*****************************************************
* CODE; orig_code/fm_op_kernel.cpp
CODE; orig_code/fm_op_kernel.cpp
*****************************************************/
//=====================================================
/*****************************************************
* CODE; orig_code/freqlut.cpp
CODE; orig_code/freqlut.cpp
*****************************************************/
//=====================================================
/*****************************************************
* CODE; orig_code/lfo.cpp
CODE; orig_code/lfo.cpp
*****************************************************/
//=====================================================
/*****************************************************
* CODE; orig_code/pitchenv.cpp
CODE; orig_code/pitchenv.cpp
*****************************************************/
//=====================================================
/*****************************************************
* CODE; orig_code/porta.cpp
CODE; orig_code/porta.cpp
*****************************************************/
//=====================================================
/*****************************************************
* CODE; orig_code/sin.cpp
CODE; orig_code/sin.cpp
*****************************************************/
//=====================================================

Loading…
Cancel
Save