%  This script runs an example of a load line analysis for a MOSFET amp
%  to:
%   1. find the operating point for Vgs through iteration
%   2. then compute a table of input (Vgs) and output (Vds)amplitude values
%      to get the transfer characteristic (TC) curve for the amp.
%   3. then apply the resulting TC curve to an input sinusoid with
%      increasing amplitude to illustrate distortion.  The sine wave
%      will be plotted and played in the demonstration.
%  The functions nmos.m and ampdist.m are needed to run this script
%

% Perform quiescent point iteration.
qpoint_iter;

%  Compute corresponding output quiescent voltage amplitude at output
ids = nmos(vds,vgsq,KP,W,L,vto);         % Compute transfer characteristic (TC) curve at quiescent point
[err, inderr] = min(abs(ids - idsll));   %  Find intersection with load line and TC
vdsq = vds(inderr(1)); disp([' The operating point for Vds is ' num2str(vdsq)])   %  Output voltage quiescent
idsq = ids(inderr(1)); disp([' The operating point for Ids is ' num2str(idsq)])   %  Output current quiescent

%  Display text on screen.
disp([' Now compute transfer characteristic between amp input and output '])

%   Now compute array for mapping the input to the output of the amplifier
inarray = [0:.001:2*vgsq];    %   AC input array amplitude sweep range should include quiescent Vgs

%  Loop to compute each point on intersection of load line for input
%  vortage amplitude sweep for output VDS
for karry = 1:length(inarray)
    vgsdcac= inarray(karry);   	%  Vgs level with AC and DC energy
    ids = nmos(vds,vgsdcac,KP,W,L,vto);  % Compute characteristic curve for that vgs
    [err, inderr] = min(abs(ids - idsll));   	%  Find closest point between load line and TC
    outarray(karry) = vds(inderr(1));      	%  Assign VDS as output array correspond to that Vgs value
end

%  Subtract quiesent Vgs offset from input array to result in AC input only component
insigac = inarray - vgsq;

%  Subtract quiesent Vds offset from input array to result in AC output only component
outsigac = outarray - vdsq; 

%  Plot transfer characteristics for AC voltage gain
figure(2)
plot(insigac,outsigac)
xlabel('Input AC voltage Amplitude')
ylabel('Output AC voltage Amplitude')
title('AC transfer characteristic of amplifier')
disp(['Hit any key to continue to hear examples of sounds played through amplifier'])
pause

%  Create a unit 300 Hz sine wave sampled at 8000 Hz and pass it through the amp
 fs = 8000;  	    	%  Sampling frequency
t= [0:3*fs-1]/fs;   	%  Create a time axis for signal for 3 seconds
sigin = sin(2*pi*t*300);   	%  Create unit sine wave
a = [.01, .05, .15];  	%Set up amplitude scales for input voltage

%  Loop to distort and play sound
for k=1:3
    sigout = ampdist(sigin*a(k),insigac,outsigac);  %  Distort sound by mapping amplitudes through TC

    %  Plot original and amplified signal on same scale to observe distortion
    figure(2+k); plot(t(1:100),sigin(1:100)/max(abs(sigin)),'r',t(1:100),-sigout(1:100)/max(abs(sigout)),'b')
    title([' Compare Scaled Input (red) at amplitude ' num2str(a(k)), ' output (blue) for Distortion'])

    %  Play both sounds consecutively
    soundsc([sigin/(max(abs(sigin))+eps), sigout/(max(abs(sigout))+eps)],fs);

    %  Pause for user key press to go on to next sound if not at the end
    if k~=3
        disp(['Hit any key to continue to next sound'])   
        pause
    end
end
