You are on page 1of 41

ELEC 484 Audio Signal Processing

Assignment 4:
 Dynamics Processors: Limiter, Compressor/Expander, Noise Gate
 Vibrato

Prepared for:
Dr. Peter Driessen
ELEC 484
University of Victoria

Prepared by:
Tim I. Perry
V00213455
June, 2009

Tim Perry
V00213455
2009-06-02

CONTENTS
Dynamic Range Controller General Form .................................................................................................... 2
PART 1: LIMITER ....................................................................................................................................... 4
PART 2: COMPRESSOR/EXPANDER .................................................................................................... 12
PART 3: NOISE GATE .............................................................................................................................. 19
PART 4: VIBRATO ................................................................................................................................... 25
REFERENCES ........................................................................................................................................... 26
APPENDIX A MATLAB Code............................................................................................................... 29

Tim Perry
V00213455
2009-06-02

ELEC 484 ASSIGNMENT 4


Dynamic Range Controller General Form
Figure 1 is a block diagram of a dynamic range controller, which is a nonlinear processor. Specific
implementations for a limiter, compressor/expander and noise gate will be based on this general structure.
Summarizing the basic operation of dynamics processors as depicted in Figure 1:


An input signal is delayed by D samples as the side chain path performs processing. The
side chain consists primarily of a level measurement, a static function, and attack and
release time adjustments. The main purpose of the side chain is to calculate a dynamic
gain factor g(n) such that at the output:
=
[ = + ( dB) in the logarithmic domain]

Figure 1. Dynamic Range Controller Bock Diagram [1]

Tim Perry
V00213455
2009-06-02
The compression factor R when representing the static curve in the logarithmic domain is the ratio of the
input level change to the output level change:

1
(1)
=
=
1
The static characteristic of a general dynamic range controller is shown in Figure 2. The straight line
equation of the output Y, and the ratio R can be derived from these curves [1]:
1
= +

(2)

=
=

Figure 2: Dynamic Range Controller Static Characteristic.

LT is the limiter threshold, CT is the compressor threshold, ET is the expander threshold, and NT is the
noise gate threshold. Typical compression factors and slope factors are [1]:

The control parameter f(n) can be calculated in the logarithmic domain F using the static characteristic. In
this way, control can be performed using line equations.

Tim Perry
V00213455
2009-06-02

PART 1: LIMITER




Implement a limiter using the ideas in the text Figures 5.3 and 5.8 and test it
on two carefully chosen sound files (e.g. voice, drums).
Adjust the parameters so that the limiting effect can be clearly heard. Clearly
document the algorithm and your code, and comment on when and how the limiter
is working.
Plot the static gain f(n) and dynamic gain g(n), along with the input waveform,
level measurement and output waveform.

After running a signal through a limiter, the objective is to receive an output signal that has lower peaks
such that the overall signal level may be boosted. However, the dynamics of the signal should be
unaltered below the limiter threshold. In order to control peaks, the attack time should be fast enough to
apply limiting to a transient as soon as the threshold is reached.

Figure 3: Limiter Block Diagram [1]

Based on the block diagram of Error! Reference source not found. which highlights the functional
elements of a limiter, a sample-based limiter was realized in Matlab. The limiter side chain functions as
follows:


Peak level measurement is used to determine if the input signal level at a particular instant is
greater than a defined threshold (Figure 5). The attack and release times for peak
measurement are typically in the range of: = 0.02 10.24 and =
1 5000 . The attack time for a time parameter of t and a sampling period of T is
calculated as follows:
= 1 = ./

Tim Perry
V00213455
2009-06-02

Figure 4: Peak Level Measurement [1]

If the peak value is greater than the threshold, then the inverse of the amplitude of the signal
will be multiplied by the normalized gain function in the sidechain (it will have a negative
gain applied such that its output level is equal to the threshold). The dynamic gain function
will be multiplied with the output signal at the onset after the attack time, and holds for a
duration equal to the release time.

If the peak value is less than the threshold, then there is no change applied to the signal (the
level corresponds to unity gain on the static function). In this case, the limiter is not triggered.

The control parameter f(n) (the static gain function or static curve) for the limiter is
represented in the logarithmic domain as:
(3)
= LSX LT + CSCT LT)

Figure 5: Peak Level Measurement [1]

The dynamic gain is calculated based on the dynamic filter [1], which is dependent on the attack and
release time of the triggered dynamic processor.

Tim Perry
V00213455
2009-06-02

Figure 6. Dynamic Filter (adjusts attack and release time for a dynamic range controller)

= 1 1 +
where k = AT or k = RT

(4)

The limiter (and each dynamic processer to be outlined) was applied to two audio files:



diner.wav (excerpt from Toms Diner vocal line)


TranSiberian_Drums.wav (excerpt from the midi-programmed drum line of a
personal composition [left channel only used])

