Lesson 10 of 15

STFT Framing

Short-Time Fourier Transform Framing

The Short-Time Fourier Transform (STFT) analyzes how the frequency content of a signal changes over time. The key idea: divide the signal into short overlapping frames, then apply the DFT to each frame.

Framing

Given a signal xx of length LL, extract frames of size FF with a hop size HH:

framei=x[iH:iH+F]\text{frame}_i = x[i \cdot H : i \cdot H + F]

Frames are extracted as long as the full frame fits within the signal. The number of frames is:

nframes=(LF)/H+1n_{\text{frames}} = \lfloor (L - F) / H \rfloor + 1

Overlap: When H<FH < F, frames overlap. A 50% overlap means H=F/2H = F/2.

STFT Frame Spectrum

For each frame, apply a window and compute the DFT magnitude:

Xi[k]=DFT(frameiw)|X_i[k]| = |\text{DFT}(\text{frame}_i \cdot w)|

The result is a 2D time-frequency representation called a spectrogram.

Example

Signal [0,1,2,3,4,5,6,7][0,1,2,3,4,5,6,7], frame size 44, hop 22:

  • Frame 0: [0,1,2,3][0,1,2,3]
  • Frame 1: [2,3,4,5][2,3,4,5]
  • Frame 2: [4,5,6,7][4,5,6,7]

Your Task

Implement:

  • frame_signal(x, frame_size, hop) — returns list of frames (each a list of floats)
  • stft_frame_spectrum(frame, window) — returns DFT(framewindow)|\text{DFT}(\text{frame} \cdot \text{window})|
import math

def dft(x):
    N = len(x)
    X = []
    for k in range(N):
        val = 0 + 0j
        for n in range(N):
            val += x[n] * math.e ** (-2j * math.pi * k * n / N)
        X.append(val)
    return X

def frame_signal(x, frame_size, hop):
    frames = []
    i = 0
    while i + frame_size <= len(x):
        frames.append(x[i:i + frame_size])
        i += hop
    return frames

def stft_frame_spectrum(frame, window):
    windowed = [f * w for f, w in zip(frame, window)]
    return [abs(v) for v in dft(windowed)]
Python runtime loading...
Loading...
Click "Run" to execute your code.