Volume fixes.

Started modulated chorus effect.
dev
Holger Wirtz 6 years ago
parent 5947d6f4ea
commit 24b930e08d
  1. 63
      MicroMDAEPiano.ino
  2. 3
      UI.hpp
  3. 1
      config.h
  4. 134
      effect_modulated_chorus.cpp
  5. 60
      effect_modulated_chorus.h
  6. 14
      mdaEPiano.cpp
  7. 3
      mdaEPiano.h

@ -30,6 +30,7 @@
#include "EEPROMAnything.h" #include "EEPROMAnything.h"
#include <limits.h> #include <limits.h>
#include "mdaEPiano.h" #include "mdaEPiano.h"
#include "effect_modulated_chorus.h"
#ifdef USE_XFADE_DATA #ifdef USE_XFADE_DATA
#include "mdaEPianoDataXfade.h" #include "mdaEPianoDataXfade.h"
#else #else
@ -53,30 +54,39 @@ AudioMixer4 mixer_r;
AudioMixer4 mixer_l; AudioMixer4 mixer_l;
AudioAmplifier volume_r; AudioAmplifier volume_r;
AudioAmplifier volume_l; AudioAmplifier volume_l;
AudioModulatedEffectChorus modchorus_r;
AudioModulatedEffectChorus modchorus_l;
AudioSynthWaveformSine mod_sine1;
AudioConnection patchCord0(queue_r, peak_r); AudioConnection patchCord0(queue_r, peak_r);
AudioConnection patchCord1(queue_l, peak_l); AudioConnection patchCord1(queue_l, peak_l);
AudioConnection patchCord4(queue_r, freeverb_r); AudioConnection patchCord2(queue_r, freeverb_r);
AudioConnection patchCord5(queue_l, freeverb_l); AudioConnection patchCord3(queue_l, freeverb_l);
AudioConnection patchCord6(queue_r, 0, mixer_r, 0); AudioConnection patchCord4(queue_r, 0, modchorus_r, 0);
AudioConnection patchCord7(queue_l, 0, mixer_l, 0); AudioConnection patchCord5(queue_l, 0, modchorus_l, 0);
AudioConnection patchCord8(freeverb_r, 0, mixer_r, 1); AudioConnection patchCord6(mod_sine1, 0, modchorus_r, 1);
AudioConnection patchCord9(freeverb_l, 0, mixer_l, 1); AudioConnection patchCord7(mod_sine1, 0, modchorus_l, 1);
AudioConnection patchCord10(mixer_r, volume_r); AudioConnection patchCord8(queue_r, 0, mixer_r, 0);
AudioConnection patchCord11(mixer_l, volume_l); AudioConnection patchCord9(queue_l, 0, mixer_l, 0);
AudioConnection patchCord10(modchorus_r, 0, mixer_r, 2);
AudioConnection patchCord11(modchorus_l, 0, mixer_l, 2);
AudioConnection patchCord12(freeverb_r, 0, mixer_r, 1);
AudioConnection patchCord13(freeverb_l, 0, mixer_l, 1);
AudioConnection patchCord14(mixer_r, volume_r);
AudioConnection patchCord15(mixer_l, volume_l);
#if defined(TEENSY_AUDIO_BOARD) #if defined(TEENSY_AUDIO_BOARD)
AudioOutputI2S i2s1; AudioOutputI2S i2s1;
AudioConnection patchCord12(volume_r, 0, i2s1, 0); AudioConnection patchCord16(volume_r, 0, i2s1, 0);
AudioConnection patchCord13(volume_l, 0, i2s1, 1); AudioConnection patchCord17(volume_l, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; AudioControlSGTL5000 sgtl5000_1;
#elif defined(TGA_AUDIO_BOARD) #elif defined(TGA_AUDIO_BOARD)
AudioOutputI2S i2s1; AudioOutputI2S i2s1;
AudioConnection patchCord12(volume_r, 0, i2s1, 1); AudioConnection patchCord16(volume_r, 0, i2s1, 1);
AudioConnection patchCord13(volume_l, 0, i2s1, 0); AudioConnection patchCord17(volume_l, 0, i2s1, 0);
AudioControlWM8731master wm8731_1; AudioControlWM8731master wm8731_1;
#else #else
AudioOutputPT8211 pt8211_1; AudioOutputPT8211 pt8211_1;
AudioConnection patchCord12(volume_r, 0, pt8211_1, 1); AudioConnection patchCord16(volume_r, 0, pt8211_1, 1);
AudioConnection patchCord13(volume_l, 0, pt8211_1, 0); AudioConnection patchCord17(volume_l, 0, pt8211_1, 0);
#endif #endif
// Objects // Objects
@ -132,7 +142,6 @@ config_t configuration = {
0 // pan 0 // pan
}; };
float _loudness = mapfloat(float(ENC_LOUDNESS_DEFAULT), ENC_LOUDNESS_MIN, ENC_LOUDNESS_MAX, 0.0, 1.0);
uint8_t master_volume = ENC_MASTER_VOLUME_DEFAULT; uint8_t master_volume = ENC_MASTER_VOLUME_DEFAULT;
int8_t pan = ENC_MASTER_PAN_DEFAULT; int8_t pan = ENC_MASTER_PAN_DEFAULT;
uint8_t eeprom_config_update_flag = 0; uint8_t eeprom_config_update_flag = 0;
@ -143,6 +152,12 @@ elapsedMillis eeprom_master_volume_update_timer;
elapsedMillis cpu_mem_millis; elapsedMillis cpu_mem_millis;
#endif #endif
// Number of samples in each delay line
#define CHORUS_DELAY_LENGTH (16*AUDIO_BLOCK_SAMPLES)
// Allocate the delay lines for left and right channels
short l_delayline[CHORUS_DELAY_LENGTH];
short r_delayline[CHORUS_DELAY_LENGTH];
//************************************************************************************************* //*************************************************************************************************
//* SETUP FUNCTION //* SETUP FUNCTION
//************************************************************************************************* //*************************************************************************************************
@ -213,6 +228,19 @@ void setup()
Serial.print(audio_block_time_us); Serial.print(audio_block_time_us);
Serial.println(F("ms)")); Serial.println(F("ms)"));
if (!modchorus_r.begin(r_delayline, CHORUS_DELAY_LENGTH, NUM_CHORUS)) {
Serial.println(F("AudioModulatedEffectChorus - right channel begin failed"));
while (1);
}
if (!modchorus_l.begin(l_delayline, CHORUS_DELAY_LENGTH, NUM_CHORUS)) {
Serial.println(F("AudioModulatedEffectChorus - left channel begin failed"));
while (1);
}
mod_sine1.amplitude(1.0);
mod_sine1.frequency(5.0);
mod_sine1.phase(0);
AudioInterrupts(); AudioInterrupts();
Serial.println(F("<setup end>")); Serial.println(F("<setup end>"));
@ -451,7 +479,7 @@ bool checkMidiChannel(byte inChannel)
void set_master_volume(uint8_t value) void set_master_volume(uint8_t value)
{ {
configuration.pan = 0; // BAD HACK! //configuration.pan = 0; // BAD HACK!
uint16_t tmp = map(value, ENC_MASTER_VOLUME_MIN, ENC_MASTER_VOLUME_MAX, 0, 0x3ff); uint16_t tmp = map(value, ENC_MASTER_VOLUME_MIN, ENC_MASTER_VOLUME_MAX, 0, 0x3ff);
float tmp2 = mapfloat(configuration.pan, ENC_MASTER_PAN_MIN, ENC_MASTER_PAN_MAX, 0.0, 1.0); float tmp2 = mapfloat(configuration.pan, ENC_MASTER_PAN_MIN, ENC_MASTER_PAN_MAX, 0.0, 1.0);
float tmp3 = (float)(tmp * (tmp + 2)) / (float)(1 << 20); float tmp3 = (float)(tmp * (tmp + 2)) / (float)(1 << 20);
@ -477,6 +505,9 @@ void set_master_volume(uint8_t value)
eeprom_master_volume_update_flag = true; eeprom_master_volume_update_flag = true;
eeprom_master_volume_update_timer = 0; eeprom_master_volume_update_timer = 0;
if (menu_system.get_currentScreen() == &master_volume_screen)
menu_system.update();
} }
/****************************************************************************** /******************************************************************************

@ -125,7 +125,6 @@ extern AudioMixer4 mixer_l;
extern AudioAmplifier volume_r; extern AudioAmplifier volume_r;
extern AudioAmplifier volume_l; extern AudioAmplifier volume_l;
extern mdaEPiano* ep; extern mdaEPiano* ep;
extern float _loudness;
extern config_t configuration; extern config_t configuration;
extern uint8_t sound; extern uint8_t sound;
extern uint8_t master_volume; extern uint8_t master_volume;
@ -2074,7 +2073,7 @@ void set_loudness(uint8_t value)
Serial.print(F("Set LOUDNESS ")); Serial.print(F("Set LOUDNESS "));
Serial.println(value); Serial.println(value);
#endif #endif
_loudness = mapfloat(float(value), ENC_LOUDNESS_MIN, ENC_LOUDNESS_MAX, 0.0, 1.0); ep->setLoudness(mapfloat(float(value), ENC_LOUDNESS_MIN, ENC_LOUDNESS_MAX, 0.0, 1.0));
//volume_r.gain(tmp); //volume_r.gain(tmp);
//volume_l.gain(tmp); //volume_l.gain(tmp);
configuration.loudness = value; configuration.loudness = value;

@ -61,6 +61,7 @@
#define SAMPLE_RATE 44100 #define SAMPLE_RATE 44100
#define REDUCE_LOUDNESS 0 #define REDUCE_LOUDNESS 0
#define USE_XFADE_DATA 1 #define USE_XFADE_DATA 1
#define NUM_CHORUS 2
//************************************************************************************************* //*************************************************************************************************
//* DEBUG OUTPUT SETTINGS //* DEBUG OUTPUT SETTINGS

@ -0,0 +1,134 @@
/* Audio Library for Teensy 3.X
Copyright (c) 2014, Pete (El Supremo)
Copyright (c) 2019, Holger Wirtz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <Arduino.h>
#include "effect_modulated_chorus.h"
/******************************************************************/
// Based on; A u d i o E f f e c t C h o r u s
// Written by Pete (El Supremo) Jan 2014
// 140529 - change to handle mono stream - change modify() to voices()
// 140219 - correct storage class (not static)
// 190527 - adding modulation input (by Holger Wirtz)
boolean AudioModulatedEffectChorus::begin(short *delayline, int d_length, int n_chorus)
{
#if 0
Serial.print("AudioModulatedEffectChorus.begin(Chorus delay line length = ");
Serial.print(d_length);
Serial.print(", n_chorus = ");
Serial.print(n_chorus);
Serial.println(")");
#endif
l_delayline = NULL;
delay_length = 0;
l_circ_idx = 0;
if (delayline == NULL) {
return (false);
}
if (d_length < 10) {
return (false);
}
if (n_chorus < 1) {
return (false);
}
l_delayline = delayline;
delay_length = d_length / 2;
num_chorus = n_chorus;
return (true);
}
void AudioModulatedEffectChorus::voices(int n_chorus)
{
num_chorus = n_chorus;
}
//int last_idx = 0;
void AudioModulatedEffectChorus::update(void)
{
audio_block_t *block;
audio_block_t *modulation;
short *bp;
int sum;
int c_idx;
if (l_delayline == NULL)return;
// do passthru
// It stores the unmodified data in the delay line so that
// it isn't as likely to click
if (num_chorus <= 1) {
// Just passthrough
block = receiveWritable(0);
if (block) {
bp = block->data;
for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
l_circ_idx++;
if (l_circ_idx >= delay_length) {
l_circ_idx = 0;
}
l_delayline[l_circ_idx] = *bp++;
}
transmit(block, 0);
release(block);
}
return;
}
// L E F T C H A N N E L
block = receiveWritable(0);
modulation = receiveReadOnly(1);
if (block) {
bp = block->data;
uint32_t tmp = delay_length / (num_chorus - 1) - 1;
for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
l_circ_idx++;
if (l_circ_idx >= delay_length) {
l_circ_idx = 0;
}
l_delayline[l_circ_idx] = *bp;
sum = 0;
c_idx = l_circ_idx;
for (int k = 0; k < num_chorus; k++) {
sum += l_delayline[c_idx];
if (num_chorus > 1)c_idx -= tmp;
if (c_idx < 0) {
c_idx += delay_length;
}
}
*bp++ = sum / num_chorus;
}
// transmit the block
transmit(block, 0);
release(block);
release(modulation);
}
}