In order to limit only the peak dynamics on diner.wav, a threshold of 0.75 was chosen. Attack times for
the peak measurement and the limiter triggering are both 0.02 ms in the file diner-Limited_attk1.wav.
Figure 7 shows that the attack time on the envelope measurement is fast enough to detect the waveform
transients, and the attack time on the limier is fast enough to suppress them. However, listening to the
audio, there is noticeable distortion caused by the limiter when it suppresses the highest peak. In a second
file, diner-Limited_attk2.wav, the attack time for limiter triggering was chosen instead to be 0.15 ms.
The result is more transparent, however, it can be seen from the plot that many transients have slipped
through without being limited. The release times are more gradual to facilitate a return to unity gain as the
peak decays. Release time for peak measurement is 5ms and release time for gain adjustment is 50ms for
both files.
Limiting was performed on TranSiberian_Drums.wav with a threshold of 0.75, attack times of 0.02ms,
peak measurement release of 1ms and release time for gain adjustment of 20ms. The hard limiting
technique worked more effectively on the drum track, suppressing all registered transients that were
detected above the threshold, and doing so without causing noticeable distortion. The results are plotted in
Figure 9, Figure 10 and Figure 11.

Tim Perry
V00213455
2009-06-02

Figure 7: Limiter Plots for diner-Limited_attk1.wav. Threshold is 0.75, attack times are both 0.02 ms,
release time for peak measurement is 5ms and release time for gain adjustment is 20ms.

Tim Perry
V00213455
2009-06-02

Figure 8: Limiter Plots for diner-Limited_attk2.wav. Same parameters as Figure 7, but with 0.15ms attack
time for limiter triggering. Here, the attack is too slow for the limiter to function properly (transients slip past
the threshold without being clamped by the limiter in time).

Tim Perry
V00213455
2009-06-02

Figure 9: Limiter Plots for "TranSiberian_Drums.wav". Threshold is 0.75, attack times are both 0.02 ms,
release time for peak measurement is 1ms and release time for gain adjustment is 20ms.

Tim Perry
V00213455
2009-06-02

Figure 10: Closer view of a section from Figure 9, highlighting the limiting the occurs on transients that have
amplitude greater than the threshold.

10

Tim Perry
V00213455
2009-06-02

Figure 11: Limiter Static and Dynamic gains in the logarithmic domain for a section of Figure 6.

11

Tim Perry
V00213455
2009-06-02

PART 2: COMPRESSOR/EXPANDER
A compression and expansion dynamic range controller is illustrated as a block diagram in Figure 12.
This system uses an RMS envelope measurement in order to compute the gain factor in the logarithmic
domain (Figure 13) [1].

Figure 12: Block Diagram for Compressor/Expander [1]

Figure 13: RMS measurement for dynamic range controller [1].

Figure 14 shows the results of compression added to Toms Diner. No attenuation has been applied to the
signal when the RMS envelope value is below the threshold. When the RMS envelope crosses the
threshold, compression is applied to the signal according to the static curve. The slope of the static curve
is dependent on the compressor factor:
1
(5)
=1

where =

= is the compression factor (fraction of input level change to output level change).

12

Tim Perry
V00213455
2009-06-02
Unlike the limiter, sharp transients sometimes pass through before the compressor activates. This is
because the RMS averaging time for the envelope is less than the attack time; therefore fast transients are
registered, but intentionally not compressed here (by lowering the attack time, they can be compressed).
This is a strategy that is often used to add weight to drum tracks - the compressor briefly adds gain to the
decaying signal directly after the transient. In this way punchiness is added to the track that the human ear
can perceive (perceiving a slightly longer lasting impact, and louder volumes for low level hits), but the
dynamic elements of the performance are not as drastically flattened.
A similar (but opposite) trend can be seen when expansion is applied to the signals. For the expander, 0 <
R < 1 and therefore the slope S is less than 0. This results in additional gain added to signals with an RMS
envelope level measured to be below the threshold.
While compression squishes the dynamic range (louder signals are reduce such that softer signals become
more comparable in level, and the overall level can be boosted) expansion expands the dynamic range
(signals with levels that land on the expansion static curve are increased in level). In its basic form with
one threshold, an expander increases the dynamic range by making loud signals louder, and leaving soft
signals untouched. Alternatively, an expander could provide a similar function to a compressor if the
expansion was applied between a lower and upper threshold, with the lower threshold just above the noise
floor and the upper threshold at the level where a compressor would normally kick in. The overall effect
will be different than compression, however, as the dynamics of loud signals will not be squished.
Instead, quieter signals will be expanded.
When compressing diner, a ratio of 6:1 (higher than typically used for natural sounding vocals) was
used in order to make the effects of squishing the dynamic range noticeable. The threshold was set to 0.6,
such that only the louder elements of the performance are brought down in level. RMS averaging time
was chosen to be 0.1ms, which is faster than typical RMS averaging. It was found that the faster
averaging time was desirable to complement the fast compressor attack time of 2ms that was chosen. This
provides noticeable gain reduction to only the loud elements of the performance, so that the compressor
may be compared with the limiter with similar parameters. The release time was chosen to be 100ms to
prevent compressor pumping.
Figure 14 shows that while the loud portions are being suppressed, some transients receive insignificant
(or no) compression as the attack time is slower than that of the limiter. Additionally, since attenuation is
applied at a ratio of 6:1 (as opposed to :1 for the limiter), the signal level is not forced down to the
threshold as it is while using a brick wall limiter.
The results of expansion on Toms Diner are shown in Figure 15 and Figure 16. A ratio of 0.45:1 was
used with a threshold of 0.5, RMS averaging time 0.1ms, attack time 20ms and release time 75ms. When
the amplitude of a signal crosses the threshold, it is increased instead of attenuated. The expander
operated smoothly, making loud signals louder, and therefore increasing the dynamic range. This can be
heard while listening to the resulting audio track louder parts jump out more.

