∿ LEARN DSPFrom signal to HF transceiver
Lab / lesson

Sine wave and samples

Amplitude, frequency, phase, and how to calculate the values of a digital signal.

The goal of the first session is to understand what an array of a digital signal contains. We start with one oscillation and learn to calculate its values at selected time instants.

Sinusoid: amplitude, frequency and phase

Imagine a voltage that rises and falls smoothly. The simplest model of this oscillation is:

x(t)=Acos⁡(2πft+ϕ).x(t)=A\cos(2\pi ft+\phi).
SymbolMeaningUnits
ttTimeseconds, s
AAPeak amplitudearbitrary units here
ffNumber of full cycles per secondhertz, Hz
ϕ\phiInitial phase: the point in the cycle where we startradians, rad

One turn is 360∘360^\circ, or 2π2\pi radians. In time tt, the signal makes ftft turns, so the angle changes by 2πft2\pi ft. The quantity ω=2πf\omega=2\pi f is the angular frequency; its unit is rad/s.

A cosine is a sinusoidal oscillation. The functions sin and cos differ only by a phase shift. When ϕ=0\phi=0, the cosine starts at its maximum x(0)=Ax(0)=A. When ϕ=π/2\phi=\pi/2, it starts at zero and first decreases. When ϕ=π\phi=\pi, it starts at −A-A. The initial phase moves the oscillation in time and keeps its frequency the same.

For example, f=1000f=1000 Hz means 1000 cycles per second. The period of one cycle is:

T=1f=0.001 s=1 ms.T=\frac{1}{f}=0.001\ \text{s}=1\ \text{ms}.

When A=1A=1, the values change from −1-1 to +1+1. The peak-to-peak range from minimum to maximum is 22.

From a continuous signal to samples

A computer keeps values only at separate time instants. We measure the signal at equal intervals. This is sampling (time discretization).

The sample rate FsF_s is the number of measurements per second. One result is a sample. Its index nn starts at zero:

Ts=1Fs,tn=nFs,x[n]=Acos⁡(2πfnFs+ϕ).T_s=\frac{1}{F_s},\qquad t_n=\frac{n}{F_s},\qquad x[n]=A\cos\left(2\pi f\frac{n}{F_s}+\phi\right).

ff is the frequency of the oscillation itself, and FsF_s is the rate of the measurements. When Fs=48 000F_s=48\,000 samples per second, the interval is Ts≈20.833T_s\approx20.833 μs. For a 11 kHz sinusoid, one period contains Fs/f=48F_s/f=48 sample periods. This ratio does not have to be an integer.

How to calculate a specific sample

For each index nn, do the same steps:

  1. Find the sampling instant: tn=n/Fst_n=n/F_s.
  2. Find the angle: θn=2πftn+ϕ\theta_n=2\pi ft_n+\phi.
  3. Calculate the value: x[n]=Acos⁡θnx[n]=A\cos\theta_n.

For example, with Fs=8000F_s=8000, f=1000f=1000, A=1A=1, ϕ=0\phi=0, sample n=1n=1 is at 0.0001250.000125 s. The angle is π/4\pi/4, or 45∘45^\circ, and the value is approximately 0.7070.707.

In NumPy, you give the angle in radians:

import numpy as np
import matplotlib.pyplot as plt

fs = 48_000
f = 1_000
n = np.arange(96)          # indices 0 ... 95
t = n / fs                # sampling instants, seconds
x = np.cos(2 * np.pi * f * t)

plt.stem(t * 1000, x)
plt.xlabel('Time (ms)')
plt.ylabel('Amplitude')
plt.show()

The first values are: [1, 0.991445, 0.965926, 0.923880, ...]. For now, we model ideal measurements. We discuss the limit of amplitude precision in the lesson on quantization.

A record of N=96N=96 samples at Fs=48F_s=48 kS/s lasts N/Fs=2N/F_s=2 ms. The last sample is at (N−1)/Fs≈1.979(N-1)/F_s\approx1.979 ms; the moment 22 ms already belongs to the next block. This is why we make the time axis as np.arange(N) / fs.

A circle as a model of oscillation

A point on a circle of radius 1 has the horizontal coordinate cos⁡θ\cos\theta. On the right, this coordinate is +1+1; at the top, 00; on the left, −1-1; at the bottom, 00. When the point turns at a constant speed, the horizontal coordinate changes as a cosine.

