0

I'm creating a distortion pedal for my guitar and I have created a distortion with a high-pass filter. Everything works really great except I get this crackling noise as notes begin to fade away.

function audio = reaper(frame, drive, tone)
    % Distortion pedal with high-pass filter and gain.
    %
    %   audio = reaper(frame, drive, tone)
    %
    %   frame: audio frame to be processed (int32)
    %   drive: amount of gain to apply to the filtered signal (between 0 and 10)
    %   tone: cuttoff frequency for high-pass filter (between 0 and 10)
    %
    %   The reaper distortion pedal first sends the signal through a
    %   butterworth filter (high-pass) that sets the cutoff frequency based
    %   on the tone. Then the filtered frequency is multiplied by the drive
    %   (gain). The resulting audio frequency is returned.

    % Use butterworth filter for high-pass filter
    [zeros,poles,gain] = butter(1,265*((tone+(10/9))*(9/10))/(44100/2),'high'); % Tone is normalized between 1 and 10
    [num,den] = zp2tf(zeros,poles,gain);
    
    % Apply high-pass filter with gain
    audio = int32(((drive+(10/99))*(99/10))*filter(num,den,double(frame))); % Drive is normalized between 1 and 100
end
Caleb Merchant
  • 289
  • 1
  • 5
  • 16
  • 1
    Filter is not memoryless, so you'd need to keep the filter state from frame to frame. This can be done by feeding back the final state (`zf` from the `[y,zf] = filter...` output) as initial state on subsequent `filter` invocations. – SleuthEye Feb 08 '15 at 01:59
  • @Caleb A distortion pedal is essentially a non-linear gain (saturation). A filter is linear, so a filter by itself can't generate the sound of a distortion pedal. How are you simulating the distortion? Do you introduce some non-linearity? – Luis Mendo Feb 08 '15 at 03:10
  • The drive variable applies linear gain to it. Its actually technically overdrive then though because distortion is non-linear while overdrive is linear. So my bad on that. And I'll try that SleuthEye. But does the butterworth filter not return the same thing every time? I assumed it would be the same every time. – Caleb Merchant Feb 08 '15 at 03:51
  • `butter` returns the same filter coefficients given the same arguments. `filter` uses those coefficients _and an initial state_ (which defaults to 0) to process the input samples. – SleuthEye Feb 08 '15 at 13:11
  • Oh I see. So how do I do what you were talking about? I see how you get the zf from the filter and it will be used in the next filter object but how do I implement that in my loop that processes each frame? – Caleb Merchant Feb 08 '15 at 17:43
  • while true stream = amplifier(reaper(step(input),10,10), settings); step(output,stream); end – Caleb Merchant Feb 08 '15 at 17:46
  • I see how I could do this in matlab I think but I'm eventually going to implement this in c/c++ so I'll have to figure out how to do that eventually. Thanks for the help. – Caleb Merchant Feb 08 '15 at 17:52

0 Answers0