Howto avoid introducing rumble from ADSR

Programming applications for making music on Linux.

Moderators: MattKingUSA, khz

Post Reply
f00bar
Established Member
Posts: 83
Joined: Sun May 12, 2013 7:40 pm

Howto avoid introducing rumble from ADSR

Post by f00bar »

My ADSR envelope is modelled after a simple RC analog:

Code: Select all

			float operator()(float value)
				{
				switch(state)
					{
					case State::ATTACK:
						value+=(1.0f - value)/A;
						if(std::abs(1.0f - value) < threshold)
							{state=State::DECAY;}
						return value;
					case State::DECAY:
						value+=(S-value)/D; 
						if(std::abs(S - value) < threshold)
							{state=State::SUSTAIN;}
						return value;
					case State::SUSTAIN:
						return S;
					case State::RELEASE:
						value+=(-value)/R;
						return value;
					}
				return 0.0f;
				}
threshold is currently 1.0f/1024

The problem here is that it tends to introduce audible rumble when it is used from the pattern generator. I guess it is the attack phase that is the problem. One way of "solving" the problem is to add a high pass filter before the output, but it is better if the rumble is not introduced at all.
Spectrum with &quot;trancegate&quot; fully activated
Spectrum with "trancegate" fully activated
with-gate.jpg (230 KiB) Viewed 1369 times
Spectrum without &quot;trancegate&quot;
Spectrum without "trancegate"
no-gate.jpg (223.24 KiB) Viewed 1369 times
Due to Heissenberg, the wider spectrum is necessary, but is it possible to avoid the LF rumble.
fundamental
Established Member
Posts: 165
Joined: Thu Nov 07, 2013 1:19 pm
Been thanked: 1 time

Re: Howto avoid introducing rumble from ADSR

Post by fundamental »

Could you perhaps upload an audio clip of the undesired rumble?
Static spectra are only so useful when applied to dynamics.
ZynAddSubFX maintainer
f00bar
Established Member
Posts: 83
Joined: Sun May 12, 2013 7:40 pm

Re: Howto avoid introducing rumble from ADSR

Post by f00bar »

fundamental wrote:Could you perhaps upload an audio clip of the undesired rumble?
Static spectra are only so useful when applied to dynamics.
Here's a demo.
Attachments
happychords-demo.wav
(725.93 KiB) Downloaded 70 times
fundamental
Established Member
Posts: 165
Joined: Thu Nov 07, 2013 1:19 pm
Been thanked: 1 time

Re: Howto avoid introducing rumble from ADSR

Post by fundamental »

ok, bug confirmed.

Why in the world are you *Adding* the envelope?
Would you not want to *Multiply* it with the waveform?
ZynAddSubFX maintainer
diizy
Established Member
Posts: 105
Joined: Tue Feb 04, 2014 2:48 am

Re: Howto avoid introducing rumble from ADSR

Post by diizy »

fundamental wrote:Why in the world are you *Adding* the envelope?
The adding modifies the curve of the envelope itself. The envelope value gets later multiplied with the actual signal, I assume.
value+=(-value)
Why not just write value -= value?

I can't really see any obvious fault with the envelope code. Maybe it's the input signal? Sure there isn't any DC offset in the input?
fundamental
Established Member
Posts: 165
Joined: Thu Nov 07, 2013 1:19 pm
Been thanked: 1 time

Re: Howto avoid introducing rumble from ADSR

Post by fundamental »

diizy, you're misunderstanding me (though it is my fault here).
Download the wave and take a looks at the raw waveform.
The envelope is added to the signal rather than being used to scale the waveform.

aka

Code: Select all

Envelope env;
for(int i=0; i<frame_size; ++i)
    output_signal[i] = input_signal[i] + env();
rather than

Code: Select all

for(int i=0; i<frame_size; ++i)
    output_signal = input_signal[i]*env();
ZynAddSubFX maintainer
diizy
Established Member
Posts: 105
Joined: Tue Feb 04, 2014 2:48 am

Re: Howto avoid introducing rumble from ADSR

Post by diizy »

In that case, the problem is that it's currently

Code: Select all

output[i] = env( input[i] );
when it should be

Code: Select all

env_phase = env( env_phase );
output[i] = input[i] * env_phase;
Meaning, that the argument given to the function in the OP should be a variable that holds the current phase of the envelope, not the input signal. The input signal should then be multiplied with the output of the function.
f00bar
Established Member
Posts: 83
Joined: Sun May 12, 2013 7:40 pm

Re: Howto avoid introducing rumble from ADSR

Post by f00bar »

fundamental wrote:diizy, you're misunderstanding me (though it is my fault here).
Download the wave and take a looks at the raw waveform.
The envelope is added to the signal rather than being used to scale the waveform.

aka

Code: Select all

Envelope env;
for(int i=0; i<frame_size; ++i)
    output_signal[i] = input_signal[i] + env();
rather than

Code: Select all

for(int i=0; i<frame_size; ++i)
    output_signal = input_signal[i]*env();
No, the envelope is not added, but multiplied. If it were added, you would see the wave go up and be turned off like this. Here is the envelope modulation:

Code: Select all

    while(n_frames)
        {
        auto v_gate=gate();             //Gets the current state of the gate and updates afterwards.
        auto v_gen=generatorsMix(); //Get values from oscillators
        auto v_out=(v_gate * (*gate_depth) + (1.0f-*gate_depth))*v_gen;
        *L=v_out.x;
        *R=v_out.y;
        ++L;
        ++R;
        gate_ctrl(); //Turns on/off the gate depending on MIDI messages in the current pattern
        --n_frames;
        }

Code: Select all

float Gate::operator()()
    {
    auto ret=G;
    G=envelope(G); //envelope is a FilterADSR
    return ret;
    }
As you see it is multiplied. However, it looks like it is booth added and multiplied somehow...
Last edited by f00bar on Wed Jul 16, 2014 6:41 pm, edited 1 time in total.
fundamental
Established Member
Posts: 165
Joined: Thu Nov 07, 2013 1:19 pm
Been thanked: 1 time

Re: Howto avoid introducing rumble from ADSR

Post by fundamental »

Well, the signal is biased somewhere.
If not the envelope code, then the original waveform.
biased.png
biased.png (15.29 KiB) Viewed 1353 times
ZynAddSubFX maintainer
f00bar
Established Member
Posts: 83
Joined: Sun May 12, 2013 7:40 pm

Re: Howto avoid introducing rumble from ADSR

Post by f00bar »

It was the waveform. I think I have done to much image processing (the sawtooth started form zero instead of -1). The gate made it more audible since it turns on and of very quickly.
Post Reply