This circle helps you imagine how the voltage changes. The frequency ff sets the number of turns per second. During sampling, we record the horizontal coordinate FsF_s times per second. In the time between two measurements, the point moves through the angle

Δθ=360∘fFs.\Delta\theta=360^\circ\frac{f}{F_s}.

Take f=1f=1 kHz and Fs=6F_s=6 kS/s. The angle step is 60∘60^\circ. The first six samples are: 1, 0.5, −0.5, −1, −0.5, 0.51,\ 0.5,\ -0.5,\ -1,\ -0.5,\ 0.5. The next sample is 11 again.

−10+1Sample = 0.500Angle 60° · time 0.167 ms · sample 0.500

The slider selects the sample index. The green dot shows the position on the circle. The orange square shows its horizontal coordinate, which is the value we record.

Lab: change the sinusoid parameters

From the project directory, run the script:

uv run labs/01/01-sine-sampling.py --show

The dependencies are declared inside the script; uv prepares the environment. At the start of the file are the parameters FS, FREQUENCY, AMPLITUDE, PHASE, N. Change them one at a time:

  1. Run with the initial values f=1000f=1000 Hz, A=1A=1, ϕ=0\phi=0, N=96N=96.
  2. Set FREQUENCY = 2_000: how many cycles fit into 2 ms now?
  3. Set 1000 Hz again and set AMPLITUDE = 0.5: how do the maximum and minimum change?
  4. Set PHASE = np.pi / 2: what is the first sample? A small remainder near 10−1610^{-16} instead of zero comes from rounding during the calculation.

Sampling of a sinusoid and initial phase

On the top plot, the smooth line is calculated on a dense time grid, and the dots are our 96 samples. The bottom plot compares three fixed initial phases.

For a separate experiment with the circle:

uv run labs/01/circle-sampling.py --show

For a step-by-step calculation of specific samples:

uv run labs/01/sample-value.py --fs 8000 --f 1000 --n 0 1 2 3

Can different signals give the same array?

The second figure of the main lab compares cosines at 20 and 28 kHz with Fs=48F_s=48 kS/s. Both have amplitude 1 and initial phase 0.

Different signals, same samples

The curves are different, but their values at the sampling instants are the same. The same thing occurs with the pair 1 and 47 kHz. This is aliasing: from the samples, you cannot find the original frequency without ambiguity. In the next lesson, we find the cause with the circle and check it with calculations.

For this experiment, keep FS = 48_000: the frequency pairs in the script are selected for this sample rate.

Self-check

Given: f=2f=2 kHz, Fs=48F_s=48 kS/s, A=0.5A=0.5, ϕ=0\phi=0. The signal is x[n]=Acos⁡(2πfn/Fs+ϕ)x[n]=A\cos(2\pi fn/F_s+\phi).

What is the period TT of the sinusoid in microseconds?

Explanation

The period is the time of one full turn: T=1/f=1/2000T=1/f=1/2000 s =500=500 µs. The sample rate has no effect on the period — it sets only how often we measure the signal.

How many sample periods TsT_s fit into one period of the signal?

Explanation

Ts=1/Fs≈20.8T_s=1/F_s\approx20.8 µs, and T=500T=500 µs. The ratio is T/Ts=Fs/f=48000/2000=24T/T_s=F_s/f=48000/2000=24. In one interval, the point turns by 360∘/24=15∘360^\circ/24=15^\circ.

What is the first sample x[0]x[0]?

Explanation

When n=0n=0, the angle is equal to the initial phase: θ0=ϕ=0\theta_0=\phi=0. The point on the circle is on the right, and its horizontal coordinate is 11. Multiply by the amplitude: x[0]=0.5⋅1=0.5x[0]=0.5\cdot1=0.5.

We change only the initial phase ϕ\phi. What happens to the period TT and the interval between samples TsT_s?

Explanation

The phase sets the angle where the rotation starts. The sample values change, for example x[0]=Acos⁡ϕx[0]=A\cos\phi, but the speed of rotation and the sampling instants do not change.

First answer without Python, then check the calculation in the lab. The sinusoid generator will be useful to test the next blocks of the transceiver.

Next lesson: aliasing — different signals, same samples →