13

Tim Perry
V00213455
2009-06-02

Figure 14: Compressor applied to "diner.wav". Compression Ratio 6:1, threshold 0.6, RMS averaging time
0.1ms, attack time 2ms, release time 100ms.

14

Tim Perry
V00213455
2009-06-02

Figure 15: Expander effects on 'diner.wav'. Ratio 0.45:1, threshold 0.5, RMS averaging time 0.1ms, attack
time 20ms, release time 75ms.

15

Tim Perry
V00213455
2009-06-02

Figure 16: Closer view of expansion effects on a section of diner.wav

16

Tim Perry
V00213455
2009-06-02
More compression ratio was used on the drum track, with a ratio of 8:1 and a low threshold of 0.3. The
performance, which is originally quite dynamic, is noticeably flattened to a more consistent level. The
RMS averaging time was once again 0.1ms, and the attack time was 5ms in order to let a little more of the
transients through (typically with drum applications the attack time will be higher than this, but the
purpose here is to visually illustrate, the gain reduction). The release time is longer, at 150ms. Its
important to have a sufficient release time with percussive tracks, as the gain should not jump right back
up after a hit, as the natural decay of the hit is occurring during this time. The dynamic gain plots in
Figure 17 illustrate this slow release, in contrast with the reasonably fast attack.

Figure 17: Compression Effects on "TranSiberian_Drums.wav". Ratio 8:1, threshold 0.3, RMS averaging
time 0.1ms, attack time 5ms, release time 150ms.

17

Tim Perry
V00213455
2009-06-02
The expander effects on TranSiberian_Drums-Expanded.wav dont significantly come into play until
the loudest part of the track, where dynamic changes are most apparent. The ratio (0.5) was carefully
chosen to expand only the loudest tom and snare hits. This occurs in a section where I originally intended
the toms to have a dynamic swell while programming the midi velocities.

Figure 18: Expansion Effects on "TranSiberian_Drums.wav". Ratio 0.5:1, threshold 0.3, RMS averaging time
0.1ms, attack time 5ms, release time 150ms.

18

Tim Perry
V00213455
2009-06-02

PART 3: NOISE GATE


The block diagram of a noise gate is displayed in Figure 19. If the input level falls below the noise gate
low threshold, the noise gate sets the input to the time constant system to zero [1]. When the high
threshold is again reached, the gate begins deactivating. The noise gate uses peak measurement to
determine if a signals level crosses either of the thresholds, and fades the gain factor in or out according
to the attack and release times.

Figure 19: Noise Gate Block Diagram [1].

