Display BPSK signal waveform in MATLAB - matlab

I want to display a signal waveform passed through AWGN channel,so I followed these block diagrams and referenced this website then finished this program.
(http://drmoazzam.com/matlab-code-bpsk-modulation-and-demodulation-with-explanation/)
I sent a bit stream 1 and 0, just two bits. Set symbol energy per bit Es=1, Bit rate Ts=1 and carrier frequency fc=2. I coded the bit stream to biplolar non-return-to-zero form, then modulated it to BPSK signal.
When the signal was received, used coherent detection to demodulate it. To verify my program ( It seems to be right from displaying the waveform. After modulating 1 and 0, the phase of two waveform shifted by 180ยบ each other,as follow image. ), I calculated the BER. The BER varies with SNR. However, I set SNR=1dB, the BER is still 0 (SNR=1,finalber=0). It doesn't make sense. I don't know why result is that. Who can help me to check? Thanks
clc;
clear all;
% BPSK trapz
for kk=1:1000
bitstream=[1 0 ];
%% modulate: BPSK
Es=1;% symbol energy per bit
Ts=1; %Bit rate is assumed to be 1 bit/s;
fc=2; % carrier frequency
d=0.01; % sampled interval
tc=[0:d:0.99];
n=1;
symbolbits=1; % how many bits in a symbol, BPSK=1,QPSK=2
NRZ=2*bitstream-1; % non-return-to-zero line code,bit 1 ->1 , bit 0 ->-1
for i=1:symbolbits:length(bitstream)
s(1,(n-1)*length(tc)+1:n*length(tc))=NRZ(i)*sqrt(2/Ts)*cos(2*pi*fc*tc);
n=n+1;
end
%% through AWGN channnel
SNR=20; % SNR in dB
snr=10^(SNR/10);
E=sum(abs(s).^2)/length(s); %signal energy
N0=E/snr; % noise spectral density
noise=sqrt(N0)*(randn(1,length(s))); % s is real value signal
received=s+noise;
%% coherent detection
for i=1:length(received)/length(tc)
Qr(1,(i-1)*length(tc)+1:i*length(tc))=received((i-1)*length(tc)+1:i*length(tc)).*(sqrt(2/Ts)*cos(2*pi*fc*tc));
end
m=1;
y=[];
time=[0:d:1.99];
for i=1:2
y(1,i)=trapz(time((i-1)*100+1:i*100),Qr((i-1)*100+1:i*100));
end
detected=y;
for i=1:length(detected)
if detected(i)>0
demod(i)=1;
else
demod(i)=0;
end
end
ber(1,kk)=sum(demod~=bitstream)/length(bitstream);
end
finalber=sum(ber)/1000;
figure(1)
time=[0:d:1.99];
subplot(3,1,1); plot(time,s); title('transmitted BPSK signal')
subplot(3,1,2); plot(time,received); title('received BPSK signal')
subplot(3,1,3); plot(time,Qr)

Related

BER result in MATLAB

I build a pam-2 modulation, then I make a pulse shaping with half sine (matched filter).
Then I send it through the AWGN channel.
At the end I do down sampling and demodulation.
But i have problem with plotting BER. I don't understand what I'm doing wrong:
clc;
clear;
N=1e4;
N2 = 1e2;
M = 2;
range = 0:10;
error = zeros(1,length(range)); %BER
%
% half sine
Rc = 1e3; % Chip rate
T = 1/Rc; % inverse of chip rate
Tc = 0.5* T;
Fs = 2e3; % sampling frequency
dt = 1/Fs;
over = Fs/Rc; % sampling factor
sps = 10;
time = 0:dt/sps:2*T;
half_Sine = sin(pi*time/(2*T)).^3;
%% BER
for i = 1:length(range)
for n = 1:N2
% Modulation
x=randi([0 M-1],N,1);
h_mod = pammod(x,M);
over_data=upsample(h_mod,over);
txSig = conv(over_data,half_Sine, 'same');
% AWGN
Ps = mean(((txSig)).^2);
Sigma = sqrt(Ps * 10^(-range(i)/10) / 2);
Noise = randn(length(txSig), 1) * Sigma;
rx_SIG = Noise + txSig;
% Downsample
down = rx_SIG(1:over:end);
% Demodulation
hDemod = pamdemod(down,M);
% Errors
error(i) = error(i)+...
sum(hDemod~=x) / length(hDemod);
end
BER = error/n;
end
figure(1);
grid on
semilogy(range,BER);
title('BER');
Update:I need to build a ber from 10^1 to 10^6
1.- Your script up and running :
There are many code lines turned comments that I used to get to run the start script. I have left them along, that should be used while debugging only.
close all;clear all;clc;
N=1024;
M = 2;
% pulse : half sine
Rc = 1e3; % [b/s] chip rate
T = 1/Rc; % [s/b] inverse of chip rate
Tc = 0.5* T;
Fs = 2e3; % [Hz] sampling frequency
dt = 1/Fs; % [s]
ov1 = Fs/Rc; % sampling factor
sps = 10;
dt2=dt/sps
% single pulse time reference
t = [0:dt2:2*T]; % [s]
% signals usually have a known preable
% a heading known sequence that helps receivers
% extract with relative ease when pulse peaks take place
% the sync preamble has to be long enough to acquire
% the sampling interval.
% For simplicity here I just make sure that the first bit of the signal is always 1
nsync=64 % length sync header
x=[ones(1,nsync) randi([0 M-1],1,N-nsync)]; % signal : data
xm=reshape(x([nsync+1:end]),[(N-nsync)/8 8])
L1=sum(repmat(2.^[7:-1:0],size(xm,1),1).*xm,2); % string to check received bytes against, to measure BER
over_data = pammod(x,M); % signal : PAM symbols
% err1 = zeros(1,length(x)); %BER
% single pulse
pulse_half_Sine = sin(pi*t/(2*T)).^3;
figure;plot(t,pulse_half_Sine)
grid on;xlabel('t');title('single pulse')
% A=[.0001:.0001:1];
A=[1e-3 5e-3 1e-2 5e-2 .1 .5 1 10 100];
% A=[5e-2:1e-2:2];
rng1 = [1:numel(A)]; % amount S power levels to check for BER
% to use power on requires a reference impedance
% usually assumed 1, in accademic literature, but then when attempting to correlated
% BER with used Watts if R0=1 the comparison is not correct.
R0=50 % [Ohm]
%% BER measuring loop
% k=1
% Logging BER for different signal power levels,
% Logging signal power levels, it was useful when getting script up and running
BER=[];
SNR_log=[];
figure(1)
ax1=gca
for k = 1:length(rng1)
% generating signal
x2=2*(x-.5); % [0 1] to [-1 1]
S=[]
for k2=1:1:numel(x)
S=[S A(k)*x2(k2)*pulse_half_Sine];
end
Ps = mean(S.^2)/R0; % signal power
% adding AWGN
% you are making the noise proportional to the signal
% this causes BER not to improve when signal power up
% sigma1 = sqrt(Ps * 10^(-rng1(k)/10) / 2); % not used
sigma1=.1
noise1 = randn(length(S), 1) * sigma1;
Pn=mean(noise1.^2)/R0;
rx_S = noise1' + S; % noise + S
% Downsample
% this downsampling is an attempt to sync received signal
% to the time stamps where pulse peaks are expected
% but it does not work
% dwn1 = rx_SIG(1:ov1:end);
% Demodulation
% because the sampling times of the previous line are not
% centered pamdemod doesn't work either
% hDemod = pamdemod(dwn1,M);
% the missing key step : conv on reception with expected pulse shape
rx2_S=conv(pulse_half_Sine,rx_S);
rx2_sync=conv(pulse_half_Sine,rx_S([1:1:nsync*numel(pulse_half_Sine)]));
% removing leading samples that only correspond to the
% pulse used to correlate over received signal
rx2_S([1:numel(pulse_half_Sine)-1])=[];
% syncing
[pks,locs]=findpeaks(abs(rx2_sync),'NPeaks',nsync,'MinPeakHeight',A(k)/2);
% [pks,locs]=findpeaks(abs(rx2_S));
% x3(find(pks<.1))=[]; % do not use sign results close to zero
% locs(find(pks<.1))=[];
% t0=dt2*[0:1:numel(rx2_sync)-1];
% figure;plot(t0,rx2_sync);hold on
% plot(t0(locs),pks,'bo')
% 5 header pulses needed, 1st and last header samples are null, not needed
n01=find(pks<.2*A(k));
if ~isempty(n01) peaks(n01)=[];locs(n01)=[]; end
% pks([1 end])=[];locs([1 end])=[];
% plot(t0(locs),pks,'rs')
% since we know there have to be 5 leading pulses to be all ones
% we extract the sampling interval from this header
nT2=round(mean(diff(locs)))
% t3=dt2*[0:1:numel(rx2_S)-1];
% figure;plot(t3,abs(rx2_S));
% hold on
% xlabel('t')
% plot(t3(locs),pks,'ro')
% nt3=[1:nT2:numel(x)*nT2]; % sampling times
% plot(t3(nt3),max(pks)*ones(1,numel(nt3)),'sg')
x3=sign(rx2_S([1:nT2:N*nT2])); % only N bits expected so only sample N times
% x3 [-1 1] back to [0 1] otherwise when comparing v3 against x
% a roughtly 50% of bits are always going to be wrong, which comes
% from the signal statistics
x3=.5*(1+x3);
% sampling
% x3=sign(rx_S(locs));
% making sure x3 and x same length
% x3(find(pks<.1))=[]; % do not use sign results close to zero
SNR=Ps/Pn;
SNR_log=[SNR_log Ps];
x3_8=reshape(x3([nsync+1:end]),[(N-nsync)/8 8])
Lrx=sum(repmat(2.^[7:-1:0],size(x3_8,1),1).*x3_8,2);
err1 = sum(L1~=Lrx) / length(Lrx);
BER = [BER err1];
end
%% BER(S)
figure(1);
plot(rng1,BER);
grid on
title('BER/rng1');
This is not BIT ERROR RATIO as we know it and as it is used in all sort of quality measurements.
Note that Bit Error Ratio is not the same as Bit Error Rate despite both terms commonly used alike.
A rate implies and amount/seconds a velocity, speed.
BER as used commonly used to measure signal quality is a RATIO, not a rate.
BER = correct_bits/total_bits , but it's not as simple as this, as I am going to show.
For instance note that worst BER obtained with your script with a quick fix doesn't reach above 0.5 (!?) BER certainly reaches 1 when message not 'getting-there'.
I believe the following points are important for you to understand how BER really works.
2.- BER was completely flat for really dispare signal power levels
In an earlier working script not shown even using pulse amplitude A=100, and low noise mean(noise1)=-7.36e-04 about 1/3 of the received symbols are erroneous while figure;plot(rx_S) shows a rather clean signal, no riding ripple, no sudden changes ..
The 1/3 errorenous bit were not corrupted by channel noise but it was already in the transmitted signal. I have spaced each pulse enough to avoid overlapped pulses.
Adjacent pulses need at least 2ms to avoid overlapping.
This is without considering doppler.
Heavily overlapping symbols is what happens when command conv is used on a train of pulses generated the way you did :
S = conv(over_data,A(k)*pulse_half_Sine, 'same');
3.- You started with 1e4 data bits treated as 1e4 modulation symbols
But your transmitted-received time signal also showed length 1e4 time samples, cannot be, way too few time samples.
The time reference of over_data and pulse_half_Sine should not be the same.
Nyquist; signal is currupted beyond recovery if only 2 samples er cycle of let's say carrier modulating pulses.
I tried
h_mod = pammod(x,M);
over_data=upsample(h_mod,ov1);
S = conv(h_mod,A(k)*pulse_half_Sine, 'same'); % modulated signal
h_mod = pammod(x,M);
S = conv(h_mod,A(k)*pulse_half_Sine, 'same'); % modulated signal
S = conv(over_data,A(k)*pulse_half_Sine, 'same'); % modulated signal
and none of these 3 got the expected BER showing whether the signal is strong or weak.
4.- It turns out command upsample is for discrete-time models
sys = tf(0.75,[1 10 2],2.25)
L = 14;
sys1 = upsample(sys,L)
not to directly interpolate a signal to, for instance, double the amount of samples as it seems you attempted.
5.- This is how the transmitted signal (before noise added) should look like
t2=dt2*[0:1:numel(S)-1];
figure;plot(t2,S);
grid on;xlabel('t');title('transmitted signal before noise')
t3=dt2*[0:1:numel(rx2_S)-1];
[pks,locs]=findpeaks(abs(rx2_S))
figure;plot(t3,rx2_S);
hold on
xlabel('t')
plot(t3(locs),pks,'ro')
6.- The chosen pulse is not particularly strong against AWGN
The main reason being because it's a baseband pulse. not modulated, and on top of this only has positive values.
Convolution efficiency highly improves when modulating the pulse, the positive and negative pulse samples to be found across each pulse increases robustness when attempting to decide whether there's pulse or just noise.
For instance Chirp pulses are a lot stronger.
7.- To measure BER : Use bytes, constellation points, coded symbols, but not bare bits
Measuring BER with bare bits, or more broadly speaking, using a random test signal with fixed statistical moments BER is constrained to whatever mean and var assinged to signal and/or mean var from noise in absence of with weak signal.
Rewording, testing for BER with bare bits counting, when weak or no signal BER is actually measuring the noise the signal was trying to avoid.
Roughly 50% of the received bits, regardless of signal or noise, the way you are attempting BER measurement, will always hit what are apparently correct bits : false positives.
To avoid these false positives following I show how to measure BER against expected caracters.
N=1024
..
nsync=64 % length sync header
x=[ones(1,nsync) randi([0 M-1],1,N-nsync)]; % signal : data
Now x is 1024 and the initial 64 bits are for syncing only, leaving N-sync for message.
Let's check BER against let's say L1 the expected sequence of bytes
xm=reshape(x([nsync+1:end]),[(N-nsync)/8 8])
L1=sum(repmat(2.^[7:-1:0],size(xm,1),1).*xm,2);
L1 is checked against Lrx generated with x3_8 the message part of x3 the demodulated symbols
8.- the upsampling downsampling didn't work
this downsampling on reception
dwn1 = rx_SIG(1:ov1:end);
was an attempt to sync received signal to the time stamps where pulse peaks are expected but it didn't not work.
Because the sampling times were not centered pamdemod didn't work either.
9.- Use sync header to calculate sampling interval
I only convolve the nsync (64) initial bits
rx2_sync=conv(pulse_half_Sine,rx_S([1:1:nsync*numel(pulse_half_Sine)]));
These pulses allow a reliable calculation of nT2 the sampling interval to check along the rest of the received frame.
I obtain nT2 with
[pks,locs]=findpeaks(abs(rx2_sync),'NPeaks',nsync,'MinPeakHeight',A(k)/2);
There's need for further conditioning but basically locs already has the necessary information to obtain nT2 .
10.- This is the graph obtained
when no signal BER = 1 and when signal strength high enough PAM signals show good `BER' ending to 0.
When refining A step, by this meaning making it smaller, one gets the following
BER testers are often plugged to base stations upon setup and left a few hours or even days recording, and such testers do not record bare bit errors, bytes, constellation points, and even frames are checked.
11.- BER/SNR BER/EbN0 not against signal only
BER is usually plotted against SNR (analog signals) or Eb/N0 (digital signals) not just against signal amplitude or signal power.
12.- The Communications Toolbox is an add-on
This toolbox adds the following support functions: pammod pamdemod genqammod genqamdemod, yes pammod and pamdemod use genqammod genqamdemod respectively.
These functions are not available unless the Communications Toolbox is installed.
for BER simulations try Simulink, there are already available BER examples.

I am using MATLAB HDL coder to convert matlab coder and currently having some error

I am not able to get this error removed. Can someone please help me. The problem is it is showing some error in step 4 while generation of hdl code.
function [Rxx]=autom(X) % [Rxx]=autom(x)
Rxx=zeros(1,1024);
for m=1: 1025
for n=1: 1025-m
Rxx(m)=Rxx(m)+X(n)*X(n+m-1);
end
end
%testbench
N=1024; % Number of samples
f1=1; % Frequency of the sinewave
FS=200; % Sampling Frequency
n=0:1023; % Sample index numbers
X=zeros(1,1024);
% X=sin(2*pi*1*(0:1023)/200);
X=sin((2*pi*1.*n)./200);
t=[1:1024]*(1/200);
%ti=f1*n/FS;
%x=sin(2*pi*ti); % Generate the signal, x(n)
%t1=[1:N];
%t=t1*(1/FS); % Prepare a time axis
subplot(2,1,1); % Prepare the figure
plot(t,X);
title('Sinwave of frequency 1000Hz [FS=8000Hz]');
xlabel('Time, [s]');
ylabel('Amplitude');
grid;
Rxx = autom(X(1:1024)); % Calculate its autocorrelation
subplot(2,1,2);
plot(Rxx);
title('Autocorrelation function of the sinewave'); % Plot the autocorrelation
xlabel('lags');
ylabel('Autocorrelation');
The error says: "[...] unsuported dynamic matrix X[...]"
Your problem is that in your function you are doing X(n)*X(n+m-1); and it seem to be understanding that this is dynamically changing the size of the matrix. I suspect in fact that the error is in Rxx
Note that your X is 1024 on length, but your iterations of n and m are 1025 in length. Rxx is 1024 on length, but you do Rxx(m) and m goes up to 1025, thus dynamically changing its size (MATLAB will increase the size of Rxx from 1024 to 1025, dynamically)
Are you sure you dont want
function [Rxx]=autom(X) % [Rxx]=autom(x)
Rxx=zeros(1,1024);
for m=1: 1024
for n=1: 1024-m
Rxx(m)=Rxx(m)+X(n)*X(n+m-1);
end
end

Measuring peaks and the distance between them in my plot

I will keep the explanation, how my codes works, very short. I advise you to try this code yourself, so perhaps you understand it better that way. I have an audio-file and read it in my code. Now i switch from the time domain to the frequency domain by using the function FFT. But the only difference is, that i am performing an STFT on my audio signal. I do it every 30ms, until to the length of my signal. I am aware, that there are many different function in matlab, which also can perform this easily, but there are not giving me the results i need. Now, i am plotting many different frequency spectrums every 30ms. But i split up my signal in three frequency bands. They are called LOW, MEDIUM and HIGH. Basically, this means I have 3 different spectrums plotting every 30ms. The next step I do, is summing all the magnitudes from ONE frequency spectrum together, this means I have ONE VALUE per frequency spectrum, which are being squared.
Now, i have the power from every spectrum ! And all of these values are being plotted in my code. I am only plotting the power values, otherwise my code performance time would be extremely slow.
Btw, the code looks long, but there are two for loop. In the first, i read the low spectrum and when it is finished, the second starts with the medium and high spectrum. Basically they are the same. I am aware, i can probably do that with findpeaks or something similar. But how can i write/pull that of? Or what the necessary steps to do that. At the end, i included a file, Hopefully you can see that.
I want to measure the peaks and get the distance between them from the red plot.
EDIT:
Ok, i got the peaks, but not in the way i imagined. I want to show the peaks, which are above 5000-line. Sorry for not being clear at the beginning. See my plot, what i mean. I want to say my code, that only the peaks should be measured, which are above the 5000-line.
[pks, locs] = findpeaks(ValuesOfYc);
p=plot(x,ValuesOfYc,'r-' ,x(locs), pks,'ob');
This is, what I did above, in my first loop. How should i go on from there?
clear;
clc;
%% MATLAB
%% read file
%_________________________________________
[y,fs]=audioread('Undertale - Megalovania.wav');
% audioread = read wav -file
% y = contains the audio signal
% fs = 44100
% 'UnchainMyHeart' = name of the wav-file
%_________________________________________
%% PARAMETER FOR STFT
%_________________________________________
t_seg=0.03; % length of segment in ms
fftlen = 4096; %FFT-Points
% Defining size of frequency bands
f_low= 1:200; %lower frequencies
f_medium= 201:600; %medium frequencies
f_high= 601:1000; %higher frequencies
%__________________________________________
%% CODE
segl =floor(t_seg*fs);
windowshift=segl/2;
% defining the size of the window shift
window=hann(segl);
% apply hann function on segment length (30 ms)
window=window.';
% transpose vector
si=1;
% defining start index
ei=segl;
% defining end index
N=floor( length(y)/windowshift - 1);
% Calculates the number, how often the window has to shift
% until to length of the audio signal
f1=figure;
% Generating new window
f=0:1:fftlen-1;
f=f/fftlen*fs;
% defining frequency vector
Ya=zeros(1,fftlen);
ValuesOfYc = NaN(1,N);
ValuesOfYd = NaN(1,N);
ValuesOfYe = NaN(1,N);
x =(1:N)*windowshift/fs;
% defining x-axis
for m= 1:1:N
y_a = y(si:ei);
% a segment is taken out from audio signal length(30ms)
y_a= y_a.*window;
% multiplying segment with window (hanning)
Ya=fft(y_a, fftlen);
% Applying fft on segment
Yb=abs(Ya(1:end/2)).^2;
% Squaring the magnitudes from one-sided spectrum
drawnow; % Updating the graphical values
figure(f1);
% Showing the power values
%% frequency bands
y_low = Yb(f_low); % LOW frequency spectrum
Yc=sum(y_low);
% Summing all the power values from one frequency spectrum together
% so you get one power value from one spectrum
ValuesOfYc(m) = Yc;
%Output values are being saved here, which are generated from the for
%loop
% m = start variable from for loop
[pks, locs] = findpeaks(ValuesOfYc);
subplot(2,1,1)
p=plot(x,ValuesOfYc,'r-', x(locs(pks>=5000)), pks(pks>=5000),'ob');
p(1).LineWidth =0.5;
xlabel('time (Audio length)')
ylabel('Power')
grid on
si=si+windowshift;
% Updating start index
ei=ei+windowshift;
% Updating end index
end
for o= 1:1:N
y_a = y(si:ei);
% a segment is taken out from audio signal length(30ms)
y_a= y_a.*window;
% multiplying segment with window (hanning)
Ya=fft(y_a, fftlen);
% Applying fft on segment
Yb=abs(Ya(1:end/2)).^2;
% Squaring the magnitudes from one-sided spectrum
drawnow; % Updating the graphical values
figure(f1);
% Showing the power values
[![enter image description here][1]][1]
%% frequency bands
y_medium = Yb(f_medium); % MEDIUM frequency spectrum
y_high = Yb(f_high); % HIGH frequency spectrum
Yd=sum(y_medium);
Ye=sum(y_high);
% Summing all the power values from one frequency spectrum together
% so you get one power value from one spectrum
ValuesOfYd(o) = Yd;
ValuesOfYe(o) = Ye;
%Output values are being saved here, which are generated from the for
%loop
% m = start variable from for loop
subplot(2,1,2)
p=plot(x, ValuesOfYd,'g-', x, ValuesOfYe,'b-' );
p(1).LineWidth =0.5;
xlabel('time (Audio length)')
ylabel('Power')
grid on
si=si+windowshift;
% Updating start index
ei=ei+windowshift;
% Updating end index
end

Separating audio file in 3 different frequency areas

I apologize in advance, if the title is confusing. Basically, i have a Audio-file, on which I perform a STFT every 50ms. My File is about 11 seconds long (10.8526s), which i have cut off from a soundtrack. Btw, i am not allowed to use the built-in function in Matlab for the STFT. I am aware it is much more easier. Anyway, after i run my code, every 50 ms a STFT is performed and the picture is being plotted.
Now i want to seperate it in 3 different plots. In the first plot i have the lower frequencies (0-300Hz), in the second plot medium frequencies(300-5kHz) and in the last plot i have high frequencies(5Khz-fs/2). fs=44100 --> Further explanations below in the code. How can i define now the areas?
%AUDIO-FILE
%______________________________________________________
[y,fs]=audioread('UnchainMyHeart.wav');
% audioread = Reads Audio file
% y = A vector, which contains the audio signal
% fs = sample rate
% 'UnchainMyHeart' = Audio file
%______________________________________________________
% Paramter for the real-time spectral-analysis
%______________________________________________________
NFA=2;
% Every second picture is being plotted
% Don't need every picture
t_seg=0.05;
%Length of the audio signal on which is a STFT performed
fftlen = 4096;
% Length of the FFT, frequency resolution
TPF= 300;
BPF= 5000;
HPF= 22050;
% Trying to define the frequencies areas
% Isn't working right now
LOW=((TPF*fftlen)/fs);
MEDIUM=((BPF*fftlen)/fs);
HIGH=((HPF*fftlen)/fs);
% Contains the number of FFT points in the frequency
%_______________________________________________________
segl =floor(t_seg*fs);
windowshift=segl/2;
window=hann(segl);
window=window.';
si=1;
% Start Index
ei=segl;
% End Index
AOS= length(y)/windowshift - 1;
f1=figure;
f=0:1:fftlen-1;
f=f/(fftlen-1)*fs;
Ya=zeros(1,fftlen);
n=0;
for m= 1:1:AOS
y_a = y(si:ei);
y_a= y_a.*window;
Ya=fft(y_a, fftlen);
n=n+1;
if n==1
Yres=abs(Ya);
else
Yres=Yres+abs(Ya);
end
if n==NFA
Yres=Yres/NFA;
n=0;
drawnow;
%Updates the graphical objects which are being plotted every 50ms
figure(f1);
plot(f(1:end/2), 20*log10(abs(Yres(1:end/2))));
ylim([-90 50]);
title('Spektrum of audio signal');
xlabel('f(Hz)');
ylabel('dB');
grid on;
end
si=si+windowshift;
% Updating Start Index
ei=ei+windowshift;
% Updating End index
end
I am not able to run you code as I do not have your audio file but I will try to explain conceptually, and use pseudo code.
Frequency brick-wall
If you just want to separate the frequencies for visual purposes you can just use brick-wall filters.
Perform an fft of the full signal. Define a frequency vector.
SigFD = fft(signal);
n = length(signal); % number of samples
fs = 44100; % sampling rate
deltaF = fs/n; % frequency resolution
F = [0:floor(n/2)-1, -(floor(n/2)):-1]*deltaF; % frequency vector
Slice the signal based on the frequency range that you want.
lowF = 0;
highF = 500;
part1Range = abs(F)>lowF&abs(F)<highF;
Fpart1 = F(part1Range);
Sig1FD = SigFD(part1Range);
Note that I am unable to test the code on your waveform so this should be considered more of pseudo code!

How to do a frequency band?

Here in this code i am doing a stft on my wav-file. There is no problem with that. At the beginning, i am defining my parameter, afterwards using my wav file and then applying the stft. Basically what i am doing is a real-time spectral analysis. Anyway my question is, how do i a frequency band? I want my signal to be separated in LOW/MEDIUM/HIGH. I want my vector to be saved, from 0-250 Hz in the LOW-Band, 250-5000 Hz in the MEDIUM-Band, 5-22.05k Hz in the HIGH-Band. I advise you, to try my code in Matlab, if you don't understand it. Just take any wav-file. Btw my signal is plotted in the variable "Yres". Any solution is appreciated!
NFA=2; % Number is used for plotting every 2nd picture
t_seg=0.05; % Length of segment in ms
fftlen = 4096;
% Lenght of "fft",because our segment contains 2205 points
[y,fs]=audioread('UnchainMyHeart.wav');
% audioread = functions reads WAV-file
% y = A vector which contains my audio signal
% fs = sample frequency (44100)
% 'UnchainMyHeart' = WAV-file
t=linspace(0,length(y)/fs,length(y));
% linspace = Creating time vector
% 0 = Start time
% length(y)/fs = End time
% length(y) = Number of samples in y
plot(t,y)
% plotting signal in the time domain
segl =floor(t_seg*fs);
% Applying fft function on the variable "segl"
windowshift=segl/2;
% Defining the size of the window, which goes to the next "segl"
window=hann(segl);
% hann function
window=window.';
si=1;
%Start index
ei=segl;
%End index
AOS= length(y)/windowshift - 1;
% AOS is the number of "segl" we use (About 433)
f1=figure;
% Opening new window
f=0:1:fftlen-1;
f=f/(fftlen-1)*fs;
% Defining frequency vector
Ya=zeros(1,fftlen);
plot(f,Ya),axis([0 fs -90 50])
grid on
n=0;
%start variable
for m= 1:1:AOS
y_a = y(si:ei);
y_a= y_a.*window;
Ya=fft(y_a, fftlen);
n=n+1;
if n==1
Yres=abs(Ya);
else
Yres=Yres+abs(Ya);
end
if n==NFA
Yres=Yres/NFA;
n=0;
drawnow;
%Tut die Grafikobjekte immer auf den neuesten Stand updaten
figure(f1);
plot(f(1:end/2), 20*log10(abs(Yres(1:end/2))));
ylim([-90 50]);
title('Spektrum eines Audiosignal');
xlabel('f(Hz)');
ylabel('dB');
grid on;
end
si=si+windowshift;
% Updating start index
ei=ei+windowshift;
% Updating end index
end
This may not be the best answer! But this may help you get started on something. You can use spectrogram() function from MATLAB's Signal Processing Toolbox.
Let's suppose you have an audio file named ''UnchainMyHeart.wav'(in your case) with one channel. The code goes as follows:
% Reading the audio file
[y1,fs] = audioread('UnchainMyHeart.wav');
% Parameters for STFT (or spectrogram)
windowDuration = 30e-3; overlapDuration = 15e-3;
windowLength = round(windowDuration*fs); % window length
overlapLength = round(overlapDuration*fs); % overlapping of windows
nfft = 1024;
% Executing STFT for the signal
[S1,F1,T1,P1] = spectrogram(x1,hanning(windowLength), ...
overlapLength, nfft, fs, 'yaxis');
S1 and P1 contain STFT and Power Spectrum Density(PSD) of the signal for a time interval of each section with a time interval whose estimations are contained in T1.
For your question, you are looking for F1 which is a vector of cyclical frequencies expressed in terms of sampling frequency, fs. For example: if you have a sampling frequency of 48 kHz (fs) and nfft of 1024, then you will have 513 [(1024/2) +1)] frequency values spaced by (fs/nfft). i.e. 46.875. So your frequency components will be 0, 46.875, 46.875*2, ..., 46.875*512. The maximum you will have is 24 kHz due to Nyquist criterion.
Now, you can easily write a simple routine specifying the ranges as you said. The same technique can be used in your code which is an implementation of stft. I would suggest using MATLAB's built-in function unless your problem requires an implementation. Hope this helps!
If needed, I can answer why the parameters for STFT are chosen as included in the code.