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