Add fft_analysis/src/fft_analysis/core.py
This commit is contained in:
parent
9bf005109a
commit
0b0901ec04
1 changed files with 58 additions and 0 deletions
58
fft_analysis/src/fft_analysis/core.py
Normal file
58
fft_analysis/src/fft_analysis/core.py
Normal 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]
|
||||||
Loading…
Reference in a new issue