Modulating audio signals in MATLAB - matlab

I have been trying to modulate and demodulate the default audio signal speech_dft.mp3 in MATLAB using various modulation methods with no luck so far. Here is the code I have written up till this point
clear;
close;
clc;
%% Constants and Initialization
Ac = 1; % Carrier Amplitude
Fc = 5.0e6; % Carrier Frequency
Fs = 20e6; % Sampling Frequency
Kf = 50; % Frequency Deviation
Kp = 75; % Phase Deviation
Beg = 1500; % Sample to begin song from
SongStr = 'speech_dft.mp3'; % Name of the File
Song = audioinfo(SongStr); % Getting Audio Info
L = 100; % Length or number of samples
audio = audioread(SongStr); % Reading the Song
audio = audio(Beg:Beg+L-1,:);
%% Modulating
Wave(:,:,1) = (ammod(audio,Fc,Fs)); % DSB-SC AM Modulation
Wave(:,:,3) = (ammod(audio,Fc,Fs,0,Ac)); % DSB-FC AM Modulation
Wave(:,:,5) = (ssbmod(audio,Fc,Fs)); % SSB-SC Lower Sideband AM Modulation
Wave(:,:,7) = (ssbmod(audio,Fc,Fs,0,'upper')); % SSB-SC Upper Sideband AM Modulation
Wave(:,:,9) = (fmmod(audio,Fc,Fs,Kf)); % FM Modulation
Wave(:,:,11) = (pmmod(audio,Fc,Fs,Kp)); % PM Modulation
%% Demodulating
Wave(:,:,2) = (amdemod(audio,Fc,Fs)); % DSB-SC AM Demodulation
Wave(:,:,4) = (amdemod(audio,Fc,Fs,0,Ac)); % DSB-FC AM Demodulation
Wave(:,:,6) = (ssbdemod(audio,Fc,Fs)); % SSB-SC Lower Sideband AM Demodulation
Wave(:,:,8) = (ssbdemod(audio,Fc,Fs)); % SSB-SC Upper Sideband AM Demodulation
Wave(:,:,10) = (fmdemod(audio,Fc,Fs,Kf)); % FM Demodulation
Wave(:,:,12) = (pmdemod(audio,Fc,Fs,Kp)); % PM Demodulation
%% Output
figure(1);
title('Demodulated')
subplot(3,2,1);
hold on;
plot(Wave(:,1,2));
plot(audio(:,1));
legend('DSB-SC','Original')
title('DSB-SC Demod');
subplot(3,2,2);
hold on;
plot(Wave(:,1,4));
plot(audio(:,1));
legend('DSB-FC','Original')
title('DSB-FC Demod');
subplot(3,2,3);
hold on;
plot(Wave(:,1,6));
plot(audio(:,1));
legend('SSB-Lower','Original')
title('SSB-Lower Demod');
subplot(3,2,4);
hold on;
plot(Wave(:,1,8));
plot(audio(:,1));
legend('SSB-Upper','Original')
title('SSB-Upper Demod');
subplot(3,2,5);
hold on;
plot(Wave(:,1,10));
plot(audio(:,1));
legend('FM','Original')
title('FM Demod');
subplot(3,2,6);
hold on;
plot(Wave(:,1,12));
plot(audio(:,1));
legend('PM','Original')
title('PM Demod');
I have kept the Wave(:,1,2) since I also tried working with audio files having two channels and plotting a single channel is much simpler.
This is the output that I get :
As pretty much obvious from the image, the demodulated output is nowhere close to the original message signal but in some cases looks more like modulated signals. Can somebody tell where my mistake is? Thanks in advance.

Related

Matlab Acoustic Modem with QAM modulation

