import math
#Baseband cutoff signal fM = 4 kHz
fM = 4 * 10**3;
#White noise power spectral density n
n = 2*10**(-9);
# Part (a)
#Input Signal energy Si = 0.001
Si_a = 0.001;
#No of levels used for PCM Coding M = 8
M_a = 8;
N_a = math.log(M_a,2);
#Input SNR is SNR_ip
SNR_ip = Si_a/(n*fM);
#Output SNR is SNR_op
SNR_op = (2**(2*N_a))/(1 + (2**(2*N_a + 1))*math.erfc((SNR_ip*(1/(2*N_a))))**0.5);
print 'Input SNR for (a) is %.4f'%(10*math.log10(SNR_ip)),' dB'
print 'Output SNR (a) is %.4f'%(10*math.log10(SNR_op)),' dB'
# Part (b)
#Input Signal energy Si = 0.001
Si_b = 0.001;
#No of levels used for PCM Coding M = 256
M_b = 256;
N_b = math.log(M_b,2);
#Input SNR is SNR_ip_b
SNR_ip_b = Si_b/(n*fM);
#Output SNR is SNR_op_b
SNR_op_b = (2**(2*N_b))/(1 + (2**(2*N_b + 1))*math.erfc((SNR_ip_b*(1/(2*N_b))))**0.5);
#Unfortunately in scilab the function erfc approximates the output value to a larger extent due to which an exact value cannot be obtained.
#The difference in the textbook answer and obatined answer is significant because of converting the answer into dB.
print 'Input SNR for (b) is %.4f'%(10*math.log10(SNR_ip_b)),' dB'
print 'Output SNR for (b) is %.4f'%(10*math.log10(SNR_op_b)),' dB'
# Part (c)
#Input Signal energy Si = 0.01
Si_c = 0.01;
#No of levels used for PCM Coding M = 256
M_c = 256;
N_c = math.log(M_c,2);
#Input SNR is SNR_ip_c
SNR_ip_c = Si_c/(n*fM);
#Output SNR is SNR_op_c
SNR_op_c = (2**(2*N_c))/(1 + (2**(2*N_c + 1))*math.erfc((SNR_ip_c*(1/(2*N_c))))**0.5);
print 'Input SNR for (c) is %.4f'%(10*math.log10(SNR_ip_c)),' dB'
print 'Output SNR for (c) is %.4f'%(10*math.log10(SNR_op_c)),' dB'
import math
#Baseband cutoff signal fM = 4 kHz
fM = 4 * 10**3;
#White noise power spectral density n
n = 2*10**(-9);
# Part (a)
#Input Signal energy Si = 0.001
Si = 0.001;
#No of levels used for PCM Coding M = 8
M = 8;
N = math.log(M,2);
#Input SNR is SNR_ip
SNR_ip = Si/(n*fM);
#Output SNR is SNR_op
SNR_op = (2**(2*N))/(1 + (2**(2*N + 1))*math.erfc((SNR_ip*(3/(10*N))))**0.5);
print 'Input SNR for (a) is ',round(10*math.log10(SNR_ip),4),' dB'
print 'Output SNR (a) is ',round(10*math.log10(SNR_op),4),' dB'
# Part (b)
#Input Signal energy Si = 0.001
Si = 0.001;
#No of levels used for PCM Coding M = 256
M_b = 256;
N_b = math.log(M_b,2);
#Input SNR is SNR_ip_b
SNR_ip_b = Si/(n*fM);
#Output SNR is SNR_op_b
SNR_op_b = (2**(2*N_b))/(1 + (2**(2*N_b + 1))*math.erfc((SNR_ip_b*(3/(10*N_b))))**0.5);
#Unfortunately in scilab the function math.erfc approximates the output value to a larger extent due to which an exact value cannot be obtained.
#The difference in the textbook answer and obatined answer is significant because of converting the answer into dB.
print 'Input SNR for (b) is ',round(10*math.log10(SNR_ip_b),4),' dB'
print 'Output SNR for (b) is ',round(10*math.log10(SNR_op_b),4),' dB'
# Part (c)
#Input Signal energy Si = 0.01
Si = 0.01;
#No of levels used for PCM Coding M = 256
M = 256;
N = math.log(M,2);
#Input SNR is SNR_ip_c
SNR_ip_c = Si/(n*fM);
#Output SNR is SNR_op_c
SNR_op_c = (2**(2*N))/(1 + (2**(2*N + 1))*math.erfc((SNR_ip_c*(3/(10*N))))**0.5);
print 'Input SNR for (c) is ',round(10*math.log10(SNR_ip_c),4),' dB'
print 'Output SNR for (c) is ',round(10*math.log10(SNR_op_c),4),' dB'
import math
#Upper cut off frequecny fb = 3200 Hz
fM = 3200;
#Lower cut off frequecny fl = 300 Hz
fl = 300;
#Data rate fb = 32000 bps
fb = 32000;
#White noise power spectral density n
n = 2*10**(-9);
#Input Signal energy Si = 0.001
Si = 0.001;
#Output SNR is SNR_op
SNR_op = (0.6*(fb/fM)**3)/(1 + (0.3*(fb**2/(fl*fM)))*math.erfc(Si/(n*fb)));
print 'Output SNR is ',round(10*math.log10(SNR_op),4),'dB'
#Data rate fb_n = 32000 bps
fb_n = 2*32000;
#Output SNR is SNR_op_n
SNR_op_n = (0.6*(fb_n/fM)**3)/(1 + (0.3*(fb_n**2/(fl*fM)))*math.erfc(Si/(n*fb_n)));
print 'Output SNR when data rate is doubled is ',round(10*math.log10(SNR_op_n),4),'dB'