image thumbnail
from Pulse code Modulation by Aditya
PCM on a sine wave and a .wav file for demonstration of various processes done during PCM.

verify_pcm_next.m
%%%%  To perform & verify Pulse Code Modulation on a .wav file     %%%%

%%%%%%%%%%    No Copyright (NoC) of Aditya Kumar     %%%%%%%%%%%%%%%%%%%%
% Everyone is permitted to copy and distribute copies of this code  % 






clc 
close all
clear all

choice=0;


while(choice~=9)                                                            %Exit from menu
choice=menu('Pulse code modulation','Process input parameters','Plot Input Signal','Sample','Quantize','Encode','Decode','Play original','Play decoded','Quit');

switch choice
case 1
    clc    
    close all
    clear all
    choice=1;
    
    h1='o';
    h2='o';
    h3='o';
    h4='o';
    h5='o';
   tic; 
 %==========================PCM parameters=========================
prompt={'Enter n value for n-bit PCM','Enter no. of samples/sec'};
dlg_title='PCM Parameters';
num_lines=1;
def={'8','8000'};
options.Resize='on';
answer=inputdlg(prompt,dlg_title,num_lines,def,options);

% Conversion from string to number required
disp('Processing input data........');
word_length=str2double(answer{1});
fs=str2double(answer{2});

%=============To generate input signal================================

%word_length=4
%fs=8000

[input_sig orgnal_sampl_freq]=wavread('z3.wav');


%========Used later to create a window using 'figure' function========
scrsz = get(0,'ScreenSize');                                                %get dimension of screen


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

[a,~]=size(input_sig);
time=(a/orgnal_sampl_freq);
fs=round(fs*time);
  
%===================SAMPLING======================================



samples=round(linspace(1,a,fs));                                               %To get n samples we divide data by n-1 so to get n points(samples)    %Input signal divided into samples with each sample separated by sample_size
sampled_signal=zeros(1,fs);                                                 
index=1;

for i=samples
        
    sampled_signal(index)=input_sig(i);
	index=index+1;
    
end


%===========Begin Quantization==============================
vmax=.5;                                                                     %get upper limit of quantization
vmin=-0.5;                                                                    %get lower limit of quantization
lsb=(vmax-vmin)/((2^word_length)-1);                                        %concept-if we divide a line segment in 2 parts  we get three points
levels=vmin:lsb:vmax;                                                     %generate level vector

partition=(vmin-(.5*lsb)):lsb:(vmax+(.5*lsb));                              %introduce +(-)1/2*LSB into levels
[~,index_levels]=size(levels);

%========generate quantized value out of sample data =========

quantiz_signal=zeros(1,index-1);                                            %index-1??? see previous for loop, there index value exceeds size of sampled_signal in the last iteration

for i=1:index-1                                                             %to increment the sampled_signal vector
 
    for j=1:index_levels                                                    %to increment the 'partition' & 'levels' vectors
  %============check if input is less than vmin============================================================
        if (sampled_signal(i)<partition(1))                                 %Compare sample with upper and lower partition of a level
                                                                            %if sample is between partitions, give that value of level to 
                                                                            %the quantize_signal array at the index equal to that of sample.
             quantiz_signal(i)=vmin;                                        %This will generate quantized array of same size of sample's array
             bin_val=dec2bin(0,word_length);                                %for example- In 4-bit PCM quantize level 1 corresponds to 0x0 & level 16 is eqv to 0xf         
         
              
                                                                            %Following commands to arrange string bits columnwise and put it at appropriate index of data stream
         
              val_rearrange=bin_val(:);                                     %Make it i:1 matrix 
              rearrange_index=((i-1)*word_length)+1;                        %Example- for 4 bit insert at 1st,5th,9th,13th..index
              data_stream(rearrange_index:(rearrange_index+word_length-1),1)=val_rearrange;
        end
 %==============check if input is greater than vmax===========================================================
        if (sampled_signal(i)>partition(end))
            
            quantiz_signal(i)=vmax;
             bin_val=dec2bin((2^word_length)-1,word_length);                %for example- In 4-bit PCM quantize level 1 corresponds to 0x0 & level 16 is eqv to 0xf         
         
              
                                                                            %Following commands to arrange string bits columnwise and put it at appropriate index of data stream
         
              val_rearrange=bin_val(:);                                     %Make it i:1 matrix 
              rearrange_index=((i-1)*word_length)+1;                        %Example- for 4 bit insert at 1st,5th,9th,13th..index
              data_stream(rearrange_index:(rearrange_index+word_length-1),1)=val_rearrange;
        end
 %=========================================================================       
        
        if (sampled_signal(i)>=partition(j))
             if (sampled_signal(i)<partition(j+1))
                quantiz_signal(i)=levels(j);
       
                
 %=====Simultaneously generating binary stream for each quantized value====
              bin_val=dec2bin(j-1,word_length);                             %for example- In 4-bit PCM quantize level 1 corresponds to 0x0 & level 16 is eqv to 0xf         
         
              
                                                                            %Following commands to arrange string bits columnwise and put it at appropriate index of data stream
         
              val_rearrange=bin_val(:);                                     %Make it i:1 matrix 
              rearrange_index=((i-1)*word_length)+1;                        %Example- for 4 bit insert at 1st,5th,9th,13th..index
              data_stream(rearrange_index:(rearrange_index+word_length-1),1)=val_rearrange;
              
            
                         
                
             end
        end
        
    end
