Add audio_visualizer/src/audio_visualizer/io_utils.py
This commit is contained in:
parent
6f45028af0
commit
05488822ee
1 changed files with 83 additions and 0 deletions
83
audio_visualizer/src/audio_visualizer/io_utils.py
Normal file
83
audio_visualizer/src/audio_visualizer/io_utils.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import csv
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import NamedTuple
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s')
|
||||
|
||||
|
||||
class SensorDataRow(NamedTuple):
|
||||
"""Repräsentiert eine einzelne Zeile von Sensordaten."""
|
||||
|
||||
timestamp: float
|
||||
frequency: float
|
||||
amplitude: float
|
||||
|
||||
|
||||
class AudioDataLoadError(Exception):
|
||||
"""Wird ausgelöst, wenn beim Laden der Audio- oder Sensordaten ein Fehler auftritt."""
|
||||
|
||||
|
||||
|
||||
def load_audio_data(path: str) -> np.ndarray:
|
||||
"""Lädt und parst Sensordaten oder Audiodateien zur Weiterverarbeitung.
|
||||
|
||||
Unterstützt aktuell CSV-Dateien mit Spalten: timestamp, frequency, amplitude.
|
||||
|
||||
Args:
|
||||
path (str): Pfad zur Eingabedatei (CSV oder WAV).
|
||||
|
||||
Returns:
|
||||
np.ndarray: Ein Array mit den geladenen Daten (timestamp, frequency, amplitude).
|
||||
|
||||
Raises:
|
||||
AudioDataLoadError: Wenn die Datei nicht existiert oder unlesbar ist.
|
||||
ValueError: Wenn Daten ungültig oder unvollständig sind.
|
||||
"""
|
||||
|
||||
file_path = Path(path)
|
||||
if not file_path.exists():
|
||||
logger.error(f"Datei nicht gefunden: {path}")
|
||||
raise AudioDataLoadError(f"Datei nicht gefunden: {path}")
|
||||
|
||||
if file_path.suffix.lower() != '.csv':
|
||||
logger.error(f"Nur CSV-Dateien werden derzeit unterstützt: {path}")
|
||||
raise AudioDataLoadError(f"Nur CSV-Dateien werden derzeit unterstützt: {path}")
|
||||
|
||||
data_rows: list[SensorDataRow] = []
|
||||
|
||||
with file_path.open('r', encoding='utf-8') as csvfile:
|
||||
reader = csv.DictReader(csvfile)
|
||||
required_fields = {'timestamp', 'frequency', 'amplitude'}
|
||||
|
||||
if not required_fields.issubset(reader.fieldnames or {}):
|
||||
logger.error(f"CSV-Datei enthält nicht alle erforderlichen Felder: {reader.fieldnames}")
|
||||
raise ValueError("Ungültiges CSV-Format: timestamp, frequency, amplitude erforderlich.")
|
||||
|
||||
for row in reader:
|
||||
try:
|
||||
timestamp = float(row['timestamp'])
|
||||
frequency = float(row['frequency'])
|
||||
amplitude = float(row['amplitude'])
|
||||
data_rows.append(SensorDataRow(timestamp, frequency, amplitude))
|
||||
except (KeyError, ValueError) as e:
|
||||
logger.warning(f"Überspringe fehlerhafte Zeile ({row}): {e}")
|
||||
|
||||
if not data_rows:
|
||||
logger.error("Keine gültigen Datenzeilen gefunden.")
|
||||
raise ValueError("Keine gültigen Sensordaten enthalten.")
|
||||
|
||||
data_array = np.array(data_rows, dtype=float)
|
||||
|
||||
logger.info(f"Geladene Datensätze: {len(data_array)} aus {path}")
|
||||
|
||||
# Zusätzliche Validierung
|
||||
assert data_array.shape[1] == 3, "Jede Zeile muss drei Werte enthalten: timestamp, frequency, amplitude"
|
||||
|
||||
return data_array
|
||||
Loading…
Reference in a new issue