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

Thread: Logarithmic / More Natural Fade with Release

  1. #1

    Logarithmic / More Natural Fade with Release

    Hello,

    My problem is that when I give WAV files a slow release time (about 4000-7000ms), it sounds like it abruptly stops at the end instead of a more natural expected fade sound. (ie. Continue to sound like it is still fading out even when it reaches the tail end and lower volume).

    Is the release a linear fade out?

    Would a logarithmic release fix this?

    Is there a way to make edits to the effect_envelope.h or similar files to get a more natural / logarithmic fade out?

    Thanks!!

    (No code posted because this ‘issue’ is relative to the envelope behavior.. I get this same issue in example sketches.)

  2. #2
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,476
    How much of the audio remains to be played when you issue a noteoff to trigger the release?
    I think it would be best if you posted code which illustrates the problem, preferably using one of the sample WAV files such as SDTEST1.WAV.

    Pete

  3. #3
    Quote Originally Posted by el_supremo View Post
    How much of the audio remains to be played when you issue a noteoff to trigger the release?
    I think it would be best if you posted code which illustrates the problem, preferably using one of the sample WAV files such as SDTEST1.WAV.

    Pete

    Thanks for the response Pete!

    To answer your question and give more information – My WAV file is like 10+min. When I trigger a release (before the end of the file), I just want it to slowly fade out.

    This all happens as planned –– but when it fades out, the fade sounds nice and smooth at the beginning, but real abrupt at the end. In my research, it sounds like this is because that's what happens when you fade out music/sound in a linear way.

    In music and sound, to get a really smooth slow fade out, you need to use more of an exponential fade instead of just a straight linear fade. Otherwise, you perceive the later end of the fade out to be more abrupt than the first half.

    This image kind of illustrates what I am talking about –– I'm looking for the exponential fade in and fade out to be applied to the attack and release of my note.

    Click image for larger version. 

Name:	Screen Shot 2020-04-12 at 9.29.08 PM.jpg 
Views:	20 
Size:	23.9 KB 
ID:	19662

    My code isn't really the issue I am having, I would just prefer that the release envelope behavior was exponential instead of linear. I'm wondering if there's away to make the release more exponential instead of linear?

  4. #4
    Senior Member
    Join Date
    Feb 2017
    Posts
    418
    Quote Originally Posted by isaacjacobson View Post
    My code isn't really the issue I am having....
    Perhaps not. But, if you did as requested, others could recreate your issue and test potential solutions. Is there some reason you're unwilling to show code?

  5. #5
    Quote Originally Posted by gfvalvo View Post
    Perhaps not. But, if you did as requested, others could recreate your issue and test potential solutions. Is there some reason you're unwilling to show code?
    Hey thanks for also jumping in to help! It's not that I am "unwilling to show code." My question was just more general and hypothetical rather than relating to any specific code I have, but I probably didn't communicate it clear enough.

    My question is probably better concisely asked as "Is it possible to modify the envelope/fade libraries or (write something new) to achieve 'exponential ADSR/fades' vs the 'linear ADSR/fades' that are prepackaged in the envelope/fade functions included in the Teensy/Audio Shield library?"

    The reason I haven't shared any code is because I really didn't have any code to share since it was all in different bits and pieces and experimenting with the example sketches.

    But I would love help finding a solution, so you're probably right that more information and clarification is needed!

    HERE is a link that compiles all the information I am about to reference...


    The core of the issue that I am trying to solve: when using slow fade outs of sustained notes via release(7000); or fadeOut(7000);, the tail end of the fade is perceived to end rather abruptly, while the beginning of the fade is nice and smooth. I'm about 90% sure that this is because both release(); and fadeOut(); follow linear functions (which is understandable and kind of the standard).

    When trying to achieve a longer and "smoother" fade out, it helps to have the function be exponential or logarithmic vs linear. It's a subtle difference, but it's there.

    HERE is a recording of a fade in and fader out recorded from Teensy 4.0 w/ Audio Shield REV D. If you listen VERY closely to the fade out at the end, you'll hear what I'm talking about. The sustained sawtooth note starts to fade out slowly, but kind of cuts out at the tail end. It's slightly tough to hear at first in this recording because theirs some background ambience. It would help to listen with headphones.

    HERE is a recording of that same sound exponentially faded out in a DAW (warning: this file is a bit louder than the first file – so you might want to adjust your speakers/headphones!) You'll notice in this recording that the tail end of the fade and transition to silence is smoother than the linear fade out recorded from the Teensy.

    The reason why I'm 90% sure that this issue isn't from my code is because I get the same issue when testing linear vs exponential fades in a DAW (Logic) with the exact same file.

    Here's a screen shot of that:
    Click image for larger version. 