end
%==========================================================================

[size_data,~]=size(data_stream);

%=================create Encoded data stream array ========================
%==============Encoded according to Natural Binary Coding==================
dec_val=zeros(size_data,1);
for i=1:size_data
dec_val(i,1)=str2double(data_stream(i,1));                                  %cant plot string array. so convert to numbers
end


%===========================Decoding=======================================

k=1;

for i=1:length(data_stream)/word_length                                     %Arrange data stream into word_length sized binary strings for conversion
    for j=1:1:word_length
        bin_rearrange(i,j)=data_stream(k);                                  %Ignoring this Warning!!!!
        k=k+1;
    end
end
bin_rearrange
bin_dec=bin2dec(bin_rearrange);
decoded_val=zeros(length(bin_dec),1);
for i=1:length(bin_dec)                                                     %bin_dec contain dec equivalents ranging from 0 to max for the word
decoded_val(i)=levels(bin_dec(i)+1);                                        %therefore dec equivalent 0 corresponds to level 1.
                                                                            %thus get quantized values from level(dec.equiv+1) and store in an array
end


%===========Reconstruction from decoded signal=============================
index=1;
reconst_sig=zeros(a,1);                                                     %reconstructed signal is of same size as input signal
for i=samples
   
    
reconst_sig(i,1)=decoded_val(index,1);
index=index+1;
    
end    

disp('Processing done');
toc;
%==============Various Plot data========================================== 

case 2
h1=figure('Name','Input Signal','NumberTitle','off','Position',[122 scrsz(4)/3 scrsz(3)/2.2 scrsz(4)/2.2]); %Position figure accordingly
plot(input_sig);

    
case 3

h2=figure('Name','Sampled Signal','NumberTitle','off','Position',[scrsz(3)/1.8 scrsz(4)/3 scrsz(3)/2.2 scrsz(4)/2.2]);
stem(sampled_signal);

case 4
if(~ischar(h1))
close(h1);
end
h3=figure('Name','Quantized Signal','NumberTitle','off','Position',[122 1 scrsz(3)/2.2 scrsz(4)]);

stairs(quantiz_signal)
ylim([vmin vmax])
                                                                            %only to customize plot
set(gca,'YTick',vmin:lsb:vmax)



    
case 5
   
  h4=figure('Name','Pulse Code Modulated Stream','NumberTitle','off','Position',[1 scrsz(4)/3 scrsz(3) scrsz(4)/2.5]);

  stairs(dec_val');
  axis([1 1000 -3 4]);
  set(gca,'YTick',-3:1:4);
  set(gca,'YTicklabel',{' ',' ',' ','0','1',' ',' ',' '});
case 6
    if(~ischar(h2))
    close(h2);
    end
    if(~ischar(h4))
    close(h4);
    end
    h5=figure('Name','Decoded Signal','NumberTitle','off','Position',[scrsz(3)/1.8 scrsz(4)/3 scrsz(3)/2.2 scrsz(4)/2.2]);
    plot(reconst_sig);
   % grid on;
    %ylim([vmin vmax])

 case 7
         wavplay(input_sig,orgnal_sampl_freq);
 case 8

     
     
     wavplay(reconst_sig,orgnal_sampl_freq);

end
end
close all



% *****The beauty of Intellect lies in Originality ****************

Contact us