Sunday, December 15, 2013

Final Post: Matlab Simulation Results

Hey guys, here is the final post for this semester project.

As I mentioned in my last post, I needed to do some Matlab simulations to wrap this thing up. It took a long time and a lot of help from my professor and a kind graduate student at school but I got some pretty cool results!

I had already decided to utilize the Matlab function "butter" and "filter" to accomplish the task at hand, that being to vary the cutoff frequency of the filter as the signal is passed through the circuit.

Here's how these two functions filter a signal. "butter" receives a cutoff frequency and generates two filter coefficients, named a and b. "filter" takes these coefficients and applies them to a signal. The problem is that "butter" only generates two coefficients for one specific cutoff frequency. No good if I want a changing cutoff frequency. Well I was thinking I would need to implement a loop of some kind to generate a whole heap of coefficients. This is exactly what my professor advise! Yay for having some intuition for this stuff...

So once I implement a loop to generate (and store in a vector, by the way) a whole heap of coefficients, I need to apply all of these to "filter." I needed to know how filter worked. Well Matlab's handy dandy "help" function proved useful as it explained that the function, "filter," is nothing more than a difference equation. That equation being (for a 1st order butterworth filter):

     a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) - a(2)*y(n-1)

I have no practical understanding of how or why this equation filters a signal but it's what Matlab said and I was going to roll with it. Haha!

So all that was left to do is create another loop that would apply all of those coefficients from "butter" and playback the resulting sound.

So I am not very familiar with Matlab. I've had a few projects at school but I haven't spent extensive time in it. I knew I needed loops but I wasn't sure how to write them! Thankfully a kind friend at school offered to help. Together, we were able to write code that receives an input wave file, applies a filter with a linearly increasing cutoff frequency, and play back the sound. I flipped out when it worked. Who knew you could do this kind of stuff with Matlab? I didn't till now.

Once the ball was rolling I wanted to do some cool stuff like vary the cutoff frequency sinusoidally. Turns out it was not that hard to do! At first, all I did was stick a sine function in front of the cutoff frequency variable inside the loop. However, sine would eventually generate negative frequencies which "butter" did not like. After a minute of thinking I figured it would be easiest to simply get the absolute value of the sine so those negatives would go away. Bam! That worked just fine.

So, my final code varied the cutoff frequency three different ways. My code also generated plots of those variations and created wave files to playback. Below are those results and the code.

Here is the original guitar clip I recorded direct into my Digital Audio Workstation (Reason 6.0!) and exported as a wave file: https://soundcloud.com/visorakmark/ampharos-original-unfiltered

First, I simply "opened up" the filter as time passed.
Here is the resulting sound: https://soundcloud.com/visorakmark/ampharos-linear-increase




Then I applied a sinusoid to the cutoff frequency.
Here is the resulting sound: https://soundcloud.com/visorakmark/ampharos-sinusoidal-variation



Finally, I applied an increasing sinusoid to the cutoff frequency.
Here is the resulting sound: https://soundcloud.com/visorakmark/ampharos-increasing-sinusoid



And here's the code. Note if you try to run this it will take several minutes to execute.

------------------------------------------------------------


% Ampharos_LPF
% This program applies an "opening" low pass filter to a wave file,
% meaning the cutoff frequency of the filter is changed as the filter
% is applied to the signal. This results in a "fading in" of the sound.
% Note that this is not the same as overall signal gain control, but a
% filtering of higher frequencies. As the wave file is played, more higher
% frequencies are allow to pass through and the sound "opens up." The
% cutoff Frequency is also vaired sinusoidaly and varied with an increasing
% sinusoid.
%
% These processes are accomplished through a "brute force" implementation of
% the Matlab function called "filter." "filter" applies two variables to a
% signal. These variables are generated using the Matlab function
% "butterworth." "butterworth" recieves a cutoff frequency and generates two
% variables that can be applied to a signal to filter specific
% frequencies.

% This program requires the cutoff frequency of the filter to
% change with time. "butter" and "filter" cannot accomplish this task
% alone. Considering 'butter" generates two filter variables for a
% specific frequency, a loop is used to generate and store multiple filter
% frequencies. A loop is then used to apply the generated cutoff
% frequencies to the signal. Finally, the signal is played back.

%This process is executed three seperate times, each time applying a
%different type of cutoff frequency variation.


% The wav file is read into Matlab
[x fs]=wavread('MarkGuitar.wav');