Many interesting results were obtained while applying the noise gate to the drum track. Since the drums
were already mixed together, the gate could not be used in a practical manner to help isolate drum voices,
which in a real world application would involve gating microphone bleed from other drums/cymbals.
Also, there was not a noticeable noise floor to gate on either the drum track or Toms Diner. As a result,
the noise gate was tested by having it close and open in sympathy with the snare drum (and anything else
loud enough). Due to the longer release times used, the after effects of gating are always apparent (the
sound directly preceding the hit that caused the gate to open will be heard). This made for some
interesting rhythmic effects (that were entirely un-natural sounding when the high and low thresholds
were above 0.4.
In TransDrums-Gated_150msRT.wav and TransDrums-Gated_75msRT only the snare activates the
upper threshold (opening the gait) until the most dynamic part and loudest. During this loud section, the
gate stays open (Figure 21). It took some experimenting to with the thresholds and the attack, release,
and hold times to achieve this. Figure 21 also shows that if the gate is activated for long enough, the
signal will fade to zero and the hold time will come into effect. This is in contrast with Figure 21, where
the hold time never comes into effect.
TransDrums-Gated_lothresh.wav (Figure 21) uses a low threshold of 0.1 and a high threshold of 0.2 to
suppress only the very low level signal between hits. The effect cannot be heard until the end of the track,
when the hits become separated. The result limiter pumping that adds a bouncing feel to the drum hits.
A much more extreme version of this can be heard in TransDrums-Gated_pump.wav, where the low
and high thresholds are 0.4 and 0.5 respectively.

19

Tim Perry
V00213455
2009-06-02
Many attempts to have a noise gate clamp down on only the distorted click in were attempted on Toms
Diner. Since there is a brief silence before the click, the intention was to add a noise gate with a very
low lower threshold but relatively long release and hold times. The goal was to have the gate close right
before the click, stay shut during the click, and open right after. This was done successfully, however, not
without negatively affecting the other audio in the track (since the thresholds are universal for the
duration of the track).
As an alternative, an attempt to set only the quietest part of the vocalists performance to zero gain was
attempted. High attack, release, and hold times were used after much experimentation, as they provided a
smoother transition from loud to silent and vice versa. A large difference between the low and high
threshold was used so that when the signal was gated, it would not re-open until a significantly louder
signal reached and crossed the high threshold. The parameters used were as follows: Lo thresh = 0.1, Hi
thresh = 0.6, Attack Time = 400ms, Release Time = 300ms, Hold Time = 400ms (Figure 23).

20

Tim Perry
V00213455
2009-06-02

Figure 20. Effects of low level noise gating on TranSiberian_Drums.wav. Lo thresh = 0.1, Hi thresh = 0.2,
Attack Time = 20ms, Release Time = 150ms, Hold Time = 20ms. Corresponding audio track for the output is
Trans_Drums-Gated_lothresh.

21

Tim Perry
V00213455
2009-06-02

Figure 21: Effects of noise gating on TranSiberian_Drums.wav with equal release time and hold time. Lo
thresh = 0.4, Hi thresh = 0.5, Attack Time = 15ms, Release Time = 150ms, Hold Time = 150ms.
Corresponding audio track for the output is TransDrums-Gated_150RT.wav.

Figure 22: Dynamic gain ratio corresponding Figure 21.

22

Tim Perry
V00213455
2009-06-02

Figure 23: Effects of noise gating on "diner.wav". Lo thresh = 0.1, Hi thresh = 0.6, Attack Time = 400ms,
Release Time = 300ms, Hold Time = 400ms.

23

Tim Perry
V00213455
2009-06-02

24

Tim Perry
V00213455
2009-06-02

PART 4: VIBRATO
Repeat the vibrato exercise (Assignment 3 part 4) using a real instrument such as a
trumpet or flute. Post both the original sound file (with no vibrato) and the
processed file. Choose the vibrato parameter (depth, rate) to yield a pleasing sound.

The vibrato effect was implemented using a fractional delay line with a linear interpolation algorithm. For
an input signal x(n), a delay of M samples plus a fractional delay (to achieve a no integer value of the
sampling interval) is [1]:
= + ,

0 1

Figure 24: Fractional delay line with interpolation

The Matlab code uses linear interpolation:


= + 1 + 1
The fractional delay is determined by modulating M, the samples of delay. An oscillator determines a
non-integer delay scalar (Modulate, as depicted below) by oscillating with a frequency equal to the
vibrato rate. M, however, must be an integer. Therefore, M is interpolated modDelay by rounding down to
the nearest integer, as shown below in the Matlab code fragment (see appendix for full code). The
fractional delay is the difference between the modulated delay and the integer delay. Using the fractional
delay, smooth sounding pitch variations can be created.
WidthEnvelope = sin(widthFreq*2*pi*n); % vibrato width envelope
Modulate = WidthEnvelope*cos(modFreq*2*pi*n); % oscillating pitch variation scaler
modDelay = 1 + delay*(1 + Modulate);
intDelay = floor(modDelay); % round down to nearest integer -->
% intDelay = n-M
(M = samples of delay)
frac = modDelay - intDelay; % fractional delay (between samples)

In attempt to achieve a somewhat natural vibrato effect, a vibrato frequency of 4.2 Hz was used (typical
slow vibrato for an instrument or human voice). The maximum delay time chosen was 2.3 ms, which
comes close to 1 semitone in pitch modulation. Additionally, a minimum width was included in the
Matlab code, so that the vibrato width is not constant.

25

Tim Perry
V00213455
2009-06-02
An envelope modulation was applied to the vibrato width, such that the maximum fractional delay in a
single modulation cycle varies compared with the previous. The goal was to make the vibrato swell, or
increase in intensity as the note sustains (and crescendos in the audio example FrenchHrn1.wav), and
then die off toward the end. The effects on the French Horn do not sound completely natural, but it serves
as an interesting example as it incorporates varying dynamics. The vibrato was tried on several other
instrument samples (cello, flute and oboe). While a pure, sine-like flute tone (without much breath noise)
is arguably the easiest to modulate without changing the formants, this vibrato effect does not transfer to
flute in a convincing manner. This is because what we are used to hearing as vibrato on a flute, is actually
more of a tremolo (amplitude variation as opposed to flute variation).
The plots below illustrate that while the spectrum and pitch of both French Horn signals appear to be the
same when plotted, zooming in reveals a subtle difference in the timing of the signals. The close up
waveform plot in Figure 27 confirms that the waveform with vibrato applied is currently leading the
original waveform; at this moment in time, it is perceived to be slightly higher in pitch. By viewing the
signals at different moments in time, as the succeeding images show, the smooth variation due to the
fractional delay is observed. When the signals are time-aligned, the delay is zero and there is no pitch
modulation (this happens at the end of each oscillation in typical a vibrato cycle that only bends above the
reference pitch, and twice for a vibrato cycle that also travels below the reference pitch).

Figure 25: Audacity Pitch plot of original signal (top) and signal with vibrato added (bottom)

Figure 26: Spectrum of original signal (top) and signal with vibrato applied (bottom).

26

Tim Perry
V00213455
2009-06-02

Figure 27: Waveform of original signal (top) and signal with vibrato applied (bottom).

Figure 28: At this moment, the pitch modulation is near maximum as the delay is highest.

Figure 29: Nearly time aligned orignal and vibrato-processed signal. At this moment, the pitch modulation is
almost none since the fractional delay is very small.

27

Tim Perry
V00213455
2009-06-02

REFERENCES
[1]

Udo Zlzer, DAFX. John Wiley & Sons, 2002.

28

Tim Perry
V00213455
2009-06-02

APPENDIX A
Part 1 Matlab Code (Limiter)
%==========================================================================
% Limiter.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 4, Part 1
2009-06-03
%
% Implementation of a limiter using the ideas in the text Figures 5.3 and
% 5.8. Takes an input signal, threshold ratio, attack and release times,
% and sampling frequency as input parameters.
% Outputs the adjusted signal, static gain f(n), dynamic gain g(n), and the
% envelope (peak level detection
%==========================================================================
function [y g f x_peak] = Limiter(x, thresh_ratio, attack, release, fs)
%------------initialize local parameters-------------Slope_dB = 1;
%slope factor for static function in dB
T = 1/fs;
%sampling period
AT = 1-exp(-2.2*T./attack) %attack time for given sampling period
RT = 1-exp(-2.2*T./release) %release time for given sampling period

Thresh_amp = thresh_ratio*max(abs(x)); %signal amplitude @ threshold level


Threshold_dB = log10(Thresh_amp);
x_peak = zeros(size(x));
%initialize peak level envelope
f = ones(size(x));
%default static gain
g = zeros(size(x));
%defailt dynamic gain
%-----------------------------------------------------------------% side chain processing on input sample followed by gain adjustment
%-----------------------------------------------------------------for n=2:length(x);
%-----peak level measurement stage (envelope detector/follower)----delta = abs(x(n))-x_peak(n-1); %detects if signal level is increasing
if (delta < 0)
delta = 0;
%if previous peak value greater, apply no adjustment
end;
x_peak(n) = delta.*AT(1) + x_peak(n-1)*(1 - RT(1)); %determine envelope of x
x_peakdB = log10(x_peak(n));
%-------limiter triggering (triggers for signals above threshold)----if (x_peak(n) >= Thresh_amp)
% determine static gain f = 10^(-LS*(X-LT))
f(n) = 10^(-Slope_dB*(x_peakdB - Threshold_dB)); %static gain in dB
% determine dynamic gain when attacking
g(n) = (1 - AT(2))*g(n-1) + AT(2)*f(n);
else %(x_peak(n-1) > Thresh_amp)&&(x_peak(n) < Thresh_amp)
%---------------------limiter releasing -------------------------g(n) = (1 - RT(2))*g(n-1) + RT(2)*f(n); % dynamic gain during release
end;
end;
y = x.*g;
f_log = log10(f);
g_log = log10(g);

%gain adjusted output (not real time)

29

Tim Perry
V00213455
2009-06-02
%==========================================================================
% a4pt1_Limiter.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 4, Part 1
2009-06-03
%
% Tests Limiter.m function on two sound files (voice and drums)
% Plot the static gain f(n) and dynamic gain g(n), along with the input
% waveform, level measurement and output waveform
%==========================================================================
clear all;
close all;
%-----------------------------------------% Limiter Input Parameters
%-----------------------------------------thresh_ratio = 0.70;
t_AT = [0.02e-3 0.02e-3]; % attack time (peak measurement and triggering)
t_RT = [1e-3 20e-3];
% release time(peak measurement and triggering)
% Input Audio
%wavfile = 'diner.wav';
wavfile = 'TransSiberian_Drums.wav';
[x fs nbits] = wavread(wavfile);
%
%
%
%

Sum mono-compatible stereo files to mono


xL = x(:,1);
xR = x(:,2);
x =(xL + xR)/2;

% For stereo files that are not mono-compatable without significant comb
% filtering, use only left channel
x = x(:,1);
% Apply Limiting
[y g f x_peak] = Limiter( x, thresh_ratio, t_AT, t_RT, fs );
%-------------------------------------------% Limiter Plots
%-------------------------------------------%min_Sample = round(length(x)*0.70);
min_Sample = 3.12e5;
Nsamples = min_Sample + length(x)/15;
samples = linspace(0,Nsamples,Nsamples);
figure(1)
subplot(5,1,1);
hold on;
plot(x);
%stem(samples, x,'.','b-','MarkerSize',11);
plot(thresh_ratio*max(x)*ones(size(x)), 'r');
grid on;
axis([min_Sample, Nsamples, 1.1*min(x(1:Nsamples)), 1.1*max(x(1:Nsamples))]);
ylabel('x(n)')
title('Input Signal x(n) (blue) and Limiter Threshold(red)')
hold off;
subplot(5,1,2);
hold on;
plot(x_peak);
plot(thresh_ratio*max(x)*ones(size(x)), 'r');
hold off;

30

Tim Perry
V00213455
2009-06-02
grid on;
axis([min_Sample, Nsamples, 0, 1.1*max(x_peak(1:Nsamples))]);
ylabel('x_peak(n)')
title('Envelope of x(n)')
subplot(5,1,3);
plot(f);
grid on;
axis([min_Sample, Nsamples, 0, 1.1]);
ylabel('f(n)')
title('Static Limiter Gain f(n)')
subplot(5,1,4);
plot(g);
grid on;
axis([min_Sample, Nsamples, 0, 1.1]);
ylabel('g(n)')
title('Dynamic Limiter Gain g(n)')

subplot(5,1,5);
hold on;
plot(y);
plot(thresh_ratio*max(x)*ones(size(x)), 'r');
axis([min_Sample Nsamples min(x(1:Nsamples)) max(x(1:Nsamples))]);
grid on;
ylabel('y(n)')
title('Output Signal y(n) (Limited)')
xlabel('n');
hold off;
%-----------------------------------------% Output File
%-----------------------------------------% name output file
file_out=strcat(wavfile(1:length(wavfile)-4),'-Limited');
% write output audio file
wavwrite(y, fs, nbits, file_out);

wavplay(x, fs);
pause(1);
wavplay(y, fs);

%play input
%pause for 3 seconds
%play processed output

31

Tim Perry
V00213455
2009-06-02

Part 2 Matlab Code (Compressor/Expander)


%==========================================================================
% CompExp.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 4, Part 2
2009-04-03
%
% Implementation of a Compressor/Expander using the ideas in Zolzer's DAFX.
% Takes an input signal, threshold, compression ratio, attack and release
times,
% and sampling frequency as input parameters.
% Outputs the adjusted signal, static gain f(n), dynamic gain g(n), and the
% envelope (peak level detection
%==========================================================================
function [y g_log f_log xd] = CompressExp(x, thresh_ratio, comp_ratio,
attack, release, fs)
%------------initialize local parameters-------------T = 1/fs;
%sampling period
AT = 1-exp(-2.2*T./attack) %attack time for given sampling period
RT = 1-exp(-2.2*T./release) %release time for given sampling period
TAV = 1-exp(-2.2*T./attack) %averaging time time for given sampling period
%for RMS measurement, TAV = AT(1)
Slope_log = 1 - (1/comp_ratio); % slope in logarithmic domain
xd = zeros(size(x));
f = ones(size(x));
g = zeros(size(x));

%initialize envelope
%default static gain
%defailt dynamic gain

%-----------------------------------------------------------------% side chain processing on input sample followed by gain adjustment


%-----------------------------------------------------------------%----------------RMS level measurement--------------xd=filter(TAV(1),[1 (1-TAV(1))],x.*x);
xd_log = log10(xd);

% for n=2:length(x)
%
delta = (x(n)^2)-xd(n-1); %detects if signal level is increasing
%
if (delta < 0)
%
delta = 0;
%if previous peak value greater, apply no adjustment
%
end;
%
%xd(n) = delta.*AT(1) + xd(n-1)*(1 - RT(1)); % peak measurement
%
xd(n) = delta.*TAV(1) + xd(n-1); % rms measurement
% end;
%-------------- threshold -----------Thresh_amp = thresh_ratio*max(xd); %signal amplitude @ threshold level
Threshold_log = log10(Thresh_amp);
%------------ static curve calculation------

32

Tim Perry
V00213455
2009-06-02
% h = xd/max(xd);
% f = h.^comp_ratio;

% envelope gain as a ratio compared to max level


% static gain

% determine static gain f = 10^(-LS*(X-LT))


for n=2:length(x);
if (xd(n) >= Thresh_amp)
f(n)=10^(-Slope_log*(xd_log(n)-Threshold_log));
else f(n)=1;
end;
end
%--------------- dynamic gain -------------for n=2:length(x)
if (xd(n) >= Thresh_amp)
g(n) = (1 - AT(2))*g(n-1) + AT(2)*f(n); %dynamic gain during attack
else
g(n) = (1 - RT(2))*g(n-1) + RT(2)*f(n); % dynamic gain during
release
end;
end;
y = x.*g;

%gain adjusted output

f_log = log10(f);
g_log = log10(g);

33

Tim Perry
V00213455
2009-06-02

%==========================================================================
% a4pt2_Compressor.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 4, Part 2
2009-06-03
%
% Tests CompExp.m function on two sound files (voice and drums)
% Plot the static gain f(n) and dynamic gain g(n), along with the input
% waveform, level measurement and output waveform
%==========================================================================
clear all;
close all;
%-----------------------------------------% Compressor/Expander Input Parameters
%-----------------------------------------thresh_ratio = 0.6;
comp_ratio = 6;
% R>1 for compresor, 0<R<1 for expander
t_AT = [0.01e-3 10e-3]; % attack times (peak measurement and triggering)
t_RT = [100e-3 100e-3];
% release times (peak measurement and triggering)
% for RMS measurement, t_TAV = t_AT(1)
% Input Audio
wavfile = 'diner.wav';
%wavfile = 'TransSiberian_Drums.wav';
[x fs nbits] = wavread(wavfile);
%
%
%
%

Sum mono-compatible stereo files to mono


xL = x(:,1);
xR = x(:,2);
x =(xL + xR)/2;

% For stereo files that are not mono-compatable without significant comb
% filtering, use only left channel
x = x(:,1);
% Apply Limiting
[y g f xd] = CompressExp(x, thresh_ratio, comp_ratio, t_AT, t_RT, fs );
%-------------------------------------------% Compressor/Expander Plots
%-------------------------------------------if comp_ratio > 1
fileTag = 'Compressed';
else
fileTag = 'Expanded';
end
%min_Sample = round(length(x)*0.70);
%min_Sample = 3.12e5;
min_Sample = 0;
Nsamples = min_Sample + length(x);
samples = linspace(0,Nsamples,Nsamples);
figure(1)
subplot(5,1,1);
hold on;
plot(x);
%stem(samples, x,'.','b-','MarkerSize',11);

34

Tim Perry
V00213455
2009-06-02
plot(thresh_ratio*max(x)*ones(size(x)), 'r');
grid on;
axis([min_Sample, Nsamples, 1.2*min(x(1:Nsamples)), 1.2*max(x(1:Nsamples))]);
ylabel('x(n)')
title('Input Signal x(n) (blue) and Threshold(red)')
hold off;
subplot(5,1,2);
hold on;
plot(xd);
plot(thresh_ratio*max(x)*ones(size(x)), 'r');
grid on;
axis([min_Sample, Nsamples, 0, 1.2*max(xd(1:Nsamples))]);
ylabel('xd(n)')
title('Envelope of x(n)')
hold off;
subplot(5,1,3);
plot(f);
grid on;
axis([min_Sample, Nsamples, -1, 1]);
ylabel('log_1_0f(n)')
title('Static Gain f(n) [logarithmic domain]')
subplot(5,1,4);
plot(g);
grid on;
axis([min_Sample, Nsamples, -1, 1]);
ylabel('log_1_0g(n)')
title('Dynamic Gain g(n) [logarithmic domain]')

subplot(5,1,5);
hold on;
plot(y);
plot(thresh_ratio*max(x)*ones(size(x)), 'r');
axis([min_Sample Nsamples 1.2*min(x(1:Nsamples)) 1.2*max(x(1:Nsamples))]);
grid on;
ylabel('y(n)')
title(strcat(fileTag, ' Output Signal y(n)'))
xlabel('n');
hold off;

%-----------------------------------------% Output File


%-----------------------------------------% name output file
file_out=strcat(wavfile(1:length(wavfile)-4),'-',fileTag);
% write output audio file
wavwrite(y, fs, nbits, file_out);

wavplay(x, fs);
pause(1);
wavplay(y, fs);

%play input
%pause for 3 seconds
%play processed output

35

Tim Perry
V00213455
2009-06-02

Part 3 Matlab Code (Noise Gate)


%==========================================================================
% Limiter.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 4, Part 3
2009-04-03
%
% Implementation of a Limiter using the ideas in Zolzer's DAFX.
% Takes an input signal, thresholds for opening and closing the gate,
% hold time, attack and release times, poles for envelope detecting
% filter, and sampling frequency as input parameters.
% Outputs the gain adjusted signal, static gain f(n), dynamic gain
% g(n), and the envelope (peak level detection).
%==========================================================================
function [y f g xd] = NoiseGate(x,lo_thresh,hi_thresh,t_HT,t_AT,t_RT,a,Fs)
RT=round(t_RT*Fs);
AT=round(t_AT*Fs);
HT=round(t_HT*Fs);
uthresh_cnt=0;
lthresh_cnt=0;

%
%
%
%
%

# of samples for fade


# of samples for fade
hold time in samples
below lower threshold counter
above upper threshold counter

g=zeros(size(x));
f=zeros(size(x));
%------- envelope detection---------------------------h=filter((1-a)^2,[1.0000 -2*a a^2],abs(x));
xd=h;
% envelope to plot
h=h/max(h);
% normalized envelope
%------------------------------------------------------% side chain processing on input
%------------------------------------------------------for n=1:length(h)
%--If < lower threshold or < upper threshold during hold time--if (h(n) <= lo_thresh) || ((h(n)<hi_thresh) && (lthresh_cnt>0))
lthresh_cnt=lthresh_cnt+1;
uthresh_cnt=0;
if lthresh_cnt>HT
if lthresh_cnt>(RT+HT)
g(n)=0;
else

g(n)=1-(lthresh_cnt-HT)/RT; %fades signal to 0


end;
elseif ((i<HT) && (lthresh_cnt==i))
g(n)=0;
else
g(n)=1;
f(n)=1;
end;
%---If > upper threshold or > lower threshold during hold time---elseif (h(n)>=hi_thresh) || ((h(n)>lo_thresh) && (uthresh_cnt>0))
uthresh_cnt=uthresh_cnt+1;
if (g(n-1)<1)

g(n)=max(uthresh_cnt/AT,g(n-1)); % fades signal in


else
f(n)=1;
g(n)=1;
end;
lthresh_cnt=0;

36

Tim Perry
V00213455
2009-06-02
else
g(n)=g(n-1);
uthresh_cnt=0;
lthresh_cnt=0;
end;
end;

y = x.*g;

%==========================================================================
% a4pt3_NoiseGate.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 4, Part 3
2009-06-03
%
% Tests NoiseGate.m function on two sound files (voice and drums).
% Plots the static gain f(n) and dynamic gain g(n), along with the input
% waveform, level measurement and output waveform
%==========================================================================
clear all;
close all;
%-----------------------------------------% Compressor/Expander Input Parameters
%-----------------------------------------lo_thresh = 0.1
% threshold for activating gate
hi_thresh = 0.2
% threshold for deactivating fate
t_AT = 0.15e-3;
% attack time
t_RT = 150e-3;
% release time
t_HT = 50e-3
% hold time
a = .3
% filter coefficient for envelope detector

% Input Audio
%wavfile = 'diner.wav';
wavfile = 'TransSiberian_Drums.wav';
[x Fs nbits] = wavread(wavfile);
%
%
%
%

Sum mono-compatible stereo files to mono


xL = x(:,1);
xR = x(:,2);
x =(xL + xR)/2;

% For stereo files that are not mono-compatable without significant comb
% filtering, use only left channel
x = x(:,1);
% Apply Limiting
[y f g xd] = NoiseGate(x,lo_thresh,hi_thresh,t_HT,t_AT,t_RT,a,Fs);
%-------------------------------------------% Noise Gate plots
%-------------------------------------------%min_Sample = round(length(x)*0.70);
%min_Sample = 3.12e5;
%min_Sample = 1.9e5;
min_Sample = 2.5e5;
Nsamples = min_Sample + length(x)/3;
samples = linspace(0,Nsamples,Nsamples);

37

Tim Perry
V00213455
2009-06-02
figure(1)
subplot(5,1,1);
hold on;
plot(x);
grid on;
axis([min_Sample, Nsamples, 1.2*min(x(1:Nsamples)), 1.2*max(x(1:Nsamples))]);
ylabel('x(n)')
title('Input Signal x(n) (blue)')
hold off;
subplot(5,1,2);
hold on;
plot(xd);
plot(lo_thresh*max(x)*ones(size(x)), 'r');
plot(hi_thresh*max(x)*ones(size(x)), 'g');
grid on;
axis([min_Sample, Nsamples, 0, 1.2*max(xd(1:Nsamples))]);
ylabel('xd(n)')
title('Envelope of x(n) (blue), Lower Threshold (red), Upper Threshold (green)')
hold off;
subplot(5,1,3);
plot(f);
grid on;
axis([min_Sample, Nsamples, 0, 1.5]);
ylabel('log_1_0f(n)')
title('Static Gain f(n)')
subplot(5,1,4);
plot(g);
grid on;
axis([min_Sample, Nsamples, -1.1, 1.1]);
ylabel('log_1_0g(n)')
title('Dynamic Gain g(n) [logarithmic domain]')

subplot(5,1,5);
hold on;
plot(y);
axis([min_Sample Nsamples 1.2*min(x(1:Nsamples)) 1.2*max(x(1:Nsamples))]);
grid on;
ylabel('y(n)')
title(strcat('Output Signal y(n) after Noise Gate'))
xlabel('n');
hold off;

%-----------------------------------------% Output File


%-----------------------------------------% name output file
file_out=strcat(wavfile(1:length(wavfile)-4),'-Gated');
% write output audio file
wavwrite(y, Fs, nbits, file_out);

wavplay(x, Fs);
pause(1);

%play input
%pause for 3 seconds

38

Tim Perry
V00213455
2009-06-02
wavplay(y, Fs);

%play processed output

Part 4 Matlab Code (Vibrato)


%==========================================================================
% a4pt4_Vibrato.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 4, Part 4
2009-06-03
%
% Repeat the vibrato exercise (Assignment 3 part 4) using a real
% instrument such as a trumpet or flute. Choose the vibrato parameters
% (depth, rate) to yield a pleasing sound.
%==========================================================================
clear all;
close all;
%-------------------------------------------------------------% Constants
%-------------------------------------------------------------DelayTime = 2.3;
% Max delay-time in ms (typical 5-10ms)
MinWidth = 0;
% Min delay-time = MinWidth*DelayTime
% (for varying vibrato width envelope)
ModFrequency = 4.2;
% Modulating frequency in Hz (typical 5-14Hz)
%-------------------------------------------------------------% Read Input Sound file, get sampling freq and bit rate
%-------------------------------------------------------------% Input Audio
wavfile = 'FrenchHrn1.wav';
%wavfile = 'Flute2.wav';
[audioIn,fs,BPS]=wavread(wavfile);
numSamples = length(audioIn);
% Get length of file in samples
y = zeros(size(audioIn));
% Matrix for output audio
%-------------------------------------------------------------% Define delayline parameters
%-------------------------------------------------------------delay = round(DelayTime*BPS);
% Unit of Delay in samples
modFreq = ModFrequency/fs;
% Modulation freq in samples
widthFreq = 0.6/numSamples;
% Freq of Vibrato width envelope swell
delayLength = delay + 2*(1 + delay);
% Total delay length
DelayLine = zeros(delayLength,1); % Delay matrix (allocated as vector)
dN = 1;
% increment samples for each loop iteration
%---------------------------------------------------------------% Apply vibrato to audio file using a time-varying fractional delay
% (to interpolate between integer values of the sampling frequency
%---------------------------------------------------------------for n = (1:dN:numSamples-1)
%WidthEnvelope = 1;
WidthEnvelope = sin(widthFreq*2*pi*n); % vibrato width envelope
Modulate = WidthEnvelope*cos(modFreq*2*pi*n); % oscillating pitch variation scaler
modDelay = 1 + delay*(1 + Modulate);
intDelay = floor(modDelay); % round down to nearest integer -->
% intDelay = n-M
(M = samples of delay)
frac = modDelay - intDelay; % fractional delay (between samples)
NextLine = DelayLine(1:delayLength-1);
DelayLine = [audioIn(n); NextLine]; % expands DelayLine ma trix

39

Tim Perry
V00213455
2009-06-02
%-------------------------------------------------------% Linear Interpolation: y(n)=x(n-[M+1])frac+x(n-M)(1-frac)
y(n,1)= DelayLine(intDelay + 1)*frac + DelayLine(intDelay)*(1-frac);
%y(n+1:n+dN) = audioIn(n+1:n+dN);
end
%y = (1/(2.*max(y))).*y;
% lower amplitude to prevent wavrite clipping
% name output file
file_out=strcat(wavfile(1:length(wavfile)-4),'-Vibrato');
wavwrite(y,fs,BPS,file_out); % write new audio file w/ vibrato
wavplay(y,fs);

40

You might also like