Add fft_analysis/src/fft_analysis/core.py

This commit is contained in:
Mika 2026-04-19 02:07:44 +00:00
parent 9bf005109a
commit 0b0901ec04

View file

@ -0,0 +1,58 @@
"""Core module for performing FFT (Fast Fourier Transform) analysis on audio data.
This module provides numerical processing of time-domain PCM audio signals using FFT,
returning their magnitude spectrum for further analysis and visualization.
"""
from __future__ import annotations
import numpy as np
from scipy import fft as sp_fft
from typing import Any
class InvalidAudioDataError(ValueError):
"""Raised when provided audio_data is invalid for FFT computation."""
def perform_fft(audio_data: np.ndarray) -> np.ndarray:
"""Compute the frequency magnitude spectrum of the given audio data.
Parameters
----------
audio_data : numpy.ndarray
1D array with PCM audio data (time-domain).
Returns
-------
numpy.ndarray
Magnitude spectrum of the audio signal.
Raises
------
InvalidAudioDataError
If the input array is invalid or empty.
"""
if not isinstance(audio_data, np.ndarray):
raise InvalidAudioDataError("audio_data must be a numpy.ndarray")
if audio_data.ndim != 1:
raise InvalidAudioDataError("audio_data must be a 1D array")
if audio_data.size == 0:
raise InvalidAudioDataError("audio_data is empty")
# Normalize to range [-1, 1] to avoid scaling effects
max_val = np.max(np.abs(audio_data))
if max_val == 0:
raise InvalidAudioDataError("audio_data contains only zeros")
normalized = audio_data / max_val
# Compute FFT using scipy for better numerical accuracy
spectrum_complex = sp_fft.fft(normalized)
magnitude = np.abs(spectrum_complex)
# Return only the positive frequency components (real signal symmetry)
half_length = magnitude.shape[0] // 2
return magnitude[:half_length]