tperry_elec484-a4

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

Upload: antoniopallone

Post on 27-Jan-2016

217 views

Category:

Documents


3 download

DESCRIPTION

Tperry_Elec484-A4

TRANSCRIPT

Page 1: Tperry_Elec484-A4

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

Page 2: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

1

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

Page 3: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

2

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]

Page 4: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

3

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.

Page 5: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

4

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 = %*+.+�/-./

Page 6: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

5

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 it’s 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:

01 = −LS�X − LT� + CS�CT − LT) (3)

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.

Page 7: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

6

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

���� = �1 − 7���� − 1� + 78���

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 Tom’s 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.

Page 8: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

7

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.

Page 9: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

8

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).

Page 10: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

9

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.

Page 11: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

10

Figure 10: Closer view of a section from Figure 9, highlighting the limiting the occurs on transients that have

amplitude greater than the threshold.

Page 12: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

11

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

Page 13: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

12

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 Tom’s 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 −1

� (5)

where � = ∆19

∆1:=

;

;*< is the compression factor (fraction of input level change to output level change).

Page 14: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

13

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 Tom’s 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.

Page 15: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

14

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.

Page 16: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

15

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.

Page 17: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

16

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

Page 18: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

17

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. It’s

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.

Page 19: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

18

The expander effects on “TranSiberian_Drums-Expanded.wav” don’t 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.

Page 20: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

19

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 signal’s 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 Tom’s 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.

Page 21: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

20

Many attempts to have a noise gate clamp down on only the distorted click in were attempted on Tom’s

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 vocalist’s 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).

Page 22: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

21

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”.

Page 23: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

22

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.

Page 24: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

23

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.

Page 25: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

24

Page 26: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

25

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]:

���� = ��� − => + 8?�&@�, 0 ≤ 8?�& ≤ 1

Figure 24: Fractional delay line with interpolation

The Matlab code uses linear interpolation:

���� = ��� − => + 1@�8?�& + ��� − >��1 − 8?�&�

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.

Page 27: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

26

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).

Page 28: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

27

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.

Page 29: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

28

REFERENCES

[1] Udo Zölzer, DAFX. John Wiley & Sons, 2002.

Page 30: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

29

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; %gain adjusted output (not real time)

f_log = log10(f);

g_log = log10(g);

Page 31: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

30

%==========================================================================

% 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;

Page 32: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

31

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); %play input

pause(1); %pause for 3 seconds

wavplay(y, fs); %play processed output

Page 33: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

32

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)); %initialize 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 %------------------------------------------------------------------

%----------------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------

Page 34: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

33

% h = xd/max(xd); % envelope gain as a ratio compared to max level % f = h.^comp_ratio; % 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);

Page 35: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

34

%==========================================================================

% 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);

Page 36: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

35

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); %play input

pause(1); %pause for 3 seconds

wavplay(y, fs); %play processed output

Page 37: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

36

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); % # of samples for fade

AT=round(t_AT*Fs); % # of samples for fade

HT=round(t_HT*Fs); % hold time in samples

uthresh_cnt=0; % below lower threshold counter

lthresh_cnt=0; % 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;

Page 38: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

37

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);

Page 39: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

38

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); %play input

pause(1); %pause for 3 seconds

Page 40: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

39

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

Page 41: Tperry_Elec484-A4

Tim Perry

V00213455

2009-06-02

40

%--------------------------------------------------------

% 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);