I am trying to make an acoustic modem with matlab. It records sound an stores it in an array, modulates it using 64-QAM and adds then demodulates it. But the demodulated sound and recorded sound are not the same.
Here is the code:
clear;
clc;
M = 64; % Modulation order (alphabet size or number of points in signal constellation)
k = log2(M);
Fs=44100;
Nbits=8;
nChannels=1;
SNR=250;
%audio recording
recObj=audiorecorder(Fs,Nbits,nChannels);
recDuration=3;
disp("Begin speaking.")s
recordblocking(recObj,recDuration);
disp("2 sec pause")
pause(2)
disp("End of recording")
y=getaudiodata(recObj);
plot(y);
% playObj=audioplayer(y,Fs);
% play(playObj);
Ts=-(1/Fs)/2:1:(1/Fs)/2;
figure
subplot(1,2,1);
plottf(y,Ts,'t');
subplot(1,2,2);
plottf(y,Ts,'f');
%MODULATION QAM
y_int = abs(round(y*1000/16));
constdiag = comm.ConstellationDiagram('XLimits',[-sqrt(M) sqrt(M)],'YLimits',[-sqrt(M) sqrt(M)]);
qamData = qammod(y_int,M);
constdiag(qamData)
%DEMODULATION QAM
demodData = qamdemod(noisySound,M);
demodData = demodData*16/1000;
isequal(y_int,demodData);
playObjn=audioplayer(demodData,Fs);
play(playObjn);
%LOWPASS FILTER
Fn = Fs/2; % Nyquist Frequency (Hz)
Wp = 1000/Fn; % Passband Frequency (Normalised)
Ws = 1010/Fn; % Stopband Frequency (Normalised)
Rp = 1; % Passband Ripple (dB)
Rs = 150; % Stopband Ripple (dB)
[n,Ws] = cheb2ord(Wp,Ws,Rp,Rs); % Filter Order
[z,p,k] = cheby2(n,Rs,Ws,'low'); % Filter Design
[soslp,glp] = zp2sos(z,p,k); % Convert To Second-Order-Section For Stability
figure(3)
freqz(soslp, 2^16, Fs) % Filter Bode Plot
filtered_sound = filtfilt(soslp, glp, demodData);
%sound(filtered_sound, 44100)
where am i doing wrong?
I tried 16QAM and 32QAM but result is the same.

QPSK simulation with AWGN and BER/SER

I have a matlab code of QPSK simulation over baseband with AWGN noise, I'm calculating BER over each SNR value and plotting it along with
Theoretical BER.
When I'm generating SNR values in dB from 1 to 20 the code only computes simulated BER values from 0 to 10, why is this happening?
% QPSK MODULATION AND BER ESTIMATION IN AWGN CHANNEL
clc; clear all; close all;
N=1e6; % Number of bits transmited
SNRdB= 0:1:20; % SNR for simulation
SNRlin=10.^(SNRdB/10);
BER = zeros(1,length(SNRlin));% simulated BER
SER = zeros(1,length(SNRlin));% simulated SER
b1 = rand(1,N) > 0.5;
b2 = rand(1,N) > 0.5;
% QPSK symbol mapping
I = (2*b1) - 1;
Q = (2*b2) - 1;
S = I + 1j*Q;
N0 = 1./SNRlin; % Variance
for k = 1:length(SNRdB)
noise = sqrt(N0(k)/2)*(randn(1,N) + 1j*randn(1,N)); % AWGN noise
sig_Rx = S + noise; % Recived signal
% For BER calculation
sig_I = real(sig_Rx); % I component
sig_Q = imag(sig_Rx); % Q component
bld_I = sig_I > 0; % I decision
bld_Q = sig_Q > 0; % Q decision
b1_error = (bld_I ~= b1); % Inphase bit error
b2_error = (bld_Q ~= b2); % Quadrature bit error
Error_bit = sum(b1_error) + sum(b2_error); % Total bit error
BER(k) = sum(Error_bit)/(2*N); % Simulated BER
% For SER calculation
error_symbol = or(b1_error, b2_error); % if bit in I or bit in Q either wrong than error
SER(k) = sum(error_symbol)/N;
end
BER_theo = 2*qfunc(sqrt(2*SNRlin)); % Theoretical BER
SER_theo = 2*qfunc(sqrt(2*SNRlin)) - (qfunc(sqrt(2*SNRlin))).^2; % Theoretical SER
figure(1);
semilogy(SNRdB, BER_theo,'r-')
hold on
semilogy(SNRdB, BER,'k*')
xlabel('SNR[dB]')
ylabel('Bit Error Rate');
legend('Theoretical', 'Simulated');
title(['Probability of Bit Error for QPSK Modulation']);
grid on;
hold off;
figure(2);
semilogy(SNRdB, SER_theo,'r-')
hold on
semilogy(SNRdB, SER,'k*')
xlabel('SNR[dB]')
ylabel('Symbol Error Rate');
legend('Theoretical', 'Simulated');
title(['Probability of symbol Error for QPSK Modulation']);
grid on;
hold off;
Here is my output plot:
BER and SER simulation results

