I have a second order sigma delta modulator in simulink matlab. it's working fine i applied a sinusoidal waveform to the input with Vp - p = 1V and i have the same waveform(with a little delay), after low-pass filtering in the output :
I get this for fft :
fft
sampling freq=256 MHz
input freq= 4MHz
Period of sample and hold clock is 1/256MHZ
And also sample time for adc_out block seen in the pic is 1/256MHz
And i didn't touch anything else.
And i calculated the input freq based on this formula :
fin=(prime/N)* sampling freq
Prime is prime number, i chose 257
N is number of fft points, i chose 16384
sampling freq is 256MHz
therefore i got 4MHz as the best input freq and these considerations, after fft, were supposed to give me a nice impulse at 4MHz and the shaped noise in the higher frequencies
as you can see i don't have my desired imupulse at 4MHz!
and i just don't know why!!
Just peeking at the image, I'd say it's a windowing issue. In particular, since you don't use an explicit window, you are using a block function. The FFT of a block is sin(x)/x, which is convoluted with your real response.
Related
I was studying for a signals & systems project and I have come across this code on high and low pass filters for an audio signal on the internet. Now I have tested this code and it works but I really don't understand how it is doing the low/high pass action.
The logic is that a sound is read into MATLAB by using the audioread or wavread function and the audio is stored as an nx2 matrix. The n depends on the sampling rate and the 2 columns are due to the 2 sterio channels.
Now here is the code for the low pass;
[hootie,fs]=wavread('hootie.wav'); % loads Hootie
out=hootie;
for n=2:length(hootie)
out(n,1)=.9*out(n-1,1)+hootie(n,1); % left
out(n,2)=.9*out(n-1,2)+hootie(n,2); % right
end
And this is for the high pass;
out=hootie;
for n=2:length(hootie)
out(n,1)=hootie(n,1)-hootie(n-1,1); % left
out(n,2)=hootie(n,2)-hootie(n-1,2); % right
end
I would really like to know how this produces the filtering effect since this is making no sense to me yet it works. Also shouldn't there be any cutoff points in these filters ?
The frequency response for a filter can be roughly estimated using a pole-zero plot. How this works can be found on the internet, for example in this link. The filter can be for example be a so called Finite Impulse Response (FIR) filter, or an Infinite Impulse Response (IIR) filter. The FIR-filters properties is determined only from the input signal (no feedback, open loop), while the IIR-filter uses the previous signal output to control the current signal output (feedback loop or closed loop). The general equation can be written like,
a_0*y(n)+a_1*y(n-1)+... = b_0*x(n)+ b_1*x(n-1)+...
Applying the discrete fourier transform you may define a filter H(z) = X(z)/Y(Z) using the fact that it is possible to define a filter H(z) so that Y(Z)=H(Z)*X(Z). Note that I skip a lot of steps here to cut down this text to proper length.
The point of the discussion is that these discrete poles can be mapped in a pole-zero plot. The pole-zero plot for digital filters plots the poles and zeros in a diagram where the normalized frequencies, relative to the sampling frequencies are illustrated by the unit circle, where fs/2 is located at 180 degrees( eg. a frequency fs/8 will be defined as the polar coordinate (r, phi)=(1,pi/4) ). The "zeros" are then the nominator polynom A(z) and the poles are defined by the denominator polynom B(z). A frequency close to a zero will have an attenuation at that frequency. A frequency close to a pole will instead have a high amplifictation at that frequency instead. Further, frequencies far from a pole is attenuated and frequencies far from a zero is amplified.
For your highpass filter you have a polynom,
y(n)=x(n)-x(n-1),
for each channel. This is transformed and it is possble to create a filter,
H(z) = 1 - z^(-1)
For your lowpass filter the equation instead looks like this,
y(n) - y(n-1) = x(n),
which becomes the filter
H(z) = 1/( 1-0.9*z^(-1) ).
Placing these filters in the pole-zero plot you will have the zero in the highpass filter on the positive x-axis. This means that you will have high attenuation for low frequencies and high amplification for high frequencies. The pole in the lowpass filter will also be loccated on the positive x-axis and will thus amplify low frequencies and attenuate high frequencies.
This description is best illustrated with images, which is why I recommend you to follow my links. Good luck and please comment ask if anything is unclear.
I have the following matlab code, and I am trying to get 64 samples of various sinewave frequencies at 16KHz sampling frequency:
close all; clear; clc;
dt=1/16000;
freq = 8000;
t=-dt;
for i=1:64,
t=t+dt;a(i)=sin(2*pi*freq*t);
end
plot(a,'-o'); grid on;
for freq = 1000, the output graph is
The graph seems normal upto 2000, but at 3000, the graph is
We can see that the amplitude changes during every cycle
Again, at 4000 the graph is
Not exactly a sinewave, but the amplitude is as expected during every cycle and if I play it out it sounds like a single frequency tone
But again at 6000 we have
and at 8000 we have
Since the sampling frequency is 16000 I was assuming that I should be able to generate sinewave samples for upto 8000, and I was expecting the graph I got at 4000 to appear at 8000. Instead, even at 3000, the graph starts to look weird
If I change the sampling frequency to 32000 and the sinewave frequency to 16000, I get the same graph that I am getting now at 8000. Why does matlab behave this way?
EDIT:
at freq = 7900
This is just an artifact of aliasing. Notice how the vertical axis for the 8kHz graph only goes up to 1.5E-13? Ideally the graph should be all zeros; what you're seeing is rounding error.
Looking at the expression for computing the samples at 16kHz:
x(n) = sin(2 * pi * freq * n / 16000)
Where x is the signal, n is the integer sample number, and freq is the frequency in hertz. So, when freq is 8kHz, it's equivalent to:
x(n) = sin(2 * pi * 8000 * n / 16000) = sin(pi * n)
Because n is an integer, sin(pi * n) will always be zero. 8kHz is called the Nyquist frequency for a sampling rate of 16kHz for this reason; in general, the Nyquist frequency is always half the sample frequency.
At 3kHz, the signal "looks weird" because some of the peaks are at non-integer multiples of 16kHz, because 16 is not evenly divisible by 3. Same goes for the 6kHz signal.
The reason they still sound like pure sine tones is because of how the amplitude is interpolated between samples. The graph uses simple linear interpolation, which gives the impression of harsh edges at the samples. However, a physical loudspeaker (more precisely, the circuitry which drives it) does not use linear interpolation directly. Instead, a small filter circuit is used to smooth out those harsh edges (aka anti-aliasing) which removes the artificial frequencies above the aforementioned Nyquist frequency.
That is problem of matlab but a nature of sampling.
16KHz sampling makes 16K (16,000) sampled data per second. 8KHz signal has 8K (8000) cycles per second. So two sample data per a cycle.
Two is minimum number of data per cycle. This is know a part of "sampling theorem".
Let try to show two cycles with three points on graph, you may understand that its impossible to show two cycles by three points. In the same way, you can't show 2N cycles by (2N-1) points.
The effect seen for 8 kHz is as all other answers already mention aliasing effects and arises due to that the sine wave for 8 kHz is sin(2*pi*n*8000*1/16000) = sin(n*pi), which is explained in Drew McGovens answer. Luckily the amplitude is not the only parameter that defines the signal. The other parameter that is required to completely define the signal is the phase. This means that when doing for fourier analysis of the signal, it is still possible to find the right frequency. Try:
close all; clear; clc;
dt=1/16000;
freq = 7300;
t=-dt;
for i=1:64,
t=t+dt;a(i)=sin(2*pi*freq*t);
end
plot(a,'-o'); grid on;
figure; plot( linspace(1,16000,1000), abs(fft(a)) );
A side comment: some people might argue against using i as index variable since that can also be used as the imagiary number i. Personally I have nothing against using i since the runtime and overhead only is affected slightly and I always uses 1i. However, just make sure to use 1i consistently for the imaginary unit then.
I have some matlab code which produces frequency (in hertz) of a sound over 5 seconds. The code as it stands outputs 100 samples per second, and I want to play the 5 second block to see what this sounds like, but I'm having issues with sampling rate and sound / soundsc commands.
My frequency oscillates (data here ) and I'd be very grateful if someone could help me convert this data into some kind of real-time approximation of what it should sound like.
Something like this may be helpful
Fs=2000; %sample rate, Hz
t=0:1/Fs:5; %time vector
F=298+sin(2*pi*t); %put your own F here
S=sin(2*pi*F.*t); %here is the sound vector
%visual check
figure(1);
plot(t,S)
figure(2);
plot(t,F)
%listen
wavplay(S,Fs)
This is like FM modulation, but different. If you have an Fold vector with a different sample rate, you can convert it with the command
F=interp1(told,Fold,t); %told and Fold are F at a different sample rate
%check it
plot(told,Fold,t,F)
First, your sampling rate should be at least twice the maximum frequency according the Nyquist–Shannon sampling theorem.
Next, you need to generate a sinusoid:
Signal = sin(2*pi*Phi);
where Phi is the phase corresponding to the desired frequency pattern, which is simply an integral of the frequency (which you can do numerically or analytically).
I have 2 arrays of 800000 input and output data samples of a system. The system in a kind of oven that works among 0 and 10 volts. The sample time is 0.001s.
I have to identify the model of this system, but first of all, given that the data are clearly dirty, I would like to filter the noise.
How can I do it with the System Identification Toolbox of Matlab?
Moreover, how can I estimate the cutoff frequency to remove the noise?
Thank you in advance.
PS: given that this is a bit out of topic, please, post your answer here thank you.
The cutoff frequency is directly given by you sampling time or sampling frequency.
you sampling frequency is 1/(sampling time) and must at least 2 the factor of the highest frequency of interest:
http://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem
f_s = 1/T_s >= 2*f_cutOff
You can then simply to same frequency domain processing in the case you sampling frequency is realy high enough. The easiest way would to have a look at the frequency domain (with function fft() ). And check first where you have high noise components. Then filter out these components (zeroing) and then transform it back into time domain ( with function ifft() ).
Noise is modeled as a white Gaussian distribution in the simplest case. If you estimate the noise energy, you can make a dummy noise by calling
noise = A*randn(1,N);
Here, A is the amplitude and N is the sample count. then just take the fft of this signal and subtract it from the fft of input signal and take the inverse fft (ifft)
I'm working on a control system that measures the movement of a vibrating robot arm. Because there is some deadtime, I need to look into the future of the somewhat noisy signal.
My idea was to use the frequencies in the sampled signal and produce a fourier function that could be used for extrapolation.
My question: I already have the FFT of the signal vector (containing 60-100 values e.g.) and can see the main frequencies in the amplitude spectrum. Now I want to have a function f(t) which fits to the signal, removes some noise, and can be used to predict the near future of the signal. How do I calculate the coefficients for the sine/cosine functions out of the complex FFT data?
Thank you so much!
AFAIR FFT essentially produces output as a sum of sine functions with different frequencies. The importance of each frequency is the height of each peak. So what you really want to do here is filter out some frequencies (ie. high frequencies for the arm to move gently) and then come back to the time domain.
In matlab this should be like going through the vector of what you got from fft, setting some values to 0 (or doing something more complex to it) and then use ifft to come back to time domain and make the prediction based on what you get.
There's also one thing you should consider while doing this - Nyquist frequency - this means that the highest frequency that you get on your fft is half of the sampling frequency.
If you use an FFT for data that isn't periodic within the FFT aperture length, then you may need to use a window to reduce spurious frequencies due to "spectral leakage". Frequency estimation techniques to better estimate "between bin" frequency content may also be appropriate. The phase of each cosine sinusoid, relative to the edge of the window, is usually atan2(imag[i], real[i]). The frequency depends on the sample rate and bin number versus the length of the FFT.
You might also want to look into using a Kalman filter instead of an FFT.
Added: If your signal isn't exactly integer periodic in the FFT length, then you may want to do an fftshift before the FFT to move the resulting phase measurement reference point to the center of your data vector, instead of a possibly discontinuous circular edge.