@ -0,0 +1,60 @@
/* Audio Library for Teensy 3.X
Copyright (c) 2014, Pete (El Supremo)
Copyright (c) 2019, Holger Wirtz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef effect_modulated_chorus_h_
#define effect_modulated_chorus_h_
#include "Arduino.h"
#include "AudioStream.h"
/******************************************************************/
// A u d i o E f f e c t C h o r u s
// Written by Pete (El Supremo) Jan 2014
// 140219 - correct storage class (not static)
// 190527 - adding modulation input (by Holger Wirtz)
#define CHORUS_DELAY_PASSTHRU -1
class AudioModulatedEffectChorus :
public AudioStream
{
public:
AudioModulatedEffectChorus(void):
AudioStream(2, inputQueueArray), num_chorus(2)
{ }
boolean begin(short *delayline, int delay_length, int n_chorus);
virtual void update(void);
void voices(int n_chorus);
private:
audio_block_t *inputQueueArray[2];
short *l_delayline;
short l_circ_idx;
int num_chorus;
int delay_length;
};
#endif

@ -29,7 +29,7 @@
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
extern float _loudness; extern void set_master_volume(uint8_t value);
extern uint8_t master_volume; extern uint8_t master_volume;
extern config_t configuration; extern config_t configuration;
@ -61,6 +61,7 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster)
setTune(0.500f); setTune(0.500f);
setDetune(0.146f); setDetune(0.146f);
setOverdrive(0.000f); setOverdrive(0.000f);
setLoudness(0.64616f);
waves = (short*)epianoDataXfade; waves = (short*)epianoDataXfade;
@ -249,6 +250,11 @@ void mdaEPiano::setOverdrive(float value)
setParameter(MDA_EP_OVERDRIVE, value); setParameter(MDA_EP_OVERDRIVE, value);
} }
void mdaEPiano::setLoudness(float value)
{
volume = value * 0.32258; // 0.00002 * 127^2
}
void mdaEPiano::setParameter(int32_t index, float value) void mdaEPiano::setParameter(int32_t index, float value)
{ {
programs[0].param[index] = value; programs[0].param[index] = value;
@ -314,8 +320,8 @@ void mdaEPiano::process(int16_t* outputs_r, int16_t* outputs_l)
l = 1.0; l = 1.0;
else if (l < -1.0) else if (l < -1.0)
l = -1.0; l = -1.0;
outputs_l[frame] = static_cast<int16_t>(l * _loudness * 0x7fff) >> REDUCE_LOUDNESS; outputs_l[frame] = static_cast<int16_t>(l * 0x7fff) >> REDUCE_LOUDNESS;
outputs_r[frame] = static_cast<int16_t>(r * _loudness * 0x7fff) >> REDUCE_LOUDNESS; outputs_r[frame] = static_cast<int16_t>(r * 0x7fff) >> REDUCE_LOUDNESS;
} }
if (fabs(tl) < 1.0e-10) tl = 0.0f; //anti-denormal if (fabs(tl) < 1.0e-10) tl = 0.0f; //anti-denormal
@ -419,7 +425,7 @@ bool mdaEPiano::processMidiController(uint8_t data1, uint8_t data2)
break; break;
case 0x07: //volume case 0x07: //volume
master_volume = map(data2, 0, 127, ENC_MASTER_VOLUME_MIN, ENC_MASTER_VOLUME_MAX); set_master_volume(map(data2, 0, 127, ENC_MASTER_VOLUME_MIN, ENC_MASTER_VOLUME_MAX));
break; break;
case 0x40: //sustain pedal case 0x40: //sustain pedal

@ -112,6 +112,7 @@ class mdaEPiano
void setTune(float value); void setTune(float value);
void setDetune(float value); void setDetune(float value);
void setOverdrive(float value); void setOverdrive(float value);
void setLoudness(float value);
int32_t getActiveVoices(void); int32_t getActiveVoices(void);
private: private:
@ -135,7 +136,7 @@ class mdaEPiano
float treb, tfrq, tl, tr; float treb, tfrq, tl, tr;
float tune, fine, random, stretch, overdrive; float tune, fine, random, stretch, overdrive;
float muff, muffvel, sizevel, velsens, modwhl; float muff, muffvel, sizevel, velsens, modwhl;
const float volume = 0.00002f * 127; float volume;
float vol; float vol;
//uint8_t curProgram; //uint8_t curProgram;
}; };

Loading…
Cancel
Save