Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: Strange latency with enevlope

  1. #1
    Junior Member
    Join Date
    Jan 2019
    Posts
    6

    Strange latency with enevlope

    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.
    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!!!

  2. #2
    Senior Member
    Join Date
    Feb 2015
    Posts
    213
    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?

  3. #3
    Junior Member
    Join Date
    Jan 2019
    Posts
    6
    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();
    }

  4. #4
    Senior Member
    Join Date
    Feb 2015
    Posts
    213
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •