Add fft_analysis/src/fft_analysis/io_utils.py

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

View file

@ -0,0 +1,66 @@
import json
import os
from pathlib import Path
from typing import Tuple, List
import numpy as np
from scipy.io import wavfile
class FFTSpectrum:
"""Datenmodell für FFT-Spektrumsausgabe."""
def __init__(self, frequencies: List[float], magnitudes: List[float]):
self.frequencies = frequencies
self.magnitudes = magnitudes
def to_dict(self) -> dict:
return {
"frequencies": self.frequencies,
"magnitudes": self.magnitudes
}
def load_audio_file(file_path: str) -> Tuple[np.ndarray, int]:
"""Lädt eine WAV- oder FLAC-Datei als normalisiertes NumPy-Array und gibt (audio_data, sample_rate) zurück."""
path = Path(file_path)
if not path.exists() or not path.is_file():
raise FileNotFoundError(f"Audio file not found: {file_path}")
if path.suffix.lower() != ".wav":
raise ValueError("Only WAV files are supported for this implementation.")
sample_rate, data = wavfile.read(file_path)
if data.ndim > 1:
data = np.mean(data, axis=1)
data = data.astype(np.float32)
max_val = np.max(np.abs(data))
if max_val > 0:
data /= max_val
assert isinstance(sample_rate, int), "Sample rate must be an integer."
assert isinstance(data, np.ndarray), "Audio data must be a NumPy array."
return data, sample_rate
def save_spectrum_to_json(spectrum: np.ndarray, output_path: str) -> None:
"""Speichert das Frequenzspektrum als JSON-Datei im FFTSpectrum-Format."""
if not isinstance(spectrum, np.ndarray):
raise TypeError("Spectrum must be a numpy.ndarray.")
if spectrum.ndim != 1:
raise ValueError("Spectrum must be a 1D numpy array.")
frequencies = np.fft.fftfreq(len(spectrum)).tolist()
magnitudes = np.abs(spectrum).tolist()
fft_obj = FFTSpectrum(frequencies=frequencies, magnitudes=magnitudes)
output_dir = os.path.dirname(output_path)
if output_dir:
os.makedirs(output_dir, exist_ok=True)
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(fft_obj.to_dict(), f, ensure_ascii=False, indent=2)
assert Path(output_path).exists(), "JSON output file was not created successfully."