How do I compare two audio signals with different sampling frequencies in Matlab?

I'm trying to better understand upsampling and downsampling, and am using an audio signal to do so. I start with a base sampling rate of 66.15kHz, upsample by 2, run it through an LPF (sample rate of 66.15kHz, cutoff frequency of half that), then downsample by 2.
To visualize the differences between the initial and final signal, I created two spectrograms, with different sampling frequencies. There's lots of clear similarities, as well as a tighter band around the signals in the lower frequency version (as a result of the upsampling?), but I think the best thing to do is just take some sort of subtraction of the images. The problem is that the matrices are different sizes, so I can't use approaches found here or here.
Should I just upsample both of them to be the same size? Will the differences still be there?
The spectrograms in question:
Here's the code I used, some parts are commented out that may help to visualize things along the way:
%clc, clear all, close all;
NFFT = 1:10:4000; % used like F in the spectrogram fxn
WINDOW = 2000;
NOVERLAP = 0;
preupsample = audioread('audioclip.wav');
Fo = 66150;
orig_nyq = Fo/2;
U = 2;
D = 3;
postupsample = upsample(preupsample, U);
[preLPF, ~, W] = myfft(postupsample,U*Fo,length(postupsample));
% figure, plot(W,mag2db(abs(preLPF))), xlabel('Frequency (Hz)'), ylabel('Magnitude Response (dB)');
% title('Magnitude Response after upsampling');
filterorder = 100;
Fpass = orig_nyq;
Fs = U*Fo;
Rpass = 0.00057565; % .1dB passband ripple
Rstop = 1e-4; % -80dB stopband attenuation
LPF = firceqrip(filterorder,Fpass/(Fs/2),[Rpass Rstop],'passedge');
% fvtool(LPF,'Fs',Fs,'Color','White');
filtered_upsample = filter(LPF,1,postupsample);
[postLPF, ~, W] = myfft(filtered_upsample,U*Fo,length(filtered_upsample));
% figure, plot(W,mag2db(abs(postLPF))), xlabel('Frequency (Hz)'), ylabel('Magnitude Response (dB)');
% title('Magnitude Response after applying LPF');
postdownsample = downsample(filtered_upsample,D);
[postDS, w, W] = myfft(postdownsample,U*Fo/D,length(postdownsample));
% figure, plot(W,mag2db(abs(postDS))), xlabel('Frequency (Hz)'), ylabel('Magnitude Response (dB)');
% title('Magnitude Response after downsampling');
%[~,F1,T1,P1]=
figure, spectrogram(preupsample(:,1),WINDOW,NOVERLAP,NFFT,Fo,'yaxis');
%[~,F2,T2,P2]=
figure, spectrogram(postdownsample(:,1),WINDOW,NOVERLAP,NFFT,Fo*U/D,'yaxis');
% surf(T2,F2,10*(log10(abs(P2))-log10(abs(P1))),'edgecolor','none');
% view(90,-90);
% axis tight;
The contents of myfft.m:
function [X, w, W] = myfft(x, F, N)
X = fftshift(fft(x, N));
w = fftshift((0:N-1)/N*2*pi);
w(1:N/2) = w(1:N/2) - 2*pi;
W = F*w;
end

phase assignment in an OFDM signal

