Strange latency with enevlope

Status
Not open for further replies.

hottib

Member
Hey,
i m using a teensy3.2 with audioshield. I am trying to program a ribbon control for my electric bass. I want to used like an extra string with synthsized sounds.....
while figuring out which synthesis works best for my band and playing live, one strange problem occurs:
I set up a simple envelope right "before" the i2s output. if my release time is 0 - i have no percetible latency problem BUT if i increase the sustain time the latency increases as well. :confused:
Does someone know why?
Or does anyone have a workaround for that issue?
Greetings from Berlin!
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveform       sineAM;         //xy=105.08332824707031,1026.9999771118164
AudioSynthWaveformDc     dcAM;           //xy=108.08332824707031,1149.9999771118164
AudioSynthWaveform       sawtoothAM;     //xy=118.08332824707031,1072.9999771118164
AudioSynthWaveformSine   sineModulator;  //xy=138.0833282470703,1276.9999771118164
AudioMixer4              mixerDcMod;     //xy=272.0833282470703,1164.9999771118164
AudioMixer4              mixerAM;        //xy=275.0833282470703,1045.9999771118164
AudioSynthWaveformModulated sineFM;         //xy=327.0833282470703,1276.9999771118164
AudioSynthWaveformModulated sawtoothFM;     //xy=338.0833282470703,1340.9999771118164
AudioEffectMultiply      multiply1;      //xy=442.08331298828125,1159.0831909179688
AudioMixer4              mixer1;         //xy=679.0500030517578,1196.0500030517578
AudioEffectEnvelope      envelope1;      //xy=869.0500030517578,1180.0500030517578
AudioOutputI2S           i2s2;           //xy=1058.0833740234375,1183
AudioConnection          patchCord1(sineAM, 0, mixerAM, 0);
AudioConnection          patchCord2(dcAM, 0, mixerDcMod, 0);
AudioConnection          patchCord3(sawtoothAM, 0, mixerAM, 1);
AudioConnection          patchCord4(sineModulator, 0, sawtoothFM, 0);
AudioConnection          patchCord5(sineModulator, 0, sineFM, 0);
AudioConnection          patchCord6(sineModulator, 0, mixerDcMod, 1);
AudioConnection          patchCord7(mixerDcMod, 0, multiply1, 1);
AudioConnection          patchCord8(mixerAM, 0, multiply1, 0);
AudioConnection          patchCord9(mixerAM, 0, mixer1, 0);
AudioConnection          patchCord10(sineFM, 0, mixer1, 2);
AudioConnection          patchCord11(sawtoothFM, 0, mixer1, 3);
AudioConnection          patchCord12(multiply1, 0, mixer1, 1);
AudioConnection          patchCord13(mixer1, envelope1);
AudioConnection          patchCord14(envelope1, 0, i2s2, 0);
AudioConnection          patchCord15(envelope1, 0, i2s2, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=663.0500030517578,1349.0500030517578
// GUItool: end automatically generated code

//Basics

elapsedMillis Print;
//Controls
int button1 = 1;
int button2 = 2;
int knob1;
int knob2;
int knob3;
int knob4;
int slider;
int force; 
int forceBig;

//Stuff for Pitching
float freq; 
float n; //Tonstufe
float cent;
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
	return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}



void setup() {
Serial.begin(38400);
pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
sgtl5000_1.unmuteHeadphone();
sgtl5000_1.adcHighPassFilterDisable();
AudioMemory(80);
sineModulator.amplitude(0.2);
sineModulator.frequency(40);
sineFM.begin(1, 40, WAVEFORM_SINE);
mixer1.gain(0, 1.0);
mixer1.gain(1, 1.0);
mixer1.gain(2, 1.0);
mixer1.gain(3, 1.0);
envelope1.attack(50);
envelope1.decay(50);
envelope1.release(250);
envelope1.releaseNoteOn(0);
}

