function y = fade(x, ta, td, Fs)
    // Audio fade in and fade out
    // This function applies half a Hann window at the 
    // begining and at the end of an audio signal with 
    // specified attack and decay times.
    //
    // Usage:
    //       y = fade(x, ta, td, Fs)
    //
    // where x:  audio signal
    //       ta: attack time in ms
    //       td: decay time in ms
    //       Fs: sampling rate in Hz
    //
    // Sampling rate is optional. If not given, its 
    // default value is 44100. Parmeter ta is the 
    // duration of the first half of the Hann window 
    // applied at the begining of the signal, while
    // td is the duration of the second half of the
    // Hann window applied at the end of the signal.
    // Both ta and td are also optional. If td is
    // omitted, it is taken equal to ta. If ta is 
    // not given, both parameters are set to 3 ms.
    // 
    // NOTE: fade may be used in a more general way 
    //       stipulating Fs = 1000 and setting ta and
    //       td to be the number of samples at the 
    //       beginning and at the end of any given
    //       vector to be faded in and out respectively.
    //
    // ------------------------------
    // Author: Federico Miyara
    // Date:   2008-08-03
    //         2010-07-08
    //         2021-06-14 

    rhs = argn(2);

    // If sampling rate is not given, set it to 44100 Hz
    if rhs < 4
        Fs = 44100;
    end

    // If td is not given, set it equal to ta
    if rhs < 3
        if nargin == 3
            td = ta;
        end
    end

    // If ta is not given, set both ta and td equal to 3 ms
    if rhs < 2
        ta = 3;
        td = 3;
    end

    // As most of y will be equal to x, start defining
    // y as x
    y = x;

    // Number of samples in attack and decay segments
    Na = round(ta/1000*Fs);
    Nd = round(td/1000*Fs);

    if length(x) > Na + Nd
        // Attack segment
        fade_a = window("hn", 2*Na); 
        y(1:Na) = y(1:Na) .* fade_a(1:Na);

        // Decay segment
        fade_d = window("hn", 2*Nd);
        y($-Nd+1:$) = y($-Nd+1:$) .* fade_d(Nd+1:2*Nd);
    else
        // Signal is too short so a single Hanning window is 
        // applied to the full signal
        mprintf("Signal is too short for required attack and decay\n")
        mprintf("A single Hann window will be applied\n") 
        y = y .* window("hn", length(y))
    end

endfunction