%play original signal
sound(x,fs)

%The butterworth loop variables are set up
count=0;
minFc=1;
inc=1;
maxFc=(1+minFc+length(x).*inc);

    %This section of code applies a linearly increasing filter to the signal
    for Fc=minFc:inc:maxFc

        count=count+1

        w = Fc/(2*fs); % Normalized frequency
        [b,a]=butter(1,w,'low'); %1st order butterworth LPF
        PlotFreq(count)=Fc;

        % This loop has been generalized to take any order butterworth filter,
        % hence the length(a) and length(b). coefA and coefB also store the
        % recieve Fc and w for reference.
        coefA(count,1:length(a))=a;
        coefA(count,length(a)+1)=Fc;
        coefA(count,length(a)+2)=w;

        coefB(count,1:length(b))=b;
        coefB(count,length(b)+1)=Fc;
        coefB(count,length(b)+2)=w;

    end
 
% Access filter variables
Avalues=coefA(:,1:2);
Bvalues=coefB(:,1:2);

% Apply filter variables to signal x.
Y=getOut(Avalues,Bvalues,x,fs);

% Plot Fc vs count to vizualize how the cutoff frequency was varied during
% variable generation
figure(1)
plot(PlotFreq)
title('Linearly Increasing Cutoff Frequency Variation');
xlabel('time');
ylabel('cutoff frequency');

%Play filtered signal
sound(Y,fs)