void Controls() {
  slider = analogRead(0);
  force = analogRead(1);
  forceBig = analogRead(6);
  knob1 = analogRead(2);
  knob2 = analogRead(3);
  knob3 = analogRead(4);
  knob4 = analogRead(5);
  button1 = digitalRead(1);
  button2 = digitalRead(2);
// freq wie auf der E-Saite
n = mapfloat((float)slider, 0., 1024., 8., 20.);
freq =  440*pow(2, (n-49)/12);
// Cent
cent = 1200.*sqrtf(41.2034/freq);
sineModulator.frequency(4*freq);
sineFM.frequency(freq);
/* Volume  Knobs
mixer1.gain(0, (float)knob1/1024.);
mixer1.gain(3, (float)knob4/1024.);
mixer1.gain(1, (float)knob2/1024.);
mixer1.gain(2, (float)knob3/1024.);
*/
if (envelope1.isActive() == false)
{
if (button2 == 0) {
  envelope1.noteOn();
  }}
else {
  if (button2 == 1) {
  envelope1.noteOff();
  }
float decay = (float(knob2)/1024.)*200.;
envelope1.decay(decay);
float attack = (float(knob1)/1024.)*200.;
envelope1.attack(attack);
float sustain = (float(knob3)/1024.);
envelope1.sustain(sustain);
float release = (float(knob4)/1024.*300);
envelope1.release(release);
}
}
 /*
void Monitoring() {
//Monitoring
if (Print>1000) {
 Serial.print("Slider is: ");
  Serial.println(slider); 
  Serial.print("                          Force is: ");
  Serial.print(force); 
  Serial.print("ForceBig is: ");
  Serial.print(forceBig); 
  Serial.print("                                   Knob1 is: ");
  Serial.println(knob1);
  Serial.print("                                         Knob2 is: ");
  Serial.println(knob2);
  Serial.print("                                             Knob3 is: ");
  Serial.println(knob3);
  Serial.print("                                                Knob4 is: ");
  Serial.println(knob4);
  Serial.print("                                                   button1 is: ");
  Serial.println(button1);
  Serial.print("                                                        button2 is: ");
  Serial.println(button2);
  Serial.print("                                                                              FREQUENZ:");
  Serial.print(freq);
  Serial.print("     Cent:");
  Serial.println(cent); 
Print = 0;
} } 
*/
void loop(){
  //Monitoring();
  Controls();
}
The code probably looks strange to you.sry---- I am not professional programmer. I would be super happy if anybody can help me!!!
 
Well, I don't know what you mean by latency problem, but I think you might have a logic problem in your code.
Code:
...
mixer1.gain(2, (float)knob3/1024.);
...
float sustain = (float(knob3)/1024.);

You have one analog reading controlling two things, perhaps that is contributing to the perceived problems?
 