Name:	Linear vs Exponential in DAW.png 
Views:	14 
Size:	192.1 KB 
ID:	19687


    If you want to try it out on a Teensy...

    HERE is the sawtooth sustained note that I am using (titled "1.wav").

    And here is a code to try it out:

    Code:
    // entering "play" into the serial monitor causes "1.wav" to play with a 7000ms fade in.
    // entering "stop" into the serial monitor causes "1.wav" to play with a 7000ms fade out.
    
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioPlaySdWav           playSdWav1;     //xy=119,334
    AudioEffectEnvelope      envelope1;      //xy=337,365
    AudioOutputI2S           i2s1;           //xy=566,359
    AudioConnection          patchCord1(playSdWav1, 0, envelope1, 0);
    AudioConnection          patchCord2(envelope1, 0, i2s1, 0);
    AudioConnection          patchCord3(envelope1, 0, i2s1, 1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=118,427
    // GUItool: end automatically generated code
    
    
    // Use these with the Teensy Audio Shield
    #define SDCARD_CS_PIN    10
    #define SDCARD_MOSI_PIN  7
    #define SDCARD_SCK_PIN   14
    
    // Use these with the Teensy 3.5 & 3.6 SD card
    //#define SDCARD_CS_PIN    BUILTIN_SDCARD
    //#define SDCARD_MOSI_PIN  11  // not actually used
    //#define SDCARD_SCK_PIN   13  // not actually used
    
    // Use these
    // for the SD+Wiz820 or other adaptors
    //#define SDCARD_CS_PIN    4
    //#define SDCARD_MOSI_PIN  11
    //#define SDCARD_SCK_PIN   13
    
    String serial_command; // A string for handing serial commands
    
    void setup() {
      Serial.begin(9600);
      AudioMemory(10);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.5);
      SPI.setMOSI(SDCARD_MOSI_PIN);
      SPI.setSCK(SDCARD_SCK_PIN);
      if (!(SD.begin(SDCARD_CS_PIN))) {
        while (1) {
          Serial.println("Unable to access the SD card");
          delay(500);
        }
      }
    
    
    
    // Envelope Settings
      envelope1.delay(0); // no attack delay necessary
      envelope1.attack(7000); // 7000ms fade in
      envelope1.release(7000); // 7000ms fade out
      envelope1.sustain(1.0); // sustain indefinitely for duration of file
    
    
      delay(200); 
     serial_command = "waiting for command"; // A neutral 'idle' state for the string
    }
    
    
    void loop() {
    
       if(Serial.available()){
            serial_command= Serial.readStringUntil('\n'); // receive commands and store in a string
            Serial.print("Command Received: ");
            Serial.println(serial_command.c_str());
       }
    
            // If serial monitor receives "play" then play a wav file with a 7000ms fade in via the 'envelope1.noteOn()'
            if(serial_command== "play"){ 
              Serial.println("[ PLAYING FILE ]"); // Communicate which action is occurring
            playSdWav1.play("1.wav");  // Play wav file (which is pretty much a 60 sec sawtooth sustained note for this example)
            envelope1.noteOn(); // Essentially begins the 'fade in'
            serial_command = "waiting for command"; // Reset the string to a neutral 'idle' state for the string
            }
    
            // If serial monitor receives "stop" then fade out for 7000ms via the 'envelope1.noteOff()'
             if(serial_command== "stop"){
              Serial.println("[ STOPPING FILE ]"); // Communicate which action is occurring
            envelope1.noteOff(); // Essentially begins the 'fade out'
            serial_command = "waiting for command"; // Reset the string to a neutral 'idle' state for the string
            }
    }

    • The code plays "1.wav" from an SD card when you type "play" into the serial monitor and fades the file in via envelope1.noteOn(); with a 7000ms attack.
    • The file is then faded out by typing "stop" into the serial monitor via envelope1.noteOff(); with a 7000ms release.
    • If you listen carefully, you should hear what I am describing my issue to be: the note starts to slowly fade, but then at the tail end of the fade seems to just cut out (again – I believe due to the linear behavior).



    Here's a diagram that visually compares 'exponential ADSR' vs "linear ADSR.':
    Click image for larger version. 