%Reset variables for second filtering implementation
count=0;
minFc=1;
inc=1;
maxFc=(1+minFc+length(x).*inc);

    %For constant sinusoidal filtering%
    for i=minFc:inc:maxFc

        count=count+1

        Fc = 20000;
        Fc = abs(sin(0.0005*i))*Fc;
        PlotFreq(i)=Fc;
        w = Fc/(2*fs); % Normalized frequency  w = (sin(count)*w
        [b,a]=butter(1,w,'low'); %1st order butterworth LPF

        % This loop has been generalized to take any order butterworth filter,
        % hence the length(a) and length(b). coefA and coefB also store the
        % recieve Fc and w for reference.
        coefA(count,1:length(a))=a;
        coefA(count,length(a)+1)=Fc;
        coefA(count,length(a)+2)=w;

        coefB(count,1:length(b))=b;
        coefB(count,length(b)+1)=Fc;
        coefB(count,length(b)+2)=w;

    end

% Access filter variables
Avalues=coefA(:,1:2);
Bvalues=coefB(:,1:2);

% Apply filter variables to signal x.
Y=getOut(Avalues,Bvalues,x,fs);

% Plot Fc vs time to vizualize how the cutoff frequency was varied during
% variable generation
figure(2)
plot(PlotFreq)
title('Sinusoidal Cutoff Frequency Variation');
xlabel('time');
ylabel('cutoff frequency');

%Play filtered signal
sound(Y,fs)






%Reset variables for second filtering implementation
count=0;
minFc=1;
inc=1;
maxFc=(1+minFc+length(x).*inc);

    %This section of code applies an increasing sinusoidal filtering to the
    %signal
    for Fc=minFc:inc:maxFc

        count=count+1
        Fc = abs(sin(0.0005*count))*Fc;
        PlotFreq(count)=Fc;
        w = Fc/(2*fs); % Normalized frequency  w = (sin(count)*w
        [b,a]=butter(1,w,'low'); %1st order butterworth LPF

        % This loop has been generalized to take any order butterworth filter,
        % hence the length(a) and length(b). coefA and coefB also store the
        % recieve Fc and w for reference.
        coefA(count,1:length(a))=a;
        coefA(count,length(a)+1)=Fc;
        coefA(count,length(a)+2)=w;

        coefB(count,1:length(b))=b;
        coefB(count,length(b)+1)=Fc;
        coefB(count,length(b)+2)=w;

    end

% Access filter variables
Avalues=coefA(:,1:2);
Bvalues=coefB(:,1:2);

% Apply filter variables to signal x.
Y=getOut(Avalues,Bvalues,x,fs);

% Plot Fc vs time to vizualize how the cutoff frequency was varied during
% variable generation
figure(3)
plot(PlotFreq)
title('Increasing Sinusoidal Cutoff Frequency Variation');
xlabel('time');
ylabel('cutoff frequency');

%Play filtered signal
sound(Y,fs)

------------------------------------------------------------

And here are those functions I called above:

------------------------------------------------------------
function y=FilterApply(a,b,x,y,sigInd,filtInd)

term1(sigInd)=(b(filtInd,1).*x(sigInd))./a(filtInd,1);
term2(sigInd)=(b(filtInd,2).*x(sigInd-1))./a(filtInd,1);
term3(sigInd)=a(filtInd,2).*y(sigInd-1)./a(filtInd,1);

y(sigInd)= term1(sigInd)+term2(sigInd)-term3(sigInd);

------------------------------------------------------------
function Y=getOut(a,b,X,fs)

% This is essentially the Matlab function "filter" but now able to
% recieved multiple filter variables and apply them. Note this function
% utilizes the mathematical definition for the filter function to apply
% the variables to the singal.

% Given
%     signal X (length n)
%     coef matrix a & b
%     fs = 44100
%     signal y previous
%     signal y at n==1

Y=zeros(1,length(X));
filtInd=2;
for sigInd=2:1:length(X)
    out=FilterApply(a,b,X,Y,sigInd,filtInd);
    Y(sigInd)=out(sigInd);
    filtInd=filtInd+1;
end

------------------------------------------------------------

And that's a wrap! Been a great semester of learning. Hope you all enjoyed following along. Perhaps I will continue this project down the road. Who knows. For now I'm going on break and will see you later.

-Mark

Saturday, December 7, 2013

Some Matlab Coding

Hey again readers, spent a couple of hours researching filter simulation in Matlab and got a few things figured out.

Right now my code uploads a wav, applies a 1st order butterworth low pass filter to it, and plays the filtered wav file back. That all is working fine. The challenge I am facing is somehow changing the cutoff frequency while the program is running so the sound "opens up and closes" during playback.

Here's how I'm approaching this right now:

------------

This function samples (at the sample rate, fs) the wav file and stores those samples in the matrix x. x is a 2 by 37000ish matrix that contains a discrete representation of the wav file. I'm currently using a short ringtone for code testing as opposed to a full guitar track.

[x fs]=wavread('Bangarang_Phone.wav');

I then set my cutoff frequency whic for the filter U currently have is 900 hz.

Fc=900;

Then I use a butterworth function to implement a 1st order low pass filter.

w = Fc/(2*fs); % Normalized frequency
[b,a]=butter(1,w,'low'); %1st order butterworth LPF
y=filter(b,a,x); % pass the input signal through the filter

Then play the filtered sound

sound(y,fs)

------------

That's what I have so far. I'm thinking I need to somehow implement a loop and change Fc as the filter is being applied. I just don't know how to do this though. That's for another hour!

More soon,

-Mark

Thursday, December 5, 2013

End of the Semester Matlab Simulation

Hey readers, finals are upon us and time is running out for this semester project. Obviously this thing is not ready to be placed in my amp so I will be writing some Matlab code and simulating what I've got so far.

First. I will simulate how I want the circuit to work. I'm going to record a short guitar track, import it into Matlab, and simulate a low pass filter. I'll vary the resistance to get the sweeping wah-wah effect I'v been looking for.

Next I'm going to simulate how the circuit is currently (not) working. Not entirely sure how to do this yet. We'll see what I can cook up over the week.

Expect one more post from me before the 16th of December!
-Mark

Sunday, November 24, 2013

Road Un-Blocked, Prototype 2 Simulation and Implementation

Hey folks,

Decided to tank the current component values in my design and just try a basic Low-Pass Filter with component values I used more frequently in Circuit II last Spring. Used 470k ohm resistors and 390 nanofarad capacitor. Not surprisingly the circuit worked! Tested it in the lab and in PSPICE. Cutoff Frequency around 900 hz. Unlike the schematic I provided, the voltage source was set to 0.

Prototype 2. V7 is varied to change overall feedback resistance 
Transient Analysis of Prototype 2. Input (Red) of 870 hz. Output (Green). Output is approx 70% of input at calculated cutoff frequency. Behaves as expected.

Frequency response of Prototype 2. Corner Frequency around 900 hz.
Top: Input of 870 hz. Bottom: Output - As you can see the output is attenuated approximately 70% of the input.  Exactly what is expected by the design.
So! I got a simple active LPF to work. Good news.

As I mentioned earlier, the V7 voltage source is what "sets" the "resistance" of the FET. Applying a voltage opens the pathway between the source and drain. Here's the problem. I've learned that for some reason using small resistances for an active LPF does not work. It just doesn't behave like a filter. Not sure why... The current FET I'm using (TIS74) can only vary between 30 to 800 ohms.  Adding 800 ohms to 470000 is not going to make much of a significant change in cutoff frequency. I doubt I would even see noticeable change if I implemented this.

I already tried simulation with the FET resistance on. Quite unsuccessful. Circuit does some weird stuff.  For voltages between 0 and 2.8, I get the output seen above. However, Once V7 is around 3 volts the entire output is shifted down by about 0.4 volts.  I don't know what model transistor PSPICE uses... But I'm thinking it's acting like a switch (like FET's are usually used for). Once a certain point is reached it completely opens/closes the drain/source path. What I'm looking for is a gradual shift in resistance. Since I don't have a TIS74 PSPICE model (and I'm not equipped to program one!) simulation might be futile for this design.

Here's the output with V7 set to 3 volts:

FET biasing voltage set to 3 volts. Basically drops the output by some constant. No good.
I've got a huge test in Power Distribution Systems on Tuesday so I've got to go study for that. We'll come back to this later. I'll see what happens when I add the FET in the actual circuit.

-Mark




Monday, November 11, 2013

Roadblock

Hey folks,

I have spent the last two hours trying to test an active low pass filter. The idea was similar to the passive LPF design: Test a filter without the FET to ensure proper operation and then add an FET. Well I've used four different oscilloscopes, tested multiple op amps, changed my resistors and capacitors, and I still haven't gotten a simple filter to work. WHAT THE HECK? I've got a major test tomorrow and multiple homework assignments to finish tonight so I'll have to come back to this and try again later. Sorry there is nothing exciting to report. I'll simulate the circuit before I come back in for a practical test, hopefully something will have changed. I've checked my circuit tons of times and everything is as it should be. It's possibly just faulty equipment... who knows...

-Mark

Monday, November 4, 2013

Prototype 2 Construction and Testing

Hey readers,

I was hoping to update you guys on my latest prototype last week but other assignments took priority. I did construct and test the circuit you see below but I could not get the circuit to behave as designed.

Prototype 2

Input and Output for Prototype 2

I haven't a clue to exact reason for this strange result but I went ahead and ordered a couple of new components to use (LM471's to be exact) in case something was faulty. Thankfully they arrived swiftly and I plan to retry this week and see what happens.

Expect another post soon!
-Mark

Wednesday, October 2, 2013

Active VCF Design (Part 1)

So I have not fallen off the face of the earth. Been getting in the groove of the semester and haven’t set aside time to write till now. I have some updates to share!

My professor and I agreed to make this Arduino-Filter circuit an active filter. An active filter differs from a passive in that it allows gain. Which basically means the output signal can be bigger than the input signal. This is useful for me in that I don’t want the guitar signal to lose too much voltage going through the VCR stage, therefore I can include a “recovery” stage in my design. Cool!

This means my design needs to include some kind of operational amplifier. The LM471 is an op-amp I am familiar with and what I plan to use in prototyping and possibly final implementation.

So, let's dive into active filters! Below is the schematic of a typical Active Low-Pass Filter. (Courtesy of Wikipedia)



Just as my passive filter design over the summer, I need to integrate an FET into this circuit to make it voltage-sensitive. Now any Average-Joe-Engineering-Student knows from AC Circuit Analysis that the cut-off frequency of this circuit is controlled by the feedback impedance (C and R2) while the gain is set by the ration of R2 to R1. Therefore, the FET will need sit in parallel or series with R2 to vary the feedback resistance.

I failed to understand that last point in my first design. The circuit below isn’t a VCF at all!



In this design, the FET simply acted as a voltage-controlled voltage divider followed by a gain stage. Possibly useful but not what I needed.

I haven't drawn it up in PSPICE yet, but my next design corrected this and has the FET in the feedback section of the circuit. Much better! I'll include some schematics of this better design in my next post.

And we have arrived at my current position! Next step is to simulate, analyze, and implement the circuit  I have to see what happens.

As you saw in the August 27th post, the amplifier is complete! It is now just waiting for the VCF to be installed. If I have time, I would like to include a switch in the amp to select between analog EQ controls and my new VCF, that way I don’t lose the good old-school EQ controls forever with this modification.

I’ll be back with a report on that circuit soon. For now, bye friends!