Hey, thank you wcalvert! unfortunately the "double contolling" is not a problem - because ... mixer1.gain(2, (float)knob3/1024.),..... is tagged as a comment.
By latency problems i mean that button2 triggers the envelope.noteOn. That works beautifully if the realease is 0ms. i hear the sound in the moment i press button2 - no latency... in the moment i am increasing the release time the sound "comes out later and later". here is another version of my code without all the distracting /* things;) */:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveform       sineAM;         //xy=105.08332824707031,1026.9999771118164
AudioSynthWaveformDc     dcAM;           //xy=108.08332824707031,1149.9999771118164
AudioSynthWaveform       sawtoothAM;     //xy=118.08332824707031,1072.9999771118164
AudioSynthWaveformSine   sineModulator;  //xy=138.0833282470703,1276.9999771118164
AudioMixer4              mixerDcMod;     //xy=272.0833282470703,1164.9999771118164
AudioMixer4              mixerAM;        //xy=275.0833282470703,1045.9999771118164
AudioSynthWaveformModulated sineFM;         //xy=327.0833282470703,1276.9999771118164
AudioSynthWaveformModulated sawtoothFM;     //xy=338.0833282470703,1340.9999771118164
AudioEffectMultiply      multiply1;      //xy=442.08331298828125,1159.0831909179688
AudioMixer4              mixer1;         //xy=679.0500030517578,1196.0500030517578
AudioEffectEnvelope      envelope1;      //xy=869.0500030517578,1180.0500030517578
AudioOutputI2S           i2s2;           //xy=1058.0833740234375,1183
AudioConnection          patchCord1(sineAM, 0, mixerAM, 0);
AudioConnection          patchCord2(dcAM, 0, mixerDcMod, 0);
AudioConnection          patchCord3(sawtoothAM, 0, mixerAM, 1);
AudioConnection          patchCord4(sineModulator, 0, sawtoothFM, 0);
AudioConnection          patchCord5(sineModulator, 0, sineFM, 0);
AudioConnection          patchCord6(sineModulator, 0, mixerDcMod, 1);
AudioConnection          patchCord7(mixerDcMod, 0, multiply1, 1);
AudioConnection          patchCord8(mixerAM, 0, multiply1, 0);
AudioConnection          patchCord9(mixerAM, 0, mixer1, 0);
AudioConnection          patchCord10(sineFM, 0, mixer1, 2);
AudioConnection          patchCord11(sawtoothFM, 0, mixer1, 3);
AudioConnection          patchCord12(multiply1, 0, mixer1, 1);
AudioConnection          patchCord13(mixer1, envelope1);
AudioConnection          patchCord14(envelope1, 0, i2s2, 0);
AudioConnection          patchCord15(envelope1, 0, i2s2, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=663.0500030517578,1349.0500030517578
// GUItool: end automatically generated code

//Basics

elapsedMillis Print;
//Controls
int button1 = 1;
int button2 = 2;
int knob1;
int knob2;
int knob3;
int knob4;
int slider;
int force; 
int forceBig;

//Stuff for Pitching
float freq; 
float n; //Tonstufe
float cent;
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
	return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}



void setup() {
Serial.begin(38400);
pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
sgtl5000_1.unmuteHeadphone();
sgtl5000_1.adcHighPassFilterDisable();
AudioMemory(80);
sineModulator.amplitude(0.2);
sineModulator.frequency(40);
sineFM.begin(1, 40, WAVEFORM_SINE);
mixer1.gain(0, 1.0);
mixer1.gain(1, 1.0);
mixer1.gain(2, 1.0);
mixer1.gain(3, 1.0);
envelope1.attack(50);
envelope1.decay(50);
envelope1.release(250);
envelope1.releaseNoteOn(0);
}

void Controls() {
  slider = analogRead(0);
  force = analogRead(1);
  forceBig = analogRead(6);
  knob1 = analogRead(2);
  knob2 = analogRead(3);
  knob3 = analogRead(4);
  knob4 = analogRead(5);
  button1 = digitalRead(1);
  button2 = digitalRead(2);
// freq wie auf der E-Saite
n = mapfloat((float)slider, 0., 1024., 8., 20.);
freq =  440*pow(2, (n-49)/12);
// Cent
cent = 1200.*sqrtf(41.2034/freq);
sineModulator.frequency(4*freq);
sineFM.frequency(freq);

if (envelope1.isActive() == false)
{
if (button2 == 0) {
  envelope1.noteOn();
  }}
else {
  if (button2 == 1) {
  envelope1.noteOff();
  }
float decay = (float(knob2)/1024.)*200.;
envelope1.decay(decay);
float attack = (float(knob1)/1024.)*200.;
envelope1.attack(attack);
float sustain = (float(knob3)/1024.);
envelope1.sustain(sustain);
float release = (float(knob4)/1024.*300);
envelope1.release(release);
}
}
 
void loop(){

  Controls();
}
 
Your synth has one voice, and you are checking if the envelope is active before letting another note play with this bit of code:
Code:
if (envelope1.isActive() == false)

If you remove the condition check, that's called 'voice stealing' or 'note stealing'. There was another thread in the past few months where I helped another user create a voice stealing system for a synth with multiple voices.
 
Status
Not open for further replies.
Back
Top