Name:	Linear ADSR vs Exponential ADSR diagram.png 
Views:	10 
Size:	41.3 KB 
ID:	19688

    One isn't right or wrong. In fact, linear is more standard, but exponential accomplishes a smoother fade to silence when using a longer fade time.


    Does anyone have any ideas for how I can either modify the envelope or fade to be more exponential? Or accomplish this smoother (log/exponential) fade effect another way?


    PS. thanks gfvalvo for requesting more info!

  6. #6
    Senior Member
    Join Date
    Feb 2017
    Posts
    418
    I'll have to take your word for it on the difference between audio clips. I have no doubt that you hear it. It's just that such minutiae in audio isn't my thing. I'm more a "blink the lights to the music while playing it loud" kind of guy. Especially for holiday displays, etc.

    Anyway,
    Quote Originally Posted by isaacjacobson View Post
    My question is probably better concisely asked as "Is it possible to modify the envelope/fade libraries or (write something new) to achieve 'exponential ADSR/fades' vs the 'linear ADSR/fades' that are prepackaged in the envelope/fade functions included in the Teensy/Audio Shield library?"
    The answer to that is easy. Being open-source like the rest of the Arduino ecosystem, the source code for then entire Audio Library is there for you to examine. You can look inside library classes in question to see how they achieve their effect. It's probably best not to modify the existing ones, but use them as guides to make your own with the characteristics that you want. Here's the PJRC guide for making your own Audio Library classes: https://www.pjrc.com/teensy/td_libs_...ewObjects.html

  7. #7
    Senior Member houtson's Avatar
    Join Date
    Aug 2015
    Location
    Scotland
    Posts
    135
    Hi

    Have a look at @a_guy_called_tom's Polaron DIY Drum Machine - https://github.com/zueblin/Polaron

    He has created a custom Envelope using an exponential look up table, have a look at the files: effect_shaped_envelope.h & .cpp.

    Not sure if it does all that you want but gets a fair way there. Also adds a different approach to attack (more like an analogue synth approach).

    Cheers, Paul

  8. #8
    Junior Member
    Join Date
    Jun 2020
    Posts
    1

    Same request here. Exponential envelope needed

    Quote Originally Posted by isaacjacobson View Post
    Hello,

    My problem is that when I give WAV files a slow release time (about 4000-7000ms), it sounds like it abruptly stops at the end instead of a more natural expected fade sound. (ie. Continue to sound like it is still fading out even when it reaches the tail end and lower volume).

    Is the release a linear fade out?

    Would a logarithmic release fix this?

    Is there a way to make edits to the effect_envelope.h or similar files to get a more natural / logarithmic fade out?

    Thanks!!

    (No code posted because this ‘issue’ is relative to the envelope behavior.. I get this same issue in example sketches.)
    I’m making a synthesizer and exponential envelope it’s a must .

  9. #9
    Senior Member
    Join Date
    Feb 2017
    Posts
    418
    Quote Originally Posted by Malmi315 View Post
    I’m making a synthesizer and exponential envelope it’s a must .
    See Reply #6 and Reply #7.

  10. #10
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    265
    The existing envelope class is written for fixed point math (as is the rest of the audio classes), which makes it hard for me to see what it's doing. It also makes it hard for a person like me to try alternatives.

    Since I use the Teensy 3.6 (or 4.x), I'd flip this class to be a floating-point class (and put it in my floating point Tympan library or OpenAudio library), which would make it way easier to try different ideas to see approach better suits your goal.

    Candidates:

    * Truly Linear: gain (in linear units) changes linearly in time
    * Linear Log: gain in dB units changes linearly in time
    * Log log: gain in dB units changes logarithmically in time


    Are you working on a Teensy 3.6 / 4.x or are you trying to do this on one of the non-floating point Teensy boards?

    Chip

  11. #11
    Thanks for the continued responses!

    The Polaron DIY Drum Machine is pretty sweet! And the OpenAudio Library is awesome– great work on that!

    I was using a 4.0.

    I ended up figuring out a somewhat "jerry rig" of a work around – I ended up just using metro.h to create timers to 're-trigger' the release again toward the tail end of the release to soften it a bit.


    ie – if I triggered a 4000ms delay on a note, I 'scheduled' it to do an additional 3000ms release again about 3300ms into the timeline of the initial 4000ms release. Re-triggering the release of the note toward the tail-end of the release timeline caused it to be a bit softer and less abrupt. Again, kind of a 'jerry rig' of a work around, but it worked for my purposes.


    Anyway, if anyone else looking to do something similar and simple, that worked for my needs.

  12. #12
    Junior Member
    Join Date
    Mar 2019
    Posts
    8
    Another workaround to get exponential envelopes is simply using several standard envelopes in parallel with different times (added in a mixer). This way you get a "linear approximation". With four envelopes it sounds already good to me for short, percussive sounds. For longer times you probably would need more.

  13. #13
    Quote Originally Posted by TomChiron View Post
    Another workaround to get exponential envelopes is simply using several standard envelopes in parallel with different times (added in a mixer). This way you get a "linear approximation". With four envelopes it sounds already good to me for short, percussive sounds. For longer times you probably would need more.
    That's very clever and much simpler than my workaround. Would you have the time to show an example like a screenshot or the 'export' from the GUI tool?

  14. #14
    Junior Member
    Join Date
    Mar 2019
    Posts
    8
    Quote Originally Posted by isaacjacobson View Post
    That's very clever and much simpler than my workaround. Would you have the time to show an example like a screenshot or the 'export' from the GUI tool?
    Here is an example which should show the principle with the relevant lines of code.

    I used it for decay only with sustain = 0. For release time it should work in the same way.

    The numbers for the times do work well for my application and should be a good starting point. This is also a matter of taste.

    Click image for larger version. 

Name:	env_x4_example.jpg 
Views:	16 
Size:	21.0 KB 
ID:	22127
    Code:
      // add up four envelopes while preserving amplitude
      env_mixer.gain(0, 0.25);
      env_mixer.gain(1, 0.25);
      env_mixer.gain(2, 0.25);
      env_mixer.gain(3, 0.25);
    
      AudioNoInterrupts();
    
      envDec = 5; // set time here
      envelope1.decay(envDec / 12);
      envelope2.decay(envDec / 7);
      envelope3.decay(envDec / 2);
      envelope4.decay(envDec);
    
      // trigger all envelopes:
      envelope1.noteOn();
      envelope2.noteOn();
      envelope3.noteOn();
      envelope4.noteOn();
    
      AudioInterrupts();

  15. #15
    Awesome! Thanks for taking the time to share that – very helpful!

Posting Permissions

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