I have an OFDM signal which is giving me half the power spectrum (half the bandwidth) I am meant to have. I am been told the phase assignment is what is causing it but I have been twitching on it for days.... still not having the right answer
prp=1e-6;
fstep=1/prp;
M = 4; % QPSK signal constellation
k = log2(M); % bits per symbol
fs=4e9;
Ns=floor(prp*fs);
no_of_data_points = (Ns/2);
no_of_points=no_of_data_points;
no_of_ifft_points = (Ns); % 256 points for the FFT/IFFT
no_of_fft_points = (Ns);
nsamp = 1; % Oversampling rate
fl = 0.5e9;
fu = 1.5e9;
Nf=(fu-fl)/fstep;
phin=zeros(Nf,1);
dataIn = randint(no_of_data_points*k*2,1,2); % Generate vector of binary
data_source = randsrc(1, no_of_data_points*k*2, 0:M-1);
qpsk_modulated_data= modulate(modem.qammod(M),data_source);
modu_data= qpsk_modulated_data(:)/sqrt(2);
[theta, rho] = cart2pol(real(modu_data), imag(modu_data));
A=angle(modu_data);
theta=radtodeg(theta);
figure(3);
plot(modu_data,'o');%plot constellation without noise
axis([-2 2 -2 2]);
grid on;
xlabel('real'); ylabel('imag');
%% E:GENERTION
phin = zeros(Nf,1);
phin(1:Nf,1)=theta(1:Nf);
No = fl/fstep;
Vn = zeros(Ns,1);
for r = 1:Nf
Vn(r+No,1) = 1*phin(r,1);
% Vn(r+No,2) = 1*phin(r,2);
end
%%
%------------------------------------------------------
%E. Serial to parallel conversion
%------------------------------------------------------
par_data = reshape(Vn,2,no_of_data_points);
%%
% F. IFFT Transform each period's spectrum (represented by a row of
% time domain via IFFT
time_domain_matrix =ifft(par_data.',Ns);
You are only considering the real part of the signal.

Get Exact Frequency From Digital Signal

I studies on Digital Signal Filtering and I have a file includes some signal data. I wrote Matlab Program to get 23 to 27 Hz from original signal. but filtered signal is different. my desire filter is bandpass but my code work like low pass filter.
this is my code :
clc;
clear all;
load('SignalFile.mat');
%number of sample
SampleNumber = 60000;
%create hamming window
hamm = hamming((SampleNumber))'; %'
% there is 4 data in SignalFile.mat
for pl=1:4
% get name of data in signalFile.mat
data = eval(['mydata' num2str(pl)]);
[n,c] = size(data);
nk=SampleNumber;
% there is 2 signal in each data. but main signal exists on data(1:nk,1);
% nk is Sample Number.
mydata = data(1:nk,1) ;
encodedata = data(1:nk,2);
% Sample Rate my this file equal to data length / 4 ->> ~ 39000 sample
% per second.
fs = floor(n/4); % Sampling rate [Hz]
noSamples = nk; % Number of samples
f = 0 : fs/noSamples : fs - fs/noSamples; % Frequency vector
figure;
subplot(2,2,1);
plot(mydata);
x_fft = abs(fft(mydata));
subplot(2,2,2);
plot(f,x_fft);
xlim([1 100]);
centerf = 25; % 25 Hz Center
bw=2; %Bandwisth
fc=pi*centerf; %Center Frequency
L = nk; %sample number;
%Compute Filter
hsuup=(-(L-1)/2:(L-1)/2);
hideal1=hamm.*(2*(fc+bw)*(sin(2*(fc+bw)*hsuup/fs)./(2*(2*fc+bw)*hsuup/fs)));
hideal2=hamm.*(2*(fc-bw)*(sin(2*(fc-bw)*hsuup/fs)./(2*(2*fc+bw)*hsuup/fs)));
h_bpf=(hideal1-hideal2);
% transform mydata to Ferequency Domain
comp_sig_fft=fft(mydata)'; %'
% transform Filter Windows to Ferequency Domain
h_bpf_fft=fft(h_bpf);
% Filter Signal
s_fft=comp_sig_fft.*h_bpf_fft;
%
band_passed_signal=real(ifft(s_fft));
subplot(2,2,3);
plot(band_passed_signal);
x_fft = abs(fft(band_passed_signal));
subplot(2,2,4);
plot(f,x_fft);
xlim([1 100]);
end
is there any idea?
best regards.
my datafile uploaded here :
http://wikisend.com/download/574638/SignalFile.mat
result Images :
https://www.imageupload.co.uk/image/ZLzM
if you look at image, you can find under 20hz signal exists in filtered signal yet.