user13267
user13267

Reputation: 7193

Why doesn't matlab give me an 8KHz sinewave for 16KHz sampling frequency?

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
enter image description here

The graph seems normal upto 2000, but at 3000, the graph is
enter image description here

We can see that the amplitude changes during every cycle

Again, at 4000 the graph is
enter image description here

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
enter image description here

and at 8000 we have
enter image description here

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
enter image description here

Upvotes: 2

Views: 2452

Answers (3)

patrik
patrik

Reputation: 4558

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.

Upvotes: 0

Fumu 7
Fumu 7

Reputation: 1091

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.

Upvotes: 0

Drew McGowen
Drew McGowen

Reputation: 11706

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.

Upvotes: 7

Related Questions